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