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