1 //! Anything related to the adapter API (IBluetooth).
2
3 use bt_topshim::btif::{
4 BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BluetoothProperty, BtAclState,
5 BtAddrType, BtBondState, BtConnectionDirection, BtConnectionState, BtDeviceType, BtDiscMode,
6 BtDiscoveryState, BtHciErrorCode, BtPinCode, BtPropertyType, BtScanMode, BtSspVariant, BtState,
7 BtStatus, BtThreadEvent, BtTransport, BtVendorProductInfo, DisplayAddress, DisplayUuid,
8 RawAddress, ToggleableProfile, Uuid, INVALID_RSSI,
9 };
10 use bt_topshim::{
11 controller, metrics,
12 profiles::gatt::GattStatus,
13 profiles::hfp::EscoCodingFormat,
14 profiles::hid_host::{
15 BthhConnectionState, BthhHidInfo, BthhProtocolMode, BthhReportType, BthhStatus,
16 HHCallbacks, HHCallbacksDispatcher, HidHost,
17 },
18 profiles::sdp::{BtSdpRecord, Sdp, SdpCallbacks, SdpCallbacksDispatcher},
19 profiles::ProfileConnectionState,
20 topstack,
21 };
22
23 use bt_utils::array_utils;
24 use bt_utils::cod::{is_cod_hid_combo, is_cod_hid_keyboard};
25 use bt_utils::uhid::UHid;
26 use btif_macros::{btif_callback, btif_callbacks_dispatcher};
27
28 use log::{debug, error, warn};
29 use num_derive::{FromPrimitive, ToPrimitive};
30 use num_traits::cast::ToPrimitive;
31 use num_traits::pow;
32 use std::collections::{HashMap, HashSet};
33 use std::convert::TryInto;
34 use std::fs::File;
35 use std::hash::Hash;
36 use std::io::Write;
37 use std::os::fd::AsRawFd;
38 use std::process;
39 use std::sync::{Arc, Condvar, Mutex};
40 use std::time::Duration;
41 use std::time::Instant;
42 use tempfile::NamedTempFile;
43 use tokio::sync::mpsc::Sender;
44 use tokio::task::JoinHandle;
45 use tokio::time;
46
47 use crate::battery_service::BatteryServiceActions;
48 use crate::bluetooth_admin::{BluetoothAdmin, IBluetoothAdmin};
49 use crate::bluetooth_gatt::{
50 BluetoothGatt, GattActions, IBluetoothGatt, IScannerCallback, ScanResult,
51 };
52 use crate::bluetooth_media::{BluetoothMedia, IBluetoothMedia, MediaActions, LEA_UNKNOWN_GROUP_ID};
53 use crate::callbacks::Callbacks;
54 use crate::socket_manager::SocketActions;
55 use crate::uuid::{Profile, UuidHelper};
56 use crate::{APIMessage, BluetoothAPI, Message, RPCProxy, SuspendMode};
57
58 pub(crate) const FLOSS_VER: u16 = 0x0001;
59 const DEFAULT_DISCOVERY_TIMEOUT_MS: u64 = 12800;
60 const MIN_ADV_INSTANCES_FOR_MULTI_ADV: u8 = 5;
61
62 /// Devices that were last seen longer than this duration are considered stale
63 /// if they haven't already bonded or connected. Once this duration expires, the
64 /// clear event should be sent to clients.
65 const FOUND_DEVICE_FRESHNESS: Duration = Duration::from_secs(30);
66
67 /// This is the value returned from Bluetooth Interface calls.
68 // TODO(241930383): Add enum to topshim
69 const BTM_SUCCESS: i32 = 0;
70
71 const PID_DIR: &str = "/var/run/bluetooth";
72
73 /// Represents various roles the adapter supports.
74 #[derive(Debug, FromPrimitive, ToPrimitive)]
75 #[repr(u32)]
76 pub enum BtAdapterRole {
77 Central = 0,
78 Peripheral,
79 CentralPeripheral,
80 }
81 /// Defines the adapter API.
82 pub trait IBluetooth {
83 /// Adds a callback from a client who wishes to observe adapter events.
register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) -> u3284 fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) -> u32;
85
86 /// Removes registered callback.
unregister_callback(&mut self, callback_id: u32) -> bool87 fn unregister_callback(&mut self, callback_id: u32) -> bool;
88
89 /// Adds a callback from a client who wishes to observe connection events.
register_connection_callback( &mut self, callback: Box<dyn IBluetoothConnectionCallback + Send>, ) -> u3290 fn register_connection_callback(
91 &mut self,
92 callback: Box<dyn IBluetoothConnectionCallback + Send>,
93 ) -> u32;
94
95 /// Removes registered callback.
unregister_connection_callback(&mut self, callback_id: u32) -> bool96 fn unregister_connection_callback(&mut self, callback_id: u32) -> bool;
97
98 /// Inits the bluetooth interface. Should always be called before enable.
init(&mut self, init_flags: Vec<String>) -> bool99 fn init(&mut self, init_flags: Vec<String>) -> bool;
100
101 /// Enables the adapter.
102 ///
103 /// Returns true if the request is accepted.
enable(&mut self) -> bool104 fn enable(&mut self) -> bool;
105
106 /// Disables the adapter.
107 ///
108 /// Returns true if the request is accepted.
disable(&mut self) -> bool109 fn disable(&mut self) -> bool;
110
111 /// Cleans up the bluetooth interface. Should always be called after disable.
cleanup(&mut self)112 fn cleanup(&mut self);
113
114 /// Returns the Bluetooth address of the local adapter.
get_address(&self) -> RawAddress115 fn get_address(&self) -> RawAddress;
116
117 /// Gets supported UUIDs by the local adapter.
get_uuids(&self) -> Vec<Uuid>118 fn get_uuids(&self) -> Vec<Uuid>;
119
120 /// Gets the local adapter name.
get_name(&self) -> String121 fn get_name(&self) -> String;
122
123 /// Sets the local adapter name.
set_name(&self, name: String) -> bool124 fn set_name(&self, name: String) -> bool;
125
126 /// Gets the bluetooth class.
get_bluetooth_class(&self) -> u32127 fn get_bluetooth_class(&self) -> u32;
128
129 /// Sets the bluetooth class.
set_bluetooth_class(&self, cod: u32) -> bool130 fn set_bluetooth_class(&self, cod: u32) -> bool;
131
132 /// Returns whether the adapter is discoverable.
get_discoverable(&self) -> bool133 fn get_discoverable(&self) -> bool;
134
135 /// Returns the adapter discoverable timeout.
get_discoverable_timeout(&self) -> u32136 fn get_discoverable_timeout(&self) -> u32;
137
138 /// Sets discoverability. If discoverable, limits the duration with given value.
set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool139 fn set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool;
140
141 /// Returns whether multi-advertisement is supported.
142 /// A minimum number of 5 advertising instances is required for multi-advertisment support.
is_multi_advertisement_supported(&self) -> bool143 fn is_multi_advertisement_supported(&self) -> bool;
144
145 /// Returns whether LE extended advertising is supported.
is_le_extended_advertising_supported(&self) -> bool146 fn is_le_extended_advertising_supported(&self) -> bool;
147
148 /// Starts BREDR Inquiry.
start_discovery(&mut self) -> bool149 fn start_discovery(&mut self) -> bool;
150
151 /// Cancels BREDR Inquiry.
cancel_discovery(&mut self) -> bool152 fn cancel_discovery(&mut self) -> bool;
153
154 /// Checks if discovery is started.
is_discovering(&self) -> bool155 fn is_discovering(&self) -> bool;
156
157 /// Checks when discovery ends in milliseconds from now.
get_discovery_end_millis(&self) -> u64158 fn get_discovery_end_millis(&self) -> u64;
159
160 /// Initiates pairing to a remote device. Triggers connection if not already started.
create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> BtStatus161 fn create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> BtStatus;
162
163 /// Cancels any pending bond attempt on given device.
cancel_bond_process(&mut self, device: BluetoothDevice) -> bool164 fn cancel_bond_process(&mut self, device: BluetoothDevice) -> bool;
165
166 /// Removes pairing for given device.
remove_bond(&mut self, device: BluetoothDevice) -> bool167 fn remove_bond(&mut self, device: BluetoothDevice) -> bool;
168
169 /// Returns a list of known bonded devices.
get_bonded_devices(&self) -> Vec<BluetoothDevice>170 fn get_bonded_devices(&self) -> Vec<BluetoothDevice>;
171
172 /// Gets the bond state of a single device.
get_bond_state(&self, device: BluetoothDevice) -> BtBondState173 fn get_bond_state(&self, device: BluetoothDevice) -> BtBondState;
174
175 /// Set pin on bonding device.
set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool176 fn set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool;
177
178 /// Set passkey on bonding device.
set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool179 fn set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool;
180
181 /// Confirm that a pairing should be completed on a bonding device.
set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool182 fn set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool;
183
184 /// Gets the name of the remote device.
get_remote_name(&self, device: BluetoothDevice) -> String185 fn get_remote_name(&self, device: BluetoothDevice) -> String;
186
187 /// Gets the type of the remote device.
get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType188 fn get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType;
189
190 /// Gets the alias of the remote device.
get_remote_alias(&self, device: BluetoothDevice) -> String191 fn get_remote_alias(&self, device: BluetoothDevice) -> String;
192
193 /// Sets the alias of the remote device.
set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String)194 fn set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String);
195
196 /// Gets the class of the remote device.
get_remote_class(&self, device: BluetoothDevice) -> u32197 fn get_remote_class(&self, device: BluetoothDevice) -> u32;
198
199 /// Gets the appearance of the remote device.
get_remote_appearance(&self, device: BluetoothDevice) -> u16200 fn get_remote_appearance(&self, device: BluetoothDevice) -> u16;
201
202 /// Gets whether the remote device is connected.
get_remote_connected(&self, device: BluetoothDevice) -> bool203 fn get_remote_connected(&self, device: BluetoothDevice) -> bool;
204
205 /// Gets whether the remote device can wake the system.
get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool206 fn get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool;
207
208 /// Gets the vendor and product information of the remote device.
get_remote_vendor_product_info(&self, device: BluetoothDevice) -> BtVendorProductInfo209 fn get_remote_vendor_product_info(&self, device: BluetoothDevice) -> BtVendorProductInfo;
210
211 /// Get the address type of the remote device.
get_remote_address_type(&self, device: BluetoothDevice) -> BtAddrType212 fn get_remote_address_type(&self, device: BluetoothDevice) -> BtAddrType;
213
214 /// Get the RSSI of the remote device.
get_remote_rssi(&self, device: BluetoothDevice) -> i8215 fn get_remote_rssi(&self, device: BluetoothDevice) -> i8;
216
217 /// Returns a list of connected devices.
get_connected_devices(&self) -> Vec<BluetoothDevice>218 fn get_connected_devices(&self) -> Vec<BluetoothDevice>;
219
220 /// Gets the connection state of a single device.
get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState221 fn get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState;
222
223 /// Gets the connection state of a specific profile.
get_profile_connection_state(&self, profile: Uuid) -> ProfileConnectionState224 fn get_profile_connection_state(&self, profile: Uuid) -> ProfileConnectionState;
225
226 /// Returns the cached UUIDs of a remote device.
get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid>227 fn get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid>;
228
229 /// Triggers SDP to get UUIDs of a remote device.
fetch_remote_uuids(&self, device: BluetoothDevice) -> bool230 fn fetch_remote_uuids(&self, device: BluetoothDevice) -> bool;
231
232 /// Triggers SDP and searches for a specific UUID on a remote device.
sdp_search(&self, device: BluetoothDevice, uuid: Uuid) -> bool233 fn sdp_search(&self, device: BluetoothDevice, uuid: Uuid) -> bool;
234
235 /// Creates a new SDP record.
create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool236 fn create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool;
237
238 /// Removes the SDP record associated with the provided handle.
remove_sdp_record(&self, handle: i32) -> bool239 fn remove_sdp_record(&self, handle: i32) -> bool;
240
241 /// Connect all profiles supported by device and enabled on adapter.
connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> BtStatus242 fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> BtStatus;
243
244 /// Disconnect all profiles supported by device and enabled on adapter.
245 /// Note that it includes all custom profiles enabled by the users e.g. through SocketManager or
246 /// BluetoothGatt interfaces; The device shall be disconnected on baseband eventually.
disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool247 fn disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool;
248
249 /// Returns whether WBS is supported.
is_wbs_supported(&self) -> bool250 fn is_wbs_supported(&self) -> bool;
251
252 /// Returns whether SWB is supported.
is_swb_supported(&self) -> bool253 fn is_swb_supported(&self) -> bool;
254
255 /// Returns a list of all the roles that are supported.
get_supported_roles(&self) -> Vec<BtAdapterRole>256 fn get_supported_roles(&self) -> Vec<BtAdapterRole>;
257
258 /// Returns whether the coding format is supported.
is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool259 fn is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool;
260
261 /// Returns whether LE Audio is supported.
is_le_audio_supported(&self) -> bool262 fn is_le_audio_supported(&self) -> bool;
263
264 /// Returns whether the remote device is a dual mode audio sink device (supports both classic and
265 /// LE Audio sink roles).
is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool266 fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool;
267
268 /// Gets diagnostic output.
get_dumpsys(&self) -> String269 fn get_dumpsys(&self) -> String;
270 }
271
272 /// Adapter API for Bluetooth qualification and verification.
273 ///
274 /// This interface is provided for testing and debugging.
275 /// Clients should not use this interface for production.
276 pub trait IBluetoothQALegacy {
277 /// Returns whether the adapter is connectable.
get_connectable(&self) -> bool278 fn get_connectable(&self) -> bool;
279
280 /// Sets connectability. Returns true on success, false otherwise.
set_connectable(&mut self, mode: bool) -> bool281 fn set_connectable(&mut self, mode: bool) -> bool;
282
283 /// Returns the adapter's Bluetooth friendly name.
get_alias(&self) -> String284 fn get_alias(&self) -> String;
285
286 /// Returns the adapter's Device ID information in modalias format
287 /// used by the kernel and udev.
get_modalias(&self) -> String288 fn get_modalias(&self) -> String;
289
290 /// Gets HID report on the peer.
get_hid_report( &mut self, addr: RawAddress, report_type: BthhReportType, report_id: u8, ) -> BtStatus291 fn get_hid_report(
292 &mut self,
293 addr: RawAddress,
294 report_type: BthhReportType,
295 report_id: u8,
296 ) -> BtStatus;
297
298 /// Sets HID report to the peer.
set_hid_report( &mut self, addr: RawAddress, report_type: BthhReportType, report: String, ) -> BtStatus299 fn set_hid_report(
300 &mut self,
301 addr: RawAddress,
302 report_type: BthhReportType,
303 report: String,
304 ) -> BtStatus;
305
306 /// Snd HID data report to the peer.
send_hid_data(&mut self, addr: RawAddress, data: String) -> BtStatus307 fn send_hid_data(&mut self, addr: RawAddress, data: String) -> BtStatus;
308 }
309
310 /// Delayed actions from adapter events.
311 pub enum DelayedActions {
312 /// Check whether the current set of found devices are still fresh.
313 DeviceFreshnessCheck,
314
315 /// Connect to all supported profiles on target device.
316 ConnectAllProfiles(BluetoothDevice),
317
318 /// Scanner for BLE discovery is registered with given status and scanner id.
319 BleDiscoveryScannerRegistered(Uuid, u8, GattStatus),
320
321 /// Scanner for BLE discovery is reporting a result.
322 BleDiscoveryScannerResult(ScanResult),
323
324 /// Update the connectable mode to allow or disallow classic reconnect.
325 /// Parameter: Whether or not there are Classic listening sockets
326 UpdateConnectableMode(bool),
327
328 /// Reset the discoverable mode to BtDiscMode::NonDiscoverable.
329 ResetDiscoverable,
330
331 /// Create bond to the device stored in |pending_create_bond|.
332 CreateBond,
333 }
334
335 /// Serializable device used in various apis.
336 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
337 pub struct BluetoothDevice {
338 pub address: RawAddress,
339 pub name: String,
340 }
341
342 impl BluetoothDevice {
new(address: RawAddress, name: String) -> Self343 pub(crate) fn new(address: RawAddress, name: String) -> Self {
344 Self { address, name }
345 }
346
from_properties(in_properties: &Vec<BluetoothProperty>) -> Self347 pub(crate) fn from_properties(in_properties: &Vec<BluetoothProperty>) -> Self {
348 let mut address = RawAddress::default();
349 let mut name = String::from("");
350
351 for prop in in_properties {
352 match &prop {
353 BluetoothProperty::BdAddr(bdaddr) => {
354 address = *bdaddr;
355 }
356 BluetoothProperty::BdName(bdname) => {
357 name = bdname.clone();
358 }
359 _ => {}
360 }
361 }
362
363 Self { address, name }
364 }
365 }
366
367 /// Internal data structure that keeps a map of cached properties for a remote device.
368 struct BluetoothDeviceContext {
369 /// Transport type reported by ACL connection (if completed).
370 pub acl_reported_transport: BtTransport,
371
372 pub bredr_acl_state: BtAclState,
373 pub ble_acl_state: BtAclState,
374 pub bond_state: BtBondState,
375 pub info: BluetoothDevice,
376 pub last_seen: Instant,
377 pub properties: HashMap<BtPropertyType, BluetoothProperty>,
378
379 /// Keep track of whether services have been resolved.
380 pub services_resolved: bool,
381
382 /// If supported UUIDs weren't available in EIR, wait for services to be
383 /// resolved to connect.
384 pub wait_to_connect: bool,
385 }
386
387 impl BluetoothDeviceContext {
new( bond_state: BtBondState, bredr_acl_state: BtAclState, ble_acl_state: BtAclState, info: BluetoothDevice, last_seen: Instant, properties: Vec<BluetoothProperty>, ) -> BluetoothDeviceContext388 pub(crate) fn new(
389 bond_state: BtBondState,
390 bredr_acl_state: BtAclState,
391 ble_acl_state: BtAclState,
392 info: BluetoothDevice,
393 last_seen: Instant,
394 properties: Vec<BluetoothProperty>,
395 ) -> BluetoothDeviceContext {
396 let mut device = BluetoothDeviceContext {
397 acl_reported_transport: BtTransport::Auto,
398 bredr_acl_state,
399 ble_acl_state,
400 bond_state,
401 info,
402 last_seen,
403 properties: HashMap::new(),
404 services_resolved: false,
405 wait_to_connect: false,
406 };
407 device.update_properties(&properties);
408 device
409 }
410
update_properties(&mut self, in_properties: &Vec<BluetoothProperty>)411 pub(crate) fn update_properties(&mut self, in_properties: &Vec<BluetoothProperty>) {
412 for prop in in_properties {
413 // Handle merging of certain properties.
414 match &prop {
415 BluetoothProperty::BdAddr(bdaddr) => {
416 self.info.address = *bdaddr;
417 self.properties.insert(prop.get_type(), prop.clone());
418 }
419 BluetoothProperty::BdName(bdname) => {
420 if !bdname.is_empty() {
421 self.info.name = bdname.clone();
422 self.properties.insert(prop.get_type(), prop.clone());
423 }
424 }
425 _ => {
426 self.properties.insert(prop.get_type(), prop.clone());
427 }
428 }
429 }
430 }
431
432 /// Mark this device as seen.
seen(&mut self)433 pub(crate) fn seen(&mut self) {
434 self.last_seen = Instant::now();
435 }
436
get_default_transport(&self) -> BtTransport437 fn get_default_transport(&self) -> BtTransport {
438 self.properties.get(&BtPropertyType::TypeOfDevice).map_or(BtTransport::Auto, |prop| {
439 match prop {
440 BluetoothProperty::TypeOfDevice(t) => match *t {
441 BtDeviceType::Bredr => BtTransport::Bredr,
442 BtDeviceType::Ble => BtTransport::Le,
443 _ => BtTransport::Auto,
444 },
445 _ => BtTransport::Auto,
446 }
447 })
448 }
449
450 /// Check if it is connected in at least one transport.
is_connected(&self) -> bool451 fn is_connected(&self) -> bool {
452 self.bredr_acl_state == BtAclState::Connected || self.ble_acl_state == BtAclState::Connected
453 }
454
455 /// Set ACL state given transport. Return true if state changed.
set_transport_state(&mut self, transport: &BtTransport, state: &BtAclState) -> bool456 fn set_transport_state(&mut self, transport: &BtTransport, state: &BtAclState) -> bool {
457 match (transport, self.get_default_transport()) {
458 (t, d)
459 if *t == BtTransport::Bredr
460 || (*t == BtTransport::Auto && d == BtTransport::Bredr) =>
461 {
462 if self.bredr_acl_state == *state {
463 return false;
464 }
465 self.bredr_acl_state = state.clone();
466 }
467 (t, d)
468 if *t == BtTransport::Le || (*t == BtTransport::Auto && d == BtTransport::Le) =>
469 {
470 if self.ble_acl_state == *state {
471 return false;
472 }
473 self.ble_acl_state = state.clone();
474 }
475 // both link transport and the default transport are Auto.
476 _ => {
477 warn!("Unable to decide the transport! Set current connection states bredr({:?}), ble({:?}) to {:?}", self.bredr_acl_state, self.ble_acl_state, *state);
478 if self.bredr_acl_state == *state && self.ble_acl_state == *state {
479 return false;
480 }
481 // There is no way for us to know which transport the link is referring to in this case.
482 self.ble_acl_state = state.clone();
483 self.bredr_acl_state = state.clone();
484 return true;
485 }
486 };
487 true
488 }
489 }
490
491 /// Structure to track all the signals for SIGTERM.
492 pub struct SigData {
493 pub enabled: Mutex<bool>,
494 pub enabled_notify: Condvar,
495
496 pub thread_attached: Mutex<bool>,
497 pub thread_notify: Condvar,
498 }
499
500 /// The interface for adapter callbacks registered through `IBluetooth::register_callback`.
501 pub trait IBluetoothCallback: RPCProxy {
502 /// When any adapter property changes.
on_adapter_property_changed(&mut self, prop: BtPropertyType)503 fn on_adapter_property_changed(&mut self, prop: BtPropertyType);
504
505 /// When any device properties change.
on_device_properties_changed( &mut self, remote_device: BluetoothDevice, props: Vec<BtPropertyType>, )506 fn on_device_properties_changed(
507 &mut self,
508 remote_device: BluetoothDevice,
509 props: Vec<BtPropertyType>,
510 );
511
512 /// When any of the adapter local address is changed.
on_address_changed(&mut self, addr: RawAddress)513 fn on_address_changed(&mut self, addr: RawAddress);
514
515 /// When the adapter name is changed.
on_name_changed(&mut self, name: String)516 fn on_name_changed(&mut self, name: String);
517
518 /// When the adapter's discoverable mode is changed.
on_discoverable_changed(&mut self, discoverable: bool)519 fn on_discoverable_changed(&mut self, discoverable: bool);
520
521 /// When a device is found via discovery.
on_device_found(&mut self, remote_device: BluetoothDevice)522 fn on_device_found(&mut self, remote_device: BluetoothDevice);
523
524 /// When a device is cleared from discovered devices cache.
on_device_cleared(&mut self, remote_device: BluetoothDevice)525 fn on_device_cleared(&mut self, remote_device: BluetoothDevice);
526
527 /// When the discovery state is changed.
on_discovering_changed(&mut self, discovering: bool)528 fn on_discovering_changed(&mut self, discovering: bool);
529
530 /// When there is a pairing/bonding process and requires agent to display the event to UI.
on_ssp_request( &mut self, remote_device: BluetoothDevice, cod: u32, variant: BtSspVariant, passkey: u32, )531 fn on_ssp_request(
532 &mut self,
533 remote_device: BluetoothDevice,
534 cod: u32,
535 variant: BtSspVariant,
536 passkey: u32,
537 );
538
539 /// When there is a pin request to display the event to client.
on_pin_request(&mut self, remote_device: BluetoothDevice, cod: u32, min_16_digit: bool)540 fn on_pin_request(&mut self, remote_device: BluetoothDevice, cod: u32, min_16_digit: bool);
541
542 /// When there is a auto-gen pin to display the event to client.
on_pin_display(&mut self, remote_device: BluetoothDevice, pincode: String)543 fn on_pin_display(&mut self, remote_device: BluetoothDevice, pincode: String);
544
545 /// When a bonding attempt has completed.
on_bond_state_changed(&mut self, status: u32, device_address: RawAddress, state: u32)546 fn on_bond_state_changed(&mut self, status: u32, device_address: RawAddress, state: u32);
547
548 /// When an SDP search has completed.
on_sdp_search_complete( &mut self, remote_device: BluetoothDevice, searched_uuid: Uuid, sdp_records: Vec<BtSdpRecord>, )549 fn on_sdp_search_complete(
550 &mut self,
551 remote_device: BluetoothDevice,
552 searched_uuid: Uuid,
553 sdp_records: Vec<BtSdpRecord>,
554 );
555
556 /// When an SDP record has been successfully created.
on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32)557 fn on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32);
558 }
559
560 /// An interface for other modules to track found remote devices.
561 pub trait IBluetoothDeviceCallback {
562 /// When a device is found via discovery.
on_device_found(&mut self, remote_device: BluetoothDevice)563 fn on_device_found(&mut self, remote_device: BluetoothDevice);
564
565 /// When a device is cleared from discovered devices cache.
on_device_cleared(&mut self, remote_device: BluetoothDevice)566 fn on_device_cleared(&mut self, remote_device: BluetoothDevice);
567
568 /// When a device property is changed.
on_remote_device_properties_changed( &mut self, remote_device: BluetoothDevice, properties: Vec<BluetoothProperty>, )569 fn on_remote_device_properties_changed(
570 &mut self,
571 remote_device: BluetoothDevice,
572 properties: Vec<BluetoothProperty>,
573 );
574 }
575
576 pub trait IBluetoothConnectionCallback: RPCProxy {
577 /// Notification sent when a remote device completes HCI connection.
on_device_connected(&mut self, remote_device: BluetoothDevice)578 fn on_device_connected(&mut self, remote_device: BluetoothDevice);
579
580 /// Notification sent when a remote device completes HCI disconnection.
on_device_disconnected(&mut self, remote_device: BluetoothDevice)581 fn on_device_disconnected(&mut self, remote_device: BluetoothDevice);
582 }
583
584 /// Implementation of the adapter API.
585 pub struct Bluetooth {
586 intf: Arc<Mutex<BluetoothInterface>>,
587
588 virt_index: i32,
589 hci_index: i32,
590 remote_devices: HashMap<RawAddress, BluetoothDeviceContext>,
591 ble_scanner_id: Option<u8>,
592 ble_scanner_uuid: Option<Uuid>,
593 bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
594 bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
595 bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
596 callbacks: Callbacks<dyn IBluetoothCallback + Send>,
597 connection_callbacks: Callbacks<dyn IBluetoothConnectionCallback + Send>,
598 discovering_started: Instant,
599 hh: Option<HidHost>,
600 is_connectable: bool,
601 discoverable_mode: BtDiscMode,
602 // This refers to the suspend mode of the functionality related to Classic scan mode,
603 // i.e., page scan and inquiry scan; Also known as connectable and discoverable.
604 scan_suspend_mode: SuspendMode,
605 is_discovering: bool,
606 is_discovering_before_suspend: bool,
607 is_discovery_paused: bool,
608 discovery_suspend_mode: SuspendMode,
609 local_address: Option<RawAddress>,
610 pending_discovery: bool,
611 properties: HashMap<BtPropertyType, BluetoothProperty>,
612 profiles_ready: bool,
613 freshness_check: Option<JoinHandle<()>>,
614 sdp: Option<Sdp>,
615 state: BtState,
616 tx: Sender<Message>,
617 api_tx: Sender<APIMessage>,
618 // Internal API members
619 discoverable_timeout: Option<JoinHandle<()>>,
620 cancelling_devices: HashSet<RawAddress>,
621 pending_create_bond: Option<(BluetoothDevice, BtTransport)>,
622 active_pairing_address: Option<RawAddress>,
623 le_supported_states: u64,
624 le_local_supported_features: u64,
625
626 /// Used to notify signal handler that we have turned off the stack.
627 sig_notifier: Arc<SigData>,
628
629 /// Virtual uhid device created to keep bluetooth as a wakeup source.
630 uhid_wakeup_source: UHid,
631 }
632
633 impl Bluetooth {
634 /// Constructs the IBluetooth implementation.
new( virt_index: i32, hci_index: i32, tx: Sender<Message>, api_tx: Sender<APIMessage>, sig_notifier: Arc<SigData>, intf: Arc<Mutex<BluetoothInterface>>, bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>, bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>, bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>, ) -> Bluetooth635 pub fn new(
636 virt_index: i32,
637 hci_index: i32,
638 tx: Sender<Message>,
639 api_tx: Sender<APIMessage>,
640 sig_notifier: Arc<SigData>,
641 intf: Arc<Mutex<BluetoothInterface>>,
642 bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
643 bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
644 bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
645 ) -> Bluetooth {
646 Bluetooth {
647 virt_index,
648 hci_index,
649 remote_devices: HashMap::new(),
650 callbacks: Callbacks::new(tx.clone(), Message::AdapterCallbackDisconnected),
651 connection_callbacks: Callbacks::new(
652 tx.clone(),
653 Message::ConnectionCallbackDisconnected,
654 ),
655 hh: None,
656 ble_scanner_id: None,
657 ble_scanner_uuid: None,
658 bluetooth_admin,
659 bluetooth_gatt,
660 bluetooth_media,
661 discovering_started: Instant::now(),
662 intf,
663 is_connectable: false,
664 discoverable_mode: BtDiscMode::NonDiscoverable,
665 scan_suspend_mode: SuspendMode::Normal,
666 is_discovering: false,
667 is_discovering_before_suspend: false,
668 is_discovery_paused: false,
669 discovery_suspend_mode: SuspendMode::Normal,
670 local_address: None,
671 pending_discovery: false,
672 properties: HashMap::new(),
673 profiles_ready: false,
674 freshness_check: None,
675 sdp: None,
676 state: BtState::Off,
677 tx,
678 api_tx,
679 // Internal API members
680 discoverable_timeout: None,
681 cancelling_devices: HashSet::new(),
682 pending_create_bond: None,
683 active_pairing_address: None,
684 le_supported_states: 0u64,
685 le_local_supported_features: 0u64,
686 sig_notifier,
687 uhid_wakeup_source: UHid::new(),
688 }
689 }
690
update_connectable_mode(&mut self, is_sock_listening: bool)691 fn update_connectable_mode(&mut self, is_sock_listening: bool) {
692 // Set connectable if
693 // - there is bredr socket listening, or
694 // - there is a classic device bonded and not connected
695 self.set_connectable_internal(
696 is_sock_listening
697 || self.remote_devices.values().any(|ctx| {
698 ctx.bond_state == BtBondState::Bonded
699 && ctx.bredr_acl_state == BtAclState::Disconnected
700 && ctx
701 .properties
702 .get(&BtPropertyType::TypeOfDevice)
703 .and_then(|prop| match prop {
704 BluetoothProperty::TypeOfDevice(transport) => {
705 Some(*transport != BtDeviceType::Ble)
706 }
707 _ => None,
708 })
709 .unwrap_or(false)
710 }),
711 );
712 }
713
trigger_update_connectable_mode(&self)714 fn trigger_update_connectable_mode(&self) {
715 if self.get_scan_suspend_mode() != SuspendMode::Normal {
716 return;
717 }
718 let txl = self.tx.clone();
719 tokio::spawn(async move {
720 let _ = txl.send(Message::TriggerUpdateConnectableMode).await;
721 });
722 }
723
disable_profile(&mut self, profile: &Profile)724 fn disable_profile(&mut self, profile: &Profile) {
725 if !UuidHelper::is_profile_supported(profile) {
726 return;
727 }
728
729 match profile {
730 Profile::Hid => {
731 self.hh.as_mut().unwrap().activate_hidp(false);
732 }
733
734 Profile::Hogp => {
735 self.hh.as_mut().unwrap().activate_hogp(false);
736 }
737
738 Profile::A2dpSource
739 | Profile::Hfp
740 | Profile::AvrcpTarget
741 | Profile::LeAudio
742 | Profile::VolumeControl
743 | Profile::CoordinatedSet => {
744 self.bluetooth_media.lock().unwrap().disable_profile(profile);
745 }
746 // Ignore profiles that we don't connect.
747 _ => (),
748 }
749 }
750
enable_profile(&mut self, profile: &Profile)751 fn enable_profile(&mut self, profile: &Profile) {
752 if !UuidHelper::is_profile_supported(profile) {
753 return;
754 }
755
756 match profile {
757 Profile::Hid => {
758 self.hh.as_mut().unwrap().activate_hidp(true);
759 }
760
761 Profile::Hogp => {
762 self.hh.as_mut().unwrap().activate_hogp(true);
763 }
764
765 Profile::A2dpSource
766 | Profile::Hfp
767 | Profile::AvrcpTarget
768 | Profile::LeAudio
769 | Profile::VolumeControl
770 | Profile::CoordinatedSet => {
771 self.bluetooth_media.lock().unwrap().enable_profile(profile);
772 }
773 // Ignore profiles that we don't connect.
774 _ => (),
775 }
776 }
777
is_profile_enabled(&self, profile: &Profile) -> Option<bool>778 fn is_profile_enabled(&self, profile: &Profile) -> Option<bool> {
779 if !UuidHelper::is_profile_supported(profile) {
780 return None;
781 }
782
783 match profile {
784 Profile::Hid => Some(self.hh.as_ref().unwrap().is_hidp_activated),
785
786 Profile::Hogp => Some(self.hh.as_ref().unwrap().is_hogp_activated),
787
788 Profile::A2dpSource
789 | Profile::Hfp
790 | Profile::AvrcpTarget
791 | Profile::LeAudio
792 | Profile::VolumeControl
793 | Profile::CoordinatedSet => {
794 self.bluetooth_media.lock().unwrap().is_profile_enabled(profile)
795 }
796 // Ignore profiles that we don't connect.
797 _ => None,
798 }
799 }
800
get_hci_index(&self) -> u16801 pub(crate) fn get_hci_index(&self) -> u16 {
802 self.hci_index as u16
803 }
804
toggle_enabled_profiles(&mut self, allowed_services: &Vec<Uuid>)805 pub fn toggle_enabled_profiles(&mut self, allowed_services: &Vec<Uuid>) {
806 for profile in UuidHelper::get_ordered_supported_profiles() {
807 // Only toggle initializable profiles.
808 if let Some(enabled) = self.is_profile_enabled(&profile) {
809 let allowed = allowed_services.len() == 0
810 || allowed_services.contains(&UuidHelper::get_profile_uuid(&profile).unwrap());
811
812 if allowed && !enabled {
813 debug!("Enabling profile {}", &profile);
814 self.enable_profile(&profile);
815 } else if !allowed && enabled {
816 debug!("Disabling profile {}", &profile);
817 self.disable_profile(&profile);
818 }
819 }
820 }
821
822 if self.hh.as_mut().unwrap().configure_enabled_profiles() {
823 self.hh.as_mut().unwrap().disable();
824 let txl = self.tx.clone();
825
826 tokio::spawn(async move {
827 // Wait 100 milliseconds to prevent race condition caused by quick disable then
828 // enable.
829 // TODO: (b/272191117): don't enable until we're sure disable is done.
830 tokio::time::sleep(Duration::from_millis(100)).await;
831 let _ = txl.send(Message::HidHostEnable).await;
832 });
833 }
834 }
835
enable_hidhost(&mut self)836 pub fn enable_hidhost(&mut self) {
837 self.hh.as_mut().unwrap().enable();
838 }
839
init_profiles(&mut self)840 pub fn init_profiles(&mut self) {
841 self.bluetooth_gatt.lock().unwrap().enable(true);
842
843 let sdptx = self.tx.clone();
844 self.sdp = Some(Sdp::new(&self.intf.lock().unwrap()));
845 self.sdp.as_mut().unwrap().initialize(SdpCallbacksDispatcher {
846 dispatch: Box::new(move |cb| {
847 let txl = sdptx.clone();
848 topstack::get_runtime().spawn(async move {
849 let _ = txl.send(Message::Sdp(cb)).await;
850 });
851 }),
852 });
853
854 let hhtx = self.tx.clone();
855 self.hh = Some(HidHost::new(&self.intf.lock().unwrap()));
856 self.hh.as_mut().unwrap().initialize(HHCallbacksDispatcher {
857 dispatch: Box::new(move |cb| {
858 let txl = hhtx.clone();
859 topstack::get_runtime().spawn(async move {
860 let _ = txl.send(Message::HidHost(cb)).await;
861 });
862 }),
863 });
864
865 let allowed_profiles = self.bluetooth_admin.lock().unwrap().get_allowed_services();
866 self.toggle_enabled_profiles(&allowed_profiles);
867 // Mark profiles as ready
868 self.profiles_ready = true;
869 }
870
update_local_address(&mut self, addr: RawAddress)871 fn update_local_address(&mut self, addr: RawAddress) {
872 self.local_address = Some(addr);
873
874 self.callbacks.for_all_callbacks(|callback| {
875 callback.on_address_changed(addr);
876 });
877 }
878
adapter_callback_disconnected(&mut self, id: u32)879 pub(crate) fn adapter_callback_disconnected(&mut self, id: u32) {
880 self.callbacks.remove_callback(id);
881 }
882
connection_callback_disconnected(&mut self, id: u32)883 pub(crate) fn connection_callback_disconnected(&mut self, id: u32) {
884 self.connection_callbacks.remove_callback(id);
885 }
886
get_remote_device_property( &self, device: &BluetoothDevice, property_type: &BtPropertyType, ) -> Option<BluetoothProperty>887 fn get_remote_device_property(
888 &self,
889 device: &BluetoothDevice,
890 property_type: &BtPropertyType,
891 ) -> Option<BluetoothProperty> {
892 self.remote_devices
893 .get(&device.address)
894 .and_then(|d| d.properties.get(property_type))
895 .cloned()
896 }
897
set_remote_device_property( &mut self, device: &BluetoothDevice, property_type: BtPropertyType, property: BluetoothProperty, ) -> Result<(), ()>898 fn set_remote_device_property(
899 &mut self,
900 device: &BluetoothDevice,
901 property_type: BtPropertyType,
902 property: BluetoothProperty,
903 ) -> Result<(), ()> {
904 let Some(remote_device) = self.remote_devices.get_mut(&device.address) else {
905 return Err(());
906 };
907
908 // TODO: Determine why a callback isn't invoked to do this.
909 remote_device.properties.insert(property_type, property.clone());
910 self.intf.lock().unwrap().set_remote_device_property(&mut device.address.clone(), property);
911 Ok(())
912 }
913
914 /// Returns whether the adapter is connectable.
get_connectable_internal(&self) -> bool915 pub(crate) fn get_connectable_internal(&self) -> bool {
916 self.properties.get(&BtPropertyType::AdapterScanMode).map_or(false, |prop| match prop {
917 BluetoothProperty::AdapterScanMode(mode) => match *mode {
918 BtScanMode::Connectable
919 | BtScanMode::ConnectableDiscoverable
920 | BtScanMode::ConnectableLimitedDiscoverable => true,
921 BtScanMode::None_ => false,
922 },
923 _ => false,
924 })
925 }
926
927 /// Sets the adapter's connectable mode for classic connections.
set_connectable_internal(&mut self, mode: bool) -> bool928 pub(crate) fn set_connectable_internal(&mut self, mode: bool) -> bool {
929 if self.get_scan_suspend_mode() != SuspendMode::Normal {
930 // We will always trigger an update on resume so no need so store the mode change.
931 return false;
932 }
933 if self.is_connectable == mode {
934 return true;
935 }
936 if self.discoverable_mode != BtDiscMode::NonDiscoverable {
937 // Discoverable always implies connectable. Don't affect the discoverable mode for now
938 // and the connectable mode would be restored when discoverable becomes off.
939 self.is_connectable = mode;
940 return true;
941 }
942 let status =
943 self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::AdapterScanMode(
944 if mode { BtScanMode::Connectable } else { BtScanMode::None_ },
945 ));
946 let status = BtStatus::from(status as u32);
947 if status != BtStatus::Success {
948 warn!("Failed to set connectable mode: {:?}", status);
949 return false;
950 }
951 self.is_connectable = mode;
952 return true;
953 }
954
955 /// Returns adapter's discoverable mode.
get_discoverable_mode_internal(&self) -> BtDiscMode956 pub(crate) fn get_discoverable_mode_internal(&self) -> BtDiscMode {
957 let off_mode = BtDiscMode::NonDiscoverable;
958
959 self.properties.get(&BtPropertyType::AdapterScanMode).map_or(off_mode.clone(), |prop| {
960 match prop {
961 BluetoothProperty::AdapterScanMode(mode) => match *mode {
962 BtScanMode::ConnectableDiscoverable => BtDiscMode::GeneralDiscoverable,
963 BtScanMode::ConnectableLimitedDiscoverable => BtDiscMode::LimitedDiscoverable,
964 BtScanMode::Connectable | BtScanMode::None_ => off_mode,
965 },
966 _ => off_mode,
967 }
968 })
969 }
970
971 /// Set the suspend mode for scan mode (connectable/discoverable mode).
set_scan_suspend_mode(&mut self, suspend_mode: SuspendMode)972 pub(crate) fn set_scan_suspend_mode(&mut self, suspend_mode: SuspendMode) {
973 if suspend_mode != self.scan_suspend_mode {
974 self.scan_suspend_mode = suspend_mode;
975 }
976 }
977
978 /// Gets current suspend mode for scan mode (connectable/discoverable mode).
get_scan_suspend_mode(&self) -> SuspendMode979 pub(crate) fn get_scan_suspend_mode(&self) -> SuspendMode {
980 self.scan_suspend_mode.clone()
981 }
982
983 /// Enters the suspend mode for scan mode (connectable/discoverable mode).
scan_mode_enter_suspend(&mut self) -> BtStatus984 pub(crate) fn scan_mode_enter_suspend(&mut self) -> BtStatus {
985 if self.get_scan_suspend_mode() != SuspendMode::Normal {
986 return BtStatus::Busy;
987 }
988 self.set_scan_suspend_mode(SuspendMode::Suspending);
989
990 if self
991 .intf
992 .lock()
993 .unwrap()
994 .set_adapter_property(BluetoothProperty::AdapterScanMode(BtScanMode::None_))
995 != 0
996 {
997 warn!("scan_mode_enter_suspend: Failed to set BtScanMode::None_");
998 }
999
1000 self.set_scan_suspend_mode(SuspendMode::Suspended);
1001
1002 return BtStatus::Success;
1003 }
1004
1005 /// Exits the suspend mode for scan mode (connectable/discoverable mode).
scan_mode_exit_suspend(&mut self) -> BtStatus1006 pub(crate) fn scan_mode_exit_suspend(&mut self) -> BtStatus {
1007 if self.get_scan_suspend_mode() != SuspendMode::Suspended {
1008 return BtStatus::Busy;
1009 }
1010 self.set_scan_suspend_mode(SuspendMode::Resuming);
1011
1012 let mode = match self.discoverable_mode {
1013 BtDiscMode::LimitedDiscoverable => BtScanMode::ConnectableLimitedDiscoverable,
1014 BtDiscMode::GeneralDiscoverable => BtScanMode::ConnectableDiscoverable,
1015 BtDiscMode::NonDiscoverable => match self.is_connectable {
1016 true => BtScanMode::Connectable,
1017 false => BtScanMode::None_,
1018 },
1019 };
1020 if self
1021 .intf
1022 .lock()
1023 .unwrap()
1024 .set_adapter_property(BluetoothProperty::AdapterScanMode(mode.clone()))
1025 != 0
1026 {
1027 warn!("scan_mode_exit_suspend: Failed to restore scan mode {:?}", mode);
1028 }
1029
1030 self.set_scan_suspend_mode(SuspendMode::Normal);
1031
1032 // Update is only available after SuspendMode::Normal
1033 self.trigger_update_connectable_mode();
1034
1035 return BtStatus::Success;
1036 }
1037
1038 /// Returns adapter's alias.
get_alias_internal(&self) -> String1039 pub(crate) fn get_alias_internal(&self) -> String {
1040 let name = self.get_name();
1041 if !name.is_empty() {
1042 return name;
1043 }
1044
1045 // If the adapter name is empty, generate one based on local BDADDR
1046 // so that test programs can have a friendly name for the adapter.
1047 match self.local_address {
1048 None => "floss_0000".to_string(),
1049 Some(addr) => format!("floss_{:02X}{:02X}", addr.address[4], addr.address[5]),
1050 }
1051 }
1052
1053 // TODO(b/328675014): Add BtAddrType and BtTransport parameters
get_hid_report_internal( &mut self, mut addr: RawAddress, report_type: BthhReportType, report_id: u8, ) -> BtStatus1054 pub(crate) fn get_hid_report_internal(
1055 &mut self,
1056 mut addr: RawAddress,
1057 report_type: BthhReportType,
1058 report_id: u8,
1059 ) -> BtStatus {
1060 self.hh.as_mut().unwrap().get_report(
1061 &mut addr,
1062 BtAddrType::Public,
1063 BtTransport::Auto,
1064 report_type,
1065 report_id,
1066 128,
1067 )
1068 }
1069
1070 // TODO(b/328675014): Add BtAddrType and BtTransport parameters
set_hid_report_internal( &mut self, mut addr: RawAddress, report_type: BthhReportType, report: String, ) -> BtStatus1071 pub(crate) fn set_hid_report_internal(
1072 &mut self,
1073 mut addr: RawAddress,
1074 report_type: BthhReportType,
1075 report: String,
1076 ) -> BtStatus {
1077 let mut rb = report.clone().into_bytes();
1078 self.hh.as_mut().unwrap().set_report(
1079 &mut addr,
1080 BtAddrType::Public,
1081 BtTransport::Auto,
1082 report_type,
1083 rb.as_mut_slice(),
1084 )
1085 }
1086
1087 // TODO(b/328675014): Add BtAddrType and BtTransport parameters
send_hid_data_internal( &mut self, mut addr: RawAddress, data: String, ) -> BtStatus1088 pub(crate) fn send_hid_data_internal(
1089 &mut self,
1090 mut addr: RawAddress,
1091 data: String,
1092 ) -> BtStatus {
1093 let mut rb = data.clone().into_bytes();
1094 self.hh.as_mut().unwrap().send_data(
1095 &mut addr,
1096 BtAddrType::Public,
1097 BtTransport::Auto,
1098 rb.as_mut_slice(),
1099 )
1100 }
1101
1102 /// Returns all bonded and connected devices.
get_bonded_and_connected_devices(&mut self) -> Vec<BluetoothDevice>1103 pub(crate) fn get_bonded_and_connected_devices(&mut self) -> Vec<BluetoothDevice> {
1104 self.remote_devices
1105 .values()
1106 .filter(|v| v.is_connected() && v.bond_state == BtBondState::Bonded)
1107 .map(|v| v.info.clone())
1108 .collect()
1109 }
1110
1111 /// Gets the bond state of a single device with its address.
get_bond_state_by_addr(&self, addr: &RawAddress) -> BtBondState1112 pub fn get_bond_state_by_addr(&self, addr: &RawAddress) -> BtBondState {
1113 self.remote_devices.get(addr).map_or(BtBondState::NotBonded, |d| d.bond_state.clone())
1114 }
1115
1116 /// Gets whether a single device is connected with its address.
get_acl_state_by_addr(&self, addr: &RawAddress) -> bool1117 fn get_acl_state_by_addr(&self, addr: &RawAddress) -> bool {
1118 self.remote_devices.get(addr).map_or(false, |d| d.is_connected())
1119 }
1120
1121 /// Check whether remote devices are still fresh. If they're outside the
1122 /// freshness window, send a notification to clear the device from clients.
trigger_freshness_check(&mut self)1123 fn trigger_freshness_check(&mut self) {
1124 // A remote device is considered fresh if:
1125 // * It was last seen less than |FOUND_DEVICE_FRESHNESS| ago.
1126 // * It is bonded / bonding (i.e., not NotBonded)
1127 // * It is currently connected.
1128 fn is_fresh(d: &BluetoothDeviceContext, now: &Instant) -> bool {
1129 let fresh_at = d.last_seen + FOUND_DEVICE_FRESHNESS;
1130 now < &fresh_at || d.is_connected() || d.bond_state != BtBondState::NotBonded
1131 }
1132
1133 let now = Instant::now();
1134 let stale_devices: Vec<BluetoothDevice> = self
1135 .remote_devices
1136 .values()
1137 .filter(|d| !is_fresh(d, &now))
1138 .map(|d| d.info.clone())
1139 .collect();
1140
1141 // Retain only devices that are fresh.
1142 self.remote_devices.retain(|_, d| is_fresh(d, &now));
1143
1144 for d in stale_devices {
1145 self.callbacks.for_all_callbacks(|callback| {
1146 callback.on_device_cleared(d.clone());
1147 });
1148
1149 self.bluetooth_admin.lock().unwrap().on_device_cleared(&d);
1150 }
1151 }
1152
1153 /// Makes an LE_RAND call to the Bluetooth interface.
le_rand(&mut self) -> bool1154 pub fn le_rand(&mut self) -> bool {
1155 self.intf.lock().unwrap().le_rand() == BTM_SUCCESS
1156 }
1157
send_metrics_remote_device_info(device: &BluetoothDeviceContext)1158 fn send_metrics_remote_device_info(device: &BluetoothDeviceContext) {
1159 if device.bond_state != BtBondState::Bonded && !device.is_connected() {
1160 return;
1161 }
1162
1163 let mut class_of_device = 0u32;
1164 let mut device_type = BtDeviceType::Unknown;
1165 let mut appearance = 0u16;
1166 let mut vpi =
1167 BtVendorProductInfo { vendor_id_src: 0, vendor_id: 0, product_id: 0, version: 0 };
1168
1169 for prop in device.properties.values() {
1170 match prop {
1171 BluetoothProperty::TypeOfDevice(p) => device_type = p.clone(),
1172 BluetoothProperty::ClassOfDevice(p) => class_of_device = p.clone(),
1173 BluetoothProperty::Appearance(p) => appearance = p.clone(),
1174 BluetoothProperty::VendorProductInfo(p) => vpi = p.clone(),
1175 _ => (),
1176 }
1177 }
1178
1179 metrics::device_info_report(
1180 device.info.address,
1181 device_type,
1182 class_of_device,
1183 appearance,
1184 vpi.vendor_id,
1185 vpi.vendor_id_src,
1186 vpi.product_id,
1187 vpi.version,
1188 );
1189 }
1190
1191 /// Handle some delayed and recurring actions within the adapter.
handle_delayed_actions(&mut self, action: DelayedActions)1192 pub(crate) fn handle_delayed_actions(&mut self, action: DelayedActions) {
1193 match action {
1194 DelayedActions::DeviceFreshnessCheck => {
1195 self.trigger_freshness_check();
1196 }
1197
1198 DelayedActions::ConnectAllProfiles(device) => {
1199 self.connect_all_enabled_profiles(device);
1200 }
1201
1202 DelayedActions::BleDiscoveryScannerRegistered(uuid, scanner_id, status) => {
1203 if let Some(app_uuid) = self.ble_scanner_uuid {
1204 if app_uuid == uuid {
1205 if status == GattStatus::Success {
1206 self.ble_scanner_id = Some(scanner_id);
1207 } else {
1208 log::error!("BLE discovery scanner failed to register: {:?}", status);
1209 }
1210 }
1211 }
1212 }
1213
1214 DelayedActions::BleDiscoveryScannerResult(result) => {
1215 // Generate a vector of properties from ScanResult.
1216 let properties = {
1217 let mut props = vec![];
1218 props.push(BluetoothProperty::BdName(result.name.clone()));
1219 props.push(BluetoothProperty::BdAddr(result.address));
1220 if result.service_uuids.len() > 0 {
1221 props.push(BluetoothProperty::Uuids(result.service_uuids.clone()));
1222 }
1223 if result.service_data.len() > 0 {
1224 props.push(BluetoothProperty::Uuids(
1225 result
1226 .service_data
1227 .keys()
1228 .map(|v| Uuid::from_string(v).unwrap())
1229 .collect(),
1230 ));
1231 }
1232 props.push(BluetoothProperty::RemoteRssi(result.rssi));
1233 props.push(BluetoothProperty::RemoteAddrType((result.addr_type as u32).into()));
1234 props
1235 };
1236
1237 let device_info = BluetoothDevice::from_properties(&properties);
1238
1239 self.remote_devices
1240 .entry(device_info.address)
1241 .and_modify(|d| {
1242 d.update_properties(&properties);
1243 d.seen();
1244 })
1245 .or_insert(BluetoothDeviceContext::new(
1246 BtBondState::NotBonded,
1247 BtAclState::Disconnected,
1248 BtAclState::Disconnected,
1249 device_info,
1250 Instant::now(),
1251 properties,
1252 ));
1253 }
1254
1255 DelayedActions::UpdateConnectableMode(is_sock_listening) => {
1256 self.update_connectable_mode(is_sock_listening);
1257 }
1258
1259 DelayedActions::ResetDiscoverable => {
1260 self.set_discoverable(BtDiscMode::NonDiscoverable, 0);
1261 }
1262
1263 DelayedActions::CreateBond => {
1264 if let Some((device, transport)) = self.pending_create_bond.take() {
1265 let status = self.create_bond(device, transport);
1266 if status != BtStatus::Success {
1267 error!("Failed CreateBond status={:?}", status);
1268 }
1269 }
1270 }
1271 }
1272 }
1273
1274 /// Creates a file to notify btmanagerd the adapter is enabled.
create_pid_file(&self) -> std::io::Result<()>1275 fn create_pid_file(&self) -> std::io::Result<()> {
1276 let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.virt_index);
1277 let mut f = File::create(&file_name)?;
1278 f.write_all(process::id().to_string().as_bytes())?;
1279 Ok(())
1280 }
1281
1282 /// Removes the file to notify btmanagerd the adapter is disabled.
remove_pid_file(&self) -> std::io::Result<()>1283 fn remove_pid_file(&self) -> std::io::Result<()> {
1284 let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.virt_index);
1285 std::fs::remove_file(&file_name)?;
1286 Ok(())
1287 }
1288
1289 /// Set the suspend mode.
set_discovery_suspend_mode(&mut self, suspend_mode: SuspendMode)1290 pub fn set_discovery_suspend_mode(&mut self, suspend_mode: SuspendMode) {
1291 if suspend_mode != self.discovery_suspend_mode {
1292 self.discovery_suspend_mode = suspend_mode;
1293 }
1294 }
1295
1296 /// Gets current suspend mode.
get_discovery_suspend_mode(&self) -> SuspendMode1297 pub fn get_discovery_suspend_mode(&self) -> SuspendMode {
1298 self.discovery_suspend_mode.clone()
1299 }
1300
1301 /// Enters the suspend mode for discovery.
discovery_enter_suspend(&mut self) -> BtStatus1302 pub fn discovery_enter_suspend(&mut self) -> BtStatus {
1303 if self.get_discovery_suspend_mode() != SuspendMode::Normal {
1304 return BtStatus::Busy;
1305 }
1306 self.set_discovery_suspend_mode(SuspendMode::Suspending);
1307
1308 if self.is_discovering {
1309 self.is_discovering_before_suspend = true;
1310 self.cancel_discovery();
1311 }
1312 self.set_discovery_suspend_mode(SuspendMode::Suspended);
1313
1314 return BtStatus::Success;
1315 }
1316
1317 /// Exits the suspend mode for discovery.
discovery_exit_suspend(&mut self) -> BtStatus1318 pub fn discovery_exit_suspend(&mut self) -> BtStatus {
1319 if self.get_discovery_suspend_mode() != SuspendMode::Suspended {
1320 return BtStatus::Busy;
1321 }
1322 self.set_discovery_suspend_mode(SuspendMode::Resuming);
1323
1324 if self.is_discovering_before_suspend {
1325 self.is_discovering_before_suspend = false;
1326 self.start_discovery();
1327 }
1328 self.set_discovery_suspend_mode(SuspendMode::Normal);
1329
1330 return BtStatus::Success;
1331 }
1332
1333 /// Temporarily stop the discovery process and mark it as paused so that clients cannot restart
1334 /// it.
pause_discovery(&mut self)1335 fn pause_discovery(&mut self) {
1336 self.cancel_discovery();
1337 self.is_discovery_paused = true;
1338 }
1339
1340 /// Remove the paused flag to allow clients to begin discovery, and if there is already a
1341 /// pending request, start discovery.
resume_discovery(&mut self)1342 fn resume_discovery(&mut self) {
1343 self.is_discovery_paused = false;
1344 if self.pending_discovery {
1345 self.pending_discovery = false;
1346 self.start_discovery();
1347 }
1348 }
1349
1350 /// Return if there are wake-allowed device in bonded status.
get_wake_allowed_device_bonded(&self) -> bool1351 fn get_wake_allowed_device_bonded(&self) -> bool {
1352 self.get_bonded_devices().into_iter().any(|d| self.get_remote_wake_allowed(d))
1353 }
1354
1355 /// Powerd recognizes bluetooth activities as valid wakeup sources if powerd keeps bluetooth in
1356 /// the monitored path. This only happens if there is at least one valid wake-allowed BT device
1357 /// connected during the suspending process. If there is no BT devices connected at any time
1358 /// during the suspending process, the wakeup count will be lost, and system goes to dark
1359 /// resume instead of full resume.
1360 /// Bluetooth stack disconnects all physical bluetooth HID devices for suspend, so a virtual
1361 /// uhid device is necessary to keep bluetooth as a valid wakeup source.
create_uhid_for_suspend_wakesource(&mut self)1362 fn create_uhid_for_suspend_wakesource(&mut self) {
1363 if !self.uhid_wakeup_source.is_empty() {
1364 return;
1365 }
1366 match self.uhid_wakeup_source.create(
1367 "VIRTUAL_SUSPEND_UHID".to_string(),
1368 self.get_address(),
1369 RawAddress::empty(),
1370 ) {
1371 Err(e) => error!("Fail to create uhid {}", e),
1372 Ok(_) => (),
1373 }
1374 }
1375
1376 /// Clear the UHID device.
clear_uhid(&mut self)1377 fn clear_uhid(&mut self) {
1378 self.uhid_wakeup_source.clear();
1379 }
1380
1381 /// Checks whether pairing is busy.
is_pairing_busy(&self) -> bool1382 pub fn is_pairing_busy(&self) -> bool {
1383 self.intf.lock().unwrap().pairing_is_busy()
1384 || self.active_pairing_address.is_some()
1385 || self.pending_create_bond.is_some()
1386 }
1387 }
1388
1389 #[btif_callbacks_dispatcher(dispatch_base_callbacks, BaseCallbacks)]
1390 #[allow(unused_variables)]
1391 pub(crate) trait BtifBluetoothCallbacks {
1392 #[btif_callback(AdapterState)]
adapter_state_changed(&mut self, state: BtState)1393 fn adapter_state_changed(&mut self, state: BtState) {}
1394
1395 #[btif_callback(AdapterProperties)]
adapter_properties_changed( &mut self, status: BtStatus, num_properties: i32, properties: Vec<BluetoothProperty>, )1396 fn adapter_properties_changed(
1397 &mut self,
1398 status: BtStatus,
1399 num_properties: i32,
1400 properties: Vec<BluetoothProperty>,
1401 ) {
1402 }
1403
1404 #[btif_callback(DeviceFound)]
device_found(&mut self, n: i32, properties: Vec<BluetoothProperty>)1405 fn device_found(&mut self, n: i32, properties: Vec<BluetoothProperty>) {}
1406
1407 #[btif_callback(DiscoveryState)]
discovery_state(&mut self, state: BtDiscoveryState)1408 fn discovery_state(&mut self, state: BtDiscoveryState) {}
1409
1410 #[btif_callback(SspRequest)]
ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32)1411 fn ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32) {}
1412
1413 #[btif_callback(BondState)]
bond_state( &mut self, status: BtStatus, addr: RawAddress, bond_state: BtBondState, fail_reason: i32, )1414 fn bond_state(
1415 &mut self,
1416 status: BtStatus,
1417 addr: RawAddress,
1418 bond_state: BtBondState,
1419 fail_reason: i32,
1420 ) {
1421 }
1422
1423 #[btif_callback(RemoteDeviceProperties)]
remote_device_properties_changed( &mut self, status: BtStatus, addr: RawAddress, num_properties: i32, properties: Vec<BluetoothProperty>, )1424 fn remote_device_properties_changed(
1425 &mut self,
1426 status: BtStatus,
1427 addr: RawAddress,
1428 num_properties: i32,
1429 properties: Vec<BluetoothProperty>,
1430 ) {
1431 }
1432
1433 #[btif_callback(AclState)]
acl_state( &mut self, status: BtStatus, addr: RawAddress, state: BtAclState, link_type: BtTransport, hci_reason: BtHciErrorCode, conn_direction: BtConnectionDirection, acl_handle: u16, )1434 fn acl_state(
1435 &mut self,
1436 status: BtStatus,
1437 addr: RawAddress,
1438 state: BtAclState,
1439 link_type: BtTransport,
1440 hci_reason: BtHciErrorCode,
1441 conn_direction: BtConnectionDirection,
1442 acl_handle: u16,
1443 ) {
1444 }
1445
1446 #[btif_callback(LeRandCallback)]
le_rand_cb(&mut self, random: u64)1447 fn le_rand_cb(&mut self, random: u64) {}
1448
1449 #[btif_callback(PinRequest)]
pin_request( &mut self, remote_addr: RawAddress, remote_name: String, cod: u32, min_16_digit: bool, )1450 fn pin_request(
1451 &mut self,
1452 remote_addr: RawAddress,
1453 remote_name: String,
1454 cod: u32,
1455 min_16_digit: bool,
1456 ) {
1457 }
1458
1459 #[btif_callback(ThreadEvent)]
thread_event(&mut self, event: BtThreadEvent)1460 fn thread_event(&mut self, event: BtThreadEvent) {}
1461 }
1462
1463 #[btif_callbacks_dispatcher(dispatch_hid_host_callbacks, HHCallbacks)]
1464 pub(crate) trait BtifHHCallbacks {
1465 #[btif_callback(ConnectionState)]
connection_state( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, state: BthhConnectionState, )1466 fn connection_state(
1467 &mut self,
1468 address: RawAddress,
1469 address_type: BtAddrType,
1470 transport: BtTransport,
1471 state: BthhConnectionState,
1472 );
1473
1474 #[btif_callback(HidInfo)]
hid_info( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, info: BthhHidInfo, )1475 fn hid_info(
1476 &mut self,
1477 address: RawAddress,
1478 address_type: BtAddrType,
1479 transport: BtTransport,
1480 info: BthhHidInfo,
1481 );
1482
1483 #[btif_callback(ProtocolMode)]
protocol_mode( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, mode: BthhProtocolMode, )1484 fn protocol_mode(
1485 &mut self,
1486 address: RawAddress,
1487 address_type: BtAddrType,
1488 transport: BtTransport,
1489 status: BthhStatus,
1490 mode: BthhProtocolMode,
1491 );
1492
1493 #[btif_callback(IdleTime)]
idle_time( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, idle_rate: i32, )1494 fn idle_time(
1495 &mut self,
1496 address: RawAddress,
1497 address_type: BtAddrType,
1498 transport: BtTransport,
1499 status: BthhStatus,
1500 idle_rate: i32,
1501 );
1502
1503 #[btif_callback(GetReport)]
get_report( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, data: Vec<u8>, size: i32, )1504 fn get_report(
1505 &mut self,
1506 address: RawAddress,
1507 address_type: BtAddrType,
1508 transport: BtTransport,
1509 status: BthhStatus,
1510 data: Vec<u8>,
1511 size: i32,
1512 );
1513
1514 #[btif_callback(Handshake)]
handshake( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, )1515 fn handshake(
1516 &mut self,
1517 address: RawAddress,
1518 address_type: BtAddrType,
1519 transport: BtTransport,
1520 status: BthhStatus,
1521 );
1522 }
1523
1524 #[btif_callbacks_dispatcher(dispatch_sdp_callbacks, SdpCallbacks)]
1525 pub(crate) trait BtifSdpCallbacks {
1526 #[btif_callback(SdpSearch)]
sdp_search( &mut self, status: BtStatus, address: RawAddress, uuid: Uuid, count: i32, records: Vec<BtSdpRecord>, )1527 fn sdp_search(
1528 &mut self,
1529 status: BtStatus,
1530 address: RawAddress,
1531 uuid: Uuid,
1532 count: i32,
1533 records: Vec<BtSdpRecord>,
1534 );
1535 }
1536
get_bt_dispatcher(tx: Sender<Message>) -> BaseCallbacksDispatcher1537 pub fn get_bt_dispatcher(tx: Sender<Message>) -> BaseCallbacksDispatcher {
1538 BaseCallbacksDispatcher {
1539 dispatch: Box::new(move |cb| {
1540 let txl = tx.clone();
1541 topstack::get_runtime().spawn(async move {
1542 let _ = txl.send(Message::Base(cb)).await;
1543 });
1544 }),
1545 }
1546 }
1547
1548 impl BtifBluetoothCallbacks for Bluetooth {
adapter_state_changed(&mut self, state: BtState)1549 fn adapter_state_changed(&mut self, state: BtState) {
1550 let prev_state = self.state.clone();
1551 self.state = state;
1552 metrics::adapter_state_changed(self.state.clone());
1553
1554 // If it's the same state as before, no further action
1555 if self.state == prev_state {
1556 return;
1557 }
1558
1559 match self.state {
1560 BtState::Off => {
1561 self.properties.clear();
1562 match self.remove_pid_file() {
1563 Err(err) => warn!("remove_pid_file() error: {}", err),
1564 _ => (),
1565 }
1566
1567 self.clear_uhid();
1568
1569 // Let the signal notifier know we are turned off.
1570 *self.sig_notifier.enabled.lock().unwrap() = false;
1571 self.sig_notifier.enabled_notify.notify_all();
1572 }
1573
1574 BtState::On => {
1575 // Initialize media
1576 self.bluetooth_media.lock().unwrap().initialize();
1577
1578 // Initialize core profiles
1579 self.init_profiles();
1580
1581 // Trigger properties update
1582 self.intf.lock().unwrap().get_adapter_properties();
1583
1584 // Also need to manually request some properties
1585 self.intf.lock().unwrap().get_adapter_property(BtPropertyType::ClassOfDevice);
1586 let mut controller = controller::Controller::new();
1587 self.le_supported_states = controller.get_ble_supported_states();
1588 self.le_local_supported_features = controller.get_ble_local_supported_features();
1589
1590 // Initialize the BLE scanner for discovery.
1591 let callback_id = self.bluetooth_gatt.lock().unwrap().register_scanner_callback(
1592 Box::new(BleDiscoveryCallbacks::new(self.tx.clone())),
1593 );
1594 self.ble_scanner_uuid =
1595 Some(self.bluetooth_gatt.lock().unwrap().register_scanner(callback_id));
1596
1597 // LibBluetooth saves and restores the discoverable mode on the previous run.
1598 // But on Floss we always want non-discoverable mode on start.
1599 self.set_discoverable(BtDiscMode::NonDiscoverable, 0);
1600 // Update connectable mode so that disconnected bonded classic device can reconnect
1601 self.trigger_update_connectable_mode();
1602
1603 // Spawn a freshness check job in the background.
1604 self.freshness_check.take().map(|h| h.abort());
1605 let txl = self.tx.clone();
1606 self.freshness_check = Some(tokio::spawn(async move {
1607 loop {
1608 time::sleep(FOUND_DEVICE_FRESHNESS).await;
1609 let _ = txl
1610 .send(Message::DelayedAdapterActions(
1611 DelayedActions::DeviceFreshnessCheck,
1612 ))
1613 .await;
1614 }
1615 }));
1616
1617 if self.get_wake_allowed_device_bonded() {
1618 self.create_uhid_for_suspend_wakesource();
1619 }
1620 // Notify the signal notifier that we are turned on.
1621 *self.sig_notifier.enabled.lock().unwrap() = true;
1622 self.sig_notifier.enabled_notify.notify_all();
1623
1624 // Signal that the stack is up and running.
1625 match self.create_pid_file() {
1626 Err(err) => warn!("create_pid_file() error: {}", err),
1627 _ => (),
1628 }
1629
1630 // Inform the rest of the stack we're ready.
1631 let txl = self.tx.clone();
1632 let api_txl = self.api_tx.clone();
1633 tokio::spawn(async move {
1634 let _ = txl.send(Message::AdapterReady).await;
1635 });
1636 tokio::spawn(async move {
1637 let _ = api_txl.send(APIMessage::IsReady(BluetoothAPI::Adapter)).await;
1638 // TODO(b:300202052) make sure media interface is exposed after initialized
1639 let _ = api_txl.send(APIMessage::IsReady(BluetoothAPI::Media)).await;
1640 });
1641 }
1642 }
1643 }
1644
1645 #[allow(unused_variables)]
adapter_properties_changed( &mut self, status: BtStatus, num_properties: i32, properties: Vec<BluetoothProperty>, )1646 fn adapter_properties_changed(
1647 &mut self,
1648 status: BtStatus,
1649 num_properties: i32,
1650 properties: Vec<BluetoothProperty>,
1651 ) {
1652 if status != BtStatus::Success {
1653 return;
1654 }
1655
1656 // Update local property cache
1657 for prop in properties {
1658 self.properties.insert(prop.get_type(), prop.clone());
1659
1660 match &prop {
1661 BluetoothProperty::BdAddr(bdaddr) => {
1662 self.update_local_address(*bdaddr);
1663 }
1664 BluetoothProperty::AdapterBondedDevices(bondlist) => {
1665 for addr in bondlist.iter() {
1666 self.remote_devices
1667 .entry(*addr)
1668 .and_modify(|d| d.bond_state = BtBondState::Bonded)
1669 .or_insert(BluetoothDeviceContext::new(
1670 BtBondState::Bonded,
1671 BtAclState::Disconnected,
1672 BtAclState::Disconnected,
1673 BluetoothDevice::new(*addr, "".to_string()),
1674 Instant::now(),
1675 vec![],
1676 ));
1677 }
1678
1679 // Update the connectable mode since bonded device list might be updated.
1680 self.trigger_update_connectable_mode();
1681 }
1682 BluetoothProperty::BdName(bdname) => {
1683 self.callbacks.for_all_callbacks(|callback| {
1684 callback.on_name_changed(bdname.clone());
1685 });
1686 }
1687 BluetoothProperty::AdapterScanMode(mode) => {
1688 self.callbacks.for_all_callbacks(|callback| {
1689 callback
1690 .on_discoverable_changed(*mode == BtScanMode::ConnectableDiscoverable);
1691 });
1692 }
1693 _ => {}
1694 }
1695
1696 self.callbacks.for_all_callbacks(|callback| {
1697 callback.on_adapter_property_changed(prop.get_type());
1698 });
1699 }
1700 }
1701
device_found(&mut self, _n: i32, properties: Vec<BluetoothProperty>)1702 fn device_found(&mut self, _n: i32, properties: Vec<BluetoothProperty>) {
1703 let device_info = BluetoothDevice::from_properties(&properties);
1704
1705 let device_info = self
1706 .remote_devices
1707 .entry(device_info.address)
1708 .and_modify(|d| {
1709 d.update_properties(&properties);
1710 d.seen();
1711 })
1712 .or_insert(BluetoothDeviceContext::new(
1713 BtBondState::NotBonded,
1714 BtAclState::Disconnected,
1715 BtAclState::Disconnected,
1716 device_info,
1717 Instant::now(),
1718 properties,
1719 ))
1720 .info
1721 .clone();
1722
1723 self.callbacks.for_all_callbacks(|callback| {
1724 callback.on_device_found(device_info.clone());
1725 });
1726
1727 self.bluetooth_admin.lock().unwrap().on_device_found(&device_info);
1728 }
1729
discovery_state(&mut self, state: BtDiscoveryState)1730 fn discovery_state(&mut self, state: BtDiscoveryState) {
1731 let is_discovering = &state == &BtDiscoveryState::Started;
1732
1733 // No-op if we're updating the state to the same value again.
1734 if &is_discovering == &self.is_discovering {
1735 return;
1736 }
1737
1738 // Cache discovering state
1739 self.is_discovering = &state == &BtDiscoveryState::Started;
1740 if self.is_discovering {
1741 self.discovering_started = Instant::now();
1742 }
1743
1744 // Prevent sending out discovering changes or freshness checks when
1745 // suspending. Clients don't need to be notified of discovery pausing
1746 // during suspend. They will probably try to restore it and fail.
1747 let discovery_suspend_mode = self.get_discovery_suspend_mode();
1748 if discovery_suspend_mode != SuspendMode::Normal
1749 && discovery_suspend_mode != SuspendMode::Resuming
1750 {
1751 return;
1752 }
1753
1754 self.callbacks.for_all_callbacks(|callback| {
1755 callback.on_discovering_changed(state == BtDiscoveryState::Started);
1756 });
1757
1758 // Start or stop BLE scanning based on discovering state
1759 if let Some(scanner_id) = self.ble_scanner_id {
1760 if is_discovering {
1761 self.bluetooth_gatt.lock().unwrap().start_active_scan(scanner_id);
1762 } else {
1763 self.bluetooth_gatt.lock().unwrap().stop_active_scan(scanner_id);
1764 }
1765 }
1766
1767 if !self.is_discovering {
1768 if self.pending_create_bond.is_some() {
1769 debug!("Invoking delayed CreateBond");
1770 let tx = self.tx.clone();
1771 tokio::spawn(async move {
1772 let _ =
1773 tx.send(Message::DelayedAdapterActions(DelayedActions::CreateBond)).await;
1774 });
1775 }
1776 }
1777 }
1778
ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32)1779 fn ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32) {
1780 // Accept the Just-Works pairing that we initiated, reject otherwise.
1781 if variant == BtSspVariant::Consent {
1782 let initiated_by_us = Some(remote_addr) == self.active_pairing_address;
1783 self.set_pairing_confirmation(
1784 BluetoothDevice::new(remote_addr, "".to_string()),
1785 initiated_by_us,
1786 );
1787 return;
1788 }
1789
1790 // Currently this supports many agent because we accept many callbacks.
1791 // TODO(b/274706838): We need a way to select the default agent.
1792 self.callbacks.for_all_callbacks(|callback| {
1793 // TODO(b/336960912): libbluetooth changed their API so that we no longer
1794 // get the Device name and CoD, which were included in our DBus API.
1795 // Now we simply put random values since we aren't ready to change our DBus API
1796 // and it works because our Clients are not using these anyway.
1797 callback.on_ssp_request(
1798 BluetoothDevice::new(remote_addr, "".to_string()),
1799 0,
1800 variant.clone(),
1801 passkey,
1802 );
1803 });
1804 }
1805
pin_request( &mut self, remote_addr: RawAddress, remote_name: String, cod: u32, min_16_digit: bool, )1806 fn pin_request(
1807 &mut self,
1808 remote_addr: RawAddress,
1809 remote_name: String,
1810 cod: u32,
1811 min_16_digit: bool,
1812 ) {
1813 let device = BluetoothDevice::new(remote_addr, remote_name.clone());
1814
1815 let digits = match min_16_digit {
1816 true => 16,
1817 false => 6,
1818 };
1819
1820 if is_cod_hid_keyboard(cod) || is_cod_hid_combo(cod) {
1821 debug!("auto gen pin for device {} (cod={:#x})", DisplayAddress(&remote_addr), cod);
1822 // generate a random pin code to display.
1823 let pin = rand::random::<u64>() % pow(10, digits);
1824 let display_pin = format!("{:06}", pin);
1825
1826 // Currently this supports many agent because we accept many callbacks.
1827 // TODO(b/274706838): We need a way to select the default agent.
1828 self.callbacks.for_all_callbacks(|callback| {
1829 callback.on_pin_display(device.clone(), display_pin.clone());
1830 });
1831
1832 let pin_vec = display_pin.chars().map(|d| d.try_into().unwrap()).collect::<Vec<u8>>();
1833
1834 self.set_pin(device, true, pin_vec);
1835 } else {
1836 debug!(
1837 "sending pin request for device {} (cod={:#x}) to clients",
1838 DisplayAddress(&remote_addr),
1839 cod
1840 );
1841 // Currently this supports many agent because we accept many callbacks.
1842 // TODO(b/274706838): We need a way to select the default agent.
1843 self.callbacks.for_all_callbacks(|callback| {
1844 callback.on_pin_request(device.clone(), cod, min_16_digit);
1845 });
1846 }
1847 }
1848
bond_state( &mut self, status: BtStatus, addr: RawAddress, bond_state: BtBondState, fail_reason: i32, )1849 fn bond_state(
1850 &mut self,
1851 status: BtStatus,
1852 addr: RawAddress,
1853 bond_state: BtBondState,
1854 fail_reason: i32,
1855 ) {
1856 // Get the device type before the device is potentially deleted.
1857 let device_type = self.get_remote_type(BluetoothDevice::new(addr, "".to_string()));
1858
1859 // Clear the pairing lock if this call corresponds to the
1860 // active pairing device.
1861 if bond_state != BtBondState::Bonding && self.active_pairing_address == Some(addr) {
1862 self.active_pairing_address = None;
1863 }
1864
1865 if self.get_bond_state_by_addr(&addr) == bond_state {
1866 debug!("[{}]: Unchanged bond_state", DisplayAddress(&addr));
1867 } else {
1868 let entry =
1869 self.remote_devices.entry(addr).and_modify(|d| d.bond_state = bond_state.clone());
1870 match bond_state {
1871 BtBondState::NotBonded => {
1872 if !self.get_wake_allowed_device_bonded() {
1873 self.clear_uhid();
1874 }
1875 // Update the connectable mode since bonded list is changed.
1876 self.trigger_update_connectable_mode();
1877 }
1878 BtBondState::Bonded => {
1879 let device = entry.or_insert(BluetoothDeviceContext::new(
1880 BtBondState::Bonded,
1881 BtAclState::Disconnected,
1882 BtAclState::Disconnected,
1883 BluetoothDevice::new(addr, "".to_string()),
1884 Instant::now(),
1885 vec![],
1886 ));
1887 let device_info = device.info.clone();
1888
1889 // Since this is a newly bonded device, we also need to trigger SDP on it.
1890 device.services_resolved = false;
1891 self.fetch_remote_uuids(device_info);
1892 if self.get_wake_allowed_device_bonded() {
1893 self.create_uhid_for_suspend_wakesource();
1894 }
1895 // Update the connectable mode since bonded list is changed.
1896 self.trigger_update_connectable_mode();
1897 }
1898 BtBondState::Bonding => {}
1899 }
1900 }
1901
1902 // Resume discovery once the bonding process is complete. Discovery was paused before the
1903 // bond request to avoid ACL connection from interfering with active inquiry.
1904 if bond_state == BtBondState::NotBonded || bond_state == BtBondState::Bonded {
1905 self.resume_discovery();
1906 }
1907
1908 // Send bond state changed notifications
1909 self.callbacks.for_all_callbacks(|callback| {
1910 callback.on_bond_state_changed(
1911 status.to_u32().unwrap(),
1912 addr,
1913 bond_state.to_u32().unwrap(),
1914 );
1915 });
1916
1917 // Don't emit the metrics event if we were cancelling the bond.
1918 // It is ok to not send the pairing complete event as the server should ignore the dangling
1919 // pairing attempt event.
1920 // This behavior aligns with BlueZ.
1921 if !self.cancelling_devices.remove(&addr) {
1922 metrics::bond_state_changed(addr, device_type, status, bond_state, fail_reason);
1923 }
1924 }
1925
remote_device_properties_changed( &mut self, _status: BtStatus, addr: RawAddress, _num_properties: i32, properties: Vec<BluetoothProperty>, )1926 fn remote_device_properties_changed(
1927 &mut self,
1928 _status: BtStatus,
1929 addr: RawAddress,
1930 _num_properties: i32,
1931 properties: Vec<BluetoothProperty>,
1932 ) {
1933 let txl = self.tx.clone();
1934
1935 let device = self.remote_devices.entry(addr).or_insert(BluetoothDeviceContext::new(
1936 BtBondState::NotBonded,
1937 BtAclState::Disconnected,
1938 BtAclState::Disconnected,
1939 BluetoothDevice::new(addr, String::from("")),
1940 Instant::now(),
1941 vec![],
1942 ));
1943
1944 device.update_properties(&properties);
1945 device.seen();
1946
1947 Bluetooth::send_metrics_remote_device_info(device);
1948
1949 let info = device.info.clone();
1950
1951 if !device.services_resolved {
1952 let has_uuids = properties.iter().any(|prop| match prop {
1953 BluetoothProperty::Uuids(uu) => uu.len() > 0,
1954 _ => false,
1955 });
1956
1957 // Services are resolved when uuids are fetched.
1958 device.services_resolved |= has_uuids;
1959 }
1960
1961 if device.wait_to_connect && device.services_resolved {
1962 device.wait_to_connect = false;
1963
1964 let sent_info = info.clone();
1965 let tx = txl.clone();
1966 tokio::spawn(async move {
1967 let _ = tx
1968 .send(Message::DelayedAdapterActions(DelayedActions::ConnectAllProfiles(
1969 sent_info,
1970 )))
1971 .await;
1972 });
1973 }
1974
1975 self.callbacks.for_all_callbacks(|callback| {
1976 callback.on_device_properties_changed(
1977 info.clone(),
1978 properties.clone().into_iter().map(|x| x.get_type()).collect(),
1979 );
1980 });
1981
1982 self.bluetooth_admin
1983 .lock()
1984 .unwrap()
1985 .on_remote_device_properties_changed(&info, &properties);
1986
1987 // Only care about device type property changed on bonded device.
1988 // If the property change happens during bonding, it will be updated after bonding complete anyway.
1989 if self.get_bond_state_by_addr(&addr) == BtBondState::Bonded
1990 && properties.iter().any(|prop| match prop {
1991 BluetoothProperty::TypeOfDevice(_) => true,
1992 _ => false,
1993 })
1994 {
1995 // Update the connectable mode since the device type is changed.
1996 self.trigger_update_connectable_mode();
1997 }
1998 }
1999
acl_state( &mut self, status: BtStatus, addr: RawAddress, state: BtAclState, link_type: BtTransport, hci_reason: BtHciErrorCode, conn_direction: BtConnectionDirection, _acl_handle: u16, )2000 fn acl_state(
2001 &mut self,
2002 status: BtStatus,
2003 addr: RawAddress,
2004 state: BtAclState,
2005 link_type: BtTransport,
2006 hci_reason: BtHciErrorCode,
2007 conn_direction: BtConnectionDirection,
2008 _acl_handle: u16,
2009 ) {
2010 // If discovery was previously paused at connect_all_enabled_profiles to avoid an outgoing
2011 // ACL connection colliding with an ongoing inquiry, resume it.
2012 self.resume_discovery();
2013
2014 if status != BtStatus::Success {
2015 warn!(
2016 "Connection to [{}] failed. Status: {:?}, Reason: {:?}",
2017 DisplayAddress(&addr),
2018 status,
2019 hci_reason
2020 );
2021 metrics::acl_connection_state_changed(
2022 addr,
2023 link_type,
2024 status,
2025 BtAclState::Disconnected,
2026 conn_direction,
2027 hci_reason,
2028 );
2029 return;
2030 }
2031
2032 let txl = self.tx.clone();
2033 let device = self.remote_devices.entry(addr).or_insert(BluetoothDeviceContext::new(
2034 BtBondState::NotBonded,
2035 BtAclState::Disconnected,
2036 BtAclState::Disconnected,
2037 BluetoothDevice::new(addr, String::from("")),
2038 Instant::now(),
2039 vec![],
2040 ));
2041
2042 // Only notify if there's been a change in state
2043 if !device.set_transport_state(&link_type, &state) {
2044 return;
2045 }
2046
2047 let info = device.info.clone();
2048 device.acl_reported_transport = link_type;
2049
2050 metrics::acl_connection_state_changed(
2051 addr,
2052 link_type,
2053 BtStatus::Success,
2054 state.clone(),
2055 conn_direction,
2056 hci_reason,
2057 );
2058
2059 match state {
2060 BtAclState::Connected => {
2061 let acl_reported_transport = device.acl_reported_transport.clone();
2062 Bluetooth::send_metrics_remote_device_info(device);
2063 self.connection_callbacks.for_all_callbacks(|callback| {
2064 callback.on_device_connected(info.clone());
2065 });
2066 let transport = match self.get_remote_type(info.clone()) {
2067 BtDeviceType::Bredr => BtTransport::Bredr,
2068 BtDeviceType::Ble => BtTransport::Le,
2069 _ => acl_reported_transport,
2070 };
2071 tokio::spawn(async move {
2072 let _ = txl.send(Message::OnAclConnected(info, transport)).await;
2073 });
2074 }
2075 BtAclState::Disconnected => {
2076 if !device.is_connected() {
2077 self.connection_callbacks.for_all_callbacks(|callback| {
2078 callback.on_device_disconnected(info.clone());
2079 });
2080 }
2081 tokio::spawn(async move {
2082 let _ = txl.send(Message::OnAclDisconnected(info)).await;
2083 });
2084 }
2085 };
2086 // If we are bonding, skip the update here as we will update it after bonding complete anyway.
2087 // This is necessary for RTK controllers, which will break RNR after |Write Scan Enable|
2088 // command. Although this is a bug of RTK controllers, but as we could avoid unwanted page
2089 // scan, it makes sense to extend it to all BT controllers here.
2090 if Some(addr) != self.active_pairing_address {
2091 // Update the connectable since the connected state could be changed.
2092 self.trigger_update_connectable_mode();
2093 }
2094 }
2095
thread_event(&mut self, event: BtThreadEvent)2096 fn thread_event(&mut self, event: BtThreadEvent) {
2097 match event {
2098 BtThreadEvent::Associate => {
2099 // Let the signal notifier know stack is initialized.
2100 *self.sig_notifier.thread_attached.lock().unwrap() = true;
2101 self.sig_notifier.thread_notify.notify_all();
2102 }
2103 BtThreadEvent::Disassociate => {
2104 // Let the signal notifier know stack is done.
2105 *self.sig_notifier.thread_attached.lock().unwrap() = false;
2106 self.sig_notifier.thread_notify.notify_all();
2107 }
2108 }
2109 }
2110 }
2111
2112 struct BleDiscoveryCallbacks {
2113 tx: Sender<Message>,
2114 }
2115
2116 impl BleDiscoveryCallbacks {
new(tx: Sender<Message>) -> Self2117 fn new(tx: Sender<Message>) -> Self {
2118 Self { tx }
2119 }
2120 }
2121
2122 // Handle BLE scanner results.
2123 impl IScannerCallback for BleDiscoveryCallbacks {
on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus)2124 fn on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus) {
2125 let tx = self.tx.clone();
2126 tokio::spawn(async move {
2127 let _ = tx
2128 .send(Message::DelayedAdapterActions(
2129 DelayedActions::BleDiscoveryScannerRegistered(uuid, scanner_id, status),
2130 ))
2131 .await;
2132 });
2133 }
2134
on_scan_result(&mut self, scan_result: ScanResult)2135 fn on_scan_result(&mut self, scan_result: ScanResult) {
2136 let tx = self.tx.clone();
2137 tokio::spawn(async move {
2138 let _ = tx
2139 .send(Message::DelayedAdapterActions(DelayedActions::BleDiscoveryScannerResult(
2140 scan_result,
2141 )))
2142 .await;
2143 });
2144 }
2145
on_advertisement_found(&mut self, _scanner_id: u8, _scan_result: ScanResult)2146 fn on_advertisement_found(&mut self, _scanner_id: u8, _scan_result: ScanResult) {}
on_advertisement_lost(&mut self, _scanner_id: u8, _scan_result: ScanResult)2147 fn on_advertisement_lost(&mut self, _scanner_id: u8, _scan_result: ScanResult) {}
on_suspend_mode_change(&mut self, _suspend_mode: SuspendMode)2148 fn on_suspend_mode_change(&mut self, _suspend_mode: SuspendMode) {}
2149 }
2150
2151 impl RPCProxy for BleDiscoveryCallbacks {
get_object_id(&self) -> String2152 fn get_object_id(&self) -> String {
2153 "BLE Discovery Callback".to_string()
2154 }
2155 }
2156
2157 // TODO: Add unit tests for this implementation
2158 impl IBluetooth for Bluetooth {
register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) -> u322159 fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) -> u32 {
2160 self.callbacks.add_callback(callback)
2161 }
2162
unregister_callback(&mut self, callback_id: u32) -> bool2163 fn unregister_callback(&mut self, callback_id: u32) -> bool {
2164 self.callbacks.remove_callback(callback_id)
2165 }
2166
register_connection_callback( &mut self, callback: Box<dyn IBluetoothConnectionCallback + Send>, ) -> u322167 fn register_connection_callback(
2168 &mut self,
2169 callback: Box<dyn IBluetoothConnectionCallback + Send>,
2170 ) -> u32 {
2171 self.connection_callbacks.add_callback(callback)
2172 }
2173
unregister_connection_callback(&mut self, callback_id: u32) -> bool2174 fn unregister_connection_callback(&mut self, callback_id: u32) -> bool {
2175 self.connection_callbacks.remove_callback(callback_id)
2176 }
2177
init(&mut self, init_flags: Vec<String>) -> bool2178 fn init(&mut self, init_flags: Vec<String>) -> bool {
2179 self.intf.lock().unwrap().initialize(get_bt_dispatcher(self.tx.clone()), init_flags)
2180 }
2181
enable(&mut self) -> bool2182 fn enable(&mut self) -> bool {
2183 self.intf.lock().unwrap().enable() == 0
2184 }
2185
disable(&mut self) -> bool2186 fn disable(&mut self) -> bool {
2187 let success = self.intf.lock().unwrap().disable() == 0;
2188 if success {
2189 self.bluetooth_gatt.lock().unwrap().enable(false);
2190 }
2191 success
2192 }
2193
cleanup(&mut self)2194 fn cleanup(&mut self) {
2195 self.intf.lock().unwrap().cleanup();
2196 }
2197
get_address(&self) -> RawAddress2198 fn get_address(&self) -> RawAddress {
2199 self.local_address.unwrap_or_default()
2200 }
2201
get_uuids(&self) -> Vec<Uuid>2202 fn get_uuids(&self) -> Vec<Uuid> {
2203 match self.properties.get(&BtPropertyType::Uuids) {
2204 Some(prop) => match prop {
2205 BluetoothProperty::Uuids(uuids) => uuids.clone(),
2206 _ => vec![],
2207 },
2208 _ => vec![],
2209 }
2210 }
2211
get_name(&self) -> String2212 fn get_name(&self) -> String {
2213 match self.properties.get(&BtPropertyType::BdName) {
2214 Some(prop) => match prop {
2215 BluetoothProperty::BdName(name) => name.clone(),
2216 _ => String::new(),
2217 },
2218 _ => String::new(),
2219 }
2220 }
2221
set_name(&self, name: String) -> bool2222 fn set_name(&self, name: String) -> bool {
2223 self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::BdName(name)) == 0
2224 }
2225
get_bluetooth_class(&self) -> u322226 fn get_bluetooth_class(&self) -> u32 {
2227 match self.properties.get(&BtPropertyType::ClassOfDevice) {
2228 Some(prop) => match prop {
2229 BluetoothProperty::ClassOfDevice(cod) => cod.clone(),
2230 _ => 0,
2231 },
2232 _ => 0,
2233 }
2234 }
2235
set_bluetooth_class(&self, cod: u32) -> bool2236 fn set_bluetooth_class(&self, cod: u32) -> bool {
2237 self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::ClassOfDevice(cod)) == 0
2238 }
2239
get_discoverable(&self) -> bool2240 fn get_discoverable(&self) -> bool {
2241 self.get_discoverable_mode_internal() != BtDiscMode::NonDiscoverable
2242 }
2243
get_discoverable_timeout(&self) -> u322244 fn get_discoverable_timeout(&self) -> u32 {
2245 match self.properties.get(&BtPropertyType::AdapterDiscoverableTimeout) {
2246 Some(prop) => match prop {
2247 BluetoothProperty::AdapterDiscoverableTimeout(timeout) => timeout.clone(),
2248 _ => 0,
2249 },
2250 _ => 0,
2251 }
2252 }
2253
set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool2254 fn set_discoverable(&mut self, mode: BtDiscMode, duration: u32) -> bool {
2255 let intf = self.intf.lock().unwrap();
2256
2257 // Checks if the duration is valid.
2258 if mode == BtDiscMode::LimitedDiscoverable && (duration > 60 || duration == 0) {
2259 warn!("Invalid duration for setting the device into limited discoverable mode. The valid duration is 1~60 seconds.");
2260 return false;
2261 }
2262
2263 // Don't really set the mode when suspend. The mode would be instead restored on resume.
2264 // However, we still need to set the discoverable timeout so it would properly reset
2265 // |self.discoverable_mode| after resume.
2266 if self.get_scan_suspend_mode() == SuspendMode::Normal {
2267 let scan_mode = match mode {
2268 BtDiscMode::LimitedDiscoverable => BtScanMode::ConnectableLimitedDiscoverable,
2269 BtDiscMode::GeneralDiscoverable => BtScanMode::ConnectableDiscoverable,
2270 BtDiscMode::NonDiscoverable => match self.is_connectable {
2271 true => BtScanMode::Connectable,
2272 false => BtScanMode::None_,
2273 },
2274 };
2275 if intf.set_adapter_property(BluetoothProperty::AdapterDiscoverableTimeout(duration))
2276 != 0
2277 || intf.set_adapter_property(BluetoothProperty::AdapterScanMode(scan_mode)) != 0
2278 {
2279 return false;
2280 }
2281 }
2282
2283 self.discoverable_mode = mode.clone();
2284
2285 // The old timer should be overwritten regardless of what the new mode is.
2286 if let Some(handle) = self.discoverable_timeout.take() {
2287 handle.abort();
2288 }
2289
2290 if mode != BtDiscMode::NonDiscoverable && duration != 0 {
2291 let txl = self.tx.clone();
2292 self.discoverable_timeout = Some(tokio::spawn(async move {
2293 time::sleep(Duration::from_secs(duration.into())).await;
2294 let _ = txl
2295 .send(Message::DelayedAdapterActions(DelayedActions::ResetDiscoverable))
2296 .await;
2297 }));
2298 }
2299
2300 true
2301 }
2302
is_multi_advertisement_supported(&self) -> bool2303 fn is_multi_advertisement_supported(&self) -> bool {
2304 match self.properties.get(&BtPropertyType::LocalLeFeatures) {
2305 Some(prop) => match prop {
2306 BluetoothProperty::LocalLeFeatures(llf) => {
2307 llf.max_adv_instance >= MIN_ADV_INSTANCES_FOR_MULTI_ADV
2308 }
2309 _ => false,
2310 },
2311 _ => false,
2312 }
2313 }
2314
is_le_extended_advertising_supported(&self) -> bool2315 fn is_le_extended_advertising_supported(&self) -> bool {
2316 match self.properties.get(&BtPropertyType::LocalLeFeatures) {
2317 Some(prop) => match prop {
2318 BluetoothProperty::LocalLeFeatures(llf) => llf.le_extended_advertising_supported,
2319 _ => false,
2320 },
2321 _ => false,
2322 }
2323 }
2324
start_discovery(&mut self) -> bool2325 fn start_discovery(&mut self) -> bool {
2326 // Short-circuit to avoid sending multiple start discovery calls.
2327 if self.is_discovering {
2328 return true;
2329 }
2330
2331 // Short-circuit if paused and add the discovery intent to the queue.
2332 if self.is_discovery_paused {
2333 self.pending_discovery = true;
2334 debug!("Queue the discovery request during paused state");
2335 return true;
2336 }
2337
2338 let discovery_suspend_mode = self.get_discovery_suspend_mode();
2339 if discovery_suspend_mode != SuspendMode::Normal
2340 && discovery_suspend_mode != SuspendMode::Resuming
2341 {
2342 log::warn!("start_discovery is not allowed when suspending or suspended.");
2343 return false;
2344 }
2345
2346 self.intf.lock().unwrap().start_discovery() == 0
2347 }
2348
cancel_discovery(&mut self) -> bool2349 fn cancel_discovery(&mut self) -> bool {
2350 // Client no longer want to discover, clear the request
2351 if self.is_discovery_paused {
2352 self.pending_discovery = false;
2353 debug!("Cancel the discovery request during paused state");
2354 }
2355
2356 // Reject the cancel discovery request if the underlying stack is not in a discovering
2357 // state. For example, previous start discovery was enqueued for ongoing discovery.
2358 if !self.is_discovering {
2359 debug!("Reject cancel_discovery as it's not in discovering state.");
2360 return false;
2361 }
2362
2363 let discovery_suspend_mode = self.get_discovery_suspend_mode();
2364 if discovery_suspend_mode != SuspendMode::Normal
2365 && discovery_suspend_mode != SuspendMode::Suspending
2366 {
2367 log::warn!("cancel_discovery is not allowed when resuming or suspended.");
2368 return false;
2369 }
2370
2371 self.intf.lock().unwrap().cancel_discovery() == 0
2372 }
2373
is_discovering(&self) -> bool2374 fn is_discovering(&self) -> bool {
2375 self.is_discovering
2376 }
2377
get_discovery_end_millis(&self) -> u642378 fn get_discovery_end_millis(&self) -> u64 {
2379 if !self.is_discovering {
2380 return 0;
2381 }
2382
2383 let elapsed_ms = self.discovering_started.elapsed().as_millis() as u64;
2384 if elapsed_ms >= DEFAULT_DISCOVERY_TIMEOUT_MS {
2385 0
2386 } else {
2387 DEFAULT_DISCOVERY_TIMEOUT_MS - elapsed_ms
2388 }
2389 }
2390
create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> BtStatus2391 fn create_bond(&mut self, device: BluetoothDevice, transport: BtTransport) -> BtStatus {
2392 let device_type = match transport {
2393 BtTransport::Bredr => BtDeviceType::Bredr,
2394 BtTransport::Le => BtDeviceType::Ble,
2395 _ => self.get_remote_type(device.clone()),
2396 };
2397 let address = device.address;
2398
2399 if let Some(active_address) = self.active_pairing_address {
2400 warn!(
2401 "Bonding requested for {} while already bonding {}, rejecting",
2402 DisplayAddress(&address),
2403 DisplayAddress(&active_address)
2404 );
2405 return BtStatus::Busy;
2406 }
2407
2408 if self.pending_create_bond.is_some() {
2409 warn!("Delayed CreateBond is still pending");
2410 return BtStatus::Busy;
2411 }
2412
2413 // There could be a race between bond complete and bond cancel, which makes
2414 // |cancelling_devices| in a wrong state. Remove the device just in case.
2415 if self.cancelling_devices.remove(&address) {
2416 warn!("Device {} is also cancelling the bond.", DisplayAddress(&address));
2417 }
2418
2419 // BREDR connection won't work when Inquiry / Remote Name Request is in progress.
2420 // If is_discovering, delay the request until discovery state change.
2421 if self.is_discovering {
2422 debug!("Discovering. Delay the CreateBond request until discovery is done.");
2423 self.pause_discovery();
2424 self.pending_create_bond = Some((device, transport));
2425 return BtStatus::Success;
2426 }
2427
2428 // We explicitly log the attempt to start the bonding separate from logging the bond state.
2429 // The start of the attempt is critical to help identify a bonding/pairing session.
2430 metrics::bond_create_attempt(address, device_type.clone());
2431
2432 self.active_pairing_address = Some(address);
2433 let status = self.intf.lock().unwrap().create_bond(&address, transport);
2434
2435 if status != 0 {
2436 metrics::bond_state_changed(
2437 address,
2438 device_type,
2439 BtStatus::from(status as u32),
2440 BtBondState::NotBonded,
2441 0,
2442 );
2443 return BtStatus::from(status as u32);
2444 }
2445
2446 // Creating bond automatically create ACL connection as well, therefore also log metrics
2447 // ACL connection attempt here.
2448 if !self.get_acl_state_by_addr(&address) {
2449 metrics::acl_connect_attempt(address, BtAclState::Connected);
2450 }
2451
2452 return BtStatus::Success;
2453 }
2454
cancel_bond_process(&mut self, device: BluetoothDevice) -> bool2455 fn cancel_bond_process(&mut self, device: BluetoothDevice) -> bool {
2456 if !self.cancelling_devices.insert(device.address) {
2457 warn!(
2458 "Device {} has been added to cancelling_device.",
2459 DisplayAddress(&device.address)
2460 );
2461 }
2462
2463 self.intf.lock().unwrap().cancel_bond(&device.address) == 0
2464 }
2465
remove_bond(&mut self, device: BluetoothDevice) -> bool2466 fn remove_bond(&mut self, device: BluetoothDevice) -> bool {
2467 let address = device.address;
2468
2469 // There could be a race between bond complete and bond cancel, which makes
2470 // |cancelling_devices| in a wrong state. Remove the device just in case.
2471 if self.cancelling_devices.remove(&address) {
2472 warn!("Device {} is also cancelling the bond.", DisplayAddress(&address));
2473 }
2474
2475 let status = self.intf.lock().unwrap().remove_bond(&address);
2476
2477 if status != 0 {
2478 return false;
2479 }
2480
2481 // Removing bond also disconnects the ACL if is connected. Therefore, also log ACL
2482 // disconnection attempt here.
2483 if self.get_acl_state_by_addr(&address) {
2484 metrics::acl_connect_attempt(address, BtAclState::Disconnected);
2485 }
2486
2487 return true;
2488 }
2489
get_bonded_devices(&self) -> Vec<BluetoothDevice>2490 fn get_bonded_devices(&self) -> Vec<BluetoothDevice> {
2491 self.remote_devices
2492 .values()
2493 .filter_map(|d| {
2494 if d.bond_state == BtBondState::Bonded {
2495 Some(d.info.clone())
2496 } else {
2497 None
2498 }
2499 })
2500 .collect()
2501 }
2502
get_bond_state(&self, device: BluetoothDevice) -> BtBondState2503 fn get_bond_state(&self, device: BluetoothDevice) -> BtBondState {
2504 self.get_bond_state_by_addr(&device.address)
2505 }
2506
set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool2507 fn set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool {
2508 if self.get_bond_state_by_addr(&device.address) != BtBondState::Bonding {
2509 warn!("Can't set pin. Device {} isn't bonding.", DisplayAddress(&device.address));
2510 return false;
2511 }
2512
2513 let mut btpin = BtPinCode { pin: array_utils::to_sized_array(&pin_code) };
2514
2515 self.intf.lock().unwrap().pin_reply(
2516 &device.address,
2517 accept as u8,
2518 pin_code.len() as u8,
2519 &mut btpin,
2520 ) == 0
2521 }
2522
set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool2523 fn set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool {
2524 if self.get_bond_state_by_addr(&device.address) != BtBondState::Bonding {
2525 warn!("Can't set passkey. Device {} isn't bonding.", DisplayAddress(&device.address));
2526 return false;
2527 }
2528
2529 let mut tmp: [u8; 4] = [0; 4];
2530 tmp.copy_from_slice(passkey.as_slice());
2531 let passkey = u32::from_ne_bytes(tmp);
2532
2533 self.intf.lock().unwrap().ssp_reply(
2534 &device.address,
2535 BtSspVariant::PasskeyEntry,
2536 accept as u8,
2537 passkey,
2538 ) == 0
2539 }
2540
set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool2541 fn set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool {
2542 self.intf.lock().unwrap().ssp_reply(
2543 &device.address,
2544 BtSspVariant::PasskeyConfirmation,
2545 accept as u8,
2546 0,
2547 ) == 0
2548 }
2549
get_remote_name(&self, device: BluetoothDevice) -> String2550 fn get_remote_name(&self, device: BluetoothDevice) -> String {
2551 match self.get_remote_device_property(&device, &BtPropertyType::BdName) {
2552 Some(BluetoothProperty::BdName(name)) => return name.clone(),
2553 _ => return "".to_string(),
2554 }
2555 }
2556
get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType2557 fn get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType {
2558 match self.get_remote_device_property(&device, &BtPropertyType::TypeOfDevice) {
2559 Some(BluetoothProperty::TypeOfDevice(device_type)) => return device_type,
2560 _ => return BtDeviceType::Unknown,
2561 }
2562 }
2563
get_remote_alias(&self, device: BluetoothDevice) -> String2564 fn get_remote_alias(&self, device: BluetoothDevice) -> String {
2565 match self.get_remote_device_property(&device, &BtPropertyType::RemoteFriendlyName) {
2566 Some(BluetoothProperty::RemoteFriendlyName(name)) => return name.clone(),
2567 _ => "".to_string(),
2568 }
2569 }
2570
set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String)2571 fn set_remote_alias(&mut self, device: BluetoothDevice, new_alias: String) {
2572 let _ = self.set_remote_device_property(
2573 &device,
2574 BtPropertyType::RemoteFriendlyName,
2575 BluetoothProperty::RemoteFriendlyName(new_alias),
2576 );
2577 }
2578
get_remote_class(&self, device: BluetoothDevice) -> u322579 fn get_remote_class(&self, device: BluetoothDevice) -> u32 {
2580 match self.get_remote_device_property(&device, &BtPropertyType::ClassOfDevice) {
2581 Some(BluetoothProperty::ClassOfDevice(class)) => return class,
2582 _ => 0,
2583 }
2584 }
2585
get_remote_appearance(&self, device: BluetoothDevice) -> u162586 fn get_remote_appearance(&self, device: BluetoothDevice) -> u16 {
2587 match self.get_remote_device_property(&device, &BtPropertyType::Appearance) {
2588 Some(BluetoothProperty::Appearance(appearance)) => appearance,
2589 _ => 0,
2590 }
2591 }
2592
get_remote_connected(&self, device: BluetoothDevice) -> bool2593 fn get_remote_connected(&self, device: BluetoothDevice) -> bool {
2594 self.get_connection_state(device) != BtConnectionState::NotConnected
2595 }
2596
get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool2597 fn get_remote_wake_allowed(&self, device: BluetoothDevice) -> bool {
2598 // Wake is allowed if the device supports HIDP or HOGP only.
2599 match self.get_remote_device_property(&device, &BtPropertyType::Uuids) {
2600 Some(BluetoothProperty::Uuids(uuids)) => {
2601 return uuids.iter().any(|&uuid| {
2602 UuidHelper::is_known_profile(&uuid).map_or(false, |profile| {
2603 profile == Profile::Hid || profile == Profile::Hogp
2604 })
2605 });
2606 }
2607 _ => false,
2608 }
2609 }
2610
get_remote_vendor_product_info(&self, device: BluetoothDevice) -> BtVendorProductInfo2611 fn get_remote_vendor_product_info(&self, device: BluetoothDevice) -> BtVendorProductInfo {
2612 match self.get_remote_device_property(&device, &BtPropertyType::VendorProductInfo) {
2613 Some(BluetoothProperty::VendorProductInfo(p)) => p.clone(),
2614 _ => BtVendorProductInfo { vendor_id_src: 0, vendor_id: 0, product_id: 0, version: 0 },
2615 }
2616 }
2617
get_remote_address_type(&self, device: BluetoothDevice) -> BtAddrType2618 fn get_remote_address_type(&self, device: BluetoothDevice) -> BtAddrType {
2619 match self.get_remote_device_property(&device, &BtPropertyType::RemoteAddrType) {
2620 Some(BluetoothProperty::RemoteAddrType(addr_type)) => addr_type,
2621 _ => BtAddrType::Unknown,
2622 }
2623 }
2624
get_remote_rssi(&self, device: BluetoothDevice) -> i82625 fn get_remote_rssi(&self, device: BluetoothDevice) -> i8 {
2626 match self.get_remote_device_property(&device, &BtPropertyType::RemoteRssi) {
2627 Some(BluetoothProperty::RemoteRssi(rssi)) => rssi,
2628 _ => INVALID_RSSI,
2629 }
2630 }
2631
get_connected_devices(&self) -> Vec<BluetoothDevice>2632 fn get_connected_devices(&self) -> Vec<BluetoothDevice> {
2633 self.remote_devices
2634 .values()
2635 .filter_map(|d| if d.is_connected() { Some(d.info.clone()) } else { None })
2636 .collect()
2637 }
2638
get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState2639 fn get_connection_state(&self, device: BluetoothDevice) -> BtConnectionState {
2640 // The underlying api adds whether this is ENCRYPTED_BREDR or ENCRYPTED_LE.
2641 // As long as it is non-zero, it is connected.
2642 self.intf.lock().unwrap().get_connection_state(&device.address)
2643 }
2644
get_profile_connection_state(&self, profile: Uuid) -> ProfileConnectionState2645 fn get_profile_connection_state(&self, profile: Uuid) -> ProfileConnectionState {
2646 if let Some(known) = UuidHelper::is_known_profile(&profile) {
2647 match known {
2648 Profile::A2dpSink | Profile::A2dpSource => {
2649 self.bluetooth_media.lock().unwrap().get_a2dp_connection_state()
2650 }
2651 Profile::Hfp | Profile::HfpAg => {
2652 self.bluetooth_media.lock().unwrap().get_hfp_connection_state()
2653 }
2654 // TODO: (b/223431229) Profile::Hid and Profile::Hogp
2655 _ => ProfileConnectionState::Disconnected,
2656 }
2657 } else {
2658 ProfileConnectionState::Disconnected
2659 }
2660 }
2661
get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid>2662 fn get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid> {
2663 match self.get_remote_device_property(&device, &BtPropertyType::Uuids) {
2664 Some(BluetoothProperty::Uuids(uuids)) => uuids,
2665 _ => vec![],
2666 }
2667 }
2668
fetch_remote_uuids(&self, remote_device: BluetoothDevice) -> bool2669 fn fetch_remote_uuids(&self, remote_device: BluetoothDevice) -> bool {
2670 let Some(device) = self.remote_devices.get(&remote_device.address) else {
2671 warn!("Won't fetch UUIDs on unknown device");
2672 return false;
2673 };
2674
2675 let transport = match self.get_remote_type(device.info.clone()) {
2676 BtDeviceType::Bredr => BtTransport::Bredr,
2677 BtDeviceType::Ble => BtTransport::Le,
2678 _ => device.acl_reported_transport,
2679 };
2680
2681 self.intf.lock().unwrap().get_remote_services(&mut device.info.address.clone(), transport)
2682 == 0
2683 }
2684
sdp_search(&self, mut device: BluetoothDevice, uuid: Uuid) -> bool2685 fn sdp_search(&self, mut device: BluetoothDevice, uuid: Uuid) -> bool {
2686 if let Some(sdp) = self.sdp.as_ref() {
2687 return sdp.sdp_search(&mut device.address, &uuid) == BtStatus::Success;
2688 }
2689 false
2690 }
2691
create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool2692 fn create_sdp_record(&mut self, sdp_record: BtSdpRecord) -> bool {
2693 let mut handle: i32 = -1;
2694 let mut sdp_record = sdp_record;
2695 match self.sdp.as_ref().unwrap().create_sdp_record(&mut sdp_record, &mut handle) {
2696 BtStatus::Success => {
2697 let record_clone = sdp_record.clone();
2698 self.callbacks.for_all_callbacks(|callback| {
2699 callback.on_sdp_record_created(record_clone.clone(), handle);
2700 });
2701 true
2702 }
2703 _ => false,
2704 }
2705 }
2706
remove_sdp_record(&self, handle: i32) -> bool2707 fn remove_sdp_record(&self, handle: i32) -> bool {
2708 self.sdp.as_ref().unwrap().remove_sdp_record(handle) == BtStatus::Success
2709 }
2710
connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> BtStatus2711 fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> BtStatus {
2712 // Profile init must be complete before this api is callable
2713 if !self.profiles_ready {
2714 return BtStatus::NotReady;
2715 }
2716 let addr = device.address;
2717
2718 if !self.get_acl_state_by_addr(&addr) {
2719 // log ACL connection attempt if it's not already connected.
2720 metrics::acl_connect_attempt(addr, BtAclState::Connected);
2721 // Pause discovery before connecting, or the ACL connection request may conflict with
2722 // the ongoing inquiry.
2723 self.pause_discovery();
2724 }
2725
2726 // Check all remote uuids to see if they match enabled profiles and connect them.
2727 let mut has_enabled_uuids = false;
2728 let mut has_classic_media_profile = false;
2729 let mut has_le_media_profile = false;
2730 let mut has_supported_profile = false;
2731 let uuids = self.get_remote_uuids(device.clone());
2732 for uuid in uuids.iter() {
2733 match UuidHelper::is_known_profile(uuid) {
2734 Some(p) => {
2735 if UuidHelper::is_profile_supported(&p) {
2736 match p {
2737 Profile::Hid | Profile::Hogp => {
2738 has_supported_profile = true;
2739 // TODO(b/328675014): Use BtAddrType
2740 // and BtTransport from
2741 // BluetoothDevice instead of default
2742 let status = self.hh.as_ref().unwrap().connect(
2743 &mut addr.clone(),
2744 BtAddrType::Public,
2745 BtTransport::Auto,
2746 );
2747 metrics::profile_connection_state_changed(
2748 addr,
2749 p as u32,
2750 BtStatus::Success,
2751 BthhConnectionState::Connecting as u32,
2752 );
2753
2754 if status != BtStatus::Success {
2755 metrics::profile_connection_state_changed(
2756 addr,
2757 p as u32,
2758 status,
2759 BthhConnectionState::Disconnected as u32,
2760 );
2761 }
2762 }
2763
2764 // TODO(b/317682584): implement policy to connect to LEA, VC, and CSIS
2765 Profile::LeAudio | Profile::VolumeControl | Profile::CoordinatedSet
2766 if !has_le_media_profile =>
2767 {
2768 has_le_media_profile = true;
2769 let txl = self.tx.clone();
2770 topstack::get_runtime().spawn(async move {
2771 let _ = txl
2772 .send(Message::Media(
2773 MediaActions::ConnectLeaGroupByMemberAddress(addr),
2774 ))
2775 .await;
2776 });
2777 }
2778
2779 Profile::A2dpSink | Profile::A2dpSource | Profile::Hfp
2780 if !has_classic_media_profile =>
2781 {
2782 has_supported_profile = true;
2783 has_classic_media_profile = true;
2784 let txl = self.tx.clone();
2785 topstack::get_runtime().spawn(async move {
2786 let _ =
2787 txl.send(Message::Media(MediaActions::Connect(addr))).await;
2788 });
2789 }
2790
2791 Profile::Bas => {
2792 has_supported_profile = true;
2793 let tx = self.tx.clone();
2794 let transport = match self.remote_devices.get(&addr) {
2795 Some(context) => context.acl_reported_transport,
2796 None => return BtStatus::RemoteDeviceDown,
2797 };
2798 let device_to_send = device.clone();
2799 let transport = match self.get_remote_type(device.clone()) {
2800 BtDeviceType::Bredr => BtTransport::Bredr,
2801 BtDeviceType::Ble => BtTransport::Le,
2802 _ => transport,
2803 };
2804 topstack::get_runtime().spawn(async move {
2805 let _ = tx
2806 .send(Message::BatteryService(
2807 BatteryServiceActions::Connect(
2808 device_to_send,
2809 transport,
2810 ),
2811 ))
2812 .await;
2813 });
2814 }
2815
2816 // We don't connect most profiles
2817 _ => (),
2818 }
2819 }
2820 has_enabled_uuids = true;
2821 }
2822 _ => {}
2823 }
2824 }
2825
2826 // If SDP isn't completed yet, we wait for it to complete and retry the connection again.
2827 // Otherwise, this connection request is done, no retry is required.
2828 if !has_enabled_uuids {
2829 warn!("[{}] SDP hasn't completed for device, wait to connect.", DisplayAddress(&addr));
2830 if let Some(d) = self.remote_devices.get_mut(&addr) {
2831 if uuids.len() == 0 || !d.services_resolved {
2832 d.wait_to_connect = true;
2833 }
2834 }
2835 }
2836
2837 // If the SDP has not been completed or the device does not have a profile that we are
2838 // interested in connecting to, resume discovery now. Other cases will be handled in the
2839 // ACL connection state or bond state callbacks.
2840 if !has_enabled_uuids || !has_supported_profile {
2841 self.resume_discovery();
2842 }
2843
2844 return BtStatus::Success;
2845 }
2846
disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool2847 fn disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool {
2848 if !self.profiles_ready {
2849 return false;
2850 }
2851 let addr = device.address;
2852
2853 // log ACL disconnection attempt if it's not already disconnected.
2854 if self.get_acl_state_by_addr(&addr) {
2855 metrics::acl_connect_attempt(addr, BtAclState::Disconnected);
2856 }
2857
2858 let uuids = self.get_remote_uuids(device.clone());
2859 let mut has_classic_media_profile = false;
2860 let mut has_le_media_profile = false;
2861 for uuid in uuids.iter() {
2862 match UuidHelper::is_known_profile(uuid) {
2863 Some(p) => {
2864 if UuidHelper::is_profile_supported(&p) {
2865 match p {
2866 Profile::Hid | Profile::Hogp => {
2867 // TODO(b/328675014): Use BtAddrType
2868 // and BtTransport from
2869 // BluetoothDevice instead of default
2870
2871 // TODO(b/329837967): Determine
2872 // correct reconnection behavior based
2873 // on device instead of the default
2874 self.hh.as_ref().unwrap().disconnect(
2875 &mut addr.clone(),
2876 BtAddrType::Public,
2877 BtTransport::Auto,
2878 /*reconnect_allowed=*/ true,
2879 );
2880 }
2881
2882 // TODO(b/317682584): implement policy to disconnect from LEA, VC, and CSIS
2883 Profile::LeAudio | Profile::VolumeControl | Profile::CoordinatedSet
2884 if !has_le_media_profile =>
2885 {
2886 has_le_media_profile = true;
2887 let txl = self.tx.clone();
2888 topstack::get_runtime().spawn(async move {
2889 let _ = txl
2890 .send(Message::Media(
2891 MediaActions::DisconnectLeaGroupByMemberAddress(addr),
2892 ))
2893 .await;
2894 });
2895 }
2896
2897 Profile::A2dpSink
2898 | Profile::A2dpSource
2899 | Profile::Hfp
2900 | Profile::AvrcpController
2901 if !has_classic_media_profile =>
2902 {
2903 has_classic_media_profile = true;
2904 let txl = self.tx.clone();
2905 topstack::get_runtime().spawn(async move {
2906 let _ = txl
2907 .send(Message::Media(MediaActions::Disconnect(addr)))
2908 .await;
2909 });
2910 }
2911
2912 Profile::Bas => {
2913 let tx = self.tx.clone();
2914 let device_to_send = device.clone();
2915 topstack::get_runtime().spawn(async move {
2916 let _ = tx
2917 .send(Message::BatteryService(
2918 BatteryServiceActions::Disconnect(device_to_send),
2919 ))
2920 .await;
2921 });
2922 }
2923
2924 // We don't connect most profiles
2925 _ => (),
2926 }
2927 }
2928 }
2929 _ => {}
2930 }
2931 }
2932
2933 // Disconnect all socket connections
2934 let txl = self.tx.clone();
2935 topstack::get_runtime().spawn(async move {
2936 let _ =
2937 txl.send(Message::SocketManagerActions(SocketActions::DisconnectAll(addr))).await;
2938 });
2939
2940 // Disconnect all GATT connections
2941 let txl = self.tx.clone();
2942 topstack::get_runtime().spawn(async move {
2943 let _ = txl.send(Message::GattActions(GattActions::Disconnect(device))).await;
2944 });
2945
2946 return true;
2947 }
2948
is_wbs_supported(&self) -> bool2949 fn is_wbs_supported(&self) -> bool {
2950 self.intf.lock().unwrap().get_wbs_supported()
2951 }
2952
is_swb_supported(&self) -> bool2953 fn is_swb_supported(&self) -> bool {
2954 self.intf.lock().unwrap().get_swb_supported()
2955 }
2956
get_supported_roles(&self) -> Vec<BtAdapterRole>2957 fn get_supported_roles(&self) -> Vec<BtAdapterRole> {
2958 let mut roles: Vec<BtAdapterRole> = vec![];
2959
2960 // See Core 5.3, Vol 4, Part E, 7.8.27 for detailed state information
2961 if self.le_supported_states >> 35 & 1 == 1u64 {
2962 roles.push(BtAdapterRole::Central);
2963 }
2964 if self.le_supported_states >> 38 & 1 == 1u64 {
2965 roles.push(BtAdapterRole::Peripheral);
2966 }
2967 if self.le_supported_states >> 28 & 1 == 1u64 {
2968 roles.push(BtAdapterRole::CentralPeripheral);
2969 }
2970
2971 roles
2972 }
2973
is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool2974 fn is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool {
2975 self.intf.lock().unwrap().is_coding_format_supported(coding_format as u8)
2976 }
2977
is_le_audio_supported(&self) -> bool2978 fn is_le_audio_supported(&self) -> bool {
2979 // We determine LE Audio support by checking CIS Central support
2980 // See Core 5.3, Vol 6, 4.6 FEATURE SUPPORT
2981 self.le_local_supported_features >> 28 & 1 == 1u64
2982 }
2983
is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool2984 fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool {
2985 fn is_dual_mode(uuids: Vec<Uuid>) -> bool {
2986 fn get_unwrapped_uuid(profile: Profile) -> Uuid {
2987 *UuidHelper::get_profile_uuid(&profile).unwrap_or(&Uuid::empty())
2988 }
2989
2990 uuids.contains(&get_unwrapped_uuid(Profile::LeAudio))
2991 && (uuids.contains(&get_unwrapped_uuid(Profile::A2dpSink))
2992 || uuids.contains(&get_unwrapped_uuid(Profile::Hfp)))
2993 }
2994
2995 let media = self.bluetooth_media.lock().unwrap();
2996 let group_id = media.get_group_id(device.address);
2997 if group_id == LEA_UNKNOWN_GROUP_ID {
2998 return is_dual_mode(self.get_remote_uuids(device));
2999 }
3000
3001 // Check if any device in the CSIP group is a dual mode audio sink device
3002 media.get_group_devices(group_id).iter().any(|addr| {
3003 is_dual_mode(self.get_remote_uuids(BluetoothDevice::new(*addr, "".to_string())))
3004 })
3005 }
3006
get_dumpsys(&self) -> String3007 fn get_dumpsys(&self) -> String {
3008 NamedTempFile::new()
3009 .and_then(|file| {
3010 let fd = file.as_raw_fd();
3011 self.intf.lock().unwrap().dump(fd);
3012 std::fs::read_to_string(file.path())
3013 })
3014 .unwrap_or_default()
3015 }
3016 }
3017
3018 impl BtifSdpCallbacks for Bluetooth {
sdp_search( &mut self, status: BtStatus, address: RawAddress, uuid: Uuid, _count: i32, records: Vec<BtSdpRecord>, )3019 fn sdp_search(
3020 &mut self,
3021 status: BtStatus,
3022 address: RawAddress,
3023 uuid: Uuid,
3024 _count: i32,
3025 records: Vec<BtSdpRecord>,
3026 ) {
3027 let device_info = match self.remote_devices.get(&address) {
3028 Some(d) => d.info.clone(),
3029 None => BluetoothDevice::new(address, "".to_string()),
3030 };
3031
3032 // The SDP records we get back do not populate the UUID so we populate it ourselves before
3033 // sending them on.
3034 let mut records = records;
3035 records.iter_mut().for_each(|record| {
3036 match record {
3037 BtSdpRecord::HeaderOverlay(header) => header.uuid = uuid,
3038 BtSdpRecord::MapMas(record) => record.hdr.uuid = uuid,
3039 BtSdpRecord::MapMns(record) => record.hdr.uuid = uuid,
3040 BtSdpRecord::PbapPse(record) => record.hdr.uuid = uuid,
3041 BtSdpRecord::PbapPce(record) => record.hdr.uuid = uuid,
3042 BtSdpRecord::OppServer(record) => record.hdr.uuid = uuid,
3043 BtSdpRecord::SapServer(record) => record.hdr.uuid = uuid,
3044 BtSdpRecord::Dip(record) => record.hdr.uuid = uuid,
3045 BtSdpRecord::Mps(record) => record.hdr.uuid = uuid,
3046 };
3047 });
3048 self.callbacks.for_all_callbacks(|callback| {
3049 callback.on_sdp_search_complete(device_info.clone(), uuid, records.clone());
3050 });
3051 debug!(
3052 "Sdp search result found: Status={:?} Address={} Uuid={}",
3053 status,
3054 DisplayAddress(&address),
3055 DisplayUuid(&uuid)
3056 );
3057 }
3058 }
3059
3060 impl BtifHHCallbacks for Bluetooth {
connection_state( &mut self, mut address: RawAddress, address_type: BtAddrType, transport: BtTransport, state: BthhConnectionState, )3061 fn connection_state(
3062 &mut self,
3063 mut address: RawAddress,
3064 address_type: BtAddrType,
3065 transport: BtTransport,
3066 state: BthhConnectionState,
3067 ) {
3068 debug!(
3069 "Hid host connection state updated: Address({}) State({:?})",
3070 DisplayAddress(&address),
3071 state
3072 );
3073
3074 // HID or HOG is not differentiated by the hid host when callback this function. Assume HOG
3075 // if the device is LE only and HID if classic only. And assume HOG if UUID said so when
3076 // device type is dual or unknown.
3077 let device = BluetoothDevice::new(address, "".to_string());
3078 let profile = match self.get_remote_type(device.clone()) {
3079 BtDeviceType::Ble => Profile::Hogp,
3080 BtDeviceType::Bredr => Profile::Hid,
3081 _ => {
3082 if self
3083 .get_remote_uuids(device)
3084 .contains(&UuidHelper::get_profile_uuid(&Profile::Hogp).unwrap())
3085 {
3086 Profile::Hogp
3087 } else {
3088 Profile::Hid
3089 }
3090 }
3091 };
3092
3093 metrics::profile_connection_state_changed(
3094 address,
3095 profile as u32,
3096 BtStatus::Success,
3097 state as u32,
3098 );
3099
3100 if BtBondState::Bonded != self.get_bond_state_by_addr(&address) {
3101 warn!(
3102 "[{}]: Rejecting a unbonded device's attempt to connect to HID/HOG profiles",
3103 DisplayAddress(&address)
3104 );
3105 // TODO(b/329837967): Determine correct reconnection
3106 // behavior based on device instead of the default
3107 self.hh.as_ref().unwrap().disconnect(
3108 &mut address,
3109 address_type,
3110 transport,
3111 /*reconnect_allowed=*/ true,
3112 );
3113 }
3114 }
3115
hid_info( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, info: BthhHidInfo, )3116 fn hid_info(
3117 &mut self,
3118 address: RawAddress,
3119 address_type: BtAddrType,
3120 transport: BtTransport,
3121 info: BthhHidInfo,
3122 ) {
3123 debug!(
3124 "Hid host info updated: Address({}) AddressType({:?}) Transport({:?}) Info({:?})",
3125 DisplayAddress(&address),
3126 address_type,
3127 transport,
3128 info
3129 );
3130 }
3131
protocol_mode( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, mode: BthhProtocolMode, )3132 fn protocol_mode(
3133 &mut self,
3134 address: RawAddress,
3135 address_type: BtAddrType,
3136 transport: BtTransport,
3137 status: BthhStatus,
3138 mode: BthhProtocolMode,
3139 ) {
3140 debug!(
3141 "Hid host protocol mode updated: Address({}) AddressType({:?}) Transport({:?}) Status({:?}) Mode({:?})",
3142 DisplayAddress(&address), address_type, transport,
3143 status,
3144 mode
3145 );
3146 }
3147
idle_time( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, idle_rate: i32, )3148 fn idle_time(
3149 &mut self,
3150 address: RawAddress,
3151 address_type: BtAddrType,
3152 transport: BtTransport,
3153 status: BthhStatus,
3154 idle_rate: i32,
3155 ) {
3156 debug!(
3157 "Hid host idle time updated: Address({}) AddressType({:?}) Transport({:?}) Status({:?}) Idle Rate({:?})",
3158 DisplayAddress(&address), address_type, transport,
3159 status,
3160 idle_rate
3161 );
3162 }
3163
get_report( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, _data: Vec<u8>, size: i32, )3164 fn get_report(
3165 &mut self,
3166 address: RawAddress,
3167 address_type: BtAddrType,
3168 transport: BtTransport,
3169 status: BthhStatus,
3170 _data: Vec<u8>,
3171 size: i32,
3172 ) {
3173 debug!(
3174 "Hid host got report: Address({}) AddressType({:?}) Transport({:?}) Status({:?}) Report Size({:?})",
3175 DisplayAddress(&address), address_type, transport,
3176 status,
3177 size
3178 );
3179 }
3180
handshake( &mut self, address: RawAddress, address_type: BtAddrType, transport: BtTransport, status: BthhStatus, )3181 fn handshake(
3182 &mut self,
3183 address: RawAddress,
3184 address_type: BtAddrType,
3185 transport: BtTransport,
3186 status: BthhStatus,
3187 ) {
3188 debug!(
3189 "Hid host handshake: Address({}) AddressType({:?}) Transport({:?}) Status({:?})",
3190 DisplayAddress(&address),
3191 address_type,
3192 transport,
3193 status
3194 );
3195 }
3196 }
3197
3198 // TODO(b/261143122): Remove these once we migrate to BluetoothQA entirely
3199 impl IBluetoothQALegacy for Bluetooth {
get_connectable(&self) -> bool3200 fn get_connectable(&self) -> bool {
3201 self.get_connectable_internal()
3202 }
3203
set_connectable(&mut self, mode: bool) -> bool3204 fn set_connectable(&mut self, mode: bool) -> bool {
3205 self.set_connectable_internal(mode)
3206 }
3207
get_alias(&self) -> String3208 fn get_alias(&self) -> String {
3209 self.get_alias_internal()
3210 }
3211
get_modalias(&self) -> String3212 fn get_modalias(&self) -> String {
3213 format!("bluetooth:v00E0pC405d{:04x}", FLOSS_VER)
3214 }
3215
get_hid_report( &mut self, addr: RawAddress, report_type: BthhReportType, report_id: u8, ) -> BtStatus3216 fn get_hid_report(
3217 &mut self,
3218 addr: RawAddress,
3219 report_type: BthhReportType,
3220 report_id: u8,
3221 ) -> BtStatus {
3222 self.get_hid_report_internal(addr, report_type, report_id)
3223 }
3224
set_hid_report( &mut self, addr: RawAddress, report_type: BthhReportType, report: String, ) -> BtStatus3225 fn set_hid_report(
3226 &mut self,
3227 addr: RawAddress,
3228 report_type: BthhReportType,
3229 report: String,
3230 ) -> BtStatus {
3231 self.set_hid_report_internal(addr, report_type, report)
3232 }
3233
send_hid_data(&mut self, addr: RawAddress, data: String) -> BtStatus3234 fn send_hid_data(&mut self, addr: RawAddress, data: String) -> BtStatus {
3235 self.send_hid_data_internal(addr, data)
3236 }
3237 }
3238