iOS CoreBluetooth 虚拟外设多重通知
iOS CoreBluetooth virtual peripheral multiple notifications
我正在开发一个 iOS 应用程序,我需要将超过 20 个字节的数据发送到蓝牙 LE 中心。我已经设置了一个外设管理器,我一个接一个地发送 20 个字节的每个 "packet"。我只在 peripheralManager.updatevalue
returns 为真时发送下一个数据包(如果 updateValue
returns 为假,我会在调用 peripheralManagerIsReadyToUpdateSubscribers
后重试)。大多数情况下这是有效的,但是大约 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
后 "buffered" 发送通知时,信息存储在 DelayedNotification
对象中。
@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()
}
问题出在客户端。我的自定义 android 客户端按预期工作。
我正在开发一个 iOS 应用程序,我需要将超过 20 个字节的数据发送到蓝牙 LE 中心。我已经设置了一个外设管理器,我一个接一个地发送 20 个字节的每个 "packet"。我只在 peripheralManager.updatevalue
returns 为真时发送下一个数据包(如果 updateValue
returns 为假,我会在调用 peripheralManagerIsReadyToUpdateSubscribers
后重试)。大多数情况下这是有效的,但是大约 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
后 "buffered" 发送通知时,信息存储在 DelayedNotification
对象中。
@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()
}
问题出在客户端。我的自定义 android 客户端按预期工作。