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