Skip to content

Commit 15b45b9

Browse files
parogaqwandor
authored andcommitted
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 8467787 commit 15b45b9

File tree

10 files changed

+159
-107
lines changed

10 files changed

+159
-107
lines changed

examples/event_driven_discovery.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,37 +40,31 @@ async fn main() -> Result<(), Box<dyn Error>> {
4040
// thread (not task, as this library does not yet use async channels).
4141
while let Some(event) = events.next().await {
4242
match event {
43-
CentralEvent::DeviceDiscovered(bd_addr) => {
44-
println!("DeviceDiscovered: {:?}", bd_addr);
43+
CentralEvent::DeviceDiscovered(id) => {
44+
println!("DeviceDiscovered: {:?}", id);
4545
}
46-
CentralEvent::DeviceConnected(bd_addr) => {
47-
println!("DeviceConnected: {:?}", bd_addr);
46+
CentralEvent::DeviceConnected(id) => {
47+
println!("DeviceConnected: {:?}", id);
4848
}
49-
CentralEvent::DeviceDisconnected(bd_addr) => {
50-
println!("DeviceDisconnected: {:?}", bd_addr);
49+
CentralEvent::DeviceDisconnected(id) => {
50+
println!("DeviceDisconnected: {:?}", id);
5151
}
5252
CentralEvent::ManufacturerDataAdvertisement {
53-
address,
53+
id,
5454
manufacturer_data,
5555
} => {
5656
println!(
5757
"ManufacturerDataAdvertisement: {:?}, {:?}",
58-
address, manufacturer_data
58+
id, manufacturer_data
5959
);
6060
}
61-
CentralEvent::ServiceDataAdvertisement {
62-
address,
63-
service_data,
64-
} => {
65-
println!(
66-
"ServiceDataAdvertisement: {:?}, {:?}",
67-
address, service_data
68-
);
61+
CentralEvent::ServiceDataAdvertisement { id, service_data } => {
62+
println!("ServiceDataAdvertisement: {:?}, {:?}", id, service_data);
6963
}
70-
CentralEvent::ServicesAdvertisement { address, services } => {
64+
CentralEvent::ServicesAdvertisement { id, services } => {
7165
let services: Vec<String> =
7266
services.into_iter().map(|s| s.to_short_string()).collect();
73-
println!("ServicesAdvertisement: {:?}, {:?}", address, services);
67+
println!("ServicesAdvertisement: {:?}, {:?}", id, services);
7468
}
7569
_ => {}
7670
}

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),
@@ -193,6 +195,9 @@ pub enum WriteType {
193195
/// as well as functions for communication.
194196
#[async_trait]
195197
pub trait Peripheral: Send + Sync + Clone + Debug {
198+
/// Returns the unique identifier of the peripheral.
199+
fn id(&self) -> PeripheralId;
200+
196201
/// Returns the MAC address of the peripheral.
197202
fn address(&self) -> BDAddr;
198203

@@ -260,23 +265,23 @@ pub trait Peripheral: Send + Sync + Clone + Debug {
260265
)]
261266
#[derive(Debug, Clone)]
262267
pub enum CentralEvent {
263-
DeviceDiscovered(BDAddr),
264-
DeviceUpdated(BDAddr),
265-
DeviceConnected(BDAddr),
266-
DeviceDisconnected(BDAddr),
268+
DeviceDiscovered(PeripheralId),
269+
DeviceUpdated(PeripheralId),
270+
DeviceConnected(PeripheralId),
271+
DeviceDisconnected(PeripheralId),
267272
/// Emitted when a Manufacturer Data advertisement has been received from a device
268273
ManufacturerDataAdvertisement {
269-
address: BDAddr,
274+
id: PeripheralId,
270275
manufacturer_data: HashMap<u16, Vec<u8>>,
271276
},
272277
/// Emitted when a Service Data advertisement has been received from a device
273278
ServiceDataAdvertisement {
274-
address: BDAddr,
279+
id: PeripheralId,
275280
service_data: HashMap<Uuid, Vec<u8>>,
276281
},
277282
/// Emitted when the advertised services for a device has been updated
278283
ServicesAdvertisement {
279-
address: BDAddr,
284+
id: PeripheralId,
280285
services: Vec<Uuid>,
281286
},
282287
}
@@ -304,7 +309,7 @@ pub trait Central: Send + Sync + Clone {
304309
async fn peripherals(&self) -> Result<Vec<Self::Peripheral>>;
305310

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

309314
/// Add a [`Peripheral`] from a MAC address without a scan result. Not supported on all Bluetooth systems.
310315
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: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ use bluez_async::{
55
};
66
use futures::future::ready;
77
use futures::stream::{Stream, StreamExt};
8+
#[cfg(feature = "serde")]
9+
use serde::{Deserialize, Serialize};
10+
#[cfg(feature = "serde")]
11+
use serde_cr as serde;
812
use std::collections::{BTreeSet, HashMap};
913
use std::pin::Pin;
1014
use std::sync::{Arc, Mutex};
@@ -22,6 +26,14 @@ struct ServiceInternal {
2226
characteristics: HashMap<Uuid, CharacteristicInfo>,
2327
}
2428

29+
#[cfg_attr(
30+
feature = "serde",
31+
derive(Serialize, Deserialize),
32+
serde(crate = "serde_cr")
33+
)]
34+
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
35+
pub struct PeripheralId(BDAddr);
36+
2537
/// Implementation of [api::Peripheral](crate::api::Peripheral).
2638
#[derive(Clone, Debug)]
2739
pub struct Peripheral {
@@ -75,6 +87,10 @@ impl Peripheral {
7587

7688
#[async_trait]
7789
impl api::Peripheral for Peripheral {
90+
fn id(&self) -> PeripheralId {
91+
PeripheralId(self.address())
92+
}
93+
7894
fn address(&self) -> BDAddr {
7995
self.mac_address
8096
}
@@ -229,6 +245,12 @@ impl From<&MacAddress> for BDAddr {
229245
}
230246
}
231247

248+
impl From<&MacAddress> for PeripheralId {
249+
fn from(mac_address: &MacAddress) -> Self {
250+
PeripheralId(BDAddr::from(mac_address))
251+
}
252+
}
253+
232254
impl From<bluez_async::AddressType> for AddressType {
233255
fn from(address_type: bluez_async::AddressType) -> Self {
234256
match address_type {

src/common/adapter_manager.rs

Lines changed: 15 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,17 @@ 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(
95+
&self,
96+
id: &PeripheralId,
97+
) -> Option<RefMut<PeripheralId, PeripheralType>> {
98+
self.shared.peripherals.get_mut(id)
9699
}
97100

98-
pub fn peripheral(&self, address: BDAddr) -> Option<PeripheralType> {
101+
pub fn peripheral(&self, id: &PeripheralId) -> Option<PeripheralType> {
99102
self.shared
100103
.peripherals
101-
.get(&address)
104+
.get(id)
102105
.map(|val| val.value().clone())
103106
}
104107
}

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());
73-
if let Some(entry) = manager_clone.peripheral_mut(id) {
61+
let id = uuid.into();
62+
if let Some(entry) = manager_clone.peripheral_mut(&id) {
7463
entry.value().update_name(&name);
7564
manager_clone.emit(CentralEvent::DeviceUpdated(id));
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> {

0 commit comments

Comments
 (0)