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