From 07f7cc07b188b514666606b7fad78714cac0ef09 Mon Sep 17 00:00:00 2001 From: MnlPhlp Date: Tue, 21 Oct 2025 11:30:28 +0200 Subject: [PATCH 1/2] add service uuids to notifications --- src/api/mod.rs | 2 ++ src/bluez/peripheral.rs | 9 +++++++-- src/corebluetooth/internal.rs | 3 ++- src/corebluetooth/peripheral.rs | 8 ++++++-- src/droidplug/peripheral.rs | 7 ++++++- src/winrtble/peripheral.rs | 7 ++++++- 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/api/mod.rs b/src/api/mod.rs index bb3acf68..70c11f69 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -86,6 +86,8 @@ impl AddressType { pub struct ValueNotification { /// UUID of the characteristic that fired the notification. pub uuid: Uuid, + /// UUID of the service that contains the characteristic. + pub service_uuid: Uuid, /// The new value of the characteristic. pub value: Vec, } diff --git a/src/bluez/peripheral.rs b/src/bluez/peripheral.rs index d2803bd7..5449e255 100644 --- a/src/bluez/peripheral.rs +++ b/src/bluez/peripheral.rs @@ -298,8 +298,13 @@ fn value_notification( event: CharacteristicEvent::Value { value }, } if id.service().device() == *device_id => { let services = services.lock().unwrap(); - let uuid = find_characteristic_by_id(&services, id)?.uuid; - Some(ValueNotification { uuid, value }) + let info = find_characteristic_by_id(&services, id.clone())?; + let service = services.iter().find(|(_, s)| s.info.id == id.service())?.0; + Some(ValueNotification { + uuid: info.uuid, + service_uuid: *service, + value, + }) } _ => None, } diff --git a/src/corebluetooth/internal.rs b/src/corebluetooth/internal.rs index 93597bc7..b703c6fe 100644 --- a/src/corebluetooth/internal.rs +++ b/src/corebluetooth/internal.rs @@ -157,7 +157,7 @@ pub enum CoreBluetoothReply { #[derive(Debug)] pub enum PeripheralEventInternal { Disconnected, - Notification(Uuid, Vec), + Notification(Uuid, Uuid, Vec), ManufacturerData(u16, Vec, i16), ServiceData(HashMap>, i16), Services(Vec, i16), @@ -818,6 +818,7 @@ impl CoreBluetoothInternal { .event_sender .send(PeripheralEventInternal::Notification( characteristic_uuid, + service_uuid, data, )) .await diff --git a/src/corebluetooth/peripheral.rs b/src/corebluetooth/peripheral.rs index 5ef24288..f114a5fd 100644 --- a/src/corebluetooth/peripheral.rs +++ b/src/corebluetooth/peripheral.rs @@ -118,8 +118,12 @@ impl Peripheral { loop { match event_receiver.next().await { - Some(PeripheralEventInternal::Notification(uuid, data)) => { - let notification = ValueNotification { uuid, value: data }; + Some(PeripheralEventInternal::Notification(uuid, service_uuid, data)) => { + let notification = ValueNotification { + uuid, + service_uuid, + value: data, + }; // Note: we ignore send errors here which may happen while there are no // receivers... diff --git a/src/droidplug/peripheral.rs b/src/droidplug/peripheral.rs index b7a1c95e..08ce1eb5 100644 --- a/src/droidplug/peripheral.rs +++ b/src/droidplug/peripheral.rs @@ -26,6 +26,7 @@ use std::{ pin::Pin, sync::{Arc, Mutex}, }; +use uuid::Uuid; use super::jni::{ global_jvm, @@ -367,7 +368,11 @@ impl api::Peripheral for Peripheral { let characteristic = JBluetoothGattCharacteristic::from_env(&env, item)?; let uuid = characteristic.get_uuid()?; let value = characteristic.get_value()?; - Ok(ValueNotification { uuid, value }) + Ok(ValueNotification { + uuid, + service_uuid: Uuid::default(), + value, + }) // TODO: get service UUID } Err(err) => Err(err), }) diff --git a/src/winrtble/peripheral.rs b/src/winrtble/peripheral.rs index bac09da4..c659fc2b 100644 --- a/src/winrtble/peripheral.rs +++ b/src/winrtble/peripheral.rs @@ -509,9 +509,14 @@ impl ApiPeripheral for Peripheral { .ok_or_else(|| Error::NotSupported("Characteristic not found for subscribe".into()))?; let notifications_sender = self.shared.notifications_channel.clone(); let uuid = characteristic.uuid; + let service_uuid = characteristic.service_uuid; ble_characteristic .subscribe(Box::new(move |value| { - let notification = ValueNotification { uuid, value }; + let notification = ValueNotification { + uuid, + service_uuid, + value, + }; // Note: we ignore send errors here which may happen while there are no // receivers... let _ = notifications_sender.send(notification); From 5f86b56731484c2e2de48cb4acade53529360105 Mon Sep 17 00:00:00 2001 From: MnlPhlp Date: Tue, 4 Nov 2025 11:24:56 +0100 Subject: [PATCH 2/2] make find_characteristic_by_id return service info --- src/bluez/peripheral.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bluez/peripheral.rs b/src/bluez/peripheral.rs index 5449e255..51f53c98 100644 --- a/src/bluez/peripheral.rs +++ b/src/bluez/peripheral.rs @@ -298,11 +298,10 @@ fn value_notification( event: CharacteristicEvent::Value { value }, } if id.service().device() == *device_id => { let services = services.lock().unwrap(); - let info = find_characteristic_by_id(&services, id.clone())?; - let service = services.iter().find(|(_, s)| s.info.id == id.service())?.0; + let (charac, service) = find_characteristic_by_id(&services, id.clone())?; Some(ValueNotification { - uuid: info.uuid, - service_uuid: *service, + uuid: charac.uuid, + service_uuid: service.uuid, value, }) } @@ -313,11 +312,11 @@ fn value_notification( fn find_characteristic_by_id( services: &HashMap, characteristic_id: CharacteristicId, -) -> Option<&CharacteristicInfo> { +) -> Option<(&CharacteristicInfo, &ServiceInfo)> { for service in services.values() { for characteristic in service.characteristics.values() { if characteristic.info.id == characteristic_id { - return Some(&characteristic.info); + return Some((&characteristic.info, &service.info)); } } }