btleplug/winrtble/ble/
watcher.rs1use crate::{api::ScanFilter, Error, Result};
15use windows::{Devices::Bluetooth::Advertisement::*, Foundation::TypedEventHandler};
16
17pub type AdvertismentEventHandler = Box<dyn Fn(&BluetoothLEAdvertisementReceivedEventArgs) + Send>;
18
19pub struct BLEWatcher {
20 watcher: BluetoothLEAdvertisementWatcher,
21}
22
23impl From<windows::core::Error> for Error {
24 fn from(err: windows::core::Error) -> Error {
25 Error::Other(format!("{:?}", err).into())
26 }
27}
28
29impl BLEWatcher {
30 pub fn new() -> Self {
31 let ad = BluetoothLEAdvertisementFilter::new().unwrap();
32 let watcher = BluetoothLEAdvertisementWatcher::Create(&ad).unwrap();
33 BLEWatcher { watcher }
34 }
35
36 pub fn start(&self, filter: ScanFilter, on_received: AdvertismentEventHandler) -> Result<()> {
37 let ScanFilter { services } = filter;
38 let ad = self
39 .watcher
40 .AdvertisementFilter()
41 .unwrap()
42 .Advertisement()
43 .unwrap();
44 let ad_services = ad.ServiceUuids().unwrap();
45 ad_services.Clear().unwrap();
46 for service in services {
47 ad_services
48 .Append(windows::core::GUID::from(service.as_u128()))
49 .unwrap();
50 }
51 self.watcher
52 .SetScanningMode(BluetoothLEScanningMode::Active)
53 .unwrap();
54 self.watcher.SetAllowExtendedAdvertisements(true)?;
55 let handler: TypedEventHandler<
56 BluetoothLEAdvertisementWatcher,
57 BluetoothLEAdvertisementReceivedEventArgs,
58 > = TypedEventHandler::new(
59 move |_sender, args: &Option<BluetoothLEAdvertisementReceivedEventArgs>| {
60 if let Some(args) = args {
61 on_received(args);
62 }
63 Ok(())
64 },
65 );
66
67 self.watcher.Received(&handler)?;
68 self.watcher.Start()?;
69 Ok(())
70 }
71
72 pub fn stop(&self) -> Result<()> {
73 self.watcher.Stop()?;
74 Ok(())
75 }
76}