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