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