From ca1ab83ed4b5e09c920f509b5b998fb00d845b10 Mon Sep 17 00:00:00 2001 From: kovapatrik Date: Mon, 15 Jul 2024 03:33:01 +0200 Subject: [PATCH 1/3] fix: reading descriptor value --- src/corebluetooth/central_delegate.rs | 17 ++++++++++++++++- src/corebluetooth/internal.rs | 5 ++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/corebluetooth/central_delegate.rs b/src/corebluetooth/central_delegate.rs index 8dfb889b..97dcfd6d 100644 --- a/src/corebluetooth/central_delegate.rs +++ b/src/corebluetooth/central_delegate.rs @@ -685,7 +685,7 @@ declare_class!( service_uuid: cbuuid_to_uuid(unsafe { &service.UUID() }), characteristic_uuid: cbuuid_to_uuid(unsafe { &characteristic.UUID() }), descriptor_uuid: cbuuid_to_uuid(unsafe { &descriptor.UUID() }), - data: get_characteristic_value(&characteristic), + data: get_descriptor_value(&descriptor), }); // Notify BluetoothGATTCharacteristic::read_value that read was successful. } @@ -749,6 +749,21 @@ fn get_characteristic_value(characteristic: &CBCharacteristic) -> Vec { v.unwrap_or_default() } +fn get_descriptor_value(descriptor: &CBDescriptor) -> Vec { + trace!("Getting data!"); + let v = unsafe { descriptor.value() }.map(|value| unsafe { + match descriptor.UUID().UUIDString().to_string().as_str() { + "2901" => { + let d: Retained = Retained::cast(value); + d.to_string().into_bytes() + } + _ => vec![], + } + }); + trace!("BluetoothGATTDescriptor::get_value -> {:?}", v); + v.unwrap_or_default() +} + fn peripheral_debug(peripheral: &CBPeripheral) -> String { let uuid = unsafe { peripheral.identifier() }.UUIDString(); if let Some(name) = unsafe { peripheral.name() } { diff --git a/src/corebluetooth/internal.rs b/src/corebluetooth/internal.rs index 867ccf47..ac454809 100644 --- a/src/corebluetooth/internal.rs +++ b/src/corebluetooth/internal.rs @@ -1009,15 +1009,14 @@ impl CoreBluetoothInternal { if let Some(service) = peripheral.services.get_mut(&service_uuid) { if let Some(characteristic) = service.characteristics.get_mut(&characteristic_uuid) { - if let Some(_descriptor) = characteristic.descriptors.get_mut(&descriptor_uuid) - { + if let Some(descriptor) = characteristic.descriptors.get_mut(&descriptor_uuid) { trace!("Got read event!"); let mut data_clone = Vec::new(); for byte in data.iter() { data_clone.push(*byte); } - let state = characteristic.read_future_state.pop_back().unwrap(); + let state = descriptor.read_future_state.pop_back().unwrap(); state .lock() .unwrap() From 35b1d3dbb86dd327327ad75677e2711a47b4e155 Mon Sep 17 00:00:00 2001 From: kovapatrik Date: Mon, 15 Jul 2024 04:14:27 +0200 Subject: [PATCH 2/3] fix: incorrect delegate --- src/corebluetooth/central_delegate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corebluetooth/central_delegate.rs b/src/corebluetooth/central_delegate.rs index 97dcfd6d..15f62737 100644 --- a/src/corebluetooth/central_delegate.rs +++ b/src/corebluetooth/central_delegate.rs @@ -599,7 +599,7 @@ declare_class!( } } - #[method(peripheral:didUpdateNotificationStateForCharacteristic:error:)] + #[method(peripheral:didWriteValueForCharacteristic:error:)] fn delegate_peripheral_didwritevalueforcharacteristic_error( &self, peripheral: &CBPeripheral, @@ -622,7 +622,7 @@ declare_class!( } } - #[method(peripheral:didWriteValueForCharacteristic:error:)] + #[method(peripheral:didUpdateNotificationStateForCharacteristic:error:)] fn delegate_peripheral_didupdatenotificationstateforcharacteristic_error( &self, peripheral: &CBPeripheral, From a090173a4e3b064e1fcec5dbbdb733c2984e0113 Mon Sep 17 00:00:00 2001 From: kovapatrik Date: Mon, 15 Jul 2024 17:34:59 +0200 Subject: [PATCH 3/3] fix: use class type instead of matching UUIDs --- src/corebluetooth/central_delegate.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/corebluetooth/central_delegate.rs b/src/corebluetooth/central_delegate.rs index 15f62737..cc6989a3 100644 --- a/src/corebluetooth/central_delegate.rs +++ b/src/corebluetooth/central_delegate.rs @@ -752,12 +752,32 @@ fn get_characteristic_value(characteristic: &CBCharacteristic) -> Vec { fn get_descriptor_value(descriptor: &CBDescriptor) -> Vec { trace!("Getting data!"); let v = unsafe { descriptor.value() }.map(|value| unsafe { - match descriptor.UUID().UUIDString().to_string().as_str() { - "2901" => { + let mut clazz = value.class(); + // Find the root class until we reach NSObject + while let Some(superclass) = clazz.superclass() { + if superclass == NSObject::class() { + break; + } + clazz = superclass; + } + + match clazz.name() { + "NSString" => { let d: Retained = Retained::cast(value); d.to_string().into_bytes() } - _ => vec![], + "NSData" => { + let d: Retained = Retained::cast(value); + d.bytes().into() + } + "NSNumber" => { + let d: Retained = Retained::cast(value); + d.stringValue().to_string().into_bytes() + } + _ => { + error!("Unknown descriptor value class: {:?}", clazz); + Vec::new() + } } }); trace!("BluetoothGATTDescriptor::get_value -> {:?}", v);