Loading flags/gap.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -173,3 +173,13 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "msft_addr_tracking_quirk" namespace: "bluetooth" description: "Scanning with MSFT paddress tracking for Realtek BT controllers" bug: "332438857" metadata { purpose: PURPOSE_BUGFIX } } system/gd/hci/msft.cc +26 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #if TARGET_FLOSS #include "hci/msft.h" #include <android_bluetooth_flags.h> #include <bluetooth/log.h> #include <hardware/bt_common_types.h> Loading Loading @@ -145,6 +146,31 @@ struct MsftExtensionManager::impl { return; } if (IS_FLAG_ENABLED(msft_addr_tracking_quirk)) { if (monitor.condition_type != MSFT_CONDITION_TYPE_ADDRESS && monitor.condition_type != MSFT_CONDITION_TYPE_PATTERNS) { log::warn("Disallowed as MSFT condition type {} is not supported.", monitor.condition_type); return; } if (monitor.condition_type == MSFT_CONDITION_TYPE_ADDRESS) { msft_adv_monitor_add_cb_ = cb; Address addr; Address::FromString(monitor.addr_info.bd_addr.ToString(), addr); hci_layer_->EnqueueCommand( MsftLeMonitorAdvConditionAddressBuilder::Create( static_cast<OpCode>(msft_.opcode.value()), monitor.rssi_threshold_high, monitor.rssi_threshold_low, monitor.rssi_threshold_low_time_interval, monitor.rssi_sampling_period, monitor.addr_info.addr_type, addr), module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_add_complete)); return; } } std::vector<MsftLeMonitorAdvConditionPattern> patterns; MsftLeMonitorAdvConditionPattern pattern; // The Microsoft Extension specifies 1 octet for the number of patterns. Loading system/gd/rust/linux/stack/src/bluetooth_gatt.rs +239 −13 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ use bt_topshim::profiles::gatt::{ GattAdvInbandCallbacksDispatcher, GattClientCallbacks, GattClientCallbacksDispatcher, GattScannerCallbacks, GattScannerCallbacksDispatcher, GattScannerInbandCallbacks, GattScannerInbandCallbacksDispatcher, GattServerCallbacks, GattServerCallbacksDispatcher, GattStatus, LePhy, MsftAdvMonitor, MsftAdvMonitorPattern, GattStatus, LePhy, MsftAdvMonitor, MsftAdvMonitorAddress, MsftAdvMonitorPattern, }; use bt_topshim::sysprop; use bt_topshim::topstack; Loading Loading @@ -1241,6 +1241,23 @@ pub struct ScanFilterPattern { pub content: Vec<u8>, } #[derive(Debug, Clone)] pub struct ScanFilterAddress { pub addr_type: u8, pub bd_addr: String, } #[derive(Debug, Clone)] #[repr(u8)] pub enum ScanFilterConditionType { /// [MSFT HCI Extension](https://learn.microsoft.com/en-us/windows-hardware/drivers/bluetooth/microsoft-defined-bluetooth-hci-commands-and-events). MsftConditionTypeAll = 0x0, MsftConditionTypePatterns = 0x1, MsftConditionTypeUuid = 0x2, MsftConditionTypeIrkResolution = 0x3, MsftConditionTypeAddress = 0x4, } /// Represents the condition for matching advertisements. /// /// Only pattern-based matching is implemented. Loading @@ -1259,7 +1276,7 @@ pub enum ScanFilterCondition { Irk, /// Match by Bluetooth address (not implemented). BluetoothAddress, BluetoothAddress(ScanFilterAddress), } /// Represents a scan filter to be passed to `IBluetoothGatt::start_scan`. Loading Loading @@ -1718,6 +1735,84 @@ impl BluetoothGatt { self.add_monitor_and_update_scan(scanner_id, filter) } fn add_child_monitor(&self, scanner_id: u8, scan_filter: ScanFilter) -> BtStatus { let gatt_async = self.gatt_async.clone(); let scanners = self.scanners.clone(); let is_msft_supported = self.is_msft_supported(); // Add and enable the monitor filter only when the MSFT extension is supported. if !is_msft_supported { log::error!("add_child_monitor: MSFT extension is not supported"); return BtStatus::Fail; } log::debug!( "add_child_monitor: monitoring address, scanner_id={}, filter={:?}", scanner_id, scan_filter ); tokio::spawn(async move { // Add address monitor to track the specified device let mut gatt_async = gatt_async.lock().await; let monitor_handle = match gatt_async.msft_adv_monitor_add((&scan_filter).into()).await { Ok((handle, 0)) => handle, _ => { log::error!("Error adding advertisement monitor"); return; } }; if let Some(scanner) = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) { // After hci complete event is received, update the monitor_handle. // The address monitor handles are needed in stop_scan(). let addr_info: MsftAdvMonitorAddress = (&scan_filter.condition).into(); if scanner.addr_handle_map.contains_key(&addr_info.bd_addr.to_string()) { scanner .addr_handle_map .insert(addr_info.bd_addr.to_string(), Some(monitor_handle)); log::debug!( "Added addr monitor {} and updated bd_addr={} to addr filter map", monitor_handle, addr_info.bd_addr.to_string() ); return; } else { log::debug!("add_child_monitor: bd_addr {} has been removed, removing the addr monitor {}.", addr_info.bd_addr.to_string(), monitor_handle); } } else { log::warn!( "add_child_monitor: scanner has been removed, removing the addr monitor {}", monitor_handle ); } let _res = gatt_async.msft_adv_monitor_remove(monitor_handle).await; }); BtStatus::Success } fn remove_child_monitor(&self, _scanner_id: u8, monitor_handle: u8) -> BtStatus { let gatt_async = self.gatt_async.clone(); let is_msft_supported = self.is_msft_supported(); tokio::spawn(async move { let mut gatt_async = gatt_async.lock().await; // Remove and disable the monitor only when the MSFT extension is supported. if is_msft_supported { let _res = gatt_async.msft_adv_monitor_remove(monitor_handle).await; log::debug!("Removed addr monitor {}.", monitor_handle); } }); BtStatus::Success } fn add_monitor_and_update_scan( &mut self, scanner_id: u8, Loading Loading @@ -1751,11 +1846,10 @@ impl BluetoothGatt { if let Some(scanner) = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) { // The monitor handle is needed in stop_scan(). scanner.monitor_handle = Some(monitor_handle); } log::debug!("Added adv monitor handle = {}", monitor_handle); log::debug!("Added adv pattern monitor handle = {}", monitor_handle); } let has_enabled_unfiltered_scanner = scanners Loading Loading @@ -1898,6 +1992,7 @@ pub enum GattWriteRequestStatus { } // This structure keeps track of the lifecycle of a scanner. #[derive(Debug)] struct ScannerInfo { // The callback to which events about this scanner needs to be sent to. // Another purpose of keeping track of the callback id is that when a callback is disconnected Loading @@ -1916,6 +2011,10 @@ struct ScannerInfo { is_suspended: bool, // The scan parameters to use scan_settings: Option<ScanSettings>, // Whether the MSFT extension monitor tracking by address filter quirk will be used. addr_tracking_quirk: bool, // Stores all the monitored handles for pattern and address. addr_handle_map: HashMap<String, Option<u8>>, } impl ScannerInfo { Loading @@ -1928,6 +2027,8 @@ impl ScannerInfo { monitor_handle: None, is_suspended: false, scan_settings: None, addr_tracking_quirk: sysprop::get_bool(sysprop::PropertyBool::LeAdvMonRtlQuirk), addr_handle_map: HashMap::new(), } } } Loading @@ -1953,14 +2054,47 @@ impl Into<Vec<MsftAdvMonitorPattern>> for &ScanFilterCondition { } } impl Into<MsftAdvMonitorAddress> for &ScanFilterAddress { fn into(self) -> MsftAdvMonitorAddress { MsftAdvMonitorAddress { addr_type: self.addr_type, bd_addr: RawAddress::from_string(self.bd_addr.clone()).unwrap(), } } } impl Into<MsftAdvMonitorAddress> for &ScanFilterCondition { fn into(self) -> MsftAdvMonitorAddress { let addr: RawAddress = RawAddress::empty(); match self { ScanFilterCondition::BluetoothAddress(addr_info) => MsftAdvMonitorAddress { addr_type: addr_info.addr_type, bd_addr: RawAddress::from_string(addr_info.bd_addr.clone()).unwrap(), }, _ => MsftAdvMonitorAddress { addr_type: 0, bd_addr: addr }, } } } impl Into<MsftAdvMonitor> for &ScanFilter { fn into(self) -> MsftAdvMonitor { let scan_filter_condition_type = match self.condition { ScanFilterCondition::Patterns(_) => { ScanFilterConditionType::MsftConditionTypePatterns as u8 } ScanFilterCondition::BluetoothAddress(_) => { ScanFilterConditionType::MsftConditionTypeAddress as u8 } _ => ScanFilterConditionType::MsftConditionTypeAll as u8, }; MsftAdvMonitor { rssi_high_threshold: self.rssi_high_threshold.try_into().unwrap(), rssi_low_threshold: self.rssi_low_threshold.try_into().unwrap(), rssi_low_timeout: self.rssi_low_timeout.try_into().unwrap(), rssi_sampling_period: self.rssi_sampling_period.try_into().unwrap(), condition_type: scan_filter_condition_type, patterns: (&self.condition).into(), addr_info: (&self.condition).into(), } } } Loading Loading @@ -2074,12 +2208,23 @@ impl IBluetoothGatt for BluetoothGatt { return BtStatus::Busy; } let monitor_handle = { let monitor_handles = { let mut scanners_lock = self.scanners.lock().unwrap(); if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { scanner.is_enabled = false; scanner.monitor_handle let mut handles: Vec<u8> = vec![]; if let Some(handle) = scanner.monitor_handle.take() { handles.push(handle); } for (_addr, handle) in scanner.addr_handle_map.drain() { if let Some(h) = handle { handles.push(h); } } handles } else { log::warn!("Scanner {} not found", scanner_id); // Clients can assume success of the removal since the scanner does not exist. Loading @@ -2099,7 +2244,7 @@ impl IBluetoothGatt for BluetoothGatt { // Remove and disable the monitor only when the MSFT extension is supported. if is_msft_supported { if let Some(handle) = monitor_handle { for handle in monitor_handles { let _res = gatt_async.msft_adv_monitor_remove(handle).await; } Loading Loading @@ -4105,11 +4250,34 @@ impl BtifGattScannerCallbacks for BluetoothGatt { } fn on_track_adv_found_lost(&mut self, track_adv_info: RustAdvertisingTrackInfo) { let scanner_id = match self.scanners.lock().unwrap().values().find_map(|scanner| { scanner.monitor_handle.and_then(|handle| { (handle == track_adv_info.monitor_handle).then(|| scanner.scanner_id).flatten() }) }) { let addr = track_adv_info.advertiser_address.to_string(); let mut binding = self.scanners.lock().unwrap(); let mut corresponding_scanner: Option<&mut ScannerInfo> = binding.values_mut().find_map(|scanner| { if scanner.monitor_handle == Some(track_adv_info.monitor_handle) { Some(scanner) } else { None } }); if corresponding_scanner.is_none() { corresponding_scanner = binding.values_mut().find_map(|scanner| { if scanner.addr_handle_map.contains_key(&addr) { Some(scanner) } else { None } }); } let corresponding_scanner = match corresponding_scanner { Some(scanner) => scanner, None => { log::warn!("No scanner having monitor handle {}", track_adv_info.monitor_handle); return; } }; let scanner_id = match corresponding_scanner.scanner_id { Some(scanner_id) => scanner_id, None => { log::warn!("No scanner id having monitor handle {}", track_adv_info.monitor_handle); Loading @@ -4117,6 +4285,62 @@ impl BtifGattScannerCallbacks for BluetoothGatt { } }; let controller_need_separate_pattern_and_address = corresponding_scanner.addr_tracking_quirk; let mut address_monitor_succeed: bool = false; if controller_need_separate_pattern_and_address { if track_adv_info.advertiser_state == 0x01 { if corresponding_scanner.addr_handle_map.contains_key(&addr) { log::debug!( "on_track_adv_found_lost: this addr {} is already handled, just return", track_adv_info.advertiser_address.to_string() ); return; } log::debug!( "on_track_adv_found_lost: state == 0x01, adding addr {} to map", addr.clone() ); corresponding_scanner.addr_handle_map.insert(addr.clone(), None); let scan_filter_addr = ScanFilterAddress { addr_type: track_adv_info.advertiser_address_type, bd_addr: track_adv_info.advertiser_address.to_string(), }; if let Some(saved_filter) = corresponding_scanner.filter.clone() { let scan_filter = ScanFilter { rssi_high_threshold: saved_filter.rssi_high_threshold, rssi_low_threshold: saved_filter.rssi_low_threshold, rssi_low_timeout: saved_filter.rssi_low_timeout, rssi_sampling_period: saved_filter.rssi_sampling_period, condition: ScanFilterCondition::BluetoothAddress(scan_filter_addr), }; self.add_child_monitor(scanner_id, scan_filter); address_monitor_succeed = true; } } else { if let Some(handle) = corresponding_scanner.monitor_handle { if handle == track_adv_info.monitor_handle { log::info!( "pattern filter lost, addr={}", track_adv_info.advertiser_address.to_string() ); return; } } if corresponding_scanner.addr_handle_map.remove(&addr).is_some() { log::debug!( "on_track_adv_found_lost: removing addr = {} from map", addr.clone() ); self.remove_child_monitor(scanner_id, track_adv_info.monitor_handle); } } } self.scanner_callbacks.for_all_callbacks(|callback| { let adv_data = [&track_adv_info.adv_packet[..], &track_adv_info.scan_response[..]].concat(); Loading @@ -4142,7 +4366,9 @@ impl BtifGattScannerCallbacks for BluetoothGatt { }; if track_adv_info.advertiser_state == 0x01 { if !controller_need_separate_pattern_and_address || address_monitor_succeed { callback.on_advertisement_found(scanner_id, scan_result); } } else { callback.on_advertisement_lost(scanner_id, scan_result); } Loading system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.cc +9 −0 Original line number Diff line number Diff line Loading @@ -109,13 +109,22 @@ std::vector<MsftAdvMonitorPattern> ConvertAdvMonitorPatterns(const ::rust::Vec<R return converted; } MsftAdvMonitorAddress ConvertAdvMonitorAddress(RustMsftAdvMonitorAddress rust_addr_info) { MsftAdvMonitorAddress addr_info; addr_info.addr_type = rust_addr_info.addr_type; addr_info.bd_addr = rust_addr_info.bd_addr; return addr_info; } MsftAdvMonitor ConvertAdvMonitor(const RustMsftAdvMonitor& monitor) { MsftAdvMonitor converted = { .rssi_threshold_high = monitor.rssi_high_threshold, .rssi_threshold_low = monitor.rssi_low_threshold, .rssi_threshold_low_time_interval = monitor.rssi_low_timeout, .rssi_sampling_period = monitor.rssi_sampling_period, .condition_type = monitor.condition_type, .patterns = ConvertAdvMonitorPatterns(monitor.patterns), .addr_info = ConvertAdvMonitorAddress(monitor.addr_info), }; return converted; } Loading system/gd/rust/topshim/src/profiles/gatt.rs +10 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,12 @@ pub mod ffi { pub pattern: Vec<u8>, } #[derive(Debug, Clone)] pub struct RustMsftAdvMonitorAddress { pub addr_type: u8, pub bd_addr: RawAddress, } // Defined in C++ and needs a translation in shim. #[derive(Debug, Clone)] pub struct RustMsftAdvMonitor { Loading @@ -106,7 +112,9 @@ pub mod ffi { pub rssi_low_threshold: u8, pub rssi_low_timeout: u8, pub rssi_sampling_period: u8, pub condition_type: u8, pub patterns: Vec<RustMsftAdvMonitorPattern>, pub addr_info: RustMsftAdvMonitorAddress, } #[derive(Debug, Clone)] Loading Loading @@ -430,6 +438,8 @@ pub type GattFilterParam = ffi::RustGattFilterParam; pub type ApcfCommand = ffi::RustApcfCommand; pub type MsftAdvMonitor = ffi::RustMsftAdvMonitor; pub type MsftAdvMonitorPattern = ffi::RustMsftAdvMonitorPattern; pub type MsftAdvMonitorAddress = ffi::RustMsftAdvMonitorAddress; pub type AdvertiseParameters = ffi::RustAdvertiseParameters; pub type PeriodicAdvertisingParameters = ffi::RustPeriodicAdvertisingParameters; Loading Loading
flags/gap.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -173,3 +173,13 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "msft_addr_tracking_quirk" namespace: "bluetooth" description: "Scanning with MSFT paddress tracking for Realtek BT controllers" bug: "332438857" metadata { purpose: PURPOSE_BUGFIX } }
system/gd/hci/msft.cc +26 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #if TARGET_FLOSS #include "hci/msft.h" #include <android_bluetooth_flags.h> #include <bluetooth/log.h> #include <hardware/bt_common_types.h> Loading Loading @@ -145,6 +146,31 @@ struct MsftExtensionManager::impl { return; } if (IS_FLAG_ENABLED(msft_addr_tracking_quirk)) { if (monitor.condition_type != MSFT_CONDITION_TYPE_ADDRESS && monitor.condition_type != MSFT_CONDITION_TYPE_PATTERNS) { log::warn("Disallowed as MSFT condition type {} is not supported.", monitor.condition_type); return; } if (monitor.condition_type == MSFT_CONDITION_TYPE_ADDRESS) { msft_adv_monitor_add_cb_ = cb; Address addr; Address::FromString(monitor.addr_info.bd_addr.ToString(), addr); hci_layer_->EnqueueCommand( MsftLeMonitorAdvConditionAddressBuilder::Create( static_cast<OpCode>(msft_.opcode.value()), monitor.rssi_threshold_high, monitor.rssi_threshold_low, monitor.rssi_threshold_low_time_interval, monitor.rssi_sampling_period, monitor.addr_info.addr_type, addr), module_handler_->BindOnceOn(this, &impl::on_msft_adv_monitor_add_complete)); return; } } std::vector<MsftLeMonitorAdvConditionPattern> patterns; MsftLeMonitorAdvConditionPattern pattern; // The Microsoft Extension specifies 1 octet for the number of patterns. Loading
system/gd/rust/linux/stack/src/bluetooth_gatt.rs +239 −13 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ use bt_topshim::profiles::gatt::{ GattAdvInbandCallbacksDispatcher, GattClientCallbacks, GattClientCallbacksDispatcher, GattScannerCallbacks, GattScannerCallbacksDispatcher, GattScannerInbandCallbacks, GattScannerInbandCallbacksDispatcher, GattServerCallbacks, GattServerCallbacksDispatcher, GattStatus, LePhy, MsftAdvMonitor, MsftAdvMonitorPattern, GattStatus, LePhy, MsftAdvMonitor, MsftAdvMonitorAddress, MsftAdvMonitorPattern, }; use bt_topshim::sysprop; use bt_topshim::topstack; Loading Loading @@ -1241,6 +1241,23 @@ pub struct ScanFilterPattern { pub content: Vec<u8>, } #[derive(Debug, Clone)] pub struct ScanFilterAddress { pub addr_type: u8, pub bd_addr: String, } #[derive(Debug, Clone)] #[repr(u8)] pub enum ScanFilterConditionType { /// [MSFT HCI Extension](https://learn.microsoft.com/en-us/windows-hardware/drivers/bluetooth/microsoft-defined-bluetooth-hci-commands-and-events). MsftConditionTypeAll = 0x0, MsftConditionTypePatterns = 0x1, MsftConditionTypeUuid = 0x2, MsftConditionTypeIrkResolution = 0x3, MsftConditionTypeAddress = 0x4, } /// Represents the condition for matching advertisements. /// /// Only pattern-based matching is implemented. Loading @@ -1259,7 +1276,7 @@ pub enum ScanFilterCondition { Irk, /// Match by Bluetooth address (not implemented). BluetoothAddress, BluetoothAddress(ScanFilterAddress), } /// Represents a scan filter to be passed to `IBluetoothGatt::start_scan`. Loading Loading @@ -1718,6 +1735,84 @@ impl BluetoothGatt { self.add_monitor_and_update_scan(scanner_id, filter) } fn add_child_monitor(&self, scanner_id: u8, scan_filter: ScanFilter) -> BtStatus { let gatt_async = self.gatt_async.clone(); let scanners = self.scanners.clone(); let is_msft_supported = self.is_msft_supported(); // Add and enable the monitor filter only when the MSFT extension is supported. if !is_msft_supported { log::error!("add_child_monitor: MSFT extension is not supported"); return BtStatus::Fail; } log::debug!( "add_child_monitor: monitoring address, scanner_id={}, filter={:?}", scanner_id, scan_filter ); tokio::spawn(async move { // Add address monitor to track the specified device let mut gatt_async = gatt_async.lock().await; let monitor_handle = match gatt_async.msft_adv_monitor_add((&scan_filter).into()).await { Ok((handle, 0)) => handle, _ => { log::error!("Error adding advertisement monitor"); return; } }; if let Some(scanner) = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) { // After hci complete event is received, update the monitor_handle. // The address monitor handles are needed in stop_scan(). let addr_info: MsftAdvMonitorAddress = (&scan_filter.condition).into(); if scanner.addr_handle_map.contains_key(&addr_info.bd_addr.to_string()) { scanner .addr_handle_map .insert(addr_info.bd_addr.to_string(), Some(monitor_handle)); log::debug!( "Added addr monitor {} and updated bd_addr={} to addr filter map", monitor_handle, addr_info.bd_addr.to_string() ); return; } else { log::debug!("add_child_monitor: bd_addr {} has been removed, removing the addr monitor {}.", addr_info.bd_addr.to_string(), monitor_handle); } } else { log::warn!( "add_child_monitor: scanner has been removed, removing the addr monitor {}", monitor_handle ); } let _res = gatt_async.msft_adv_monitor_remove(monitor_handle).await; }); BtStatus::Success } fn remove_child_monitor(&self, _scanner_id: u8, monitor_handle: u8) -> BtStatus { let gatt_async = self.gatt_async.clone(); let is_msft_supported = self.is_msft_supported(); tokio::spawn(async move { let mut gatt_async = gatt_async.lock().await; // Remove and disable the monitor only when the MSFT extension is supported. if is_msft_supported { let _res = gatt_async.msft_adv_monitor_remove(monitor_handle).await; log::debug!("Removed addr monitor {}.", monitor_handle); } }); BtStatus::Success } fn add_monitor_and_update_scan( &mut self, scanner_id: u8, Loading Loading @@ -1751,11 +1846,10 @@ impl BluetoothGatt { if let Some(scanner) = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) { // The monitor handle is needed in stop_scan(). scanner.monitor_handle = Some(monitor_handle); } log::debug!("Added adv monitor handle = {}", monitor_handle); log::debug!("Added adv pattern monitor handle = {}", monitor_handle); } let has_enabled_unfiltered_scanner = scanners Loading Loading @@ -1898,6 +1992,7 @@ pub enum GattWriteRequestStatus { } // This structure keeps track of the lifecycle of a scanner. #[derive(Debug)] struct ScannerInfo { // The callback to which events about this scanner needs to be sent to. // Another purpose of keeping track of the callback id is that when a callback is disconnected Loading @@ -1916,6 +2011,10 @@ struct ScannerInfo { is_suspended: bool, // The scan parameters to use scan_settings: Option<ScanSettings>, // Whether the MSFT extension monitor tracking by address filter quirk will be used. addr_tracking_quirk: bool, // Stores all the monitored handles for pattern and address. addr_handle_map: HashMap<String, Option<u8>>, } impl ScannerInfo { Loading @@ -1928,6 +2027,8 @@ impl ScannerInfo { monitor_handle: None, is_suspended: false, scan_settings: None, addr_tracking_quirk: sysprop::get_bool(sysprop::PropertyBool::LeAdvMonRtlQuirk), addr_handle_map: HashMap::new(), } } } Loading @@ -1953,14 +2054,47 @@ impl Into<Vec<MsftAdvMonitorPattern>> for &ScanFilterCondition { } } impl Into<MsftAdvMonitorAddress> for &ScanFilterAddress { fn into(self) -> MsftAdvMonitorAddress { MsftAdvMonitorAddress { addr_type: self.addr_type, bd_addr: RawAddress::from_string(self.bd_addr.clone()).unwrap(), } } } impl Into<MsftAdvMonitorAddress> for &ScanFilterCondition { fn into(self) -> MsftAdvMonitorAddress { let addr: RawAddress = RawAddress::empty(); match self { ScanFilterCondition::BluetoothAddress(addr_info) => MsftAdvMonitorAddress { addr_type: addr_info.addr_type, bd_addr: RawAddress::from_string(addr_info.bd_addr.clone()).unwrap(), }, _ => MsftAdvMonitorAddress { addr_type: 0, bd_addr: addr }, } } } impl Into<MsftAdvMonitor> for &ScanFilter { fn into(self) -> MsftAdvMonitor { let scan_filter_condition_type = match self.condition { ScanFilterCondition::Patterns(_) => { ScanFilterConditionType::MsftConditionTypePatterns as u8 } ScanFilterCondition::BluetoothAddress(_) => { ScanFilterConditionType::MsftConditionTypeAddress as u8 } _ => ScanFilterConditionType::MsftConditionTypeAll as u8, }; MsftAdvMonitor { rssi_high_threshold: self.rssi_high_threshold.try_into().unwrap(), rssi_low_threshold: self.rssi_low_threshold.try_into().unwrap(), rssi_low_timeout: self.rssi_low_timeout.try_into().unwrap(), rssi_sampling_period: self.rssi_sampling_period.try_into().unwrap(), condition_type: scan_filter_condition_type, patterns: (&self.condition).into(), addr_info: (&self.condition).into(), } } } Loading Loading @@ -2074,12 +2208,23 @@ impl IBluetoothGatt for BluetoothGatt { return BtStatus::Busy; } let monitor_handle = { let monitor_handles = { let mut scanners_lock = self.scanners.lock().unwrap(); if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { scanner.is_enabled = false; scanner.monitor_handle let mut handles: Vec<u8> = vec![]; if let Some(handle) = scanner.monitor_handle.take() { handles.push(handle); } for (_addr, handle) in scanner.addr_handle_map.drain() { if let Some(h) = handle { handles.push(h); } } handles } else { log::warn!("Scanner {} not found", scanner_id); // Clients can assume success of the removal since the scanner does not exist. Loading @@ -2099,7 +2244,7 @@ impl IBluetoothGatt for BluetoothGatt { // Remove and disable the monitor only when the MSFT extension is supported. if is_msft_supported { if let Some(handle) = monitor_handle { for handle in monitor_handles { let _res = gatt_async.msft_adv_monitor_remove(handle).await; } Loading Loading @@ -4105,11 +4250,34 @@ impl BtifGattScannerCallbacks for BluetoothGatt { } fn on_track_adv_found_lost(&mut self, track_adv_info: RustAdvertisingTrackInfo) { let scanner_id = match self.scanners.lock().unwrap().values().find_map(|scanner| { scanner.monitor_handle.and_then(|handle| { (handle == track_adv_info.monitor_handle).then(|| scanner.scanner_id).flatten() }) }) { let addr = track_adv_info.advertiser_address.to_string(); let mut binding = self.scanners.lock().unwrap(); let mut corresponding_scanner: Option<&mut ScannerInfo> = binding.values_mut().find_map(|scanner| { if scanner.monitor_handle == Some(track_adv_info.monitor_handle) { Some(scanner) } else { None } }); if corresponding_scanner.is_none() { corresponding_scanner = binding.values_mut().find_map(|scanner| { if scanner.addr_handle_map.contains_key(&addr) { Some(scanner) } else { None } }); } let corresponding_scanner = match corresponding_scanner { Some(scanner) => scanner, None => { log::warn!("No scanner having monitor handle {}", track_adv_info.monitor_handle); return; } }; let scanner_id = match corresponding_scanner.scanner_id { Some(scanner_id) => scanner_id, None => { log::warn!("No scanner id having monitor handle {}", track_adv_info.monitor_handle); Loading @@ -4117,6 +4285,62 @@ impl BtifGattScannerCallbacks for BluetoothGatt { } }; let controller_need_separate_pattern_and_address = corresponding_scanner.addr_tracking_quirk; let mut address_monitor_succeed: bool = false; if controller_need_separate_pattern_and_address { if track_adv_info.advertiser_state == 0x01 { if corresponding_scanner.addr_handle_map.contains_key(&addr) { log::debug!( "on_track_adv_found_lost: this addr {} is already handled, just return", track_adv_info.advertiser_address.to_string() ); return; } log::debug!( "on_track_adv_found_lost: state == 0x01, adding addr {} to map", addr.clone() ); corresponding_scanner.addr_handle_map.insert(addr.clone(), None); let scan_filter_addr = ScanFilterAddress { addr_type: track_adv_info.advertiser_address_type, bd_addr: track_adv_info.advertiser_address.to_string(), }; if let Some(saved_filter) = corresponding_scanner.filter.clone() { let scan_filter = ScanFilter { rssi_high_threshold: saved_filter.rssi_high_threshold, rssi_low_threshold: saved_filter.rssi_low_threshold, rssi_low_timeout: saved_filter.rssi_low_timeout, rssi_sampling_period: saved_filter.rssi_sampling_period, condition: ScanFilterCondition::BluetoothAddress(scan_filter_addr), }; self.add_child_monitor(scanner_id, scan_filter); address_monitor_succeed = true; } } else { if let Some(handle) = corresponding_scanner.monitor_handle { if handle == track_adv_info.monitor_handle { log::info!( "pattern filter lost, addr={}", track_adv_info.advertiser_address.to_string() ); return; } } if corresponding_scanner.addr_handle_map.remove(&addr).is_some() { log::debug!( "on_track_adv_found_lost: removing addr = {} from map", addr.clone() ); self.remove_child_monitor(scanner_id, track_adv_info.monitor_handle); } } } self.scanner_callbacks.for_all_callbacks(|callback| { let adv_data = [&track_adv_info.adv_packet[..], &track_adv_info.scan_response[..]].concat(); Loading @@ -4142,7 +4366,9 @@ impl BtifGattScannerCallbacks for BluetoothGatt { }; if track_adv_info.advertiser_state == 0x01 { if !controller_need_separate_pattern_and_address || address_monitor_succeed { callback.on_advertisement_found(scanner_id, scan_result); } } else { callback.on_advertisement_lost(scanner_id, scan_result); } Loading
system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.cc +9 −0 Original line number Diff line number Diff line Loading @@ -109,13 +109,22 @@ std::vector<MsftAdvMonitorPattern> ConvertAdvMonitorPatterns(const ::rust::Vec<R return converted; } MsftAdvMonitorAddress ConvertAdvMonitorAddress(RustMsftAdvMonitorAddress rust_addr_info) { MsftAdvMonitorAddress addr_info; addr_info.addr_type = rust_addr_info.addr_type; addr_info.bd_addr = rust_addr_info.bd_addr; return addr_info; } MsftAdvMonitor ConvertAdvMonitor(const RustMsftAdvMonitor& monitor) { MsftAdvMonitor converted = { .rssi_threshold_high = monitor.rssi_high_threshold, .rssi_threshold_low = monitor.rssi_low_threshold, .rssi_threshold_low_time_interval = monitor.rssi_low_timeout, .rssi_sampling_period = monitor.rssi_sampling_period, .condition_type = monitor.condition_type, .patterns = ConvertAdvMonitorPatterns(monitor.patterns), .addr_info = ConvertAdvMonitorAddress(monitor.addr_info), }; return converted; } Loading
system/gd/rust/topshim/src/profiles/gatt.rs +10 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,12 @@ pub mod ffi { pub pattern: Vec<u8>, } #[derive(Debug, Clone)] pub struct RustMsftAdvMonitorAddress { pub addr_type: u8, pub bd_addr: RawAddress, } // Defined in C++ and needs a translation in shim. #[derive(Debug, Clone)] pub struct RustMsftAdvMonitor { Loading @@ -106,7 +112,9 @@ pub mod ffi { pub rssi_low_threshold: u8, pub rssi_low_timeout: u8, pub rssi_sampling_period: u8, pub condition_type: u8, pub patterns: Vec<RustMsftAdvMonitorPattern>, pub addr_info: RustMsftAdvMonitorAddress, } #[derive(Debug, Clone)] Loading Loading @@ -430,6 +438,8 @@ pub type GattFilterParam = ffi::RustGattFilterParam; pub type ApcfCommand = ffi::RustApcfCommand; pub type MsftAdvMonitor = ffi::RustMsftAdvMonitor; pub type MsftAdvMonitorPattern = ffi::RustMsftAdvMonitorPattern; pub type MsftAdvMonitorAddress = ffi::RustMsftAdvMonitorAddress; pub type AdvertiseParameters = ffi::RustAdvertiseParameters; pub type PeriodicAdvertisingParameters = ffi::RustPeriodicAdvertisingParameters; Loading