diff --git a/src/winrtble/adapter.rs b/src/winrtble/adapter.rs index a7348f8d..a7e33140 100644 --- a/src/winrtble/adapter.rs +++ b/src/winrtble/adapter.rs @@ -128,6 +128,16 @@ impl Adapter { _state_handler: state_handler, }) } + + /// Overrides whether the adapter is treated as supporting the Coded (long-range) PHY. + /// With `false`, scans never request Coded PHY. Some adapters that report support stop + /// delivering most 1M PHY advertisements with it enabled. Takes effect on the next + /// [`Central::start_scan`]. + pub fn set_coded_phy_supported(&self, supported: bool) -> Result<()> { + let mut watcher = self.watcher.lock().map_err(Into::::into)?; + watcher.set_coded_phy_supported(supported); + Ok(()) + } } #[cfg(test)] diff --git a/src/winrtble/ble/watcher.rs b/src/winrtble/ble/watcher.rs index c9564087..683faa57 100644 --- a/src/winrtble/ble/watcher.rs +++ b/src/winrtble/ble/watcher.rs @@ -25,9 +25,10 @@ pub type AdvertisementEventHandler = pub struct BLEWatcher { watcher: BluetoothLEAdvertisementWatcher, received_token: Option, - /// Whether the adapter reports Coded (long-range) PHY support. Only - /// then is `UseCodedPhy` requested: the setter succeeds on any adapter, - /// and on one without Coded PHY the scan starts but never reports. + /// Whether the adapter reports Coded (long-range) PHY support, unless + /// overridden by `Adapter::set_coded_phy_supported`. Only then is + /// `UseCodedPhy` requested: the setter succeeds on any adapter, and on + /// one without Coded PHY the scan starts but never reports. coded_phy_supported: bool, } @@ -65,6 +66,10 @@ impl BLEWatcher { }) } + pub fn set_coded_phy_supported(&mut self, supported: bool) { + self.coded_phy_supported = supported; + } + pub fn start( &mut self, filter: ScanFilter, @@ -87,10 +92,9 @@ impl BLEWatcher { // adapter supports it. `SetUseCodedPhy(true)` is accepted (and // `Start` succeeds) on adapters without Coded PHY as well, and the // scan then delivers no advertisements at all, so the capability - // check is the guard rather than the setter's result. - if self.coded_phy_supported { - let _ = self.watcher.SetUseCodedPhy(true); - } + // check is the guard rather than the setter's result. Set it on every + // scan: the watcher is reused and the flag can change between scans. + let _ = self.watcher.SetUseCodedPhy(self.coded_phy_supported); debug!( "extended scanning enabled; coded PHY {}", if self.coded_phy_supported {