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