1 //! Shim for `bt_interface_t`, providing access to libbluetooth.
2 //!
3 //! This is a shim interface for calling the C++ bluetooth interface via Rust.
4 
5 use crate::bindings::root as bindings;
6 use crate::topstack::get_dispatchers;
7 use crate::utils::{LTCheckedPtr, LTCheckedPtrMut};
8 use num_derive::{FromPrimitive, ToPrimitive};
9 use num_traits::cast::{FromPrimitive, ToPrimitive};
10 use std::cmp;
11 use std::convert::TryFrom;
12 use std::fmt::{Debug, Display, Formatter, Result};
13 use std::hash::{Hash, Hasher};
14 use std::mem;
15 use std::os::fd::RawFd;
16 use std::os::raw::c_char;
17 use std::ptr::NonNull;
18 use std::sync::{Arc, Mutex};
19 use std::vec::Vec;
20 use topshim_macros::{cb_variant, gen_cxx_extern_trivial};
21 
22 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
23 #[repr(u32)]
24 pub enum BtState {
25     Off = 0,
26     On,
27 }
28 
29 impl From<bindings::bt_state_t> for BtState {
from(item: bindings::bt_state_t) -> Self30     fn from(item: bindings::bt_state_t) -> Self {
31         BtState::from_u32(item).unwrap_or(BtState::Off)
32     }
33 }
34 
35 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd, Copy)]
36 #[repr(u32)]
37 pub enum BtTransport {
38     Auto = 0,
39     Bredr,
40     Le,
41 }
42 
43 impl From<i32> for BtTransport {
from(item: i32) -> Self44     fn from(item: i32) -> Self {
45         BtTransport::from_i32(item).unwrap_or(BtTransport::Auto)
46     }
47 }
48 
49 impl From<BtTransport> for i32 {
from(item: BtTransport) -> Self50     fn from(item: BtTransport) -> Self {
51         item.to_i32().unwrap_or(0)
52     }
53 }
54 
55 impl From<u8> for BtTransport {
from(transport: u8) -> Self56     fn from(transport: u8) -> Self {
57         BtTransport::from_u8(transport).unwrap_or(BtTransport::Auto)
58     }
59 }
60 
61 impl Into<u8> for BtTransport {
into(self) -> u862     fn into(self) -> u8 {
63         self.to_u8().unwrap_or(0)
64     }
65 }
66 
67 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
68 #[repr(u32)]
69 pub enum BtSspVariant {
70     PasskeyConfirmation = 0,
71     PasskeyEntry,
72     Consent,
73     PasskeyNotification,
74 }
75 
76 impl From<bindings::bt_ssp_variant_t> for BtSspVariant {
from(item: bindings::bt_ssp_variant_t) -> Self77     fn from(item: bindings::bt_ssp_variant_t) -> Self {
78         BtSspVariant::from_u32(item).unwrap_or(BtSspVariant::PasskeyConfirmation)
79     }
80 }
81 
82 impl From<BtSspVariant> for bindings::bt_ssp_variant_t {
from(item: BtSspVariant) -> Self83     fn from(item: BtSspVariant) -> Self {
84         item.to_u32().unwrap_or(0)
85     }
86 }
87 
88 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
89 #[repr(u32)]
90 pub enum BtBondState {
91     NotBonded = 0,
92     Bonding,
93     Bonded,
94 }
95 
96 impl From<bindings::bt_bond_state_t> for BtBondState {
from(item: bindings::bt_bond_state_t) -> Self97     fn from(item: bindings::bt_bond_state_t) -> Self {
98         BtBondState::from_u32(item).unwrap_or(BtBondState::NotBonded)
99     }
100 }
101 
102 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
103 #[repr(u32)]
104 pub enum BtConnectionState {
105     NotConnected = 0,
106     ConnectedOnly = 1,
107     EncryptedBredr = 3,
108     EncryptedLe = 5,
109     EncryptedBoth = 7,
110 }
111 
112 impl From<i32> for BtConnectionState {
from(item: i32) -> Self113     fn from(item: i32) -> Self {
114         let fallback = if item > 0 {
115             BtConnectionState::ConnectedOnly
116         } else {
117             BtConnectionState::NotConnected
118         };
119 
120         BtConnectionState::from_i32(item).unwrap_or(fallback)
121     }
122 }
123 
124 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
125 #[repr(u32)]
126 pub enum BtAclState {
127     Connected = 0,
128     Disconnected,
129 }
130 
131 impl From<bindings::bt_acl_state_t> for BtAclState {
from(item: bindings::bt_acl_state_t) -> Self132     fn from(item: bindings::bt_acl_state_t) -> Self {
133         BtAclState::from_u32(item).unwrap_or(BtAclState::Disconnected)
134     }
135 }
136 
137 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
138 #[repr(u32)]
139 pub enum BtDeviceType {
140     Unknown = 0,
141     Bredr,
142     Ble,
143     Dual,
144 }
145 
146 #[derive(Clone, Debug, Eq, Hash, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
147 #[repr(u32)]
148 pub enum BtPropertyType {
149     BdName = 0x1,
150     BdAddr,
151     Uuids,
152     ClassOfDevice,
153     TypeOfDevice,
154     ServiceRecord,
155     Reserved07,
156     AdapterBondedDevices,
157     AdapterDiscoverableTimeout,
158     RemoteFriendlyName,
159     RemoteRssi,
160     RemoteVersionInfo,
161     LocalLeFeatures,
162     LocalIoCaps,
163     LocalIoCapsBle,
164     DynamicAudioBuffer,
165     RemoteIsCoordinatedSetMember,
166     Appearance,
167     VendorProductInfo,
168     // Unimplemented:
169     //  BT_PROPERTY_REMOTE_ASHA_CAPABILITY,
170     //  BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID,
171     //  BT_PROPERTY_REMOTE_MODEL_NUM,
172     RemoteAddrType = 0x18,
173 
174     Unknown = 0xFE,
175     RemoteDeviceTimestamp = 0xFF,
176 }
177 
178 impl From<u32> for BtPropertyType {
from(item: u32) -> Self179     fn from(item: u32) -> Self {
180         BtPropertyType::from_u32(item).unwrap_or(BtPropertyType::Unknown)
181     }
182 }
183 
184 impl From<BtPropertyType> for u32 {
from(item: BtPropertyType) -> Self185     fn from(item: BtPropertyType) -> Self {
186         item.to_u32().unwrap_or(0)
187     }
188 }
189 
190 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
191 #[repr(u32)]
192 pub enum BtDiscoveryState {
193     Stopped = 0x0,
194     Started,
195 }
196 
197 impl From<u32> for BtDiscoveryState {
from(item: u32) -> Self198     fn from(item: u32) -> Self {
199         BtDiscoveryState::from_u32(item).unwrap_or(BtDiscoveryState::Stopped)
200     }
201 }
202 
203 #[derive(Clone, Copy, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
204 #[repr(u32)]
205 pub enum BtStatus {
206     Success = 0,
207     Fail,
208     NotReady,
209     NoMemory,
210     Busy,
211     Done,
212     Unsupported,
213     InvalidParam,
214     Unhandled,
215     AuthFailure,
216     RemoteDeviceDown,
217     AuthRejected,
218     JniEnvironmentError,
219     JniThreadAttachError,
220     WakeLockError,
221     Timeout,
222     DeviceNotFound,
223     UnexpectedState,
224     SocketError,
225 
226     // Any statuses that couldn't be cleanly converted
227     Unknown = 0xff,
228 }
229 
230 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
231 #[repr(u32)]
232 pub enum BtConnectionDirection {
233     Unknown = 0,
234     Outgoing,
235     Incoming,
236 }
237 
238 impl From<u32> for BtConnectionDirection {
from(item: u32) -> Self239     fn from(item: u32) -> Self {
240         BtConnectionDirection::from_u32(item).unwrap_or(BtConnectionDirection::Unknown)
241     }
242 }
243 
ascii_to_string(data: &[u8], length: usize) -> String244 pub fn ascii_to_string(data: &[u8], length: usize) -> String {
245     // We need to reslice data because from_utf8 tries to interpret the
246     // whole slice and not just what is before the null terminated portion
247     let ascii = data
248         .iter()
249         .enumerate()
250         .take_while(|&(pos, &c)| c != 0 && pos < length)
251         .map(|(_pos, &x)| x.clone())
252         .collect::<Vec<u8>>();
253 
254     return String::from_utf8(ascii).unwrap_or_default();
255 }
256 
u32_from_bytes(item: &[u8]) -> u32257 fn u32_from_bytes(item: &[u8]) -> u32 {
258     let mut u: [u8; 4] = [0; 4];
259     let len = std::cmp::min(item.len(), 4);
260     u[0..len].copy_from_slice(&item);
261     u32::from_ne_bytes(u)
262 }
263 
u16_from_bytes(item: &[u8]) -> u16264 fn u16_from_bytes(item: &[u8]) -> u16 {
265     let mut u: [u8; 2] = [0; 2];
266     let len = std::cmp::min(item.len(), 2);
267     u[0..len].copy_from_slice(&item);
268     u16::from_ne_bytes(u)
269 }
270 
271 impl From<bindings::bt_status_t> for BtStatus {
from(item: bindings::bt_status_t) -> Self272     fn from(item: bindings::bt_status_t) -> Self {
273         match BtStatus::from_u32(item) {
274             Some(x) => x,
275             _ => BtStatus::Unknown,
276         }
277     }
278 }
279 
280 impl Into<u32> for BtStatus {
into(self) -> u32281     fn into(self) -> u32 {
282         self.to_u32().unwrap_or_default()
283     }
284 }
285 
286 impl Into<i32> for BtStatus {
into(self) -> i32287     fn into(self) -> i32 {
288         self.to_i32().unwrap_or_default()
289     }
290 }
291 
292 impl From<bindings::bt_bdname_t> for String {
from(item: bindings::bt_bdname_t) -> Self293     fn from(item: bindings::bt_bdname_t) -> Self {
294         ascii_to_string(&item.name, item.name.len())
295     }
296 }
297 
298 #[derive(Debug, Clone)]
299 pub struct BtServiceRecord {
300     pub uuid: bindings::bluetooth::Uuid,
301     pub channel: u16,
302     pub name: String,
303 }
304 
305 impl From<bindings::bt_service_record_t> for BtServiceRecord {
from(item: bindings::bt_service_record_t) -> Self306     fn from(item: bindings::bt_service_record_t) -> Self {
307         let name = item.name.iter().map(|&x| x.clone() as u8).collect::<Vec<u8>>();
308 
309         BtServiceRecord {
310             uuid: item.uuid,
311             channel: item.channel,
312             name: ascii_to_string(name.as_slice(), name.len()),
313         }
314     }
315 }
316 
317 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
318 #[repr(u32)]
319 pub enum BtScanMode {
320     None_,
321     Connectable,
322     ConnectableDiscoverable,
323     ConnectableLimitedDiscoverable,
324 }
325 
326 impl From<bindings::bt_scan_mode_t> for BtScanMode {
from(item: bindings::bt_scan_mode_t) -> Self327     fn from(item: bindings::bt_scan_mode_t) -> Self {
328         BtScanMode::from_u32(item).unwrap_or(BtScanMode::None_)
329     }
330 }
331 
332 impl Into<bindings::bt_scan_mode_t> for BtScanMode {
into(self) -> bindings::bt_scan_mode_t333     fn into(self) -> bindings::bt_scan_mode_t {
334         BtScanMode::to_u32(&self).unwrap_or_default()
335     }
336 }
337 
338 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
339 #[repr(u32)]
340 pub enum BtDiscMode {
341     // reference to system/stack/btm/neighbor_inquiry.h
342     NonDiscoverable = 0,
343     LimitedDiscoverable = 1,
344     GeneralDiscoverable = 2,
345 }
346 
347 impl From<u32> for BtDiscMode {
from(num: u32) -> Self348     fn from(num: u32) -> Self {
349         BtDiscMode::from_u32(num).unwrap_or(BtDiscMode::NonDiscoverable)
350     }
351 }
352 
353 impl Into<u32> for BtDiscMode {
into(self) -> u32354     fn into(self) -> u32 {
355         self.to_u32().unwrap_or(0)
356     }
357 }
358 
359 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
360 #[repr(u32)]
361 pub enum BtThreadEvent {
362     Associate = 0,
363     Disassociate,
364 }
365 
366 impl From<bindings::bt_cb_thread_evt> for BtThreadEvent {
from(item: bindings::bt_cb_thread_evt) -> Self367     fn from(item: bindings::bt_cb_thread_evt) -> Self {
368         BtThreadEvent::from_u32(item).unwrap_or(BtThreadEvent::Associate)
369     }
370 }
371 
372 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
373 #[repr(u32)]
374 pub enum BtIoCap {
375     Out,
376     InOut,
377     In,
378     None_,
379     KbDisp,
380     Max,
381     Unknown = 0xff,
382 }
383 
384 impl From<bindings::bt_io_cap_t> for BtIoCap {
from(item: bindings::bt_io_cap_t) -> Self385     fn from(item: bindings::bt_io_cap_t) -> Self {
386         BtIoCap::from_u32(item).unwrap_or(BtIoCap::Unknown)
387     }
388 }
389 
390 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
391 #[repr(u32)]
392 pub enum BtAddrType {
393     Public,
394     Random,
395     PublicId,
396     RandomId,
397     Unknown = 0xfe,
398     Anonymous = 0xff,
399 }
400 
401 impl From<u32> for BtAddrType {
from(num: u32) -> Self402     fn from(num: u32) -> Self {
403         BtAddrType::from_u32(num).unwrap_or(BtAddrType::Unknown)
404     }
405 }
406 
407 impl Into<u32> for BtAddrType {
into(self) -> u32408     fn into(self) -> u32 {
409         self.to_u32().unwrap_or(0)
410     }
411 }
412 
413 impl From<u8> for BtAddrType {
from(address_type: u8) -> Self414     fn from(address_type: u8) -> Self {
415         BtAddrType::from_u8(address_type).unwrap_or(BtAddrType::Unknown)
416     }
417 }
418 
419 impl Into<u8> for BtAddrType {
into(self) -> u8420     fn into(self) -> u8 {
421         self.to_u8().unwrap_or(0)
422     }
423 }
424 
425 pub type BtHciErrorCode = u8;
426 pub type BtLocalLeFeatures = bindings::bt_local_le_features_t;
427 pub type BtPinCode = bindings::bt_pin_code_t;
428 pub type BtRemoteVersion = bindings::bt_remote_version_t;
429 pub type BtVendorProductInfo = bindings::bt_vendor_product_info_t;
430 
431 impl ToString for BtVendorProductInfo {
to_string(&self) -> String432     fn to_string(&self) -> String {
433         format!(
434             "{}:v{:04X}p{:04X}d{:04X}",
435             match self.vendor_id_src {
436                 1 => "bluetooth",
437                 2 => "usb",
438                 _ => "unknown",
439             },
440             self.vendor_id,
441             self.product_id,
442             self.version
443         )
444     }
445 }
446 
447 impl TryFrom<Uuid> for Vec<u8> {
448     type Error = &'static str;
449 
try_from(value: Uuid) -> std::result::Result<Self, Self::Error>450     fn try_from(value: Uuid) -> std::result::Result<Self, Self::Error> {
451         Ok((&value.uu).to_vec())
452     }
453 }
454 
455 impl TryFrom<Vec<u8>> for Uuid {
456     type Error = &'static str;
457 
try_from(value: Vec<u8>) -> std::result::Result<Self, Self::Error>458     fn try_from(value: Vec<u8>) -> std::result::Result<Self, Self::Error> {
459         // base UUID defined in the Bluetooth specification
460         let mut uu: [u8; 16] =
461             [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x80, 0x0, 0x0, 0x80, 0x5f, 0x9b, 0x34, 0xfb];
462         match value.len() {
463             2 => {
464                 uu[2..4].copy_from_slice(&value[0..2]);
465                 Ok(Uuid::from(uu))
466             }
467             4 => {
468                 uu[0..4].copy_from_slice(&value[0..4]);
469                 Ok(Uuid::from(uu))
470             }
471             16 => {
472                 uu.copy_from_slice(&value[0..16]);
473                 Ok(Uuid::from(uu))
474             }
475             _ => {
476                 Err("Vector size must be exactly 2 (16 bit UUID), 4 (32 bit UUID), or 16 (128 bit UUID).")
477             }
478         }
479     }
480 }
481 
482 impl From<[u8; 16]> for Uuid {
from(value: [u8; 16]) -> Self483     fn from(value: [u8; 16]) -> Self {
484         Self { uu: value }
485     }
486 }
487 
488 impl From<Uuid> for [u8; 16] {
from(uuid: Uuid) -> Self489     fn from(uuid: Uuid) -> Self {
490         uuid.uu
491     }
492 }
493 
494 impl Hash for Uuid {
hash<H: Hasher>(&self, state: &mut H)495     fn hash<H: Hasher>(&self, state: &mut H) {
496         self.uu.hash(state);
497     }
498 }
499 
500 impl Uuid {
501     const BASE_UUID_NUM: u128 = 0x0000000000001000800000805f9b34fbu128;
502     const BASE_UUID_MASK: u128 = !(0xffffffffu128 << 96);
503 
504     /// Creates a Uuid from little endian slice of bytes
try_from_little_endian(value: &[u8]) -> std::result::Result<Uuid, &'static str>505     pub fn try_from_little_endian(value: &[u8]) -> std::result::Result<Uuid, &'static str> {
506         Uuid::try_from(value.iter().rev().cloned().collect::<Vec<u8>>())
507     }
508 
empty() -> Uuid509     pub fn empty() -> Uuid {
510         unsafe { bindings::bluetooth::Uuid_kEmpty }
511     }
512 
from_string<S: Into<String>>(raw: S) -> Option<Self>513     pub fn from_string<S: Into<String>>(raw: S) -> Option<Self> {
514         let raw: String = raw.into();
515 
516         let raw = raw.chars().filter(|c| c.is_digit(16)).collect::<String>();
517         let s = raw.as_str();
518         if s.len() != 32 {
519             return None;
520         }
521 
522         let mut uu = [0; 16];
523         for i in 0..16 {
524             uu[i] = u8::from_str_radix(&s[i * 2..i * 2 + 2], 16).ok()?;
525         }
526 
527         Some(uu.into())
528     }
529 
530     /// Parses an 128-bit UUID into a byte array of shortest representation.
get_shortest_slice(&self) -> &[u8]531     pub fn get_shortest_slice(&self) -> &[u8] {
532         if self.in_16bit_uuid_range() {
533             &self.uu[2..4]
534         } else if self.in_32bit_uuid_range() {
535             &self.uu[0..4]
536         } else {
537             &self.uu[..]
538         }
539     }
540 
541     /// Checks whether the UUID value is in the 16-bit Bluetooth UUID range.
in_16bit_uuid_range(&self) -> bool542     fn in_16bit_uuid_range(&self) -> bool {
543         if !self.in_32bit_uuid_range() {
544             return false;
545         }
546         self.uu[0] == 0 && self.uu[1] == 0
547     }
548 
549     /// Checks whether the UUID value is in the 32-bit Bluetooth UUID range.
in_32bit_uuid_range(&self) -> bool550     fn in_32bit_uuid_range(&self) -> bool {
551         let num = u128::from_be_bytes(self.uu);
552         (num & Self::BASE_UUID_MASK) == Self::BASE_UUID_NUM
553     }
554 }
555 
556 /// Formats this UUID to a human-readable representation.
557 impl Display for Uuid {
fmt(&self, f: &mut Formatter) -> Result558     fn fmt(&self, f: &mut Formatter) -> Result {
559         write!(
560             f,
561             "{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
562             self.uu[0], self.uu[1], self.uu[2], self.uu[3],
563             self.uu[4], self.uu[5],
564             self.uu[6], self.uu[7],
565             self.uu[8], self.uu[9],
566             self.uu[10], self.uu[11], self.uu[12], self.uu[13], self.uu[14], self.uu[15]
567         )
568     }
569 }
570 
571 /// UUID that is safe to display in logs.
572 pub struct DisplayUuid<'a>(pub &'a Uuid);
573 impl<'a> Display for DisplayUuid<'a> {
fmt(&self, f: &mut Formatter) -> Result574     fn fmt(&self, f: &mut Formatter) -> Result {
575         write!(
576             f,
577             "{:02x}{:02x}{:02x}{:02x}-xxxx-xxxx-xxxx-xxxx{:02x}{:02x}{:02x}{:02x}",
578             self.0.uu[0],
579             self.0.uu[1],
580             self.0.uu[2],
581             self.0.uu[3],
582             self.0.uu[12],
583             self.0.uu[13],
584             self.0.uu[14],
585             self.0.uu[15]
586         )
587     }
588 }
589 
590 /// All supported Bluetooth properties after conversion.
591 #[derive(Debug, Clone)]
592 pub enum BluetoothProperty {
593     BdName(String),
594     BdAddr(RawAddress),
595     Uuids(Vec<Uuid>),
596     ClassOfDevice(u32),
597     TypeOfDevice(BtDeviceType),
598     ServiceRecord(BtServiceRecord),
599     AdapterBondedDevices(Vec<RawAddress>),
600     AdapterDiscoverableTimeout(u32),
601     RemoteFriendlyName(String),
602     RemoteRssi(i8),
603     RemoteVersionInfo(BtRemoteVersion),
604     LocalLeFeatures(BtLocalLeFeatures),
605     LocalIoCaps(BtIoCap),
606     LocalIoCapsBle(BtIoCap),
607     DynamicAudioBuffer(),
608     RemoteIsCoordinatedSetMember(bool),
609     Appearance(u16),
610     VendorProductInfo(BtVendorProductInfo),
611     RemoteAddrType(BtAddrType),
612     RemoteDeviceTimestamp(),
613 
614     Unknown(),
615 }
616 
617 /// Unknown or invalid RSSI value.
618 /// Per Core v5.3, Vol 4, E, 7.5.4. Valid RSSI is represent in 1-byte with the range:
619 /// BR/EDR: -128 to 127
620 /// LE: -127 to 20, 127
621 /// Set 127 as invalid value also aligns with bluez.
622 pub const INVALID_RSSI: i8 = 127;
623 
624 /// Wherever names are sent in bindings::bt_property_t, the size of the character
625 /// arrays are 256. Keep one extra byte for null termination.
626 const PROPERTY_NAME_MAX: usize = 255;
627 
628 impl BluetoothProperty {
get_type(&self) -> BtPropertyType629     pub fn get_type(&self) -> BtPropertyType {
630         match &*self {
631             BluetoothProperty::BdName(_) => BtPropertyType::BdName,
632             BluetoothProperty::BdAddr(_) => BtPropertyType::BdAddr,
633             BluetoothProperty::Uuids(_) => BtPropertyType::Uuids,
634             BluetoothProperty::ClassOfDevice(_) => BtPropertyType::ClassOfDevice,
635             BluetoothProperty::TypeOfDevice(_) => BtPropertyType::TypeOfDevice,
636             BluetoothProperty::ServiceRecord(_) => BtPropertyType::ServiceRecord,
637             BluetoothProperty::AdapterBondedDevices(_) => BtPropertyType::AdapterBondedDevices,
638             BluetoothProperty::AdapterDiscoverableTimeout(_) => {
639                 BtPropertyType::AdapterDiscoverableTimeout
640             }
641             BluetoothProperty::RemoteFriendlyName(_) => BtPropertyType::RemoteFriendlyName,
642             BluetoothProperty::RemoteRssi(_) => BtPropertyType::RemoteRssi,
643             BluetoothProperty::RemoteVersionInfo(_) => BtPropertyType::RemoteVersionInfo,
644             BluetoothProperty::LocalLeFeatures(_) => BtPropertyType::LocalLeFeatures,
645             BluetoothProperty::LocalIoCaps(_) => BtPropertyType::LocalIoCaps,
646             BluetoothProperty::LocalIoCapsBle(_) => BtPropertyType::LocalIoCapsBle,
647             BluetoothProperty::DynamicAudioBuffer() => BtPropertyType::DynamicAudioBuffer,
648             BluetoothProperty::RemoteIsCoordinatedSetMember(_) => {
649                 BtPropertyType::RemoteIsCoordinatedSetMember
650             }
651             BluetoothProperty::Appearance(_) => BtPropertyType::Appearance,
652             BluetoothProperty::VendorProductInfo(_) => BtPropertyType::VendorProductInfo,
653             BluetoothProperty::RemoteDeviceTimestamp() => BtPropertyType::RemoteDeviceTimestamp,
654             BluetoothProperty::RemoteAddrType(_) => BtPropertyType::RemoteAddrType,
655             BluetoothProperty::Unknown() => BtPropertyType::Unknown,
656         }
657     }
658 
get_len(&self) -> usize659     fn get_len(&self) -> usize {
660         match &*self {
661             BluetoothProperty::BdName(name) => cmp::min(PROPERTY_NAME_MAX, name.len() + 1),
662             BluetoothProperty::BdAddr(addr) => addr.address.len(),
663             BluetoothProperty::Uuids(uulist) => uulist.len() * mem::size_of::<Uuid>(),
664             BluetoothProperty::ClassOfDevice(_) => mem::size_of::<u32>(),
665             BluetoothProperty::TypeOfDevice(_) => mem::size_of::<BtDeviceType>(),
666             BluetoothProperty::ServiceRecord(rec) => {
667                 mem::size_of::<BtServiceRecord>() + cmp::min(PROPERTY_NAME_MAX, rec.name.len() + 1)
668             }
669             BluetoothProperty::AdapterBondedDevices(devlist) => {
670                 devlist.len() * mem::size_of::<RawAddress>()
671             }
672             BluetoothProperty::AdapterDiscoverableTimeout(_) => mem::size_of::<u32>(),
673             BluetoothProperty::RemoteFriendlyName(name) => {
674                 cmp::min(PROPERTY_NAME_MAX, name.len() + 1)
675             }
676             BluetoothProperty::RemoteRssi(_) => mem::size_of::<i8>(),
677             BluetoothProperty::RemoteVersionInfo(_) => mem::size_of::<BtRemoteVersion>(),
678             BluetoothProperty::LocalLeFeatures(_) => mem::size_of::<BtLocalLeFeatures>(),
679             BluetoothProperty::LocalIoCaps(_) => mem::size_of::<BtIoCap>(),
680             BluetoothProperty::LocalIoCapsBle(_) => mem::size_of::<BtIoCap>(),
681             BluetoothProperty::RemoteIsCoordinatedSetMember(_) => mem::size_of::<bool>(),
682             BluetoothProperty::Appearance(_) => mem::size_of::<u16>(),
683             BluetoothProperty::VendorProductInfo(_) => mem::size_of::<BtVendorProductInfo>(),
684             BluetoothProperty::RemoteAddrType(_) => mem::size_of::<BtAddrType>(),
685 
686             // TODO(abps) - Figure out sizes for these
687             BluetoothProperty::DynamicAudioBuffer() => 0,
688             BluetoothProperty::RemoteDeviceTimestamp() => 0,
689             BluetoothProperty::Unknown() => 0,
690         }
691     }
692 
693     /// Given a mutable array, this will copy the data to that array and return a
694     /// LTCheckedPtrMut to it.
695     ///
696     /// The lifetime of the returned pointer is tied to that of the slice given.
get_data_ptr<'a>(&'a self, data: &'a mut [u8]) -> LTCheckedPtrMut<'a, u8>697     fn get_data_ptr<'a>(&'a self, data: &'a mut [u8]) -> LTCheckedPtrMut<'a, u8> {
698         let len = self.get_len();
699         match &*self {
700             BluetoothProperty::BdName(name) => {
701                 let copy_len = len - 1;
702                 data[0..copy_len].copy_from_slice(&name.as_bytes()[0..copy_len]);
703                 data[copy_len] = 0;
704             }
705             BluetoothProperty::BdAddr(addr) => {
706                 data.copy_from_slice(&addr.address);
707             }
708             BluetoothProperty::Uuids(uulist) => {
709                 for (idx, &uuid) in uulist.iter().enumerate() {
710                     let start = idx * mem::size_of::<Uuid>();
711                     let end = start + mem::size_of::<Uuid>();
712                     data[start..end].copy_from_slice(&uuid.uu);
713                 }
714             }
715             BluetoothProperty::ClassOfDevice(cod) => {
716                 data.copy_from_slice(&cod.to_ne_bytes());
717             }
718             BluetoothProperty::TypeOfDevice(tod) => {
719                 data.copy_from_slice(&BtDeviceType::to_u32(tod).unwrap_or_default().to_ne_bytes());
720             }
721             BluetoothProperty::ServiceRecord(sr) => {
722                 // Do an unsafe cast to binding:: type and assign the values
723                 // The underlying memory location is provided by |data| which will
724                 // have enough space because it uses get_len()
725                 let record =
726                     unsafe { &mut *(data.as_mut_ptr() as *mut bindings::bt_service_record_t) };
727                 record.uuid = sr.uuid;
728                 record.channel = sr.channel;
729                 let name_len = len - mem::size_of::<BtServiceRecord>() - 1;
730                 record.name[0..name_len].copy_from_slice(
731                     &(sr.name.as_bytes().iter().map(|x| *x as c_char).collect::<Vec<c_char>>())
732                         [0..name_len],
733                 );
734                 record.name[name_len] = 0;
735             }
736             BluetoothProperty::AdapterBondedDevices(devlist) => {
737                 for (idx, &dev) in devlist.iter().enumerate() {
738                     let start = idx * mem::size_of::<RawAddress>();
739                     let end = idx + mem::size_of::<RawAddress>();
740                     data[start..end].copy_from_slice(&dev.address);
741                 }
742             }
743             BluetoothProperty::AdapterDiscoverableTimeout(timeout) => {
744                 data.copy_from_slice(&timeout.to_ne_bytes());
745             }
746             BluetoothProperty::RemoteFriendlyName(name) => {
747                 let copy_len = len - 1;
748                 data[0..copy_len].copy_from_slice(&name.as_bytes()[0..copy_len]);
749                 data[copy_len] = 0;
750             }
751             BluetoothProperty::RemoteRssi(rssi) => {
752                 data[0] = *rssi as u8;
753             }
754             BluetoothProperty::RemoteVersionInfo(rvi) => {
755                 let ptr: *const BtRemoteVersion = rvi;
756                 let slice = unsafe {
757                     std::slice::from_raw_parts(ptr as *mut u8, mem::size_of::<BtRemoteVersion>())
758                 };
759                 data.copy_from_slice(&slice);
760             }
761             BluetoothProperty::LocalLeFeatures(llf) => {
762                 let ptr: *const BtLocalLeFeatures = llf;
763                 let slice = unsafe {
764                     std::slice::from_raw_parts(ptr as *mut u8, mem::size_of::<BtLocalLeFeatures>())
765                 };
766                 data.copy_from_slice(&slice);
767             }
768             BluetoothProperty::LocalIoCaps(iocap) => {
769                 data.copy_from_slice(&BtIoCap::to_u32(iocap).unwrap_or_default().to_ne_bytes());
770             }
771             BluetoothProperty::LocalIoCapsBle(iocap) => {
772                 data.copy_from_slice(&BtIoCap::to_u32(iocap).unwrap_or_default().to_ne_bytes());
773             }
774             BluetoothProperty::RemoteIsCoordinatedSetMember(icsm) => {
775                 data[0] = *icsm as u8;
776             }
777             BluetoothProperty::Appearance(appearance) => {
778                 data.copy_from_slice(&appearance.to_ne_bytes());
779             }
780             BluetoothProperty::VendorProductInfo(vpi) => {
781                 let ptr: *const BtVendorProductInfo = vpi;
782                 let slice = unsafe {
783                     std::slice::from_raw_parts(
784                         ptr as *mut u8,
785                         mem::size_of::<BtVendorProductInfo>(),
786                     )
787                 };
788                 data.copy_from_slice(&slice);
789             }
790             BluetoothProperty::RemoteAddrType(addr_type) => {
791                 data.copy_from_slice(
792                     &BtAddrType::to_u32(addr_type).unwrap_or_default().to_ne_bytes(),
793                 );
794             }
795 
796             BluetoothProperty::DynamicAudioBuffer() => (),
797             BluetoothProperty::RemoteDeviceTimestamp() => (),
798             BluetoothProperty::Unknown() => (),
799         };
800 
801         data.into()
802     }
803 }
804 
805 // TODO(abps) - Check that sizes are correct when given a BtProperty
806 impl From<bindings::bt_property_t> for BluetoothProperty {
from(prop: bindings::bt_property_t) -> Self807     fn from(prop: bindings::bt_property_t) -> Self {
808         // Property values may be null, which isn't valid to pass for `slice::from_raw_parts`.
809         // Choose a dangling pointer in that case.
810         let prop_val_ptr =
811             NonNull::new(prop.val as *mut u8).unwrap_or(NonNull::dangling()).as_ptr();
812         let len = prop.len as usize;
813         let slice: &[u8] = unsafe { std::slice::from_raw_parts(prop_val_ptr, len) };
814 
815         match BtPropertyType::from(prop.type_) {
816             BtPropertyType::BdName => BluetoothProperty::BdName(ascii_to_string(slice, len)),
817             BtPropertyType::BdAddr => {
818                 BluetoothProperty::BdAddr(RawAddress::from_bytes(slice).unwrap_or_default())
819             }
820             BtPropertyType::Uuids => {
821                 let count = len / mem::size_of::<Uuid>();
822                 BluetoothProperty::Uuids(ptr_to_vec(prop.val as *const Uuid, count))
823             }
824             BtPropertyType::ClassOfDevice => {
825                 BluetoothProperty::ClassOfDevice(u32_from_bytes(slice))
826             }
827             BtPropertyType::TypeOfDevice => BluetoothProperty::TypeOfDevice(
828                 BtDeviceType::from_u32(u32_from_bytes(slice)).unwrap_or(BtDeviceType::Unknown),
829             ),
830             BtPropertyType::ServiceRecord => {
831                 let v =
832                     unsafe { (prop.val as *const bindings::bt_service_record_t).read_unaligned() };
833                 BluetoothProperty::ServiceRecord(BtServiceRecord::from(v))
834             }
835             BtPropertyType::AdapterBondedDevices => {
836                 let count = len / mem::size_of::<RawAddress>();
837                 BluetoothProperty::AdapterBondedDevices(ptr_to_vec(
838                     prop.val as *const RawAddress,
839                     count,
840                 ))
841             }
842             BtPropertyType::AdapterDiscoverableTimeout => {
843                 BluetoothProperty::AdapterDiscoverableTimeout(u32_from_bytes(slice))
844             }
845             BtPropertyType::RemoteFriendlyName => {
846                 BluetoothProperty::RemoteFriendlyName(ascii_to_string(slice, len))
847             }
848             BtPropertyType::RemoteRssi => BluetoothProperty::RemoteRssi(slice[0] as i8),
849             BtPropertyType::RemoteVersionInfo => {
850                 let v = unsafe { (prop.val as *const BtRemoteVersion).read_unaligned() };
851                 BluetoothProperty::RemoteVersionInfo(v.clone())
852             }
853             BtPropertyType::LocalLeFeatures => {
854                 let v = unsafe { (prop.val as *const BtLocalLeFeatures).read_unaligned() };
855                 BluetoothProperty::LocalLeFeatures(v.clone())
856             }
857             BtPropertyType::LocalIoCaps => BluetoothProperty::LocalIoCaps(
858                 BtIoCap::from_u32(u32_from_bytes(slice)).unwrap_or(BtIoCap::Unknown),
859             ),
860             BtPropertyType::LocalIoCapsBle => BluetoothProperty::LocalIoCapsBle(
861                 BtIoCap::from_u32(u32_from_bytes(slice)).unwrap_or(BtIoCap::Unknown),
862             ),
863             BtPropertyType::RemoteIsCoordinatedSetMember => {
864                 BluetoothProperty::RemoteIsCoordinatedSetMember(slice[0] != 0)
865             }
866             BtPropertyType::Appearance => BluetoothProperty::Appearance(u16_from_bytes(slice)),
867             BtPropertyType::VendorProductInfo => {
868                 let v = unsafe { (prop.val as *const BtVendorProductInfo).read_unaligned() };
869                 BluetoothProperty::VendorProductInfo(BtVendorProductInfo::from(v))
870             }
871             BtPropertyType::RemoteAddrType => BluetoothProperty::RemoteAddrType(
872                 BtAddrType::from_u32(u32_from_bytes(slice)).unwrap_or(BtAddrType::Unknown),
873             ),
874             // TODO(abps) - Figure out if these values should actually have contents
875             BtPropertyType::DynamicAudioBuffer => BluetoothProperty::DynamicAudioBuffer(),
876             BtPropertyType::RemoteDeviceTimestamp => BluetoothProperty::RemoteDeviceTimestamp(),
877             _ => BluetoothProperty::Unknown(),
878         }
879     }
880 }
881 
882 impl From<BluetoothProperty> for (Box<[u8]>, bindings::bt_property_t) {
from(prop: BluetoothProperty) -> Self883     fn from(prop: BluetoothProperty) -> Self {
884         let dvec: Vec<u8> = vec![0; prop.get_len()];
885         let mut data: Box<[u8]> = dvec.into_boxed_slice();
886         let prop = bindings::bt_property_t {
887             type_: prop.get_type().into(),
888             len: prop.get_len() as i32,
889             val: prop.get_data_ptr(&mut data).cast_into::<std::os::raw::c_void>(),
890         };
891 
892         (data, prop)
893     }
894 }
895 
896 pub enum SupportedProfiles {
897     HidHost,
898     Hfp,
899     A2dp,
900     Gatt,
901     Sdp,
902     Socket,
903     HfClient,
904     AvrcpCtrl,
905     LeAudio,
906     VolumeControl,
907     CoordinatedSet,
908 }
909 
910 impl From<SupportedProfiles> for Vec<u8> {
from(item: SupportedProfiles) -> Self911     fn from(item: SupportedProfiles) -> Self {
912         match item {
913             SupportedProfiles::HidHost => "hidhost",
914             SupportedProfiles::Hfp => "handsfree",
915             SupportedProfiles::A2dp => "a2dp",
916             SupportedProfiles::Gatt => "gatt",
917             SupportedProfiles::Sdp => "sdp",
918             SupportedProfiles::Socket => "socket",
919             SupportedProfiles::HfClient => "handsfree_client",
920             SupportedProfiles::AvrcpCtrl => "avrcp_ctrl",
921             SupportedProfiles::LeAudio => "le_audio",
922             SupportedProfiles::VolumeControl => "volume_control",
923             SupportedProfiles::CoordinatedSet => "csis_client",
924         }
925         .bytes()
926         .chain("\0".bytes())
927         .collect::<Vec<u8>>()
928     }
929 }
930 
931 /// Generate impl cxx::ExternType for RawAddress and Uuid.
932 ///
933 /// To make use of RawAddress and Uuid in cxx::bridge C++ blocks,
934 /// include the following snippet in the ffi module.
935 /// ```ignore
936 /// #[cxx::bridge(namespace = bluetooth::topshim::rust)]
937 /// mod ffi {
938 ///     unsafe extern "C++" {
939 ///         include!("types/raw_address.h");
940 ///         include!("types/bluetooth/uuid.h");
941 ///
942 ///         #[namespace = ""]
943 ///         type RawAddress = crate::btif::RawAddress;
944 ///
945 ///         #[namespace = "bluetooth"]
946 ///         type Uuid = crate::btif::Uuid;
947 ///     }
948 ///     // Place you shared stuff here.
949 /// }
950 /// ```
951 #[gen_cxx_extern_trivial]
952 pub type RawAddress = bindings::RawAddress;
953 #[gen_cxx_extern_trivial]
954 pub type Uuid = bindings::bluetooth::Uuid;
955 
956 impl Hash for RawAddress {
hash<H: Hasher>(&self, state: &mut H)957     fn hash<H: Hasher>(&self, state: &mut H) {
958         self.address.hash(state);
959     }
960 }
961 
962 impl ToString for RawAddress {
to_string(&self) -> String963     fn to_string(&self) -> String {
964         format!(
965             "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
966             self.address[0],
967             self.address[1],
968             self.address[2],
969             self.address[3],
970             self.address[4],
971             self.address[5]
972         )
973     }
974 }
975 
976 impl RawAddress {
977     /// Constructs a RawAddress from a slice of 6 bytes.
from_bytes(raw_addr: &[u8]) -> Option<RawAddress>978     pub fn from_bytes(raw_addr: &[u8]) -> Option<RawAddress> {
979         if raw_addr.len() != 6 {
980             return None;
981         }
982         let mut raw: [u8; 6] = [0; 6];
983         raw.copy_from_slice(raw_addr);
984         return Some(RawAddress { address: raw });
985     }
986 
from_string<S: Into<String>>(addr: S) -> Option<RawAddress>987     pub fn from_string<S: Into<String>>(addr: S) -> Option<RawAddress> {
988         let addr: String = addr.into();
989         let s = addr.split(':').collect::<Vec<&str>>();
990 
991         if s.len() != 6 {
992             return None;
993         }
994 
995         let mut raw: [u8; 6] = [0; 6];
996         for i in 0..s.len() {
997             raw[i] = match u8::from_str_radix(s[i], 16) {
998                 Ok(res) => res,
999                 Err(_) => {
1000                     return None;
1001                 }
1002             };
1003         }
1004 
1005         Some(RawAddress { address: raw })
1006     }
1007 
to_byte_arr(&self) -> [u8; 6]1008     pub fn to_byte_arr(&self) -> [u8; 6] {
1009         self.address.clone()
1010     }
1011 
empty() -> RawAddress1012     pub fn empty() -> RawAddress {
1013         unsafe { bindings::RawAddress_kEmpty }
1014     }
1015 }
1016 
1017 /// Address that is safe to display in logs.
1018 pub struct DisplayAddress<'a>(pub &'a RawAddress);
1019 impl<'a> Display for DisplayAddress<'a> {
fmt(&self, f: &mut Formatter) -> Result1020     fn fmt(&self, f: &mut Formatter) -> Result {
1021         if self.0.address.iter().all(|&x| x == 0x00) {
1022             write!(f, "00:00:00:00:00:00")
1023         } else if self.0.address.iter().all(|&x| x == 0xff) {
1024             write!(f, "ff:ff:ff:ff:ff:ff")
1025         } else {
1026             write!(f, "xx:xx:xx:xx:{:02x}:{:02x}", &self.0.address[4], &self.0.address[5])
1027         }
1028     }
1029 }
1030 
1031 pub type OobData = bindings::bt_oob_data_s;
1032 
1033 /// An enum representing `bt_callbacks_t` from btif.
1034 #[derive(Clone, Debug)]
1035 pub enum BaseCallbacks {
1036     AdapterState(BtState),
1037     AdapterProperties(BtStatus, i32, Vec<BluetoothProperty>),
1038     RemoteDeviceProperties(BtStatus, RawAddress, i32, Vec<BluetoothProperty>),
1039     DeviceFound(i32, Vec<BluetoothProperty>),
1040     DiscoveryState(BtDiscoveryState),
1041     PinRequest(RawAddress, String, u32, bool),
1042     SspRequest(RawAddress, BtSspVariant, u32),
1043     BondState(BtStatus, RawAddress, BtBondState, i32),
1044     AddressConsolidate(RawAddress, RawAddress),
1045     LeAddressAssociate(RawAddress, RawAddress, u8),
1046     AclState(
1047         BtStatus,
1048         RawAddress,
1049         BtAclState,
1050         BtTransport,
1051         BtHciErrorCode,
1052         BtConnectionDirection,
1053         u16,
1054     ),
1055     ThreadEvent(BtThreadEvent),
1056     // Unimplemented so far:
1057     // dut_mode_recv_cb
1058     // le_test_mode_cb
1059     // energy_info_cb
1060     // link_quality_report_cb
1061     // switch_buffer_size_cb
1062     // switch_codec_cb
1063     GenerateLocalOobData(u8, Box<OobData>), // Box OobData as its size is much bigger than others
1064     LeRandCallback(u64),
1065     // key_missing_cb
1066     // encryption_change_cb
1067 }
1068 
1069 pub struct BaseCallbacksDispatcher {
1070     pub dispatch: Box<dyn Fn(BaseCallbacks) + Send>,
1071 }
1072 
1073 type BaseCb = Arc<Mutex<BaseCallbacksDispatcher>>;
1074 
1075 cb_variant!(BaseCb, adapter_state_cb -> BaseCallbacks::AdapterState, u32 -> BtState);
1076 cb_variant!(BaseCb, adapter_properties_cb -> BaseCallbacks::AdapterProperties,
1077 u32 -> BtStatus, i32, *mut bindings::bt_property_t, {
1078     let _2 = ptr_to_vec(_2, _1 as usize);
1079 });
1080 cb_variant!(BaseCb, remote_device_properties_cb -> BaseCallbacks::RemoteDeviceProperties,
1081 u32 -> BtStatus, *mut RawAddress -> RawAddress, i32, *mut bindings::bt_property_t, {
1082     let _1 = unsafe { *(_1 as *const RawAddress) };
1083     let _3 = ptr_to_vec(_3, _2 as usize);
1084 });
1085 cb_variant!(BaseCb, device_found_cb -> BaseCallbacks::DeviceFound,
1086 i32, *mut bindings::bt_property_t, {
1087     let _1 = ptr_to_vec(_1, _0 as usize);
1088 });
1089 cb_variant!(BaseCb, discovery_state_cb -> BaseCallbacks::DiscoveryState,
1090     bindings::bt_discovery_state_t -> BtDiscoveryState);
1091 cb_variant!(BaseCb, pin_request_cb -> BaseCallbacks::PinRequest,
1092 *mut RawAddress, *mut bindings::bt_bdname_t, u32, bool, {
1093     let _0 = unsafe { *(_0 as *const RawAddress)};
1094     let _1 = String::from(unsafe{*_1});
1095 });
1096 cb_variant!(BaseCb, ssp_request_cb -> BaseCallbacks::SspRequest,
1097 *mut RawAddress, bindings::bt_ssp_variant_t -> BtSspVariant, u32, {
1098     let _0 = unsafe { *(_0 as *const RawAddress) };
1099 });
1100 cb_variant!(BaseCb, bond_state_cb -> BaseCallbacks::BondState,
1101 u32 -> BtStatus, *mut RawAddress, bindings::bt_bond_state_t -> BtBondState, i32, {
1102     let _1 = unsafe { *(_1 as *const RawAddress) };
1103 });
1104 
1105 cb_variant!(BaseCb, address_consolidate_cb -> BaseCallbacks::AddressConsolidate,
1106 *mut RawAddress, *mut RawAddress, {
1107     let _0 = unsafe { *(_0 as *const RawAddress) };
1108     let _1 = unsafe { *(_1 as *const RawAddress) };
1109 });
1110 
1111 cb_variant!(BaseCb, le_address_associate_cb -> BaseCallbacks::LeAddressAssociate,
1112 *mut RawAddress, *mut RawAddress, u8, {
1113     let _0 = unsafe { *(_0 as *const RawAddress) };
1114     let _1 = unsafe { *(_1 as *const RawAddress) };
1115 });
1116 
1117 cb_variant!(BaseCb, thread_evt_cb -> BaseCallbacks::ThreadEvent, u32 -> BtThreadEvent);
1118 
1119 cb_variant!(BaseCb, acl_state_cb -> BaseCallbacks::AclState,
1120 u32 -> BtStatus, *mut RawAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, bindings::bt_conn_direction_t -> BtConnectionDirection, u16 -> u16, {
1121     let _1 = unsafe { *(_1 as *const RawAddress) };
1122 });
1123 
1124 cb_variant!(BaseCb, generate_local_oob_data_cb -> BaseCallbacks::GenerateLocalOobData, u8, OobData -> Box::<OobData>);
1125 
1126 cb_variant!(BaseCb, le_rand_cb -> BaseCallbacks::LeRandCallback, u64);
1127 
1128 struct RawInterfaceWrapper {
1129     pub raw: *const bindings::bt_interface_t,
1130 }
1131 
1132 unsafe impl Send for RawInterfaceWrapper {}
1133 
1134 /// Macro to call functions via function pointers. Expects the self object to
1135 /// have a raw interface wrapper at `self.internal`. The actual function call is
1136 /// marked unsafe since it will need to dereference a C object. This can cause
1137 /// segfaults if not validated beforehand.
1138 ///
1139 /// Example:
1140 ///     ccall!(self, foobar, arg1, arg2)
1141 ///     Expands to: unsafe {((*self.internal.raw).foobar.unwrap())(arg1, arg2)}
1142 #[macro_export]
1143 macro_rules! ccall {
1144     ($self:ident,$fn_name:ident) => {
1145         unsafe {
1146             ((*$self.internal.raw).$fn_name.unwrap())()
1147         }
1148     };
1149     ($self:ident,$fn_name:ident, $($args:expr),*) => {
1150         unsafe {
1151             ((*$self.internal.raw).$fn_name.unwrap())($($args),*)
1152         }
1153     };
1154 }
1155 
1156 /// Macro to call const functions via cxx. Expects the self object to have the
1157 /// cxx object to be called at `self.internal_cxx`.
1158 ///
1159 /// Example:
1160 ///     cxxcall!(self, foobar, arg1, arg2)
1161 ///     Expands to: self.internal_cxx.foobar(arg1, arg2)
1162 #[macro_export]
1163 macro_rules! cxxcall {
1164     ($self:expr,$fn_name:ident) => {
1165         $self.internal_cxx.$fn_name()
1166     };
1167     ($self:expr,$fn_name:ident, $($args:expr),*) => {
1168         $self.internal_cxx.$fn_name($($args),*)
1169     };
1170 }
1171 
1172 /// Macro to call mutable functions via cxx. Mutable functions are always
1173 /// required to be defined with `self: Pin<&mut Self>`. The self object must
1174 /// have the cxx object at `self.internal_cxx`.
1175 ///
1176 /// Example:
1177 ///     mutcxxcall!(self, foobar, arg1, arg2)
1178 ///     Expands to: self.internal_cxx.pin_mut().foobar(arg1, arg2)
1179 #[macro_export]
1180 macro_rules! mutcxxcall {
1181     ($self:expr,$fn_name:ident) => {
1182         $self.internal_cxx.pin_mut().$fn_name()
1183     };
1184     ($self:expr,$fn_name:ident, $($args:expr),*) => {
1185         $self.internal_cxx.pin_mut().$fn_name($($args),*)
1186     };
1187 }
1188 
1189 #[no_mangle]
wake_lock_noop(_0: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int1190 extern "C" fn wake_lock_noop(_0: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int {
1191     // The wakelock mechanism is not available on this platform,
1192     // so just returning success to avoid error log.
1193     0
1194 }
1195 
1196 /// Rust wrapper around `bt_interface_t`.
1197 pub struct BluetoothInterface {
1198     internal: RawInterfaceWrapper,
1199 
1200     /// Set to true after `initialize` is called.
1201     pub is_init: bool,
1202 
1203     // Need to take ownership of callbacks so it doesn't get freed after init
1204     callbacks: Option<Box<bindings::bt_callbacks_t>>,
1205     os_callouts: Option<Box<bindings::bt_os_callouts_t>>,
1206 }
1207 
1208 impl BluetoothInterface {
is_initialized(&self) -> bool1209     pub fn is_initialized(&self) -> bool {
1210         self.is_init
1211     }
1212 
1213     /// Initialize the Bluetooth interface by setting up the underlying interface.
1214     ///
1215     /// # Arguments
1216     ///
1217     /// * `callbacks` - Dispatcher struct that accepts [`BaseCallbacks`]
1218     /// * `hci_index` - Index of the hci adapter in use
initialize(&mut self, callbacks: BaseCallbacksDispatcher, hci_index: i32) -> bool1219     pub fn initialize(&mut self, callbacks: BaseCallbacksDispatcher, hci_index: i32) -> bool {
1220         if get_dispatchers().lock().unwrap().set::<BaseCb>(Arc::new(Mutex::new(callbacks))) {
1221             panic!("Tried to set dispatcher for BaseCallbacks but it already existed");
1222         }
1223 
1224         // Fill up callbacks struct to pass to init function (will be copied so
1225         // no need to worry about ownership)
1226         let mut callbacks = Box::new(bindings::bt_callbacks_t {
1227             size: std::mem::size_of::<bindings::bt_callbacks_t>(),
1228             adapter_state_changed_cb: Some(adapter_state_cb),
1229             adapter_properties_cb: Some(adapter_properties_cb),
1230             remote_device_properties_cb: Some(remote_device_properties_cb),
1231             device_found_cb: Some(device_found_cb),
1232             discovery_state_changed_cb: Some(discovery_state_cb),
1233             pin_request_cb: Some(pin_request_cb),
1234             ssp_request_cb: Some(ssp_request_cb),
1235             bond_state_changed_cb: Some(bond_state_cb),
1236             address_consolidate_cb: Some(address_consolidate_cb),
1237             le_address_associate_cb: Some(le_address_associate_cb),
1238             acl_state_changed_cb: Some(acl_state_cb),
1239             thread_evt_cb: Some(thread_evt_cb),
1240             dut_mode_recv_cb: None,
1241             le_test_mode_cb: None,
1242             energy_info_cb: None,
1243             link_quality_report_cb: None,
1244             generate_local_oob_data_cb: Some(generate_local_oob_data_cb),
1245             switch_buffer_size_cb: None,
1246             switch_codec_cb: None,
1247             le_rand_cb: Some(le_rand_cb),
1248             key_missing_cb: None,
1249             encryption_change_cb: None,
1250         });
1251 
1252         let cb_ptr = LTCheckedPtrMut::from(&mut callbacks);
1253 
1254         let (guest_mode, is_common_criteria_mode, config_compare_result, is_atv) =
1255             (false, false, 0, false);
1256 
1257         ccall!(self, set_adapter_index, hci_index);
1258         let init = ccall!(
1259             self,
1260             init,
1261             cb_ptr.into(),
1262             guest_mode,
1263             is_common_criteria_mode,
1264             config_compare_result,
1265             is_atv
1266         );
1267 
1268         self.is_init = init == 0;
1269         self.callbacks = Some(callbacks);
1270 
1271         if self.is_init {
1272             // Fill up OSI function table and register it with BTIF.
1273             // TODO(b/271931441) - pass a NoOpOsCallouts structure from
1274             // gd/rust/linux/stack.
1275             let mut callouts = Box::new(bindings::bt_os_callouts_t {
1276                 size: std::mem::size_of::<bindings::bt_os_callouts_t>(),
1277                 acquire_wake_lock: Some(wake_lock_noop),
1278                 release_wake_lock: Some(wake_lock_noop),
1279             });
1280             let callouts_ptr = LTCheckedPtrMut::from(&mut callouts);
1281             ccall!(self, set_os_callouts, callouts_ptr.into());
1282             self.os_callouts = Some(callouts);
1283         }
1284 
1285         return self.is_init;
1286     }
1287 
cleanup(&self)1288     pub fn cleanup(&self) {
1289         ccall!(self, cleanup)
1290     }
1291 
enable(&self) -> i321292     pub fn enable(&self) -> i32 {
1293         ccall!(self, enable)
1294     }
1295 
disable(&self) -> i321296     pub fn disable(&self) -> i32 {
1297         ccall!(self, disable)
1298     }
1299 
get_adapter_properties(&self) -> i321300     pub fn get_adapter_properties(&self) -> i32 {
1301         ccall!(self, get_adapter_properties)
1302     }
1303 
get_adapter_property(&self, prop: BtPropertyType) -> i321304     pub fn get_adapter_property(&self, prop: BtPropertyType) -> i32 {
1305         let converted_type = bindings::bt_property_type_t::from(prop);
1306         ccall!(self, get_adapter_property, converted_type)
1307     }
1308 
set_adapter_property(&self, prop: BluetoothProperty) -> i321309     pub fn set_adapter_property(&self, prop: BluetoothProperty) -> i32 {
1310         let prop_pair: (Box<[u8]>, bindings::bt_property_t) = prop.into();
1311         let prop_ptr = LTCheckedPtr::from_ref(&prop_pair.1);
1312         ccall!(self, set_adapter_property, prop_ptr.into())
1313     }
1314 
set_scan_mode(&self, mode: BtScanMode)1315     pub fn set_scan_mode(&self, mode: BtScanMode) {
1316         ccall!(self, set_scan_mode, mode.into())
1317     }
1318 
get_remote_device_properties(&self, addr: &mut RawAddress) -> i321319     pub fn get_remote_device_properties(&self, addr: &mut RawAddress) -> i32 {
1320         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1321         ccall!(self, get_remote_device_properties, addr_ptr.into())
1322     }
1323 
get_remote_device_property( &self, addr: &mut RawAddress, prop_type: BtPropertyType, ) -> i321324     pub fn get_remote_device_property(
1325         &self,
1326         addr: &mut RawAddress,
1327         prop_type: BtPropertyType,
1328     ) -> i32 {
1329         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1330         let converted_type = bindings::bt_property_type_t::from(prop_type);
1331         ccall!(self, get_remote_device_property, addr_ptr.into(), converted_type)
1332     }
1333 
set_remote_device_property( &self, addr: &mut RawAddress, prop: BluetoothProperty, ) -> i321334     pub fn set_remote_device_property(
1335         &self,
1336         addr: &mut RawAddress,
1337         prop: BluetoothProperty,
1338     ) -> i32 {
1339         let prop_pair: (Box<[u8]>, bindings::bt_property_t) = prop.into();
1340         let prop_ptr = LTCheckedPtr::from_ref(&prop_pair.1);
1341         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1342         ccall!(self, set_remote_device_property, addr_ptr.into(), prop_ptr.into())
1343     }
1344 
get_remote_services(&self, addr: &mut RawAddress, transport: BtTransport) -> i321345     pub fn get_remote_services(&self, addr: &mut RawAddress, transport: BtTransport) -> i32 {
1346         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1347         ccall!(self, get_remote_services, addr_ptr.into(), transport.to_i32().unwrap())
1348     }
1349 
start_discovery(&self) -> i321350     pub fn start_discovery(&self) -> i32 {
1351         ccall!(self, start_discovery)
1352     }
1353 
cancel_discovery(&self) -> i321354     pub fn cancel_discovery(&self) -> i32 {
1355         ccall!(self, cancel_discovery)
1356     }
1357 
pairing_is_busy(&self) -> bool1358     pub fn pairing_is_busy(&self) -> bool {
1359         ccall!(self, pairing_is_busy)
1360     }
1361 
create_bond(&self, addr: &RawAddress, transport: BtTransport) -> i321362     pub fn create_bond(&self, addr: &RawAddress, transport: BtTransport) -> i32 {
1363         let ctransport: i32 = transport.into();
1364         let addr_ptr = LTCheckedPtr::from_ref(addr);
1365         ccall!(self, create_bond, addr_ptr.into(), ctransport)
1366     }
1367 
remove_bond(&self, addr: &RawAddress) -> i321368     pub fn remove_bond(&self, addr: &RawAddress) -> i32 {
1369         let addr_ptr = LTCheckedPtr::from_ref(addr);
1370         ccall!(self, remove_bond, addr_ptr.into())
1371     }
1372 
cancel_bond(&self, addr: &RawAddress) -> i321373     pub fn cancel_bond(&self, addr: &RawAddress) -> i32 {
1374         let addr_ptr = LTCheckedPtr::from_ref(addr);
1375         ccall!(self, cancel_bond, addr_ptr.into())
1376     }
1377 
get_connection_state(&self, addr: &RawAddress) -> BtConnectionState1378     pub fn get_connection_state(&self, addr: &RawAddress) -> BtConnectionState {
1379         let addr_ptr = LTCheckedPtr::from_ref(addr);
1380         ccall!(self, get_connection_state, addr_ptr.into()).into()
1381     }
1382 
pin_reply( &self, addr: &RawAddress, accept: u8, pin_len: u8, pin_code: &mut BtPinCode, ) -> i321383     pub fn pin_reply(
1384         &self,
1385         addr: &RawAddress,
1386         accept: u8,
1387         pin_len: u8,
1388         pin_code: &mut BtPinCode,
1389     ) -> i32 {
1390         let addr_ptr = LTCheckedPtr::from_ref(addr);
1391         let pin_code_ptr = LTCheckedPtrMut::from_ref(pin_code);
1392         ccall!(self, pin_reply, addr_ptr.into(), accept, pin_len, pin_code_ptr.into())
1393     }
1394 
ssp_reply( &self, addr: &RawAddress, variant: BtSspVariant, accept: u8, passkey: u32, ) -> i321395     pub fn ssp_reply(
1396         &self,
1397         addr: &RawAddress,
1398         variant: BtSspVariant,
1399         accept: u8,
1400         passkey: u32,
1401     ) -> i32 {
1402         let addr_ptr = LTCheckedPtr::from_ref(addr);
1403         let cvariant = bindings::bt_ssp_variant_t::from(variant);
1404         ccall!(self, ssp_reply, addr_ptr.into(), cvariant, accept, passkey)
1405     }
1406 
clear_event_filter(&self) -> i321407     pub fn clear_event_filter(&self) -> i32 {
1408         ccall!(self, clear_event_filter)
1409     }
1410 
clear_event_mask(&self) -> i321411     pub fn clear_event_mask(&self) -> i32 {
1412         ccall!(self, clear_event_mask)
1413     }
1414 
clear_filter_accept_list(&self) -> i321415     pub fn clear_filter_accept_list(&self) -> i32 {
1416         ccall!(self, clear_filter_accept_list)
1417     }
1418 
disconnect_all_acls(&self) -> i321419     pub fn disconnect_all_acls(&self) -> i32 {
1420         ccall!(self, disconnect_all_acls)
1421     }
1422 
allow_wake_by_hid(&self) -> i321423     pub fn allow_wake_by_hid(&self) -> i32 {
1424         ccall!(self, allow_wake_by_hid)
1425     }
1426 
get_wbs_supported(&self) -> bool1427     pub fn get_wbs_supported(&self) -> bool {
1428         ccall!(self, get_wbs_supported)
1429     }
1430 
get_swb_supported(&self) -> bool1431     pub fn get_swb_supported(&self) -> bool {
1432         ccall!(self, get_swb_supported)
1433     }
1434 
is_coding_format_supported(&self, coding_format: u8) -> bool1435     pub fn is_coding_format_supported(&self, coding_format: u8) -> bool {
1436         ccall!(self, is_coding_format_supported, coding_format)
1437     }
1438 
le_rand(&self) -> i321439     pub fn le_rand(&self) -> i32 {
1440         ccall!(self, le_rand)
1441     }
1442 
generate_local_oob_data(&self, transport: i32) -> i321443     pub fn generate_local_oob_data(&self, transport: i32) -> i32 {
1444         ccall!(self, generate_local_oob_data, transport as u8)
1445     }
1446 
restore_filter_accept_list(&self) -> i321447     pub fn restore_filter_accept_list(&self) -> i32 {
1448         ccall!(self, restore_filter_accept_list)
1449     }
1450 
set_default_event_mask_except(&self, mask: u64, le_mask: u64) -> i321451     pub fn set_default_event_mask_except(&self, mask: u64, le_mask: u64) -> i32 {
1452         ccall!(self, set_default_event_mask_except, mask, le_mask)
1453     }
1454 
set_event_filter_inquiry_result_all_devices(&self) -> i321455     pub fn set_event_filter_inquiry_result_all_devices(&self) -> i32 {
1456         ccall!(self, set_event_filter_inquiry_result_all_devices)
1457     }
1458 
set_event_filter_connection_setup_all_devices(&self) -> i321459     pub fn set_event_filter_connection_setup_all_devices(&self) -> i32 {
1460         ccall!(self, set_event_filter_connection_setup_all_devices)
1461     }
1462 
get_profile_interface( &self, profile: SupportedProfiles, ) -> *const std::os::raw::c_void1463     pub(crate) fn get_profile_interface(
1464         &self,
1465         profile: SupportedProfiles,
1466     ) -> *const std::os::raw::c_void {
1467         let cprofile = Vec::<u8>::from(profile);
1468         let cprofile_ptr = LTCheckedPtr::from(&cprofile);
1469         ccall!(self, get_profile_interface, cprofile_ptr.cast_into::<std::os::raw::c_char>())
1470     }
1471 
as_raw_ptr(&self) -> *const u81472     pub(crate) fn as_raw_ptr(&self) -> *const u8 {
1473         self.internal.raw as *const u8
1474     }
1475 
dump(&self, fd: RawFd)1476     pub fn dump(&self, fd: RawFd) {
1477         ccall!(self, dump, fd, std::ptr::null_mut())
1478     }
1479 }
1480 
1481 pub trait ToggleableProfile {
is_enabled(&self) -> bool1482     fn is_enabled(&self) -> bool;
enable(&mut self) -> bool1483     fn enable(&mut self) -> bool;
disable(&mut self) -> bool1484     fn disable(&mut self) -> bool;
1485 }
1486 
get_btinterface() -> BluetoothInterface1487 pub fn get_btinterface() -> BluetoothInterface {
1488     let mut ifptr: *const bindings::bt_interface_t = std::ptr::null();
1489 
1490     if unsafe { bindings::hal_util_load_bt_library(&mut ifptr) } == 0 {
1491         BluetoothInterface {
1492             internal: RawInterfaceWrapper { raw: ifptr },
1493             is_init: false,
1494             callbacks: None,
1495             os_callouts: None,
1496         }
1497     } else {
1498         panic!("Failed to get BluetoothInterface");
1499     }
1500 }
1501 
1502 // Turns C-array T[] to Vec<U>.
ptr_to_vec<T: Copy, U: From<T>>(start: *const T, length: usize) -> Vec<U>1503 pub(crate) fn ptr_to_vec<T: Copy, U: From<T>>(start: *const T, length: usize) -> Vec<U> {
1504     unsafe {
1505         (0..length).map(|i| U::from(start.offset(i as isize).read_unaligned())).collect::<Vec<U>>()
1506     }
1507 }
1508 
1509 #[cfg(test)]
1510 mod tests {
1511     use super::*;
1512 
make_bdname_from_slice(slice: &[u8]) -> bindings::bt_bdname_t1513     fn make_bdname_from_slice(slice: &[u8]) -> bindings::bt_bdname_t {
1514         // Length of slice must be less than bd_name max
1515         assert!(slice.len() <= 249);
1516 
1517         let mut bdname = bindings::bt_bdname_t { name: [128; 249] };
1518 
1519         for (i, v) in slice.iter().enumerate() {
1520             bdname.name[i] = v.clone();
1521         }
1522 
1523         bdname
1524     }
1525 
1526     #[test]
test_bdname_conversions()1527     fn test_bdname_conversions() {
1528         let hello_bdname = make_bdname_from_slice(&[72, 69, 76, 76, 79, 0]);
1529         assert_eq!("HELLO".to_string(), String::from(hello_bdname));
1530 
1531         let empty_bdname = make_bdname_from_slice(&[0]);
1532         assert_eq!("".to_string(), String::from(empty_bdname));
1533 
1534         let no_nullterm_bdname = make_bdname_from_slice(&[72, 69, 76, 76, 79]);
1535         assert_eq!("".to_string(), String::from(no_nullterm_bdname));
1536 
1537         let invalid_bdname = make_bdname_from_slice(&[128; 249]);
1538         assert_eq!("".to_string(), String::from(invalid_bdname));
1539     }
1540 
1541     #[test]
test_ptr_to_vec()1542     fn test_ptr_to_vec() {
1543         let arr: [i32; 3] = [1, 2, 3];
1544         let vec: Vec<i32> = ptr_to_vec(arr.as_ptr(), arr.len());
1545         let expected: Vec<i32> = vec![1, 2, 3];
1546         assert_eq!(expected, vec);
1547     }
1548 
1549     #[test]
test_property_with_string_conversions()1550     fn test_property_with_string_conversions() {
1551         {
1552             let bdname = BluetoothProperty::BdName("FooBar".into());
1553             let prop_pair: (Box<[u8]>, bindings::bt_property_t) = bdname.into();
1554             let converted: BluetoothProperty = prop_pair.1.into();
1555             assert!(match converted {
1556                 BluetoothProperty::BdName(name) => "FooBar".to_string() == name,
1557                 _ => false,
1558             });
1559         }
1560 
1561         {
1562             let orig_record = BtServiceRecord {
1563                 uuid: Uuid::from([0; 16]),
1564                 channel: 3,
1565                 name: "FooBar".to_string(),
1566             };
1567             let service_record = BluetoothProperty::ServiceRecord(orig_record.clone());
1568             let prop_pair: (Box<[u8]>, bindings::bt_property_t) = service_record.into();
1569             let converted: BluetoothProperty = prop_pair.1.into();
1570             assert!(match converted {
1571                 BluetoothProperty::ServiceRecord(sr) => {
1572                     sr.uuid == orig_record.uuid
1573                         && sr.channel == orig_record.channel
1574                         && sr.name == orig_record.name
1575                 }
1576                 _ => false,
1577             });
1578         }
1579 
1580         {
1581             let rfname = BluetoothProperty::RemoteFriendlyName("FooBizz".into());
1582             let prop_pair: (Box<[u8]>, bindings::bt_property_t) = rfname.into();
1583             let converted: BluetoothProperty = prop_pair.1.into();
1584             assert!(match converted {
1585                 BluetoothProperty::RemoteFriendlyName(name) => "FooBizz".to_string() == name,
1586                 _ => false,
1587             });
1588         }
1589     }
1590 
1591     #[test]
test_display_address()1592     fn test_display_address() {
1593         assert_eq!(
1594             format!("{}", DisplayAddress(&RawAddress::from_string("00:00:00:00:00:00").unwrap())),
1595             String::from("00:00:00:00:00:00")
1596         );
1597         assert_eq!(
1598             format!("{}", DisplayAddress(&RawAddress::from_string("ff:ff:ff:ff:ff:ff").unwrap())),
1599             String::from("ff:ff:ff:ff:ff:ff")
1600         );
1601         assert_eq!(
1602             format!("{}", DisplayAddress(&RawAddress::from_string("1a:2b:1a:2b:1a:2b").unwrap())),
1603             String::from("xx:xx:xx:xx:1a:2b")
1604         );
1605         assert_eq!(
1606             format!("{}", DisplayAddress(&RawAddress::from_string("3C:4D:3C:4D:3C:4D").unwrap())),
1607             String::from("xx:xx:xx:xx:3c:4d")
1608         );
1609         assert_eq!(
1610             format!("{}", DisplayAddress(&RawAddress::from_string("11:35:11:35:11:35").unwrap())),
1611             String::from("xx:xx:xx:xx:11:35")
1612         );
1613     }
1614 
1615     #[test]
test_get_shortest_slice()1616     fn test_get_shortest_slice() {
1617         let uuid_16 = Uuid::from_string("0000fef3-0000-1000-8000-00805f9b34fb").unwrap();
1618         assert_eq!(uuid_16.get_shortest_slice(), [0xfe, 0xf3]);
1619 
1620         let uuid_32 = Uuid::from_string("00112233-0000-1000-8000-00805f9b34fb").unwrap();
1621         assert_eq!(uuid_32.get_shortest_slice(), [0x00, 0x11, 0x22, 0x33]);
1622 
1623         let uuid_128 = Uuid::from_string("00112233-4455-6677-8899-aabbccddeeff").unwrap();
1624         assert_eq!(
1625             uuid_128.get_shortest_slice(),
1626             [
1627                 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
1628                 0xee, 0xff
1629             ]
1630         );
1631     }
1632 }
1633