Skip to content

Add ScanFilter to Central::start_scan() #208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/discover_adapters_peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::error::Error;
use std::time::Duration;
use tokio::time;

use btleplug::api::{Central, Manager as _, Peripheral};
use btleplug::api::{Central, Manager as _, Peripheral, ScanFilter};
use btleplug::platform::Manager;

#[tokio::main]
Expand All @@ -21,7 +21,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
for adapter in adapter_list.iter() {
println!("Starting scan...");
adapter
.start_scan()
.start_scan(ScanFilter::default())
.await
.expect("Can't scan BLE adapter for connected devices...");
time::sleep(Duration::from_secs(10)).await;
Expand Down
4 changes: 2 additions & 2 deletions examples/event_driven_discovery.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// See the "macOS permissions note" in README.md before running this on macOS
// Big Sur or later.

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

// start scanning for devices
central.start_scan().await?;
central.start_scan(ScanFilter::default()).await?;

// Print based on whatever the event receiver outputs. Note that the event
// receiver blocks, so in a real program, this should be run in its own
Expand Down
6 changes: 4 additions & 2 deletions examples/lights.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// See the "macOS permissions note" in README.md before running this on macOS
// Big Sur or later.

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

// start scanning for devices
central.start_scan().await?;
central.start_scan(ScanFilter::default()).await?;
// instead of waiting, you can use central.event_receiver() to get a channel
// to listen for notifications on.
time::sleep(Duration::from_secs(2)).await;
Expand Down
5 changes: 2 additions & 3 deletions examples/subscribe_notify_characteristic.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// See the "macOS permissions note" in README.md before running this on macOS
// Big Sur or later.

use btleplug::api::CharPropFlags;
use btleplug::api::{Central, Manager as _, Peripheral};
use btleplug::api::{Central, CharPropFlags, Manager as _, Peripheral, ScanFilter};
use btleplug::platform::Manager;
use futures::stream::StreamExt;
use std::error::Error;
Expand All @@ -26,7 +25,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
for adapter in adapter_list.iter() {
println!("Starting scan...");
adapter
.start_scan()
.start_scan(ScanFilter::default())
.await
.expect("Can't scan BLE adapter for connected devices...");
time::sleep(Duration::from_secs(2)).await;
Expand Down
14 changes: 13 additions & 1 deletion src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ pub struct PeripheralProperties {
pub services: Vec<Uuid>,
}

/// The filter used when scanning for BLE devices.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct ScanFilter {
/// If the filter contains at least one service UUID, only devices supporting at least one of
/// the given services will be available.
pub services: Vec<Uuid>,
}

/// The type of write operation to use.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum WriteType {
Expand Down Expand Up @@ -299,7 +307,11 @@ pub trait Central: Send + Sync + Clone {
/// 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
/// to subscribers of `events` and will be available via `peripherals()`.
async fn start_scan(&self) -> Result<()>;
/// The filter can be used to scan only for specific devices. While some implementations might
/// ignore (parts of) the filter and make additional devices available, other implementations
/// might require at least one filter for security reasons. Cross-platform code should provide
/// a filter, but must be able to handle devices, which do not fit into the filter.
async fn start_scan(&self, filter: ScanFilter) -> Result<()>;

/// Stops scanning for BLE devices.
async fn stop_scan(&self) -> Result<()>;
Expand Down
5 changes: 3 additions & 2 deletions src/bluez/adapter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::peripheral::{Peripheral, PeripheralId};
use crate::api::{BDAddr, Central, CentralEvent};
use crate::api::{BDAddr, Central, CentralEvent, ScanFilter};
use crate::{Error, Result};
use async_trait::async_trait;
use bluez_async::{
Expand Down Expand Up @@ -46,8 +46,9 @@ impl Central for Adapter {
Ok(Box::pin(initial_events.chain(events)))
}

async fn start_scan(&self) -> Result<()> {
async fn start_scan(&self, filter: ScanFilter) -> Result<()> {
let filter = DiscoveryFilter {
service_uuids: filter.services,
transport: Some(Transport::Auto),
..Default::default()
};
Expand Down
6 changes: 3 additions & 3 deletions src/corebluetooth/adapter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::internal::{run_corebluetooth_thread, CoreBluetoothEvent, CoreBluetoothMessage};
use super::peripheral::{Peripheral, PeripheralId};
use crate::api::{BDAddr, Central, CentralEvent};
use crate::api::{BDAddr, Central, CentralEvent, ScanFilter};
use crate::common::adapter_manager::AdapterManager;
use crate::{Error, Result};
use async_trait::async_trait;
Expand Down Expand Up @@ -87,10 +87,10 @@ impl Central for Adapter {
Ok(self.manager.event_stream())
}

async fn start_scan(&self) -> Result<()> {
async fn start_scan(&self, filter: ScanFilter) -> Result<()> {
self.sender
.to_owned()
.send(CoreBluetoothMessage::StartScanning)
.send(CoreBluetoothMessage::StartScanning { filter })
.await?;
Ok(())
}
Expand Down
11 changes: 7 additions & 4 deletions src/corebluetooth/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use super::{
future::{BtlePlugFuture, BtlePlugFutureStateShared},
utils::{core_bluetooth::cbuuid_to_uuid, nsstring::nsstring_to_string, nsuuid_to_uuid},
};
use crate::api::{CharPropFlags, Characteristic, Service, WriteType};
use crate::api::{CharPropFlags, Characteristic, ScanFilter, Service, WriteType};
use crate::Error;
use futures::channel::mpsc::{self, Receiver, Sender};
use futures::select;
Expand Down Expand Up @@ -258,7 +258,9 @@ impl Debug for CoreBluetoothInternal {

#[derive(Debug)]
pub enum CoreBluetoothMessage {
StartScanning,
StartScanning {
filter: ScanFilter,
},
StopScanning,
ConnectDevice {
peripheral_uuid: Uuid,
Expand Down Expand Up @@ -762,7 +764,7 @@ impl CoreBluetoothInternal {
adapter_msg = self.message_receiver.select_next_some() => {
trace!("Adapter message!");
match adapter_msg {
CoreBluetoothMessage::StartScanning => self.start_discovery(),
CoreBluetoothMessage::StartScanning{filter} => self.start_discovery(filter),
CoreBluetoothMessage::StopScanning => self.stop_discovery(),
CoreBluetoothMessage::ConnectDevice{peripheral_uuid, future} => {
trace!("got connectdevice msg!");
Expand Down Expand Up @@ -793,14 +795,15 @@ impl CoreBluetoothInternal {
}
}

fn start_discovery(&mut self) {
fn start_discovery(&mut self, _filter: ScanFilter) {
trace!("BluetoothAdapter::start_discovery");
let options = ns::mutabledictionary();
// NOTE: If duplicates are not allowed then a peripheral will not show
// up again once connected and then disconnected.
ns::mutabledictionary_setobject_forkey(options, ns::number_withbool(YES), unsafe {
cb::CENTRALMANAGERSCANOPTIONALLOWDUPLICATESKEY
});
// TODO: set cb::CBCENTRALMANAGERSCANOPTIONSOLICITEDSERVICEUUIDSKEY with filter.services
cb::centralmanager_scanforperipherals_options(*self.manager, options);
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
//! An example of how to use the library to control some BLE smart lights:
//!
//! ```rust,no_run
//! use btleplug::api::{bleuuid::uuid_from_u16, Central, Manager as _, Peripheral as _, WriteType};
//! use btleplug::api::{bleuuid::uuid_from_u16, Central, Manager as _, Peripheral as _, ScanFilter, WriteType};
//! use btleplug::platform::{Adapter, Manager, Peripheral};
//! use rand::{Rng, thread_rng};
//! use std::error::Error;
Expand All @@ -40,7 +40,7 @@
//! let central = adapters.into_iter().nth(0).unwrap();
//!
//! // start scanning for devices
//! central.start_scan().await?;
//! central.start_scan(ScanFilter::default()).await?;
//! // instead of waiting, you can use central.event_receiver() to fetch a channel and
//! // be notified of new devices
//! time::sleep(Duration::from_secs(2)).await;
Expand Down
5 changes: 3 additions & 2 deletions src/winrtble/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

use super::{ble::watcher::BLEWatcher, peripheral::Peripheral, peripheral::PeripheralId};
use crate::{
api::{BDAddr, Central, CentralEvent},
api::{BDAddr, Central, CentralEvent, ScanFilter},
common::adapter_manager::AdapterManager,
Error, Result,
};
Expand Down Expand Up @@ -55,7 +55,8 @@ impl Central for Adapter {
Ok(self.manager.event_stream())
}

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