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