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