1 //! Anything related to the GATT API (IBluetoothGatt). 2 3 use btif_macros::{btif_callback, btif_callbacks_dispatcher}; 4 5 use bt_topshim::bindings::root::bluetooth::Uuid; 6 use bt_topshim::btif::{BluetoothInterface, BtStatus, BtTransport, RawAddress, Uuid128Bit}; 7 use bt_topshim::profiles::gatt::{ 8 ffi::RustAdvertisingTrackInfo, AdvertisingStatus, BtGattDbElement, BtGattNotifyParams, 9 BtGattReadParams, BtGattResponse, BtGattValue, Gatt, GattAdvCallbacks, 10 GattAdvCallbacksDispatcher, GattAdvInbandCallbacksDispatcher, GattClientCallbacks, 11 GattClientCallbacksDispatcher, GattScannerCallbacks, GattScannerCallbacksDispatcher, 12 GattScannerInbandCallbacks, GattScannerInbandCallbacksDispatcher, GattServerCallbacks, 13 GattServerCallbacksDispatcher, GattStatus, LePhy, MsftAdvMonitor, MsftAdvMonitorPattern, 14 }; 15 use bt_topshim::sysprop; 16 use bt_topshim::topstack; 17 use bt_utils::adv_parser; 18 use bt_utils::array_utils; 19 20 use crate::async_helper::{AsyncHelper, CallbackSender}; 21 use crate::bluetooth::{Bluetooth, IBluetooth}; 22 use crate::bluetooth_adv::{ 23 AdvertiseData, Advertisers, AdvertisingSetInfo, AdvertisingSetParameters, 24 IAdvertisingSetCallback, PeriodicAdvertisingParameters, INVALID_REG_ID, 25 }; 26 use crate::callbacks::Callbacks; 27 use crate::uuid::UuidHelper; 28 use crate::{Message, RPCProxy, SuspendMode}; 29 use log::{debug, warn}; 30 use num_derive::{FromPrimitive, ToPrimitive}; 31 use num_traits::cast::{FromPrimitive, ToPrimitive}; 32 use num_traits::clamp; 33 use rand::rngs::SmallRng; 34 use rand::{RngCore, SeedableRng}; 35 use std::collections::{HashMap, HashSet}; 36 use std::convert::TryInto; 37 use std::sync::{Arc, Mutex, MutexGuard}; 38 use tokio::sync::mpsc::Sender; 39 40 struct Client { 41 id: Option<i32>, 42 cbid: u32, 43 uuid: Uuid128Bit, 44 is_congested: bool, 45 46 // Queued on_characteristic_write callback. 47 congestion_queue: Vec<(String, GattStatus, i32)>, 48 } 49 50 struct Connection { 51 conn_id: i32, 52 address: String, 53 54 // Connections are made to either a client or server 55 client_id: i32, 56 server_id: i32, 57 } 58 59 struct ContextMap { 60 // TODO(b/196635530): Consider using `multimap` for a more efficient implementation of get by 61 // multiple keys. 62 callbacks: Callbacks<dyn IBluetoothGattCallback + Send>, 63 clients: Vec<Client>, 64 connections: Vec<Connection>, 65 } 66 67 type GattClientCallback = Box<dyn IBluetoothGattCallback + Send>; 68 69 impl ContextMap { new(tx: Sender<Message>) -> ContextMap70 fn new(tx: Sender<Message>) -> ContextMap { 71 ContextMap { 72 callbacks: Callbacks::new(tx, Message::GattClientCallbackDisconnected), 73 clients: vec![], 74 connections: vec![], 75 } 76 } 77 get_by_uuid(&self, uuid: &Uuid128Bit) -> Option<&Client>78 fn get_by_uuid(&self, uuid: &Uuid128Bit) -> Option<&Client> { 79 self.clients.iter().find(|client| client.uuid == *uuid) 80 } 81 get_by_client_id(&self, client_id: i32) -> Option<&Client>82 fn get_by_client_id(&self, client_id: i32) -> Option<&Client> { 83 self.clients.iter().find(|client| client.id.is_some() && client.id.unwrap() == client_id) 84 } 85 get_by_client_id_mut(&mut self, client_id: i32) -> Option<&mut Client>86 fn get_by_client_id_mut(&mut self, client_id: i32) -> Option<&mut Client> { 87 self.clients 88 .iter_mut() 89 .find(|client| client.id.is_some() && client.id.unwrap() == client_id) 90 } 91 get_by_callback_id(&self, callback_id: u32) -> Option<&Client>92 fn get_by_callback_id(&self, callback_id: u32) -> Option<&Client> { 93 self.clients.iter().find(|client| client.cbid == callback_id) 94 } 95 get_address_by_conn_id(&self, conn_id: i32) -> Option<String>96 fn get_address_by_conn_id(&self, conn_id: i32) -> Option<String> { 97 match self.connections.iter().find(|conn| conn.conn_id == conn_id) { 98 None => None, 99 Some(conn) => Some(conn.address.clone()), 100 } 101 } 102 get_client_by_conn_id(&self, conn_id: i32) -> Option<&Client>103 fn get_client_by_conn_id(&self, conn_id: i32) -> Option<&Client> { 104 match self.connections.iter().find(|conn| conn.conn_id == conn_id) { 105 None => None, 106 Some(conn) => self.get_by_client_id(conn.client_id), 107 } 108 } 109 get_client_by_conn_id_mut(&mut self, conn_id: i32) -> Option<&mut Client>110 fn get_client_by_conn_id_mut(&mut self, conn_id: i32) -> Option<&mut Client> { 111 let client_id = match self.connections.iter().find(|conn| conn.conn_id == conn_id) { 112 None => return None, 113 Some(conn) => conn.client_id, 114 }; 115 116 self.get_by_client_id_mut(client_id) 117 } 118 add(&mut self, uuid: &Uuid128Bit, callback: GattClientCallback)119 fn add(&mut self, uuid: &Uuid128Bit, callback: GattClientCallback) { 120 if self.get_by_uuid(uuid).is_some() { 121 return; 122 } 123 124 let cbid = self.callbacks.add_callback(callback); 125 126 self.clients.push(Client { 127 id: None, 128 cbid, 129 uuid: uuid.clone(), 130 is_congested: false, 131 congestion_queue: vec![], 132 }); 133 } 134 remove(&mut self, id: i32)135 fn remove(&mut self, id: i32) { 136 // Remove any callbacks 137 if let Some(c) = self.get_by_client_id(id) { 138 let cbid = c.cbid; 139 self.remove_callback(cbid); 140 } 141 142 self.clients.retain(|client| !(client.id.is_some() && client.id.unwrap() == id)); 143 } 144 remove_callback(&mut self, callback_id: u32)145 fn remove_callback(&mut self, callback_id: u32) { 146 self.callbacks.remove_callback(callback_id); 147 } 148 set_client_id(&mut self, uuid: &Uuid128Bit, id: i32)149 fn set_client_id(&mut self, uuid: &Uuid128Bit, id: i32) { 150 let client = self.clients.iter_mut().find(|client| client.uuid == *uuid); 151 if client.is_none() { 152 return; 153 } 154 155 client.unwrap().id = Some(id); 156 } 157 add_connection(&mut self, client_id: i32, conn_id: i32, address: &String)158 fn add_connection(&mut self, client_id: i32, conn_id: i32, address: &String) { 159 if self.get_conn_id_from_address(client_id, address).is_some() { 160 return; 161 } 162 163 self.connections.push(Connection { 164 conn_id, 165 address: address.clone(), 166 client_id, 167 server_id: 0, 168 }); 169 } 170 remove_connection(&mut self, _client_id: i32, conn_id: i32)171 fn remove_connection(&mut self, _client_id: i32, conn_id: i32) { 172 self.connections.retain(|conn| conn.conn_id != conn_id); 173 } 174 get_conn_id_from_address(&self, client_id: i32, address: &String) -> Option<i32>175 fn get_conn_id_from_address(&self, client_id: i32, address: &String) -> Option<i32> { 176 match self 177 .connections 178 .iter() 179 .find(|conn| conn.client_id == client_id && conn.address == *address) 180 { 181 None => None, 182 Some(conn) => Some(conn.conn_id), 183 } 184 } 185 get_callback_from_callback_id( &mut self, callback_id: u32, ) -> Option<&mut GattClientCallback>186 fn get_callback_from_callback_id( 187 &mut self, 188 callback_id: u32, 189 ) -> Option<&mut GattClientCallback> { 190 self.callbacks.get_by_id_mut(callback_id) 191 } 192 } 193 194 struct Server { 195 id: Option<i32>, 196 cbid: u32, 197 uuid: Uuid128Bit, 198 services: Vec<BluetoothGattService>, 199 is_congested: bool, 200 201 // Queued on_notification_sent callback. 202 congestion_queue: Vec<(String, GattStatus)>, 203 } 204 205 struct Request { 206 id: i32, 207 handle: i32, 208 } 209 210 struct ServerContextMap { 211 // TODO(b/196635530): Consider using `multimap` for a more efficient implementation of get by 212 // multiple keys. 213 callbacks: Callbacks<dyn IBluetoothGattServerCallback + Send>, 214 servers: Vec<Server>, 215 connections: Vec<Connection>, 216 requests: Vec<Request>, 217 } 218 219 type GattServerCallback = Box<dyn IBluetoothGattServerCallback + Send>; 220 221 impl ServerContextMap { new(tx: Sender<Message>) -> ServerContextMap222 fn new(tx: Sender<Message>) -> ServerContextMap { 223 ServerContextMap { 224 callbacks: Callbacks::new(tx, Message::GattServerCallbackDisconnected), 225 servers: vec![], 226 connections: vec![], 227 requests: vec![], 228 } 229 } 230 get_by_uuid(&self, uuid: &Uuid128Bit) -> Option<&Server>231 fn get_by_uuid(&self, uuid: &Uuid128Bit) -> Option<&Server> { 232 self.servers.iter().find(|server| server.uuid == *uuid) 233 } 234 get_by_server_id(&self, server_id: i32) -> Option<&Server>235 fn get_by_server_id(&self, server_id: i32) -> Option<&Server> { 236 self.servers.iter().find(|server| server.id.map_or(false, |id| id == server_id)) 237 } 238 get_mut_by_server_id(&mut self, server_id: i32) -> Option<&mut Server>239 fn get_mut_by_server_id(&mut self, server_id: i32) -> Option<&mut Server> { 240 self.servers.iter_mut().find(|server| server.id.map_or(false, |id| id == server_id)) 241 } 242 get_by_callback_id(&self, callback_id: u32) -> Option<&Server>243 fn get_by_callback_id(&self, callback_id: u32) -> Option<&Server> { 244 self.servers.iter().find(|server| server.cbid == callback_id) 245 } 246 get_by_conn_id(&self, conn_id: i32) -> Option<&Server>247 fn get_by_conn_id(&self, conn_id: i32) -> Option<&Server> { 248 self.connections 249 .iter() 250 .find(|conn| conn.conn_id == conn_id) 251 .and_then(|conn| self.get_by_server_id(conn.server_id)) 252 } 253 get_mut_by_conn_id(&mut self, conn_id: i32) -> Option<&mut Server>254 fn get_mut_by_conn_id(&mut self, conn_id: i32) -> Option<&mut Server> { 255 self.connections 256 .iter() 257 .find_map(|conn| (conn.conn_id == conn_id).then(|| conn.server_id.clone())) 258 .and_then(move |server_id| self.get_mut_by_server_id(server_id)) 259 } 260 add(&mut self, uuid: &Uuid128Bit, callback: GattServerCallback)261 fn add(&mut self, uuid: &Uuid128Bit, callback: GattServerCallback) { 262 if self.get_by_uuid(uuid).is_some() { 263 return; 264 } 265 266 let cbid = self.callbacks.add_callback(callback); 267 268 self.servers.push(Server { 269 id: None, 270 cbid, 271 uuid: uuid.clone(), 272 services: vec![], 273 is_congested: false, 274 congestion_queue: vec![], 275 }); 276 } 277 remove(&mut self, id: i32)278 fn remove(&mut self, id: i32) { 279 // Remove any callbacks 280 if let Some(cbid) = self.get_by_server_id(id).map(|server| server.cbid) { 281 self.remove_callback(cbid); 282 } 283 284 self.servers.retain(|server| !(server.id.is_some() && server.id.unwrap() == id)); 285 } 286 remove_callback(&mut self, callback_id: u32)287 fn remove_callback(&mut self, callback_id: u32) { 288 self.callbacks.remove_callback(callback_id); 289 } 290 set_server_id(&mut self, uuid: &Uuid128Bit, id: i32)291 fn set_server_id(&mut self, uuid: &Uuid128Bit, id: i32) { 292 let server = self.servers.iter_mut().find(|server| server.uuid == *uuid); 293 if let Some(s) = server { 294 s.id = Some(id); 295 } 296 } 297 get_callback_from_callback_id( &mut self, callback_id: u32, ) -> Option<&mut GattServerCallback>298 fn get_callback_from_callback_id( 299 &mut self, 300 callback_id: u32, 301 ) -> Option<&mut GattServerCallback> { 302 self.callbacks.get_by_id_mut(callback_id) 303 } 304 add_connection(&mut self, server_id: i32, conn_id: i32, address: &String)305 fn add_connection(&mut self, server_id: i32, conn_id: i32, address: &String) { 306 if self.get_conn_id_from_address(server_id, address).is_some() { 307 return; 308 } 309 310 self.connections.push(Connection { 311 conn_id, 312 address: address.clone(), 313 client_id: 0, 314 server_id, 315 }); 316 } 317 remove_connection(&mut self, conn_id: i32)318 fn remove_connection(&mut self, conn_id: i32) { 319 self.connections.retain(|conn| conn.conn_id != conn_id); 320 } 321 get_conn_id_from_address(&self, server_id: i32, address: &String) -> Option<i32>322 fn get_conn_id_from_address(&self, server_id: i32, address: &String) -> Option<i32> { 323 return self 324 .connections 325 .iter() 326 .find(|conn| conn.server_id == server_id && conn.address == *address) 327 .map(|conn| conn.conn_id); 328 } 329 get_address_from_conn_id(&self, conn_id: i32) -> Option<String>330 fn get_address_from_conn_id(&self, conn_id: i32) -> Option<String> { 331 self.connections 332 .iter() 333 .find_map(|conn| (conn.conn_id == conn_id).then(|| conn.address.clone())) 334 } 335 add_service(&mut self, server_id: i32, service: BluetoothGattService)336 fn add_service(&mut self, server_id: i32, service: BluetoothGattService) { 337 if let Some(s) = self.get_mut_by_server_id(server_id) { 338 s.services.push(service) 339 } 340 } 341 delete_service(&mut self, server_id: i32, handle: i32)342 fn delete_service(&mut self, server_id: i32, handle: i32) { 343 self.get_mut_by_server_id(server_id) 344 .map(|s: &mut Server| s.services.retain(|service| service.instance_id != handle)); 345 } 346 add_request(&mut self, request_id: i32, handle: i32)347 fn add_request(&mut self, request_id: i32, handle: i32) { 348 self.requests.push(Request { id: request_id, handle }); 349 } 350 _delete_request(&mut self, request_id: i32)351 fn _delete_request(&mut self, request_id: i32) { 352 self.requests.retain(|request| request.id != request_id); 353 } 354 get_request_handle_from_id(&self, request_id: i32) -> Option<i32>355 fn get_request_handle_from_id(&self, request_id: i32) -> Option<i32> { 356 self.requests.iter().find_map(|request| (request.id == request_id).then(|| request.handle)) 357 } 358 } 359 360 /// Defines the GATT API. 361 // TODO(242083290): Split out interfaces. 362 pub trait IBluetoothGatt { 363 // Scanning 364 365 /// Returns whether LE Scan can be performed by hardware offload defined by 366 /// [MSFT HCI Extension](https://learn.microsoft.com/en-us/windows-hardware/drivers/bluetooth/microsoft-defined-bluetooth-hci-commands-and-events). is_msft_supported(&self) -> bool367 fn is_msft_supported(&self) -> bool; 368 369 /// Registers an LE scanner callback. 370 /// 371 /// Returns the callback id. register_scanner_callback(&mut self, callback: Box<dyn IScannerCallback + Send>) -> u32372 fn register_scanner_callback(&mut self, callback: Box<dyn IScannerCallback + Send>) -> u32; 373 374 /// Unregisters an LE scanner callback identified by the given id. unregister_scanner_callback(&mut self, callback_id: u32) -> bool375 fn unregister_scanner_callback(&mut self, callback_id: u32) -> bool; 376 377 /// Registers LE scanner. 378 /// 379 /// `callback_id`: The callback to receive updates about the scanner state. 380 /// Returns the UUID of the registered scanner. register_scanner(&mut self, callback_id: u32) -> Uuid128Bit381 fn register_scanner(&mut self, callback_id: u32) -> Uuid128Bit; 382 383 /// Unregisters an LE scanner identified by the given scanner id. unregister_scanner(&mut self, scanner_id: u8) -> bool384 fn unregister_scanner(&mut self, scanner_id: u8) -> bool; 385 386 /// Activate scan of the given scanner id. start_scan( &mut self, scanner_id: u8, settings: ScanSettings, filter: Option<ScanFilter>, ) -> BtStatus387 fn start_scan( 388 &mut self, 389 scanner_id: u8, 390 settings: ScanSettings, 391 filter: Option<ScanFilter>, 392 ) -> BtStatus; 393 394 /// Deactivate scan of the given scanner id. stop_scan(&mut self, scanner_id: u8) -> BtStatus395 fn stop_scan(&mut self, scanner_id: u8) -> BtStatus; 396 397 /// Returns the current suspend mode. get_scan_suspend_mode(&self) -> SuspendMode398 fn get_scan_suspend_mode(&self) -> SuspendMode; 399 400 // Advertising 401 402 /// Registers callback for BLE advertising. register_advertiser_callback( &mut self, callback: Box<dyn IAdvertisingSetCallback + Send>, ) -> u32403 fn register_advertiser_callback( 404 &mut self, 405 callback: Box<dyn IAdvertisingSetCallback + Send>, 406 ) -> u32; 407 408 /// Unregisters callback for BLE advertising. unregister_advertiser_callback(&mut self, callback_id: u32)409 fn unregister_advertiser_callback(&mut self, callback_id: u32); 410 411 /// Creates a new BLE advertising set and start advertising. 412 /// 413 /// Returns the reg_id for the advertising set, which is used in the callback 414 /// `on_advertising_set_started` to identify the advertising set started. 415 /// 416 /// * `parameters` - Advertising set parameters. 417 /// * `advertise_data` - Advertisement data to be broadcasted. 418 /// * `scan_response` - Scan response. 419 /// * `periodic_parameters` - Periodic advertising parameters. If None, periodic advertising 420 /// will not be started. 421 /// * `periodic_data` - Periodic advertising data. 422 /// * `duration` - Advertising duration, in 10 ms unit. Valid range is from 1 (10 ms) to 423 /// 65535 (655.35 sec). 0 means no advertising timeout. 424 /// * `max_ext_adv_events` - Maximum number of extended advertising events the controller 425 /// shall attempt to send before terminating the extended advertising, even if the 426 /// duration has not expired. Valid range is from 1 to 255. 0 means event count limitation. 427 /// * `callback_id` - Identifies callback registered in register_advertiser_callback. start_advertising_set( &mut self, parameters: AdvertisingSetParameters, advertise_data: AdvertiseData, scan_response: Option<AdvertiseData>, periodic_parameters: Option<PeriodicAdvertisingParameters>, periodic_data: Option<AdvertiseData>, duration: i32, max_ext_adv_events: i32, callback_id: u32, ) -> i32428 fn start_advertising_set( 429 &mut self, 430 parameters: AdvertisingSetParameters, 431 advertise_data: AdvertiseData, 432 scan_response: Option<AdvertiseData>, 433 periodic_parameters: Option<PeriodicAdvertisingParameters>, 434 periodic_data: Option<AdvertiseData>, 435 duration: i32, 436 max_ext_adv_events: i32, 437 callback_id: u32, 438 ) -> i32; 439 440 /// Disposes a BLE advertising set. stop_advertising_set(&mut self, advertiser_id: i32)441 fn stop_advertising_set(&mut self, advertiser_id: i32); 442 443 /// Queries address associated with the advertising set. get_own_address(&mut self, advertiser_id: i32)444 fn get_own_address(&mut self, advertiser_id: i32); 445 446 /// Enables or disables an advertising set. enable_advertising_set( &mut self, advertiser_id: i32, enable: bool, duration: i32, max_ext_adv_events: i32, )447 fn enable_advertising_set( 448 &mut self, 449 advertiser_id: i32, 450 enable: bool, 451 duration: i32, 452 max_ext_adv_events: i32, 453 ); 454 455 /// Updates advertisement data of the advertising set. set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)456 fn set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData); 457 458 /// Set the advertisement data of the advertising set. set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>)459 fn set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>); 460 461 /// Updates scan response of the advertising set. set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData)462 fn set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData); 463 464 /// Updates advertising parameters of the advertising set. 465 /// 466 /// It must be called when advertising is not active. set_advertising_parameters( &mut self, advertiser_id: i32, parameters: AdvertisingSetParameters, )467 fn set_advertising_parameters( 468 &mut self, 469 advertiser_id: i32, 470 parameters: AdvertisingSetParameters, 471 ); 472 473 /// Updates periodic advertising parameters. set_periodic_advertising_parameters( &mut self, advertiser_id: i32, parameters: PeriodicAdvertisingParameters, )474 fn set_periodic_advertising_parameters( 475 &mut self, 476 advertiser_id: i32, 477 parameters: PeriodicAdvertisingParameters, 478 ); 479 480 /// Updates periodic advertisement data. 481 /// 482 /// It must be called after `set_periodic_advertising_parameters`, or after 483 /// advertising was started with periodic advertising data set. set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)484 fn set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData); 485 486 /// Enables or disables periodic advertising. set_periodic_advertising_enable( &mut self, advertiser_id: i32, enable: bool, include_adi: bool, )487 fn set_periodic_advertising_enable( 488 &mut self, 489 advertiser_id: i32, 490 enable: bool, 491 include_adi: bool, 492 ); 493 494 // GATT Client 495 496 /// Registers a GATT Client. register_client( &mut self, app_uuid: String, callback: Box<dyn IBluetoothGattCallback + Send>, eatt_support: bool, )497 fn register_client( 498 &mut self, 499 app_uuid: String, 500 callback: Box<dyn IBluetoothGattCallback + Send>, 501 eatt_support: bool, 502 ); 503 504 /// Unregisters a GATT Client. unregister_client(&mut self, client_id: i32)505 fn unregister_client(&mut self, client_id: i32); 506 507 /// Initiates a GATT connection to a peer device. client_connect( &self, client_id: i32, addr: String, is_direct: bool, transport: BtTransport, opportunistic: bool, phy: LePhy, )508 fn client_connect( 509 &self, 510 client_id: i32, 511 addr: String, 512 is_direct: bool, 513 transport: BtTransport, 514 opportunistic: bool, 515 phy: LePhy, 516 ); 517 518 /// Disconnects a GATT connection. client_disconnect(&self, client_id: i32, addr: String)519 fn client_disconnect(&self, client_id: i32, addr: String); 520 521 /// Clears the attribute cache of a device. refresh_device(&self, client_id: i32, addr: String)522 fn refresh_device(&self, client_id: i32, addr: String); 523 524 /// Enumerates all GATT services on a connected device. discover_services(&self, client_id: i32, addr: String)525 fn discover_services(&self, client_id: i32, addr: String); 526 527 /// Discovers all GATT services on a connected device. Only used by PTS. btif_gattc_discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String)528 fn btif_gattc_discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String); 529 530 /// Search a GATT service on a connected device based on a UUID. discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String)531 fn discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String); 532 533 /// Reads a characteristic on a remote device. read_characteristic(&self, client_id: i32, addr: String, handle: i32, auth_req: i32)534 fn read_characteristic(&self, client_id: i32, addr: String, handle: i32, auth_req: i32); 535 536 /// Reads a characteristic on a remote device. read_using_characteristic_uuid( &self, client_id: i32, addr: String, uuid: String, start_handle: i32, end_handle: i32, auth_req: i32, )537 fn read_using_characteristic_uuid( 538 &self, 539 client_id: i32, 540 addr: String, 541 uuid: String, 542 start_handle: i32, 543 end_handle: i32, 544 auth_req: i32, 545 ); 546 547 /// Writes a remote characteristic. write_characteristic( &self, client_id: i32, addr: String, handle: i32, write_type: GattWriteType, auth_req: i32, value: Vec<u8>, ) -> GattWriteRequestStatus548 fn write_characteristic( 549 &self, 550 client_id: i32, 551 addr: String, 552 handle: i32, 553 write_type: GattWriteType, 554 auth_req: i32, 555 value: Vec<u8>, 556 ) -> GattWriteRequestStatus; 557 558 /// Reads the descriptor for a given characteristic. read_descriptor(&self, client_id: i32, addr: String, handle: i32, auth_req: i32)559 fn read_descriptor(&self, client_id: i32, addr: String, handle: i32, auth_req: i32); 560 561 /// Writes a remote descriptor for a given characteristic. write_descriptor( &self, client_id: i32, addr: String, handle: i32, auth_req: i32, value: Vec<u8>, )562 fn write_descriptor( 563 &self, 564 client_id: i32, 565 addr: String, 566 handle: i32, 567 auth_req: i32, 568 value: Vec<u8>, 569 ); 570 571 /// Registers to receive notifications or indications for a given characteristic. register_for_notification(&self, client_id: i32, addr: String, handle: i32, enable: bool)572 fn register_for_notification(&self, client_id: i32, addr: String, handle: i32, enable: bool); 573 574 /// Begins reliable write. begin_reliable_write(&mut self, client_id: i32, addr: String)575 fn begin_reliable_write(&mut self, client_id: i32, addr: String); 576 577 /// Ends reliable write. end_reliable_write(&mut self, client_id: i32, addr: String, execute: bool)578 fn end_reliable_write(&mut self, client_id: i32, addr: String, execute: bool); 579 580 /// Requests RSSI for a given remote device. read_remote_rssi(&self, client_id: i32, addr: String)581 fn read_remote_rssi(&self, client_id: i32, addr: String); 582 583 /// Configures the MTU of a given connection. configure_mtu(&self, client_id: i32, addr: String, mtu: i32)584 fn configure_mtu(&self, client_id: i32, addr: String, mtu: i32); 585 586 /// Requests a connection parameter update. connection_parameter_update( &self, client_id: i32, addr: String, min_interval: i32, max_interval: i32, latency: i32, timeout: i32, min_ce_len: u16, max_ce_len: u16, )587 fn connection_parameter_update( 588 &self, 589 client_id: i32, 590 addr: String, 591 min_interval: i32, 592 max_interval: i32, 593 latency: i32, 594 timeout: i32, 595 min_ce_len: u16, 596 max_ce_len: u16, 597 ); 598 599 /// Sets preferred PHY. client_set_preferred_phy( &self, client_id: i32, addr: String, tx_phy: LePhy, rx_phy: LePhy, phy_options: i32, )600 fn client_set_preferred_phy( 601 &self, 602 client_id: i32, 603 addr: String, 604 tx_phy: LePhy, 605 rx_phy: LePhy, 606 phy_options: i32, 607 ); 608 609 /// Reads the PHY used by a peer. client_read_phy(&mut self, client_id: i32, addr: String)610 fn client_read_phy(&mut self, client_id: i32, addr: String); 611 612 // GATT Server 613 614 /// Registers a GATT Server. register_server( &mut self, app_uuid: String, callback: Box<dyn IBluetoothGattServerCallback + Send>, eatt_support: bool, )615 fn register_server( 616 &mut self, 617 app_uuid: String, 618 callback: Box<dyn IBluetoothGattServerCallback + Send>, 619 eatt_support: bool, 620 ); 621 622 /// Unregisters a GATT Server. unregister_server(&mut self, server_id: i32)623 fn unregister_server(&mut self, server_id: i32); 624 625 /// Initiates a GATT connection to the server. server_connect( &self, server_id: i32, addr: String, is_direct: bool, transport: BtTransport, ) -> bool626 fn server_connect( 627 &self, 628 server_id: i32, 629 addr: String, 630 is_direct: bool, 631 transport: BtTransport, 632 ) -> bool; 633 634 /// Disconnects the server GATT connection. server_disconnect(&self, server_id: i32, addr: String) -> bool635 fn server_disconnect(&self, server_id: i32, addr: String) -> bool; 636 637 /// Adds a service to the GATT server. add_service(&self, server_id: i32, service: BluetoothGattService)638 fn add_service(&self, server_id: i32, service: BluetoothGattService); 639 640 /// Removes a service from the GATT server. remove_service(&self, server_id: i32, handle: i32)641 fn remove_service(&self, server_id: i32, handle: i32); 642 643 /// Clears all services from the GATT server. clear_services(&self, server_id: i32)644 fn clear_services(&self, server_id: i32); 645 646 /// Sends a response to a read/write operation. send_response( &self, server_id: i32, addr: String, request_id: i32, status: GattStatus, offset: i32, value: Vec<u8>, ) -> bool647 fn send_response( 648 &self, 649 server_id: i32, 650 addr: String, 651 request_id: i32, 652 status: GattStatus, 653 offset: i32, 654 value: Vec<u8>, 655 ) -> bool; 656 657 /// Sends a notification to a remote device. send_notification( &self, server_id: i32, addr: String, handle: i32, confirm: bool, value: Vec<u8>, ) -> bool658 fn send_notification( 659 &self, 660 server_id: i32, 661 addr: String, 662 handle: i32, 663 confirm: bool, 664 value: Vec<u8>, 665 ) -> bool; 666 667 /// Sets preferred PHY. server_set_preferred_phy( &self, server_id: i32, addr: String, tx_phy: LePhy, rx_phy: LePhy, phy_options: i32, )668 fn server_set_preferred_phy( 669 &self, 670 server_id: i32, 671 addr: String, 672 tx_phy: LePhy, 673 rx_phy: LePhy, 674 phy_options: i32, 675 ); 676 677 /// Reads the PHY used by a peer. server_read_phy(&self, server_id: i32, addr: String)678 fn server_read_phy(&self, server_id: i32, addr: String); 679 } 680 681 #[derive(Debug, Default, Clone)] 682 /// Represents a GATT Descriptor. 683 pub struct BluetoothGattDescriptor { 684 pub uuid: Uuid128Bit, 685 pub instance_id: i32, 686 pub permissions: i32, 687 } 688 689 impl BluetoothGattDescriptor { new( uuid: Uuid128Bit, instance_id: i32, permissions: i32, ) -> BluetoothGattDescriptor690 pub(crate) fn new( 691 uuid: Uuid128Bit, 692 instance_id: i32, 693 permissions: i32, 694 ) -> BluetoothGattDescriptor { 695 BluetoothGattDescriptor { uuid, instance_id, permissions } 696 } 697 } 698 699 #[derive(Debug, Default, Clone)] 700 /// Represents a GATT Characteristic. 701 pub struct BluetoothGattCharacteristic { 702 pub uuid: Uuid128Bit, 703 pub instance_id: i32, 704 pub properties: i32, 705 pub permissions: i32, 706 pub key_size: i32, 707 pub write_type: GattWriteType, 708 pub descriptors: Vec<BluetoothGattDescriptor>, 709 } 710 711 impl BluetoothGattCharacteristic { 712 // Properties are u8 but i32 in these apis. 713 pub const PROPERTY_BROADCAST: i32 = 1 << 0; 714 pub const PROPERTY_READ: i32 = 1 << 1; 715 pub const PROPERTY_WRITE_NO_RESPONSE: i32 = 1 << 2; 716 pub const PROPERTY_WRITE: i32 = 1 << 3; 717 pub const PROPERTY_NOTIFY: i32 = 1 << 4; 718 pub const PROPERTY_INDICATE: i32 = 1 << 5; 719 pub const PROPERTY_SIGNED_WRITE: i32 = 1 << 6; 720 pub const PROPERTY_EXTENDED_PROPS: i32 = 1 << 7; 721 722 // Permissions are u16 but i32 in these apis. 723 pub const PERMISSION_READ: i32 = 1 << 0; 724 pub const PERMISSION_READ_ENCRYPTED: i32 = 1 << 1; 725 pub const PERMISSION_READ_ENCRYPED_MITM: i32 = 1 << 2; 726 pub const PERMISSION_WRITE: i32 = 1 << 4; 727 pub const PERMISSION_WRITE_ENCRYPTED: i32 = 1 << 5; 728 pub const PERMISSION_WRITE_ENCRYPTED_MITM: i32 = 1 << 6; 729 pub const PERMISSION_WRITE_SIGNED: i32 = 1 << 7; 730 pub const PERMISSION_WRITE_SIGNED_MITM: i32 = 1 << 8; 731 new( uuid: Uuid128Bit, instance_id: i32, properties: i32, permissions: i32, ) -> BluetoothGattCharacteristic732 pub(crate) fn new( 733 uuid: Uuid128Bit, 734 instance_id: i32, 735 properties: i32, 736 permissions: i32, 737 ) -> BluetoothGattCharacteristic { 738 BluetoothGattCharacteristic { 739 uuid, 740 instance_id, 741 properties, 742 permissions, 743 write_type: if properties & BluetoothGattCharacteristic::PROPERTY_WRITE_NO_RESPONSE != 0 744 { 745 GattWriteType::WriteNoRsp 746 } else { 747 GattWriteType::Write 748 }, 749 key_size: 16, 750 descriptors: vec![], 751 } 752 } 753 } 754 755 #[derive(Debug, Default, Clone)] 756 /// Represents a GATT Service. 757 pub struct BluetoothGattService { 758 pub uuid: Uuid128Bit, 759 pub instance_id: i32, 760 pub service_type: i32, 761 pub characteristics: Vec<BluetoothGattCharacteristic>, 762 pub included_services: Vec<BluetoothGattService>, 763 } 764 765 impl BluetoothGattService { new( uuid: Uuid128Bit, instance_id: i32, service_type: i32, ) -> BluetoothGattService766 pub(crate) fn new( 767 uuid: Uuid128Bit, 768 instance_id: i32, 769 service_type: i32, 770 ) -> BluetoothGattService { 771 BluetoothGattService { 772 uuid, 773 instance_id, 774 service_type, 775 characteristics: vec![], 776 included_services: vec![], 777 } 778 } 779 from_db(elements: Vec<BtGattDbElement>) -> Vec<BluetoothGattService>780 fn from_db(elements: Vec<BtGattDbElement>) -> Vec<BluetoothGattService> { 781 let mut db_out: Vec<BluetoothGattService> = vec![]; 782 783 for elem in elements { 784 match GattDbElementType::from_u32(elem.type_).unwrap() { 785 GattDbElementType::PrimaryService | GattDbElementType::SecondaryService => { 786 db_out.push(BluetoothGattService::new( 787 elem.uuid.uu, 788 elem.attribute_handle as i32, 789 elem.type_ as i32, 790 )); 791 // TODO(b/200065274): Mark restricted services. 792 } 793 794 GattDbElementType::Characteristic => { 795 match db_out.last_mut() { 796 Some(s) => s.characteristics.push(BluetoothGattCharacteristic::new( 797 elem.uuid.uu, 798 elem.attribute_handle as i32, 799 elem.properties as i32, 800 0, 801 )), 802 None => { 803 // TODO(b/193685325): Log error. 804 } 805 } 806 // TODO(b/200065274): Mark restricted characteristics. 807 } 808 809 GattDbElementType::Descriptor => { 810 match db_out.last_mut() { 811 Some(s) => match s.characteristics.last_mut() { 812 Some(c) => c.descriptors.push(BluetoothGattDescriptor::new( 813 elem.uuid.uu, 814 elem.attribute_handle as i32, 815 0, 816 )), 817 None => { 818 // TODO(b/193685325): Log error. 819 } 820 }, 821 None => { 822 // TODO(b/193685325): Log error. 823 } 824 } 825 // TODO(b/200065274): Mark restricted descriptors. 826 } 827 828 GattDbElementType::IncludedService => { 829 match db_out.last_mut() { 830 Some(s) => { 831 s.included_services.push(BluetoothGattService::new( 832 elem.uuid.uu, 833 elem.attribute_handle as i32, 834 elem.type_ as i32, 835 )); 836 } 837 None => { 838 // TODO(b/193685325): Log error. 839 } 840 } 841 } 842 } 843 } 844 845 db_out 846 } 847 into_db(service: BluetoothGattService) -> Vec<BtGattDbElement>848 fn into_db(service: BluetoothGattService) -> Vec<BtGattDbElement> { 849 let mut db_out: Vec<BtGattDbElement> = vec![]; 850 db_out.push(BtGattDbElement { 851 id: service.instance_id as u16, 852 uuid: Uuid::from(service.uuid), 853 type_: service.service_type as u32, 854 attribute_handle: service.instance_id as u16, 855 start_handle: service.instance_id as u16, 856 end_handle: 0, 857 properties: 0, 858 extended_properties: 0, 859 permissions: 0, 860 }); 861 862 for char in service.characteristics { 863 db_out.push(BtGattDbElement { 864 id: char.instance_id as u16, 865 uuid: Uuid::from(char.uuid), 866 type_: GattDbElementType::Characteristic as u32, 867 attribute_handle: char.instance_id as u16, 868 start_handle: 0, 869 end_handle: 0, 870 properties: char.properties as u8, 871 extended_properties: 0, 872 permissions: char.permissions as u16, 873 }); 874 875 for desc in char.descriptors { 876 db_out.push(BtGattDbElement { 877 id: desc.instance_id as u16, 878 uuid: Uuid::from(desc.uuid), 879 type_: GattDbElementType::Descriptor as u32, 880 attribute_handle: desc.instance_id as u16, 881 start_handle: 0, 882 end_handle: 0, 883 properties: 0, 884 extended_properties: 0, 885 permissions: desc.permissions as u16, 886 }); 887 } 888 } 889 890 for included_service in service.included_services { 891 db_out.push(BtGattDbElement { 892 id: included_service.instance_id as u16, 893 uuid: Uuid::from(included_service.uuid), 894 type_: included_service.service_type as u32, 895 attribute_handle: included_service.instance_id as u16, 896 start_handle: 0, 897 end_handle: 0, 898 properties: 0, 899 extended_properties: 0, 900 permissions: 0, 901 }); 902 } 903 904 // Set end handle of primary/secondary attribute to last element's handle 905 if let Some(elem) = db_out.last() { 906 db_out[0].end_handle = elem.attribute_handle; 907 } 908 909 db_out 910 } 911 } 912 913 /// Callback for GATT Client API. 914 pub trait IBluetoothGattCallback: RPCProxy { 915 /// When the `register_client` request is done. on_client_registered(&mut self, _status: GattStatus, _client_id: i32)916 fn on_client_registered(&mut self, _status: GattStatus, _client_id: i32); 917 918 /// When there is a change in the state of a GATT client connection. on_client_connection_state( &mut self, _status: GattStatus, _client_id: i32, _connected: bool, _addr: String, )919 fn on_client_connection_state( 920 &mut self, 921 _status: GattStatus, 922 _client_id: i32, 923 _connected: bool, 924 _addr: String, 925 ); 926 927 /// When there is a change of PHY. on_phy_update(&mut self, _addr: String, _tx_phy: LePhy, _rx_phy: LePhy, _status: GattStatus)928 fn on_phy_update(&mut self, _addr: String, _tx_phy: LePhy, _rx_phy: LePhy, _status: GattStatus); 929 930 /// The completion of IBluetoothGatt::read_phy. on_phy_read(&mut self, _addr: String, _tx_phy: LePhy, _rx_phy: LePhy, _status: GattStatus)931 fn on_phy_read(&mut self, _addr: String, _tx_phy: LePhy, _rx_phy: LePhy, _status: GattStatus); 932 933 /// When GATT db is available. on_search_complete( &mut self, _addr: String, _services: Vec<BluetoothGattService>, _status: GattStatus, )934 fn on_search_complete( 935 &mut self, 936 _addr: String, 937 _services: Vec<BluetoothGattService>, 938 _status: GattStatus, 939 ); 940 941 /// The completion of IBluetoothGatt::read_characteristic. on_characteristic_read( &mut self, _addr: String, _status: GattStatus, _handle: i32, _value: Vec<u8>, )942 fn on_characteristic_read( 943 &mut self, 944 _addr: String, 945 _status: GattStatus, 946 _handle: i32, 947 _value: Vec<u8>, 948 ); 949 950 /// The completion of IBluetoothGatt::write_characteristic. on_characteristic_write(&mut self, _addr: String, _status: GattStatus, _handle: i32)951 fn on_characteristic_write(&mut self, _addr: String, _status: GattStatus, _handle: i32); 952 953 /// When a reliable write is completed. on_execute_write(&mut self, _addr: String, _status: GattStatus)954 fn on_execute_write(&mut self, _addr: String, _status: GattStatus); 955 956 /// The completion of IBluetoothGatt::read_descriptor. on_descriptor_read( &mut self, _addr: String, _status: GattStatus, _handle: i32, _value: Vec<u8>, )957 fn on_descriptor_read( 958 &mut self, 959 _addr: String, 960 _status: GattStatus, 961 _handle: i32, 962 _value: Vec<u8>, 963 ); 964 965 /// The completion of IBluetoothGatt::write_descriptor. on_descriptor_write(&mut self, _addr: String, _status: GattStatus, _handle: i32)966 fn on_descriptor_write(&mut self, _addr: String, _status: GattStatus, _handle: i32); 967 968 /// When notification or indication is received. on_notify(&mut self, _addr: String, _handle: i32, _value: Vec<u8>)969 fn on_notify(&mut self, _addr: String, _handle: i32, _value: Vec<u8>); 970 971 /// The completion of IBluetoothGatt::read_remote_rssi. on_read_remote_rssi(&mut self, _addr: String, _rssi: i32, _status: GattStatus)972 fn on_read_remote_rssi(&mut self, _addr: String, _rssi: i32, _status: GattStatus); 973 974 /// The completion of IBluetoothGatt::configure_mtu. on_configure_mtu(&mut self, _addr: String, _mtu: i32, _status: GattStatus)975 fn on_configure_mtu(&mut self, _addr: String, _mtu: i32, _status: GattStatus); 976 977 /// When a connection parameter changes. on_connection_updated( &mut self, _addr: String, _interval: i32, _latency: i32, _timeout: i32, _status: GattStatus, )978 fn on_connection_updated( 979 &mut self, 980 _addr: String, 981 _interval: i32, 982 _latency: i32, 983 _timeout: i32, 984 _status: GattStatus, 985 ); 986 987 /// When there is an addition, removal, or change of a GATT service. on_service_changed(&mut self, _addr: String)988 fn on_service_changed(&mut self, _addr: String); 989 } 990 991 /// Callback for GATT Server API. 992 pub trait IBluetoothGattServerCallback: RPCProxy { 993 /// When the `register_server` request is done. on_server_registered(&mut self, _status: GattStatus, _server_id: i32)994 fn on_server_registered(&mut self, _status: GattStatus, _server_id: i32); 995 996 /// When there is a change in the state of a GATT server connection. on_server_connection_state(&mut self, _server_id: i32, _connected: bool, _addr: String)997 fn on_server_connection_state(&mut self, _server_id: i32, _connected: bool, _addr: String); 998 999 /// When there is a service added to the GATT server. on_service_added(&mut self, _status: GattStatus, _service: BluetoothGattService)1000 fn on_service_added(&mut self, _status: GattStatus, _service: BluetoothGattService); 1001 1002 /// When a service has been removed from the GATT server. on_service_removed(&mut self, status: GattStatus, handle: i32)1003 fn on_service_removed(&mut self, status: GattStatus, handle: i32); 1004 1005 /// When a remote device has requested to read a characteristic. on_characteristic_read_request( &mut self, _addr: String, _trans_id: i32, _offset: i32, _is_long: bool, _handle: i32, )1006 fn on_characteristic_read_request( 1007 &mut self, 1008 _addr: String, 1009 _trans_id: i32, 1010 _offset: i32, 1011 _is_long: bool, 1012 _handle: i32, 1013 ); 1014 1015 /// When a remote device has requested to read a descriptor. on_descriptor_read_request( &mut self, _addr: String, _trans_id: i32, _offset: i32, _is_long: bool, _handle: i32, )1016 fn on_descriptor_read_request( 1017 &mut self, 1018 _addr: String, 1019 _trans_id: i32, 1020 _offset: i32, 1021 _is_long: bool, 1022 _handle: i32, 1023 ); 1024 1025 /// When a remote device has requested to write to a characteristic. on_characteristic_write_request( &mut self, _addr: String, _trans_id: i32, _offset: i32, _len: i32, _is_prep: bool, _need_rsp: bool, _handle: i32, _value: Vec<u8>, )1026 fn on_characteristic_write_request( 1027 &mut self, 1028 _addr: String, 1029 _trans_id: i32, 1030 _offset: i32, 1031 _len: i32, 1032 _is_prep: bool, 1033 _need_rsp: bool, 1034 _handle: i32, 1035 _value: Vec<u8>, 1036 ); 1037 1038 /// When a remote device has requested to write to a descriptor. on_descriptor_write_request( &mut self, _addr: String, _trans_id: i32, _offset: i32, _len: i32, _is_prep: bool, _need_rsp: bool, _handle: i32, _value: Vec<u8>, )1039 fn on_descriptor_write_request( 1040 &mut self, 1041 _addr: String, 1042 _trans_id: i32, 1043 _offset: i32, 1044 _len: i32, 1045 _is_prep: bool, 1046 _need_rsp: bool, 1047 _handle: i32, 1048 _value: Vec<u8>, 1049 ); 1050 1051 /// When a previously prepared write is to be executed. on_execute_write(&mut self, _addr: String, _trans_id: i32, _exec_write: bool)1052 fn on_execute_write(&mut self, _addr: String, _trans_id: i32, _exec_write: bool); 1053 1054 /// When a notification or indication has been sent to a remote device. on_notification_sent(&mut self, _addr: String, _status: GattStatus)1055 fn on_notification_sent(&mut self, _addr: String, _status: GattStatus); 1056 1057 /// When the MTU for a given connection changes on_mtu_changed(&mut self, addr: String, mtu: i32)1058 fn on_mtu_changed(&mut self, addr: String, mtu: i32); 1059 1060 /// When there is a change of PHY. on_phy_update(&mut self, addr: String, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus)1061 fn on_phy_update(&mut self, addr: String, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus); 1062 1063 /// The completion of IBluetoothGatt::server_read_phy. on_phy_read(&mut self, addr: String, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus)1064 fn on_phy_read(&mut self, addr: String, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus); 1065 1066 /// When the connection parameters for a given connection changes. on_connection_updated( &mut self, addr: String, interval: i32, latency: i32, timeout: i32, status: GattStatus, )1067 fn on_connection_updated( 1068 &mut self, 1069 addr: String, 1070 interval: i32, 1071 latency: i32, 1072 timeout: i32, 1073 status: GattStatus, 1074 ); 1075 1076 /// When the subrate change event for a given connection is received. on_subrate_change( &mut self, addr: String, subrate_factor: i32, latency: i32, cont_num: i32, timeout: i32, status: GattStatus, )1077 fn on_subrate_change( 1078 &mut self, 1079 addr: String, 1080 subrate_factor: i32, 1081 latency: i32, 1082 cont_num: i32, 1083 timeout: i32, 1084 status: GattStatus, 1085 ); 1086 } 1087 1088 /// Interface for scanner callbacks to clients, passed to 1089 /// `IBluetoothGatt::register_scanner_callback`. 1090 pub trait IScannerCallback: RPCProxy { 1091 /// When the `register_scanner` request is done. on_scanner_registered(&mut self, uuid: Uuid128Bit, scanner_id: u8, status: GattStatus)1092 fn on_scanner_registered(&mut self, uuid: Uuid128Bit, scanner_id: u8, status: GattStatus); 1093 1094 /// When an LE advertisement matching aggregate filters is detected. This callback is shared 1095 /// among all scanner callbacks and is triggered for *every* advertisement that the controller 1096 /// receives. For listening to the beginning and end of a specific scanner's advertisements 1097 /// detected while in RSSI range, use on_advertisement_found and on_advertisement_lost below. on_scan_result(&mut self, scan_result: ScanResult)1098 fn on_scan_result(&mut self, scan_result: ScanResult); 1099 1100 /// When an LE advertisement matching aggregate filters is found. The criteria of 1101 /// how a device is considered found is specified by ScanFilter. on_advertisement_found(&mut self, scanner_id: u8, scan_result: ScanResult)1102 fn on_advertisement_found(&mut self, scanner_id: u8, scan_result: ScanResult); 1103 1104 /// When an LE advertisement matching aggregate filters is no longer detected. The criteria of 1105 /// how a device is considered lost is specified by ScanFilter. 1106 // TODO(b/269343922): Rename this to on_advertisement_lost for symmetry with 1107 // on_advertisement_found. on_advertisement_lost(&mut self, scanner_id: u8, scan_result: ScanResult)1108 fn on_advertisement_lost(&mut self, scanner_id: u8, scan_result: ScanResult); 1109 1110 /// When LE Scan module changes suspend mode due to system suspend/resume. on_suspend_mode_change(&mut self, suspend_mode: SuspendMode)1111 fn on_suspend_mode_change(&mut self, suspend_mode: SuspendMode); 1112 } 1113 1114 #[derive(Debug, FromPrimitive, ToPrimitive)] 1115 #[repr(u8)] 1116 /// GATT write type. 1117 pub(crate) enum GattDbElementType { 1118 PrimaryService = 0, 1119 SecondaryService = 1, 1120 IncludedService = 2, 1121 Characteristic = 3, 1122 Descriptor = 4, 1123 } 1124 1125 impl Into<i32> for GattDbElementType { into(self) -> i321126 fn into(self) -> i32 { 1127 self.to_u8().unwrap_or(0).into() 1128 } 1129 } 1130 1131 #[derive(Debug, FromPrimitive, ToPrimitive, Copy, Clone)] 1132 #[repr(u8)] 1133 /// GATT write type. 1134 pub enum GattWriteType { 1135 Invalid = 0, 1136 WriteNoRsp = 1, 1137 Write = 2, 1138 WritePrepare = 3, 1139 } 1140 1141 impl Default for GattWriteType { default() -> Self1142 fn default() -> Self { 1143 GattWriteType::Write 1144 } 1145 } 1146 1147 #[derive(Debug, FromPrimitive, ToPrimitive)] 1148 #[repr(u32)] 1149 /// Scan type configuration. 1150 pub enum ScanType { 1151 Active = 0, 1152 Passive = 1, 1153 } 1154 1155 impl Default for ScanType { default() -> Self1156 fn default() -> Self { 1157 ScanType::Active 1158 } 1159 } 1160 1161 /// Represents scanning configurations to be passed to `IBluetoothGatt::start_scan`. 1162 /// 1163 /// This configuration is general and supported on all Bluetooth hardware, irrelevant of the 1164 /// hardware filter offload (APCF or MSFT). 1165 #[derive(Debug, Default)] 1166 pub struct ScanSettings { 1167 pub interval: i32, 1168 pub window: i32, 1169 pub scan_type: ScanType, 1170 } 1171 1172 /// Represents scan result 1173 #[derive(Debug)] 1174 pub struct ScanResult { 1175 pub name: String, 1176 pub address: String, 1177 pub addr_type: u8, 1178 pub event_type: u16, 1179 pub primary_phy: u8, 1180 pub secondary_phy: u8, 1181 pub advertising_sid: u8, 1182 pub tx_power: i8, 1183 pub rssi: i8, 1184 pub periodic_adv_int: u16, 1185 pub flags: u8, 1186 pub service_uuids: Vec<Uuid128Bit>, 1187 /// A map of 128-bit UUID and its corresponding service data. 1188 pub service_data: HashMap<String, Vec<u8>>, 1189 pub manufacturer_data: HashMap<u16, Vec<u8>>, 1190 pub adv_data: Vec<u8>, 1191 } 1192 1193 #[derive(Debug, Clone)] 1194 pub struct ScanFilterPattern { 1195 /// Specifies the starting byte position of the pattern immediately following AD Type. 1196 pub start_position: u8, 1197 1198 /// Advertising Data type (https://www.bluetooth.com/specifications/assigned-numbers/). 1199 pub ad_type: u8, 1200 1201 /// The pattern to be matched for the specified AD Type within the advertisement packet from 1202 /// the specified starting byte. 1203 pub content: Vec<u8>, 1204 } 1205 1206 /// Represents the condition for matching advertisements. 1207 /// 1208 /// Only pattern-based matching is implemented. 1209 #[derive(Debug, Clone)] 1210 pub enum ScanFilterCondition { 1211 /// All advertisements are matched. 1212 All, 1213 1214 /// Match by pattern anywhere in the advertisement data. Multiple patterns are "OR"-ed. 1215 Patterns(Vec<ScanFilterPattern>), 1216 1217 /// Match by UUID (not implemented). 1218 Uuid, 1219 1220 /// Match if the IRK resolves an advertisement (not implemented). 1221 Irk, 1222 1223 /// Match by Bluetooth address (not implemented). 1224 BluetoothAddress, 1225 } 1226 1227 /// Represents a scan filter to be passed to `IBluetoothGatt::start_scan`. 1228 /// 1229 /// This filter is intentionally modelled close to the MSFT hardware offload filter. 1230 /// Reference: 1231 /// https://learn.microsoft.com/en-us/windows-hardware/drivers/bluetooth/microsoft-defined-bluetooth-hci-commands-and-events 1232 #[derive(Debug, Clone)] 1233 pub struct ScanFilter { 1234 /// Advertisements with RSSI above or equal this value is considered "found". 1235 pub rssi_high_threshold: u8, 1236 1237 /// Advertisements with RSSI below or equal this value (for a period of rssi_low_timeout) is 1238 /// considered "lost". 1239 pub rssi_low_threshold: u8, 1240 1241 /// The time in seconds over which the RSSI value should be below rssi_low_threshold before 1242 /// being considered "lost". 1243 pub rssi_low_timeout: u8, 1244 1245 /// The sampling interval in milliseconds. 1246 pub rssi_sampling_period: u8, 1247 1248 /// The condition to match advertisements with. 1249 pub condition: ScanFilterCondition, 1250 } 1251 1252 type ScannersMap = HashMap<Uuid, ScannerInfo>; 1253 1254 const DEFAULT_ASYNC_TIMEOUT_MS: u64 = 5000; 1255 1256 /// Abstraction for async GATT operations. Contains async methods for coordinating async operations 1257 /// more conveniently. 1258 struct GattAsyncIntf { 1259 scanners: Arc<Mutex<ScannersMap>>, 1260 gatt: Option<Arc<Mutex<Gatt>>>, 1261 1262 async_helper_msft_adv_monitor_add: AsyncHelper<(u8, u8)>, 1263 async_helper_msft_adv_monitor_remove: AsyncHelper<u8>, 1264 async_helper_msft_adv_monitor_enable: AsyncHelper<u8>, 1265 } 1266 1267 impl GattAsyncIntf { 1268 /// Adds an advertisement monitor. Returns monitor handle and status. msft_adv_monitor_add(&mut self, monitor: MsftAdvMonitor) -> Result<(u8, u8), ()>1269 async fn msft_adv_monitor_add(&mut self, monitor: MsftAdvMonitor) -> Result<(u8, u8), ()> { 1270 let gatt = self.gatt.as_ref().unwrap().clone(); 1271 1272 self.async_helper_msft_adv_monitor_add 1273 .call_method( 1274 move |call_id| { 1275 gatt.lock().unwrap().scanner.msft_adv_monitor_add(call_id, &monitor); 1276 }, 1277 Some(DEFAULT_ASYNC_TIMEOUT_MS), 1278 ) 1279 .await 1280 } 1281 1282 /// Removes an advertisement monitor. Returns status. msft_adv_monitor_remove(&mut self, monitor_handle: u8) -> Result<u8, ()>1283 async fn msft_adv_monitor_remove(&mut self, monitor_handle: u8) -> Result<u8, ()> { 1284 let gatt = self.gatt.as_ref().unwrap().clone(); 1285 1286 self.async_helper_msft_adv_monitor_remove 1287 .call_method( 1288 move |call_id| { 1289 gatt.lock().unwrap().scanner.msft_adv_monitor_remove(call_id, monitor_handle); 1290 }, 1291 Some(DEFAULT_ASYNC_TIMEOUT_MS), 1292 ) 1293 .await 1294 } 1295 1296 /// Enables/disables an advertisement monitor. Returns status. msft_adv_monitor_enable(&mut self, enable: bool) -> Result<u8, ()>1297 async fn msft_adv_monitor_enable(&mut self, enable: bool) -> Result<u8, ()> { 1298 let gatt = self.gatt.as_ref().unwrap().clone(); 1299 1300 self.async_helper_msft_adv_monitor_enable 1301 .call_method( 1302 move |call_id| { 1303 gatt.lock().unwrap().scanner.msft_adv_monitor_enable(call_id, enable); 1304 }, 1305 Some(DEFAULT_ASYNC_TIMEOUT_MS), 1306 ) 1307 .await 1308 } 1309 1310 /// Updates the topshim's scan state depending on the states of registered scanners. Scan is 1311 /// enabled if there is at least 1 active registered scanner. 1312 /// 1313 /// Note: this does not need to be async, but declared as async for consistency in this struct. 1314 /// May be converted into real async in the future if btif supports it. update_scan(&mut self)1315 async fn update_scan(&mut self) { 1316 if self.scanners.lock().unwrap().values().find(|scanner| scanner.is_active).is_some() { 1317 // Toggle the scan off and on so that we reset the scan parameters based on whether 1318 // we have active scanners using hardware filtering. 1319 // TODO(b/266752123): We can do more bookkeeping to optimize when we really need to 1320 // toggle. Also improve toggling API into 1 operation that guarantees correct ordering. 1321 self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan(); 1322 self.gatt.as_ref().unwrap().lock().unwrap().scanner.start_scan(); 1323 } else { 1324 self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan(); 1325 } 1326 } 1327 } 1328 1329 /// Implementation of the GATT API (IBluetoothGatt). 1330 pub struct BluetoothGatt { 1331 intf: Arc<Mutex<BluetoothInterface>>, 1332 // TODO(b/254870880): Wrapping in an `Option` makes the code unnecessarily verbose. Find a way 1333 // to not wrap this in `Option` since we know that we can't function without `gatt` being 1334 // initialized anyway. 1335 gatt: Option<Arc<Mutex<Gatt>>>, 1336 adapter: Option<Arc<Mutex<Box<Bluetooth>>>>, 1337 1338 context_map: ContextMap, 1339 server_context_map: ServerContextMap, 1340 reliable_queue: HashSet<String>, 1341 scanner_callbacks: Callbacks<dyn IScannerCallback + Send>, 1342 scanners: Arc<Mutex<ScannersMap>>, 1343 scan_suspend_mode: SuspendMode, 1344 paused_scanner_ids: Vec<u8>, 1345 advertisers: Advertisers, 1346 1347 adv_mon_add_cb_sender: CallbackSender<(u8, u8)>, 1348 adv_mon_remove_cb_sender: CallbackSender<u8>, 1349 adv_mon_enable_cb_sender: CallbackSender<u8>, 1350 1351 // Used for generating random UUIDs. SmallRng is chosen because it is fast, don't use this for 1352 // cryptography. 1353 small_rng: SmallRng, 1354 1355 gatt_async: Arc<tokio::sync::Mutex<GattAsyncIntf>>, 1356 } 1357 1358 impl BluetoothGatt { 1359 /// Constructs a new IBluetoothGatt implementation. new(intf: Arc<Mutex<BluetoothInterface>>, tx: Sender<Message>) -> BluetoothGatt1360 pub fn new(intf: Arc<Mutex<BluetoothInterface>>, tx: Sender<Message>) -> BluetoothGatt { 1361 let scanners = Arc::new(Mutex::new(HashMap::new())); 1362 1363 let async_helper_msft_adv_monitor_add = AsyncHelper::new("MsftAdvMonitorAdd"); 1364 let async_helper_msft_adv_monitor_remove = AsyncHelper::new("MsftAdvMonitorRemove"); 1365 let async_helper_msft_adv_monitor_enable = AsyncHelper::new("MsftAdvMonitorEnable"); 1366 BluetoothGatt { 1367 intf, 1368 gatt: None, 1369 adapter: None, 1370 context_map: ContextMap::new(tx.clone()), 1371 server_context_map: ServerContextMap::new(tx.clone()), 1372 reliable_queue: HashSet::new(), 1373 scanner_callbacks: Callbacks::new(tx.clone(), Message::ScannerCallbackDisconnected), 1374 scanners: scanners.clone(), 1375 scan_suspend_mode: SuspendMode::Normal, 1376 paused_scanner_ids: Vec::new(), 1377 small_rng: SmallRng::from_entropy(), 1378 advertisers: Advertisers::new(tx.clone()), 1379 adv_mon_add_cb_sender: async_helper_msft_adv_monitor_add.get_callback_sender(), 1380 adv_mon_remove_cb_sender: async_helper_msft_adv_monitor_remove.get_callback_sender(), 1381 adv_mon_enable_cb_sender: async_helper_msft_adv_monitor_enable.get_callback_sender(), 1382 gatt_async: Arc::new(tokio::sync::Mutex::new(GattAsyncIntf { 1383 scanners, 1384 gatt: None, 1385 async_helper_msft_adv_monitor_add, 1386 async_helper_msft_adv_monitor_remove, 1387 async_helper_msft_adv_monitor_enable, 1388 })), 1389 } 1390 } 1391 init_profiles(&mut self, tx: Sender<Message>, adapter: Arc<Mutex<Box<Bluetooth>>>)1392 pub fn init_profiles(&mut self, tx: Sender<Message>, adapter: Arc<Mutex<Box<Bluetooth>>>) { 1393 self.gatt = Gatt::new(&self.intf.lock().unwrap()).map(|gatt| Arc::new(Mutex::new(gatt))); 1394 self.adapter = Some(adapter); 1395 1396 let tx_clone = tx.clone(); 1397 let gatt_client_callbacks_dispatcher = GattClientCallbacksDispatcher { 1398 dispatch: Box::new(move |cb| { 1399 let tx_clone = tx_clone.clone(); 1400 topstack::get_runtime().spawn(async move { 1401 let _ = tx_clone.send(Message::GattClient(cb)).await; 1402 }); 1403 }), 1404 }; 1405 1406 let tx_clone = tx.clone(); 1407 let gatt_server_callbacks_dispatcher = GattServerCallbacksDispatcher { 1408 dispatch: Box::new(move |cb| { 1409 let tx_clone = tx_clone.clone(); 1410 topstack::get_runtime().spawn(async move { 1411 let _ = tx_clone.send(Message::GattServer(cb)).await; 1412 }); 1413 }), 1414 }; 1415 1416 let tx_clone = tx.clone(); 1417 let gatt_scanner_callbacks_dispatcher = GattScannerCallbacksDispatcher { 1418 dispatch: Box::new(move |cb| { 1419 let tx_clone = tx_clone.clone(); 1420 topstack::get_runtime().spawn(async move { 1421 let _ = tx_clone.send(Message::LeScanner(cb)).await; 1422 }); 1423 }), 1424 }; 1425 1426 let tx_clone = tx.clone(); 1427 let gatt_scanner_inband_callbacks_dispatcher = GattScannerInbandCallbacksDispatcher { 1428 dispatch: Box::new(move |cb| { 1429 let tx_clone = tx_clone.clone(); 1430 topstack::get_runtime().spawn(async move { 1431 let _ = tx_clone.send(Message::LeScannerInband(cb)).await; 1432 }); 1433 }), 1434 }; 1435 1436 let tx_clone = tx.clone(); 1437 let gatt_adv_inband_callbacks_dispatcher = GattAdvInbandCallbacksDispatcher { 1438 dispatch: Box::new(move |cb| { 1439 let tx_clone = tx_clone.clone(); 1440 topstack::get_runtime().spawn(async move { 1441 let _ = tx_clone.send(Message::LeAdvInband(cb)).await; 1442 }); 1443 }), 1444 }; 1445 1446 let tx_clone = tx.clone(); 1447 let gatt_adv_callbacks_dispatcher = GattAdvCallbacksDispatcher { 1448 dispatch: Box::new(move |cb| { 1449 let tx_clone = tx_clone.clone(); 1450 topstack::get_runtime().spawn(async move { 1451 let _ = tx_clone.send(Message::LeAdv(cb)).await; 1452 }); 1453 }), 1454 }; 1455 1456 self.gatt.as_ref().unwrap().lock().unwrap().initialize( 1457 gatt_client_callbacks_dispatcher, 1458 gatt_server_callbacks_dispatcher, 1459 gatt_scanner_callbacks_dispatcher, 1460 gatt_scanner_inband_callbacks_dispatcher, 1461 gatt_adv_inband_callbacks_dispatcher, 1462 gatt_adv_callbacks_dispatcher, 1463 ); 1464 1465 let gatt = self.gatt.clone(); 1466 let gatt_async = self.gatt_async.clone(); 1467 tokio::spawn(async move { 1468 gatt_async.lock().await.gatt = gatt; 1469 }); 1470 } 1471 1472 /// Remove a scanner callback and unregisters all scanners associated with that callback. remove_scanner_callback(&mut self, callback_id: u32) -> bool1473 pub fn remove_scanner_callback(&mut self, callback_id: u32) -> bool { 1474 let affected_scanner_ids: Vec<u8> = self 1475 .scanners 1476 .lock() 1477 .unwrap() 1478 .iter() 1479 .filter(|(_uuid, scanner)| scanner.callback_id == callback_id) 1480 .filter_map(|(_uuid, scanner)| { 1481 if let Some(scanner_id) = scanner.scanner_id { 1482 Some(scanner_id) 1483 } else { 1484 None 1485 } 1486 }) 1487 .collect(); 1488 1489 // All scanners associated with the callback must be also unregistered. 1490 for scanner_id in affected_scanner_ids { 1491 self.unregister_scanner(scanner_id); 1492 } 1493 1494 self.scanner_callbacks.remove_callback(callback_id) 1495 } 1496 1497 /// Set the suspend mode. set_scan_suspend_mode(&mut self, suspend_mode: SuspendMode)1498 pub fn set_scan_suspend_mode(&mut self, suspend_mode: SuspendMode) { 1499 if suspend_mode != self.scan_suspend_mode { 1500 self.scan_suspend_mode = suspend_mode.clone(); 1501 1502 // Notify current suspend mode to all active callbacks. 1503 self.scanner_callbacks.for_all_callbacks(|callback| { 1504 callback.on_suspend_mode_change(suspend_mode.clone()); 1505 }); 1506 } 1507 } 1508 1509 /// Enters suspend mode for LE Scan. 1510 /// 1511 /// This "pauses" all operations managed by this module to prepare for system suspend. A 1512 /// callback is triggered to let clients know that this module is in suspend mode and some 1513 /// subsequent API calls will be blocked in this mode. scan_enter_suspend(&mut self) -> BtStatus1514 pub fn scan_enter_suspend(&mut self) -> BtStatus { 1515 if self.get_scan_suspend_mode() != SuspendMode::Normal { 1516 return BtStatus::Busy; 1517 } 1518 self.set_scan_suspend_mode(SuspendMode::Suspending); 1519 1520 // Collect the scanners that will be paused so that they can be re-enabled at resume. 1521 let paused_scanner_ids = self 1522 .scanners 1523 .lock() 1524 .unwrap() 1525 .iter() 1526 .filter_map(|(_uuid, scanner)| { 1527 if let (true, Some(scanner_id)) = (scanner.is_active, scanner.scanner_id) { 1528 Some(scanner_id) 1529 } else { 1530 None 1531 } 1532 }) 1533 .collect(); 1534 1535 // Note: We can't simply disable the LE scanning. When a filter is offloaded 1536 // with the MSFT extension and it is monitoring a device, it sends a 1537 // `Monitor Device Event` to indicate that monitoring is stopped and this 1538 // can cause an early wake-up. Until we fix the disable + mask solution, we 1539 // must remove all monitors before suspend and re-monitor them on resume. 1540 for &scanner_id in &paused_scanner_ids { 1541 self.stop_scan(scanner_id); 1542 if let Some(scanner) = 1543 Self::find_scanner_by_id(&mut self.scanners.lock().unwrap(), scanner_id) 1544 { 1545 scanner.is_suspended = true; 1546 } 1547 } 1548 self.paused_scanner_ids = paused_scanner_ids; 1549 self.set_scan_suspend_mode(SuspendMode::Suspended); 1550 return BtStatus::Success; 1551 } 1552 1553 /// Exits suspend mode for LE Scan. 1554 /// 1555 /// To be called after system resume/wake up. This "unpauses" the operations that were "paused" 1556 /// due to suspend. A callback is triggered to let clients when this module has exited suspend 1557 /// mode. scan_exit_suspend(&mut self) -> BtStatus1558 pub fn scan_exit_suspend(&mut self) -> BtStatus { 1559 if self.get_scan_suspend_mode() != SuspendMode::Suspended { 1560 return BtStatus::Busy; 1561 } 1562 self.set_scan_suspend_mode(SuspendMode::Resuming); 1563 1564 // The resume_scan() will add and reenable the monitors individually. 1565 for scanner_id in self.paused_scanner_ids.drain(..).collect::<Vec<_>>() { 1566 self.resume_scan(scanner_id); 1567 } 1568 self.set_scan_suspend_mode(SuspendMode::Normal); 1569 1570 return BtStatus::Success; 1571 } 1572 find_scanner_by_id<'a>( scanners: &'a mut MutexGuard<ScannersMap>, scanner_id: u8, ) -> Option<&'a mut ScannerInfo>1573 fn find_scanner_by_id<'a>( 1574 scanners: &'a mut MutexGuard<ScannersMap>, 1575 scanner_id: u8, 1576 ) -> Option<&'a mut ScannerInfo> { 1577 scanners.values_mut().find(|scanner| scanner.scanner_id == Some(scanner_id)) 1578 } 1579 1580 /// The resume_scan method is used to resume scanning after system suspension. 1581 /// It assumes that scanner.filter has already had the filter data. resume_scan(&mut self, scanner_id: u8) -> BtStatus1582 fn resume_scan(&mut self, scanner_id: u8) -> BtStatus { 1583 let scan_suspend_mode = self.get_scan_suspend_mode(); 1584 if scan_suspend_mode != SuspendMode::Normal && scan_suspend_mode != SuspendMode::Resuming { 1585 return BtStatus::Busy; 1586 } 1587 1588 let filter = { 1589 let mut scanners_lock = self.scanners.lock().unwrap(); 1590 if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { 1591 if scanner.is_suspended { 1592 scanner.is_suspended = false; 1593 scanner.is_active = true; 1594 // When a scanner resumes from a suspended state, the 1595 // scanner.filter has already had the filter data. 1596 scanner.filter.clone() 1597 } else { 1598 log::warn!( 1599 "This Scanner {} is supposed to resume from suspended state", 1600 scanner_id 1601 ); 1602 return BtStatus::Fail; 1603 } 1604 } else { 1605 log::warn!("Scanner {} not found", scanner_id); 1606 return BtStatus::Fail; 1607 } 1608 }; 1609 1610 self.add_monitor_and_update_scan(scanner_id, filter) 1611 } 1612 add_monitor_and_update_scan( &mut self, scanner_id: u8, filter: Option<ScanFilter>, ) -> BtStatus1613 fn add_monitor_and_update_scan( 1614 &mut self, 1615 scanner_id: u8, 1616 filter: Option<ScanFilter>, 1617 ) -> BtStatus { 1618 let has_active_unfiltered_scanner = self 1619 .scanners 1620 .lock() 1621 .unwrap() 1622 .iter() 1623 .any(|(_uuid, scanner)| scanner.is_active && scanner.filter.is_none()); 1624 1625 let gatt_async = self.gatt_async.clone(); 1626 let scanners = self.scanners.clone(); 1627 let is_msft_supported = self.is_msft_supported(); 1628 1629 tokio::spawn(async move { 1630 // The three operations below (monitor add, monitor enable, update scan) happen one 1631 // after another, and cannot be interleaved with other GATT async operations. 1632 // So acquire the GATT async lock in the beginning of this block and will be released 1633 // at the end of this block. 1634 // TODO(b/217274432): Consider not using async model but instead add actions when 1635 // handling callbacks. 1636 let mut gatt_async = gatt_async.lock().await; 1637 1638 // Add and enable the monitor filter only when the MSFT extension is supported. 1639 if is_msft_supported { 1640 if let Some(filter) = filter { 1641 let monitor_handle = 1642 match gatt_async.msft_adv_monitor_add((&filter).into()).await { 1643 Ok((handle, 0)) => handle, 1644 _ => { 1645 log::error!("Error adding advertisement monitor"); 1646 return; 1647 } 1648 }; 1649 1650 if let Some(scanner) = 1651 Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) 1652 { 1653 // The monitor handle is needed in stop_scan(). 1654 scanner.monitor_handle = Some(monitor_handle); 1655 } 1656 1657 log::debug!("Added adv monitor handle = {}", monitor_handle); 1658 } 1659 1660 if !gatt_async 1661 .msft_adv_monitor_enable(!has_active_unfiltered_scanner) 1662 .await 1663 .map_or(false, |status| status == 0) 1664 { 1665 // TODO(b/266752123): 1666 // Intel controller throws "Command Disallowed" error if we tried to enable/disable 1667 // filter but it's already at the same state. This is harmless but we can improve 1668 // the state machine to avoid calling enable/disable if it's already at that state 1669 log::error!("Error updating Advertisement Monitor enable"); 1670 } 1671 } 1672 1673 gatt_async.update_scan().await; 1674 }); 1675 1676 BtStatus::Success 1677 } 1678 1679 /// Remove an advertiser callback and unregisters all advertising sets associated with that callback. remove_adv_callback(&mut self, callback_id: u32) -> bool1680 pub fn remove_adv_callback(&mut self, callback_id: u32) -> bool { 1681 self.advertisers 1682 .remove_callback(callback_id, &mut self.gatt.as_ref().unwrap().lock().unwrap()) 1683 } 1684 get_adapter_name(&self) -> String1685 fn get_adapter_name(&self) -> String { 1686 if let Some(adapter) = &self.adapter { 1687 adapter.lock().unwrap().get_name() 1688 } else { 1689 String::new() 1690 } 1691 } 1692 remove_client_callback(&mut self, callback_id: u32)1693 pub fn remove_client_callback(&mut self, callback_id: u32) { 1694 // Unregister client if client id exists. 1695 if let Some(client) = self.context_map.get_by_callback_id(callback_id) { 1696 if let Some(id) = client.id { 1697 self.unregister_client(id); 1698 } 1699 } 1700 1701 // Always remove callback. 1702 self.context_map.remove_callback(callback_id); 1703 } 1704 remove_server_callback(&mut self, callback_id: u32)1705 pub fn remove_server_callback(&mut self, callback_id: u32) { 1706 // Unregister server if server id exists. 1707 if let Some(server) = self.server_context_map.get_by_callback_id(callback_id) { 1708 if let Some(id) = server.id { 1709 self.unregister_server(id); 1710 } 1711 } 1712 1713 // Always remove callback. 1714 self.context_map.remove_callback(callback_id); 1715 } 1716 1717 /// Enters suspend mode for LE advertising. advertising_enter_suspend(&mut self)1718 pub fn advertising_enter_suspend(&mut self) { 1719 self.advertisers.set_suspend_mode(SuspendMode::Suspending); 1720 1721 let mut pausing_cnt = 0; 1722 for s in self.advertisers.enabled_sets_mut() { 1723 s.set_paused(true); 1724 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( 1725 s.adv_id(), 1726 false, 1727 s.adv_timeout(), 1728 s.adv_events(), 1729 ); 1730 pausing_cnt += 1; 1731 } 1732 1733 if pausing_cnt == 0 { 1734 self.advertisers.set_suspend_mode(SuspendMode::Suspended); 1735 } 1736 } 1737 1738 /// Exits suspend mode for LE advertising. advertising_exit_suspend(&mut self)1739 pub fn advertising_exit_suspend(&mut self) { 1740 for s in self.advertisers.paused_sets_mut() { 1741 s.set_paused(false); 1742 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( 1743 s.adv_id(), 1744 true, 1745 s.adv_timeout(), 1746 s.adv_events(), 1747 ); 1748 } 1749 1750 self.advertisers.set_suspend_mode(SuspendMode::Normal); 1751 } 1752 1753 /// Start an active scan on given scanner id. This will look up and assign 1754 /// the correct ScanSettings for it as well. start_active_scan(&mut self, scanner_id: u8) -> BtStatus1755 pub(crate) fn start_active_scan(&mut self, scanner_id: u8) -> BtStatus { 1756 let interval: u16 = sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval) 1757 .try_into() 1758 .expect("Bad value configured for LeInquiryScanInterval"); 1759 let window: u16 = sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow) 1760 .try_into() 1761 .expect("Bad value configured for LeInquiryScanWindow"); 1762 1763 self.gatt 1764 .as_ref() 1765 .unwrap() 1766 .lock() 1767 .unwrap() 1768 .scanner 1769 .set_scan_parameters(scanner_id, interval, window); 1770 1771 self.start_scan(scanner_id, ScanSettings::default(), /*filter=*/ None) 1772 } 1773 stop_active_scan(&mut self, scanner_id: u8) -> BtStatus1774 pub(crate) fn stop_active_scan(&mut self, scanner_id: u8) -> BtStatus { 1775 self.stop_scan(scanner_id) 1776 } 1777 } 1778 1779 #[derive(Debug, FromPrimitive, ToPrimitive)] 1780 #[repr(u8)] 1781 /// Status of WriteCharacteristic methods. 1782 pub enum GattWriteRequestStatus { 1783 Success = 0, 1784 Fail = 1, 1785 Busy = 2, 1786 } 1787 1788 // This structure keeps track of the lifecycle of a scanner. 1789 struct ScannerInfo { 1790 // The callback to which events about this scanner needs to be sent to. 1791 // Another purpose of keeping track of the callback id is that when a callback is disconnected 1792 // or unregistered we need to also unregister all scanners associated with that callback to 1793 // prevent dangling unowned scanners. 1794 callback_id: u32, 1795 // If the scanner is registered successfully, this contains the scanner id, otherwise None. 1796 scanner_id: Option<u8>, 1797 // If one of scanners is active, we scan. 1798 is_active: bool, 1799 // Scan filter. 1800 filter: Option<ScanFilter>, 1801 // Adv monitor handle, if exists. 1802 monitor_handle: Option<u8>, 1803 // Used by start_scan() to determine if it is called because of system resuming. 1804 is_suspended: bool, 1805 } 1806 1807 impl ScannerInfo { new(callback_id: u32) -> Self1808 fn new(callback_id: u32) -> Self { 1809 Self { 1810 callback_id, 1811 scanner_id: None, 1812 is_active: false, 1813 filter: None, 1814 monitor_handle: None, 1815 is_suspended: false, 1816 } 1817 } 1818 } 1819 1820 impl Into<MsftAdvMonitorPattern> for &ScanFilterPattern { into(self) -> MsftAdvMonitorPattern1821 fn into(self) -> MsftAdvMonitorPattern { 1822 MsftAdvMonitorPattern { 1823 ad_type: self.ad_type, 1824 start_byte: self.start_position, 1825 pattern: self.content.clone(), 1826 } 1827 } 1828 } 1829 1830 impl Into<Vec<MsftAdvMonitorPattern>> for &ScanFilterCondition { into(self) -> Vec<MsftAdvMonitorPattern>1831 fn into(self) -> Vec<MsftAdvMonitorPattern> { 1832 match self { 1833 ScanFilterCondition::Patterns(patterns) => { 1834 patterns.iter().map(|pattern| pattern.into()).collect() 1835 } 1836 _ => vec![], 1837 } 1838 } 1839 } 1840 1841 impl Into<MsftAdvMonitor> for &ScanFilter { into(self) -> MsftAdvMonitor1842 fn into(self) -> MsftAdvMonitor { 1843 MsftAdvMonitor { 1844 rssi_high_threshold: self.rssi_high_threshold.try_into().unwrap(), 1845 rssi_low_threshold: self.rssi_low_threshold.try_into().unwrap(), 1846 rssi_low_timeout: self.rssi_low_timeout.try_into().unwrap(), 1847 rssi_sampling_period: self.rssi_sampling_period.try_into().unwrap(), 1848 patterns: (&self.condition).into(), 1849 } 1850 } 1851 } 1852 1853 impl IBluetoothGatt for BluetoothGatt { is_msft_supported(&self) -> bool1854 fn is_msft_supported(&self) -> bool { 1855 self.gatt.as_ref().unwrap().lock().unwrap().scanner.is_msft_supported() 1856 } 1857 register_scanner_callback(&mut self, callback: Box<dyn IScannerCallback + Send>) -> u321858 fn register_scanner_callback(&mut self, callback: Box<dyn IScannerCallback + Send>) -> u32 { 1859 self.scanner_callbacks.add_callback(callback) 1860 } 1861 unregister_scanner_callback(&mut self, callback_id: u32) -> bool1862 fn unregister_scanner_callback(&mut self, callback_id: u32) -> bool { 1863 self.remove_scanner_callback(callback_id) 1864 } 1865 register_scanner(&mut self, callback_id: u32) -> Uuid128Bit1866 fn register_scanner(&mut self, callback_id: u32) -> Uuid128Bit { 1867 let mut bytes: [u8; 16] = [0; 16]; 1868 self.small_rng.fill_bytes(&mut bytes); 1869 let uuid = Uuid::from(bytes); 1870 1871 self.scanners.lock().unwrap().insert(uuid, ScannerInfo::new(callback_id)); 1872 1873 // libbluetooth's register_scanner takes a UUID of the scanning application. This UUID does 1874 // not correspond to higher level concept of "application" so we use random UUID that 1875 // functions as a unique identifier of the scanner. 1876 self.gatt.as_ref().unwrap().lock().unwrap().scanner.register_scanner(uuid); 1877 1878 uuid.uu 1879 } 1880 unregister_scanner(&mut self, scanner_id: u8) -> bool1881 fn unregister_scanner(&mut self, scanner_id: u8) -> bool { 1882 self.gatt.as_ref().unwrap().lock().unwrap().scanner.unregister(scanner_id); 1883 1884 // The unregistered scanner must also be stopped. 1885 self.stop_scan(scanner_id); 1886 1887 self.scanners 1888 .lock() 1889 .unwrap() 1890 .retain(|_uuid, scanner| scanner.scanner_id != Some(scanner_id)); 1891 1892 true 1893 } 1894 start_scan( &mut self, scanner_id: u8, _settings: ScanSettings, filter: Option<ScanFilter>, ) -> BtStatus1895 fn start_scan( 1896 &mut self, 1897 scanner_id: u8, 1898 _settings: ScanSettings, 1899 filter: Option<ScanFilter>, 1900 ) -> BtStatus { 1901 let scan_suspend_mode = self.get_scan_suspend_mode(); 1902 if scan_suspend_mode != SuspendMode::Normal && scan_suspend_mode != SuspendMode::Resuming { 1903 return BtStatus::Busy; 1904 } 1905 1906 // Multiplexing scanners happens at this layer. The implementations of start_scan 1907 // and stop_scan maintains the state of all registered scanners and based on the states 1908 // update the scanning and/or filter states of libbluetooth. 1909 { 1910 let mut scanners_lock = self.scanners.lock().unwrap(); 1911 1912 if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { 1913 scanner.is_active = true; 1914 scanner.filter = filter.clone(); 1915 } else { 1916 log::warn!("Scanner {} not found", scanner_id); 1917 return BtStatus::Fail; 1918 } 1919 } 1920 1921 return self.add_monitor_and_update_scan(scanner_id, filter); 1922 } 1923 stop_scan(&mut self, scanner_id: u8) -> BtStatus1924 fn stop_scan(&mut self, scanner_id: u8) -> BtStatus { 1925 let scan_suspend_mode = self.get_scan_suspend_mode(); 1926 if scan_suspend_mode != SuspendMode::Normal && scan_suspend_mode != SuspendMode::Suspending 1927 { 1928 return BtStatus::Busy; 1929 } 1930 1931 let monitor_handle = { 1932 let mut scanners_lock = self.scanners.lock().unwrap(); 1933 1934 if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { 1935 scanner.is_active = false; 1936 scanner.monitor_handle 1937 } else { 1938 log::warn!("Scanner {} not found", scanner_id); 1939 // Clients can assume success of the removal since the scanner does not exist. 1940 return BtStatus::Success; 1941 } 1942 }; 1943 1944 let has_active_unfiltered_scanner = self 1945 .scanners 1946 .lock() 1947 .unwrap() 1948 .iter() 1949 .any(|(_uuid, scanner)| scanner.is_active && scanner.filter.is_none()); 1950 1951 let gatt_async = self.gatt_async.clone(); 1952 let is_msft_supported = self.is_msft_supported(); 1953 tokio::spawn(async move { 1954 // The two operations below (monitor remove, update scan) happen one after another, and 1955 // cannot be interleaved with other GATT async operations. 1956 // So acquire the GATT async lock in the beginning of this block and will be released 1957 // at the end of this block. 1958 let mut gatt_async = gatt_async.lock().await; 1959 1960 // Remove and disable the monitor only when the MSFT extension is supported. 1961 if is_msft_supported { 1962 if let Some(handle) = monitor_handle { 1963 let _res = gatt_async.msft_adv_monitor_remove(handle).await; 1964 } 1965 1966 if !gatt_async 1967 .msft_adv_monitor_enable(!has_active_unfiltered_scanner) 1968 .await 1969 .map_or(false, |status| status == 0) 1970 { 1971 log::error!("Error updating Advertisement Monitor enable"); 1972 } 1973 } 1974 1975 gatt_async.update_scan().await; 1976 }); 1977 1978 BtStatus::Success 1979 } 1980 get_scan_suspend_mode(&self) -> SuspendMode1981 fn get_scan_suspend_mode(&self) -> SuspendMode { 1982 self.scan_suspend_mode.clone() 1983 } 1984 1985 // Advertising 1986 register_advertiser_callback( &mut self, callback: Box<dyn IAdvertisingSetCallback + Send>, ) -> u321987 fn register_advertiser_callback( 1988 &mut self, 1989 callback: Box<dyn IAdvertisingSetCallback + Send>, 1990 ) -> u32 { 1991 self.advertisers.add_callback(callback) 1992 } 1993 unregister_advertiser_callback(&mut self, callback_id: u32)1994 fn unregister_advertiser_callback(&mut self, callback_id: u32) { 1995 self.advertisers 1996 .remove_callback(callback_id, &mut self.gatt.as_ref().unwrap().lock().unwrap()); 1997 } 1998 start_advertising_set( &mut self, parameters: AdvertisingSetParameters, advertise_data: AdvertiseData, scan_response: Option<AdvertiseData>, periodic_parameters: Option<PeriodicAdvertisingParameters>, periodic_data: Option<AdvertiseData>, duration: i32, max_ext_adv_events: i32, callback_id: u32, ) -> i321999 fn start_advertising_set( 2000 &mut self, 2001 parameters: AdvertisingSetParameters, 2002 advertise_data: AdvertiseData, 2003 scan_response: Option<AdvertiseData>, 2004 periodic_parameters: Option<PeriodicAdvertisingParameters>, 2005 periodic_data: Option<AdvertiseData>, 2006 duration: i32, 2007 max_ext_adv_events: i32, 2008 callback_id: u32, 2009 ) -> i32 { 2010 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2011 return INVALID_REG_ID; 2012 } 2013 2014 let device_name = self.get_adapter_name(); 2015 let params = parameters.into(); 2016 let adv_bytes = advertise_data.make_with(&device_name); 2017 let scan_bytes = 2018 if let Some(d) = scan_response { d.make_with(&device_name) } else { Vec::<u8>::new() }; 2019 let periodic_params = if let Some(p) = periodic_parameters { 2020 p.into() 2021 } else { 2022 bt_topshim::profiles::gatt::PeriodicAdvertisingParameters::default() 2023 }; 2024 let periodic_bytes = 2025 if let Some(d) = periodic_data { d.make_with(&device_name) } else { Vec::<u8>::new() }; 2026 let adv_timeout = clamp(duration, 0, 0xffff) as u16; 2027 let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8; 2028 2029 let s = AdvertisingSetInfo::new(callback_id, adv_timeout, adv_events); 2030 let reg_id = s.reg_id(); 2031 self.advertisers.add(s); 2032 2033 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.start_advertising_set( 2034 reg_id, 2035 params, 2036 adv_bytes, 2037 scan_bytes, 2038 periodic_params, 2039 periodic_bytes, 2040 adv_timeout, 2041 adv_events, 2042 ); 2043 reg_id 2044 } 2045 stop_advertising_set(&mut self, advertiser_id: i32)2046 fn stop_advertising_set(&mut self, advertiser_id: i32) { 2047 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2048 return; 2049 } 2050 2051 let s = self.advertisers.get_by_advertiser_id(advertiser_id); 2052 if None == s { 2053 return; 2054 } 2055 let s = s.unwrap().clone(); 2056 2057 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.unregister(s.adv_id()); 2058 2059 if let Some(cb) = self.advertisers.get_callback(&s) { 2060 cb.on_advertising_set_stopped(advertiser_id); 2061 } 2062 self.advertisers.remove_by_advertiser_id(advertiser_id); 2063 } 2064 get_own_address(&mut self, advertiser_id: i32)2065 fn get_own_address(&mut self, advertiser_id: i32) { 2066 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2067 return; 2068 } 2069 2070 if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { 2071 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.get_own_address(s.adv_id()); 2072 } 2073 } 2074 enable_advertising_set( &mut self, advertiser_id: i32, enable: bool, duration: i32, max_ext_adv_events: i32, )2075 fn enable_advertising_set( 2076 &mut self, 2077 advertiser_id: i32, 2078 enable: bool, 2079 duration: i32, 2080 max_ext_adv_events: i32, 2081 ) { 2082 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2083 return; 2084 } 2085 2086 let adv_timeout = clamp(duration, 0, 0xffff) as u16; 2087 let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8; 2088 2089 if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { 2090 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( 2091 s.adv_id(), 2092 enable, 2093 adv_timeout, 2094 adv_events, 2095 ); 2096 } 2097 } 2098 set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)2099 fn set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) { 2100 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2101 return; 2102 } 2103 2104 let device_name = self.get_adapter_name(); 2105 let bytes = data.make_with(&device_name); 2106 2107 if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { 2108 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.set_data( 2109 s.adv_id(), 2110 false, 2111 bytes, 2112 ); 2113 } 2114 } 2115 set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>)2116 fn set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>) { 2117 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2118 return; 2119 } 2120 2121 if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { 2122 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.set_data( 2123 s.adv_id(), 2124 false, 2125 data, 2126 ); 2127 } 2128 } 2129 set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData)2130 fn set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData) { 2131 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2132 return; 2133 } 2134 2135 let device_name = self.get_adapter_name(); 2136 let bytes = data.make_with(&device_name); 2137 2138 if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { 2139 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.set_data( 2140 s.adv_id(), 2141 true, 2142 bytes, 2143 ); 2144 } 2145 } 2146 set_advertising_parameters( &mut self, advertiser_id: i32, parameters: AdvertisingSetParameters, )2147 fn set_advertising_parameters( 2148 &mut self, 2149 advertiser_id: i32, 2150 parameters: AdvertisingSetParameters, 2151 ) { 2152 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2153 return; 2154 } 2155 2156 let params = parameters.into(); 2157 2158 if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { 2159 let was_enabled = s.is_enabled(); 2160 if was_enabled { 2161 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( 2162 s.adv_id(), 2163 false, 2164 s.adv_timeout(), 2165 s.adv_events(), 2166 ); 2167 } 2168 self.gatt 2169 .as_ref() 2170 .unwrap() 2171 .lock() 2172 .unwrap() 2173 .advertiser 2174 .set_parameters(s.adv_id(), params); 2175 if was_enabled { 2176 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( 2177 s.adv_id(), 2178 true, 2179 s.adv_timeout(), 2180 s.adv_events(), 2181 ); 2182 } 2183 } 2184 } 2185 set_periodic_advertising_parameters( &mut self, advertiser_id: i32, parameters: PeriodicAdvertisingParameters, )2186 fn set_periodic_advertising_parameters( 2187 &mut self, 2188 advertiser_id: i32, 2189 parameters: PeriodicAdvertisingParameters, 2190 ) { 2191 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2192 return; 2193 } 2194 2195 let params = parameters.into(); 2196 2197 if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { 2198 self.gatt 2199 .as_ref() 2200 .unwrap() 2201 .lock() 2202 .unwrap() 2203 .advertiser 2204 .set_periodic_advertising_parameters(s.adv_id(), params); 2205 } 2206 } 2207 set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)2208 fn set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) { 2209 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2210 return; 2211 } 2212 2213 let device_name = self.get_adapter_name(); 2214 let bytes = data.make_with(&device_name); 2215 2216 if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { 2217 self.gatt 2218 .as_ref() 2219 .unwrap() 2220 .lock() 2221 .unwrap() 2222 .advertiser 2223 .set_periodic_advertising_data(s.adv_id(), bytes); 2224 } 2225 } 2226 set_periodic_advertising_enable( &mut self, advertiser_id: i32, enable: bool, include_adi: bool, )2227 fn set_periodic_advertising_enable( 2228 &mut self, 2229 advertiser_id: i32, 2230 enable: bool, 2231 include_adi: bool, 2232 ) { 2233 if self.advertisers.suspend_mode() != SuspendMode::Normal { 2234 return; 2235 } 2236 if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { 2237 self.gatt.as_ref().unwrap().lock().unwrap().advertiser.set_periodic_advertising_enable( 2238 s.adv_id(), 2239 enable, 2240 include_adi, 2241 ); 2242 } 2243 } 2244 2245 // GATT Client 2246 register_client( &mut self, app_uuid: String, callback: Box<dyn IBluetoothGattCallback + Send>, eatt_support: bool, )2247 fn register_client( 2248 &mut self, 2249 app_uuid: String, 2250 callback: Box<dyn IBluetoothGattCallback + Send>, 2251 eatt_support: bool, 2252 ) { 2253 let uuid = match UuidHelper::parse_string(&app_uuid) { 2254 Some(id) => id, 2255 None => { 2256 log::info!("Uuid is malformed: {}", app_uuid); 2257 return; 2258 } 2259 }; 2260 self.context_map.add(&uuid.uu, callback); 2261 self.gatt 2262 .as_ref() 2263 .expect("GATT has not been initialized") 2264 .lock() 2265 .unwrap() 2266 .client 2267 .register_client(&uuid, eatt_support); 2268 } 2269 unregister_client(&mut self, client_id: i32)2270 fn unregister_client(&mut self, client_id: i32) { 2271 self.context_map.remove(client_id); 2272 self.gatt.as_ref().unwrap().lock().unwrap().client.unregister_client(client_id); 2273 } 2274 client_connect( &self, client_id: i32, addr: String, is_direct: bool, transport: BtTransport, opportunistic: bool, phy: LePhy, )2275 fn client_connect( 2276 &self, 2277 client_id: i32, 2278 addr: String, 2279 is_direct: bool, 2280 transport: BtTransport, 2281 opportunistic: bool, 2282 phy: LePhy, 2283 ) { 2284 let address = match RawAddress::from_string(addr.clone()) { 2285 None => return, 2286 Some(addr) => addr, 2287 }; 2288 2289 self.gatt.as_ref().unwrap().lock().unwrap().client.connect( 2290 client_id, 2291 &address, 2292 // Addr type is default PUBLIC. 2293 0, 2294 is_direct, 2295 transport.into(), 2296 opportunistic, 2297 phy.into(), 2298 ); 2299 } 2300 client_disconnect(&self, client_id: i32, address: String)2301 fn client_disconnect(&self, client_id: i32, address: String) { 2302 let conn_id = self.context_map.get_conn_id_from_address(client_id, &address); 2303 if conn_id.is_none() { 2304 return; 2305 } 2306 2307 self.gatt.as_ref().unwrap().lock().unwrap().client.disconnect( 2308 client_id, 2309 &RawAddress::from_string(address).unwrap(), 2310 conn_id.unwrap(), 2311 ); 2312 } 2313 refresh_device(&self, client_id: i32, addr: String)2314 fn refresh_device(&self, client_id: i32, addr: String) { 2315 self.gatt 2316 .as_ref() 2317 .unwrap() 2318 .lock() 2319 .unwrap() 2320 .client 2321 .refresh(client_id, &RawAddress::from_string(addr).unwrap()); 2322 } 2323 discover_services(&self, client_id: i32, addr: String)2324 fn discover_services(&self, client_id: i32, addr: String) { 2325 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2326 if conn_id.is_none() { 2327 return; 2328 } 2329 2330 self.gatt.as_ref().unwrap().lock().unwrap().client.search_service(conn_id.unwrap(), None); 2331 } 2332 discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String)2333 fn discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String) { 2334 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2335 if conn_id.is_none() { 2336 return; 2337 } 2338 2339 let uuid = UuidHelper::parse_string(uuid); 2340 if uuid.is_none() { 2341 return; 2342 } 2343 2344 self.gatt.as_ref().unwrap().lock().unwrap().client.search_service(conn_id.unwrap(), uuid); 2345 } 2346 btif_gattc_discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String)2347 fn btif_gattc_discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String) { 2348 let conn_id = match self.context_map.get_conn_id_from_address(client_id, &addr) { 2349 None => return, 2350 Some(id) => id, 2351 }; 2352 2353 let uuid = match UuidHelper::parse_string(uuid) { 2354 None => return, 2355 Some(uuid) => uuid, 2356 }; 2357 2358 self.gatt 2359 .as_ref() 2360 .unwrap() 2361 .lock() 2362 .unwrap() 2363 .client 2364 .btif_gattc_discover_service_by_uuid(conn_id, &uuid); 2365 } 2366 read_characteristic(&self, client_id: i32, addr: String, handle: i32, auth_req: i32)2367 fn read_characteristic(&self, client_id: i32, addr: String, handle: i32, auth_req: i32) { 2368 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2369 if conn_id.is_none() { 2370 return; 2371 } 2372 2373 // TODO(b/200065274): Perform check on restricted handles. 2374 2375 self.gatt.as_ref().unwrap().lock().unwrap().client.read_characteristic( 2376 conn_id.unwrap(), 2377 handle as u16, 2378 auth_req, 2379 ); 2380 } 2381 read_using_characteristic_uuid( &self, client_id: i32, addr: String, uuid: String, start_handle: i32, end_handle: i32, auth_req: i32, )2382 fn read_using_characteristic_uuid( 2383 &self, 2384 client_id: i32, 2385 addr: String, 2386 uuid: String, 2387 start_handle: i32, 2388 end_handle: i32, 2389 auth_req: i32, 2390 ) { 2391 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2392 if conn_id.is_none() { 2393 return; 2394 } 2395 2396 let uuid = UuidHelper::parse_string(uuid); 2397 if uuid.is_none() { 2398 return; 2399 } 2400 2401 // TODO(b/200065274): Perform check on restricted handles. 2402 2403 self.gatt.as_ref().unwrap().lock().unwrap().client.read_using_characteristic_uuid( 2404 conn_id.unwrap(), 2405 &uuid.unwrap(), 2406 start_handle as u16, 2407 end_handle as u16, 2408 auth_req, 2409 ); 2410 } 2411 write_characteristic( &self, client_id: i32, addr: String, handle: i32, mut write_type: GattWriteType, auth_req: i32, value: Vec<u8>, ) -> GattWriteRequestStatus2412 fn write_characteristic( 2413 &self, 2414 client_id: i32, 2415 addr: String, 2416 handle: i32, 2417 mut write_type: GattWriteType, 2418 auth_req: i32, 2419 value: Vec<u8>, 2420 ) -> GattWriteRequestStatus { 2421 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2422 if conn_id.is_none() { 2423 return GattWriteRequestStatus::Fail; 2424 } 2425 2426 if self.reliable_queue.contains(&addr) { 2427 write_type = GattWriteType::WritePrepare; 2428 } 2429 2430 // TODO(b/200065274): Perform check on restricted handles. 2431 2432 // TODO(b/200070162): Handle concurrent write characteristic. 2433 2434 self.gatt.as_ref().unwrap().lock().unwrap().client.write_characteristic( 2435 conn_id.unwrap(), 2436 handle as u16, 2437 write_type.to_i32().unwrap(), 2438 auth_req, 2439 &value, 2440 ); 2441 2442 return GattWriteRequestStatus::Success; 2443 } 2444 read_descriptor(&self, client_id: i32, addr: String, handle: i32, auth_req: i32)2445 fn read_descriptor(&self, client_id: i32, addr: String, handle: i32, auth_req: i32) { 2446 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2447 if conn_id.is_none() { 2448 return; 2449 } 2450 2451 // TODO(b/200065274): Perform check on restricted handles. 2452 2453 self.gatt.as_ref().unwrap().lock().unwrap().client.read_descriptor( 2454 conn_id.unwrap(), 2455 handle as u16, 2456 auth_req, 2457 ); 2458 } 2459 write_descriptor( &self, client_id: i32, addr: String, handle: i32, auth_req: i32, value: Vec<u8>, )2460 fn write_descriptor( 2461 &self, 2462 client_id: i32, 2463 addr: String, 2464 handle: i32, 2465 auth_req: i32, 2466 value: Vec<u8>, 2467 ) { 2468 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2469 if conn_id.is_none() { 2470 return; 2471 } 2472 2473 // TODO(b/200065274): Perform check on restricted handles. 2474 2475 self.gatt.as_ref().unwrap().lock().unwrap().client.write_descriptor( 2476 conn_id.unwrap(), 2477 handle as u16, 2478 auth_req, 2479 &value, 2480 ); 2481 } 2482 register_for_notification(&self, client_id: i32, addr: String, handle: i32, enable: bool)2483 fn register_for_notification(&self, client_id: i32, addr: String, handle: i32, enable: bool) { 2484 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2485 if conn_id.is_none() { 2486 return; 2487 } 2488 2489 // TODO(b/200065274): Perform check on restricted handles. 2490 2491 if enable { 2492 self.gatt.as_ref().unwrap().lock().unwrap().client.register_for_notification( 2493 client_id, 2494 &RawAddress::from_string(addr).unwrap(), 2495 handle as u16, 2496 ); 2497 } else { 2498 self.gatt.as_ref().unwrap().lock().unwrap().client.deregister_for_notification( 2499 client_id, 2500 &RawAddress::from_string(addr).unwrap(), 2501 handle as u16, 2502 ); 2503 } 2504 } 2505 begin_reliable_write(&mut self, _client_id: i32, addr: String)2506 fn begin_reliable_write(&mut self, _client_id: i32, addr: String) { 2507 self.reliable_queue.insert(addr); 2508 } 2509 end_reliable_write(&mut self, client_id: i32, addr: String, execute: bool)2510 fn end_reliable_write(&mut self, client_id: i32, addr: String, execute: bool) { 2511 self.reliable_queue.remove(&addr); 2512 2513 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2514 if conn_id.is_none() { 2515 return; 2516 } 2517 2518 self.gatt 2519 .as_ref() 2520 .unwrap() 2521 .lock() 2522 .unwrap() 2523 .client 2524 .execute_write(conn_id.unwrap(), if execute { 1 } else { 0 }); 2525 } 2526 read_remote_rssi(&self, client_id: i32, addr: String)2527 fn read_remote_rssi(&self, client_id: i32, addr: String) { 2528 self.gatt 2529 .as_ref() 2530 .unwrap() 2531 .lock() 2532 .unwrap() 2533 .client 2534 .read_remote_rssi(client_id, &RawAddress::from_string(addr).unwrap()); 2535 } 2536 configure_mtu(&self, client_id: i32, addr: String, mtu: i32)2537 fn configure_mtu(&self, client_id: i32, addr: String, mtu: i32) { 2538 let conn_id = self.context_map.get_conn_id_from_address(client_id, &addr); 2539 if conn_id.is_none() { 2540 return; 2541 } 2542 2543 self.gatt.as_ref().unwrap().lock().unwrap().client.configure_mtu(conn_id.unwrap(), mtu); 2544 } 2545 connection_parameter_update( &self, _client_id: i32, addr: String, min_interval: i32, max_interval: i32, latency: i32, timeout: i32, min_ce_len: u16, max_ce_len: u16, )2546 fn connection_parameter_update( 2547 &self, 2548 _client_id: i32, 2549 addr: String, 2550 min_interval: i32, 2551 max_interval: i32, 2552 latency: i32, 2553 timeout: i32, 2554 min_ce_len: u16, 2555 max_ce_len: u16, 2556 ) { 2557 self.gatt.as_ref().unwrap().lock().unwrap().client.conn_parameter_update( 2558 &RawAddress::from_string(addr).unwrap(), 2559 min_interval, 2560 max_interval, 2561 latency, 2562 timeout, 2563 min_ce_len, 2564 max_ce_len, 2565 ); 2566 } 2567 client_set_preferred_phy( &self, client_id: i32, address: String, tx_phy: LePhy, rx_phy: LePhy, phy_options: i32, )2568 fn client_set_preferred_phy( 2569 &self, 2570 client_id: i32, 2571 address: String, 2572 tx_phy: LePhy, 2573 rx_phy: LePhy, 2574 phy_options: i32, 2575 ) { 2576 let conn_id = self.context_map.get_conn_id_from_address(client_id, &address); 2577 if conn_id.is_none() { 2578 return; 2579 } 2580 2581 self.gatt.as_ref().unwrap().lock().unwrap().client.set_preferred_phy( 2582 &RawAddress::from_string(address).unwrap(), 2583 tx_phy.to_u8().unwrap(), 2584 rx_phy.to_u8().unwrap(), 2585 phy_options as u16, 2586 ); 2587 } 2588 client_read_phy(&mut self, client_id: i32, addr: String)2589 fn client_read_phy(&mut self, client_id: i32, addr: String) { 2590 let address = match RawAddress::from_string(addr.clone()) { 2591 None => return, 2592 Some(addr) => addr, 2593 }; 2594 2595 self.gatt.as_ref().unwrap().lock().unwrap().client.read_phy(client_id, &address); 2596 } 2597 2598 // GATT Server 2599 register_server( &mut self, app_uuid: String, callback: Box<dyn IBluetoothGattServerCallback + Send>, eatt_support: bool, )2600 fn register_server( 2601 &mut self, 2602 app_uuid: String, 2603 callback: Box<dyn IBluetoothGattServerCallback + Send>, 2604 eatt_support: bool, 2605 ) { 2606 let uuid = match UuidHelper::parse_string(&app_uuid) { 2607 Some(id) => id, 2608 None => { 2609 log::info!("Uuid is malformed: {}", app_uuid); 2610 return; 2611 } 2612 }; 2613 self.server_context_map.add(&uuid.uu, callback); 2614 self.gatt 2615 .as_ref() 2616 .expect("GATT has not been initialized") 2617 .lock() 2618 .unwrap() 2619 .server 2620 .register_server(&uuid, eatt_support); 2621 } 2622 unregister_server(&mut self, server_id: i32)2623 fn unregister_server(&mut self, server_id: i32) { 2624 self.server_context_map.remove(server_id); 2625 self.gatt.as_ref().unwrap().lock().unwrap().server.unregister_server(server_id); 2626 } 2627 server_connect( &self, server_id: i32, addr: String, is_direct: bool, transport: BtTransport, ) -> bool2628 fn server_connect( 2629 &self, 2630 server_id: i32, 2631 addr: String, 2632 is_direct: bool, 2633 transport: BtTransport, 2634 ) -> bool { 2635 let address = match RawAddress::from_string(addr.clone()) { 2636 None => return false, 2637 Some(addr) => addr, 2638 }; 2639 2640 self.gatt.as_ref().unwrap().lock().unwrap().server.connect( 2641 server_id, 2642 &address, 2643 is_direct, 2644 transport.into(), 2645 ); 2646 2647 true 2648 } 2649 server_disconnect(&self, server_id: i32, addr: String) -> bool2650 fn server_disconnect(&self, server_id: i32, addr: String) -> bool { 2651 let address = match RawAddress::from_string(addr.clone()) { 2652 None => return false, 2653 Some(addr) => addr, 2654 }; 2655 2656 let conn_id = match self.server_context_map.get_conn_id_from_address(server_id, &addr) { 2657 None => return false, 2658 Some(id) => id, 2659 }; 2660 2661 self.gatt.as_ref().unwrap().lock().unwrap().server.disconnect(server_id, &address, conn_id); 2662 2663 true 2664 } 2665 add_service(&self, server_id: i32, service: BluetoothGattService)2666 fn add_service(&self, server_id: i32, service: BluetoothGattService) { 2667 self.gatt 2668 .as_ref() 2669 .unwrap() 2670 .lock() 2671 .unwrap() 2672 .server 2673 .add_service(server_id, &BluetoothGattService::into_db(service)); 2674 } 2675 remove_service(&self, server_id: i32, handle: i32)2676 fn remove_service(&self, server_id: i32, handle: i32) { 2677 self.gatt.as_ref().unwrap().lock().unwrap().server.delete_service(server_id, handle); 2678 } 2679 clear_services(&self, server_id: i32)2680 fn clear_services(&self, server_id: i32) { 2681 if let Some(s) = self.server_context_map.get_by_server_id(server_id) { 2682 for service in &s.services { 2683 self.gatt 2684 .as_ref() 2685 .unwrap() 2686 .lock() 2687 .unwrap() 2688 .server 2689 .delete_service(server_id, service.instance_id); 2690 } 2691 } 2692 } 2693 send_response( &self, server_id: i32, addr: String, request_id: i32, status: GattStatus, offset: i32, value: Vec<u8>, ) -> bool2694 fn send_response( 2695 &self, 2696 server_id: i32, 2697 addr: String, 2698 request_id: i32, 2699 status: GattStatus, 2700 offset: i32, 2701 value: Vec<u8>, 2702 ) -> bool { 2703 (|| { 2704 let conn_id = self.server_context_map.get_conn_id_from_address(server_id, &addr)?; 2705 let handle = self.server_context_map.get_request_handle_from_id(request_id)?; 2706 let len = value.len() as u16; 2707 2708 let data: [u8; 600] = array_utils::to_sized_array(&value); 2709 2710 self.gatt.as_ref().unwrap().lock().unwrap().server.send_response( 2711 conn_id, 2712 request_id, 2713 status as i32, 2714 &BtGattResponse { 2715 attr_value: BtGattValue { 2716 value: data, 2717 handle: handle as u16, 2718 offset: offset as u16, 2719 len, 2720 auth_req: 0 as u8, 2721 }, 2722 }, 2723 ); 2724 2725 Some(()) 2726 })() 2727 .is_some() 2728 } 2729 send_notification( &self, server_id: i32, addr: String, handle: i32, confirm: bool, value: Vec<u8>, ) -> bool2730 fn send_notification( 2731 &self, 2732 server_id: i32, 2733 addr: String, 2734 handle: i32, 2735 confirm: bool, 2736 value: Vec<u8>, 2737 ) -> bool { 2738 let conn_id = match self.server_context_map.get_conn_id_from_address(server_id, &addr) { 2739 None => return false, 2740 Some(id) => id, 2741 }; 2742 2743 self.gatt.as_ref().unwrap().lock().unwrap().server.send_indication( 2744 server_id, 2745 handle, 2746 conn_id, 2747 confirm as i32, 2748 value.as_ref(), 2749 ); 2750 2751 true 2752 } 2753 server_set_preferred_phy( &self, _server_id: i32, addr: String, tx_phy: LePhy, rx_phy: LePhy, phy_options: i32, )2754 fn server_set_preferred_phy( 2755 &self, 2756 _server_id: i32, 2757 addr: String, 2758 tx_phy: LePhy, 2759 rx_phy: LePhy, 2760 phy_options: i32, 2761 ) { 2762 (|| { 2763 let address = RawAddress::from_string(addr)?; 2764 2765 self.gatt.as_ref().unwrap().lock().unwrap().server.set_preferred_phy( 2766 &address, 2767 tx_phy.to_u8().unwrap_or_default(), 2768 rx_phy.to_u8().unwrap_or_default(), 2769 phy_options as u16, 2770 ); 2771 2772 Some(()) 2773 })(); 2774 } 2775 server_read_phy(&self, server_id: i32, addr: String)2776 fn server_read_phy(&self, server_id: i32, addr: String) { 2777 if let Some(address) = RawAddress::from_string(addr.clone()) { 2778 self.gatt.as_ref().unwrap().lock().unwrap().server.read_phy(server_id, &address); 2779 } 2780 } 2781 } 2782 2783 #[btif_callbacks_dispatcher(dispatch_gatt_client_callbacks, GattClientCallbacks)] 2784 pub(crate) trait BtifGattClientCallbacks { 2785 #[btif_callback(RegisterClient)] register_client_cb(&mut self, status: GattStatus, client_id: i32, app_uuid: Uuid)2786 fn register_client_cb(&mut self, status: GattStatus, client_id: i32, app_uuid: Uuid); 2787 2788 #[btif_callback(Connect)] connect_cb(&mut self, conn_id: i32, status: GattStatus, client_id: i32, addr: RawAddress)2789 fn connect_cb(&mut self, conn_id: i32, status: GattStatus, client_id: i32, addr: RawAddress); 2790 2791 #[btif_callback(Disconnect)] disconnect_cb(&mut self, conn_id: i32, status: GattStatus, client_id: i32, addr: RawAddress)2792 fn disconnect_cb(&mut self, conn_id: i32, status: GattStatus, client_id: i32, addr: RawAddress); 2793 2794 #[btif_callback(SearchComplete)] search_complete_cb(&mut self, conn_id: i32, status: GattStatus)2795 fn search_complete_cb(&mut self, conn_id: i32, status: GattStatus); 2796 2797 #[btif_callback(RegisterForNotification)] register_for_notification_cb( &mut self, conn_id: i32, registered: i32, status: GattStatus, handle: u16, )2798 fn register_for_notification_cb( 2799 &mut self, 2800 conn_id: i32, 2801 registered: i32, 2802 status: GattStatus, 2803 handle: u16, 2804 ); 2805 2806 #[btif_callback(Notify)] notify_cb(&mut self, conn_id: i32, data: BtGattNotifyParams)2807 fn notify_cb(&mut self, conn_id: i32, data: BtGattNotifyParams); 2808 2809 #[btif_callback(ReadCharacteristic)] read_characteristic_cb(&mut self, conn_id: i32, status: GattStatus, data: BtGattReadParams)2810 fn read_characteristic_cb(&mut self, conn_id: i32, status: GattStatus, data: BtGattReadParams); 2811 2812 #[btif_callback(WriteCharacteristic)] write_characteristic_cb( &mut self, conn_id: i32, status: GattStatus, handle: u16, len: u16, value: *const u8, )2813 fn write_characteristic_cb( 2814 &mut self, 2815 conn_id: i32, 2816 status: GattStatus, 2817 handle: u16, 2818 len: u16, 2819 value: *const u8, 2820 ); 2821 2822 #[btif_callback(ReadDescriptor)] read_descriptor_cb(&mut self, conn_id: i32, status: GattStatus, data: BtGattReadParams)2823 fn read_descriptor_cb(&mut self, conn_id: i32, status: GattStatus, data: BtGattReadParams); 2824 2825 #[btif_callback(WriteDescriptor)] write_descriptor_cb( &mut self, conn_id: i32, status: GattStatus, handle: u16, len: u16, value: *const u8, )2826 fn write_descriptor_cb( 2827 &mut self, 2828 conn_id: i32, 2829 status: GattStatus, 2830 handle: u16, 2831 len: u16, 2832 value: *const u8, 2833 ); 2834 2835 #[btif_callback(ExecuteWrite)] execute_write_cb(&mut self, conn_id: i32, status: GattStatus)2836 fn execute_write_cb(&mut self, conn_id: i32, status: GattStatus); 2837 2838 #[btif_callback(ReadRemoteRssi)] read_remote_rssi_cb( &mut self, client_id: i32, addr: RawAddress, rssi: i32, status: GattStatus, )2839 fn read_remote_rssi_cb( 2840 &mut self, 2841 client_id: i32, 2842 addr: RawAddress, 2843 rssi: i32, 2844 status: GattStatus, 2845 ); 2846 2847 #[btif_callback(ConfigureMtu)] configure_mtu_cb(&mut self, conn_id: i32, status: GattStatus, mtu: i32)2848 fn configure_mtu_cb(&mut self, conn_id: i32, status: GattStatus, mtu: i32); 2849 2850 #[btif_callback(Congestion)] congestion_cb(&mut self, conn_id: i32, congested: bool)2851 fn congestion_cb(&mut self, conn_id: i32, congested: bool); 2852 2853 #[btif_callback(GetGattDb)] get_gatt_db_cb(&mut self, conn_id: i32, elements: Vec<BtGattDbElement>, count: i32)2854 fn get_gatt_db_cb(&mut self, conn_id: i32, elements: Vec<BtGattDbElement>, count: i32); 2855 2856 #[btif_callback(PhyUpdated)] phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: GattStatus)2857 fn phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: GattStatus); 2858 2859 #[btif_callback(ConnUpdated)] conn_updated_cb( &mut self, conn_id: i32, interval: u16, latency: u16, timeout: u16, status: GattStatus, )2860 fn conn_updated_cb( 2861 &mut self, 2862 conn_id: i32, 2863 interval: u16, 2864 latency: u16, 2865 timeout: u16, 2866 status: GattStatus, 2867 ); 2868 2869 #[btif_callback(ServiceChanged)] service_changed_cb(&mut self, conn_id: i32)2870 fn service_changed_cb(&mut self, conn_id: i32); 2871 2872 #[btif_callback(ReadPhy)] read_phy_cb( &mut self, client_id: i32, addr: RawAddress, tx_phy: u8, rx_phy: u8, status: GattStatus, )2873 fn read_phy_cb( 2874 &mut self, 2875 client_id: i32, 2876 addr: RawAddress, 2877 tx_phy: u8, 2878 rx_phy: u8, 2879 status: GattStatus, 2880 ); 2881 } 2882 2883 impl BtifGattClientCallbacks for BluetoothGatt { register_client_cb(&mut self, status: GattStatus, client_id: i32, app_uuid: Uuid)2884 fn register_client_cb(&mut self, status: GattStatus, client_id: i32, app_uuid: Uuid) { 2885 self.context_map.set_client_id(&app_uuid.uu, client_id); 2886 2887 let client = self.context_map.get_by_uuid(&app_uuid.uu); 2888 match client { 2889 Some(c) => { 2890 let cbid = c.cbid; 2891 self.context_map.get_callback_from_callback_id(cbid).and_then( 2892 |cb: &mut GattClientCallback| { 2893 cb.on_client_registered(status, client_id); 2894 Some(()) 2895 }, 2896 ); 2897 } 2898 None => { 2899 warn!("Warning: Client not registered for UUID {}", app_uuid); 2900 } 2901 } 2902 } 2903 connect_cb(&mut self, conn_id: i32, status: GattStatus, client_id: i32, addr: RawAddress)2904 fn connect_cb(&mut self, conn_id: i32, status: GattStatus, client_id: i32, addr: RawAddress) { 2905 if status == GattStatus::Success { 2906 self.context_map.add_connection(client_id, conn_id, &addr.to_string()); 2907 } 2908 2909 let client = self.context_map.get_by_client_id(client_id); 2910 if let Some(c) = client { 2911 let cbid = c.cbid; 2912 self.context_map.get_callback_from_callback_id(cbid).and_then( 2913 |cb: &mut GattClientCallback| { 2914 cb.on_client_connection_state( 2915 status, 2916 client_id, 2917 status == GattStatus::Success, 2918 addr.to_string(), 2919 ); 2920 Some(()) 2921 }, 2922 ); 2923 } 2924 } 2925 disconnect_cb( &mut self, conn_id: i32, status: GattStatus, client_id: i32, addr: RawAddress, )2926 fn disconnect_cb( 2927 &mut self, 2928 conn_id: i32, 2929 status: GattStatus, 2930 client_id: i32, 2931 addr: RawAddress, 2932 ) { 2933 let client = self.context_map.get_by_client_id(client_id); 2934 if let Some(c) = client { 2935 let cbid = c.cbid; 2936 self.context_map.get_callback_from_callback_id(cbid).and_then( 2937 |cb: &mut GattClientCallback| { 2938 cb.on_client_connection_state(status, client_id, false, addr.to_string()); 2939 Some(()) 2940 }, 2941 ); 2942 } 2943 self.context_map.remove_connection(client_id, conn_id); 2944 } 2945 search_complete_cb(&mut self, conn_id: i32, _status: GattStatus)2946 fn search_complete_cb(&mut self, conn_id: i32, _status: GattStatus) { 2947 // Gatt DB is ready! 2948 self.gatt.as_ref().unwrap().lock().unwrap().client.get_gatt_db(conn_id); 2949 } 2950 register_for_notification_cb( &mut self, _conn_id: i32, _registered: i32, _status: GattStatus, _handle: u16, )2951 fn register_for_notification_cb( 2952 &mut self, 2953 _conn_id: i32, 2954 _registered: i32, 2955 _status: GattStatus, 2956 _handle: u16, 2957 ) { 2958 // No-op. 2959 } 2960 notify_cb(&mut self, conn_id: i32, data: BtGattNotifyParams)2961 fn notify_cb(&mut self, conn_id: i32, data: BtGattNotifyParams) { 2962 let client = self.context_map.get_client_by_conn_id(conn_id); 2963 if let Some(c) = client { 2964 let cbid = c.cbid; 2965 self.context_map.get_callback_from_callback_id(cbid).and_then( 2966 |cb: &mut GattClientCallback| { 2967 cb.on_notify( 2968 data.bda.to_string(), 2969 data.handle as i32, 2970 data.value[0..data.len as usize].to_vec(), 2971 ); 2972 Some(()) 2973 }, 2974 ); 2975 } 2976 } 2977 read_characteristic_cb(&mut self, conn_id: i32, status: GattStatus, data: BtGattReadParams)2978 fn read_characteristic_cb(&mut self, conn_id: i32, status: GattStatus, data: BtGattReadParams) { 2979 let address = self.context_map.get_address_by_conn_id(conn_id); 2980 if address.is_none() { 2981 return; 2982 } 2983 2984 let client = self.context_map.get_client_by_conn_id(conn_id); 2985 if let Some(c) = client { 2986 let cbid = c.cbid; 2987 self.context_map.get_callback_from_callback_id(cbid).and_then( 2988 |cb: &mut GattClientCallback| { 2989 cb.on_characteristic_read( 2990 address.unwrap().to_string(), 2991 status, 2992 data.handle as i32, 2993 data.value.value[0..data.value.len as usize].to_vec(), 2994 ); 2995 Some(()) 2996 }, 2997 ); 2998 } 2999 } 3000 write_characteristic_cb( &mut self, conn_id: i32, mut status: GattStatus, handle: u16, _len: u16, _value: *const u8, )3001 fn write_characteristic_cb( 3002 &mut self, 3003 conn_id: i32, 3004 mut status: GattStatus, 3005 handle: u16, 3006 _len: u16, 3007 _value: *const u8, 3008 ) { 3009 let address = self.context_map.get_address_by_conn_id(conn_id); 3010 if address.is_none() { 3011 return; 3012 } 3013 3014 // TODO(b/200070162): Design how to handle concurrent write characteristic to the same 3015 // peer. 3016 3017 let client = self.context_map.get_client_by_conn_id_mut(conn_id); 3018 if client.is_none() { 3019 return; 3020 } 3021 3022 match (client, address) { 3023 (Some(c), Some(addr)) => { 3024 if c.is_congested { 3025 if status == GattStatus::Congested { 3026 status = GattStatus::Success; 3027 } 3028 3029 c.congestion_queue.push((addr.to_string(), status, handle as i32)); 3030 return; 3031 } 3032 3033 let cbid = c.cbid; 3034 self.context_map.get_callback_from_callback_id(cbid).and_then( 3035 |cb: &mut GattClientCallback| { 3036 cb.on_characteristic_write(addr.to_string(), status, handle as i32); 3037 Some(()) 3038 }, 3039 ); 3040 } 3041 _ => (), 3042 }; 3043 } 3044 read_descriptor_cb(&mut self, conn_id: i32, status: GattStatus, data: BtGattReadParams)3045 fn read_descriptor_cb(&mut self, conn_id: i32, status: GattStatus, data: BtGattReadParams) { 3046 let address = self.context_map.get_address_by_conn_id(conn_id); 3047 if address.is_none() { 3048 return; 3049 } 3050 3051 let client = self.context_map.get_client_by_conn_id(conn_id); 3052 if let Some(c) = client { 3053 let cbid = c.cbid; 3054 self.context_map.get_callback_from_callback_id(cbid).and_then( 3055 |cb: &mut GattClientCallback| { 3056 cb.on_descriptor_read( 3057 address.unwrap().to_string(), 3058 status, 3059 data.handle as i32, 3060 data.value.value[0..data.value.len as usize].to_vec(), 3061 ); 3062 Some(()) 3063 }, 3064 ); 3065 } 3066 } 3067 write_descriptor_cb( &mut self, conn_id: i32, status: GattStatus, handle: u16, _len: u16, _value: *const u8, )3068 fn write_descriptor_cb( 3069 &mut self, 3070 conn_id: i32, 3071 status: GattStatus, 3072 handle: u16, 3073 _len: u16, 3074 _value: *const u8, 3075 ) { 3076 let address = self.context_map.get_address_by_conn_id(conn_id); 3077 if address.is_none() { 3078 return; 3079 } 3080 3081 let client = self.context_map.get_client_by_conn_id(conn_id); 3082 if let Some(c) = client { 3083 let cbid = c.cbid; 3084 self.context_map.get_callback_from_callback_id(cbid).and_then( 3085 |cb: &mut GattClientCallback| { 3086 cb.on_descriptor_write(address.unwrap().to_string(), status, handle as i32); 3087 Some(()) 3088 }, 3089 ); 3090 } 3091 } 3092 execute_write_cb(&mut self, conn_id: i32, status: GattStatus)3093 fn execute_write_cb(&mut self, conn_id: i32, status: GattStatus) { 3094 let address = self.context_map.get_address_by_conn_id(conn_id); 3095 if address.is_none() { 3096 return; 3097 } 3098 3099 let client = self.context_map.get_client_by_conn_id(conn_id); 3100 if let Some(c) = client { 3101 let cbid = c.cbid; 3102 self.context_map.get_callback_from_callback_id(cbid).and_then( 3103 |cb: &mut GattClientCallback| { 3104 cb.on_execute_write(address.unwrap().to_string(), status); 3105 Some(()) 3106 }, 3107 ); 3108 } 3109 } 3110 read_remote_rssi_cb( &mut self, client_id: i32, addr: RawAddress, rssi: i32, status: GattStatus, )3111 fn read_remote_rssi_cb( 3112 &mut self, 3113 client_id: i32, 3114 addr: RawAddress, 3115 rssi: i32, 3116 status: GattStatus, 3117 ) { 3118 let client = self.context_map.get_by_client_id(client_id); 3119 if let Some(c) = client { 3120 let cbid = c.cbid; 3121 self.context_map.get_callback_from_callback_id(cbid).and_then( 3122 |cb: &mut GattClientCallback| { 3123 cb.on_read_remote_rssi(addr.to_string(), rssi, status); 3124 Some(()) 3125 }, 3126 ); 3127 } 3128 } 3129 configure_mtu_cb(&mut self, conn_id: i32, status: GattStatus, mtu: i32)3130 fn configure_mtu_cb(&mut self, conn_id: i32, status: GattStatus, mtu: i32) { 3131 let client = self.context_map.get_client_by_conn_id(conn_id); 3132 let addr = self.context_map.get_address_by_conn_id(conn_id); 3133 3134 match (client, addr) { 3135 (Some(c), Some(addr)) => { 3136 let cbid = c.cbid; 3137 self.context_map.get_callback_from_callback_id(cbid).and_then( 3138 |cb: &mut GattClientCallback| { 3139 cb.on_configure_mtu(addr, mtu, status); 3140 Some(()) 3141 }, 3142 ); 3143 } 3144 _ => (), 3145 }; 3146 } 3147 congestion_cb(&mut self, conn_id: i32, congested: bool)3148 fn congestion_cb(&mut self, conn_id: i32, congested: bool) { 3149 if let Some(mut client) = self.context_map.get_client_by_conn_id_mut(conn_id) { 3150 client.is_congested = congested; 3151 if !client.is_congested { 3152 let cbid = client.cbid; 3153 let mut congestion_queue: Vec<(String, GattStatus, i32)> = vec![]; 3154 client.congestion_queue.retain(|v| { 3155 congestion_queue.push(v.clone()); 3156 false 3157 }); 3158 3159 self.context_map.get_callback_from_callback_id(cbid).and_then( 3160 |cb: &mut GattClientCallback| { 3161 for callback in congestion_queue.iter() { 3162 cb.on_characteristic_write(callback.0.clone(), callback.1, callback.2); 3163 } 3164 Some(()) 3165 }, 3166 ); 3167 } 3168 } 3169 } 3170 get_gatt_db_cb(&mut self, conn_id: i32, elements: Vec<BtGattDbElement>, _count: i32)3171 fn get_gatt_db_cb(&mut self, conn_id: i32, elements: Vec<BtGattDbElement>, _count: i32) { 3172 let address = self.context_map.get_address_by_conn_id(conn_id); 3173 if address.is_none() { 3174 return; 3175 } 3176 3177 let client = self.context_map.get_client_by_conn_id(conn_id); 3178 if client.is_none() { 3179 return; 3180 } 3181 3182 match (client, address) { 3183 (Some(c), Some(addr)) => { 3184 let cbid = c.cbid; 3185 self.context_map.get_callback_from_callback_id(cbid).and_then( 3186 |cb: &mut GattClientCallback| { 3187 cb.on_search_complete( 3188 addr.to_string(), 3189 BluetoothGattService::from_db(elements), 3190 GattStatus::Success, 3191 ); 3192 Some(()) 3193 }, 3194 ); 3195 } 3196 _ => (), 3197 }; 3198 } 3199 phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: GattStatus)3200 fn phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: GattStatus) { 3201 let client = self.context_map.get_client_by_conn_id(conn_id); 3202 if client.is_none() { 3203 return; 3204 } 3205 3206 let address = self.context_map.get_address_by_conn_id(conn_id); 3207 if address.is_none() { 3208 return; 3209 } 3210 match (client, address) { 3211 (Some(c), Some(addr)) => { 3212 let cbid = c.cbid; 3213 self.context_map.get_callback_from_callback_id(cbid).and_then( 3214 |cb: &mut GattClientCallback| { 3215 cb.on_phy_update( 3216 addr, 3217 LePhy::from_u8(tx_phy).unwrap(), 3218 LePhy::from_u8(rx_phy).unwrap(), 3219 status, 3220 ); 3221 Some(()) 3222 }, 3223 ); 3224 } 3225 _ => (), 3226 }; 3227 } 3228 read_phy_cb( &mut self, client_id: i32, addr: RawAddress, tx_phy: u8, rx_phy: u8, status: GattStatus, )3229 fn read_phy_cb( 3230 &mut self, 3231 client_id: i32, 3232 addr: RawAddress, 3233 tx_phy: u8, 3234 rx_phy: u8, 3235 status: GattStatus, 3236 ) { 3237 let client = self.context_map.get_by_client_id(client_id); 3238 if client.is_none() { 3239 return; 3240 } 3241 3242 if let Some(c) = client { 3243 let cbid = c.cbid; 3244 self.context_map.get_callback_from_callback_id(cbid).and_then( 3245 |cb: &mut GattClientCallback| { 3246 cb.on_phy_read( 3247 addr.to_string(), 3248 LePhy::from_u8(tx_phy).unwrap(), 3249 LePhy::from_u8(rx_phy).unwrap(), 3250 status, 3251 ); 3252 Some(()) 3253 }, 3254 ); 3255 } 3256 } 3257 conn_updated_cb( &mut self, conn_id: i32, interval: u16, latency: u16, timeout: u16, status: GattStatus, )3258 fn conn_updated_cb( 3259 &mut self, 3260 conn_id: i32, 3261 interval: u16, 3262 latency: u16, 3263 timeout: u16, 3264 status: GattStatus, 3265 ) { 3266 let client = self.context_map.get_client_by_conn_id(conn_id); 3267 if client.is_none() { 3268 return; 3269 } 3270 3271 let address = self.context_map.get_address_by_conn_id(conn_id); 3272 if address.is_none() { 3273 return; 3274 } 3275 3276 match (client, address) { 3277 (Some(c), Some(addr)) => { 3278 let cbid = c.cbid; 3279 self.context_map.get_callback_from_callback_id(cbid).and_then( 3280 |cb: &mut GattClientCallback| { 3281 cb.on_connection_updated( 3282 addr, 3283 interval as i32, 3284 latency as i32, 3285 timeout as i32, 3286 status, 3287 ); 3288 Some(()) 3289 }, 3290 ); 3291 } 3292 _ => (), 3293 }; 3294 } 3295 service_changed_cb(&mut self, conn_id: i32)3296 fn service_changed_cb(&mut self, conn_id: i32) { 3297 let address = self.context_map.get_address_by_conn_id(conn_id); 3298 if address.is_none() { 3299 return; 3300 } 3301 3302 let client = self.context_map.get_client_by_conn_id(conn_id); 3303 if client.is_none() { 3304 return; 3305 } 3306 3307 match (client, address) { 3308 (Some(c), Some(addr)) => { 3309 let cbid = c.cbid; 3310 self.context_map.get_callback_from_callback_id(cbid).and_then( 3311 |cb: &mut GattClientCallback| { 3312 cb.on_service_changed(addr); 3313 Some(()) 3314 }, 3315 ); 3316 } 3317 _ => (), 3318 }; 3319 } 3320 } 3321 3322 #[btif_callbacks_dispatcher(dispatch_gatt_server_callbacks, GattServerCallbacks)] 3323 pub(crate) trait BtifGattServerCallbacks { 3324 #[btif_callback(RegisterServer)] register_server_cb(&mut self, status: GattStatus, server_id: i32, app_uuid: Uuid)3325 fn register_server_cb(&mut self, status: GattStatus, server_id: i32, app_uuid: Uuid); 3326 3327 #[btif_callback(Connection)] connection_cb(&mut self, conn_id: i32, server_id: i32, connected: i32, addr: RawAddress)3328 fn connection_cb(&mut self, conn_id: i32, server_id: i32, connected: i32, addr: RawAddress); 3329 3330 #[btif_callback(ServiceAdded)] service_added_cb( &mut self, status: GattStatus, server_id: i32, elements: Vec<BtGattDbElement>, _count: usize, )3331 fn service_added_cb( 3332 &mut self, 3333 status: GattStatus, 3334 server_id: i32, 3335 elements: Vec<BtGattDbElement>, 3336 _count: usize, 3337 ); 3338 3339 #[btif_callback(ServiceDeleted)] service_deleted_cb(&mut self, status: GattStatus, server_id: i32, handle: i32)3340 fn service_deleted_cb(&mut self, status: GattStatus, server_id: i32, handle: i32); 3341 3342 #[btif_callback(RequestReadCharacteristic)] request_read_characteristic_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, handle: i32, offset: i32, is_long: bool, )3343 fn request_read_characteristic_cb( 3344 &mut self, 3345 conn_id: i32, 3346 trans_id: i32, 3347 addr: RawAddress, 3348 handle: i32, 3349 offset: i32, 3350 is_long: bool, 3351 ); 3352 3353 #[btif_callback(RequestReadDescriptor)] request_read_descriptor_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, handle: i32, offset: i32, is_long: bool, )3354 fn request_read_descriptor_cb( 3355 &mut self, 3356 conn_id: i32, 3357 trans_id: i32, 3358 addr: RawAddress, 3359 handle: i32, 3360 offset: i32, 3361 is_long: bool, 3362 ); 3363 3364 #[btif_callback(RequestWriteCharacteristic)] request_write_characteristic_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, handle: i32, offset: i32, need_rsp: bool, is_prep: bool, data: Vec<u8>, len: usize, )3365 fn request_write_characteristic_cb( 3366 &mut self, 3367 conn_id: i32, 3368 trans_id: i32, 3369 addr: RawAddress, 3370 handle: i32, 3371 offset: i32, 3372 need_rsp: bool, 3373 is_prep: bool, 3374 data: Vec<u8>, 3375 len: usize, 3376 ); 3377 3378 #[btif_callback(RequestWriteDescriptor)] request_write_descriptor_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, handle: i32, offset: i32, need_rsp: bool, is_prep: bool, data: Vec<u8>, len: usize, )3379 fn request_write_descriptor_cb( 3380 &mut self, 3381 conn_id: i32, 3382 trans_id: i32, 3383 addr: RawAddress, 3384 handle: i32, 3385 offset: i32, 3386 need_rsp: bool, 3387 is_prep: bool, 3388 data: Vec<u8>, 3389 len: usize, 3390 ); 3391 3392 #[btif_callback(RequestExecWrite)] request_exec_write_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, exec_write: i32, )3393 fn request_exec_write_cb( 3394 &mut self, 3395 conn_id: i32, 3396 trans_id: i32, 3397 addr: RawAddress, 3398 exec_write: i32, 3399 ); 3400 3401 #[btif_callback(IndicationSent)] indication_sent_cb(&mut self, conn_id: i32, status: GattStatus)3402 fn indication_sent_cb(&mut self, conn_id: i32, status: GattStatus); 3403 3404 #[btif_callback(Congestion)] congestion_cb(&mut self, conn_id: i32, congested: bool)3405 fn congestion_cb(&mut self, conn_id: i32, congested: bool); 3406 3407 #[btif_callback(MtuChanged)] mtu_changed_cb(&mut self, conn_id: i32, mtu: i32)3408 fn mtu_changed_cb(&mut self, conn_id: i32, mtu: i32); 3409 3410 #[btif_callback(PhyUpdated)] phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: GattStatus)3411 fn phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: GattStatus); 3412 3413 #[btif_callback(ReadPhy)] read_phy_cb( &mut self, server_id: i32, addr: RawAddress, tx_phy: u8, rx_phy: u8, status: GattStatus, )3414 fn read_phy_cb( 3415 &mut self, 3416 server_id: i32, 3417 addr: RawAddress, 3418 tx_phy: u8, 3419 rx_phy: u8, 3420 status: GattStatus, 3421 ); 3422 3423 #[btif_callback(ConnUpdated)] conn_updated_cb( &mut self, conn_id: i32, interval: u16, latency: u16, timeout: u16, status: GattStatus, )3424 fn conn_updated_cb( 3425 &mut self, 3426 conn_id: i32, 3427 interval: u16, 3428 latency: u16, 3429 timeout: u16, 3430 status: GattStatus, 3431 ); 3432 3433 #[btif_callback(SubrateChanged)] subrate_chg_cb( &mut self, conn_id: i32, subrate_factor: u16, latency: u16, cont_num: u16, timeout: u16, status: GattStatus, )3434 fn subrate_chg_cb( 3435 &mut self, 3436 conn_id: i32, 3437 subrate_factor: u16, 3438 latency: u16, 3439 cont_num: u16, 3440 timeout: u16, 3441 status: GattStatus, 3442 ); 3443 } 3444 3445 impl BtifGattServerCallbacks for BluetoothGatt { register_server_cb(&mut self, status: GattStatus, server_id: i32, app_uuid: Uuid)3446 fn register_server_cb(&mut self, status: GattStatus, server_id: i32, app_uuid: Uuid) { 3447 self.server_context_map.set_server_id(&app_uuid.uu, server_id); 3448 3449 let cbid = self.server_context_map.get_by_uuid(&app_uuid.uu).map(|server| server.cbid); 3450 match cbid { 3451 Some(cbid) => { 3452 if let Some(cb) = 3453 self.server_context_map.get_callback_from_callback_id(cbid).as_mut() 3454 { 3455 cb.on_server_registered(status, server_id) 3456 } 3457 } 3458 None => { 3459 warn!("Warning: No callback found for UUID {}", app_uuid); 3460 } 3461 } 3462 } 3463 connection_cb(&mut self, conn_id: i32, server_id: i32, connected: i32, addr: RawAddress)3464 fn connection_cb(&mut self, conn_id: i32, server_id: i32, connected: i32, addr: RawAddress) { 3465 let is_connected = connected != 0; 3466 if is_connected { 3467 self.server_context_map.add_connection(server_id, conn_id, &addr.to_string()); 3468 } else { 3469 self.server_context_map.remove_connection(conn_id); 3470 } 3471 3472 let cbid = self.server_context_map.get_by_server_id(server_id).map(|server| server.cbid); 3473 match cbid { 3474 Some(cbid) => { 3475 if let Some(cb) = 3476 self.server_context_map.get_callback_from_callback_id(cbid).as_mut() 3477 { 3478 cb.on_server_connection_state(server_id, is_connected, addr.to_string()); 3479 } 3480 } 3481 None => { 3482 warn!("Warning: No callback found for server ID {}", server_id); 3483 } 3484 } 3485 } 3486 service_added_cb( &mut self, status: GattStatus, server_id: i32, elements: Vec<BtGattDbElement>, _count: usize, )3487 fn service_added_cb( 3488 &mut self, 3489 status: GattStatus, 3490 server_id: i32, 3491 elements: Vec<BtGattDbElement>, 3492 _count: usize, 3493 ) { 3494 for service in BluetoothGattService::from_db(elements) { 3495 if status == GattStatus::Success { 3496 self.server_context_map.add_service(server_id, service.clone()); 3497 } 3498 3499 let cbid = 3500 self.server_context_map.get_by_server_id(server_id).map(|server| server.cbid); 3501 match cbid { 3502 Some(cbid) => { 3503 if let Some(cb) = 3504 self.server_context_map.get_callback_from_callback_id(cbid).as_mut() 3505 { 3506 cb.on_service_added(status, service); 3507 } 3508 } 3509 None => { 3510 warn!("Warning: No callback found for server ID {}", server_id); 3511 } 3512 } 3513 } 3514 } 3515 service_deleted_cb(&mut self, status: GattStatus, server_id: i32, handle: i32)3516 fn service_deleted_cb(&mut self, status: GattStatus, server_id: i32, handle: i32) { 3517 if status == GattStatus::Success { 3518 self.server_context_map.delete_service(server_id, handle); 3519 } 3520 3521 let cbid = self 3522 .server_context_map 3523 .get_by_server_id(server_id) 3524 .and_then(|server| Some(server.cbid)); 3525 3526 if let Some(cbid) = cbid { 3527 if let Some(cb) = self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { 3528 cb.on_service_removed(status, handle); 3529 } 3530 } 3531 } 3532 request_read_characteristic_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, handle: i32, offset: i32, is_long: bool, )3533 fn request_read_characteristic_cb( 3534 &mut self, 3535 conn_id: i32, 3536 trans_id: i32, 3537 addr: RawAddress, 3538 handle: i32, 3539 offset: i32, 3540 is_long: bool, 3541 ) { 3542 self.server_context_map.add_request(trans_id, handle); 3543 3544 if let Some(cbid) = 3545 self.server_context_map.get_by_conn_id(conn_id).map(|server| server.cbid) 3546 { 3547 if let Some(cb) = self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { 3548 cb.on_characteristic_read_request( 3549 addr.to_string(), 3550 trans_id, 3551 offset, 3552 is_long, 3553 handle, 3554 ); 3555 } 3556 } 3557 } 3558 request_read_descriptor_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, handle: i32, offset: i32, is_long: bool, )3559 fn request_read_descriptor_cb( 3560 &mut self, 3561 conn_id: i32, 3562 trans_id: i32, 3563 addr: RawAddress, 3564 handle: i32, 3565 offset: i32, 3566 is_long: bool, 3567 ) { 3568 self.server_context_map.add_request(trans_id, handle); 3569 3570 if let Some(cbid) = 3571 self.server_context_map.get_by_conn_id(conn_id).map(|server| server.cbid) 3572 { 3573 if let Some(cb) = self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { 3574 cb.on_descriptor_read_request(addr.to_string(), trans_id, offset, is_long, handle); 3575 } 3576 } 3577 } 3578 request_write_characteristic_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, handle: i32, offset: i32, need_rsp: bool, is_prep: bool, data: Vec<u8>, len: usize, )3579 fn request_write_characteristic_cb( 3580 &mut self, 3581 conn_id: i32, 3582 trans_id: i32, 3583 addr: RawAddress, 3584 handle: i32, 3585 offset: i32, 3586 need_rsp: bool, 3587 is_prep: bool, 3588 data: Vec<u8>, 3589 len: usize, 3590 ) { 3591 self.server_context_map.add_request(trans_id, handle); 3592 3593 if let Some(cbid) = 3594 self.server_context_map.get_by_conn_id(conn_id).map(|server| server.cbid) 3595 { 3596 if let Some(cb) = self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { 3597 cb.on_characteristic_write_request( 3598 addr.to_string(), 3599 trans_id, 3600 offset, 3601 len as i32, 3602 is_prep, 3603 need_rsp, 3604 handle, 3605 data, 3606 ); 3607 } 3608 } 3609 } 3610 request_write_descriptor_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, handle: i32, offset: i32, need_rsp: bool, is_prep: bool, data: Vec<u8>, len: usize, )3611 fn request_write_descriptor_cb( 3612 &mut self, 3613 conn_id: i32, 3614 trans_id: i32, 3615 addr: RawAddress, 3616 handle: i32, 3617 offset: i32, 3618 need_rsp: bool, 3619 is_prep: bool, 3620 data: Vec<u8>, 3621 len: usize, 3622 ) { 3623 self.server_context_map.add_request(trans_id, handle); 3624 3625 if let Some(cbid) = 3626 self.server_context_map.get_by_conn_id(conn_id).map(|server| server.cbid) 3627 { 3628 if let Some(cb) = self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { 3629 cb.on_descriptor_write_request( 3630 addr.to_string(), 3631 trans_id, 3632 offset, 3633 len as i32, 3634 is_prep, 3635 need_rsp, 3636 handle, 3637 data, 3638 ); 3639 } 3640 } 3641 } 3642 request_exec_write_cb( &mut self, conn_id: i32, trans_id: i32, addr: RawAddress, exec_write: i32, )3643 fn request_exec_write_cb( 3644 &mut self, 3645 conn_id: i32, 3646 trans_id: i32, 3647 addr: RawAddress, 3648 exec_write: i32, 3649 ) { 3650 self.server_context_map.add_request(trans_id, 0); 3651 3652 if let Some(cbid) = 3653 self.server_context_map.get_by_conn_id(conn_id).map(|server| server.cbid) 3654 { 3655 if let Some(cb) = self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { 3656 cb.on_execute_write(addr.to_string(), trans_id, exec_write != 0); 3657 } 3658 } 3659 } 3660 indication_sent_cb(&mut self, conn_id: i32, mut status: GattStatus)3661 fn indication_sent_cb(&mut self, conn_id: i32, mut status: GattStatus) { 3662 (|| { 3663 let address = self.server_context_map.get_address_from_conn_id(conn_id)?; 3664 let server = self.server_context_map.get_mut_by_conn_id(conn_id)?; 3665 3666 if server.is_congested { 3667 if status == GattStatus::Congested { 3668 status = GattStatus::Success; 3669 } 3670 3671 server.congestion_queue.push((address, status)); 3672 return None; 3673 } 3674 3675 let cbid = server.cbid; 3676 if let Some(cb) = self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { 3677 cb.on_notification_sent(address.to_string(), status); 3678 } 3679 3680 Some(()) 3681 })(); 3682 } 3683 congestion_cb(&mut self, conn_id: i32, congested: bool)3684 fn congestion_cb(&mut self, conn_id: i32, congested: bool) { 3685 if let Some(mut server) = self.server_context_map.get_mut_by_conn_id(conn_id) { 3686 server.is_congested = congested; 3687 if !server.is_congested { 3688 let cbid = server.cbid; 3689 let congestion_queue: Vec<_> = server.congestion_queue.drain(..).collect(); 3690 3691 if let Some(cb) = 3692 self.server_context_map.get_callback_from_callback_id(cbid).as_mut() 3693 { 3694 for callback in congestion_queue { 3695 cb.on_notification_sent(callback.0.clone(), callback.1); 3696 } 3697 } 3698 } 3699 } 3700 } 3701 mtu_changed_cb(&mut self, conn_id: i32, mtu: i32)3702 fn mtu_changed_cb(&mut self, conn_id: i32, mtu: i32) { 3703 (|| { 3704 let address = self.server_context_map.get_address_from_conn_id(conn_id)?; 3705 let server_cbid = self.server_context_map.get_by_conn_id(conn_id)?.cbid; 3706 3707 if let Some(cb) = 3708 self.server_context_map.get_callback_from_callback_id(server_cbid).as_mut() 3709 { 3710 cb.on_mtu_changed(address, mtu); 3711 } 3712 3713 Some(()) 3714 })(); 3715 } 3716 phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: GattStatus)3717 fn phy_updated_cb(&mut self, conn_id: i32, tx_phy: u8, rx_phy: u8, status: GattStatus) { 3718 (|| { 3719 let address = self.server_context_map.get_address_from_conn_id(conn_id)?; 3720 let server_cbid = self.server_context_map.get_by_conn_id(conn_id)?.cbid; 3721 3722 if let Some(cb) = 3723 self.server_context_map.get_callback_from_callback_id(server_cbid).as_mut() 3724 { 3725 cb.on_phy_update( 3726 address, 3727 LePhy::from_u8(tx_phy).unwrap_or_default(), 3728 LePhy::from_u8(rx_phy).unwrap_or_default(), 3729 status, 3730 ); 3731 } 3732 3733 Some(()) 3734 })(); 3735 } 3736 read_phy_cb( &mut self, server_id: i32, addr: RawAddress, tx_phy: u8, rx_phy: u8, status: GattStatus, )3737 fn read_phy_cb( 3738 &mut self, 3739 server_id: i32, 3740 addr: RawAddress, 3741 tx_phy: u8, 3742 rx_phy: u8, 3743 status: GattStatus, 3744 ) { 3745 if let Some(cbid) = 3746 self.server_context_map.get_by_server_id(server_id).map(|server| server.cbid) 3747 { 3748 if let Some(cb) = self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { 3749 cb.on_phy_read( 3750 addr.to_string(), 3751 LePhy::from_u8(tx_phy).unwrap_or_default(), 3752 LePhy::from_u8(rx_phy).unwrap_or_default(), 3753 status, 3754 ); 3755 } 3756 } 3757 } 3758 conn_updated_cb( &mut self, conn_id: i32, interval: u16, latency: u16, timeout: u16, status: GattStatus, )3759 fn conn_updated_cb( 3760 &mut self, 3761 conn_id: i32, 3762 interval: u16, 3763 latency: u16, 3764 timeout: u16, 3765 status: GattStatus, 3766 ) { 3767 (|| { 3768 let address = self.server_context_map.get_address_from_conn_id(conn_id)?; 3769 let server_cbid = self.server_context_map.get_by_conn_id(conn_id)?.cbid; 3770 3771 if let Some(cb) = 3772 self.server_context_map.get_callback_from_callback_id(server_cbid).as_mut() 3773 { 3774 cb.on_connection_updated( 3775 address, 3776 interval as i32, 3777 latency as i32, 3778 timeout as i32, 3779 status, 3780 ); 3781 } 3782 3783 Some(()) 3784 })(); 3785 } 3786 subrate_chg_cb( &mut self, conn_id: i32, subrate_factor: u16, latency: u16, cont_num: u16, timeout: u16, status: GattStatus, )3787 fn subrate_chg_cb( 3788 &mut self, 3789 conn_id: i32, 3790 subrate_factor: u16, 3791 latency: u16, 3792 cont_num: u16, 3793 timeout: u16, 3794 status: GattStatus, 3795 ) { 3796 (|| { 3797 let address = self.server_context_map.get_address_from_conn_id(conn_id)?; 3798 let server_cbid = self.server_context_map.get_by_conn_id(conn_id)?.cbid; 3799 3800 if let Some(cb) = 3801 self.server_context_map.get_callback_from_callback_id(server_cbid).as_mut() 3802 { 3803 cb.on_subrate_change( 3804 address, 3805 subrate_factor as i32, 3806 latency as i32, 3807 cont_num as i32, 3808 timeout as i32, 3809 status, 3810 ); 3811 } 3812 3813 Some(()) 3814 })(); 3815 } 3816 } 3817 3818 #[btif_callbacks_dispatcher(dispatch_le_scanner_callbacks, GattScannerCallbacks)] 3819 pub(crate) trait BtifGattScannerCallbacks { 3820 #[btif_callback(OnScannerRegistered)] on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus)3821 fn on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus); 3822 3823 #[btif_callback(OnScanResult)] on_scan_result( &mut self, event_type: u16, addr_type: u8, bda: RawAddress, primary_phy: u8, secondary_phy: u8, advertising_sid: u8, tx_power: i8, rssi: i8, periodic_adv_int: u16, adv_data: Vec<u8>, )3824 fn on_scan_result( 3825 &mut self, 3826 event_type: u16, 3827 addr_type: u8, 3828 bda: RawAddress, 3829 primary_phy: u8, 3830 secondary_phy: u8, 3831 advertising_sid: u8, 3832 tx_power: i8, 3833 rssi: i8, 3834 periodic_adv_int: u16, 3835 adv_data: Vec<u8>, 3836 ); 3837 3838 #[btif_callback(OnTrackAdvFoundLost)] on_track_adv_found_lost(&mut self, adv_track_info: RustAdvertisingTrackInfo)3839 fn on_track_adv_found_lost(&mut self, adv_track_info: RustAdvertisingTrackInfo); 3840 } 3841 3842 #[btif_callbacks_dispatcher(dispatch_le_scanner_inband_callbacks, GattScannerInbandCallbacks)] 3843 pub(crate) trait BtifGattScannerInbandCallbacks { 3844 #[btif_callback(RegisterCallback)] inband_register_callback(&mut self, app_uuid: Uuid, scanner_id: u8, btm_status: u8)3845 fn inband_register_callback(&mut self, app_uuid: Uuid, scanner_id: u8, btm_status: u8); 3846 3847 #[btif_callback(StatusCallback)] inband_status_callback(&mut self, scanner_id: u8, btm_status: u8)3848 fn inband_status_callback(&mut self, scanner_id: u8, btm_status: u8); 3849 3850 #[btif_callback(EnableCallback)] inband_enable_callback(&mut self, action: u8, btm_status: u8)3851 fn inband_enable_callback(&mut self, action: u8, btm_status: u8); 3852 3853 #[btif_callback(FilterParamSetupCallback)] inband_filter_param_setup_callback( &mut self, scanner_id: u8, available_space: u8, action_type: u8, btm_status: u8, )3854 fn inband_filter_param_setup_callback( 3855 &mut self, 3856 scanner_id: u8, 3857 available_space: u8, 3858 action_type: u8, 3859 btm_status: u8, 3860 ); 3861 3862 #[btif_callback(FilterConfigCallback)] inband_filter_config_callback( &mut self, filter_index: u8, filter_type: u8, available_space: u8, action: u8, btm_status: u8, )3863 fn inband_filter_config_callback( 3864 &mut self, 3865 filter_index: u8, 3866 filter_type: u8, 3867 available_space: u8, 3868 action: u8, 3869 btm_status: u8, 3870 ); 3871 3872 #[btif_callback(MsftAdvMonitorAddCallback)] inband_msft_adv_monitor_add_callback( &mut self, call_id: u32, monitor_handle: u8, status: u8, )3873 fn inband_msft_adv_monitor_add_callback( 3874 &mut self, 3875 call_id: u32, 3876 monitor_handle: u8, 3877 status: u8, 3878 ); 3879 3880 #[btif_callback(MsftAdvMonitorRemoveCallback)] inband_msft_adv_monitor_remove_callback(&mut self, call_id: u32, status: u8)3881 fn inband_msft_adv_monitor_remove_callback(&mut self, call_id: u32, status: u8); 3882 3883 #[btif_callback(MsftAdvMonitorEnableCallback)] inband_msft_adv_monitor_enable_callback(&mut self, call_id: u32, status: u8)3884 fn inband_msft_adv_monitor_enable_callback(&mut self, call_id: u32, status: u8); 3885 3886 #[btif_callback(StartSyncCallback)] inband_start_sync_callback( &mut self, status: u8, sync_handle: u16, advertising_sid: u8, address_type: u8, address: RawAddress, phy: u8, interval: u16, )3887 fn inband_start_sync_callback( 3888 &mut self, 3889 status: u8, 3890 sync_handle: u16, 3891 advertising_sid: u8, 3892 address_type: u8, 3893 address: RawAddress, 3894 phy: u8, 3895 interval: u16, 3896 ); 3897 3898 #[btif_callback(SyncReportCallback)] inband_sync_report_callback( &mut self, sync_handle: u16, tx_power: i8, rssi: i8, status: u8, data: Vec<u8>, )3899 fn inband_sync_report_callback( 3900 &mut self, 3901 sync_handle: u16, 3902 tx_power: i8, 3903 rssi: i8, 3904 status: u8, 3905 data: Vec<u8>, 3906 ); 3907 3908 #[btif_callback(SyncLostCallback)] inband_sync_lost_callback(&mut self, sync_handle: u16)3909 fn inband_sync_lost_callback(&mut self, sync_handle: u16); 3910 3911 #[btif_callback(SyncTransferCallback)] inband_sync_transfer_callback(&mut self, status: u8, address: RawAddress)3912 fn inband_sync_transfer_callback(&mut self, status: u8, address: RawAddress); 3913 } 3914 3915 impl BtifGattScannerInbandCallbacks for BluetoothGatt { inband_register_callback(&mut self, app_uuid: Uuid, scanner_id: u8, btm_status: u8)3916 fn inband_register_callback(&mut self, app_uuid: Uuid, scanner_id: u8, btm_status: u8) { 3917 log::debug!( 3918 "Callback received: {:#?}", 3919 GattScannerInbandCallbacks::RegisterCallback(app_uuid, scanner_id, btm_status) 3920 ); 3921 } 3922 inband_status_callback(&mut self, scanner_id: u8, btm_status: u8)3923 fn inband_status_callback(&mut self, scanner_id: u8, btm_status: u8) { 3924 log::debug!( 3925 "Callback received: {:#?}", 3926 GattScannerInbandCallbacks::StatusCallback(scanner_id, btm_status) 3927 ); 3928 } 3929 inband_enable_callback(&mut self, action: u8, btm_status: u8)3930 fn inband_enable_callback(&mut self, action: u8, btm_status: u8) { 3931 log::debug!( 3932 "Callback received: {:#?}", 3933 GattScannerInbandCallbacks::EnableCallback(action, btm_status) 3934 ); 3935 } 3936 inband_filter_param_setup_callback( &mut self, scanner_id: u8, available_space: u8, action_type: u8, btm_status: u8, )3937 fn inband_filter_param_setup_callback( 3938 &mut self, 3939 scanner_id: u8, 3940 available_space: u8, 3941 action_type: u8, 3942 btm_status: u8, 3943 ) { 3944 log::debug!( 3945 "Callback received: {:#?}", 3946 GattScannerInbandCallbacks::FilterParamSetupCallback( 3947 scanner_id, 3948 available_space, 3949 action_type, 3950 btm_status 3951 ) 3952 ); 3953 } 3954 inband_filter_config_callback( &mut self, filter_index: u8, filter_type: u8, available_space: u8, action: u8, btm_status: u8, )3955 fn inband_filter_config_callback( 3956 &mut self, 3957 filter_index: u8, 3958 filter_type: u8, 3959 available_space: u8, 3960 action: u8, 3961 btm_status: u8, 3962 ) { 3963 log::debug!( 3964 "Callback received: {:#?}", 3965 GattScannerInbandCallbacks::FilterConfigCallback( 3966 filter_index, 3967 filter_type, 3968 available_space, 3969 action, 3970 btm_status, 3971 ) 3972 ); 3973 } 3974 inband_msft_adv_monitor_add_callback( &mut self, call_id: u32, monitor_handle: u8, status: u8, )3975 fn inband_msft_adv_monitor_add_callback( 3976 &mut self, 3977 call_id: u32, 3978 monitor_handle: u8, 3979 status: u8, 3980 ) { 3981 (self.adv_mon_add_cb_sender.lock().unwrap())(call_id, (monitor_handle, status)); 3982 } 3983 inband_msft_adv_monitor_remove_callback(&mut self, call_id: u32, status: u8)3984 fn inband_msft_adv_monitor_remove_callback(&mut self, call_id: u32, status: u8) { 3985 (self.adv_mon_remove_cb_sender.lock().unwrap())(call_id, status); 3986 } 3987 inband_msft_adv_monitor_enable_callback(&mut self, call_id: u32, status: u8)3988 fn inband_msft_adv_monitor_enable_callback(&mut self, call_id: u32, status: u8) { 3989 (self.adv_mon_enable_cb_sender.lock().unwrap())(call_id, status); 3990 } 3991 inband_start_sync_callback( &mut self, status: u8, sync_handle: u16, advertising_sid: u8, address_type: u8, address: RawAddress, phy: u8, interval: u16, )3992 fn inband_start_sync_callback( 3993 &mut self, 3994 status: u8, 3995 sync_handle: u16, 3996 advertising_sid: u8, 3997 address_type: u8, 3998 address: RawAddress, 3999 phy: u8, 4000 interval: u16, 4001 ) { 4002 log::debug!( 4003 "Callback received: {:#?}", 4004 GattScannerInbandCallbacks::StartSyncCallback( 4005 status, 4006 sync_handle, 4007 advertising_sid, 4008 address_type, 4009 address, 4010 phy, 4011 interval, 4012 ) 4013 ); 4014 } 4015 inband_sync_report_callback( &mut self, sync_handle: u16, tx_power: i8, rssi: i8, status: u8, data: Vec<u8>, )4016 fn inband_sync_report_callback( 4017 &mut self, 4018 sync_handle: u16, 4019 tx_power: i8, 4020 rssi: i8, 4021 status: u8, 4022 data: Vec<u8>, 4023 ) { 4024 log::debug!( 4025 "Callback received: {:#?}", 4026 GattScannerInbandCallbacks::SyncReportCallback( 4027 sync_handle, 4028 tx_power, 4029 rssi, 4030 status, 4031 data 4032 ) 4033 ); 4034 } 4035 inband_sync_lost_callback(&mut self, sync_handle: u16)4036 fn inband_sync_lost_callback(&mut self, sync_handle: u16) { 4037 log::debug!( 4038 "Callback received: {:#?}", 4039 GattScannerInbandCallbacks::SyncLostCallback(sync_handle,) 4040 ); 4041 } 4042 inband_sync_transfer_callback(&mut self, status: u8, address: RawAddress)4043 fn inband_sync_transfer_callback(&mut self, status: u8, address: RawAddress) { 4044 log::debug!( 4045 "Callback received: {:#?}", 4046 GattScannerInbandCallbacks::SyncTransferCallback(status, address) 4047 ); 4048 } 4049 } 4050 4051 impl BtifGattScannerCallbacks for BluetoothGatt { on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus)4052 fn on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus) { 4053 log::debug!( 4054 "on_scanner_registered UUID = {}, scanner_id = {}, status = {}", 4055 uuid, 4056 scanner_id, 4057 status 4058 ); 4059 4060 if status != GattStatus::Success { 4061 log::error!("Error registering scanner UUID {}", uuid); 4062 self.scanners.lock().unwrap().remove(&uuid); 4063 return; 4064 } 4065 4066 let mut scanners_lock = self.scanners.lock().unwrap(); 4067 let scanner_info = scanners_lock.get_mut(&uuid); 4068 4069 if let Some(info) = scanner_info { 4070 info.scanner_id = Some(scanner_id); 4071 if let Some(cb) = self.scanner_callbacks.get_by_id_mut(info.callback_id) { 4072 cb.on_scanner_registered(uuid.uu, scanner_id, status); 4073 } else { 4074 log::warn!("There is no callback for scanner UUID {}", uuid); 4075 } 4076 } else { 4077 log::warn!( 4078 "Scanner registered callback for non-existent scanner info, UUID = {}", 4079 uuid 4080 ); 4081 } 4082 } 4083 on_scan_result( &mut self, event_type: u16, addr_type: u8, address: RawAddress, primary_phy: u8, secondary_phy: u8, advertising_sid: u8, tx_power: i8, rssi: i8, periodic_adv_int: u16, adv_data: Vec<u8>, )4084 fn on_scan_result( 4085 &mut self, 4086 event_type: u16, 4087 addr_type: u8, 4088 address: RawAddress, 4089 primary_phy: u8, 4090 secondary_phy: u8, 4091 advertising_sid: u8, 4092 tx_power: i8, 4093 rssi: i8, 4094 periodic_adv_int: u16, 4095 adv_data: Vec<u8>, 4096 ) { 4097 self.scanner_callbacks.for_all_callbacks(|callback| { 4098 callback.on_scan_result(ScanResult { 4099 name: adv_parser::extract_name(adv_data.as_slice()), 4100 address: address.to_string(), 4101 addr_type, 4102 event_type, 4103 primary_phy, 4104 secondary_phy, 4105 advertising_sid, 4106 tx_power, 4107 rssi, 4108 periodic_adv_int, 4109 flags: adv_parser::extract_flags(adv_data.as_slice()), 4110 service_uuids: adv_parser::extract_service_uuids(adv_data.as_slice()), 4111 service_data: adv_parser::extract_service_data(adv_data.as_slice()), 4112 manufacturer_data: adv_parser::extract_manufacturer_data(adv_data.as_slice()), 4113 adv_data: adv_data.clone(), 4114 }); 4115 }); 4116 } 4117 on_track_adv_found_lost(&mut self, track_adv_info: RustAdvertisingTrackInfo)4118 fn on_track_adv_found_lost(&mut self, track_adv_info: RustAdvertisingTrackInfo) { 4119 let scanner_id = match self.scanners.lock().unwrap().values().find_map(|scanner| { 4120 scanner.monitor_handle.and_then(|handle| { 4121 (handle == track_adv_info.monitor_handle).then(|| scanner.scanner_id).flatten() 4122 }) 4123 }) { 4124 Some(scanner_id) => scanner_id, 4125 None => { 4126 log::warn!("No scanner id having monitor handle {}", track_adv_info.monitor_handle); 4127 return; 4128 } 4129 }; 4130 4131 self.scanner_callbacks.for_all_callbacks(|callback| { 4132 let adv_data = 4133 [&track_adv_info.adv_packet[..], &track_adv_info.scan_response[..]].concat(); 4134 4135 let scan_result = ScanResult { 4136 name: adv_parser::extract_name(adv_data.as_slice()), 4137 address: track_adv_info.advertiser_address.to_string(), 4138 addr_type: track_adv_info.advertiser_address_type, 4139 event_type: 0, /* not used */ 4140 primary_phy: LePhy::Phy1m as u8, 4141 secondary_phy: 0, /* not used */ 4142 advertising_sid: 0xff, /* not present */ 4143 /* A bug in libbluetooth that uses u8 for TX power. 4144 * TODO(b/261482382): Fix the data type in C++ layer to use i8 instead of u8. */ 4145 tx_power: track_adv_info.tx_power as i8, 4146 rssi: track_adv_info.rssi, 4147 periodic_adv_int: 0, /* not used */ 4148 flags: adv_parser::extract_flags(adv_data.as_slice()), 4149 service_uuids: adv_parser::extract_service_uuids(adv_data.as_slice()), 4150 service_data: adv_parser::extract_service_data(adv_data.as_slice()), 4151 manufacturer_data: adv_parser::extract_manufacturer_data(adv_data.as_slice()), 4152 adv_data, 4153 }; 4154 4155 if track_adv_info.advertiser_state == 0x01 { 4156 callback.on_advertisement_found(scanner_id, scan_result); 4157 } else { 4158 callback.on_advertisement_lost(scanner_id, scan_result); 4159 } 4160 }); 4161 } 4162 } 4163 4164 #[btif_callbacks_dispatcher(dispatch_le_adv_callbacks, GattAdvCallbacks)] 4165 pub(crate) trait BtifGattAdvCallbacks { 4166 #[btif_callback(OnAdvertisingSetStarted)] on_advertising_set_started( &mut self, reg_id: i32, advertiser_id: u8, tx_power: i8, status: AdvertisingStatus, )4167 fn on_advertising_set_started( 4168 &mut self, 4169 reg_id: i32, 4170 advertiser_id: u8, 4171 tx_power: i8, 4172 status: AdvertisingStatus, 4173 ); 4174 4175 #[btif_callback(OnAdvertisingEnabled)] on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus)4176 fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus); 4177 4178 #[btif_callback(OnAdvertisingDataSet)] on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)4179 fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus); 4180 4181 #[btif_callback(OnScanResponseDataSet)] on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)4182 fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus); 4183 4184 #[btif_callback(OnAdvertisingParametersUpdated)] on_advertising_parameters_updated( &mut self, adv_id: u8, tx_power: i8, status: AdvertisingStatus, )4185 fn on_advertising_parameters_updated( 4186 &mut self, 4187 adv_id: u8, 4188 tx_power: i8, 4189 status: AdvertisingStatus, 4190 ); 4191 4192 #[btif_callback(OnPeriodicAdvertisingParametersUpdated)] on_periodic_advertising_parameters_updated(&mut self, adv_id: u8, status: AdvertisingStatus)4193 fn on_periodic_advertising_parameters_updated(&mut self, adv_id: u8, status: AdvertisingStatus); 4194 4195 #[btif_callback(OnPeriodicAdvertisingDataSet)] on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)4196 fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus); 4197 4198 #[btif_callback(OnPeriodicAdvertisingEnabled)] on_periodic_advertising_enabled( &mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus, )4199 fn on_periodic_advertising_enabled( 4200 &mut self, 4201 adv_id: u8, 4202 enabled: bool, 4203 status: AdvertisingStatus, 4204 ); 4205 4206 #[btif_callback(OnOwnAddressRead)] on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress)4207 fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress); 4208 } 4209 4210 impl BtifGattAdvCallbacks for BluetoothGatt { on_advertising_set_started( &mut self, reg_id: i32, advertiser_id: u8, tx_power: i8, status: AdvertisingStatus, )4211 fn on_advertising_set_started( 4212 &mut self, 4213 reg_id: i32, 4214 advertiser_id: u8, 4215 tx_power: i8, 4216 status: AdvertisingStatus, 4217 ) { 4218 debug!( 4219 "on_advertising_set_started(): reg_id = {}, advertiser_id = {}, tx_power = {}, status = {:?}", 4220 reg_id, advertiser_id, tx_power, status 4221 ); 4222 4223 if let Some(s) = self.advertisers.get_mut_by_reg_id(reg_id) { 4224 s.set_adv_id(Some(advertiser_id.into())); 4225 s.set_enabled(status == AdvertisingStatus::Success); 4226 } else { 4227 return; 4228 } 4229 let s = self.advertisers.get_mut_by_reg_id(reg_id).unwrap().clone(); 4230 4231 if let Some(cb) = self.advertisers.get_callback(&s) { 4232 cb.on_advertising_set_started(reg_id, advertiser_id.into(), tx_power.into(), status); 4233 } 4234 4235 if status != AdvertisingStatus::Success { 4236 warn!( 4237 "on_advertising_set_started(): failed! reg_id = {}, status = {:?}", 4238 reg_id, status 4239 ); 4240 self.advertisers.remove_by_reg_id(reg_id); 4241 } 4242 } 4243 on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus)4244 fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus) { 4245 debug!( 4246 "on_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}", 4247 adv_id, enabled, status 4248 ); 4249 4250 let advertiser_id: i32 = adv_id.into(); 4251 4252 if let Some(s) = self.advertisers.get_mut_by_advertiser_id(advertiser_id) { 4253 s.set_enabled(enabled); 4254 } else { 4255 return; 4256 } 4257 4258 let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); 4259 if let Some(cb) = self.advertisers.get_callback(&s) { 4260 cb.on_advertising_enabled(advertiser_id, enabled, status); 4261 } 4262 4263 if self.advertisers.suspend_mode() == SuspendMode::Suspending { 4264 if self.advertisers.enabled_sets().count() == 0 { 4265 self.advertisers.set_suspend_mode(SuspendMode::Suspended); 4266 } 4267 } 4268 } 4269 on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)4270 fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) { 4271 debug!("on_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status); 4272 4273 let advertiser_id: i32 = adv_id.into(); 4274 if None == self.advertisers.get_by_advertiser_id(advertiser_id) { 4275 return; 4276 } 4277 let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); 4278 4279 if let Some(cb) = self.advertisers.get_callback(&s) { 4280 cb.on_advertising_data_set(advertiser_id, status); 4281 } 4282 } 4283 on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)4284 fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) { 4285 debug!("on_scan_response_data_set(): adv_id = {}, status = {:?}", adv_id, status); 4286 4287 let advertiser_id: i32 = adv_id.into(); 4288 if None == self.advertisers.get_by_advertiser_id(advertiser_id) { 4289 return; 4290 } 4291 let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); 4292 4293 if let Some(cb) = self.advertisers.get_callback(&s) { 4294 cb.on_scan_response_data_set(advertiser_id, status); 4295 } 4296 } 4297 on_advertising_parameters_updated( &mut self, adv_id: u8, tx_power: i8, status: AdvertisingStatus, )4298 fn on_advertising_parameters_updated( 4299 &mut self, 4300 adv_id: u8, 4301 tx_power: i8, 4302 status: AdvertisingStatus, 4303 ) { 4304 debug!( 4305 "on_advertising_parameters_updated(): adv_id = {}, tx_power = {}, status = {:?}", 4306 adv_id, tx_power, status 4307 ); 4308 4309 let advertiser_id: i32 = adv_id.into(); 4310 if None == self.advertisers.get_by_advertiser_id(advertiser_id) { 4311 return; 4312 } 4313 let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); 4314 4315 if let Some(cb) = self.advertisers.get_callback(&s) { 4316 cb.on_advertising_parameters_updated(advertiser_id, tx_power.into(), status); 4317 } 4318 } 4319 on_periodic_advertising_parameters_updated( &mut self, adv_id: u8, status: AdvertisingStatus, )4320 fn on_periodic_advertising_parameters_updated( 4321 &mut self, 4322 adv_id: u8, 4323 status: AdvertisingStatus, 4324 ) { 4325 debug!( 4326 "on_periodic_advertising_parameters_updated(): adv_id = {}, status = {:?}", 4327 adv_id, status 4328 ); 4329 4330 let advertiser_id: i32 = adv_id.into(); 4331 if None == self.advertisers.get_by_advertiser_id(advertiser_id) { 4332 return; 4333 } 4334 let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); 4335 4336 if let Some(cb) = self.advertisers.get_callback(&s) { 4337 cb.on_periodic_advertising_parameters_updated(advertiser_id, status); 4338 } 4339 } 4340 on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)4341 fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) { 4342 debug!("on_periodic_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status); 4343 4344 let advertiser_id: i32 = adv_id.into(); 4345 if None == self.advertisers.get_by_advertiser_id(advertiser_id) { 4346 return; 4347 } 4348 let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); 4349 4350 if let Some(cb) = self.advertisers.get_callback(&s) { 4351 cb.on_periodic_advertising_data_set(advertiser_id, status); 4352 } 4353 } 4354 on_periodic_advertising_enabled( &mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus, )4355 fn on_periodic_advertising_enabled( 4356 &mut self, 4357 adv_id: u8, 4358 enabled: bool, 4359 status: AdvertisingStatus, 4360 ) { 4361 debug!( 4362 "on_periodic_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}", 4363 adv_id, enabled, status 4364 ); 4365 4366 let advertiser_id: i32 = adv_id.into(); 4367 if None == self.advertisers.get_by_advertiser_id(advertiser_id) { 4368 return; 4369 } 4370 let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); 4371 4372 if let Some(cb) = self.advertisers.get_callback(&s) { 4373 cb.on_periodic_advertising_enabled(advertiser_id, enabled, status); 4374 } 4375 } 4376 on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress)4377 fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress) { 4378 debug!( 4379 "on_own_address_read(): adv_id = {}, addr_type = {}, address = {:?}", 4380 adv_id, addr_type, address 4381 ); 4382 4383 let advertiser_id: i32 = adv_id.into(); 4384 if None == self.advertisers.get_by_advertiser_id(advertiser_id) { 4385 return; 4386 } 4387 let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); 4388 4389 if let Some(cb) = self.advertisers.get_callback(&s) { 4390 cb.on_own_address_read(advertiser_id, addr_type.into(), address.to_string()); 4391 } 4392 } 4393 } 4394 4395 #[cfg(test)] 4396 mod tests { 4397 struct TestBluetoothGattCallback { 4398 id: String, 4399 } 4400 4401 impl TestBluetoothGattCallback { new(id: String) -> TestBluetoothGattCallback4402 fn new(id: String) -> TestBluetoothGattCallback { 4403 TestBluetoothGattCallback { id } 4404 } 4405 } 4406 4407 impl IBluetoothGattCallback for TestBluetoothGattCallback { on_client_registered(&mut self, _status: GattStatus, _client_id: i32)4408 fn on_client_registered(&mut self, _status: GattStatus, _client_id: i32) {} on_client_connection_state( &mut self, _status: GattStatus, _client_id: i32, _connected: bool, _addr: String, )4409 fn on_client_connection_state( 4410 &mut self, 4411 _status: GattStatus, 4412 _client_id: i32, 4413 _connected: bool, 4414 _addr: String, 4415 ) { 4416 } 4417 on_phy_update( &mut self, _addr: String, _tx_phy: LePhy, _rx_phy: LePhy, _status: GattStatus, )4418 fn on_phy_update( 4419 &mut self, 4420 _addr: String, 4421 _tx_phy: LePhy, 4422 _rx_phy: LePhy, 4423 _status: GattStatus, 4424 ) { 4425 } 4426 on_phy_read( &mut self, _addr: String, _tx_phy: LePhy, _rx_phy: LePhy, _status: GattStatus, )4427 fn on_phy_read( 4428 &mut self, 4429 _addr: String, 4430 _tx_phy: LePhy, 4431 _rx_phy: LePhy, 4432 _status: GattStatus, 4433 ) { 4434 } 4435 on_search_complete( &mut self, _addr: String, _services: Vec<BluetoothGattService>, _status: GattStatus, )4436 fn on_search_complete( 4437 &mut self, 4438 _addr: String, 4439 _services: Vec<BluetoothGattService>, 4440 _status: GattStatus, 4441 ) { 4442 } 4443 on_characteristic_read( &mut self, _addr: String, _status: GattStatus, _handle: i32, _value: Vec<u8>, )4444 fn on_characteristic_read( 4445 &mut self, 4446 _addr: String, 4447 _status: GattStatus, 4448 _handle: i32, 4449 _value: Vec<u8>, 4450 ) { 4451 } 4452 on_characteristic_write(&mut self, _addr: String, _status: GattStatus, _handle: i32)4453 fn on_characteristic_write(&mut self, _addr: String, _status: GattStatus, _handle: i32) {} 4454 on_execute_write(&mut self, _addr: String, _status: GattStatus)4455 fn on_execute_write(&mut self, _addr: String, _status: GattStatus) {} 4456 on_descriptor_read( &mut self, _addr: String, _status: GattStatus, _handle: i32, _value: Vec<u8>, )4457 fn on_descriptor_read( 4458 &mut self, 4459 _addr: String, 4460 _status: GattStatus, 4461 _handle: i32, 4462 _value: Vec<u8>, 4463 ) { 4464 } 4465 on_descriptor_write(&mut self, _addr: String, _status: GattStatus, _handle: i32)4466 fn on_descriptor_write(&mut self, _addr: String, _status: GattStatus, _handle: i32) {} 4467 on_notify(&mut self, _addr: String, _handle: i32, _value: Vec<u8>)4468 fn on_notify(&mut self, _addr: String, _handle: i32, _value: Vec<u8>) {} 4469 on_read_remote_rssi(&mut self, _addr: String, _rssi: i32, _status: GattStatus)4470 fn on_read_remote_rssi(&mut self, _addr: String, _rssi: i32, _status: GattStatus) {} 4471 on_configure_mtu(&mut self, _addr: String, _mtu: i32, _status: GattStatus)4472 fn on_configure_mtu(&mut self, _addr: String, _mtu: i32, _status: GattStatus) {} 4473 on_connection_updated( &mut self, _addr: String, _interval: i32, _latency: i32, _timeout: i32, _status: GattStatus, )4474 fn on_connection_updated( 4475 &mut self, 4476 _addr: String, 4477 _interval: i32, 4478 _latency: i32, 4479 _timeout: i32, 4480 _status: GattStatus, 4481 ) { 4482 } 4483 on_service_changed(&mut self, _addr: String)4484 fn on_service_changed(&mut self, _addr: String) {} 4485 } 4486 4487 impl RPCProxy for TestBluetoothGattCallback { get_object_id(&self) -> String4488 fn get_object_id(&self) -> String { 4489 self.id.clone() 4490 } 4491 } 4492 4493 use super::*; 4494 4495 #[test] test_uuid_from_string()4496 fn test_uuid_from_string() { 4497 let uuid = UuidHelper::parse_string("abcdef"); 4498 assert!(uuid.is_none()); 4499 4500 let uuid = UuidHelper::parse_string("0123456789abcdef0123456789abcdef"); 4501 assert!(uuid.is_some()); 4502 let expected: [u8; 16] = [ 4503 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 4504 0xcd, 0xef, 4505 ]; 4506 assert_eq!(Uuid::from(expected), uuid.unwrap()); 4507 } 4508 4509 #[test] test_context_map_clients()4510 fn test_context_map_clients() { 4511 let (tx, _rx) = crate::Stack::create_channel(); 4512 let mut map = ContextMap::new(tx.clone()); 4513 4514 // Add client 1. 4515 let callback1 = Box::new(TestBluetoothGattCallback::new(String::from("Callback 1"))); 4516 let uuid1 = UuidHelper::parse_string("00000000000000000000000000000001").unwrap().uu; 4517 map.add(&uuid1, callback1); 4518 let found = map.get_by_uuid(&uuid1); 4519 assert!(found.is_some()); 4520 assert_eq!( 4521 "Callback 1", 4522 match found { 4523 Some(c) => { 4524 let cbid = c.cbid; 4525 map.callbacks 4526 .get_by_id(cbid) 4527 .and_then(|cb| Some(cb.get_object_id())) 4528 .unwrap_or(String::new()) 4529 } 4530 None => String::new(), 4531 } 4532 ); 4533 4534 // Add client 2. 4535 let callback2 = Box::new(TestBluetoothGattCallback::new(String::from("Callback 2"))); 4536 let uuid2 = UuidHelper::parse_string("00000000000000000000000000000002").unwrap().uu; 4537 map.add(&uuid2, callback2); 4538 let found = map.get_by_uuid(&uuid2); 4539 assert!(found.is_some()); 4540 assert_eq!( 4541 "Callback 2", 4542 match found { 4543 Some(c) => { 4544 let cbid = c.cbid; 4545 map.callbacks 4546 .get_by_id(cbid) 4547 .and_then(|cb| Some(cb.get_object_id())) 4548 .unwrap_or(String::new()) 4549 } 4550 None => String::new(), 4551 } 4552 ); 4553 4554 // Set client ID and get by client ID. 4555 map.set_client_id(&uuid1, 3); 4556 let found = map.get_by_client_id(3); 4557 assert!(found.is_some()); 4558 4559 // Remove client 1. 4560 map.remove(3); 4561 let found = map.get_by_uuid(&uuid1); 4562 assert!(found.is_none()); 4563 } 4564 4565 #[test] test_context_map_connections()4566 fn test_context_map_connections() { 4567 let (tx, _rx) = crate::Stack::create_channel(); 4568 let mut map = ContextMap::new(tx.clone()); 4569 let client_id = 1; 4570 4571 map.add_connection(client_id, 3, &String::from("aa:bb:cc:dd:ee:ff")); 4572 map.add_connection(client_id, 4, &String::from("11:22:33:44:55:66")); 4573 4574 let found = map.get_conn_id_from_address(client_id, &String::from("aa:bb:cc:dd:ee:ff")); 4575 assert!(found.is_some()); 4576 assert_eq!(3, found.unwrap()); 4577 4578 let found = map.get_conn_id_from_address(client_id, &String::from("11:22:33:44:55:66")); 4579 assert!(found.is_some()); 4580 assert_eq!(4, found.unwrap()); 4581 } 4582 } 4583