在iOS(10.3)上使用CoreBluetooth我在绑定(配对?)到自定义BLE HID设备时无法读取特征值。如果我保持不受约束,我可以阅读特征罚款。
BLE设备通过GATT(HOGP)实现HID,并通过单一通知特性实现附加服务。这个额外的服务/特性是我尝试阅读的内容,而不是我知道过滤掉的GATT数据上的HID。
看来didDiscoverServices永远不会被调用。我确实看到didConnect被调用。
我能够在Android上完成此操作,因此我不认为这是BLE设备的问题。
以下相关代码:
func centralManagerDidUpdateState(_ central: CBCentralManager) {
var showAlert = true
var message = ""
switch central.state {
case .poweredOff:
message = NSLocalizedString("Bluetooth on this device is currently powered off.", comment: "")
case .unsupported:
message = NSLocalizedString("This device does not support Bluetooth Low Energy.", comment: "")
case .unauthorized:
message = NSLocalizedString("This app is not authorized to use Bluetooth Low Energy.", comment: "")
case .resetting:
message = NSLocalizedString("The BLE Manager is resetting; a state update is pending.", comment: "")
case .unknown:
message = NSLocalizedString("The state of the BLE Manager is unknown.", comment: "")
case .poweredOn:
showAlert = false
message = NSLocalizedString("Bluetooth LE is turned on and ready for communication.", comment: "")
let lastPeripherals = centralManager.retrieveConnectedPeripherals(withServices: [CBUUID(string: Device.DeviceServiceUUID)])
print("count: \(lastPeripherals.count)")
if lastPeripherals.count > 0{
let device = lastPeripherals.last!;
connectingPeripheral = device;
centralManager.connect(connectingPeripheral, options: nil)
} else {
centralManager.scanForPeripherals(withServices: [CBUUID(string: "7340")], options: nil)
}
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
if peripheralName == deviceName {
// save a reference to the device
device= peripheral
device!.delegate = self
// Request a connection to the peripheral
centralManager.connect(device!, options: nil)
}
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.discoverServices(nil)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
if error != nil {
print("****** DISCONNECTION DETAILS: \(error!.localizedDescription)")
}
device = nil
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if error != nil {
print("ERROR DISCOVERING SERVICES: \(error?.localizedDescription)")
return
}
if let services = peripheral.services {
for service in services {
print("DISCOVERED SERVICE: \(service)")
if (service.uuid == CBUUID(string: Device.DeviceServiceUUID)) {
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if error != nil {
print("ERROR DISCOVERING CHARACTERISTICS: \(error?.localizedDescription)")
return
}
if let characteristics = service.characteristics {
for characteristic in characteristics {
// Message Data Characteristic
if characteristic.uuid == CBUUID(string: Device.MessageCharacteristicUUID) {
// Enable the message notifications
messageCharacteristic = characteristic
device?.setNotifyValue(true, for: characteristic)
}
}
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if error != nil {
print("ERROR ON UPDATING VALUE FOR CHARACTERISTIC: \(characteristic) - \(error?.localizedDescription)")
return
}
// extract the data from the characteristic's value property and display the value based on the characteristic type
if let dataBytes = characteristic.value {
if characteristic.uuid == CBUUID(string: Device.MessageCharacteristicUUID) {
displayMessage(dataBytes)
}
}
}