• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     KeyMissing(RawAddress),
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 cb_variant!(BaseCb, key_missing_cb -> BaseCallbacks::KeyMissing, RawAddress);
1129 
1130 struct RawInterfaceWrapper {
1131     pub raw: *const bindings::bt_interface_t,
1132 }
1133 
1134 unsafe impl Send for RawInterfaceWrapper {}
1135 
1136 /// Macro to call functions via function pointers. Expects the self object to
1137 /// have a raw interface wrapper at `self.internal`. The actual function call is
1138 /// marked unsafe since it will need to dereference a C object. This can cause
1139 /// segfaults if not validated beforehand.
1140 ///
1141 /// Example:
1142 ///     ccall!(self, foobar, arg1, arg2)
1143 ///     Expands to: unsafe {((*self.internal.raw).foobar.unwrap())(arg1, arg2)}
1144 #[macro_export]
1145 macro_rules! ccall {
1146     ($self:ident,$fn_name:ident) => {
1147         unsafe {
1148             ((*$self.internal.raw).$fn_name.unwrap())()
1149         }
1150     };
1151     ($self:ident,$fn_name:ident, $($args:expr),*) => {
1152         unsafe {
1153             ((*$self.internal.raw).$fn_name.unwrap())($($args),*)
1154         }
1155     };
1156 }
1157 
1158 /// Macro to call const functions via cxx. Expects the self object to have the
1159 /// cxx object to be called at `self.internal_cxx`.
1160 ///
1161 /// Example:
1162 ///     cxxcall!(self, foobar, arg1, arg2)
1163 ///     Expands to: self.internal_cxx.foobar(arg1, arg2)
1164 #[macro_export]
1165 macro_rules! cxxcall {
1166     ($self:expr,$fn_name:ident) => {
1167         $self.internal_cxx.$fn_name()
1168     };
1169     ($self:expr,$fn_name:ident, $($args:expr),*) => {
1170         $self.internal_cxx.$fn_name($($args),*)
1171     };
1172 }
1173 
1174 /// Macro to call mutable functions via cxx. Mutable functions are always
1175 /// required to be defined with `self: Pin<&mut Self>`. The self object must
1176 /// have the cxx object at `self.internal_cxx`.
1177 ///
1178 /// Example:
1179 ///     mutcxxcall!(self, foobar, arg1, arg2)
1180 ///     Expands to: self.internal_cxx.pin_mut().foobar(arg1, arg2)
1181 #[macro_export]
1182 macro_rules! mutcxxcall {
1183     ($self:expr,$fn_name:ident) => {
1184         $self.internal_cxx.pin_mut().$fn_name()
1185     };
1186     ($self:expr,$fn_name:ident, $($args:expr),*) => {
1187         $self.internal_cxx.pin_mut().$fn_name($($args),*)
1188     };
1189 }
1190 
1191 #[no_mangle]
wake_lock_noop(_0: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int1192 extern "C" fn wake_lock_noop(_0: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int {
1193     // The wakelock mechanism is not available on this platform,
1194     // so just returning success to avoid error log.
1195     0
1196 }
1197 
1198 /// Rust wrapper around `bt_interface_t`.
1199 pub struct BluetoothInterface {
1200     internal: RawInterfaceWrapper,
1201 
1202     /// Set to true after `initialize` is called.
1203     pub is_init: bool,
1204 
1205     // Need to take ownership of callbacks so it doesn't get freed after init
1206     callbacks: Option<Box<bindings::bt_callbacks_t>>,
1207     os_callouts: Option<Box<bindings::bt_os_callouts_t>>,
1208 }
1209 
1210 impl BluetoothInterface {
is_initialized(&self) -> bool1211     pub fn is_initialized(&self) -> bool {
1212         self.is_init
1213     }
1214 
1215     /// Initialize the Bluetooth interface by setting up the underlying interface.
1216     ///
1217     /// # Arguments
1218     ///
1219     /// * `callbacks` - Dispatcher struct that accepts [`BaseCallbacks`]
1220     /// * `hci_index` - Index of the hci adapter in use
initialize(&mut self, callbacks: BaseCallbacksDispatcher, hci_index: i32) -> bool1221     pub fn initialize(&mut self, callbacks: BaseCallbacksDispatcher, hci_index: i32) -> bool {
1222         if get_dispatchers().lock().unwrap().set::<BaseCb>(Arc::new(Mutex::new(callbacks))) {
1223             panic!("Tried to set dispatcher for BaseCallbacks but it already existed");
1224         }
1225 
1226         // Fill up callbacks struct to pass to init function (will be copied so
1227         // no need to worry about ownership)
1228         let mut callbacks = Box::new(bindings::bt_callbacks_t {
1229             size: std::mem::size_of::<bindings::bt_callbacks_t>(),
1230             adapter_state_changed_cb: Some(adapter_state_cb),
1231             adapter_properties_cb: Some(adapter_properties_cb),
1232             remote_device_properties_cb: Some(remote_device_properties_cb),
1233             device_found_cb: Some(device_found_cb),
1234             discovery_state_changed_cb: Some(discovery_state_cb),
1235             pin_request_cb: Some(pin_request_cb),
1236             ssp_request_cb: Some(ssp_request_cb),
1237             bond_state_changed_cb: Some(bond_state_cb),
1238             address_consolidate_cb: Some(address_consolidate_cb),
1239             le_address_associate_cb: Some(le_address_associate_cb),
1240             acl_state_changed_cb: Some(acl_state_cb),
1241             thread_evt_cb: Some(thread_evt_cb),
1242             dut_mode_recv_cb: None,
1243             le_test_mode_cb: None,
1244             energy_info_cb: None,
1245             link_quality_report_cb: None,
1246             generate_local_oob_data_cb: Some(generate_local_oob_data_cb),
1247             switch_buffer_size_cb: None,
1248             switch_codec_cb: None,
1249             le_rand_cb: Some(le_rand_cb),
1250             key_missing_cb: Some(key_missing_cb),
1251             encryption_change_cb: None,
1252         });
1253 
1254         let cb_ptr = LTCheckedPtrMut::from(&mut callbacks);
1255 
1256         let (guest_mode, is_common_criteria_mode, config_compare_result, is_atv) =
1257             (false, false, 0, false);
1258 
1259         ccall!(self, set_adapter_index, hci_index);
1260         let init = ccall!(
1261             self,
1262             init,
1263             cb_ptr.into(),
1264             guest_mode,
1265             is_common_criteria_mode,
1266             config_compare_result,
1267             is_atv
1268         );
1269 
1270         self.is_init = init == 0;
1271         self.callbacks = Some(callbacks);
1272 
1273         if self.is_init {
1274             // Fill up OSI function table and register it with BTIF.
1275             // TODO(b/271931441) - pass a NoOpOsCallouts structure from
1276             // gd/rust/linux/stack.
1277             let mut callouts = Box::new(bindings::bt_os_callouts_t {
1278                 size: std::mem::size_of::<bindings::bt_os_callouts_t>(),
1279                 acquire_wake_lock: Some(wake_lock_noop),
1280                 release_wake_lock: Some(wake_lock_noop),
1281             });
1282             let callouts_ptr = LTCheckedPtrMut::from(&mut callouts);
1283             ccall!(self, set_os_callouts, callouts_ptr.into());
1284             self.os_callouts = Some(callouts);
1285         }
1286 
1287         return self.is_init;
1288     }
1289 
cleanup(&self)1290     pub fn cleanup(&self) {
1291         ccall!(self, cleanup)
1292     }
1293 
enable(&self) -> i321294     pub fn enable(&self) -> i32 {
1295         ccall!(self, enable)
1296     }
1297 
disable(&self) -> i321298     pub fn disable(&self) -> i32 {
1299         ccall!(self, disable)
1300     }
1301 
get_adapter_properties(&self) -> i321302     pub fn get_adapter_properties(&self) -> i32 {
1303         ccall!(self, get_adapter_properties)
1304     }
1305 
get_adapter_property(&self, prop: BtPropertyType) -> i321306     pub fn get_adapter_property(&self, prop: BtPropertyType) -> i32 {
1307         let converted_type = bindings::bt_property_type_t::from(prop);
1308         ccall!(self, get_adapter_property, converted_type)
1309     }
1310 
set_adapter_property(&self, prop: BluetoothProperty) -> i321311     pub fn set_adapter_property(&self, prop: BluetoothProperty) -> i32 {
1312         let prop_pair: (Box<[u8]>, bindings::bt_property_t) = prop.into();
1313         let prop_ptr = LTCheckedPtr::from_ref(&prop_pair.1);
1314         ccall!(self, set_adapter_property, prop_ptr.into())
1315     }
1316 
set_scan_mode(&self, mode: BtScanMode)1317     pub fn set_scan_mode(&self, mode: BtScanMode) {
1318         ccall!(self, set_scan_mode, mode.into())
1319     }
1320 
get_remote_device_properties(&self, addr: &mut RawAddress) -> i321321     pub fn get_remote_device_properties(&self, addr: &mut RawAddress) -> i32 {
1322         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1323         ccall!(self, get_remote_device_properties, addr_ptr.into())
1324     }
1325 
get_remote_device_property( &self, addr: &mut RawAddress, prop_type: BtPropertyType, ) -> i321326     pub fn get_remote_device_property(
1327         &self,
1328         addr: &mut RawAddress,
1329         prop_type: BtPropertyType,
1330     ) -> i32 {
1331         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1332         let converted_type = bindings::bt_property_type_t::from(prop_type);
1333         ccall!(self, get_remote_device_property, addr_ptr.into(), converted_type)
1334     }
1335 
set_remote_device_property( &self, addr: &mut RawAddress, prop: BluetoothProperty, ) -> i321336     pub fn set_remote_device_property(
1337         &self,
1338         addr: &mut RawAddress,
1339         prop: BluetoothProperty,
1340     ) -> i32 {
1341         let prop_pair: (Box<[u8]>, bindings::bt_property_t) = prop.into();
1342         let prop_ptr = LTCheckedPtr::from_ref(&prop_pair.1);
1343         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1344         ccall!(self, set_remote_device_property, addr_ptr.into(), prop_ptr.into())
1345     }
1346 
get_remote_services(&self, addr: &mut RawAddress, transport: BtTransport) -> i321347     pub fn get_remote_services(&self, addr: &mut RawAddress, transport: BtTransport) -> i32 {
1348         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1349         ccall!(self, get_remote_services, addr_ptr.into(), transport.to_i32().unwrap())
1350     }
1351 
start_discovery(&self) -> i321352     pub fn start_discovery(&self) -> i32 {
1353         ccall!(self, start_discovery)
1354     }
1355 
cancel_discovery(&self) -> i321356     pub fn cancel_discovery(&self) -> i32 {
1357         ccall!(self, cancel_discovery)
1358     }
1359 
pairing_is_busy(&self) -> bool1360     pub fn pairing_is_busy(&self) -> bool {
1361         ccall!(self, pairing_is_busy)
1362     }
1363 
create_bond(&self, addr: &RawAddress, transport: BtTransport) -> i321364     pub fn create_bond(&self, addr: &RawAddress, transport: BtTransport) -> i32 {
1365         let ctransport: i32 = transport.into();
1366         let addr_ptr = LTCheckedPtr::from_ref(addr);
1367         ccall!(self, create_bond, addr_ptr.into(), ctransport)
1368     }
1369 
remove_bond(&self, addr: &RawAddress) -> i321370     pub fn remove_bond(&self, addr: &RawAddress) -> i32 {
1371         let addr_ptr = LTCheckedPtr::from_ref(addr);
1372         ccall!(self, remove_bond, addr_ptr.into())
1373     }
1374 
cancel_bond(&self, addr: &RawAddress) -> i321375     pub fn cancel_bond(&self, addr: &RawAddress) -> i32 {
1376         let addr_ptr = LTCheckedPtr::from_ref(addr);
1377         ccall!(self, cancel_bond, addr_ptr.into())
1378     }
1379 
get_connection_state(&self, addr: &RawAddress) -> BtConnectionState1380     pub fn get_connection_state(&self, addr: &RawAddress) -> BtConnectionState {
1381         let addr_ptr = LTCheckedPtr::from_ref(addr);
1382         ccall!(self, get_connection_state, addr_ptr.into()).into()
1383     }
1384 
pin_reply( &self, addr: &RawAddress, accept: u8, pin_len: u8, pin_code: &mut BtPinCode, ) -> i321385     pub fn pin_reply(
1386         &self,
1387         addr: &RawAddress,
1388         accept: u8,
1389         pin_len: u8,
1390         pin_code: &mut BtPinCode,
1391     ) -> i32 {
1392         let addr_ptr = LTCheckedPtr::from_ref(addr);
1393         let pin_code_ptr = LTCheckedPtrMut::from_ref(pin_code);
1394         ccall!(self, pin_reply, addr_ptr.into(), accept, pin_len, pin_code_ptr.into())
1395     }
1396 
ssp_reply( &self, addr: &RawAddress, variant: BtSspVariant, accept: u8, passkey: u32, ) -> i321397     pub fn ssp_reply(
1398         &self,
1399         addr: &RawAddress,
1400         variant: BtSspVariant,
1401         accept: u8,
1402         passkey: u32,
1403     ) -> i32 {
1404         let addr_ptr = LTCheckedPtr::from_ref(addr);
1405         let cvariant = bindings::bt_ssp_variant_t::from(variant);
1406         ccall!(self, ssp_reply, addr_ptr.into(), cvariant, accept, passkey)
1407     }
1408 
clear_event_filter(&self) -> i321409     pub fn clear_event_filter(&self) -> i32 {
1410         ccall!(self, clear_event_filter)
1411     }
1412 
clear_event_mask(&self) -> i321413     pub fn clear_event_mask(&self) -> i32 {
1414         ccall!(self, clear_event_mask)
1415     }
1416 
clear_filter_accept_list(&self) -> i321417     pub fn clear_filter_accept_list(&self) -> i32 {
1418         ccall!(self, clear_filter_accept_list)
1419     }
1420 
disconnect_all_acls(&self) -> i321421     pub fn disconnect_all_acls(&self) -> i32 {
1422         ccall!(self, disconnect_all_acls)
1423     }
1424 
allow_wake_by_hid(&self) -> i321425     pub fn allow_wake_by_hid(&self) -> i32 {
1426         ccall!(self, allow_wake_by_hid)
1427     }
1428 
get_wbs_supported(&self) -> bool1429     pub fn get_wbs_supported(&self) -> bool {
1430         ccall!(self, get_wbs_supported)
1431     }
1432 
get_swb_supported(&self) -> bool1433     pub fn get_swb_supported(&self) -> bool {
1434         ccall!(self, get_swb_supported)
1435     }
1436 
is_coding_format_supported(&self, coding_format: u8) -> bool1437     pub fn is_coding_format_supported(&self, coding_format: u8) -> bool {
1438         ccall!(self, is_coding_format_supported, coding_format)
1439     }
1440 
le_rand(&self) -> i321441     pub fn le_rand(&self) -> i32 {
1442         ccall!(self, le_rand)
1443     }
1444 
generate_local_oob_data(&self, transport: i32) -> i321445     pub fn generate_local_oob_data(&self, transport: i32) -> i32 {
1446         ccall!(self, generate_local_oob_data, transport as u8)
1447     }
1448 
restore_filter_accept_list(&self) -> i321449     pub fn restore_filter_accept_list(&self) -> i32 {
1450         ccall!(self, restore_filter_accept_list)
1451     }
1452 
set_default_event_mask_except(&self, mask: u64, le_mask: u64) -> i321453     pub fn set_default_event_mask_except(&self, mask: u64, le_mask: u64) -> i32 {
1454         ccall!(self, set_default_event_mask_except, mask, le_mask)
1455     }
1456 
set_event_filter_inquiry_result_all_devices(&self) -> i321457     pub fn set_event_filter_inquiry_result_all_devices(&self) -> i32 {
1458         ccall!(self, set_event_filter_inquiry_result_all_devices)
1459     }
1460 
set_event_filter_connection_setup_all_devices(&self) -> i321461     pub fn set_event_filter_connection_setup_all_devices(&self) -> i32 {
1462         ccall!(self, set_event_filter_connection_setup_all_devices)
1463     }
1464 
get_profile_interface( &self, profile: SupportedProfiles, ) -> *const std::os::raw::c_void1465     pub(crate) fn get_profile_interface(
1466         &self,
1467         profile: SupportedProfiles,
1468     ) -> *const std::os::raw::c_void {
1469         let cprofile = Vec::<u8>::from(profile);
1470         let cprofile_ptr = LTCheckedPtr::from(&cprofile);
1471         ccall!(self, get_profile_interface, cprofile_ptr.cast_into::<std::os::raw::c_char>())
1472     }
1473 
as_raw_ptr(&self) -> *const u81474     pub(crate) fn as_raw_ptr(&self) -> *const u8 {
1475         self.internal.raw as *const u8
1476     }
1477 
dump(&self, fd: RawFd)1478     pub fn dump(&self, fd: RawFd) {
1479         ccall!(self, dump, fd, std::ptr::null_mut())
1480     }
1481 }
1482 
1483 impl Debug for BluetoothInterface {
fmt(&self, f: &mut Formatter<'_>) -> Result1484     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
1485         write!(f, "BluetoothInterface {{ is_init: {:?} }}", self.is_init)
1486     }
1487 }
1488 
1489 pub trait ToggleableProfile {
is_enabled(&self) -> bool1490     fn is_enabled(&self) -> bool;
enable(&mut self) -> bool1491     fn enable(&mut self) -> bool;
disable(&mut self) -> bool1492     fn disable(&mut self) -> bool;
1493 }
1494 
get_btinterface() -> BluetoothInterface1495 pub fn get_btinterface() -> BluetoothInterface {
1496     let mut ifptr: *const bindings::bt_interface_t = std::ptr::null();
1497 
1498     if unsafe { bindings::hal_util_load_bt_library(&mut ifptr) } == 0 {
1499         BluetoothInterface {
1500             internal: RawInterfaceWrapper { raw: ifptr },
1501             is_init: false,
1502             callbacks: None,
1503             os_callouts: None,
1504         }
1505     } else {
1506         panic!("Failed to get BluetoothInterface");
1507     }
1508 }
1509 
1510 // Turns C-array T[] to Vec<U>.
ptr_to_vec<T: Copy, U: From<T>>(start: *const T, length: usize) -> Vec<U>1511 pub(crate) fn ptr_to_vec<T: Copy, U: From<T>>(start: *const T, length: usize) -> Vec<U> {
1512     unsafe {
1513         (0..length).map(|i| U::from(start.offset(i as isize).read_unaligned())).collect::<Vec<U>>()
1514     }
1515 }
1516 
1517 #[cfg(test)]
1518 mod tests {
1519     use super::*;
1520 
make_bdname_from_slice(slice: &[u8]) -> bindings::bt_bdname_t1521     fn make_bdname_from_slice(slice: &[u8]) -> bindings::bt_bdname_t {
1522         // Length of slice must be less than bd_name max
1523         assert!(slice.len() <= 249);
1524 
1525         let mut bdname = bindings::bt_bdname_t { name: [128; 249] };
1526 
1527         for (i, v) in slice.iter().enumerate() {
1528             bdname.name[i] = v.clone();
1529         }
1530 
1531         bdname
1532     }
1533 
1534     #[test]
test_bdname_conversions()1535     fn test_bdname_conversions() {
1536         let hello_bdname = make_bdname_from_slice(&[72, 69, 76, 76, 79, 0]);
1537         assert_eq!("HELLO".to_string(), String::from(hello_bdname));
1538 
1539         let empty_bdname = make_bdname_from_slice(&[0]);
1540         assert_eq!("".to_string(), String::from(empty_bdname));
1541 
1542         let no_nullterm_bdname = make_bdname_from_slice(&[72, 69, 76, 76, 79]);
1543         assert_eq!("".to_string(), String::from(no_nullterm_bdname));
1544 
1545         let invalid_bdname = make_bdname_from_slice(&[128; 249]);
1546         assert_eq!("".to_string(), String::from(invalid_bdname));
1547     }
1548 
1549     #[test]
test_ptr_to_vec()1550     fn test_ptr_to_vec() {
1551         let arr: [i32; 3] = [1, 2, 3];
1552         let vec: Vec<i32> = ptr_to_vec(arr.as_ptr(), arr.len());
1553         let expected: Vec<i32> = vec![1, 2, 3];
1554         assert_eq!(expected, vec);
1555     }
1556 
1557     #[test]
test_property_with_string_conversions()1558     fn test_property_with_string_conversions() {
1559         {
1560             let bdname = BluetoothProperty::BdName("FooBar".into());
1561             let prop_pair: (Box<[u8]>, bindings::bt_property_t) = bdname.into();
1562             let converted: BluetoothProperty = prop_pair.1.into();
1563             assert!(match converted {
1564                 BluetoothProperty::BdName(name) => "FooBar".to_string() == name,
1565                 _ => false,
1566             });
1567         }
1568 
1569         {
1570             let orig_record = BtServiceRecord {
1571                 uuid: Uuid::from([0; 16]),
1572                 channel: 3,
1573                 name: "FooBar".to_string(),
1574             };
1575             let service_record = BluetoothProperty::ServiceRecord(orig_record.clone());
1576             let prop_pair: (Box<[u8]>, bindings::bt_property_t) = service_record.into();
1577             let converted: BluetoothProperty = prop_pair.1.into();
1578             assert!(match converted {
1579                 BluetoothProperty::ServiceRecord(sr) => {
1580                     sr.uuid == orig_record.uuid
1581                         && sr.channel == orig_record.channel
1582                         && sr.name == orig_record.name
1583                 }
1584                 _ => false,
1585             });
1586         }
1587 
1588         {
1589             let rfname = BluetoothProperty::RemoteFriendlyName("FooBizz".into());
1590             let prop_pair: (Box<[u8]>, bindings::bt_property_t) = rfname.into();
1591             let converted: BluetoothProperty = prop_pair.1.into();
1592             assert!(match converted {
1593                 BluetoothProperty::RemoteFriendlyName(name) => "FooBizz".to_string() == name,
1594                 _ => false,
1595             });
1596         }
1597     }
1598 
1599     #[test]
test_display_address()1600     fn test_display_address() {
1601         assert_eq!(
1602             format!("{}", DisplayAddress(&RawAddress::from_string("00:00:00:00:00:00").unwrap())),
1603             String::from("00:00:00:00:00:00")
1604         );
1605         assert_eq!(
1606             format!("{}", DisplayAddress(&RawAddress::from_string("ff:ff:ff:ff:ff:ff").unwrap())),
1607             String::from("ff:ff:ff:ff:ff:ff")
1608         );
1609         assert_eq!(
1610             format!("{}", DisplayAddress(&RawAddress::from_string("1a:2b:1a:2b:1a:2b").unwrap())),
1611             String::from("xx:xx:xx:xx:1a:2b")
1612         );
1613         assert_eq!(
1614             format!("{}", DisplayAddress(&RawAddress::from_string("3C:4D:3C:4D:3C:4D").unwrap())),
1615             String::from("xx:xx:xx:xx:3c:4d")
1616         );
1617         assert_eq!(
1618             format!("{}", DisplayAddress(&RawAddress::from_string("11:35:11:35:11:35").unwrap())),
1619             String::from("xx:xx:xx:xx:11:35")
1620         );
1621     }
1622 
1623     #[test]
test_get_shortest_slice()1624     fn test_get_shortest_slice() {
1625         let uuid_16 = Uuid::from_string("0000fef3-0000-1000-8000-00805f9b34fb").unwrap();
1626         assert_eq!(uuid_16.get_shortest_slice(), [0xfe, 0xf3]);
1627 
1628         let uuid_32 = Uuid::from_string("00112233-0000-1000-8000-00805f9b34fb").unwrap();
1629         assert_eq!(uuid_32.get_shortest_slice(), [0x00, 0x11, 0x22, 0x33]);
1630 
1631         let uuid_128 = Uuid::from_string("00112233-4455-6677-8899-aabbccddeeff").unwrap();
1632         assert_eq!(
1633             uuid_128.get_shortest_slice(),
1634             [
1635                 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd,
1636                 0xee, 0xff
1637             ]
1638         );
1639     }
1640 }
1641