Skip to content

Commit dca2adc

Browse files
committed
Add ScanFilter to Central::start_scan()
1 parent 15b45b9 commit dca2adc

10 files changed

+41
-23
lines changed

examples/discover_adapters_peripherals.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::error::Error;
55
use std::time::Duration;
66
use tokio::time;
77

8-
use btleplug::api::{Central, Manager as _, Peripheral};
8+
use btleplug::api::{Central, Manager as _, Peripheral, ScanFilter};
99
use btleplug::platform::Manager;
1010

1111
#[tokio::main]
@@ -21,7 +21,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
2121
for adapter in adapter_list.iter() {
2222
println!("Starting scan...");
2323
adapter
24-
.start_scan()
24+
.start_scan(ScanFilter::default())
2525
.await
2626
.expect("Can't scan BLE adapter for connected devices...");
2727
time::sleep(Duration::from_secs(10)).await;

examples/event_driven_discovery.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// See the "macOS permissions note" in README.md before running this on macOS
22
// Big Sur or later.
33

4-
use btleplug::api::{bleuuid::BleUuid, Central, CentralEvent, Manager as _};
4+
use btleplug::api::{bleuuid::BleUuid, Central, CentralEvent, Manager as _, ScanFilter};
55
use btleplug::platform::{Adapter, Manager};
66
use futures::stream::StreamExt;
77
use std::error::Error;
@@ -33,7 +33,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
3333
let mut events = central.events().await?;
3434

3535
// start scanning for devices
36-
central.start_scan().await?;
36+
central.start_scan(ScanFilter::default()).await?;
3737

3838
// Print based on whatever the event receiver outputs. Note that the event
3939
// receiver blocks, so in a real program, this should be run in its own

examples/lights.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// See the "macOS permissions note" in README.md before running this on macOS
22
// Big Sur or later.
33

4-
use btleplug::api::{bleuuid::uuid_from_u16, Central, Manager as _, Peripheral as _, WriteType};
4+
use btleplug::api::{
5+
bleuuid::uuid_from_u16, Central, Manager as _, Peripheral as _, ScanFilter, WriteType,
6+
};
57
use btleplug::platform::{Adapter, Manager, Peripheral};
68
use rand::{thread_rng, Rng};
79
use std::error::Error;
@@ -43,7 +45,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
4345
.expect("Unable to find adapters.");
4446

4547
// start scanning for devices
46-
central.start_scan().await?;
48+
central.start_scan(ScanFilter::default()).await?;
4749
// instead of waiting, you can use central.event_receiver() to get a channel
4850
// to listen for notifications on.
4951
time::sleep(Duration::from_secs(2)).await;

examples/subscribe_notify_characteristic.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// See the "macOS permissions note" in README.md before running this on macOS
22
// Big Sur or later.
33

4-
use btleplug::api::CharPropFlags;
5-
use btleplug::api::{Central, Manager as _, Peripheral};
4+
use btleplug::api::{Central, CharPropFlags, Manager as _, Peripheral, ScanFilter};
65
use btleplug::platform::Manager;
76
use futures::stream::StreamExt;
87
use std::error::Error;
@@ -26,7 +25,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
2625
for adapter in adapter_list.iter() {
2726
println!("Starting scan...");
2827
adapter
29-
.start_scan()
28+
.start_scan(ScanFilter::default())
3029
.await
3130
.expect("Can't scan BLE adapter for connected devices...");
3231
time::sleep(Duration::from_secs(2)).await;

src/api/mod.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,14 @@ pub struct PeripheralProperties {
180180
pub services: Vec<Uuid>,
181181
}
182182

183+
/// The filter used when scanning for BLE devices.
184+
#[derive(Debug, Default, Clone)]
185+
pub struct ScanFilter {
186+
/// If the filter contains at least one service UUID, only devices supporting at least one of
187+
/// the given services will be available.
188+
pub services: Vec<Uuid>,
189+
}
190+
183191
/// The type of write operation to use.
184192
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
185193
pub enum WriteType {
@@ -299,7 +307,11 @@ pub trait Central: Send + Sync + Clone {
299307
/// Starts a scan for BLE devices. This scan will generally continue until explicitly stopped,
300308
/// although this may depend on your Bluetooth adapter. Discovered devices will be announced
301309
/// to subscribers of `events` and will be available via `peripherals()`.
302-
async fn start_scan(&self) -> Result<()>;
310+
/// The filter can be used to scan only for specific devices. While some implementations migth
311+
/// ignore (parts of) the filter and make additional devices available, other implementations
312+
/// might require at least one filter for security reasons. Cross-platform code should provide
313+
/// a filter, but must be able to handle devices, which do not fit into the filter.
314+
async fn start_scan(&self, filter: ScanFilter) -> Result<()>;
303315

304316
/// Stops scanning for BLE devices.
305317
async fn stop_scan(&self) -> Result<()>;

src/bluez/adapter.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::peripheral::{Peripheral, PeripheralId};
2-
use crate::api::{BDAddr, Central, CentralEvent};
2+
use crate::api::{BDAddr, Central, CentralEvent, ScanFilter};
33
use crate::{Error, Result};
44
use async_trait::async_trait;
55
use bluez_async::{
@@ -46,8 +46,9 @@ impl Central for Adapter {
4646
Ok(Box::pin(initial_events.chain(events)))
4747
}
4848

49-
async fn start_scan(&self) -> Result<()> {
49+
async fn start_scan(&self, filter: ScanFilter) -> Result<()> {
5050
let filter = DiscoveryFilter {
51+
service_uuids: filter.services,
5152
transport: Some(Transport::Auto),
5253
..Default::default()
5354
};

src/corebluetooth/adapter.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::internal::{run_corebluetooth_thread, CoreBluetoothEvent, CoreBluetoothMessage};
22
use super::peripheral::{Peripheral, PeripheralId};
3-
use crate::api::{BDAddr, Central, CentralEvent};
3+
use crate::api::{BDAddr, Central, CentralEvent, ScanFilter};
44
use crate::common::adapter_manager::AdapterManager;
55
use crate::{Error, Result};
66
use async_trait::async_trait;
@@ -87,10 +87,10 @@ impl Central for Adapter {
8787
Ok(self.manager.event_stream())
8888
}
8989

90-
async fn start_scan(&self) -> Result<()> {
90+
async fn start_scan(&self, filter: ScanFilter) -> Result<()> {
9191
self.sender
9292
.to_owned()
93-
.send(CoreBluetoothMessage::StartScanning)
93+
.send(CoreBluetoothMessage::StartScanning { filter })
9494
.await?;
9595
Ok(())
9696
}

src/corebluetooth/internal.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use super::{
1717
future::{BtlePlugFuture, BtlePlugFutureStateShared},
1818
utils::{core_bluetooth::cbuuid_to_uuid, nsstring::nsstring_to_string, nsuuid_to_uuid},
1919
};
20-
use crate::api::{CharPropFlags, Characteristic, Service, WriteType};
20+
use crate::api::{CharPropFlags, Characteristic, ScanFilter, Service, WriteType};
2121
use crate::Error;
2222
use futures::channel::mpsc::{self, Receiver, Sender};
2323
use futures::select;
@@ -258,7 +258,9 @@ impl Debug for CoreBluetoothInternal {
258258

259259
#[derive(Debug)]
260260
pub enum CoreBluetoothMessage {
261-
StartScanning,
261+
StartScanning {
262+
filter: ScanFilter,
263+
},
262264
StopScanning,
263265
ConnectDevice {
264266
peripheral_uuid: Uuid,
@@ -762,7 +764,7 @@ impl CoreBluetoothInternal {
762764
adapter_msg = self.message_receiver.select_next_some() => {
763765
trace!("Adapter message!");
764766
match adapter_msg {
765-
CoreBluetoothMessage::StartScanning => self.start_discovery(),
767+
CoreBluetoothMessage::StartScanning{filter} => self.start_discovery(filter),
766768
CoreBluetoothMessage::StopScanning => self.stop_discovery(),
767769
CoreBluetoothMessage::ConnectDevice{peripheral_uuid, future} => {
768770
trace!("got connectdevice msg!");
@@ -793,14 +795,15 @@ impl CoreBluetoothInternal {
793795
}
794796
}
795797

796-
fn start_discovery(&mut self) {
798+
fn start_discovery(&mut self, _filter: ScanFilter) {
797799
trace!("BluetoothAdapter::start_discovery");
798800
let options = ns::mutabledictionary();
799801
// NOTE: If duplicates are not allowed then a peripheral will not show
800802
// up again once connected and then disconnected.
801803
ns::mutabledictionary_setobject_forkey(options, ns::number_withbool(YES), unsafe {
802804
cb::CENTRALMANAGERSCANOPTIONALLOWDUPLICATESKEY
803805
});
806+
// TODO: set cb::CBCENTRALMANAGERSCANOPTIONSOLICITEDSERVICEUUIDSKEY with filter.services
804807
cb::centralmanager_scanforperipherals_options(*self.manager, options);
805808
}
806809

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
//! An example of how to use the library to control some BLE smart lights:
2121
//!
2222
//! ```rust,no_run
23-
//! use btleplug::api::{bleuuid::uuid_from_u16, Central, Manager as _, Peripheral as _, WriteType};
23+
//! use btleplug::api::{bleuuid::uuid_from_u16, Central, Manager as _, Peripheral as _, ScanFilter, WriteType};
2424
//! use btleplug::platform::{Adapter, Manager, Peripheral};
2525
//! use rand::{Rng, thread_rng};
2626
//! use std::error::Error;
@@ -40,7 +40,7 @@
4040
//! let central = adapters.into_iter().nth(0).unwrap();
4141
//!
4242
//! // start scanning for devices
43-
//! central.start_scan().await?;
43+
//! central.start_scan(ScanFilter::default()).await?;
4444
//! // instead of waiting, you can use central.event_receiver() to fetch a channel and
4545
//! // be notified of new devices
4646
//! time::sleep(Duration::from_secs(2)).await;

src/winrtble/adapter.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
use super::{ble::watcher::BLEWatcher, peripheral::Peripheral, peripheral::PeripheralId};
1515
use crate::{
16-
api::{BDAddr, Central, CentralEvent},
16+
api::{BDAddr, Central, CentralEvent, ScanFilter},
1717
common::adapter_manager::AdapterManager,
1818
Error, Result,
1919
};
@@ -55,7 +55,8 @@ impl Central for Adapter {
5555
Ok(self.manager.event_stream())
5656
}
5757

58-
async fn start_scan(&self) -> Result<()> {
58+
async fn start_scan(&self, _filter: ScanFilter) -> Result<()> {
59+
// TODO: implement filter
5960
let watcher = self.watcher.lock().unwrap();
6061
let manager = self.manager.clone();
6162
watcher.start(Box::new(move |args| {

0 commit comments

Comments
 (0)