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