Skip to content

Commit da4f29c

Browse files
committed
chore: Add type PeripheralId
Some platforms do not use a BDAddr to identify a specific device. This new type allows different platforms to use their own identifier.
1 parent 8719d7c commit da4f29c

File tree

9 files changed

+113
-85
lines changed

9 files changed

+113
-85
lines changed

src/api/mod.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ use uuid::Uuid;
4141

4242
pub use self::bdaddr::{BDAddr, ParseBDAddrError};
4343

44+
use crate::platform::PeripheralId;
45+
4446
#[cfg_attr(
4547
feature = "serde",
4648
derive(Serialize, Deserialize),
@@ -179,6 +181,9 @@ pub enum WriteType {
179181
/// as well as functions for communication.
180182
#[async_trait]
181183
pub trait Peripheral: Send + Sync + Clone + Debug {
184+
/// Returns the unique identifier of the peripheral.
185+
fn id(&self) -> PeripheralId;
186+
182187
/// Returns the MAC address of the peripheral.
183188
fn address(&self) -> BDAddr;
184189

@@ -237,23 +242,23 @@ pub trait Peripheral: Send + Sync + Clone + Debug {
237242
)]
238243
#[derive(Debug, Clone)]
239244
pub enum CentralEvent {
240-
DeviceDiscovered(BDAddr),
241-
DeviceUpdated(BDAddr),
242-
DeviceConnected(BDAddr),
243-
DeviceDisconnected(BDAddr),
245+
DeviceDiscovered(PeripheralId),
246+
DeviceUpdated(PeripheralId),
247+
DeviceConnected(PeripheralId),
248+
DeviceDisconnected(PeripheralId),
244249
/// Emitted when a Manufacturer Data advertisement has been received from a device
245250
ManufacturerDataAdvertisement {
246-
address: BDAddr,
251+
id: PeripheralId,
247252
manufacturer_data: HashMap<u16, Vec<u8>>,
248253
},
249254
/// Emitted when a Service Data advertisement has been received from a device
250255
ServiceDataAdvertisement {
251-
address: BDAddr,
256+
id: PeripheralId,
252257
service_data: HashMap<Uuid, Vec<u8>>,
253258
},
254259
/// Emitted when the advertised services for a device has been updated
255260
ServicesAdvertisement {
256-
address: BDAddr,
261+
id: PeripheralId,
257262
services: Vec<Uuid>,
258263
},
259264
}
@@ -281,7 +286,7 @@ pub trait Central: Send + Sync + Clone {
281286
async fn peripherals(&self) -> Result<Vec<Self::Peripheral>>;
282287

283288
/// Returns a particular [`Peripheral`] by its address if it has been discovered.
284-
async fn peripheral(&self, address: BDAddr) -> Result<Self::Peripheral>;
289+
async fn peripheral(&self, id: PeripheralId) -> Result<Self::Peripheral>;
285290

286291
/// Add a [`Peripheral`] from a MAC address without a scan result. Not supported on all Bluetooth systems.
287292
async fn add_peripheral(&self, address: BDAddr) -> Result<Self::Peripheral>;

src/bluez/adapter.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::peripheral::Peripheral;
1+
use super::peripheral::{Peripheral, PeripheralId};
22
use crate::api::{BDAddr, Central, CentralEvent};
33
use crate::{Error, Result};
44
use async_trait::async_trait;
@@ -37,7 +37,7 @@ impl Central for Adapter {
3737
let initial_events = stream::iter(
3838
devices
3939
.into_iter()
40-
.map(|device| CentralEvent::DeviceDiscovered(BDAddr::from(&device.mac_address))),
40+
.map(|device| CentralEvent::DeviceDiscovered((&device.mac_address).into())),
4141
);
4242

4343
let session = self.session.clone();
@@ -68,12 +68,12 @@ impl Central for Adapter {
6868
.collect())
6969
}
7070

71-
async fn peripheral(&self, address: BDAddr) -> Result<Peripheral> {
71+
async fn peripheral(&self, id: PeripheralId) -> Result<Peripheral> {
7272
let devices = self.session.get_devices().await?;
7373
devices
7474
.into_iter()
7575
.find_map(|device| {
76-
if BDAddr::from(&device.mac_address) == address {
76+
if PeripheralId::from(&device.mac_address) == id {
7777
Some(Peripheral::new(self.session.clone(), device))
7878
} else {
7979
None
@@ -130,7 +130,7 @@ async fn central_event(event: BluetoothEvent, session: BluetoothSession) -> Opti
130130
} => {
131131
let device = session.get_device_info(&id).await.ok()?;
132132
Some(CentralEvent::ManufacturerDataAdvertisement {
133-
address: (&device.mac_address).into(),
133+
id: (&device.mac_address).into(),
134134
manufacturer_data,
135135
})
136136
}
@@ -140,7 +140,7 @@ async fn central_event(event: BluetoothEvent, session: BluetoothSession) -> Opti
140140
} => {
141141
let device = session.get_device_info(&id).await.ok()?;
142142
Some(CentralEvent::ServiceDataAdvertisement {
143-
address: (&device.mac_address).into(),
143+
id: (&device.mac_address).into(),
144144
service_data,
145145
})
146146
}
@@ -150,7 +150,7 @@ async fn central_event(event: BluetoothEvent, session: BluetoothSession) -> Opti
150150
} => {
151151
let device = session.get_device_info(&id).await.ok()?;
152152
Some(CentralEvent::ServicesAdvertisement {
153-
address: (&device.mac_address).into(),
153+
id: (&device.mac_address).into(),
154154
services,
155155
})
156156
}

src/bluez/peripheral.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ use crate::api::{
1515
};
1616
use crate::{Error, Result};
1717

18+
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
19+
pub struct PeripheralId(BDAddr);
20+
1821
/// Implementation of [api::Peripheral](crate::api::Peripheral).
1922
#[derive(Clone, Debug)]
2023
pub struct Peripheral {
@@ -58,6 +61,10 @@ impl Peripheral {
5861

5962
#[async_trait]
6063
impl api::Peripheral for Peripheral {
64+
fn id(&self) -> PeripheralId {
65+
PeripheralId(self.address())
66+
}
67+
6168
fn address(&self) -> BDAddr {
6269
self.mac_address
6370
}
@@ -192,6 +199,12 @@ impl From<&MacAddress> for BDAddr {
192199
}
193200
}
194201

202+
impl From<&MacAddress> for PeripheralId {
203+
fn from(mac_address: &MacAddress) -> Self {
204+
PeripheralId(BDAddr::from(mac_address))
205+
}
206+
}
207+
195208
impl From<bluez_async::AddressType> for AddressType {
196209
fn from(address_type: bluez_async::AddressType) -> Self {
197210
match address_type {

src/common/adapter_manager.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
// following copyright:
1212
//
1313
// Copyright (c) 2014 The Rust Project Developers
14-
use crate::api::{BDAddr, CentralEvent, Peripheral};
14+
use crate::api::{CentralEvent, Peripheral};
15+
use crate::platform::PeripheralId;
1516
use dashmap::{mapref::one::RefMut, DashMap};
1617
use futures::stream::{Stream, StreamExt};
1718
use log::trace;
@@ -30,7 +31,7 @@ where
3031

3132
#[derive(Debug)]
3233
struct Shared<PeripheralType> {
33-
peripherals: DashMap<BDAddr, PeripheralType>,
34+
peripherals: DashMap<PeripheralId, PeripheralType>,
3435
events_channel: broadcast::Sender<CentralEvent>,
3536
}
3637

@@ -52,8 +53,8 @@ where
5253
{
5354
pub fn emit(&self, event: CentralEvent) {
5455
match event {
55-
CentralEvent::DeviceDisconnected(ref addr) => {
56-
self.shared.peripherals.remove(addr);
56+
CentralEvent::DeviceDisconnected(ref id) => {
57+
self.shared.peripherals.remove(id);
5758
}
5859
_ => {}
5960
}
@@ -74,13 +75,12 @@ where
7475
}))
7576
}
7677

77-
pub fn add_peripheral(&self, addr: BDAddr, peripheral: PeripheralType) {
78+
pub fn add_peripheral(&self, peripheral: PeripheralType) {
7879
assert!(
79-
!self.shared.peripherals.contains_key(&addr),
80+
!self.shared.peripherals.contains_key(&peripheral.id()),
8081
"Adding a peripheral that's already in the map."
8182
);
82-
assert_eq!(peripheral.address(), addr, "Device has unexpected address."); // TODO remove addr argument
83-
self.shared.peripherals.insert(addr, peripheral);
83+
self.shared.peripherals.insert(peripheral.id(), peripheral);
8484
}
8585

8686
pub fn peripherals(&self) -> Vec<PeripheralType> {
@@ -91,14 +91,14 @@ where
9191
.collect()
9292
}
9393

94-
pub fn peripheral_mut(&self, address: BDAddr) -> Option<RefMut<BDAddr, PeripheralType>> {
95-
self.shared.peripherals.get_mut(&address)
94+
pub fn peripheral_mut(&self, id: PeripheralId) -> Option<RefMut<PeripheralId, PeripheralType>> {
95+
self.shared.peripherals.get_mut(&id)
9696
}
9797

98-
pub fn peripheral(&self, address: BDAddr) -> Option<PeripheralType> {
98+
pub fn peripheral(&self, id: PeripheralId) -> Option<PeripheralType> {
9999
self.shared
100100
.peripherals
101-
.get(&address)
101+
.get(&id)
102102
.map(|val| val.value().clone())
103103
}
104104
}

src/corebluetooth/adapter.rs

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::internal::{run_corebluetooth_thread, CoreBluetoothEvent, CoreBluetoothMessage};
2-
use super::peripheral::Peripheral;
2+
use super::peripheral::{Peripheral, PeripheralId};
33
use crate::api::{BDAddr, Central, CentralEvent};
44
use crate::common::adapter_manager::AdapterManager;
55
use crate::{Error, Result};
@@ -19,11 +19,6 @@ pub struct Adapter {
1919
sender: Sender<CoreBluetoothMessage>,
2020
}
2121

22-
pub(crate) fn uuid_to_bdaddr(uuid: &str) -> BDAddr {
23-
let b: [u8; 6] = uuid.as_bytes()[0..6].try_into().unwrap();
24-
BDAddr::try_from(b).unwrap()
25-
}
26-
2722
impl Adapter {
2823
pub(crate) async fn new() -> Result<Self> {
2924
let (sender, mut receiver) = mpsc::channel(256);
@@ -53,31 +48,24 @@ impl Adapter {
5348
name,
5449
event_receiver,
5550
} => {
56-
// TODO Gotta change uuid into a BDAddr for now. Expand
57-
// library identifier type. :(
58-
let id = uuid_to_bdaddr(&uuid.to_string());
59-
manager_clone.add_peripheral(
60-
id,
61-
Peripheral::new(
62-
uuid,
63-
name,
64-
manager_clone.clone(),
65-
event_receiver,
66-
adapter_sender_clone.clone(),
67-
),
68-
);
69-
manager_clone.emit(CentralEvent::DeviceDiscovered(id));
51+
manager_clone.add_peripheral(Peripheral::new(
52+
uuid,
53+
name,
54+
manager_clone.clone(),
55+
event_receiver,
56+
adapter_sender_clone.clone(),
57+
));
58+
manager_clone.emit(CentralEvent::DeviceDiscovered(uuid.into()));
7059
}
7160
CoreBluetoothEvent::DeviceUpdated { uuid, name } => {
72-
let id = uuid_to_bdaddr(&uuid.to_string());
61+
let id = uuid.into();
7362
if let Some(entry) = manager_clone.peripheral_mut(id) {
7463
entry.value().update_name(&name);
75-
manager_clone.emit(CentralEvent::DeviceUpdated(id));
64+
manager_clone.emit(CentralEvent::DeviceUpdated(uuid.into()));
7665
}
7766
}
7867
CoreBluetoothEvent::DeviceDisconnected { uuid } => {
79-
let id = uuid_to_bdaddr(&uuid.to_string());
80-
manager_clone.emit(CentralEvent::DeviceDisconnected(id));
68+
manager_clone.emit(CentralEvent::DeviceDisconnected(uuid.into()));
8169
}
8270
_ => {}
8371
}
@@ -119,10 +107,8 @@ impl Central for Adapter {
119107
Ok(self.manager.peripherals())
120108
}
121109

122-
async fn peripheral(&self, address: BDAddr) -> Result<Peripheral> {
123-
self.manager
124-
.peripheral(address)
125-
.ok_or(Error::DeviceNotFound)
110+
async fn peripheral(&self, id: PeripheralId) -> Result<Peripheral> {
111+
self.manager.peripheral(id).ok_or(Error::DeviceNotFound)
126112
}
127113

128114
async fn add_peripheral(&self, _address: BDAddr) -> Result<Peripheral> {

src/corebluetooth/peripheral.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// for full license information.
77

88
use super::{
9-
adapter::uuid_to_bdaddr,
109
framework::cb::CBPeripheralState,
1110
internal::{
1211
CBPeripheralEvent, CoreBluetoothMessage, CoreBluetoothReply, CoreBluetoothReplyFuture,
@@ -35,6 +34,9 @@ use tokio::sync::broadcast;
3534
use tokio::task;
3635
use uuid::Uuid;
3736

37+
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
38+
pub struct PeripheralId(Uuid);
39+
3840
/// Implementation of [api::Peripheral](crate::api::Peripheral).
3941
#[derive(Clone)]
4042
pub struct Peripheral {
@@ -65,9 +67,7 @@ impl Peripheral {
6567
// Since we're building the object, we have an active advertisement.
6668
// Build properties now.
6769
let properties = Mutex::from(PeripheralProperties {
68-
// Rumble required ONLY a BDAddr, not something you can get from
69-
// MacOS, so we make it up for now. This sucks.
70-
address: uuid_to_bdaddr(&uuid.to_string()),
70+
address: BDAddr::default(),
7171
address_type: None,
7272
local_name,
7373
tx_power_level: None,
@@ -108,7 +108,7 @@ impl Peripheral {
108108
shared
109109
.manager
110110
.emit(CentralEvent::ManufacturerDataAdvertisement {
111-
address: properties.address,
111+
id: shared.uuid.into(),
112112
manufacturer_data: properties.manufacturer_data.clone(),
113113
});
114114
}
@@ -117,7 +117,7 @@ impl Peripheral {
117117
properties.service_data.extend(service_data.clone());
118118

119119
shared.manager.emit(CentralEvent::ServiceDataAdvertisement {
120-
address: properties.address,
120+
id: shared.uuid.into(),
121121
service_data,
122122
});
123123
}
@@ -126,7 +126,7 @@ impl Peripheral {
126126
properties.services = services.clone();
127127

128128
shared.manager.emit(CentralEvent::ServicesAdvertisement {
129-
address: properties.address,
129+
id: shared.uuid.into(),
130130
services,
131131
});
132132
}
@@ -169,10 +169,12 @@ impl Debug for Peripheral {
169169

170170
#[async_trait]
171171
impl api::Peripheral for Peripheral {
172+
fn id(&self) -> PeripheralId {
173+
PeripheralId(self.shared.uuid)
174+
}
175+
172176
fn address(&self) -> BDAddr {
173-
// TODO: look at moving/copying address out of properties so we don't have to
174-
// take a lock here! (the address for the peripheral won't ever change)
175-
self.shared.properties.lock().unwrap().address
177+
BDAddr::default()
176178
}
177179

178180
async fn properties(&self) -> Result<Option<PeripheralProperties>> {
@@ -215,11 +217,9 @@ impl api::Peripheral for Peripheral {
215217
match fut.await {
216218
CoreBluetoothReply::Connected(chars) => {
217219
*(self.shared.characteristics.lock().unwrap()) = chars;
218-
self.shared.manager.emit(CentralEvent::DeviceConnected(
219-
// TODO: look at moving/copying address out of properties so we don't have to
220-
// take a lock here! (the address for the peripheral won't ever change)
221-
self.shared.properties.lock().unwrap().address,
222-
));
220+
self.shared
221+
.manager
222+
.emit(CentralEvent::DeviceConnected(self.shared.uuid.into()));
223223
}
224224
_ => panic!("Shouldn't get anything but connected!"),
225225
}
@@ -333,6 +333,12 @@ impl api::Peripheral for Peripheral {
333333
}
334334
}
335335

336+
impl From<Uuid> for PeripheralId {
337+
fn from(uuid: Uuid) -> Self {
338+
PeripheralId(uuid)
339+
}
340+
}
341+
336342
impl From<SendError> for Error {
337343
fn from(_: SendError) -> Self {
338344
Error::Other("Channel closed".to_string().into())

0 commit comments

Comments
 (0)