iOS CoreBluetooth виртуальная периферия несколько уведомлений - PullRequest
0 голосов
/ 10 декабря 2018

Я работаю над приложением для iOS, в котором мне нужно отправить более 20 байтов данных в центральный терминал Bluetooth LE.Я установил периферийный менеджер и отправляю каждый «пакет» по 20 байт один за другим.Я отправляю следующий пакет только один раз, когда peripheralManager.updatevalue возвращает значение true (повторная попытка после вызова peripheralManagerIsReadyToUpdateSubscribers, если updateValue возвращает значение false).В большинстве случаев это работает, однако примерно в 20% случаев отправляемые данные неверны.

У меня три пакета.Большую часть времени центральный получает A, затем B, а затем C, однако иногда центральный получает B, затем B, затем C или A, затем C, а затем снова C.

Он всегда отправляет три уведомления, однако значения неверны.

В случае, если это важно:

Значения для характеристики сохраняются в экземплярах BLECharacteristic объектов

@objc public class BLECharacteristic: CBMutableCharacteristic{
    public var dynamicValue: Data?
    public override init(type UUID: CBUUID, properties: CBCharacteristicProperties, value: Data?, permissions: CBAttributePermissions){
        super.init(type: UUID, properties: properties, value: nil, permissions: permissions)
        self.dynamicValue = value
    }
    public convenience init(characteristic: CBCharacteristic){
        self.init(type: characteristic.uuid, properties: characteristic.properties, value: characteristic.value, permissions: CBAttributePermissions.readable)
    }
}

И когда уведомления «буферизируются» дляотправляется после вызова peripheralManagerIsReadyToUpdateSubscribers, информация сохраняется в объекте * 1017. *

@objc public class DelayedNotification: NSObject{
    private(set) var valueToNotify: Data
    private(set) var characteristic: BLECharacteristic
    private(set) var devicesToNotify: [CBCentral]?

    @objc public init(_ data: Data, _ char: BLECharacteristic, _ devsNotify: [CBCentral]?){
        valueToNotify = data
        characteristic = char
        devicesToNotify = devsNotify
    }
}

Когда объект создан:

var valueToSend: Data
if(characteristic.dynamicValue == nil){
    valueToSend = Data()
}else{
    valueToSend = characteristic.dynamicValue!
}

buffer.append(DelayedNotification(valueToSend, characteristic, devicesToNotify))

Редактировать: Больше кода

private func notifyDevices(_ characteristic: BLECharacteristic){
    DispatchQueue.main.async {
        var valueToSend: Data
        if(characteristic.dynamicValue == nil){
            valueToSend = Data()
        }else{
            valueToSend = Data(characteristic.dynamicValue!)
        }

        self.notificationLock.wait()
        self.notBuffer.append(DelayedNotification(valueToSend, characteristic, nil))
        self.notificationLock.signal()

        self.processNotificationBuffer()
    }
}

private func processNotificationBuffer(){
    DispatchQueue.main.async{
        self.notificationLock.wait()

        for notification in self.notBuffer{
            let res = self.peripheralManager.updateValue(Data(notification.valueToNotify), for: notification.characteristic, onSubscribedCentrals: notification.devicesToNotify)
            if(res){
                NSLog("Sent: " + String(data: notification.valueToNotify, encoding: .utf8)!) // This is always printed in the right order
                notificationSent()
                self.notBuffer.remove(at: self.notBuffer.index(of: notification)!)
            }
        }

        self.notificationLock.signal()
    }
}

@objc public func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
    processNotificationBuffer()
}

1 Ответ

0 голосов
/ 12 декабря 2018

Проблема была с клиентом.Мой пользовательский Android-клиент работает как положено.

...