Loading system/gd/rust/linux/stack/src/bluetooth_gatt.rs +59 −21 Original line number Diff line number Diff line Loading @@ -33,7 +33,7 @@ use num_traits::clamp; use rand::rngs::SmallRng; use rand::{RngCore, SeedableRng}; use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use std::convert::{TryFrom, TryInto}; use std::sync::{Arc, Mutex, MutexGuard}; use tokio::sync::mpsc::Sender; use tokio::time; Loading Loading @@ -1145,7 +1145,7 @@ impl Default for GattWriteType { } } #[derive(Debug, FromPrimitive, ToPrimitive)] #[derive(Debug, FromPrimitive, ToPrimitive, Clone)] #[repr(u32)] /// Scan type configuration. pub enum ScanType { Loading @@ -1163,13 +1163,31 @@ impl Default for ScanType { /// /// This configuration is general and supported on all Bluetooth hardware, irrelevant of the /// hardware filter offload (APCF or MSFT). #[derive(Debug, Default)] #[derive(Debug, Clone)] pub struct ScanSettings { pub interval: i32, pub window: i32, pub scan_type: ScanType, } impl ScanSettings { fn extract_scan_parameters(self) -> Option<(u16, u16)> { let interval = u16::try_from(self.interval); if interval.is_err() { println!("Invalid scan interval {}", self.interval); return None; } let window = u16::try_from(self.window); if window.is_err() { println!("Invalid scan window {}", self.window); return None; } return Some((interval.unwrap(), window.unwrap())); } } /// Represents scan result #[derive(Debug)] pub struct ScanResult { Loading Loading @@ -1313,13 +1331,22 @@ impl GattAsyncIntf { /// /// Note: this does not need to be async, but declared as async for consistency in this struct. /// May be converted into real async in the future if btif supports it. async fn update_scan(&mut self) { async fn update_scan(&mut self, scanner_id: u8, scan_settings: Option<ScanSettings>) { if self.scanners.lock().unwrap().values().find(|scanner| scanner.is_active).is_some() { // Toggle the scan off and on so that we reset the scan parameters based on whether // we have active scanners using hardware filtering. // TODO(b/266752123): We can do more bookkeeping to optimize when we really need to // toggle. Also improve toggling API into 1 operation that guarantees correct ordering. self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan(); if let Some(settings) = scan_settings { if let Some((scan_interval, scan_window)) = settings.extract_scan_parameters() { self.gatt.as_ref().unwrap().lock().unwrap().scanner.set_scan_parameters( scanner_id, scan_interval, scan_window, ); } } self.gatt.as_ref().unwrap().lock().unwrap().scanner.start_scan(); } else { self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan(); Loading Loading @@ -1681,7 +1708,10 @@ impl BluetoothGatt { } } gatt_async.update_scan().await; let scan_settings = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) .map_or(None, |s| s.scan_settings.clone()); gatt_async.update_scan(scanner_id, scan_settings).await; }); BtStatus::Success Loading Loading @@ -1768,22 +1798,13 @@ impl BluetoothGatt { /// Start an active scan on given scanner id. This will look up and assign /// the correct ScanSettings for it as well. pub(crate) fn start_active_scan(&mut self, scanner_id: u8) -> BtStatus { let interval: u16 = sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval) .try_into() .expect("Bad value configured for LeInquiryScanInterval"); let window: u16 = sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow) .try_into() .expect("Bad value configured for LeInquiryScanWindow"); self.gatt .as_ref() .unwrap() .lock() .unwrap() .scanner .set_scan_parameters(scanner_id, interval, window); let settings = ScanSettings { interval: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval), window: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow), scan_type: ScanType::Active, }; self.start_scan(scanner_id, ScanSettings::default(), /*filter=*/ None) self.start_scan(scanner_id, settings, /*filter=*/ None) } pub(crate) fn stop_active_scan(&mut self, scanner_id: u8) -> BtStatus { Loading Loading @@ -1817,6 +1838,8 @@ struct ScannerInfo { monitor_handle: Option<u8>, // Used by start_scan() to determine if it is called because of system resuming. is_suspended: bool, // The scan parameters to use scan_settings: Option<ScanSettings>, } impl ScannerInfo { Loading @@ -1828,6 +1851,7 @@ impl ScannerInfo { filter: None, monitor_handle: None, is_suspended: false, scan_settings: None, } } } Loading Loading @@ -1918,6 +1942,16 @@ impl IBluetoothGatt for BluetoothGatt { return BtStatus::Busy; } // We're supposed to directly use the settings provided by the input parameter, but // currently UI is sending temporary variables instead. Therefore, load some preset values // known to work. // TODO(b/217274013): Fix UI plumbing and directly use the provided settings. let settings = ScanSettings { interval: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval), window: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow), scan_type: ScanType::Active, }; // Multiplexing scanners happens at this layer. The implementations of start_scan // and stop_scan maintains the state of all registered scanners and based on the states // update the scanning and/or filter states of libbluetooth. Loading @@ -1927,6 +1961,7 @@ impl IBluetoothGatt for BluetoothGatt { if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { scanner.is_active = true; scanner.filter = filter.clone(); scanner.scan_settings = Some(settings); } else { log::warn!("Scanner {} not found", scanner_id); return BtStatus::Fail; Loading Loading @@ -1987,7 +2022,10 @@ impl IBluetoothGatt for BluetoothGatt { } } gatt_async.update_scan().await; let scan_settings = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) .map_or(None, |s| s.scan_settings.clone()); gatt_async.update_scan(scanner_id, scan_settings).await; }); BtStatus::Success Loading Loading
system/gd/rust/linux/stack/src/bluetooth_gatt.rs +59 −21 Original line number Diff line number Diff line Loading @@ -33,7 +33,7 @@ use num_traits::clamp; use rand::rngs::SmallRng; use rand::{RngCore, SeedableRng}; use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use std::convert::{TryFrom, TryInto}; use std::sync::{Arc, Mutex, MutexGuard}; use tokio::sync::mpsc::Sender; use tokio::time; Loading Loading @@ -1145,7 +1145,7 @@ impl Default for GattWriteType { } } #[derive(Debug, FromPrimitive, ToPrimitive)] #[derive(Debug, FromPrimitive, ToPrimitive, Clone)] #[repr(u32)] /// Scan type configuration. pub enum ScanType { Loading @@ -1163,13 +1163,31 @@ impl Default for ScanType { /// /// This configuration is general and supported on all Bluetooth hardware, irrelevant of the /// hardware filter offload (APCF or MSFT). #[derive(Debug, Default)] #[derive(Debug, Clone)] pub struct ScanSettings { pub interval: i32, pub window: i32, pub scan_type: ScanType, } impl ScanSettings { fn extract_scan_parameters(self) -> Option<(u16, u16)> { let interval = u16::try_from(self.interval); if interval.is_err() { println!("Invalid scan interval {}", self.interval); return None; } let window = u16::try_from(self.window); if window.is_err() { println!("Invalid scan window {}", self.window); return None; } return Some((interval.unwrap(), window.unwrap())); } } /// Represents scan result #[derive(Debug)] pub struct ScanResult { Loading Loading @@ -1313,13 +1331,22 @@ impl GattAsyncIntf { /// /// Note: this does not need to be async, but declared as async for consistency in this struct. /// May be converted into real async in the future if btif supports it. async fn update_scan(&mut self) { async fn update_scan(&mut self, scanner_id: u8, scan_settings: Option<ScanSettings>) { if self.scanners.lock().unwrap().values().find(|scanner| scanner.is_active).is_some() { // Toggle the scan off and on so that we reset the scan parameters based on whether // we have active scanners using hardware filtering. // TODO(b/266752123): We can do more bookkeeping to optimize when we really need to // toggle. Also improve toggling API into 1 operation that guarantees correct ordering. self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan(); if let Some(settings) = scan_settings { if let Some((scan_interval, scan_window)) = settings.extract_scan_parameters() { self.gatt.as_ref().unwrap().lock().unwrap().scanner.set_scan_parameters( scanner_id, scan_interval, scan_window, ); } } self.gatt.as_ref().unwrap().lock().unwrap().scanner.start_scan(); } else { self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan(); Loading Loading @@ -1681,7 +1708,10 @@ impl BluetoothGatt { } } gatt_async.update_scan().await; let scan_settings = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) .map_or(None, |s| s.scan_settings.clone()); gatt_async.update_scan(scanner_id, scan_settings).await; }); BtStatus::Success Loading Loading @@ -1768,22 +1798,13 @@ impl BluetoothGatt { /// Start an active scan on given scanner id. This will look up and assign /// the correct ScanSettings for it as well. pub(crate) fn start_active_scan(&mut self, scanner_id: u8) -> BtStatus { let interval: u16 = sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval) .try_into() .expect("Bad value configured for LeInquiryScanInterval"); let window: u16 = sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow) .try_into() .expect("Bad value configured for LeInquiryScanWindow"); self.gatt .as_ref() .unwrap() .lock() .unwrap() .scanner .set_scan_parameters(scanner_id, interval, window); let settings = ScanSettings { interval: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval), window: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow), scan_type: ScanType::Active, }; self.start_scan(scanner_id, ScanSettings::default(), /*filter=*/ None) self.start_scan(scanner_id, settings, /*filter=*/ None) } pub(crate) fn stop_active_scan(&mut self, scanner_id: u8) -> BtStatus { Loading Loading @@ -1817,6 +1838,8 @@ struct ScannerInfo { monitor_handle: Option<u8>, // Used by start_scan() to determine if it is called because of system resuming. is_suspended: bool, // The scan parameters to use scan_settings: Option<ScanSettings>, } impl ScannerInfo { Loading @@ -1828,6 +1851,7 @@ impl ScannerInfo { filter: None, monitor_handle: None, is_suspended: false, scan_settings: None, } } } Loading Loading @@ -1918,6 +1942,16 @@ impl IBluetoothGatt for BluetoothGatt { return BtStatus::Busy; } // We're supposed to directly use the settings provided by the input parameter, but // currently UI is sending temporary variables instead. Therefore, load some preset values // known to work. // TODO(b/217274013): Fix UI plumbing and directly use the provided settings. let settings = ScanSettings { interval: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval), window: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow), scan_type: ScanType::Active, }; // Multiplexing scanners happens at this layer. The implementations of start_scan // and stop_scan maintains the state of all registered scanners and based on the states // update the scanning and/or filter states of libbluetooth. Loading @@ -1927,6 +1961,7 @@ impl IBluetoothGatt for BluetoothGatt { if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { scanner.is_active = true; scanner.filter = filter.clone(); scanner.scan_settings = Some(settings); } else { log::warn!("Scanner {} not found", scanner_id); return BtStatus::Fail; Loading Loading @@ -1987,7 +2022,10 @@ impl IBluetoothGatt for BluetoothGatt { } } gatt_async.update_scan().await; let scan_settings = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) .map_or(None, |s| s.scan_settings.clone()); gatt_async.update_scan(scanner_id, scan_settings).await; }); BtStatus::Success Loading