• 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::raw::c_char;
16 use std::sync::{Arc, Mutex};
17 use std::vec::Vec;
18 use topshim_macros::cb_variant;
19 
20 use cxx::{type_id, ExternType};
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 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
56 #[repr(u32)]
57 pub enum BtSspVariant {
58     PasskeyConfirmation = 0,
59     PasskeyEntry,
60     Consent,
61     PasskeyNotification,
62 }
63 
64 impl From<bindings::bt_ssp_variant_t> for BtSspVariant {
from(item: bindings::bt_ssp_variant_t) -> Self65     fn from(item: bindings::bt_ssp_variant_t) -> Self {
66         BtSspVariant::from_u32(item).unwrap_or(BtSspVariant::PasskeyConfirmation)
67     }
68 }
69 
70 impl From<BtSspVariant> for bindings::bt_ssp_variant_t {
from(item: BtSspVariant) -> Self71     fn from(item: BtSspVariant) -> Self {
72         item.to_u32().unwrap_or(0)
73     }
74 }
75 
76 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
77 #[repr(u32)]
78 pub enum BtBondState {
79     NotBonded = 0,
80     Bonding,
81     Bonded,
82 }
83 
84 impl From<bindings::bt_bond_state_t> for BtBondState {
from(item: bindings::bt_bond_state_t) -> Self85     fn from(item: bindings::bt_bond_state_t) -> Self {
86         BtBondState::from_u32(item).unwrap_or(BtBondState::NotBonded)
87     }
88 }
89 
90 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
91 #[repr(u32)]
92 pub enum BtConnectionState {
93     NotConnected = 0,
94     ConnectedOnly = 1,
95     EncryptedBredr = 3,
96     EncryptedLe = 5,
97     EncryptedBoth = 7,
98 }
99 
100 impl From<i32> for BtConnectionState {
from(item: i32) -> Self101     fn from(item: i32) -> Self {
102         let fallback = if item > 0 {
103             BtConnectionState::ConnectedOnly
104         } else {
105             BtConnectionState::NotConnected
106         };
107 
108         BtConnectionState::from_i32(item).unwrap_or(fallback)
109     }
110 }
111 
112 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
113 #[repr(u32)]
114 pub enum BtAclState {
115     Connected = 0,
116     Disconnected,
117 }
118 
119 impl From<bindings::bt_acl_state_t> for BtAclState {
from(item: bindings::bt_acl_state_t) -> Self120     fn from(item: bindings::bt_acl_state_t) -> Self {
121         BtAclState::from_u32(item).unwrap_or(BtAclState::Disconnected)
122     }
123 }
124 
125 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
126 #[repr(u32)]
127 pub enum BtDeviceType {
128     Unknown = 0,
129     Bredr,
130     Ble,
131     Dual,
132 }
133 
134 #[derive(Clone, Debug, Eq, Hash, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
135 #[repr(u32)]
136 pub enum BtPropertyType {
137     BdName = 0x1,
138     BdAddr,
139     Uuids,
140     ClassOfDevice,
141     TypeOfDevice,
142     ServiceRecord,
143     AdapterScanMode,
144     AdapterBondedDevices,
145     AdapterDiscoverableTimeout,
146     RemoteFriendlyName,
147     RemoteRssi,
148     RemoteVersionInfo,
149     LocalLeFeatures,
150     LocalIoCaps,
151     LocalIoCapsBle,
152     DynamicAudioBuffer,
153     RemoteIsCoordinatedSetMember,
154     Appearance,
155     VendorProductInfo,
156 
157     Unknown = 0xFE,
158     RemoteDeviceTimestamp = 0xFF,
159 }
160 
161 impl From<u32> for BtPropertyType {
from(item: u32) -> Self162     fn from(item: u32) -> Self {
163         BtPropertyType::from_u32(item).unwrap_or(BtPropertyType::Unknown)
164     }
165 }
166 
167 impl From<BtPropertyType> for u32 {
from(item: BtPropertyType) -> Self168     fn from(item: BtPropertyType) -> Self {
169         item.to_u32().unwrap_or(0)
170     }
171 }
172 
173 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
174 #[repr(u32)]
175 pub enum BtDiscoveryState {
176     Stopped = 0x0,
177     Started,
178 }
179 
180 impl From<u32> for BtDiscoveryState {
from(item: u32) -> Self181     fn from(item: u32) -> Self {
182         BtDiscoveryState::from_u32(item).unwrap_or(BtDiscoveryState::Stopped)
183     }
184 }
185 
186 #[derive(Clone, Copy, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
187 #[repr(u32)]
188 pub enum BtStatus {
189     Success = 0,
190     Fail,
191     NotReady,
192     NoMemory,
193     Busy,
194     Done,
195     Unsupported,
196     InvalidParam,
197     Unhandled,
198     AuthFailure,
199     RemoteDeviceDown,
200     AuthRejected,
201     JniEnvironmentError,
202     JniThreadAttachError,
203     WakeLockError,
204 
205     // Any statuses that couldn't be cleanly converted
206     Unknown = 0xff,
207 }
208 
209 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
210 #[repr(u32)]
211 pub enum BtConnectionDirection {
212     Unknown = 0,
213     Outgoing,
214     Incoming,
215 }
216 
217 impl From<u32> for BtConnectionDirection {
from(item: u32) -> Self218     fn from(item: u32) -> Self {
219         BtConnectionDirection::from_u32(item).unwrap_or(BtConnectionDirection::Unknown)
220     }
221 }
222 
ascii_to_string(data: &[u8], length: usize) -> String223 pub fn ascii_to_string(data: &[u8], length: usize) -> String {
224     // We need to reslice data because from_utf8 tries to interpret the
225     // whole slice and not just what is before the null terminated portion
226     let ascii = data
227         .iter()
228         .enumerate()
229         .take_while(|&(pos, &c)| c != 0 && pos < length)
230         .map(|(_pos, &x)| x.clone())
231         .collect::<Vec<u8>>();
232 
233     return String::from_utf8(ascii).unwrap_or_default();
234 }
235 
u32_from_bytes(item: &[u8]) -> u32236 fn u32_from_bytes(item: &[u8]) -> u32 {
237     let mut u: [u8; 4] = [0; 4];
238     let len = std::cmp::min(item.len(), 4);
239     u[0..len].copy_from_slice(&item);
240     u32::from_ne_bytes(u)
241 }
242 
u16_from_bytes(item: &[u8]) -> u16243 fn u16_from_bytes(item: &[u8]) -> u16 {
244     let mut u: [u8; 2] = [0; 2];
245     let len = std::cmp::min(item.len(), 2);
246     u[0..len].copy_from_slice(&item);
247     u16::from_ne_bytes(u)
248 }
249 
250 impl From<bindings::bt_status_t> for BtStatus {
from(item: bindings::bt_status_t) -> Self251     fn from(item: bindings::bt_status_t) -> Self {
252         match BtStatus::from_u32(item) {
253             Some(x) => x,
254             _ => BtStatus::Unknown,
255         }
256     }
257 }
258 
259 impl Into<u32> for BtStatus {
into(self) -> u32260     fn into(self) -> u32 {
261         self.to_u32().unwrap_or_default()
262     }
263 }
264 
265 impl Into<i32> for BtStatus {
into(self) -> i32266     fn into(self) -> i32 {
267         self.to_i32().unwrap_or_default()
268     }
269 }
270 
271 impl From<bindings::bt_bdname_t> for String {
from(item: bindings::bt_bdname_t) -> Self272     fn from(item: bindings::bt_bdname_t) -> Self {
273         ascii_to_string(&item.name, item.name.len())
274     }
275 }
276 
277 #[derive(Debug, Clone)]
278 pub struct BtServiceRecord {
279     pub uuid: bindings::bluetooth::Uuid,
280     pub channel: u16,
281     pub name: String,
282 }
283 
284 impl From<bindings::bt_service_record_t> for BtServiceRecord {
from(item: bindings::bt_service_record_t) -> Self285     fn from(item: bindings::bt_service_record_t) -> Self {
286         let name = item.name.iter().map(|&x| x.clone() as u8).collect::<Vec<u8>>();
287 
288         BtServiceRecord {
289             uuid: item.uuid,
290             channel: item.channel,
291             name: ascii_to_string(name.as_slice(), name.len()),
292         }
293     }
294 }
295 
296 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
297 #[repr(u32)]
298 pub enum BtScanMode {
299     None_,
300     Connectable,
301     ConnectableDiscoverable,
302     ConnectableLimitedDiscoverable,
303 }
304 
305 impl From<bindings::bt_scan_mode_t> for BtScanMode {
from(item: bindings::bt_scan_mode_t) -> Self306     fn from(item: bindings::bt_scan_mode_t) -> Self {
307         BtScanMode::from_u32(item).unwrap_or(BtScanMode::None_)
308     }
309 }
310 
311 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
312 #[repr(u32)]
313 pub enum BtDiscMode {
314     // reference to system/stack/btm/neighbor_inquiry.h
315     NonDiscoverable = 0,
316     LimitedDiscoverable = 1,
317     GeneralDiscoverable = 2,
318 }
319 
320 impl From<u32> for BtDiscMode {
from(num: u32) -> Self321     fn from(num: u32) -> Self {
322         BtDiscMode::from_u32(num).unwrap_or(BtDiscMode::NonDiscoverable)
323     }
324 }
325 
326 impl Into<u32> for BtDiscMode {
into(self) -> u32327     fn into(self) -> u32 {
328         self.to_u32().unwrap_or(0)
329     }
330 }
331 
332 #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
333 #[repr(u32)]
334 pub enum BtIoCap {
335     Out,
336     InOut,
337     In,
338     None_,
339     KbDisp,
340     Max,
341     Unknown = 0xff,
342 }
343 
344 impl From<bindings::bt_io_cap_t> for BtIoCap {
from(item: bindings::bt_io_cap_t) -> Self345     fn from(item: bindings::bt_io_cap_t) -> Self {
346         BtIoCap::from_u32(item).unwrap_or(BtIoCap::Unknown)
347     }
348 }
349 
350 pub type BtHciErrorCode = u8;
351 pub type BtLocalLeFeatures = bindings::bt_local_le_features_t;
352 pub type BtPinCode = bindings::bt_pin_code_t;
353 pub type BtRemoteVersion = bindings::bt_remote_version_t;
354 pub type BtVendorProductInfo = bindings::bt_vendor_product_info_t;
355 pub type Uuid = bindings::bluetooth::Uuid;
356 pub type Uuid128Bit = bindings::bluetooth::Uuid_UUID128Bit;
357 
358 impl TryFrom<Uuid> for Vec<u8> {
359     type Error = &'static str;
360 
try_from(value: Uuid) -> std::result::Result<Self, Self::Error>361     fn try_from(value: Uuid) -> std::result::Result<Self, Self::Error> {
362         Ok((&value.uu).to_vec())
363     }
364 }
365 
366 impl TryFrom<Vec<u8>> for Uuid {
367     type Error = &'static str;
368 
try_from(value: Vec<u8>) -> std::result::Result<Self, Self::Error>369     fn try_from(value: Vec<u8>) -> std::result::Result<Self, Self::Error> {
370         // base UUID defined in the Bluetooth specification
371         let mut uu: [u8; 16] =
372             [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x80, 0x0, 0x0, 0x80, 0x5f, 0x9b, 0x34, 0xfb];
373         match value.len() {
374             2 => {
375                 uu[2..4].copy_from_slice(&value[0..2]);
376                 Ok(Uuid::from(uu))
377             }
378             4 => {
379                 uu[0..4].copy_from_slice(&value[0..4]);
380                 Ok(Uuid::from(uu))
381             }
382             16 => {
383                 uu.copy_from_slice(&value[0..16]);
384                 Ok(Uuid::from(uu))
385             }
386             _ => {
387                 Err("Vector size must be exactly 2 (16 bit UUID), 4 (32 bit UUID), or 16 (128 bit UUID).")
388             }
389         }
390     }
391 }
392 
393 impl From<[u8; 16]> for Uuid {
from(value: [u8; 16]) -> Self394     fn from(value: [u8; 16]) -> Self {
395         Self { uu: value }
396     }
397 }
398 
399 impl From<Uuid> for [u8; 16] {
from(uuid: Uuid) -> Self400     fn from(uuid: Uuid) -> Self {
401         uuid.uu
402     }
403 }
404 
405 impl Hash for Uuid {
hash<H: Hasher>(&self, state: &mut H)406     fn hash<H: Hasher>(&self, state: &mut H) {
407         self.uu.hash(state);
408     }
409 }
410 
411 impl Uuid {
412     /// Creates a Uuid from little endian slice of bytes
try_from_little_endian(value: &[u8]) -> std::result::Result<Uuid, &'static str>413     pub fn try_from_little_endian(value: &[u8]) -> std::result::Result<Uuid, &'static str> {
414         Uuid::try_from(value.iter().rev().cloned().collect::<Vec<u8>>())
415     }
416 
417     /// Formats this UUID to a human-readable representation.
format(uuid: &Uuid128Bit, f: &mut Formatter) -> Result418     pub fn format(uuid: &Uuid128Bit, f: &mut Formatter) -> Result {
419         write!(f, "{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
420             uuid[0], uuid[1], uuid[2], uuid[3],
421             uuid[4], uuid[5],
422             uuid[6], uuid[7],
423             uuid[8], uuid[9],
424             uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15])
425     }
426 }
427 
428 impl Display for Uuid {
fmt(&self, f: &mut Formatter) -> Result429     fn fmt(&self, f: &mut Formatter) -> Result {
430         Uuid::format(&self.uu, f)
431     }
432 }
433 
434 /// All supported Bluetooth properties after conversion.
435 #[derive(Debug, Clone)]
436 pub enum BluetoothProperty {
437     BdName(String),
438     BdAddr(RawAddress),
439     Uuids(Vec<Uuid>),
440     ClassOfDevice(u32),
441     TypeOfDevice(BtDeviceType),
442     ServiceRecord(BtServiceRecord),
443     AdapterScanMode(BtScanMode),
444     AdapterBondedDevices(Vec<RawAddress>),
445     AdapterDiscoverableTimeout(u32),
446     RemoteFriendlyName(String),
447     RemoteRssi(i8),
448     RemoteVersionInfo(BtRemoteVersion),
449     LocalLeFeatures(BtLocalLeFeatures),
450     LocalIoCaps(BtIoCap),
451     LocalIoCapsBle(BtIoCap),
452     DynamicAudioBuffer(),
453     RemoteIsCoordinatedSetMember(bool),
454     Appearance(u16),
455     VendorProductInfo(BtVendorProductInfo),
456     RemoteDeviceTimestamp(),
457 
458     Unknown(),
459 }
460 
461 /// Wherever names are sent in bindings::bt_property_t, the size of the character
462 /// arrays are 256. Keep one extra byte for null termination.
463 const PROPERTY_NAME_MAX: usize = 255;
464 
465 impl BluetoothProperty {
get_type(&self) -> BtPropertyType466     pub fn get_type(&self) -> BtPropertyType {
467         match &*self {
468             BluetoothProperty::BdName(_) => BtPropertyType::BdName,
469             BluetoothProperty::BdAddr(_) => BtPropertyType::BdAddr,
470             BluetoothProperty::Uuids(_) => BtPropertyType::Uuids,
471             BluetoothProperty::ClassOfDevice(_) => BtPropertyType::ClassOfDevice,
472             BluetoothProperty::TypeOfDevice(_) => BtPropertyType::TypeOfDevice,
473             BluetoothProperty::ServiceRecord(_) => BtPropertyType::ServiceRecord,
474             BluetoothProperty::AdapterScanMode(_) => BtPropertyType::AdapterScanMode,
475             BluetoothProperty::AdapterBondedDevices(_) => BtPropertyType::AdapterBondedDevices,
476             BluetoothProperty::AdapterDiscoverableTimeout(_) => {
477                 BtPropertyType::AdapterDiscoverableTimeout
478             }
479             BluetoothProperty::RemoteFriendlyName(_) => BtPropertyType::RemoteFriendlyName,
480             BluetoothProperty::RemoteRssi(_) => BtPropertyType::RemoteRssi,
481             BluetoothProperty::RemoteVersionInfo(_) => BtPropertyType::RemoteVersionInfo,
482             BluetoothProperty::LocalLeFeatures(_) => BtPropertyType::LocalLeFeatures,
483             BluetoothProperty::LocalIoCaps(_) => BtPropertyType::LocalIoCaps,
484             BluetoothProperty::LocalIoCapsBle(_) => BtPropertyType::LocalIoCapsBle,
485             BluetoothProperty::DynamicAudioBuffer() => BtPropertyType::DynamicAudioBuffer,
486             BluetoothProperty::RemoteIsCoordinatedSetMember(_) => {
487                 BtPropertyType::RemoteIsCoordinatedSetMember
488             }
489             BluetoothProperty::Appearance(_) => BtPropertyType::Appearance,
490             BluetoothProperty::VendorProductInfo(_) => BtPropertyType::VendorProductInfo,
491             BluetoothProperty::RemoteDeviceTimestamp() => BtPropertyType::RemoteDeviceTimestamp,
492             BluetoothProperty::Unknown() => BtPropertyType::Unknown,
493         }
494     }
495 
get_len(&self) -> usize496     fn get_len(&self) -> usize {
497         match &*self {
498             BluetoothProperty::BdName(name) => cmp::min(PROPERTY_NAME_MAX, name.len() + 1),
499             BluetoothProperty::BdAddr(addr) => addr.address.len(),
500             BluetoothProperty::Uuids(uulist) => uulist.len() * mem::size_of::<Uuid>(),
501             BluetoothProperty::ClassOfDevice(_) => mem::size_of::<u32>(),
502             BluetoothProperty::TypeOfDevice(_) => mem::size_of::<BtDeviceType>(),
503             BluetoothProperty::ServiceRecord(rec) => {
504                 mem::size_of::<BtServiceRecord>() + cmp::min(PROPERTY_NAME_MAX, rec.name.len() + 1)
505             }
506             BluetoothProperty::AdapterScanMode(_) => mem::size_of::<BtScanMode>(),
507             BluetoothProperty::AdapterBondedDevices(devlist) => {
508                 devlist.len() * mem::size_of::<RawAddress>()
509             }
510             BluetoothProperty::AdapterDiscoverableTimeout(_) => mem::size_of::<u32>(),
511             BluetoothProperty::RemoteFriendlyName(name) => {
512                 cmp::min(PROPERTY_NAME_MAX, name.len() + 1)
513             }
514             BluetoothProperty::RemoteRssi(_) => mem::size_of::<i8>(),
515             BluetoothProperty::RemoteVersionInfo(_) => mem::size_of::<BtRemoteVersion>(),
516             BluetoothProperty::LocalLeFeatures(_) => mem::size_of::<BtLocalLeFeatures>(),
517             BluetoothProperty::LocalIoCaps(_) => mem::size_of::<BtIoCap>(),
518             BluetoothProperty::LocalIoCapsBle(_) => mem::size_of::<BtIoCap>(),
519             BluetoothProperty::RemoteIsCoordinatedSetMember(_) => mem::size_of::<bool>(),
520             BluetoothProperty::Appearance(_) => mem::size_of::<u16>(),
521             BluetoothProperty::VendorProductInfo(_) => mem::size_of::<BtVendorProductInfo>(),
522 
523             // TODO(abps) - Figure out sizes for these
524             BluetoothProperty::DynamicAudioBuffer() => 0,
525             BluetoothProperty::RemoteDeviceTimestamp() => 0,
526             BluetoothProperty::Unknown() => 0,
527         }
528     }
529 
530     /// Given a mutable array, this will copy the data to that array and return a
531     /// LTCheckedPtrMut to it.
532     ///
533     /// 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>534     fn get_data_ptr<'a>(&'a self, data: &'a mut [u8]) -> LTCheckedPtrMut<'a, u8> {
535         let len = self.get_len();
536         match &*self {
537             BluetoothProperty::BdName(name) => {
538                 let copy_len = len - 1;
539                 data[0..copy_len].copy_from_slice(&name.as_bytes()[0..copy_len]);
540                 data[copy_len] = 0;
541             }
542             BluetoothProperty::BdAddr(addr) => {
543                 data.copy_from_slice(&addr.address);
544             }
545             BluetoothProperty::Uuids(uulist) => {
546                 for (idx, &uuid) in uulist.iter().enumerate() {
547                     let start = idx * mem::size_of::<Uuid>();
548                     let end = start + mem::size_of::<Uuid>();
549                     data[start..end].copy_from_slice(&uuid.uu);
550                 }
551             }
552             BluetoothProperty::ClassOfDevice(cod) => {
553                 data.copy_from_slice(&cod.to_ne_bytes());
554             }
555             BluetoothProperty::TypeOfDevice(tod) => {
556                 data.copy_from_slice(&BtDeviceType::to_u32(tod).unwrap_or_default().to_ne_bytes());
557             }
558             BluetoothProperty::ServiceRecord(sr) => {
559                 // Do an unsafe cast to binding:: type and assign the values
560                 // The underlying memory location is provided by |data| which will
561                 // have enough space because it uses get_len()
562                 let mut record =
563                     unsafe { &mut *(data.as_mut_ptr() as *mut bindings::bt_service_record_t) };
564                 record.uuid = sr.uuid;
565                 record.channel = sr.channel;
566                 let name_len = len - mem::size_of::<BtServiceRecord>() - 1;
567                 record.name[0..name_len].copy_from_slice(
568                     &(sr.name.as_bytes().iter().map(|x| *x as c_char).collect::<Vec<c_char>>())
569                         [0..name_len],
570                 );
571                 record.name[name_len] = 0;
572             }
573             BluetoothProperty::AdapterScanMode(sm) => {
574                 data.copy_from_slice(&BtScanMode::to_u32(sm).unwrap_or_default().to_ne_bytes());
575             }
576             BluetoothProperty::AdapterBondedDevices(devlist) => {
577                 for (idx, &dev) in devlist.iter().enumerate() {
578                     let start = idx * mem::size_of::<RawAddress>();
579                     let end = idx + mem::size_of::<RawAddress>();
580                     data[start..end].copy_from_slice(&dev.address);
581                 }
582             }
583             BluetoothProperty::AdapterDiscoverableTimeout(timeout) => {
584                 data.copy_from_slice(&timeout.to_ne_bytes());
585             }
586             BluetoothProperty::RemoteFriendlyName(name) => {
587                 let copy_len = len - 1;
588                 data[0..copy_len].copy_from_slice(&name.as_bytes()[0..copy_len]);
589                 data[copy_len] = 0;
590             }
591             BluetoothProperty::RemoteRssi(rssi) => {
592                 data[0] = *rssi as u8;
593             }
594             BluetoothProperty::RemoteVersionInfo(rvi) => {
595                 let ptr: *const BtRemoteVersion = rvi;
596                 let slice = unsafe {
597                     std::slice::from_raw_parts(ptr as *mut u8, mem::size_of::<BtRemoteVersion>())
598                 };
599                 data.copy_from_slice(&slice);
600             }
601             BluetoothProperty::LocalLeFeatures(llf) => {
602                 let ptr: *const BtLocalLeFeatures = llf;
603                 let slice = unsafe {
604                     std::slice::from_raw_parts(ptr as *mut u8, mem::size_of::<BtLocalLeFeatures>())
605                 };
606                 data.copy_from_slice(&slice);
607             }
608             BluetoothProperty::LocalIoCaps(iocap) => {
609                 data.copy_from_slice(&BtIoCap::to_u32(iocap).unwrap_or_default().to_ne_bytes());
610             }
611             BluetoothProperty::LocalIoCapsBle(iocap) => {
612                 data.copy_from_slice(&BtIoCap::to_u32(iocap).unwrap_or_default().to_ne_bytes());
613             }
614             BluetoothProperty::RemoteIsCoordinatedSetMember(icsm) => {
615                 data[0] = *icsm as u8;
616             }
617             BluetoothProperty::Appearance(appearance) => {
618                 data.copy_from_slice(&appearance.to_ne_bytes());
619             }
620             BluetoothProperty::VendorProductInfo(vpi) => {
621                 let ptr: *const BtVendorProductInfo = vpi;
622                 let slice = unsafe {
623                     std::slice::from_raw_parts(
624                         ptr as *mut u8,
625                         mem::size_of::<BtVendorProductInfo>(),
626                     )
627                 };
628                 data.copy_from_slice(&slice);
629             }
630 
631             BluetoothProperty::DynamicAudioBuffer() => (),
632             BluetoothProperty::RemoteDeviceTimestamp() => (),
633             BluetoothProperty::Unknown() => (),
634         };
635 
636         data.into()
637     }
638 }
639 
640 // TODO(abps) - Check that sizes are correct when given a BtProperty
641 impl From<bindings::bt_property_t> for BluetoothProperty {
from(prop: bindings::bt_property_t) -> Self642     fn from(prop: bindings::bt_property_t) -> Self {
643         let slice: &[u8] =
644             unsafe { std::slice::from_raw_parts(prop.val as *mut u8, prop.len as usize) };
645         let len = prop.len as usize;
646 
647         match BtPropertyType::from(prop.type_) {
648             BtPropertyType::BdName => BluetoothProperty::BdName(ascii_to_string(slice, len)),
649             BtPropertyType::BdAddr => {
650                 BluetoothProperty::BdAddr(RawAddress::from_bytes(slice).unwrap_or_default())
651             }
652             BtPropertyType::Uuids => {
653                 let count = len / mem::size_of::<Uuid>();
654                 BluetoothProperty::Uuids(ptr_to_vec(prop.val as *mut Uuid, count))
655             }
656             BtPropertyType::ClassOfDevice => {
657                 BluetoothProperty::ClassOfDevice(u32_from_bytes(slice))
658             }
659             BtPropertyType::TypeOfDevice => BluetoothProperty::TypeOfDevice(
660                 BtDeviceType::from_u32(u32_from_bytes(slice)).unwrap_or(BtDeviceType::Unknown),
661             ),
662             BtPropertyType::ServiceRecord => {
663                 let v = unsafe { *(prop.val as *const bindings::bt_service_record_t) };
664                 BluetoothProperty::ServiceRecord(BtServiceRecord::from(v))
665             }
666             BtPropertyType::AdapterScanMode => BluetoothProperty::AdapterScanMode(
667                 BtScanMode::from_u32(u32_from_bytes(slice)).unwrap_or(BtScanMode::None_),
668             ),
669             BtPropertyType::AdapterBondedDevices => {
670                 let count = len / mem::size_of::<RawAddress>();
671                 BluetoothProperty::AdapterBondedDevices(ptr_to_vec(
672                     prop.val as *mut RawAddress,
673                     count,
674                 ))
675             }
676             BtPropertyType::AdapterDiscoverableTimeout => {
677                 BluetoothProperty::AdapterDiscoverableTimeout(u32_from_bytes(slice))
678             }
679             BtPropertyType::RemoteFriendlyName => {
680                 BluetoothProperty::RemoteFriendlyName(ascii_to_string(slice, len))
681             }
682             BtPropertyType::RemoteRssi => BluetoothProperty::RemoteRssi(slice[0] as i8),
683             BtPropertyType::RemoteVersionInfo => {
684                 let v = unsafe { *(prop.val as *const BtRemoteVersion) };
685                 BluetoothProperty::RemoteVersionInfo(v.clone())
686             }
687             BtPropertyType::LocalLeFeatures => {
688                 let v = unsafe { *(prop.val as *const BtLocalLeFeatures) };
689                 BluetoothProperty::LocalLeFeatures(v.clone())
690             }
691             BtPropertyType::LocalIoCaps => BluetoothProperty::LocalIoCaps(
692                 BtIoCap::from_u32(u32_from_bytes(slice)).unwrap_or(BtIoCap::Unknown),
693             ),
694             BtPropertyType::LocalIoCapsBle => BluetoothProperty::LocalIoCapsBle(
695                 BtIoCap::from_u32(u32_from_bytes(slice)).unwrap_or(BtIoCap::Unknown),
696             ),
697             BtPropertyType::RemoteIsCoordinatedSetMember => {
698                 BluetoothProperty::RemoteIsCoordinatedSetMember(slice[0] != 0)
699             }
700             BtPropertyType::Appearance => BluetoothProperty::Appearance(u16_from_bytes(slice)),
701             BtPropertyType::VendorProductInfo => {
702                 let v = unsafe { *(prop.val as *const BtVendorProductInfo) };
703                 BluetoothProperty::VendorProductInfo(BtVendorProductInfo::from(v))
704             }
705 
706             // TODO(abps) - Figure out if these values should actually have contents
707             BtPropertyType::DynamicAudioBuffer => BluetoothProperty::DynamicAudioBuffer(),
708             BtPropertyType::RemoteDeviceTimestamp => BluetoothProperty::RemoteDeviceTimestamp(),
709             _ => BluetoothProperty::Unknown(),
710         }
711     }
712 }
713 
714 impl From<BluetoothProperty> for (Box<[u8]>, bindings::bt_property_t) {
from(prop: BluetoothProperty) -> Self715     fn from(prop: BluetoothProperty) -> Self {
716         let dvec: Vec<u8> = vec![0; prop.get_len()];
717         let mut data: Box<[u8]> = dvec.into_boxed_slice();
718         let prop = bindings::bt_property_t {
719             type_: prop.get_type().into(),
720             len: prop.get_len() as i32,
721             val: prop.get_data_ptr(&mut data).cast_into::<std::os::raw::c_void>(),
722         };
723 
724         (data, prop)
725     }
726 }
727 
728 pub enum SupportedProfiles {
729     HidHost,
730     Hfp,
731     A2dp,
732     Gatt,
733     Sdp,
734     Socket,
735     HfClient,
736     AvrcpCtrl,
737 }
738 
739 impl From<SupportedProfiles> for Vec<u8> {
from(item: SupportedProfiles) -> Self740     fn from(item: SupportedProfiles) -> Self {
741         match item {
742             SupportedProfiles::HidHost => "hidhost",
743             SupportedProfiles::Hfp => "handsfree",
744             SupportedProfiles::A2dp => "a2dp",
745             SupportedProfiles::Gatt => "gatt",
746             SupportedProfiles::Sdp => "sdp",
747             SupportedProfiles::Socket => "socket",
748             SupportedProfiles::HfClient => "handsfree_client",
749             SupportedProfiles::AvrcpCtrl => "avrcp_ctrl",
750         }
751         .bytes()
752         .chain("\0".bytes())
753         .collect::<Vec<u8>>()
754     }
755 }
756 
757 #[cxx::bridge(namespace = bluetooth::topshim::rust)]
758 mod ffi {
759     unsafe extern "C++" {
760         include!("btif/btif_shim.h");
761 
762         // For converting init flags from Vec<String> to const char **
763         type InitFlags;
764 
765         // Convert flgas into an InitFlags object
ConvertFlags(flags: Vec<String>) -> UniquePtr<InitFlags>766         fn ConvertFlags(flags: Vec<String>) -> UniquePtr<InitFlags>;
GetFlagsPtr(self: &InitFlags) -> *mut *const c_char767         fn GetFlagsPtr(self: &InitFlags) -> *mut *const c_char;
768     }
769 }
770 
771 /// The RawAddress directly exported from the bindings.
772 ///
773 /// To make use of RawAddress in cxx::bridge C++ blocks,
774 /// include the following snippet in the ffi module.
775 /// ```ignore
776 /// #[cxx::bridge(namespace = bluetooth::topshim::rust)]
777 /// mod ffi {
778 ///     unsafe extern "C++" {
779 ///         include!("gd/rust/topshim/common/type_alias.h");
780 ///         type RawAddress = crate::btif::RawAddress;
781 ///     }
782 ///     // Place you shared stuff here.
783 /// }
784 /// ```
785 pub type RawAddress = bindings::RawAddress;
786 pub type OobData = bindings::bt_oob_data_s;
787 
788 unsafe impl ExternType for RawAddress {
789     type Id = type_id!("bluetooth::topshim::rust::RawAddress");
790     type Kind = cxx::kind::Trivial;
791 }
792 
793 impl Hash for RawAddress {
hash<H: Hasher>(&self, state: &mut H)794     fn hash<H: Hasher>(&self, state: &mut H) {
795         self.address.hash(state);
796     }
797 }
798 
799 // TODO (b/264603574): Handling address hiding in rust logging statements
800 impl ToString for RawAddress {
to_string(&self) -> String801     fn to_string(&self) -> String {
802         String::from(format!(
803             "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
804             self.address[0],
805             self.address[1],
806             self.address[2],
807             self.address[3],
808             self.address[4],
809             self.address[5]
810         ))
811     }
812 }
813 
814 impl RawAddress {
815     /// Constructs a RawAddress from a slice of 6 bytes.
from_bytes(raw_addr: &[u8]) -> Option<RawAddress>816     pub fn from_bytes(raw_addr: &[u8]) -> Option<RawAddress> {
817         if raw_addr.len() != 6 {
818             return None;
819         }
820         let mut raw: [u8; 6] = [0; 6];
821         raw.copy_from_slice(raw_addr);
822         return Some(RawAddress { address: raw });
823     }
824 
from_string<S: Into<String>>(addr: S) -> Option<RawAddress>825     pub fn from_string<S: Into<String>>(addr: S) -> Option<RawAddress> {
826         let addr: String = addr.into();
827         let s = addr.split(':').collect::<Vec<&str>>();
828 
829         if s.len() != 6 {
830             return None;
831         }
832 
833         let mut raw: [u8; 6] = [0; 6];
834         for i in 0..s.len() {
835             raw[i] = match u8::from_str_radix(s[i], 16) {
836                 Ok(res) => res,
837                 Err(_) => {
838                     return None;
839                 }
840             };
841         }
842 
843         Some(RawAddress { address: raw })
844     }
845 
to_byte_arr(&self) -> [u8; 6]846     pub fn to_byte_arr(&self) -> [u8; 6] {
847         self.address.clone()
848     }
849 
empty() -> RawAddress850     pub fn empty() -> RawAddress {
851         unsafe { bindings::RawAddress_kEmpty }
852     }
853 }
854 
855 /// Address that is safe to display in logs.
856 pub struct DisplayAddress<'a>(pub &'a RawAddress);
857 impl<'a> Display for DisplayAddress<'a> {
fmt(&self, f: &mut Formatter) -> Result858     fn fmt(&self, f: &mut Formatter) -> Result {
859         write!(f, "xx:xx:xx:xx:{:02X}:{:02X}", &self.0.address[4], &self.0.address[5])
860     }
861 }
862 
863 /// An enum representing `bt_callbacks_t` from btif.
864 #[derive(Clone, Debug)]
865 pub enum BaseCallbacks {
866     AdapterState(BtState),
867     AdapterProperties(BtStatus, i32, Vec<BluetoothProperty>),
868     RemoteDeviceProperties(BtStatus, RawAddress, i32, Vec<BluetoothProperty>),
869     DeviceFound(i32, Vec<BluetoothProperty>),
870     DiscoveryState(BtDiscoveryState),
871     PinRequest(RawAddress, String, u32, bool),
872     SspRequest(RawAddress, String, u32, BtSspVariant, u32),
873     BondState(BtStatus, RawAddress, BtBondState, i32),
874     AddressConsolidate(RawAddress, RawAddress),
875     LeAddressAssociate(RawAddress, RawAddress),
876     AclState(
877         BtStatus,
878         RawAddress,
879         BtAclState,
880         BtTransport,
881         BtHciErrorCode,
882         BtConnectionDirection,
883         u16,
884     ),
885     // Unimplemented so far:
886     // thread_evt_cb
887     // energy_info_cb
888     // link_quality_report_cb
889     // switch_buffer_size_cb
890     // switch_codec_cb
891     GenerateLocalOobData(u8, OobData),
892     LeRandCallback(u64),
893 }
894 
895 pub struct BaseCallbacksDispatcher {
896     pub dispatch: Box<dyn Fn(BaseCallbacks) + Send>,
897 }
898 
899 type BaseCb = Arc<Mutex<BaseCallbacksDispatcher>>;
900 
901 cb_variant!(BaseCb, adapter_state_cb -> BaseCallbacks::AdapterState, u32 -> BtState);
902 cb_variant!(BaseCb, adapter_properties_cb -> BaseCallbacks::AdapterProperties,
903 u32 -> BtStatus, i32, *mut bindings::bt_property_t, {
904     let _2 = ptr_to_vec(_2, _1 as usize);
905 });
906 cb_variant!(BaseCb, remote_device_properties_cb -> BaseCallbacks::RemoteDeviceProperties,
907 u32 -> BtStatus, *mut RawAddress -> RawAddress, i32, *mut bindings::bt_property_t, {
908     let _1 = unsafe { *(_1 as *const RawAddress) };
909     let _3 = ptr_to_vec(_3, _2 as usize);
910 });
911 cb_variant!(BaseCb, device_found_cb -> BaseCallbacks::DeviceFound,
912 i32, *mut bindings::bt_property_t, {
913     let _1 = ptr_to_vec(_1, _0 as usize);
914 });
915 cb_variant!(BaseCb, discovery_state_cb -> BaseCallbacks::DiscoveryState,
916     bindings::bt_discovery_state_t -> BtDiscoveryState);
917 cb_variant!(BaseCb, pin_request_cb -> BaseCallbacks::PinRequest,
918 *mut RawAddress, *mut bindings::bt_bdname_t, u32, bool, {
919     let _0 = unsafe { *(_0 as *const RawAddress)};
920     let _1 = String::from(unsafe{*_1});
921 });
922 cb_variant!(BaseCb, ssp_request_cb -> BaseCallbacks::SspRequest,
923 *mut RawAddress, *mut bindings::bt_bdname_t, u32, bindings::bt_ssp_variant_t -> BtSspVariant, u32, {
924     let _0 = unsafe { *(_0 as *const RawAddress) };
925     let _1 = String::from(unsafe{*_1});
926 });
927 cb_variant!(BaseCb, bond_state_cb -> BaseCallbacks::BondState,
928 u32 -> BtStatus, *mut RawAddress, bindings::bt_bond_state_t -> BtBondState, i32, {
929     let _1 = unsafe { *(_1 as *const RawAddress) };
930 });
931 
932 cb_variant!(BaseCb, address_consolidate_cb -> BaseCallbacks::AddressConsolidate,
933 *mut RawAddress, *mut RawAddress, {
934     let _0 = unsafe { *(_0 as *const RawAddress) };
935     let _1 = unsafe { *(_1 as *const RawAddress) };
936 });
937 
938 cb_variant!(BaseCb, le_address_associate_cb -> BaseCallbacks::LeAddressAssociate,
939 *mut RawAddress, *mut RawAddress, {
940     let _0 = unsafe { *(_0 as *const RawAddress) };
941     let _1 = unsafe { *(_1 as *const RawAddress) };
942 });
943 
944 cb_variant!(BaseCb, acl_state_cb -> BaseCallbacks::AclState,
945 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, {
946     let _1 = unsafe { *(_1 as *const RawAddress) };
947 });
948 
949 cb_variant!(BaseCb, generate_local_oob_data_cb -> BaseCallbacks::GenerateLocalOobData, u8, OobData);
950 
951 cb_variant!(BaseCb, le_rand_cb -> BaseCallbacks::LeRandCallback, u64);
952 
953 struct RawInterfaceWrapper {
954     pub raw: *const bindings::bt_interface_t,
955 }
956 
957 unsafe impl Send for RawInterfaceWrapper {}
958 
959 /// Macro to call functions via function pointers. Expects the self object to
960 /// have a raw interface wrapper at `self.internal`. The actual function call is
961 /// marked unsafe since it will need to dereference a C object. This can cause
962 /// segfaults if not validated beforehand.
963 ///
964 /// Example:
965 ///     ccall!(self, foobar, arg1, arg2)
966 ///     Expands to: unsafe {((*self.internal.raw).foobar.unwrap())(arg1, arg2)}
967 #[macro_export]
968 macro_rules! ccall {
969     ($self:ident,$fn_name:ident) => {
970         unsafe {
971             ((*$self.internal.raw).$fn_name.unwrap())()
972         }
973     };
974     ($self:ident,$fn_name:ident, $($args:expr),*) => {
975         unsafe {
976             ((*$self.internal.raw).$fn_name.unwrap())($($args),*)
977         }
978     };
979 }
980 
981 /// Macro to call const functions via cxx. Expects the self object to have the
982 /// cxx object to be called at `self.internal_cxx`.
983 ///
984 /// Example:
985 ///     cxxcall!(self, foobar, arg1, arg2)
986 ///     Expands to: self.internal_cxx.foobar(arg1, arg2)
987 #[macro_export]
988 macro_rules! cxxcall {
989     ($self:expr,$fn_name:ident) => {
990         $self.internal_cxx.$fn_name()
991     };
992     ($self:expr,$fn_name:ident, $($args:expr),*) => {
993         $self.internal_cxx.$fn_name($($args),*)
994     };
995 }
996 
997 /// Macro to call mutable functions via cxx. Mutable functions are always
998 /// required to be defined with `self: Pin<&mut Self>`. The self object must
999 /// have the cxx object at `self.internal_cxx`.
1000 ///
1001 /// Example:
1002 ///     mutcxxcall!(self, foobar, arg1, arg2)
1003 ///     Expands to: self.internal_cxx.pin_mut().foobar(arg1, arg2)
1004 #[macro_export]
1005 macro_rules! mutcxxcall {
1006     ($self:expr,$fn_name:ident) => {
1007         $self.internal_cxx.pin_mut().$fn_name()
1008     };
1009     ($self:expr,$fn_name:ident, $($args:expr),*) => {
1010         $self.internal_cxx.pin_mut().$fn_name($($args),*)
1011     };
1012 }
1013 
1014 #[no_mangle]
wake_lock_noop(_0: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int1015 extern "C" fn wake_lock_noop(_0: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int {
1016     // The wakelock mechanism is not available on this platform,
1017     // so just returning success to avoid error log.
1018     0
1019 }
1020 
1021 /// Rust wrapper around `bt_interface_t`.
1022 pub struct BluetoothInterface {
1023     internal: RawInterfaceWrapper,
1024 
1025     /// Set to true after `initialize` is called.
1026     pub is_init: bool,
1027 
1028     // Need to take ownership of callbacks so it doesn't get freed after init
1029     callbacks: Option<Box<bindings::bt_callbacks_t>>,
1030     os_callouts: Option<Box<bindings::bt_os_callouts_t>>,
1031 }
1032 
1033 impl BluetoothInterface {
is_initialized(&self) -> bool1034     pub fn is_initialized(&self) -> bool {
1035         self.is_init
1036     }
1037 
1038     /// Initialize the Bluetooth interface by setting up the underlying interface.
1039     ///
1040     /// # Arguments
1041     ///
1042     /// * `callbacks` - Dispatcher struct that accepts [`BaseCallbacks`]
1043     /// * `init_flags` - List of flags sent to libbluetooth for init.
initialize( &mut self, callbacks: BaseCallbacksDispatcher, init_flags: Vec<String>, ) -> bool1044     pub fn initialize(
1045         &mut self,
1046         callbacks: BaseCallbacksDispatcher,
1047         init_flags: Vec<String>,
1048     ) -> bool {
1049         // Init flags need to be converted from string to null terminated bytes
1050         let converted: cxx::UniquePtr<ffi::InitFlags> = ffi::ConvertFlags(init_flags);
1051         let flags = (*converted).GetFlagsPtr();
1052 
1053         if get_dispatchers().lock().unwrap().set::<BaseCb>(Arc::new(Mutex::new(callbacks))) {
1054             panic!("Tried to set dispatcher for BaseCallbacks but it already existed");
1055         }
1056 
1057         // Fill up callbacks struct to pass to init function (will be copied so
1058         // no need to worry about ownership)
1059         let mut callbacks = Box::new(bindings::bt_callbacks_t {
1060             size: std::mem::size_of::<bindings::bt_callbacks_t>(),
1061             adapter_state_changed_cb: Some(adapter_state_cb),
1062             adapter_properties_cb: Some(adapter_properties_cb),
1063             remote_device_properties_cb: Some(remote_device_properties_cb),
1064             device_found_cb: Some(device_found_cb),
1065             discovery_state_changed_cb: Some(discovery_state_cb),
1066             pin_request_cb: Some(pin_request_cb),
1067             ssp_request_cb: Some(ssp_request_cb),
1068             bond_state_changed_cb: Some(bond_state_cb),
1069             address_consolidate_cb: Some(address_consolidate_cb),
1070             le_address_associate_cb: Some(le_address_associate_cb),
1071             acl_state_changed_cb: Some(acl_state_cb),
1072             thread_evt_cb: None,
1073             energy_info_cb: None,
1074             link_quality_report_cb: None,
1075             generate_local_oob_data_cb: Some(generate_local_oob_data_cb),
1076             switch_buffer_size_cb: None,
1077             switch_codec_cb: None,
1078             le_rand_cb: Some(le_rand_cb),
1079         });
1080 
1081         let cb_ptr = LTCheckedPtrMut::from(&mut callbacks);
1082 
1083         let (guest_mode, is_common_criteria_mode, config_compare_result, is_atv) =
1084             (false, false, 0, false);
1085 
1086         let init = ccall!(
1087             self,
1088             init,
1089             cb_ptr.into(),
1090             guest_mode,
1091             is_common_criteria_mode,
1092             config_compare_result,
1093             flags,
1094             is_atv,
1095             std::ptr::null()
1096         );
1097 
1098         self.is_init = init == 0;
1099         self.callbacks = Some(callbacks);
1100 
1101         if self.is_init {
1102             // Fill up OSI function table and register it with BTIF.
1103             // TODO(b/271931441) - pass a NoOpOsCallouts structure from
1104             // gd/rust/linux/stack.
1105             let mut callouts = Box::new(bindings::bt_os_callouts_t {
1106                 size: std::mem::size_of::<bindings::bt_os_callouts_t>(),
1107                 set_wake_alarm: None, // Not used
1108                 acquire_wake_lock: Some(wake_lock_noop),
1109                 release_wake_lock: Some(wake_lock_noop),
1110             });
1111             let callouts_ptr = LTCheckedPtrMut::from(&mut callouts);
1112             ccall!(self, set_os_callouts, callouts_ptr.into());
1113             self.os_callouts = Some(callouts);
1114         }
1115 
1116         return self.is_init;
1117     }
1118 
cleanup(&self)1119     pub fn cleanup(&self) {
1120         ccall!(self, cleanup)
1121     }
1122 
enable(&self) -> i321123     pub fn enable(&self) -> i32 {
1124         ccall!(self, enable)
1125     }
1126 
disable(&self) -> i321127     pub fn disable(&self) -> i32 {
1128         ccall!(self, disable)
1129     }
1130 
get_adapter_properties(&self) -> i321131     pub fn get_adapter_properties(&self) -> i32 {
1132         ccall!(self, get_adapter_properties)
1133     }
1134 
get_adapter_property(&self, prop: BtPropertyType) -> i321135     pub fn get_adapter_property(&self, prop: BtPropertyType) -> i32 {
1136         let converted_type = bindings::bt_property_type_t::from(prop);
1137         ccall!(self, get_adapter_property, converted_type)
1138     }
1139 
set_adapter_property(&self, prop: BluetoothProperty) -> i321140     pub fn set_adapter_property(&self, prop: BluetoothProperty) -> i32 {
1141         let prop_pair: (Box<[u8]>, bindings::bt_property_t) = prop.into();
1142         let prop_ptr = LTCheckedPtr::from_ref(&prop_pair.1);
1143         ccall!(self, set_adapter_property, prop_ptr.into())
1144     }
1145 
get_remote_device_properties(&self, addr: &mut RawAddress) -> i321146     pub fn get_remote_device_properties(&self, addr: &mut RawAddress) -> i32 {
1147         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1148         ccall!(self, get_remote_device_properties, addr_ptr.into())
1149     }
1150 
get_remote_device_property( &self, addr: &mut RawAddress, prop_type: BtPropertyType, ) -> i321151     pub fn get_remote_device_property(
1152         &self,
1153         addr: &mut RawAddress,
1154         prop_type: BtPropertyType,
1155     ) -> i32 {
1156         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1157         let converted_type = bindings::bt_property_type_t::from(prop_type);
1158         ccall!(self, get_remote_device_property, addr_ptr.into(), converted_type)
1159     }
1160 
set_remote_device_property( &self, addr: &mut RawAddress, prop: BluetoothProperty, ) -> i321161     pub fn set_remote_device_property(
1162         &self,
1163         addr: &mut RawAddress,
1164         prop: BluetoothProperty,
1165     ) -> i32 {
1166         let prop_pair: (Box<[u8]>, bindings::bt_property_t) = prop.into();
1167         let prop_ptr = LTCheckedPtr::from_ref(&prop_pair.1);
1168         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1169         ccall!(self, set_remote_device_property, addr_ptr.into(), prop_ptr.into())
1170     }
1171 
get_remote_services(&self, addr: &mut RawAddress, transport: BtTransport) -> i321172     pub fn get_remote_services(&self, addr: &mut RawAddress, transport: BtTransport) -> i32 {
1173         let addr_ptr = LTCheckedPtrMut::from_ref(addr);
1174         ccall!(self, get_remote_services, addr_ptr.into(), transport.to_i32().unwrap())
1175     }
1176 
start_discovery(&self) -> i321177     pub fn start_discovery(&self) -> i32 {
1178         ccall!(self, start_discovery)
1179     }
1180 
cancel_discovery(&self) -> i321181     pub fn cancel_discovery(&self) -> i32 {
1182         ccall!(self, cancel_discovery)
1183     }
1184 
create_bond(&self, addr: &RawAddress, transport: BtTransport) -> i321185     pub fn create_bond(&self, addr: &RawAddress, transport: BtTransport) -> i32 {
1186         let ctransport: i32 = transport.into();
1187         let addr_ptr = LTCheckedPtr::from_ref(addr);
1188         ccall!(self, create_bond, addr_ptr.into(), ctransport)
1189     }
1190 
remove_bond(&self, addr: &RawAddress) -> i321191     pub fn remove_bond(&self, addr: &RawAddress) -> i32 {
1192         let addr_ptr = LTCheckedPtr::from_ref(addr);
1193         ccall!(self, remove_bond, addr_ptr.into())
1194     }
1195 
cancel_bond(&self, addr: &RawAddress) -> i321196     pub fn cancel_bond(&self, addr: &RawAddress) -> i32 {
1197         let addr_ptr = LTCheckedPtr::from_ref(addr);
1198         ccall!(self, cancel_bond, addr_ptr.into())
1199     }
1200 
get_connection_state(&self, addr: &RawAddress) -> BtConnectionState1201     pub fn get_connection_state(&self, addr: &RawAddress) -> BtConnectionState {
1202         let addr_ptr = LTCheckedPtr::from_ref(addr);
1203         ccall!(self, get_connection_state, addr_ptr.into()).into()
1204     }
1205 
pin_reply( &self, addr: &RawAddress, accept: u8, pin_len: u8, pin_code: &mut BtPinCode, ) -> i321206     pub fn pin_reply(
1207         &self,
1208         addr: &RawAddress,
1209         accept: u8,
1210         pin_len: u8,
1211         pin_code: &mut BtPinCode,
1212     ) -> i32 {
1213         let addr_ptr = LTCheckedPtr::from_ref(addr);
1214         let pin_code_ptr = LTCheckedPtrMut::from_ref(pin_code);
1215         ccall!(self, pin_reply, addr_ptr.into(), accept, pin_len, pin_code_ptr.into())
1216     }
1217 
ssp_reply( &self, addr: &RawAddress, variant: BtSspVariant, accept: u8, passkey: u32, ) -> i321218     pub fn ssp_reply(
1219         &self,
1220         addr: &RawAddress,
1221         variant: BtSspVariant,
1222         accept: u8,
1223         passkey: u32,
1224     ) -> i32 {
1225         let addr_ptr = LTCheckedPtr::from_ref(addr);
1226         let cvariant = bindings::bt_ssp_variant_t::from(variant);
1227         ccall!(self, ssp_reply, addr_ptr.into(), cvariant, accept, passkey)
1228     }
1229 
clear_event_filter(&self) -> i321230     pub fn clear_event_filter(&self) -> i32 {
1231         ccall!(self, clear_event_filter)
1232     }
1233 
clear_event_mask(&self) -> i321234     pub fn clear_event_mask(&self) -> i32 {
1235         ccall!(self, clear_event_mask)
1236     }
1237 
clear_filter_accept_list(&self) -> i321238     pub fn clear_filter_accept_list(&self) -> i32 {
1239         ccall!(self, clear_filter_accept_list)
1240     }
1241 
disconnect_all_acls(&self) -> i321242     pub fn disconnect_all_acls(&self) -> i32 {
1243         ccall!(self, disconnect_all_acls)
1244     }
1245 
allow_wake_by_hid(&self) -> i321246     pub fn allow_wake_by_hid(&self) -> i32 {
1247         ccall!(self, allow_wake_by_hid)
1248     }
1249 
get_wbs_supported(&self) -> bool1250     pub fn get_wbs_supported(&self) -> bool {
1251         ccall!(self, get_wbs_supported)
1252     }
1253 
get_swb_supported(&self) -> bool1254     pub fn get_swb_supported(&self) -> bool {
1255         ccall!(self, get_swb_supported)
1256     }
1257 
le_rand(&self) -> i321258     pub fn le_rand(&self) -> i32 {
1259         ccall!(self, le_rand)
1260     }
1261 
generate_local_oob_data(&self, transport: i32) -> i321262     pub fn generate_local_oob_data(&self, transport: i32) -> i32 {
1263         ccall!(self, generate_local_oob_data, transport as u8)
1264     }
1265 
restore_filter_accept_list(&self) -> i321266     pub fn restore_filter_accept_list(&self) -> i32 {
1267         ccall!(self, restore_filter_accept_list)
1268     }
1269 
set_default_event_mask_except(&self, mask: u64, le_mask: u64) -> i321270     pub fn set_default_event_mask_except(&self, mask: u64, le_mask: u64) -> i32 {
1271         ccall!(self, set_default_event_mask_except, mask, le_mask)
1272     }
1273 
set_event_filter_inquiry_result_all_devices(&self) -> i321274     pub fn set_event_filter_inquiry_result_all_devices(&self) -> i32 {
1275         ccall!(self, set_event_filter_inquiry_result_all_devices)
1276     }
1277 
set_event_filter_connection_setup_all_devices(&self) -> i321278     pub fn set_event_filter_connection_setup_all_devices(&self) -> i32 {
1279         ccall!(self, set_event_filter_connection_setup_all_devices)
1280     }
1281 
get_profile_interface( &self, profile: SupportedProfiles, ) -> *const std::os::raw::c_void1282     pub(crate) fn get_profile_interface(
1283         &self,
1284         profile: SupportedProfiles,
1285     ) -> *const std::os::raw::c_void {
1286         let cprofile = Vec::<u8>::from(profile);
1287         let cprofile_ptr = LTCheckedPtr::from(&cprofile);
1288         ccall!(self, get_profile_interface, cprofile_ptr.cast_into::<std::os::raw::c_char>())
1289     }
1290 
as_raw_ptr(&self) -> *const u81291     pub(crate) fn as_raw_ptr(&self) -> *const u8 {
1292         self.internal.raw as *const u8
1293     }
1294 }
1295 
1296 pub trait ToggleableProfile {
is_enabled(&self) -> bool1297     fn is_enabled(&self) -> bool;
enable(&mut self) -> bool1298     fn enable(&mut self) -> bool;
disable(&mut self) -> bool1299     fn disable(&mut self) -> bool;
1300 }
1301 
get_btinterface() -> Option<BluetoothInterface>1302 pub fn get_btinterface() -> Option<BluetoothInterface> {
1303     let mut ret: Option<BluetoothInterface> = None;
1304     let mut ifptr: *const bindings::bt_interface_t = std::ptr::null();
1305 
1306     unsafe {
1307         if bindings::hal_util_load_bt_library(&mut ifptr) == 0 {
1308             ret = Some(BluetoothInterface {
1309                 internal: RawInterfaceWrapper { raw: ifptr },
1310                 is_init: false,
1311                 callbacks: None,
1312                 os_callouts: None,
1313             });
1314         }
1315     }
1316 
1317     ret
1318 }
1319 
1320 // Turns C-array T[] to Vec<U>.
ptr_to_vec<T: Copy, U: From<T>>(start: *const T, length: usize) -> Vec<U>1321 pub(crate) fn ptr_to_vec<T: Copy, U: From<T>>(start: *const T, length: usize) -> Vec<U> {
1322     unsafe { (0..length).map(|i| U::from(*start.offset(i as isize))).collect::<Vec<U>>() }
1323 }
1324 
1325 #[cfg(test)]
1326 mod tests {
1327     use super::*;
1328 
make_bdname_from_slice(slice: &[u8]) -> bindings::bt_bdname_t1329     fn make_bdname_from_slice(slice: &[u8]) -> bindings::bt_bdname_t {
1330         // Length of slice must be less than bd_name max
1331         assert!(slice.len() <= 249);
1332 
1333         let mut bdname = bindings::bt_bdname_t { name: [128; 249] };
1334 
1335         for (i, v) in slice.iter().enumerate() {
1336             bdname.name[i] = v.clone();
1337         }
1338 
1339         bdname
1340     }
1341 
1342     #[test]
test_bdname_conversions()1343     fn test_bdname_conversions() {
1344         let hello_bdname = make_bdname_from_slice(&[72, 69, 76, 76, 79, 0]);
1345         assert_eq!("HELLO".to_string(), String::from(hello_bdname));
1346 
1347         let empty_bdname = make_bdname_from_slice(&[0]);
1348         assert_eq!("".to_string(), String::from(empty_bdname));
1349 
1350         let no_nullterm_bdname = make_bdname_from_slice(&[72, 69, 76, 76, 79]);
1351         assert_eq!("".to_string(), String::from(no_nullterm_bdname));
1352 
1353         let invalid_bdname = make_bdname_from_slice(&[128; 249]);
1354         assert_eq!("".to_string(), String::from(invalid_bdname));
1355     }
1356 
1357     #[test]
test_ptr_to_vec()1358     fn test_ptr_to_vec() {
1359         let arr: [i32; 3] = [1, 2, 3];
1360         let vec: Vec<i32> = ptr_to_vec(arr.as_ptr(), arr.len());
1361         let expected: Vec<i32> = vec![1, 2, 3];
1362         assert_eq!(expected, vec);
1363     }
1364 
1365     #[test]
test_property_with_string_conversions()1366     fn test_property_with_string_conversions() {
1367         {
1368             let bdname = BluetoothProperty::BdName("FooBar".into());
1369             let prop_pair: (Box<[u8]>, bindings::bt_property_t) = bdname.into();
1370             let converted: BluetoothProperty = prop_pair.1.into();
1371             assert!(match converted {
1372                 BluetoothProperty::BdName(name) => "FooBar".to_string() == name,
1373                 _ => false,
1374             });
1375         }
1376 
1377         {
1378             let orig_record = BtServiceRecord {
1379                 uuid: Uuid::from([0; 16]),
1380                 channel: 3,
1381                 name: "FooBar".to_string(),
1382             };
1383             let service_record = BluetoothProperty::ServiceRecord(orig_record.clone());
1384             let prop_pair: (Box<[u8]>, bindings::bt_property_t) = service_record.into();
1385             let converted: BluetoothProperty = prop_pair.1.into();
1386             assert!(match converted {
1387                 BluetoothProperty::ServiceRecord(sr) => {
1388                     sr.uuid == orig_record.uuid
1389                         && sr.channel == orig_record.channel
1390                         && sr.name == orig_record.name
1391                 }
1392                 _ => false,
1393             });
1394         }
1395 
1396         {
1397             let rfname = BluetoothProperty::RemoteFriendlyName("FooBizz".into());
1398             let prop_pair: (Box<[u8]>, bindings::bt_property_t) = rfname.into();
1399             let converted: BluetoothProperty = prop_pair.1.into();
1400             assert!(match converted {
1401                 BluetoothProperty::RemoteFriendlyName(name) => "FooBizz".to_string() == name,
1402                 _ => false,
1403             });
1404         }
1405     }
1406 
1407     #[test]
test_display_address()1408     fn test_display_address() {
1409         assert_eq!(
1410             format!("{}", DisplayAddress(&RawAddress::from_string("00:00:00:00:00:00").unwrap())),
1411             String::from("xx:xx:xx:xx:00:00")
1412         );
1413         assert_eq!(
1414             format!("{}", DisplayAddress(&RawAddress::from_string("1a:2b:1a:2b:1a:2b").unwrap())),
1415             String::from("xx:xx:xx:xx:1A:2B")
1416         );
1417         assert_eq!(
1418             format!("{}", DisplayAddress(&RawAddress::from_string("3C:4D:3C:4D:3C:4D").unwrap())),
1419             String::from("xx:xx:xx:xx:3C:4D")
1420         );
1421         assert_eq!(
1422             format!("{}", DisplayAddress(&RawAddress::from_string("11:35:11:35:11:35").unwrap())),
1423             String::from("xx:xx:xx:xx:11:35")
1424         );
1425     }
1426 }
1427