diff --git a/src/api/mod.rs b/src/api/mod.rs index 5986714e..74886582 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -42,8 +42,6 @@ use uuid::Uuid; pub use self::bdaddr::{BDAddr, ParseBDAddrError}; -use crate::platform::PeripheralId; - /// The default MTU size for a peripheral. pub const DEFAULT_MTU_SIZE: u16 = 23; @@ -254,8 +252,10 @@ pub enum WriteType { /// as well as functions for communication. #[async_trait] pub trait Peripheral: Send + Sync + Clone + Debug { + type ID: PeripheralId; + /// Returns the unique identifier of the peripheral. - fn id(&self) -> PeripheralId; + fn id(&self) -> Self::ID; /// Returns the MAC address of the peripheral. fn address(&self) -> BDAddr; @@ -380,6 +380,14 @@ pub trait Peripheral: Send + Sync + Clone + Debug { } } +/// ID for a [`Peripheral`]. +/// +/// Different backends use different ID types. +pub trait PeripheralId: + 'static + Send + Sync + Clone + Debug + PartialEq + Eq + std::hash::Hash + std::fmt::Display +{ +} + #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), @@ -399,33 +407,33 @@ pub enum CentralState { serde(crate = "serde_cr") )] #[derive(Debug, Clone)] -pub enum CentralEvent { - DeviceDiscovered(PeripheralId), - DeviceUpdated(PeripheralId), - DeviceConnected(PeripheralId), - DeviceDisconnected(PeripheralId), +pub enum CentralEvent { + DeviceDiscovered(ID), + DeviceUpdated(ID), + DeviceConnected(ID), + DeviceDisconnected(ID), /// Only emitted on the corebluetooth subsystem - DeviceServicesModified(PeripheralId), + DeviceServicesModified(ID), /// Emitted when a Manufacturer Data advertisement has been received from a device ManufacturerDataAdvertisement { - id: PeripheralId, + id: ID, manufacturer_data: HashMap>, }, /// Emitted when a Service Data advertisement has been received from a device ServiceDataAdvertisement { - id: PeripheralId, + id: ID, service_data: HashMap>, }, /// Emitted when the advertised services for a device has been updated ServicesAdvertisement { - id: PeripheralId, + id: ID, services: Vec, }, /// Emitted when an RSSI (signal strength) update is received for a device. /// This may come from advertisements during scanning, or from an active /// `read_rssi()` call on connected platforms. RssiUpdate { - id: PeripheralId, + id: ID, rssi: i16, }, StateUpdate(CentralState), @@ -439,7 +447,11 @@ pub trait Central: Send + Sync + Clone { /// Retrieve a stream of `CentralEvent`s. This stream will receive notifications when events /// occur for this Central module. See [`CentralEvent`] for the full set of possible events. - async fn events(&self) -> Result + Send>>>; + async fn events( + &self, + ) -> Result< + Pin::ID>> + Send>>, + >; /// Starts a scan for BLE devices. This scan will generally continue until explicitly stopped, /// although this may depend on your Bluetooth adapter. Discovered devices will be announced @@ -458,10 +470,16 @@ pub trait Central: Send + Sync + Clone { async fn peripherals(&self) -> Result>; /// Returns a particular [`Peripheral`] by its address if it has been discovered. - async fn peripheral(&self, id: &PeripheralId) -> Result; + async fn peripheral( + &self, + id: &::ID, + ) -> Result; /// Add a [`Peripheral`] from a MAC address without a scan result. Not supported on all Bluetooth systems. - async fn add_peripheral(&self, address: &PeripheralId) -> Result; + async fn add_peripheral( + &self, + address: &::ID, + ) -> Result; /// Clears the list of [`Peripheral`]s that have been discovered so far. Connected peripherals /// should be disconnected before calling this method. On platforms that do not cache peripherals diff --git a/src/bluez/adapter.rs b/src/bluez/adapter.rs index e8d495b7..b732f5af 100644 --- a/src/bluez/adapter.rs +++ b/src/bluez/adapter.rs @@ -33,7 +33,9 @@ fn get_central_state(powered: bool) -> CentralState { impl Central for Adapter { type Peripheral = Peripheral; - async fn events(&self) -> Result + Send>>> { + async fn events( + &self, + ) -> Result> + Send>>> { // There's a race between getting this event stream and getting the current set of devices. // Get the stream first, on the basis that it's better to have a duplicate DeviceDiscovered // event than to miss one. It's unlikely to happen in any case. @@ -145,7 +147,7 @@ async fn central_events( event: BluetoothEvent, session: BluetoothSession, adapter_id: AdapterId, -) -> Option> { +) -> Option>> { match event { BluetoothEvent::Device { id, diff --git a/src/bluez/peripheral.rs b/src/bluez/peripheral.rs index 2310aa1b..1a3b2adb 100644 --- a/src/bluez/peripheral.rs +++ b/src/bluez/peripheral.rs @@ -54,6 +54,8 @@ impl Display for PeripheralId { } } +impl crate::api::PeripheralId for PeripheralId {} + /// Implementation of [api::Peripheral](crate::api::Peripheral). #[derive(Clone, Debug)] pub struct Peripheral { @@ -130,6 +132,8 @@ impl Peripheral { #[async_trait] impl api::Peripheral for Peripheral { + type ID = PeripheralId; + fn id(&self) -> PeripheralId { PeripheralId(self.device.to_owned()) } diff --git a/src/common/adapter_manager.rs b/src/common/adapter_manager.rs index 7da91d66..c70f60c4 100644 --- a/src/common/adapter_manager.rs +++ b/src/common/adapter_manager.rs @@ -12,7 +12,6 @@ // // Copyright (c) 2014 The Rust Project Developers use crate::api::{CentralEvent, Peripheral}; -use crate::platform::PeripheralId; use dashmap::{DashMap, mapref::one::RefMut}; use futures::stream::{Stream, StreamExt}; use log::trace; @@ -25,8 +24,8 @@ pub struct AdapterManager where PeripheralType: Peripheral, { - peripherals: DashMap, - events_channel: broadcast::Sender, + peripherals: DashMap, + events_channel: broadcast::Sender>, } impl Default for AdapterManager { @@ -43,7 +42,7 @@ impl AdapterManager where PeripheralType: Peripheral + 'static, { - pub fn emit(&self, event: CentralEvent) { + pub fn emit(&self, event: CentralEvent) { if let CentralEvent::DeviceDisconnected(ref id) = event { self.peripherals.remove(id); } @@ -53,7 +52,9 @@ where } } - pub fn event_stream(&self) -> Pin + Send>> { + pub fn event_stream( + &self, + ) -> Pin> + Send>> { let receiver = self.events_channel.subscribe(); Box::pin(BroadcastStream::new(receiver).filter_map(|x| async move { x.ok() })) } @@ -81,12 +82,12 @@ where #[allow(dead_code)] pub fn peripheral_mut( &self, - id: &PeripheralId, - ) -> Option> { + id: &PeripheralType::ID, + ) -> Option> { self.peripherals.get_mut(id) } - pub fn peripheral(&self, id: &PeripheralId) -> Option { + pub fn peripheral(&self, id: &PeripheralType::ID) -> Option { self.peripherals.get(id).map(|val| val.value().clone()) } } diff --git a/src/corebluetooth/adapter.rs b/src/corebluetooth/adapter.rs index 0c489a28..37b14286 100644 --- a/src/corebluetooth/adapter.rs +++ b/src/corebluetooth/adapter.rs @@ -104,7 +104,9 @@ impl Adapter { impl Central for Adapter { type Peripheral = Peripheral; - async fn events(&self) -> Result + Send>>> { + async fn events( + &self, + ) -> Result> + Send>>> { Ok(self.manager.event_stream()) } diff --git a/src/corebluetooth/peripheral.rs b/src/corebluetooth/peripheral.rs index 229daaa6..01f5eac3 100644 --- a/src/corebluetooth/peripheral.rs +++ b/src/corebluetooth/peripheral.rs @@ -45,6 +45,8 @@ use uuid::Uuid; #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct PeripheralId(Uuid); +impl crate::api::PeripheralId for PeripheralId {} + impl Display for PeripheralId { fn fmt(&self, f: &mut Formatter) -> fmt::Result { Display::fmt(&self.0, f) @@ -71,7 +73,7 @@ struct Shared { } impl Shared { - fn emit_event(&self, event: CentralEvent) { + fn emit_event(&self, event: CentralEvent) { match self.manager.upgrade() { Some(manager) => { manager.emit(event); @@ -231,6 +233,8 @@ impl Debug for Peripheral { #[async_trait] impl api::Peripheral for Peripheral { + type ID = PeripheralId; + fn id(&self) -> PeripheralId { PeripheralId(self.shared.uuid) } diff --git a/src/droidplug/adapter.rs b/src/droidplug/adapter.rs index 5e0a4f2b..dbe7ca08 100644 --- a/src/droidplug/adapter.rs +++ b/src/droidplug/adapter.rs @@ -134,7 +134,9 @@ impl Central for Adapter { Ok("Android".to_string()) } - async fn events(&self) -> Result + Send>>> { + async fn events( + &self, + ) -> Result> + Send>>> { Ok(self.manager.event_stream()) } diff --git a/src/droidplug/peripheral.rs b/src/droidplug/peripheral.rs index 8554376e..5f6dfbd8 100644 --- a/src/droidplug/peripheral.rs +++ b/src/droidplug/peripheral.rs @@ -51,6 +51,8 @@ impl Display for PeripheralId { } } +impl crate::api::PeripheralId for PeripheralId {} + fn get_poll_result<'a: 'b, 'b>( env: &'b JNIEnv<'a>, result: JPollResult<'a, 'b>, @@ -229,7 +231,8 @@ impl Debug for Peripheral { #[async_trait] impl api::Peripheral for Peripheral { - /// Returns the unique identifier of the peripheral. + type ID = PeripheralId; + fn id(&self) -> PeripheralId { PeripheralId(self.addr) } diff --git a/src/winrtble/adapter.rs b/src/winrtble/adapter.rs index c4cba39d..a28e56b8 100644 --- a/src/winrtble/adapter.rs +++ b/src/winrtble/adapter.rs @@ -82,7 +82,9 @@ impl Debug for Adapter { impl Central for Adapter { type Peripheral = Peripheral; - async fn events(&self) -> Result + Send>>> { + async fn events( + &self, + ) -> Result> + Send>>> { Ok(self.manager.event_stream()) } diff --git a/src/winrtble/peripheral.rs b/src/winrtble/peripheral.rs index 7924d678..48740d94 100644 --- a/src/winrtble/peripheral.rs +++ b/src/winrtble/peripheral.rs @@ -63,6 +63,8 @@ impl Display for PeripheralId { } } +impl crate::api::PeripheralId for PeripheralId {} + /// Implementation of [api::Peripheral](crate::api::Peripheral). #[derive(Clone)] pub struct Peripheral { @@ -305,7 +307,7 @@ impl Peripheral { } } - fn emit_event(&self, event: CentralEvent) { + fn emit_event(&self, event: CentralEvent) { if let Some(manager) = self.shared.adapter.upgrade() { manager.emit(event); } else { @@ -354,6 +356,8 @@ impl Debug for Peripheral { #[async_trait] impl ApiPeripheral for Peripheral { + type ID = PeripheralId; + fn id(&self) -> PeripheralId { PeripheralId(self.shared.address) }