diff --git a/src/api/mod.rs b/src/api/mod.rs index f24bba61..c18f0d4b 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -84,6 +84,8 @@ impl AddressType { /// A notification sent from a peripheral due to a change in a value. #[derive(Clone, Debug, Eq, PartialEq)] pub struct ValueNotification { + /// UUID of the service that fired the notification. + pub service_uuid: Uuid, /// UUID of the characteristic that fired the notification. pub uuid: Uuid, /// The new value of the characteristic. diff --git a/src/bluez/peripheral.rs b/src/bluez/peripheral.rs index 426ff30b..b6455479 100644 --- a/src/bluez/peripheral.rs +++ b/src/bluez/peripheral.rs @@ -282,8 +282,12 @@ 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 (service, characteristic) = find_characteristic_by_id(&services, id)?; + Some(ValueNotification { + uuid: characteristic.uuid, + service_uuid: service.info.uuid, + value, + }) } _ => None, } @@ -292,11 +296,11 @@ fn value_notification( fn find_characteristic_by_id( services: &HashMap, characteristic_id: CharacteristicId, -) -> Option<&CharacteristicInfo> { +) -> Option<(&ServiceInternal, &CharacteristicInfo)> { for service in services.values() { for characteristic in service.characteristics.values() { if characteristic.info.id == characteristic_id { - return Some(&characteristic.info); + return Some((service, &characteristic.info)); } } } diff --git a/src/corebluetooth/internal.rs b/src/corebluetooth/internal.rs index c3dd3eef..2aa00dc5 100644 --- a/src/corebluetooth/internal.rs +++ b/src/corebluetooth/internal.rs @@ -155,7 +155,7 @@ pub enum CoreBluetoothReply { #[derive(Debug)] pub enum CBPeripheralEvent { Disconnected, - Notification(Uuid, Vec), + Notification(Uuid, Uuid, Vec), ManufacturerData(u16, Vec, i16), ServiceData(HashMap>, i16), Services(Vec, i16), @@ -742,7 +742,11 @@ impl CoreBluetoothInternal { .set_reply(CoreBluetoothReply::ReadResult(data_clone)); } else if let Err(e) = peripheral .event_sender - .send(CBPeripheralEvent::Notification(characteristic_uuid, data)) + .send(CBPeripheralEvent::Notification( + service_uuid, + characteristic_uuid, + data, + )) .await { error!("Error sending notification event: {}", e); diff --git a/src/corebluetooth/peripheral.rs b/src/corebluetooth/peripheral.rs index 6f5b67d1..462ee55a 100644 --- a/src/corebluetooth/peripheral.rs +++ b/src/corebluetooth/peripheral.rs @@ -120,8 +120,12 @@ impl Peripheral { loop { match event_receiver.next().await { - Some(CBPeripheralEvent::Notification(uuid, data)) => { - let notification = ValueNotification { uuid, value: data }; + Some(CBPeripheralEvent::Notification(service_uuid, uuid, data)) => { + let notification = ValueNotification { + service_uuid, + uuid, + value: data, + }; // Note: we ignore send errors here which may happen while there are no // receivers... diff --git a/src/winrtble/peripheral.rs b/src/winrtble/peripheral.rs index fda061f9..f86071d1 100644 --- a/src/winrtble/peripheral.rs +++ b/src/winrtble/peripheral.rs @@ -493,9 +493,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 = ble_service.uuid; ble_characteristic .subscribe(Box::new(move |value| { - let notification = ValueNotification { uuid, value }; + let notification = ValueNotification { + service_uuid, + uuid, + value, + }; // Note: we ignore send errors here which may happen while there are no // receivers... let _ = notifications_sender.send(notification);