Как обработать запрос на чтение и подписку для длинных значений признаков в PeripheralManager? - PullRequest
0 голосов
/ 31 марта 2019

Я создал периферийное устройство в своем приложении для iOS, которое имеет характеристику, которую я использую для отправки данных размером около 540 байт.Я не могу получить данные на центральной стороне (не iOS).Как мне реагировать на события подписки и запрашивать чтение из подключенного централизованного центра для успешной передачи данных?

Я испробовал следующие подходы.

1.Подписаться на характеристику и выполнитьблок данных

, когда центральный сервер подписывает (разрешает уведомления) на характеристику, я вызываю

let isSuccessful = peripheralManager.updateValue(data, for: characteristic, onSubscribedCentrals: nil)

Данные имеют размер около 540 байтов.Когда я проверяю возвращаемое значение, оно возвращает true, даже если оно передает только 20 байтов в подписанный центр.

Если он когда-либо возвращал false, что по какой-то причине не так, я делал это

if !isSuccessful {
   let range = 0 ..< 19
   globalDataVariable?.removeSubrange(range)               
}

Я ожидал, что приведенный ниже метод делегата ПериферическийМенеджер будет запущен, но это не так..

func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
   guard let data = globalDataVariable else { return }
   let isSuccessful = peripheral.updateValue(data, for: characteristic, onSubscribedCentrals: nil)
   if !isSuccessful {
      print("Data still pending..... ")
      let range = 0 ..< 19
      shareData?.removeSubrange(range)
   }        
}

Для порции я сохраняю данные для отправки в свойстве класса, а затем удаляю данные, которые уже отправлены.Центральное значение maximumUpdateValueLength составляет 20 байтов.Я не уверен, что этот подход к чанки и отправке правильный или я правильно делаю чанкинг.

2.Если для характеристики имеется уведомление, центральное устройство сделает запрос на чтение.

Для этого подхода, когда существует подписка от центрального на указанную характеристику, периферийное устройство будет вызывать

characteristic.value = data // doing this for handling the read request
peripheralManager.updateValue(data, for: characteristic, onSubscribedCentrals: nil)

когда центральный получит уведомление с частичными данными, он отправит запрос на чтение к периферийному устройству.

На периферии я обрабатываю это следующим образом.

func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
    switch(request.characteristic.uuid) {
    case characteristicUUID:
        print(request.offset)
        guard let data = characteristic.value else { return }
        guard request.offset < data.count else {
           print("Invalid Offset")
           peripheralManager.respond(to: request, withResult: .invalidOffset)
           return
        }
        request.value = data.subdata(in: request.offset ..< data.count)
        peripheralManager.respond(to: request, withResult: .success)

        default:
            print("Unknown Characteristic")
   }
}

Этот подход работает для другой характеристики, которая у меня есть, но она используется для отправки сравнительно небольшого объема данных, меньше чем500 байтов, но для данных более 512 байт это не так

Я также следовал этой теме Чтение длинных значений характеристик с использованием CoreBluetooth , но подход к разделению на блоки не был описан в нем.

Являются ли эти подходы правильными?Есть ли другой способ обработки чтения / подписки длинных значений признаков?

...