• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::bindings::root as bindings;
2 use crate::btif::{
3     ptr_to_vec, BluetoothInterface, BtStatus, FfiAddress, RawAddress, SupportedProfiles, Uuid,
4 };
5 use crate::profiles::gatt::bindings::{
6     btgatt_callbacks_t, btgatt_client_callbacks_t, btgatt_client_interface_t, btgatt_interface_t,
7     btgatt_scanner_callbacks_t, btgatt_server_callbacks_t, btgatt_server_interface_t,
8     BleAdvertiserInterface, BleScannerInterface,
9 };
10 use crate::topstack::get_dispatchers;
11 use crate::{cast_to_ffi_address, ccall, deref_ffi_address, mutcxxcall};
12 
13 use num_traits::cast::FromPrimitive;
14 
15 use std::sync::{Arc, Mutex};
16 
17 use topshim_macros::cb_variant;
18 
19 pub type BtGattNotifyParams = bindings::btgatt_notify_params_t;
20 pub type BtGattReadParams = bindings::btgatt_read_params_t;
21 pub type BtGattDbElement = bindings::btgatt_db_element_t;
22 pub type BtGattResponse = bindings::btgatt_response_t;
23 pub type BtGattTestParams = bindings::btgatt_test_params_t;
24 
25 #[cxx::bridge(namespace = bluetooth::topshim::rust)]
26 pub mod ffi {
27     #[derive(Debug, Copy, Clone)]
28     pub struct RustRawAddress {
29         address: [u8; 6],
30     }
31 
32     #[derive(Debug, Copy, Clone)]
33     pub struct RustUuid {
34         uu: [u8; 16],
35     }
36 
37     #[derive(Debug, Clone)]
38     pub struct RustAdvertisingTrackInfo {
39         scanner_id: u8,
40         filter_index: u8,
41         advertiser_state: u8,
42         advertiser_info_present: u8,
43         advertiser_address: RustRawAddress,
44         advertiser_address_type: u8,
45         tx_power: u8,
46         rssi: i8,
47         timestamp: u16,
48         adv_packet_len: u8,
49         adv_packet: Vec<u8>,
50         scan_response_len: u8,
51         scan_response: Vec<u8>,
52     }
53 
54     // Original definition exists in C++.
55     #[derive(Debug, Clone)]
56     pub struct RustGattFilterParam {
57         feat_seln: u16,
58         list_logic_type: u16,
59         filt_logic_type: u8,
60         rssi_high_thres: u8,
61         rssi_low_thres: u8,
62         delay_mode: u8,
63         found_timeout: u16,
64         lost_timeout: u16,
65         found_timeout_count: u8,
66         num_of_tracking_entries: u16,
67     }
68 
69     // Defined in C++ and needs a translation in shim.
70     #[derive(Debug, Clone)]
71     pub struct RustApcfCommand {
72         type_: u8,
73         address: RustRawAddress,
74         addr_type: u8,
75         uuid: RustUuid,
76         uuid_mask: RustUuid,
77         name: Vec<u8>,
78         company: u16,
79         company_mask: u16,
80         ad_type: u8,
81         data: Vec<u8>,
82         data_mask: Vec<u8>,
83         irk: [u8; 16],
84     }
85 
86     #[derive(Debug, Clone)]
87     pub struct RustAdvertiseParameters {
88         advertising_event_properties: u16,
89         min_interval: u32,
90         max_interval: u32,
91         channel_map: u8,
92         tx_power: i8,
93         primary_advertising_phy: u8,
94         secondary_advertising_phy: u8,
95         scan_request_notification_enable: u8,
96         own_address_type: i8,
97     }
98 
99     #[derive(Debug, Clone)]
100     pub struct RustPeriodicAdvertisingParameters {
101         enable: u8,
102         min_interval: u16,
103         max_interval: u16,
104         periodic_advertising_properties: u16,
105     }
106 
107     unsafe extern "C++" {
108         include!("gatt/gatt_shim.h");
109 
110         type GattClientIntf;
111 
GetGattClientProfile(btif: *const u8) -> UniquePtr<GattClientIntf>112         unsafe fn GetGattClientProfile(btif: *const u8) -> UniquePtr<GattClientIntf>;
113 
read_phy(self: Pin<&mut GattClientIntf>, client_if: i32, bt_addr: RustRawAddress) -> i32114         fn read_phy(self: Pin<&mut GattClientIntf>, client_if: i32, bt_addr: RustRawAddress)
115             -> i32;
116     }
117 
118     extern "Rust" {
119         // Generated by cb_variant! below.
read_phy_callback( client_if: i32, addr: RustRawAddress, tx_phy: u8, rx_phy: u8, status: u8, )120         fn read_phy_callback(
121             client_if: i32,
122             addr: RustRawAddress,
123             tx_phy: u8,
124             rx_phy: u8,
125             status: u8,
126         );
127     }
128 
129     unsafe extern "C++" {
130         include!("gatt/gatt_ble_scanner_shim.h");
131 
132         type BleScannerIntf;
133 
GetBleScannerIntf(gatt: *const u8) -> UniquePtr<BleScannerIntf>134         unsafe fn GetBleScannerIntf(gatt: *const u8) -> UniquePtr<BleScannerIntf>;
135 
RegisterScanner(self: Pin<&mut BleScannerIntf>, uuid: RustUuid)136         fn RegisterScanner(self: Pin<&mut BleScannerIntf>, uuid: RustUuid);
Unregister(self: Pin<&mut BleScannerIntf>, scanner_id: u8)137         fn Unregister(self: Pin<&mut BleScannerIntf>, scanner_id: u8);
Scan(self: Pin<&mut BleScannerIntf>, start: bool)138         fn Scan(self: Pin<&mut BleScannerIntf>, start: bool);
ScanFilterParamSetup( self: Pin<&mut BleScannerIntf>, scanner_id: u8, action: u8, filter_index: u8, filt_param: RustGattFilterParam, )139         fn ScanFilterParamSetup(
140             self: Pin<&mut BleScannerIntf>,
141             scanner_id: u8,
142             action: u8,
143             filter_index: u8,
144             filt_param: RustGattFilterParam,
145         );
ScanFilterAdd( self: Pin<&mut BleScannerIntf>, filter_index: u8, filters: Vec<RustApcfCommand>, )146         fn ScanFilterAdd(
147             self: Pin<&mut BleScannerIntf>,
148             filter_index: u8,
149             filters: Vec<RustApcfCommand>,
150         );
ScanFilterClear(self: Pin<&mut BleScannerIntf>, filter_index: u8)151         fn ScanFilterClear(self: Pin<&mut BleScannerIntf>, filter_index: u8);
ScanFilterEnable(self: Pin<&mut BleScannerIntf>, enable: bool)152         fn ScanFilterEnable(self: Pin<&mut BleScannerIntf>, enable: bool);
SetScanParameters( self: Pin<&mut BleScannerIntf>, scanner_id: u8, scan_interval: u16, scan_window: u16, )153         fn SetScanParameters(
154             self: Pin<&mut BleScannerIntf>,
155             scanner_id: u8,
156             scan_interval: u16,
157             scan_window: u16,
158         );
159 
BatchscanConfigStorage( self: Pin<&mut BleScannerIntf>, scanner_id: u8, batch_scan_full_max: i32, batch_scan_trunc_max: i32, batch_scan_notify_threshold: i32, )160         fn BatchscanConfigStorage(
161             self: Pin<&mut BleScannerIntf>,
162             scanner_id: u8,
163             batch_scan_full_max: i32,
164             batch_scan_trunc_max: i32,
165             batch_scan_notify_threshold: i32,
166         );
BatchscanEnable( self: Pin<&mut BleScannerIntf>, scan_mode: i32, scan_interval: u16, scan_window: u16, addr_type: i32, discard_rule: i32, )167         fn BatchscanEnable(
168             self: Pin<&mut BleScannerIntf>,
169             scan_mode: i32,
170             scan_interval: u16,
171             scan_window: u16,
172             addr_type: i32,
173             discard_rule: i32,
174         );
BatchscanDisable(self: Pin<&mut BleScannerIntf>)175         fn BatchscanDisable(self: Pin<&mut BleScannerIntf>);
BatchscanReadReports(self: Pin<&mut BleScannerIntf>, scanner_id: u8, scan_mode: i32)176         fn BatchscanReadReports(self: Pin<&mut BleScannerIntf>, scanner_id: u8, scan_mode: i32);
177 
StartSync( self: Pin<&mut BleScannerIntf>, sid: u8, address: RustRawAddress, skip: u16, timeout: u16, )178         fn StartSync(
179             self: Pin<&mut BleScannerIntf>,
180             sid: u8,
181             address: RustRawAddress,
182             skip: u16,
183             timeout: u16,
184         );
StopSync(self: Pin<&mut BleScannerIntf>, handle: u16)185         fn StopSync(self: Pin<&mut BleScannerIntf>, handle: u16);
CancelCreateSync(self: Pin<&mut BleScannerIntf>, sid: u8, address: RustRawAddress)186         fn CancelCreateSync(self: Pin<&mut BleScannerIntf>, sid: u8, address: RustRawAddress);
TransferSync( self: Pin<&mut BleScannerIntf>, address: RustRawAddress, service_data: u16, sync_handle: u16, )187         fn TransferSync(
188             self: Pin<&mut BleScannerIntf>,
189             address: RustRawAddress,
190             service_data: u16,
191             sync_handle: u16,
192         );
TransferSetInfo( self: Pin<&mut BleScannerIntf>, address: RustRawAddress, service_data: u16, adv_handle: u8, )193         fn TransferSetInfo(
194             self: Pin<&mut BleScannerIntf>,
195             address: RustRawAddress,
196             service_data: u16,
197             adv_handle: u8,
198         );
SyncTxParameters( self: Pin<&mut BleScannerIntf>, address: RustRawAddress, mode: u8, skip: u16, timeout: u16, )199         fn SyncTxParameters(
200             self: Pin<&mut BleScannerIntf>,
201             address: RustRawAddress,
202             mode: u8,
203             skip: u16,
204             timeout: u16,
205         );
206 
207         /// Registers a C++ |ScanningCallbacks| implementation with the BleScanner.
208         /// The shim implementation will call all the callbacks defined via |cb_variant!|.
RegisterCallbacks(self: Pin<&mut BleScannerIntf>)209         fn RegisterCallbacks(self: Pin<&mut BleScannerIntf>);
210     }
211 
212     extern "Rust" {
213         // All callbacks below are generated by cb_variant! and will be called
214         // by the ScanningCallbacks handler in shim.
gdscan_on_scanner_registered(uuid: *const i8, scannerId: u8, status: u8)215         unsafe fn gdscan_on_scanner_registered(uuid: *const i8, scannerId: u8, status: u8);
gdscan_on_set_scanner_parameter_complete(scannerId: u8, status: u8)216         unsafe fn gdscan_on_set_scanner_parameter_complete(scannerId: u8, status: u8);
gdscan_on_scan_result( event_type: u16, addr_type: u8, addr: *const i8, primary_phy: u8, secondary_phy: u8, advertising_sid: u8, tx_power: i8, rssi: i8, periodic_adv_int: u16, adv_data_ptr: *const u8, adv_data_len: usize, )217         unsafe fn gdscan_on_scan_result(
218             event_type: u16,
219             addr_type: u8,
220             addr: *const i8,
221             primary_phy: u8,
222             secondary_phy: u8,
223             advertising_sid: u8,
224             tx_power: i8,
225             rssi: i8,
226             periodic_adv_int: u16,
227             adv_data_ptr: *const u8,
228             adv_data_len: usize,
229         );
gdscan_on_track_adv_found_lost(adv_track_info: RustAdvertisingTrackInfo)230         unsafe fn gdscan_on_track_adv_found_lost(adv_track_info: RustAdvertisingTrackInfo);
gdscan_on_batch_scan_reports( client_if: i32, status: i32, report_format: i32, num_records: i32, data_ptr: *const u8, data_len: usize, )231         unsafe fn gdscan_on_batch_scan_reports(
232             client_if: i32,
233             status: i32,
234             report_format: i32,
235             num_records: i32,
236             data_ptr: *const u8,
237             data_len: usize,
238         );
gdscan_on_batch_scan_threshold_crossed(client_if: i32)239         unsafe fn gdscan_on_batch_scan_threshold_crossed(client_if: i32);
240 
241         // Static cb_variant! callbacks using base::Callback
gdscan_register_callback(uuid: RustUuid, scanner_id: u8, btm_status: u8)242         unsafe fn gdscan_register_callback(uuid: RustUuid, scanner_id: u8, btm_status: u8);
gdscan_status_callback(scanner_id: u8, btm_status: u8)243         unsafe fn gdscan_status_callback(scanner_id: u8, btm_status: u8);
gdscan_enable_callback(action: u8, btm_status: u8)244         unsafe fn gdscan_enable_callback(action: u8, btm_status: u8);
gdscan_filter_param_setup_callback( scanner_id: u8, available_space: u8, action: u8, btm_status: u8, )245         unsafe fn gdscan_filter_param_setup_callback(
246             scanner_id: u8,
247             available_space: u8,
248             action: u8,
249             btm_status: u8,
250         );
gdscan_filter_config_callback( filter_index: u8, filter_type: u8, available_space: u8, action: u8, btm_status: u8, )251         unsafe fn gdscan_filter_config_callback(
252             filter_index: u8,
253             filter_type: u8,
254             available_space: u8,
255             action: u8,
256             btm_status: u8,
257         );
gdscan_start_sync_callback( status: u8, sync_handle: u16, advertising_sid: u8, addr_type: u8, address: *const RustRawAddress, phy: u8, interval: u16, )258         unsafe fn gdscan_start_sync_callback(
259             status: u8,
260             sync_handle: u16,
261             advertising_sid: u8,
262             addr_type: u8,
263             address: *const RustRawAddress,
264             phy: u8,
265             interval: u16,
266         );
gdscan_sync_report_callback( sync_handle: u16, tx_power: i8, rssi: i8, status: u8, data: *const u8, len: usize, )267         unsafe fn gdscan_sync_report_callback(
268             sync_handle: u16,
269             tx_power: i8,
270             rssi: i8,
271             status: u8,
272             data: *const u8,
273             len: usize,
274         );
gdscan_sync_lost_callback(sync_handle: u16)275         unsafe fn gdscan_sync_lost_callback(sync_handle: u16);
gdscan_sync_transfer_callback(status: u8, address: *const RustRawAddress)276         unsafe fn gdscan_sync_transfer_callback(status: u8, address: *const RustRawAddress);
277     }
278 
279     unsafe extern "C++" {
280         include!("gatt/gatt_ble_advertiser_shim.h");
281 
282         type BleAdvertiserIntf;
283 
284         /// Given the gatt profile interface, creates a shim interface for
285         /// |BleAdvertiserInterface|.
GetBleAdvertiserIntf(gatt: *const u8) -> UniquePtr<BleAdvertiserIntf>286         unsafe fn GetBleAdvertiserIntf(gatt: *const u8) -> UniquePtr<BleAdvertiserIntf>;
287 
RegisterAdvertiser(self: Pin<&mut BleAdvertiserIntf>)288         fn RegisterAdvertiser(self: Pin<&mut BleAdvertiserIntf>);
Unregister(self: Pin<&mut BleAdvertiserIntf>, adv_id: u8)289         fn Unregister(self: Pin<&mut BleAdvertiserIntf>, adv_id: u8);
290 
GetOwnAddress(self: Pin<&mut BleAdvertiserIntf>, adv_id: u8)291         fn GetOwnAddress(self: Pin<&mut BleAdvertiserIntf>, adv_id: u8);
SetParameters( self: Pin<&mut BleAdvertiserIntf>, adv_id: u8, params: RustAdvertiseParameters, )292         fn SetParameters(
293             self: Pin<&mut BleAdvertiserIntf>,
294             adv_id: u8,
295             params: RustAdvertiseParameters,
296         );
SetData( self: Pin<&mut BleAdvertiserIntf>, adv_id: u8, set_scan_rsp: bool, data: Vec<u8>, )297         fn SetData(
298             self: Pin<&mut BleAdvertiserIntf>,
299             adv_id: u8,
300             set_scan_rsp: bool,
301             data: Vec<u8>,
302         );
Enable( self: Pin<&mut BleAdvertiserIntf>, adv_id: u8, enable: bool, duration: u16, max_ext_adv_events: u8, )303         fn Enable(
304             self: Pin<&mut BleAdvertiserIntf>,
305             adv_id: u8,
306             enable: bool,
307             duration: u16,
308             max_ext_adv_events: u8,
309         );
StartAdvertising( self: Pin<&mut BleAdvertiserIntf>, adv_id: u8, params: RustAdvertiseParameters, advertise_data: Vec<u8>, scan_response_data: Vec<u8>, timeout_in_sec: i32, )310         fn StartAdvertising(
311             self: Pin<&mut BleAdvertiserIntf>,
312             adv_id: u8,
313             params: RustAdvertiseParameters,
314             advertise_data: Vec<u8>,
315             scan_response_data: Vec<u8>,
316             timeout_in_sec: i32,
317         );
StartAdvertisingSet( self: Pin<&mut BleAdvertiserIntf>, reg_id: i32, params: RustAdvertiseParameters, advertise_data: Vec<u8>, scan_response_data: Vec<u8>, periodic_params: RustPeriodicAdvertisingParameters, periodic_data: Vec<u8>, duration: u16, max_ext_adv_events: u8, )318         fn StartAdvertisingSet(
319             self: Pin<&mut BleAdvertiserIntf>,
320             reg_id: i32,
321             params: RustAdvertiseParameters,
322             advertise_data: Vec<u8>,
323             scan_response_data: Vec<u8>,
324             periodic_params: RustPeriodicAdvertisingParameters,
325             periodic_data: Vec<u8>,
326             duration: u16,
327             max_ext_adv_events: u8,
328         );
SetPeriodicAdvertisingParameters( self: Pin<&mut BleAdvertiserIntf>, adv_id: u8, params: RustPeriodicAdvertisingParameters, )329         fn SetPeriodicAdvertisingParameters(
330             self: Pin<&mut BleAdvertiserIntf>,
331             adv_id: u8,
332             params: RustPeriodicAdvertisingParameters,
333         );
SetPeriodicAdvertisingData(self: Pin<&mut BleAdvertiserIntf>, adv_id: u8, data: Vec<u8>)334         fn SetPeriodicAdvertisingData(self: Pin<&mut BleAdvertiserIntf>, adv_id: u8, data: Vec<u8>);
SetPeriodicAdvertisingEnable( self: Pin<&mut BleAdvertiserIntf>, adv_id: u8, enable: bool, )335         fn SetPeriodicAdvertisingEnable(
336             self: Pin<&mut BleAdvertiserIntf>,
337             adv_id: u8,
338             enable: bool,
339         );
340 
341         /// Registers a C++ |AdvertisingCallbacks| implementation with the BleAdvertiser.
342         /// The shim implementation will call all the callbacks defined via |cb_variant!|.
RegisterCallbacks(self: Pin<&mut BleAdvertiserIntf>)343         fn RegisterCallbacks(self: Pin<&mut BleAdvertiserIntf>);
344     }
345 
346     extern "Rust" {
347         // All callbacks below are generated by cb_variant!.
gdadv_on_advertising_set_started( reg_id: i32, adv_id: u8, tx_power: i8, status: u8, )348         unsafe fn gdadv_on_advertising_set_started(
349             reg_id: i32,
350             adv_id: u8,
351             tx_power: i8,
352             status: u8,
353         );
gdadv_on_advertising_enabled(adv_id: u8, enabled: bool, status: u8)354         unsafe fn gdadv_on_advertising_enabled(adv_id: u8, enabled: bool, status: u8);
gdadv_on_advertising_data_set(adv_id: u8, status: u8)355         unsafe fn gdadv_on_advertising_data_set(adv_id: u8, status: u8);
gdadv_on_scan_response_data_set(adv_id: u8, status: u8)356         unsafe fn gdadv_on_scan_response_data_set(adv_id: u8, status: u8);
gdadv_on_advertising_parameters_updated(adv_id: u8, tx_power: i8, status: u8)357         unsafe fn gdadv_on_advertising_parameters_updated(adv_id: u8, tx_power: i8, status: u8);
gdadv_on_periodic_advertising_parameters_updated(adv_id: u8, status: u8)358         unsafe fn gdadv_on_periodic_advertising_parameters_updated(adv_id: u8, status: u8);
gdadv_on_periodic_advertising_data_set(adv_id: u8, status: u8)359         unsafe fn gdadv_on_periodic_advertising_data_set(adv_id: u8, status: u8);
gdadv_on_periodic_advertising_enabled(adv_id: u8, enabled: bool, status: u8)360         unsafe fn gdadv_on_periodic_advertising_enabled(adv_id: u8, enabled: bool, status: u8);
gdadv_on_own_address_read( adv_id: u8, addr_type: u8, address: *const RustRawAddress, )361         unsafe fn gdadv_on_own_address_read(
362             adv_id: u8,
363             addr_type: u8,
364             address: *const RustRawAddress,
365         );
366 
367         // In-band callbacks also generated with cb_variant!.
gdadv_idstatus_callback(adv_id: u8, status: u8)368         unsafe fn gdadv_idstatus_callback(adv_id: u8, status: u8);
gdadv_idtxpowerstatus_callback(adv_id: u8, tx_power: i8, status: u8)369         unsafe fn gdadv_idtxpowerstatus_callback(adv_id: u8, tx_power: i8, status: u8);
gdadv_parameters_callback(adv_id: u8, status: u8, tx_power: i8)370         unsafe fn gdadv_parameters_callback(adv_id: u8, status: u8, tx_power: i8);
gdadv_getaddress_callback( adv_id: u8, addr_type: u8, address: *const RustRawAddress, )371         unsafe fn gdadv_getaddress_callback(
372             adv_id: u8,
373             addr_type: u8,
374             address: *const RustRawAddress,
375         );
376     }
377 }
378 
379 pub type AdvertisingTrackInfo = ffi::RustAdvertisingTrackInfo;
380 pub type GattFilterParam = ffi::RustGattFilterParam;
381 pub type ApcfCommand = ffi::RustApcfCommand;
382 pub type AdvertiseParameters = ffi::RustAdvertiseParameters;
383 pub type PeriodicAdvertisingParameters = ffi::RustPeriodicAdvertisingParameters;
384 
385 impl From<ffi::RustUuid> for Uuid {
from(item: ffi::RustUuid) -> Self386     fn from(item: ffi::RustUuid) -> Self {
387         Uuid { uu: item.uu }
388     }
389 }
390 
391 impl From<Uuid> for ffi::RustUuid {
from(item: Uuid) -> Self392     fn from(item: Uuid) -> Self {
393         ffi::RustUuid { uu: item.uu }
394     }
395 }
396 
397 #[derive(Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
398 #[repr(u32)]
399 pub enum GattStatus {
400     Success = 0x00,
401     InvalidHandle = 0x01,
402     ReadNotPermit = 0x02,
403     WriteNotPermit = 0x03,
404     InvalidPdu = 0x04,
405     InsufAuthentication = 0x05,
406     ReqNotSupported = 0x06,
407     InvalidOffset = 0x07,
408     InsufAuthorization = 0x08,
409     PrepareQFull = 0x09,
410     NotFound = 0x0a,
411     NotLong = 0x0b,
412     InsufKeySize = 0x0c,
413     InvalidAttrLen = 0x0d,
414     ErrUnlikely = 0x0e,
415     InsufEncryption = 0x0f,
416     UnsupportGrpType = 0x10,
417     InsufResource = 0x11,
418     DatabaseOutOfSync = 0x12,
419     ValueNotAllowed = 0x13,
420     IllegalParameter = 0x87,
421     TooShort = 0x7f,
422     NoResources = 0x80,
423     InternalError = 0x81,
424     WrongState = 0x82,
425     DbFull = 0x83,
426     Busy = 0x84,
427     Error = 0x85,
428     CmdStarted = 0x86,
429     Pending = 0x88,
430     AuthFail = 0x89,
431     More = 0x8a,
432     InvalidCfg = 0x8b,
433     ServiceStarted = 0x8c,
434     EncryptedNoMitm = 0x8d,
435     NotEncrypted = 0x8e,
436     Congested = 0x8f,
437     DupReg = 0x90,      /* 0x90 */
438     AlreadyOpen = 0x91, /* 0x91 */
439     Cancel = 0x92,      /* 0x92 */
440     /* = 0xE0 ~ 0xFC reserved for future use */
441 
442     /* Client Characteristic Configuration Descriptor Improperly Configured */
443     CccCfgErr = 0xFD,
444     /* Procedure Already in progress */
445     PrcInProgress = 0xFE,
446     /* Attribute value out of range */
447     OutOfRange = 0xFF,
448 }
449 
450 #[derive(Debug)]
451 pub enum GattClientCallbacks {
452     RegisterClient(i32, i32, Uuid),
453     Connect(i32, i32, i32, RawAddress),
454     Disconnect(i32, i32, i32, RawAddress),
455     SearchComplete(i32, i32),
456     RegisterForNotification(i32, i32, i32, u16),
457     Notify(i32, BtGattNotifyParams),
458     ReadCharacteristic(i32, i32, BtGattReadParams),
459     WriteCharacteristic(i32, i32, u16, u16, *const u8),
460     ReadDescriptor(i32, i32, BtGattReadParams),
461     WriteDescriptor(i32, i32, u16, u16, *const u8),
462     ExecuteWrite(i32, i32),
463     ReadRemoteRssi(i32, RawAddress, i32, i32),
464     ConfigureMtu(i32, i32, i32),
465     Congestion(i32, bool),
466     GetGattDb(i32, Vec<BtGattDbElement>, i32),
467     PhyUpdated(i32, u8, u8, u8),
468     ConnUpdated(i32, u16, u16, u16, u8),
469     ServiceChanged(i32),
470     ReadPhy(i32, RawAddress, u8, u8, u8),
471 }
472 
473 #[derive(Debug)]
474 pub enum GattServerCallbacks {
475     RegisterServer(i32, i32, Uuid),
476     Connection(i32, i32, i32, RawAddress),
477     ServiceAdded(i32, i32, Vec<BtGattDbElement>, usize),
478     ServiceStopped(i32, i32, i32),
479     ServiceDeleted(i32, i32, i32),
480     RequestReadCharacteristic(i32, i32, RawAddress, i32, i32, bool),
481     RequestReadDescriptor(i32, i32, RawAddress, i32, i32, bool),
482     RequestWriteCharacteristic(i32, i32, RawAddress, i32, i32, bool, bool, Vec<u8>, usize),
483     RequestWriteDescriptor(i32, i32, RawAddress, i32, i32, bool, bool, Vec<u8>, usize),
484     RequestExecWrite(i32, i32, RawAddress, i32),
485     ResponseConfirmation(i32, i32),
486     IndicationSent(i32, i32),
487     Congestion(i32, bool),
488     MtuChanged(i32, i32),
489     PhyUpdated(i32, u8, u8, u8),
490     ConnUpdated(i32, u16, u16, u16, u8),
491 }
492 
493 pub struct GattClientCallbacksDispatcher {
494     pub dispatch: Box<dyn Fn(GattClientCallbacks) + Send>,
495 }
496 
497 pub struct GattServerCallbacksDispatcher {
498     pub dispatch: Box<dyn Fn(GattServerCallbacks) + Send>,
499 }
500 
501 type GattClientCb = Arc<Mutex<GattClientCallbacksDispatcher>>;
502 type GattServerCb = Arc<Mutex<GattServerCallbacksDispatcher>>;
503 
504 cb_variant!(
505     GattClientCb,
506     gc_register_client_cb -> GattClientCallbacks::RegisterClient,
507     i32, i32, *const Uuid, {
508         let _2 = unsafe { *_2.clone() };
509     }
510 );
511 
512 cb_variant!(
513     GattClientCb,
514     gc_open_cb -> GattClientCallbacks::Connect,
515     i32, i32, i32, *const FfiAddress, {
516         let _3 = unsafe { deref_ffi_address!(_3) };
517     }
518 );
519 
520 cb_variant!(
521     GattClientCb,
522     gc_close_cb -> GattClientCallbacks::Disconnect,
523     i32, i32, i32, *const FfiAddress, {
524         let _3 = unsafe { deref_ffi_address!(_3) };
525     }
526 );
527 
528 cb_variant!(
529     GattClientCb,
530     gc_search_complete_cb -> GattClientCallbacks::SearchComplete,
531     i32, i32, {}
532 );
533 
534 cb_variant!(
535     GattClientCb,
536     gc_register_for_notification_cb -> GattClientCallbacks::RegisterForNotification,
537     i32, i32, i32, u16, {}
538 );
539 
540 cb_variant!(
541     GattClientCb,
542     gc_notify_cb -> GattClientCallbacks::Notify,
543     i32, *const BtGattNotifyParams, {
544         let _1 = unsafe { *_1.clone() };
545     }
546 );
547 
548 cb_variant!(
549     GattClientCb,
550     gc_read_characteristic_cb -> GattClientCallbacks::ReadCharacteristic,
551     i32, i32, *mut BtGattReadParams, {
552         let _2 = unsafe { *_2.clone() };
553     }
554 );
555 
556 cb_variant!(
557     GattClientCb,
558     gc_write_characteristic_cb -> GattClientCallbacks::WriteCharacteristic,
559     i32, i32, u16, u16, *const u8, {}
560 );
561 
562 cb_variant!(
563     GattClientCb,
564     gc_read_descriptor_cb -> GattClientCallbacks::ReadDescriptor,
565     i32, i32, *const BtGattReadParams, {
566         let _2 = unsafe { *_2.clone() };
567     }
568 );
569 
570 cb_variant!(
571     GattClientCb,
572     gc_write_descriptor_cb -> GattClientCallbacks::WriteDescriptor,
573     i32, i32, u16, u16, *const u8, {}
574 );
575 
576 cb_variant!(
577     GattClientCb,
578     gc_execute_write_cb -> GattClientCallbacks::ExecuteWrite,
579     i32, i32, {}
580 );
581 
582 cb_variant!(
583     GattClientCb,
584     gc_read_remote_rssi_cb -> GattClientCallbacks::ReadRemoteRssi,
585     i32, *const FfiAddress, i32, i32, {
586         let _1 = unsafe { deref_ffi_address!(_1) };
587     }
588 );
589 
590 cb_variant!(
591     GattClientCb,
592     gc_configure_mtu_cb -> GattClientCallbacks::ConfigureMtu,
593     i32, i32, i32, {}
594 );
595 
596 cb_variant!(
597     GattClientCb,
598     gc_congestion_cb -> GattClientCallbacks::Congestion,
599     i32, bool, {}
600 );
601 
602 cb_variant!(
603     GattClientCb,
604     gc_get_gatt_db_cb -> GattClientCallbacks::GetGattDb,
605     i32, *const BtGattDbElement, i32, {
606         let _1 = ptr_to_vec(_1, _2 as usize);
607     }
608 );
609 
610 cb_variant!(
611     GattClientCb,
612     gc_phy_updated_cb -> GattClientCallbacks::PhyUpdated,
613     i32, u8, u8, u8, {}
614 );
615 
616 cb_variant!(
617     GattClientCb,
618     gc_conn_updated_cb -> GattClientCallbacks::ConnUpdated,
619     i32, u16, u16, u16, u8, {}
620 );
621 
622 cb_variant!(
623     GattClientCb,
624     gc_service_changed_cb -> GattClientCallbacks::ServiceChanged,
625     i32, {}
626 );
627 
628 cb_variant!(
629     GattClientCb,
630     read_phy_callback -> GattClientCallbacks::ReadPhy,
631     i32, ffi::RustRawAddress -> RawAddress, u8, u8, u8, {
632         let _1 = RawAddress { val: _1.address };
633     }
634 );
635 
636 cb_variant!(
637     GattServerCb,
638     gs_register_server_cb -> GattServerCallbacks::RegisterServer,
639     i32, i32, *const Uuid, {
640         let _2 = unsafe { *_2.clone() };
641     }
642 );
643 
644 cb_variant!(
645     GattServerCb,
646     gs_connection_cb -> GattServerCallbacks::Connection,
647     i32, i32, i32, *const FfiAddress, {
648         let _3 = unsafe { deref_ffi_address!(_3) };
649     }
650 );
651 
652 cb_variant!(
653     GattServerCb,
654     gs_service_added_cb -> GattServerCallbacks::ServiceAdded,
655     i32, i32, *const BtGattDbElement, usize, {
656         let _2 = ptr_to_vec(_2, _3);
657     }
658 );
659 
660 cb_variant!(
661     GattServerCb,
662     gs_service_stopped_cb -> GattServerCallbacks::ServiceStopped,
663     i32, i32, i32, {}
664 );
665 
666 cb_variant!(
667     GattServerCb,
668     gs_service_deleted_cb -> GattServerCallbacks::ServiceDeleted,
669     i32, i32, i32, {}
670 );
671 
672 cb_variant!(
673     GattServerCb,
674     gs_request_read_characteristic_cb -> GattServerCallbacks::RequestReadCharacteristic,
675     i32, i32, *const FfiAddress, i32, i32, bool, {
676         let _2 = unsafe { deref_ffi_address!(_2) };
677     }
678 );
679 
680 cb_variant!(
681     GattServerCb,
682     gs_request_read_descriptor_cb -> GattServerCallbacks::RequestReadDescriptor,
683     i32, i32, *const FfiAddress, i32, i32, bool, {
684         let _2 = unsafe { deref_ffi_address!(_2) };
685     }
686 );
687 
688 cb_variant!(
689     GattServerCb,
690     gs_request_write_characteristic_cb -> GattServerCallbacks::RequestWriteCharacteristic,
691     i32, i32, *const FfiAddress, i32, i32, bool, bool, *const u8, usize, {
692         let _2 = unsafe { deref_ffi_address!(_2) };
693         let _7 = ptr_to_vec(_7, _8);
694     }
695 );
696 
697 cb_variant!(
698     GattServerCb,
699     gs_request_write_descriptor_cb -> GattServerCallbacks::RequestWriteDescriptor,
700     i32, i32, *const FfiAddress, i32, i32, bool, bool, *const u8, usize, {
701         let _2 = unsafe { deref_ffi_address!(_2) };
702         let _7 = ptr_to_vec(_7, _8);
703     }
704 );
705 
706 cb_variant!(
707     GattServerCb,
708     gs_request_exec_write_cb -> GattServerCallbacks::RequestExecWrite,
709     i32, i32, *const FfiAddress, i32, {
710         let _2 = unsafe { deref_ffi_address!(_2) };
711     }
712 );
713 
714 cb_variant!(
715     GattServerCb,
716     gs_response_confirmation_cb -> GattServerCallbacks::ResponseConfirmation,
717     i32, i32, {}
718 );
719 
720 cb_variant!(
721     GattServerCb,
722     gs_indication_sent_cb -> GattServerCallbacks::IndicationSent,
723     i32, i32, {}
724 );
725 
726 cb_variant!(
727     GattServerCb,
728     gs_congestion_cb -> GattServerCallbacks::Congestion,
729     i32, bool, {}
730 );
731 
732 cb_variant!(
733     GattServerCb,
734     gs_mtu_changed_cb -> GattServerCallbacks::MtuChanged,
735     i32, i32, {}
736 );
737 
738 cb_variant!(
739     GattServerCb,
740     gs_phy_updated_cb -> GattServerCallbacks::PhyUpdated,
741     i32, u8, u8, u8, {}
742 );
743 
744 cb_variant!(
745     GattServerCb,
746     gs_conn_updated_cb -> GattServerCallbacks::ConnUpdated,
747     i32, u16, u16, u16, u8, {}
748 );
749 
750 /// Scanning callbacks used by the GD implementation of BleScannerInterface.
751 /// These callbacks should be registered using |RegisterCallbacks| on
752 /// `BleScannerInterface`.
753 #[derive(Debug)]
754 pub enum GattScannerCallbacks {
755     OnScannerRegistered(Uuid, u8, u8),
756     OnSetScannerParameterComplete(u8, u8),
757     OnScanResult(u16, u8, RawAddress, u8, u8, u8, i8, i8, u16, Vec<u8>),
758     OnTrackAdvFoundLost(AdvertisingTrackInfo),
759     OnBatchScanReports(i32, i32, i32, i32, Vec<u8>),
760     OnBatchScanThresholdCrossed(i32),
761 }
762 
763 pub struct GattScannerCallbacksDispatcher {
764     pub dispatch: Box<dyn Fn(GattScannerCallbacks) + Send>,
765 }
766 
767 type GDScannerCb = Arc<Mutex<GattScannerCallbacksDispatcher>>;
768 
769 cb_variant!(
770     GDScannerCb,
771     gdscan_on_scanner_registered -> GattScannerCallbacks::OnScannerRegistered,
772     *const i8, u8, u8, {
773         let _0 = unsafe { *(_0 as *const Uuid).clone() };
774     }
775 );
776 
777 cb_variant!(
778     GDScannerCb,
779     gdscan_on_set_scanner_parameter_complete -> GattScannerCallbacks::OnSetScannerParameterComplete,
780     u8, u8
781 );
782 
783 cb_variant!(
784     GDScannerCb,
785     gdscan_on_scan_result -> GattScannerCallbacks::OnScanResult,
786     u16, u8, *const i8, u8, u8, u8, i8, i8, u16, *const u8, usize -> _, {
787         // Convert FfiAddress to RawAddress
788         let _2 = unsafe { deref_ffi_address!(_2) };
789 
790         // Convert the vec! at the end. Since this cb is being called via cxx
791         // ffi, we do the vector separation at the cxx layer. The usize is consumed during
792         // conversion.
793         let _9 : Vec<u8> = ptr_to_vec(_9, _10);
794     }
795 );
796 
797 cb_variant!(
798     GDScannerCb,
799     gdscan_on_track_adv_found_lost -> GattScannerCallbacks::OnTrackAdvFoundLost,
800     AdvertisingTrackInfo);
801 
802 cb_variant!(
803     GDScannerCb,
804     gdscan_on_batch_scan_reports -> GattScannerCallbacks::OnBatchScanReports,
805     i32, i32, i32, i32, *const u8, usize -> _, {
806         // Write the vector to the output and consume the usize in the input.
807         let _4 : Vec<u8> = ptr_to_vec(_4, _5);
808     }
809 );
810 
811 cb_variant!(GDScannerCb, gdscan_on_batch_scan_threshold_crossed -> GattScannerCallbacks::OnBatchScanThresholdCrossed, i32);
812 
813 /// In-band callbacks from the various |BleScannerInterface| methods. Rather than
814 /// store closures for each registered callback, we instead bind and return an
815 /// identifier for the callback instead (such as scanner id or Uuid).
816 #[derive(Debug)]
817 pub enum GattScannerInbandCallbacks {
818     /// Params: App Uuid, Scanner Id, BTM Status
819     RegisterCallback(Uuid, u8, u8),
820 
821     /// Params: Scanner Id, BTM Status
822     StatusCallback(u8, u8),
823 
824     /// Params: Action (enable/disable), BTM Status
825     EnableCallback(u8, u8),
826 
827     /// Params: Scanner Id, Available Space, Action Type, BTM Status
828     FilterParamSetupCallback(u8, u8, u8, u8),
829 
830     /// Params: Filter Index, Filter Type, Available Space, Action, BTM Status
831     FilterConfigCallback(u8, u8, u8, u8, u8),
832 
833     /// Params: Status, Sync Handle, Advertising Sid, Address Type, Address, Phy, Interval
834     StartSyncCallback(u8, u16, u8, u8, RawAddress, u8, u16),
835 
836     /// Params: Sync Handle, Tx Power, RSSI, Status, Data
837     SyncReportCallback(u16, i8, i8, u8, Vec<u8>),
838 
839     /// Params: Sync Handle
840     SyncLostCallback(u16),
841 
842     /// Params: Status, Address
843     SyncTransferCallback(u8, RawAddress),
844 }
845 
846 pub struct GattScannerInbandCallbacksDispatcher {
847     pub dispatch: Box<dyn Fn(GattScannerInbandCallbacks) + Send>,
848 }
849 
850 type GDScannerInbandCb = Arc<Mutex<GattScannerInbandCallbacksDispatcher>>;
851 
852 cb_variant!(GDScannerInbandCb, gdscan_register_callback -> GattScannerInbandCallbacks::RegisterCallback,
853     ffi::RustUuid -> Uuid, u8, u8);
854 
855 cb_variant!(GDScannerInbandCb, gdscan_status_callback -> GattScannerInbandCallbacks::StatusCallback, u8, u8);
856 cb_variant!(GDScannerInbandCb, gdscan_enable_callback -> GattScannerInbandCallbacks::EnableCallback, u8, u8);
857 cb_variant!(GDScannerInbandCb,
858     gdscan_filter_param_setup_callback -> GattScannerInbandCallbacks::FilterParamSetupCallback,
859     u8, u8, u8, u8);
860 cb_variant!(GDScannerInbandCb,
861     gdscan_filter_config_callback -> GattScannerInbandCallbacks::FilterConfigCallback,
862     u8, u8, u8, u8, u8);
863 cb_variant!(GDScannerInbandCb,
864 gdscan_start_sync_callback -> GattScannerInbandCallbacks::StartSyncCallback,
865 u8, u16, u8, u8, *const ffi::RustRawAddress, u8, u16, {
866     let _4 = unsafe { deref_ffi_address!(_4) };
867 });
868 cb_variant!(GDScannerInbandCb,
869 gdscan_sync_report_callback -> GattScannerInbandCallbacks::SyncReportCallback,
870 u16, i8, i8, u8, *const u8, usize -> _, {
871     let _4 = ptr_to_vec(_4, _5 as usize);
872 });
873 cb_variant!(GDScannerInbandCb, gdscan_sync_lost_callback -> GattScannerInbandCallbacks::SyncLostCallback, u16);
874 cb_variant!(GDScannerInbandCb, gdscan_sync_transfer_callback -> GattScannerInbandCallbacks::SyncTransferCallback,
875 u8, *const ffi::RustRawAddress, {
876     let _1 = unsafe { deref_ffi_address!(_1) };
877 });
878 
879 /// Advertising callbacks used by the GD implementation of BleAdvertiserInterface.
880 /// These callbacks should be registered using |RegisterCallbacks| on
881 /// `BleAdvertiser`.
882 #[derive(Debug)]
883 pub enum GattAdvCallbacks {
884     /// Params: Reg Id, Advertiser Id, Tx Power, Status
885     OnAdvertisingSetStarted(i32, u8, i8, u8),
886 
887     /// Params: Advertiser Id, Enabled, Status
888     OnAdvertisingEnabled(u8, bool, u8),
889 
890     /// Params: Advertiser Id, Status
891     OnAdvertisingDataSet(u8, u8),
892 
893     /// Params: Advertiser Id, Status
894     OnScanResponseDataSet(u8, u8),
895 
896     /// Params: Advertiser Id, Tx Power, Status
897     OnAdvertisingParametersUpdated(u8, i8, u8),
898 
899     /// Params: Advertiser Id, Status
900     OnPeriodicAdvertisingParametersUpdated(u8, u8),
901 
902     /// Params: Advertiser Id, Status
903     OnPeriodicAdvertisingDataSet(u8, u8),
904 
905     /// Params: Advertiser Id, Enabled, Status
906     OnPeriodicAdvertisingEnabled(u8, bool, u8),
907 
908     /// Params: Advertiser Id, Address Type, Address
909     OnOwnAddressRead(u8, u8, RawAddress),
910 }
911 
912 pub struct GattAdvCallbacksDispatcher {
913     pub dispatch: Box<dyn Fn(GattAdvCallbacks) + Send>,
914 }
915 
916 type GDAdvCb = Arc<Mutex<GattAdvCallbacksDispatcher>>;
917 
918 cb_variant!(GDAdvCb,
919     gdadv_on_advertising_set_started -> GattAdvCallbacks::OnAdvertisingSetStarted,
920     i32, u8, i8, u8);
921 cb_variant!(GDAdvCb,
922     gdadv_on_advertising_enabled -> GattAdvCallbacks::OnAdvertisingEnabled,
923     u8, bool, u8);
924 cb_variant!(GDAdvCb,
925     gdadv_on_advertising_data_set -> GattAdvCallbacks::OnAdvertisingDataSet,
926     u8, u8);
927 cb_variant!(GDAdvCb,
928     gdadv_on_scan_response_data_set -> GattAdvCallbacks::OnScanResponseDataSet,
929     u8, u8);
930 cb_variant!(GDAdvCb,
931     gdadv_on_advertising_parameters_updated -> GattAdvCallbacks::OnAdvertisingParametersUpdated,
932     u8, i8, u8);
933 cb_variant!(GDAdvCb,
934     gdadv_on_periodic_advertising_parameters_updated -> GattAdvCallbacks::OnPeriodicAdvertisingParametersUpdated,
935     u8, u8);
936 cb_variant!(GDAdvCb,
937     gdadv_on_periodic_advertising_data_set -> GattAdvCallbacks::OnPeriodicAdvertisingDataSet,
938     u8, u8);
939 cb_variant!(GDAdvCb,
940     gdadv_on_periodic_advertising_enabled -> GattAdvCallbacks::OnPeriodicAdvertisingEnabled,
941     u8, bool, u8);
942 cb_variant!(GDAdvCb,
943 gdadv_on_own_address_read -> GattAdvCallbacks::OnOwnAddressRead, u8, u8,
944 *const ffi::RustRawAddress, {
945     let _2 = unsafe { deref_ffi_address!(_2) };
946 });
947 
948 #[derive(Debug)]
949 pub enum GattAdvInbandCallbacks {
950     /// Params: Advertiser Id, Status
951     /// StatusCallback isn't implemented because we always want advertiser id.
952     IdStatusCallback(u8, u8),
953 
954     /// Params: Advertiser Id, Tx Power, Status
955     IdTxPowerStatusCallback(u8, i8, u8),
956 
957     /// Params: Advertiser Id, Status, Tx Power
958     ParametersCallback(u8, u8, i8),
959 
960     /// Params: Advertiser Id, Addr Type, Address
961     GetAddressCallback(u8, u8, RawAddress),
962 }
963 
964 pub struct GattAdvInbandCallbacksDispatcher {
965     pub dispatch: Box<dyn Fn(GattAdvInbandCallbacks) + Send>,
966 }
967 
968 type GDAdvInbandCb = Arc<Mutex<GattAdvInbandCallbacksDispatcher>>;
969 
970 cb_variant!(GDAdvInbandCb, gdadv_idstatus_callback -> GattAdvInbandCallbacks::IdStatusCallback, u8, u8);
971 cb_variant!(GDAdvInbandCb, gdadv_idtxpowerstatus_callback -> GattAdvInbandCallbacks::IdTxPowerStatusCallback, u8, i8, u8);
972 cb_variant!(GDAdvInbandCb, gdadv_parameters_callback -> GattAdvInbandCallbacks::ParametersCallback, u8, u8, i8);
973 cb_variant!(GDAdvInbandCb, gdadv_getaddress_callback -> GattAdvInbandCallbacks::GetAddressCallback,
974 u8, u8, *const ffi::RustRawAddress, {
975     let _2 = unsafe { deref_ffi_address!(_2) };
976 });
977 
978 struct RawGattWrapper {
979     raw: *const btgatt_interface_t,
980 }
981 
982 struct RawGattClientWrapper {
983     raw: *const btgatt_client_interface_t,
984 }
985 
986 struct RawGattServerWrapper {
987     raw: *const btgatt_server_interface_t,
988 }
989 
990 struct RawBleScannerWrapper {
991     _raw: *const BleScannerInterface,
992 }
993 
994 struct RawBleAdvertiserWrapper {
995     _raw: *const BleAdvertiserInterface,
996 }
997 
998 // Pointers unsafe due to ownership but this is a static pointer so Send is ok
999 unsafe impl Send for RawGattWrapper {}
1000 unsafe impl Send for RawGattClientWrapper {}
1001 unsafe impl Send for RawGattServerWrapper {}
1002 unsafe impl Send for RawBleScannerWrapper {}
1003 unsafe impl Send for RawBleAdvertiserWrapper {}
1004 unsafe impl Send for btgatt_callbacks_t {}
1005 unsafe impl Send for GattClient {}
1006 unsafe impl Send for GattClientCallbacks {}
1007 unsafe impl Send for BleScanner {}
1008 unsafe impl Send for BleAdvertiser {}
1009 
1010 pub struct GattClient {
1011     internal: RawGattClientWrapper,
1012     internal_cxx: cxx::UniquePtr<ffi::GattClientIntf>,
1013 }
1014 
1015 impl GattClient {
register_client(&self, uuid: &Uuid, eatt_support: bool) -> BtStatus1016     pub fn register_client(&self, uuid: &Uuid, eatt_support: bool) -> BtStatus {
1017         BtStatus::from(ccall!(self, register_client, uuid, eatt_support))
1018     }
1019 
unregister_client(&self, client_if: i32) -> BtStatus1020     pub fn unregister_client(&self, client_if: i32) -> BtStatus {
1021         BtStatus::from(ccall!(self, unregister_client, client_if))
1022     }
1023 
connect( &self, client_if: i32, addr: &RawAddress, is_direct: bool, transport: i32, opportunistic: bool, initiating_phys: i32, ) -> BtStatus1024     pub fn connect(
1025         &self,
1026         client_if: i32,
1027         addr: &RawAddress,
1028         is_direct: bool,
1029         transport: i32,
1030         opportunistic: bool,
1031         initiating_phys: i32,
1032     ) -> BtStatus {
1033         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1034         BtStatus::from(ccall!(
1035             self,
1036             connect,
1037             client_if,
1038             ffi_addr,
1039             is_direct,
1040             transport,
1041             opportunistic,
1042             initiating_phys
1043         ))
1044     }
1045 
disconnect(&self, client_if: i32, addr: &RawAddress, conn_id: i32) -> BtStatus1046     pub fn disconnect(&self, client_if: i32, addr: &RawAddress, conn_id: i32) -> BtStatus {
1047         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1048         BtStatus::from(ccall!(self, disconnect, client_if, ffi_addr, conn_id))
1049     }
1050 
refresh(&self, client_if: i32, addr: &RawAddress) -> BtStatus1051     pub fn refresh(&self, client_if: i32, addr: &RawAddress) -> BtStatus {
1052         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1053         BtStatus::from(ccall!(self, refresh, client_if, ffi_addr))
1054     }
1055 
search_service(&self, conn_id: i32, filter_uuid: Option<Uuid>) -> BtStatus1056     pub fn search_service(&self, conn_id: i32, filter_uuid: Option<Uuid>) -> BtStatus {
1057         let filter_uuid_ptr = match filter_uuid {
1058             None => std::ptr::null(),
1059             Some(uuid) => &uuid,
1060         };
1061 
1062         BtStatus::from(ccall!(self, search_service, conn_id, filter_uuid_ptr))
1063     }
1064 
btif_gattc_discover_service_by_uuid(&self, conn_id: i32, uuid: &Uuid)1065     pub fn btif_gattc_discover_service_by_uuid(&self, conn_id: i32, uuid: &Uuid) {
1066         ccall!(self, btif_gattc_discover_service_by_uuid, conn_id, uuid)
1067     }
1068 
read_characteristic(&self, conn_id: i32, handle: u16, auth_req: i32) -> BtStatus1069     pub fn read_characteristic(&self, conn_id: i32, handle: u16, auth_req: i32) -> BtStatus {
1070         BtStatus::from(ccall!(self, read_characteristic, conn_id, handle, auth_req))
1071     }
1072 
read_using_characteristic_uuid( &self, conn_id: i32, uuid: &Uuid, s_handle: u16, e_handle: u16, auth_req: i32, ) -> BtStatus1073     pub fn read_using_characteristic_uuid(
1074         &self,
1075         conn_id: i32,
1076         uuid: &Uuid,
1077         s_handle: u16,
1078         e_handle: u16,
1079         auth_req: i32,
1080     ) -> BtStatus {
1081         BtStatus::from(ccall!(
1082             self,
1083             read_using_characteristic_uuid,
1084             conn_id,
1085             uuid,
1086             s_handle,
1087             e_handle,
1088             auth_req
1089         ))
1090     }
1091 
write_characteristic( &self, conn_id: i32, handle: u16, write_type: i32, auth_req: i32, value: &[u8], ) -> BtStatus1092     pub fn write_characteristic(
1093         &self,
1094         conn_id: i32,
1095         handle: u16,
1096         write_type: i32,
1097         auth_req: i32,
1098         value: &[u8],
1099     ) -> BtStatus {
1100         BtStatus::from(ccall!(
1101             self,
1102             write_characteristic,
1103             conn_id,
1104             handle,
1105             write_type,
1106             auth_req,
1107             value.as_ptr(),
1108             value.len()
1109         ))
1110     }
1111 
read_descriptor(&self, conn_id: i32, handle: u16, auth_req: i32) -> BtStatus1112     pub fn read_descriptor(&self, conn_id: i32, handle: u16, auth_req: i32) -> BtStatus {
1113         BtStatus::from(ccall!(self, read_descriptor, conn_id, handle, auth_req))
1114     }
1115 
write_descriptor( &self, conn_id: i32, handle: u16, auth_req: i32, value: &[u8], ) -> BtStatus1116     pub fn write_descriptor(
1117         &self,
1118         conn_id: i32,
1119         handle: u16,
1120         auth_req: i32,
1121         value: &[u8],
1122     ) -> BtStatus {
1123         BtStatus::from(ccall!(
1124             self,
1125             write_descriptor,
1126             conn_id,
1127             handle,
1128             auth_req,
1129             value.as_ptr(),
1130             value.len()
1131         ))
1132     }
1133 
execute_write(&self, conn_id: i32, execute: i32) -> BtStatus1134     pub fn execute_write(&self, conn_id: i32, execute: i32) -> BtStatus {
1135         BtStatus::from(ccall!(self, execute_write, conn_id, execute))
1136     }
1137 
register_for_notification( &self, client_if: i32, addr: &RawAddress, handle: u16, ) -> BtStatus1138     pub fn register_for_notification(
1139         &self,
1140         client_if: i32,
1141         addr: &RawAddress,
1142         handle: u16,
1143     ) -> BtStatus {
1144         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1145         BtStatus::from(ccall!(self, register_for_notification, client_if, ffi_addr, handle))
1146     }
1147 
deregister_for_notification( &self, client_if: i32, addr: &RawAddress, handle: u16, ) -> BtStatus1148     pub fn deregister_for_notification(
1149         &self,
1150         client_if: i32,
1151         addr: &RawAddress,
1152         handle: u16,
1153     ) -> BtStatus {
1154         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1155         BtStatus::from(ccall!(self, deregister_for_notification, client_if, ffi_addr, handle))
1156     }
1157 
read_remote_rssi(&self, client_if: i32, addr: &RawAddress) -> BtStatus1158     pub fn read_remote_rssi(&self, client_if: i32, addr: &RawAddress) -> BtStatus {
1159         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1160         BtStatus::from(ccall!(self, read_remote_rssi, client_if, ffi_addr))
1161     }
1162 
get_device_type(&self, addr: &RawAddress) -> i321163     pub fn get_device_type(&self, addr: &RawAddress) -> i32 {
1164         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1165         ccall!(self, get_device_type, ffi_addr)
1166     }
1167 
configure_mtu(&self, conn_id: i32, mtu: i32) -> BtStatus1168     pub fn configure_mtu(&self, conn_id: i32, mtu: i32) -> BtStatus {
1169         BtStatus::from(ccall!(self, configure_mtu, conn_id, mtu))
1170     }
1171 
conn_parameter_update( &self, addr: &RawAddress, min_interval: i32, max_interval: i32, latency: i32, timeout: i32, min_ce_len: u16, max_ce_len: u16, ) -> BtStatus1172     pub fn conn_parameter_update(
1173         &self,
1174         addr: &RawAddress,
1175         min_interval: i32,
1176         max_interval: i32,
1177         latency: i32,
1178         timeout: i32,
1179         min_ce_len: u16,
1180         max_ce_len: u16,
1181     ) -> BtStatus {
1182         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1183         BtStatus::from(ccall!(
1184             self,
1185             conn_parameter_update,
1186             ffi_addr,
1187             min_interval,
1188             max_interval,
1189             latency,
1190             timeout,
1191             min_ce_len,
1192             max_ce_len
1193         ))
1194     }
1195 
set_preferred_phy( &self, addr: &RawAddress, tx_phy: u8, rx_phy: u8, phy_options: u16, ) -> BtStatus1196     pub fn set_preferred_phy(
1197         &self,
1198         addr: &RawAddress,
1199         tx_phy: u8,
1200         rx_phy: u8,
1201         phy_options: u16,
1202     ) -> BtStatus {
1203         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1204         BtStatus::from(ccall!(self, set_preferred_phy, ffi_addr, tx_phy, rx_phy, phy_options))
1205     }
1206 
read_phy(&mut self, client_if: i32, addr: &RawAddress) -> BtStatus1207     pub fn read_phy(&mut self, client_if: i32, addr: &RawAddress) -> BtStatus {
1208         BtStatus::from_i32(mutcxxcall!(
1209             self,
1210             read_phy,
1211             client_if,
1212             ffi::RustRawAddress { address: addr.val }
1213         ))
1214         .unwrap()
1215     }
1216 
test_command(&self, command: i32, params: &BtGattTestParams) -> BtStatus1217     pub fn test_command(&self, command: i32, params: &BtGattTestParams) -> BtStatus {
1218         BtStatus::from(ccall!(self, test_command, command, params))
1219     }
1220 
get_gatt_db(&self, conn_id: i32) -> BtStatus1221     pub fn get_gatt_db(&self, conn_id: i32) -> BtStatus {
1222         BtStatus::from(ccall!(self, get_gatt_db, conn_id))
1223     }
1224 }
1225 
1226 pub struct GattServer {
1227     internal: RawGattServerWrapper,
1228 }
1229 
1230 impl GattServer {
register_server(&self, uuid: &Uuid, eatt_support: bool) -> BtStatus1231     pub fn register_server(&self, uuid: &Uuid, eatt_support: bool) -> BtStatus {
1232         BtStatus::from(ccall!(self, register_server, uuid, eatt_support))
1233     }
1234 
unregister_server(&self, server_if: i32) -> BtStatus1235     pub fn unregister_server(&self, server_if: i32) -> BtStatus {
1236         BtStatus::from(ccall!(self, unregister_server, server_if))
1237     }
1238 
connect( &self, server_if: i32, addr: &RawAddress, is_direct: bool, transport: i32, ) -> BtStatus1239     pub fn connect(
1240         &self,
1241         server_if: i32,
1242         addr: &RawAddress,
1243         is_direct: bool,
1244         transport: i32,
1245     ) -> BtStatus {
1246         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1247         BtStatus::from(ccall!(self, connect, server_if, ffi_addr, is_direct, transport))
1248     }
1249 
disconnect(&self, server_if: i32, addr: &RawAddress, conn_id: i32) -> BtStatus1250     pub fn disconnect(&self, server_if: i32, addr: &RawAddress, conn_id: i32) -> BtStatus {
1251         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1252         BtStatus::from(ccall!(self, disconnect, server_if, ffi_addr, conn_id))
1253     }
1254 
add_service(&self, server_if: i32, service: &[BtGattDbElement]) -> BtStatus1255     pub fn add_service(&self, server_if: i32, service: &[BtGattDbElement]) -> BtStatus {
1256         BtStatus::from(ccall!(self, add_service, server_if, service.as_ptr(), service.len()))
1257     }
1258 
stop_service(&self, server_if: i32, service_handle: i32) -> BtStatus1259     pub fn stop_service(&self, server_if: i32, service_handle: i32) -> BtStatus {
1260         BtStatus::from(ccall!(self, stop_service, server_if, service_handle))
1261     }
1262 
delete_service(&self, server_if: i32, service_handle: i32) -> BtStatus1263     pub fn delete_service(&self, server_if: i32, service_handle: i32) -> BtStatus {
1264         BtStatus::from(ccall!(self, delete_service, server_if, service_handle))
1265     }
1266 
send_indication( &self, server_if: i32, attribute_handle: i32, conn_id: i32, confirm: i32, value: &[u8], ) -> BtStatus1267     pub fn send_indication(
1268         &self,
1269         server_if: i32,
1270         attribute_handle: i32,
1271         conn_id: i32,
1272         confirm: i32,
1273         value: &[u8],
1274     ) -> BtStatus {
1275         BtStatus::from(ccall!(
1276             self,
1277             send_indication,
1278             server_if,
1279             attribute_handle,
1280             conn_id,
1281             confirm,
1282             value.as_ptr(),
1283             value.len()
1284         ))
1285     }
1286 
send_response( &self, conn_id: i32, trans_id: i32, status: i32, response: &BtGattResponse, ) -> BtStatus1287     pub fn send_response(
1288         &self,
1289         conn_id: i32,
1290         trans_id: i32,
1291         status: i32,
1292         response: &BtGattResponse,
1293     ) -> BtStatus {
1294         BtStatus::from(ccall!(self, send_response, conn_id, trans_id, status, response))
1295     }
1296 
set_preferred_phy( &self, addr: &RawAddress, tx_phy: u8, rx_phy: u8, phy_options: u16, ) -> BtStatus1297     pub fn set_preferred_phy(
1298         &self,
1299         addr: &RawAddress,
1300         tx_phy: u8,
1301         rx_phy: u8,
1302         phy_options: u16,
1303     ) -> BtStatus {
1304         let ffi_addr = cast_to_ffi_address!(addr as *const RawAddress);
1305         BtStatus::from(ccall!(self, set_preferred_phy, ffi_addr, tx_phy, rx_phy, phy_options))
1306     }
1307 
1308     // TODO(b/193916778): Figure out how to shim read_phy which accepts base::Callback
1309 }
1310 
1311 pub struct BleScanner {
1312     _internal: RawBleScannerWrapper,
1313     internal_cxx: cxx::UniquePtr<ffi::BleScannerIntf>,
1314 }
1315 
1316 impl BleScanner {
new( raw_gatt: *const btgatt_interface_t, internal_cxx: cxx::UniquePtr<ffi::BleScannerIntf>, ) -> Self1317     pub(crate) fn new(
1318         raw_gatt: *const btgatt_interface_t,
1319         internal_cxx: cxx::UniquePtr<ffi::BleScannerIntf>,
1320     ) -> Self {
1321         BleScanner {
1322             _internal: RawBleScannerWrapper {
1323                 _raw: unsafe { (*raw_gatt).scanner as *const BleScannerInterface },
1324             },
1325             internal_cxx,
1326         }
1327     }
1328 
register_scanner(&mut self, app_uuid: Uuid)1329     pub fn register_scanner(&mut self, app_uuid: Uuid) {
1330         mutcxxcall!(self, RegisterScanner, app_uuid.into());
1331     }
1332 
unregister(&mut self, scanner_id: u8)1333     pub fn unregister(&mut self, scanner_id: u8) {
1334         mutcxxcall!(self, Unregister, scanner_id);
1335     }
1336 
start_scan(&mut self)1337     pub fn start_scan(&mut self) {
1338         mutcxxcall!(self, Scan, true);
1339     }
1340 
stop_scan(&mut self)1341     pub fn stop_scan(&mut self) {
1342         mutcxxcall!(self, Scan, false);
1343     }
1344 
scan_filter_setup( &mut self, scanner_id: u8, action: u8, filter_index: u8, param: GattFilterParam, )1345     pub fn scan_filter_setup(
1346         &mut self,
1347         scanner_id: u8,
1348         action: u8,
1349         filter_index: u8,
1350         param: GattFilterParam,
1351     ) {
1352         mutcxxcall!(self, ScanFilterParamSetup, scanner_id, action, filter_index, param);
1353     }
1354 
scan_filter_add(&mut self, filter_index: u8, filters: Vec<ApcfCommand>)1355     pub fn scan_filter_add(&mut self, filter_index: u8, filters: Vec<ApcfCommand>) {
1356         mutcxxcall!(self, ScanFilterAdd, filter_index, filters);
1357     }
1358 
scan_filter_clear(&mut self, filter_index: u8)1359     pub fn scan_filter_clear(&mut self, filter_index: u8) {
1360         mutcxxcall!(self, ScanFilterClear, filter_index);
1361     }
1362 
scan_filter_enable(&mut self)1363     pub fn scan_filter_enable(&mut self) {
1364         mutcxxcall!(self, ScanFilterEnable, true);
1365     }
1366 
scan_filter_disable(&mut self)1367     pub fn scan_filter_disable(&mut self) {
1368         mutcxxcall!(self, ScanFilterEnable, false);
1369     }
1370 
set_scan_parameters(&mut self, scanner_id: u8, scan_interval: u16, scan_window: u16)1371     pub fn set_scan_parameters(&mut self, scanner_id: u8, scan_interval: u16, scan_window: u16) {
1372         mutcxxcall!(self, SetScanParameters, scanner_id, scan_interval, scan_window);
1373     }
1374 
batchscan_config_storage( &mut self, scanner_id: u8, full_max: i32, trunc_max: i32, notify_threshold: i32, )1375     pub fn batchscan_config_storage(
1376         &mut self,
1377         scanner_id: u8,
1378         full_max: i32,
1379         trunc_max: i32,
1380         notify_threshold: i32,
1381     ) {
1382         mutcxxcall!(
1383             self,
1384             BatchscanConfigStorage,
1385             scanner_id,
1386             full_max,
1387             trunc_max,
1388             notify_threshold
1389         );
1390     }
1391 
batchscan_enable( &mut self, scan_mode: i32, scan_interval: u16, scan_window: u16, addr_type: i32, discard_rule: i32, )1392     pub fn batchscan_enable(
1393         &mut self,
1394         scan_mode: i32,
1395         scan_interval: u16,
1396         scan_window: u16,
1397         addr_type: i32,
1398         discard_rule: i32,
1399     ) {
1400         mutcxxcall!(
1401             self,
1402             BatchscanEnable,
1403             scan_mode,
1404             scan_interval,
1405             scan_window,
1406             addr_type,
1407             discard_rule
1408         );
1409     }
1410 
batchscan_disable(&mut self)1411     pub fn batchscan_disable(&mut self) {
1412         mutcxxcall!(self, BatchscanDisable);
1413     }
1414 
batchscan_read_reports(&mut self, scanner_id: u8, scan_mode: i32)1415     pub fn batchscan_read_reports(&mut self, scanner_id: u8, scan_mode: i32) {
1416         mutcxxcall!(self, BatchscanReadReports, scanner_id, scan_mode);
1417     }
1418 
start_sync(&mut self, sid: u8, address: RawAddress, skip: u16, timeout: u16)1419     pub fn start_sync(&mut self, sid: u8, address: RawAddress, skip: u16, timeout: u16) {
1420         let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
1421         mutcxxcall!(self, StartSync, sid, addr, skip, timeout);
1422     }
1423 
stop_sync(&mut self, handle: u16)1424     pub fn stop_sync(&mut self, handle: u16) {
1425         mutcxxcall!(self, StopSync, handle);
1426     }
1427 
cancel_create_sync(&mut self, sid: u8, address: RawAddress)1428     pub fn cancel_create_sync(&mut self, sid: u8, address: RawAddress) {
1429         let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
1430         mutcxxcall!(self, CancelCreateSync, sid, addr);
1431     }
1432 
transfer_sync(&mut self, address: RawAddress, service_data: u16, sync_handle: u16)1433     pub fn transfer_sync(&mut self, address: RawAddress, service_data: u16, sync_handle: u16) {
1434         let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
1435         mutcxxcall!(self, TransferSync, addr, service_data, sync_handle);
1436     }
1437 
transfer_set_info(&mut self, address: RawAddress, service_data: u16, adv_handle: u8)1438     pub fn transfer_set_info(&mut self, address: RawAddress, service_data: u16, adv_handle: u8) {
1439         let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
1440         mutcxxcall!(self, TransferSetInfo, addr, service_data, adv_handle);
1441     }
1442 
sync_tx_parameters(&mut self, address: RawAddress, mode: u8, skip: u16, timeout: u16)1443     pub fn sync_tx_parameters(&mut self, address: RawAddress, mode: u8, skip: u16, timeout: u16) {
1444         let addr = unsafe { *((&address as *const RawAddress) as *const ffi::RustRawAddress) };
1445         mutcxxcall!(self, SyncTxParameters, addr, mode, skip, timeout);
1446     }
1447 }
1448 
1449 pub struct BleAdvertiser {
1450     _internal: RawBleAdvertiserWrapper,
1451     internal_cxx: cxx::UniquePtr<ffi::BleAdvertiserIntf>,
1452 }
1453 
1454 impl BleAdvertiser {
new( raw_gatt: *const btgatt_interface_t, internal_cxx: cxx::UniquePtr<ffi::BleAdvertiserIntf>, ) -> Self1455     pub(crate) fn new(
1456         raw_gatt: *const btgatt_interface_t,
1457         internal_cxx: cxx::UniquePtr<ffi::BleAdvertiserIntf>,
1458     ) -> Self {
1459         BleAdvertiser {
1460             _internal: RawBleAdvertiserWrapper {
1461                 _raw: unsafe { (*raw_gatt).advertiser as *const BleAdvertiserInterface },
1462             },
1463             internal_cxx,
1464         }
1465     }
1466 
register_advertiser(&mut self)1467     pub fn register_advertiser(&mut self) {
1468         mutcxxcall!(self, RegisterAdvertiser);
1469     }
1470 
unregister(&mut self, adv_id: u8)1471     pub fn unregister(&mut self, adv_id: u8) {
1472         mutcxxcall!(self, Unregister, adv_id);
1473     }
1474 
get_own_address(&mut self, adv_id: u8)1475     pub fn get_own_address(&mut self, adv_id: u8) {
1476         mutcxxcall!(self, GetOwnAddress, adv_id);
1477     }
1478 
set_parameters(&mut self, adv_id: u8, params: AdvertiseParameters)1479     pub fn set_parameters(&mut self, adv_id: u8, params: AdvertiseParameters) {
1480         mutcxxcall!(self, SetParameters, adv_id, params);
1481     }
set_data(&mut self, adv_id: u8, set_scan_rsp: bool, data: Vec<u8>)1482     pub fn set_data(&mut self, adv_id: u8, set_scan_rsp: bool, data: Vec<u8>) {
1483         mutcxxcall!(self, SetData, adv_id, set_scan_rsp, data);
1484     }
enable(&mut self, adv_id: u8, enable: bool, duration: u16, max_ext_adv_events: u8)1485     pub fn enable(&mut self, adv_id: u8, enable: bool, duration: u16, max_ext_adv_events: u8) {
1486         mutcxxcall!(self, Enable, adv_id, enable, duration, max_ext_adv_events);
1487     }
start_advertising( &mut self, adv_id: u8, params: AdvertiseParameters, advertise_data: Vec<u8>, scan_response_data: Vec<u8>, timeout_in_sec: i32, )1488     pub fn start_advertising(
1489         &mut self,
1490         adv_id: u8,
1491         params: AdvertiseParameters,
1492         advertise_data: Vec<u8>,
1493         scan_response_data: Vec<u8>,
1494         timeout_in_sec: i32,
1495     ) {
1496         mutcxxcall!(
1497             self,
1498             StartAdvertising,
1499             adv_id,
1500             params,
1501             advertise_data,
1502             scan_response_data,
1503             timeout_in_sec
1504         );
1505     }
start_advertising_set( &mut self, reg_id: i32, params: AdvertiseParameters, advertise_data: Vec<u8>, scan_response_data: Vec<u8>, periodic_params: PeriodicAdvertisingParameters, periodic_data: Vec<u8>, duration: u16, max_ext_adv_events: u8, )1506     pub fn start_advertising_set(
1507         &mut self,
1508         reg_id: i32,
1509         params: AdvertiseParameters,
1510         advertise_data: Vec<u8>,
1511         scan_response_data: Vec<u8>,
1512         periodic_params: PeriodicAdvertisingParameters,
1513         periodic_data: Vec<u8>,
1514         duration: u16,
1515         max_ext_adv_events: u8,
1516     ) {
1517         mutcxxcall!(
1518             self,
1519             StartAdvertisingSet,
1520             reg_id,
1521             params,
1522             advertise_data,
1523             scan_response_data,
1524             periodic_params,
1525             periodic_data,
1526             duration,
1527             max_ext_adv_events
1528         );
1529     }
set_periodic_advertising_parameters( &mut self, adv_id: u8, params: PeriodicAdvertisingParameters, )1530     pub fn set_periodic_advertising_parameters(
1531         &mut self,
1532         adv_id: u8,
1533         params: PeriodicAdvertisingParameters,
1534     ) {
1535         mutcxxcall!(self, SetPeriodicAdvertisingParameters, adv_id, params);
1536     }
set_periodic_advertising_data(&mut self, adv_id: u8, data: Vec<u8>)1537     pub fn set_periodic_advertising_data(&mut self, adv_id: u8, data: Vec<u8>) {
1538         mutcxxcall!(self, SetPeriodicAdvertisingData, adv_id, data);
1539     }
set_periodic_advertising_enable(&mut self, adv_id: u8, enable: bool)1540     pub fn set_periodic_advertising_enable(&mut self, adv_id: u8, enable: bool) {
1541         mutcxxcall!(self, SetPeriodicAdvertisingEnable, adv_id, enable);
1542     }
1543 }
1544 
1545 pub struct Gatt {
1546     internal: RawGattWrapper,
1547     is_init: bool,
1548 
1549     pub client: GattClient,
1550     pub server: GattServer,
1551     pub scanner: BleScanner,
1552     pub advertiser: BleAdvertiser,
1553 
1554     // Keep callback object in memory (underlying code doesn't make copy)
1555     callbacks: Option<Box<bindings::btgatt_callbacks_t>>,
1556     gatt_client_callbacks: Option<Box<bindings::btgatt_client_callbacks_t>>,
1557     gatt_server_callbacks: Option<Box<bindings::btgatt_server_callbacks_t>>,
1558     gatt_scanner_callbacks: Option<Box<bindings::btgatt_scanner_callbacks_t>>,
1559 }
1560 
1561 impl Gatt {
new(intf: &BluetoothInterface) -> Option<Gatt>1562     pub fn new(intf: &BluetoothInterface) -> Option<Gatt> {
1563         let r = intf.get_profile_interface(SupportedProfiles::Gatt);
1564 
1565         if r == std::ptr::null() {
1566             return None;
1567         }
1568 
1569         let gatt_client_intf = unsafe { ffi::GetGattClientProfile(r as *const u8) };
1570         let gatt_scanner_intf = unsafe { ffi::GetBleScannerIntf(r as *const u8) };
1571         let gatt_advertiser_intf = unsafe { ffi::GetBleAdvertiserIntf(r as *const u8) };
1572 
1573         Some(Gatt {
1574             internal: RawGattWrapper { raw: r as *const btgatt_interface_t },
1575             is_init: false,
1576             client: GattClient {
1577                 internal: RawGattClientWrapper {
1578                     raw: unsafe {
1579                         (*(r as *const btgatt_interface_t)).client
1580                             as *const btgatt_client_interface_t
1581                     },
1582                 },
1583                 internal_cxx: gatt_client_intf,
1584             },
1585             server: GattServer {
1586                 internal: RawGattServerWrapper {
1587                     raw: unsafe {
1588                         (*(r as *const btgatt_interface_t)).server
1589                             as *const btgatt_server_interface_t
1590                     },
1591                 },
1592             },
1593             scanner: BleScanner::new(r as *const btgatt_interface_t, gatt_scanner_intf),
1594             advertiser: BleAdvertiser::new(r as *const btgatt_interface_t, gatt_advertiser_intf),
1595             callbacks: None,
1596             gatt_client_callbacks: None,
1597             gatt_server_callbacks: None,
1598             gatt_scanner_callbacks: None,
1599         })
1600     }
1601 
is_initialized(&self) -> bool1602     pub fn is_initialized(&self) -> bool {
1603         self.is_init
1604     }
1605 
initialize( &mut self, gatt_client_callbacks_dispatcher: GattClientCallbacksDispatcher, gatt_server_callbacks_dispatcher: GattServerCallbacksDispatcher, gatt_scanner_callbacks_dispatcher: GattScannerCallbacksDispatcher, ) -> bool1606     pub fn initialize(
1607         &mut self,
1608         gatt_client_callbacks_dispatcher: GattClientCallbacksDispatcher,
1609         gatt_server_callbacks_dispatcher: GattServerCallbacksDispatcher,
1610         gatt_scanner_callbacks_dispatcher: GattScannerCallbacksDispatcher,
1611     ) -> bool {
1612         // Register dispatcher
1613         if get_dispatchers()
1614             .lock()
1615             .unwrap()
1616             .set::<GattClientCb>(Arc::new(Mutex::new(gatt_client_callbacks_dispatcher)))
1617         {
1618             panic!("Tried to set dispatcher for GattClientCallbacks but it already existed");
1619         }
1620 
1621         if get_dispatchers()
1622             .lock()
1623             .unwrap()
1624             .set::<GattServerCb>(Arc::new(Mutex::new(gatt_server_callbacks_dispatcher)))
1625         {
1626             panic!("Tried to set dispatcher for GattServerCallbacks but it already existed");
1627         }
1628 
1629         if get_dispatchers()
1630             .lock()
1631             .unwrap()
1632             .set::<GDScannerCb>(Arc::new(Mutex::new(gatt_scanner_callbacks_dispatcher)))
1633         {
1634             panic!("Tried to set dispatcher for GattScannerCallbacks but it already existed");
1635         }
1636 
1637         let mut gatt_client_callbacks = Box::new(btgatt_client_callbacks_t {
1638             register_client_cb: Some(gc_register_client_cb),
1639             open_cb: Some(gc_open_cb),
1640             close_cb: Some(gc_close_cb),
1641             search_complete_cb: Some(gc_search_complete_cb),
1642             register_for_notification_cb: Some(gc_register_for_notification_cb),
1643             notify_cb: Some(gc_notify_cb),
1644             read_characteristic_cb: Some(gc_read_characteristic_cb),
1645             write_characteristic_cb: Some(gc_write_characteristic_cb),
1646             read_descriptor_cb: Some(gc_read_descriptor_cb),
1647             write_descriptor_cb: Some(gc_write_descriptor_cb),
1648             execute_write_cb: Some(gc_execute_write_cb),
1649             read_remote_rssi_cb: Some(gc_read_remote_rssi_cb),
1650             configure_mtu_cb: Some(gc_configure_mtu_cb),
1651             congestion_cb: Some(gc_congestion_cb),
1652             get_gatt_db_cb: Some(gc_get_gatt_db_cb),
1653             phy_updated_cb: Some(gc_phy_updated_cb),
1654             conn_updated_cb: Some(gc_conn_updated_cb),
1655             service_changed_cb: Some(gc_service_changed_cb),
1656             // These callbacks are never used and will also be removed from btif.
1657             // TODO(b/200073464): Remove these.
1658             services_removed_cb: None,
1659             services_added_cb: None,
1660         });
1661 
1662         let mut gatt_server_callbacks = Box::new(btgatt_server_callbacks_t {
1663             register_server_cb: Some(gs_register_server_cb),
1664             connection_cb: Some(gs_connection_cb),
1665             service_added_cb: Some(gs_service_added_cb),
1666             service_stopped_cb: Some(gs_service_stopped_cb),
1667             service_deleted_cb: Some(gs_service_deleted_cb),
1668             request_read_characteristic_cb: Some(gs_request_read_characteristic_cb),
1669             request_read_descriptor_cb: Some(gs_request_read_descriptor_cb),
1670             request_write_characteristic_cb: Some(gs_request_write_characteristic_cb),
1671             request_write_descriptor_cb: Some(gs_request_write_descriptor_cb),
1672             request_exec_write_cb: Some(gs_request_exec_write_cb),
1673             response_confirmation_cb: Some(gs_response_confirmation_cb),
1674             indication_sent_cb: Some(gs_indication_sent_cb),
1675             congestion_cb: Some(gs_congestion_cb),
1676             mtu_changed_cb: Some(gs_mtu_changed_cb),
1677             phy_updated_cb: Some(gs_phy_updated_cb),
1678             conn_updated_cb: Some(gs_conn_updated_cb),
1679         });
1680 
1681         let mut gatt_scanner_callbacks = Box::new(btgatt_scanner_callbacks_t {
1682             scan_result_cb: None,
1683             batchscan_reports_cb: None,
1684             batchscan_threshold_cb: None,
1685             track_adv_event_cb: None,
1686         });
1687 
1688         let mut callbacks = Box::new(btgatt_callbacks_t {
1689             size: 4 * 8,
1690             client: &mut *gatt_client_callbacks,
1691             server: &mut *gatt_server_callbacks,
1692             scanner: &mut *gatt_scanner_callbacks,
1693         });
1694 
1695         let rawcb = &mut *callbacks;
1696 
1697         let init = ccall!(self, init, rawcb);
1698         self.is_init = init == 0;
1699         self.callbacks = Some(callbacks);
1700         self.gatt_client_callbacks = Some(gatt_client_callbacks);
1701         self.gatt_server_callbacks = Some(gatt_server_callbacks);
1702         self.gatt_scanner_callbacks = Some(gatt_scanner_callbacks);
1703 
1704         // Register callbacks for gatt scanner and advertiser
1705         mutcxxcall!(self.scanner, RegisterCallbacks);
1706         mutcxxcall!(self.advertiser, RegisterCallbacks);
1707 
1708         return self.is_init;
1709     }
1710 }
1711