1 use crate::command_handler::SocketSchedule;
2 use crate::dbus_iface::{
3 export_admin_policy_callback_dbus_intf, export_advertising_set_callback_dbus_intf,
4 export_battery_manager_callback_dbus_intf, export_bluetooth_callback_dbus_intf,
5 export_bluetooth_connection_callback_dbus_intf, export_bluetooth_gatt_callback_dbus_intf,
6 export_bluetooth_manager_callback_dbus_intf, export_bluetooth_media_callback_dbus_intf,
7 export_bluetooth_telephony_callback_dbus_intf, export_gatt_server_callback_dbus_intf,
8 export_qa_callback_dbus_intf, export_scanner_callback_dbus_intf,
9 export_socket_callback_dbus_intf, export_suspend_callback_dbus_intf,
10 };
11 use crate::{console_red, console_yellow, print_error, print_info};
12 use crate::{ClientContext, GattRequest};
13 use bt_topshim::btif::{BtBondState, BtPropertyType, BtSspVariant, BtStatus, RawAddress, Uuid};
14 use bt_topshim::profiles::gatt::{AdvertisingStatus, GattStatus, LePhy};
15 use bt_topshim::profiles::hfp::HfpCodecId;
16 use bt_topshim::profiles::le_audio::{
17 BtLeAudioDirection, BtLeAudioGroupNodeStatus, BtLeAudioGroupStatus, BtLeAudioGroupStreamStatus,
18 BtLeAudioUnicastMonitorModeStatus,
19 };
20 use bt_topshim::profiles::sdp::BtSdpRecord;
21 use btstack::battery_manager::{BatterySet, IBatteryManagerCallback};
22 use btstack::bluetooth::{
23 BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback,
24 };
25 use btstack::bluetooth_admin::{IBluetoothAdminPolicyCallback, PolicyEffect};
26 use btstack::bluetooth_adv::IAdvertisingSetCallback;
27 use btstack::bluetooth_gatt::{
28 BluetoothGattService, IBluetoothGattCallback, IBluetoothGattServerCallback, IScannerCallback,
29 ScanResult,
30 };
31 use btstack::bluetooth_media::{
32 BluetoothAudioDevice, IBluetoothMediaCallback, IBluetoothTelephonyCallback,
33 };
34 use btstack::bluetooth_qa::IBluetoothQACallback;
35 use btstack::socket_manager::{
36 BluetoothServerSocket, BluetoothSocket, IBluetoothSocketManager,
37 IBluetoothSocketManagerCallbacks, SocketId,
38 };
39 use btstack::suspend::ISuspendCallback;
40 use btstack::{RPCProxy, SuspendMode};
41 use chrono::{TimeZone, Utc};
42 use dbus::nonblock::SyncConnection;
43 use dbus_crossroads::Crossroads;
44 use dbus_projection::DisconnectWatcher;
45 use manager_service::iface_bluetooth_manager::IBluetoothManagerCallback;
46 use std::convert::TryFrom;
47 use std::io::{Read, Write};
48 use std::sync::{Arc, Mutex};
49 use std::time::Duration;
50
51 const SOCKET_TEST_WRITE: &[u8] =
52 b"01234567890123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
53
54 // Avoid 32, 40, 64 consecutive hex characters so CrOS feedback redact tool
55 // doesn't trim our dump.
56 const BINARY_PACKET_STATUS_WRAP: usize = 50;
57
58 /// Callback context for manager interface callbacks.
59 pub(crate) struct BtManagerCallback {
60 objpath: String,
61 context: Arc<Mutex<ClientContext>>,
62
63 dbus_connection: Arc<SyncConnection>,
64 dbus_crossroads: Arc<Mutex<Crossroads>>,
65 }
66
67 impl BtManagerCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self68 pub(crate) fn new(
69 objpath: String,
70 context: Arc<Mutex<ClientContext>>,
71 dbus_connection: Arc<SyncConnection>,
72 dbus_crossroads: Arc<Mutex<Crossroads>>,
73 ) -> Self {
74 Self { objpath, context, dbus_connection, dbus_crossroads }
75 }
76 }
77
78 impl IBluetoothManagerCallback for BtManagerCallback {
on_hci_device_changed(&mut self, hci_interface: i32, present: bool)79 fn on_hci_device_changed(&mut self, hci_interface: i32, present: bool) {
80 print_info!("hci{} present = {}", hci_interface, present);
81
82 if present {
83 self.context.lock().unwrap().adapters.entry(hci_interface).or_insert(false);
84 } else {
85 self.context.lock().unwrap().adapters.remove(&hci_interface);
86 }
87 }
88
on_hci_enabled_changed(&mut self, hci_interface: i32, enabled: bool)89 fn on_hci_enabled_changed(&mut self, hci_interface: i32, enabled: bool) {
90 self.context.lock().unwrap().set_adapter_enabled(hci_interface, enabled);
91 }
92
on_default_adapter_changed(&mut self, hci_interface: i32)93 fn on_default_adapter_changed(&mut self, hci_interface: i32) {
94 print_info!("hci{} is now the default", hci_interface);
95 }
96 }
97
98 impl RPCProxy for BtManagerCallback {
get_object_id(&self) -> String99 fn get_object_id(&self) -> String {
100 self.objpath.clone()
101 }
102
export_for_rpc(self: Box<Self>)103 fn export_for_rpc(self: Box<Self>) {
104 let cr = self.dbus_crossroads.clone();
105 let iface = export_bluetooth_manager_callback_dbus_intf(
106 self.dbus_connection.clone(),
107 &mut cr.lock().unwrap(),
108 Arc::new(Mutex::new(DisconnectWatcher::new())),
109 );
110 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
111 }
112 }
113
114 /// Callback container for adapter interface callbacks.
115 pub(crate) struct BtCallback {
116 objpath: String,
117 context: Arc<Mutex<ClientContext>>,
118
119 dbus_connection: Arc<SyncConnection>,
120 dbus_crossroads: Arc<Mutex<Crossroads>>,
121 }
122
123 impl BtCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self124 pub(crate) fn new(
125 objpath: String,
126 context: Arc<Mutex<ClientContext>>,
127 dbus_connection: Arc<SyncConnection>,
128 dbus_crossroads: Arc<Mutex<Crossroads>>,
129 ) -> Self {
130 Self { objpath, context, dbus_connection, dbus_crossroads }
131 }
132 }
133
134 impl IBluetoothCallback for BtCallback {
on_adapter_property_changed(&mut self, _prop: BtPropertyType)135 fn on_adapter_property_changed(&mut self, _prop: BtPropertyType) {}
136
on_device_properties_changed( &mut self, remote_device: BluetoothDevice, props: Vec<BtPropertyType>, )137 fn on_device_properties_changed(
138 &mut self,
139 remote_device: BluetoothDevice,
140 props: Vec<BtPropertyType>,
141 ) {
142 print_info!(
143 "Bluetooth properties {:?} changed for [{}: {:?}]",
144 props,
145 remote_device.address.to_string(),
146 remote_device.name
147 );
148 }
149
on_address_changed(&mut self, addr: RawAddress)150 fn on_address_changed(&mut self, addr: RawAddress) {
151 print_info!("Address changed to {}", addr.to_string());
152 self.context.lock().unwrap().adapter_address = Some(addr);
153 }
154
on_name_changed(&mut self, name: String)155 fn on_name_changed(&mut self, name: String) {
156 print_info!("Name changed to {}", &name);
157 }
158
on_discoverable_changed(&mut self, discoverable: bool)159 fn on_discoverable_changed(&mut self, discoverable: bool) {
160 print_info!("Discoverable changed to {}", &discoverable);
161 }
162
on_device_found(&mut self, remote_device: BluetoothDevice)163 fn on_device_found(&mut self, remote_device: BluetoothDevice) {
164 self.context
165 .lock()
166 .unwrap()
167 .found_devices
168 .entry(remote_device.address.to_string())
169 .or_insert(remote_device.clone());
170
171 print_info!(
172 "Found device: [{}: {:?}]",
173 remote_device.address.to_string(),
174 remote_device.name
175 );
176 }
177
on_device_cleared(&mut self, remote_device: BluetoothDevice)178 fn on_device_cleared(&mut self, remote_device: BluetoothDevice) {
179 match self.context.lock().unwrap().found_devices.remove(&remote_device.address.to_string())
180 {
181 Some(_) => print_info!(
182 "Removed device: [{}: {:?}]",
183 remote_device.address.to_string(),
184 remote_device.name
185 ),
186 None => (),
187 };
188
189 self.context.lock().unwrap().bonded_devices.remove(&remote_device.address.to_string());
190 }
191
on_discovering_changed(&mut self, discovering: bool)192 fn on_discovering_changed(&mut self, discovering: bool) {
193 self.context.lock().unwrap().discovering_state = discovering;
194
195 print_info!("Discovering: {}", discovering);
196 }
197
on_ssp_request( &mut self, remote_device: BluetoothDevice, _cod: u32, variant: BtSspVariant, passkey: u32, )198 fn on_ssp_request(
199 &mut self,
200 remote_device: BluetoothDevice,
201 _cod: u32,
202 variant: BtSspVariant,
203 passkey: u32,
204 ) {
205 match variant {
206 BtSspVariant::PasskeyNotification | BtSspVariant::PasskeyConfirmation => {
207 print_info!(
208 "Device [{}: {:?}] would like to pair, enter passkey on remote device: {:06}",
209 remote_device.address.to_string(),
210 remote_device.name,
211 passkey
212 );
213 }
214 BtSspVariant::Consent => {
215 let rd = remote_device.clone();
216 self.context.lock().unwrap().run_callback(Box::new(move |context| {
217 // Auto-confirm bonding attempts that were locally initiated.
218 // Ignore all other bonding attempts.
219 let bonding_device = context.lock().unwrap().bonding_attempt.as_ref().cloned();
220 match bonding_device {
221 Some(bd) => {
222 if bd.address == rd.address {
223 context
224 .lock()
225 .unwrap()
226 .adapter_dbus
227 .as_ref()
228 .unwrap()
229 .set_pairing_confirmation(rd.clone(), true);
230 }
231 }
232 None => (),
233 }
234 }));
235 }
236 BtSspVariant::PasskeyEntry => {
237 println!("Got PasskeyEntry but it is not supported...");
238 }
239 }
240 }
241
on_pin_request(&mut self, remote_device: BluetoothDevice, _cod: u32, min_16_digit: bool)242 fn on_pin_request(&mut self, remote_device: BluetoothDevice, _cod: u32, min_16_digit: bool) {
243 print_info!(
244 "Device [{}: {:?}] would like to pair, enter pin code {}",
245 remote_device.address.to_string(),
246 remote_device.name,
247 match min_16_digit {
248 true => "with at least 16 digits",
249 false => "",
250 }
251 );
252 }
253
on_pin_display(&mut self, remote_device: BluetoothDevice, pincode: String)254 fn on_pin_display(&mut self, remote_device: BluetoothDevice, pincode: String) {
255 print_info!(
256 "Device [{}: {:?}] would like to pair, enter pin code {} on the remote",
257 remote_device.address.to_string(),
258 remote_device.name,
259 pincode
260 );
261 }
262
on_bond_state_changed(&mut self, status: u32, address: RawAddress, state: u32)263 fn on_bond_state_changed(&mut self, status: u32, address: RawAddress, state: u32) {
264 print_info!(
265 "Bonding state changed: [{}] state: {}, Status = {}",
266 address.to_string(),
267 state,
268 status
269 );
270
271 // Clear bonding attempt if bonding fails or succeeds
272 match BtBondState::from(state) {
273 BtBondState::NotBonded | BtBondState::Bonded => {
274 let bonding_attempt =
275 self.context.lock().unwrap().bonding_attempt.as_ref().cloned();
276 match bonding_attempt {
277 Some(bd) => {
278 if address == bd.address {
279 self.context.lock().unwrap().bonding_attempt = None;
280 }
281 }
282 None => (),
283 }
284 }
285 BtBondState::Bonding => (),
286 }
287
288 let device = BluetoothDevice { address: address, name: String::from("Classic device") };
289
290 // If bonded, we should also automatically connect all enabled profiles
291 if BtBondState::Bonded == state.into() {
292 self.context.lock().unwrap().bonded_devices.insert(address.to_string(), device.clone());
293 self.context.lock().unwrap().connect_all_enabled_profiles(device.clone());
294 }
295
296 if BtBondState::NotBonded == state.into() {
297 self.context.lock().unwrap().bonded_devices.remove(&address.to_string());
298 }
299 }
300
on_sdp_search_complete( &mut self, remote_device: BluetoothDevice, searched_uuid: Uuid, sdp_records: Vec<BtSdpRecord>, )301 fn on_sdp_search_complete(
302 &mut self,
303 remote_device: BluetoothDevice,
304 searched_uuid: Uuid,
305 sdp_records: Vec<BtSdpRecord>,
306 ) {
307 print_info!(
308 "SDP search of [{}: {:?}] for UUID {} returned {} results",
309 remote_device.address.to_string(),
310 remote_device.name,
311 searched_uuid,
312 sdp_records.len()
313 );
314 if !sdp_records.is_empty() {
315 print_info!("{:?}", sdp_records);
316 }
317 }
318
on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32)319 fn on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32) {
320 print_info!("SDP record handle={} created", handle);
321 if let BtSdpRecord::Mps(_) = record {
322 let context = self.context.clone();
323 // Callbacks first lock the DBus resource and then lock the context,
324 // while the command handlers lock them in the reversed order.
325 // `telephony enable` command happens to deadlock easily,
326 // so use async call to prevent deadlock here.
327 tokio::spawn(async move {
328 context.lock().unwrap().mps_sdp_handle = Some(handle);
329 });
330 }
331 }
332 }
333
334 impl RPCProxy for BtCallback {
get_object_id(&self) -> String335 fn get_object_id(&self) -> String {
336 self.objpath.clone()
337 }
338
export_for_rpc(self: Box<Self>)339 fn export_for_rpc(self: Box<Self>) {
340 let cr = self.dbus_crossroads.clone();
341 let iface = export_bluetooth_callback_dbus_intf(
342 self.dbus_connection.clone(),
343 &mut cr.lock().unwrap(),
344 Arc::new(Mutex::new(DisconnectWatcher::new())),
345 );
346 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
347 }
348 }
349
350 pub(crate) struct BtConnectionCallback {
351 objpath: String,
352 _context: Arc<Mutex<ClientContext>>,
353
354 dbus_connection: Arc<SyncConnection>,
355 dbus_crossroads: Arc<Mutex<Crossroads>>,
356 }
357
358 impl BtConnectionCallback {
new( objpath: String, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self359 pub(crate) fn new(
360 objpath: String,
361 _context: Arc<Mutex<ClientContext>>,
362 dbus_connection: Arc<SyncConnection>,
363 dbus_crossroads: Arc<Mutex<Crossroads>>,
364 ) -> Self {
365 Self { objpath, _context, dbus_connection, dbus_crossroads }
366 }
367 }
368
369 impl IBluetoothConnectionCallback for BtConnectionCallback {
on_device_connected(&mut self, remote_device: BluetoothDevice)370 fn on_device_connected(&mut self, remote_device: BluetoothDevice) {
371 print_info!("Connected: [{}: {:?}]", remote_device.address.to_string(), remote_device.name);
372 }
373
on_device_disconnected(&mut self, remote_device: BluetoothDevice)374 fn on_device_disconnected(&mut self, remote_device: BluetoothDevice) {
375 print_info!(
376 "Disconnected: [{}: {:?}]",
377 remote_device.address.to_string(),
378 remote_device.name
379 );
380 }
381 }
382
383 impl RPCProxy for BtConnectionCallback {
get_object_id(&self) -> String384 fn get_object_id(&self) -> String {
385 self.objpath.clone()
386 }
387
export_for_rpc(self: Box<Self>)388 fn export_for_rpc(self: Box<Self>) {
389 let cr = self.dbus_crossroads.clone();
390 let iface = export_bluetooth_connection_callback_dbus_intf(
391 self.dbus_connection.clone(),
392 &mut cr.lock().unwrap(),
393 Arc::new(Mutex::new(DisconnectWatcher::new())),
394 );
395 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
396 }
397 }
398
399 pub(crate) struct ScannerCallback {
400 objpath: String,
401 context: Arc<Mutex<ClientContext>>,
402
403 dbus_connection: Arc<SyncConnection>,
404 dbus_crossroads: Arc<Mutex<Crossroads>>,
405 }
406
407 impl ScannerCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self408 pub(crate) fn new(
409 objpath: String,
410 context: Arc<Mutex<ClientContext>>,
411 dbus_connection: Arc<SyncConnection>,
412 dbus_crossroads: Arc<Mutex<Crossroads>>,
413 ) -> Self {
414 Self { objpath, context, dbus_connection, dbus_crossroads }
415 }
416 }
417
418 impl IScannerCallback for ScannerCallback {
on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus)419 fn on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus) {
420 if status != GattStatus::Success {
421 print_error!("Failed registering scanner, status = {}", status);
422 return;
423 }
424
425 print_info!("Scanner callback registered, uuid = {}, id = {}", uuid, scanner_id);
426 }
427
on_scan_result(&mut self, scan_result: ScanResult)428 fn on_scan_result(&mut self, scan_result: ScanResult) {
429 if self.context.lock().unwrap().active_scanner_ids.len() > 0 {
430 print_info!("Scan result: {:#?}", scan_result);
431 }
432 }
433
on_advertisement_found(&mut self, scanner_id: u8, scan_result: ScanResult)434 fn on_advertisement_found(&mut self, scanner_id: u8, scan_result: ScanResult) {
435 if self.context.lock().unwrap().active_scanner_ids.len() > 0 {
436 print_info!("Advertisement found for scanner_id {} : {:#?}", scanner_id, scan_result);
437 }
438 }
439
on_advertisement_lost(&mut self, scanner_id: u8, scan_result: ScanResult)440 fn on_advertisement_lost(&mut self, scanner_id: u8, scan_result: ScanResult) {
441 if self.context.lock().unwrap().active_scanner_ids.len() > 0 {
442 print_info!("Advertisement lost for scanner_id {} : {:#?}", scanner_id, scan_result);
443 }
444 }
445
on_suspend_mode_change(&mut self, suspend_mode: SuspendMode)446 fn on_suspend_mode_change(&mut self, suspend_mode: SuspendMode) {
447 if self.context.lock().unwrap().active_scanner_ids.len() > 0 {
448 print_info!("Scan suspend mode change: {:#?}", suspend_mode);
449 }
450 }
451 }
452
453 impl RPCProxy for ScannerCallback {
get_object_id(&self) -> String454 fn get_object_id(&self) -> String {
455 self.objpath.clone()
456 }
457
export_for_rpc(self: Box<Self>)458 fn export_for_rpc(self: Box<Self>) {
459 let cr = self.dbus_crossroads.clone();
460 let iface = export_scanner_callback_dbus_intf(
461 self.dbus_connection.clone(),
462 &mut cr.lock().unwrap(),
463 Arc::new(Mutex::new(DisconnectWatcher::new())),
464 );
465 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
466 }
467 }
468
469 pub(crate) struct AdminCallback {
470 objpath: String,
471
472 dbus_connection: Arc<SyncConnection>,
473 dbus_crossroads: Arc<Mutex<Crossroads>>,
474 }
475
476 impl AdminCallback {
new( objpath: String, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self477 pub(crate) fn new(
478 objpath: String,
479 dbus_connection: Arc<SyncConnection>,
480 dbus_crossroads: Arc<Mutex<Crossroads>>,
481 ) -> Self {
482 Self { objpath, dbus_connection, dbus_crossroads }
483 }
484 }
485
486 impl IBluetoothAdminPolicyCallback for AdminCallback {
on_service_allowlist_changed(&mut self, allowlist: Vec<Uuid>)487 fn on_service_allowlist_changed(&mut self, allowlist: Vec<Uuid>) {
488 print_info!(
489 "new allowlist: [{}]",
490 allowlist.into_iter().map(|uu| uu.to_string()).collect::<Vec<String>>().join(", ")
491 );
492 }
493
on_device_policy_effect_changed( &mut self, device: BluetoothDevice, new_policy_effect: Option<PolicyEffect>, )494 fn on_device_policy_effect_changed(
495 &mut self,
496 device: BluetoothDevice,
497 new_policy_effect: Option<PolicyEffect>,
498 ) {
499 print_info!(
500 "new device policy effect. Device: [{}: {:?}]. New Effect: {:?}",
501 device.address.to_string(),
502 device.name,
503 new_policy_effect
504 );
505 }
506 }
507
508 impl RPCProxy for AdminCallback {
get_object_id(&self) -> String509 fn get_object_id(&self) -> String {
510 self.objpath.clone()
511 }
512
export_for_rpc(self: Box<Self>)513 fn export_for_rpc(self: Box<Self>) {
514 let cr = self.dbus_crossroads.clone();
515 let iface = export_admin_policy_callback_dbus_intf(
516 self.dbus_connection.clone(),
517 &mut cr.lock().unwrap(),
518 Arc::new(Mutex::new(DisconnectWatcher::new())),
519 );
520 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
521 }
522 }
523
524 pub(crate) struct AdvertisingSetCallback {
525 objpath: String,
526 context: Arc<Mutex<ClientContext>>,
527
528 dbus_connection: Arc<SyncConnection>,
529 dbus_crossroads: Arc<Mutex<Crossroads>>,
530 }
531
532 impl AdvertisingSetCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self533 pub(crate) fn new(
534 objpath: String,
535 context: Arc<Mutex<ClientContext>>,
536 dbus_connection: Arc<SyncConnection>,
537 dbus_crossroads: Arc<Mutex<Crossroads>>,
538 ) -> Self {
539 Self { objpath, context, dbus_connection, dbus_crossroads }
540 }
541 }
542
543 impl IAdvertisingSetCallback for AdvertisingSetCallback {
on_advertising_set_started( &mut self, reg_id: i32, advertiser_id: i32, tx_power: i32, status: AdvertisingStatus, )544 fn on_advertising_set_started(
545 &mut self,
546 reg_id: i32,
547 advertiser_id: i32,
548 tx_power: i32,
549 status: AdvertisingStatus,
550 ) {
551 print_info!(
552 "on_advertising_set_started: reg_id = {}, advertiser_id = {}, tx_power = {}, status = {:?}",
553 reg_id,
554 advertiser_id,
555 tx_power,
556 status
557 );
558
559 let mut context = self.context.lock().unwrap();
560 if status != AdvertisingStatus::Success {
561 print_error!(
562 "on_advertising_set_started: removing advertising set registered ({})",
563 reg_id
564 );
565 context.adv_sets.remove(®_id);
566 return;
567 }
568 if let Some(s) = context.adv_sets.get_mut(®_id) {
569 s.adv_id = Some(advertiser_id);
570 } else {
571 print_error!("on_advertising_set_started: invalid callback for reg_id={}", reg_id);
572 }
573 }
574
on_own_address_read(&mut self, advertiser_id: i32, address_type: i32, address: RawAddress)575 fn on_own_address_read(&mut self, advertiser_id: i32, address_type: i32, address: RawAddress) {
576 print_info!(
577 "on_own_address_read: advertiser_id = {}, address_type = {}, address = {}",
578 advertiser_id,
579 address_type,
580 address.to_string()
581 );
582 }
583
on_advertising_set_stopped(&mut self, advertiser_id: i32)584 fn on_advertising_set_stopped(&mut self, advertiser_id: i32) {
585 print_info!("on_advertising_set_stopped: advertiser_id = {}", advertiser_id);
586 }
587
on_advertising_enabled( &mut self, advertiser_id: i32, enable: bool, status: AdvertisingStatus, )588 fn on_advertising_enabled(
589 &mut self,
590 advertiser_id: i32,
591 enable: bool,
592 status: AdvertisingStatus,
593 ) {
594 print_info!(
595 "on_advertising_enabled: advertiser_id = {}, enable = {}, status = {:?}",
596 advertiser_id,
597 enable,
598 status
599 );
600 }
601
on_advertising_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus)602 fn on_advertising_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus) {
603 print_info!(
604 "on_advertising_data_set: advertiser_id = {}, status = {:?}",
605 advertiser_id,
606 status
607 );
608 }
609
on_scan_response_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus)610 fn on_scan_response_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus) {
611 print_info!(
612 "on_scan_response_data_set: advertiser_id = {}, status = {:?}",
613 advertiser_id,
614 status
615 );
616 }
617
on_advertising_parameters_updated( &mut self, advertiser_id: i32, tx_power: i32, status: AdvertisingStatus, )618 fn on_advertising_parameters_updated(
619 &mut self,
620 advertiser_id: i32,
621 tx_power: i32,
622 status: AdvertisingStatus,
623 ) {
624 print_info!(
625 "on_advertising_parameters_updated: advertiser_id = {}, tx_power: {}, status = {:?}",
626 advertiser_id,
627 tx_power,
628 status
629 );
630 }
631
on_periodic_advertising_parameters_updated( &mut self, advertiser_id: i32, status: AdvertisingStatus, )632 fn on_periodic_advertising_parameters_updated(
633 &mut self,
634 advertiser_id: i32,
635 status: AdvertisingStatus,
636 ) {
637 print_info!(
638 "on_periodic_advertising_parameters_updated: advertiser_id = {}, status = {:?}",
639 advertiser_id,
640 status
641 );
642 }
643
on_periodic_advertising_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus)644 fn on_periodic_advertising_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus) {
645 print_info!(
646 "on_periodic_advertising_data_set: advertiser_id = {}, status = {:?}",
647 advertiser_id,
648 status
649 );
650 }
651
on_periodic_advertising_enabled( &mut self, advertiser_id: i32, enable: bool, status: AdvertisingStatus, )652 fn on_periodic_advertising_enabled(
653 &mut self,
654 advertiser_id: i32,
655 enable: bool,
656 status: AdvertisingStatus,
657 ) {
658 print_info!(
659 "on_periodic_advertising_enabled: advertiser_id = {}, enable = {}, status = {:?}",
660 advertiser_id,
661 enable,
662 status
663 );
664 }
665
on_suspend_mode_change(&mut self, suspend_mode: SuspendMode)666 fn on_suspend_mode_change(&mut self, suspend_mode: SuspendMode) {
667 print_info!("on_suspend_mode_change: advertising suspend_mode = {:?}", suspend_mode);
668 }
669 }
670
671 impl RPCProxy for AdvertisingSetCallback {
get_object_id(&self) -> String672 fn get_object_id(&self) -> String {
673 self.objpath.clone()
674 }
675
export_for_rpc(self: Box<Self>)676 fn export_for_rpc(self: Box<Self>) {
677 let cr = self.dbus_crossroads.clone();
678 let iface = export_advertising_set_callback_dbus_intf(
679 self.dbus_connection.clone(),
680 &mut cr.lock().unwrap(),
681 Arc::new(Mutex::new(DisconnectWatcher::new())),
682 );
683 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
684 }
685 }
686
687 pub(crate) struct BtGattCallback {
688 objpath: String,
689 context: Arc<Mutex<ClientContext>>,
690
691 dbus_connection: Arc<SyncConnection>,
692 dbus_crossroads: Arc<Mutex<Crossroads>>,
693 }
694
695 impl BtGattCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self696 pub(crate) fn new(
697 objpath: String,
698 context: Arc<Mutex<ClientContext>>,
699 dbus_connection: Arc<SyncConnection>,
700 dbus_crossroads: Arc<Mutex<Crossroads>>,
701 ) -> Self {
702 Self { objpath, context, dbus_connection, dbus_crossroads }
703 }
704 }
705
706 impl IBluetoothGattCallback for BtGattCallback {
on_client_registered(&mut self, status: GattStatus, client_id: i32)707 fn on_client_registered(&mut self, status: GattStatus, client_id: i32) {
708 print_info!("GATT Client registered status = {}, client_id = {}", status, client_id);
709 self.context.lock().unwrap().gatt_client_context.client_id = Some(client_id);
710 }
711
on_client_connection_state( &mut self, status: GattStatus, client_id: i32, connected: bool, addr: RawAddress, )712 fn on_client_connection_state(
713 &mut self,
714 status: GattStatus,
715 client_id: i32,
716 connected: bool,
717 addr: RawAddress,
718 ) {
719 print_info!(
720 "GATT Client connection state = {}, client_id = {}, connected = {}, addr = {}",
721 status,
722 client_id,
723 connected,
724 addr.to_string()
725 );
726 }
727
on_phy_update( &mut self, addr: RawAddress, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus, )728 fn on_phy_update(
729 &mut self,
730 addr: RawAddress,
731 tx_phy: LePhy,
732 rx_phy: LePhy,
733 status: GattStatus,
734 ) {
735 print_info!(
736 "Phy updated: addr = {}, tx_phy = {:?}, rx_phy = {:?}, status = {:?}",
737 addr.to_string(),
738 tx_phy,
739 rx_phy,
740 status
741 );
742 }
743
on_phy_read(&mut self, addr: RawAddress, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus)744 fn on_phy_read(&mut self, addr: RawAddress, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus) {
745 print_info!(
746 "Phy read: addr = {}, tx_phy = {:?}, rx_phy = {:?}, status = {:?}",
747 addr.to_string(),
748 tx_phy,
749 rx_phy,
750 status
751 );
752 }
753
on_search_complete( &mut self, addr: RawAddress, services: Vec<BluetoothGattService>, status: GattStatus, )754 fn on_search_complete(
755 &mut self,
756 addr: RawAddress,
757 services: Vec<BluetoothGattService>,
758 status: GattStatus,
759 ) {
760 print_info!(
761 "GATT DB Search complete: addr = {}, services = {:?}, status = {}",
762 addr.to_string(),
763 services,
764 status
765 );
766 }
767
on_characteristic_read( &mut self, addr: RawAddress, status: GattStatus, handle: i32, value: Vec<u8>, )768 fn on_characteristic_read(
769 &mut self,
770 addr: RawAddress,
771 status: GattStatus,
772 handle: i32,
773 value: Vec<u8>,
774 ) {
775 print_info!(
776 "GATT Characteristic read: addr = {}, status = {}, handle = {}, value = {:?}",
777 addr.to_string(),
778 status,
779 handle,
780 value
781 );
782 }
783
on_characteristic_write(&mut self, addr: RawAddress, status: GattStatus, handle: i32)784 fn on_characteristic_write(&mut self, addr: RawAddress, status: GattStatus, handle: i32) {
785 print_info!(
786 "GATT Characteristic write: addr = {}, status = {}, handle = {}",
787 addr.to_string(),
788 status,
789 handle
790 );
791 }
792
on_execute_write(&mut self, addr: RawAddress, status: GattStatus)793 fn on_execute_write(&mut self, addr: RawAddress, status: GattStatus) {
794 print_info!("GATT execute write addr = {}, status = {}", addr.to_string(), status);
795 }
796
on_descriptor_read( &mut self, addr: RawAddress, status: GattStatus, handle: i32, value: Vec<u8>, )797 fn on_descriptor_read(
798 &mut self,
799 addr: RawAddress,
800 status: GattStatus,
801 handle: i32,
802 value: Vec<u8>,
803 ) {
804 print_info!(
805 "GATT Descriptor read: addr = {}, status = {}, handle = {}, value = {:?}",
806 addr.to_string(),
807 status,
808 handle,
809 value
810 );
811 }
812
on_descriptor_write(&mut self, addr: RawAddress, status: GattStatus, handle: i32)813 fn on_descriptor_write(&mut self, addr: RawAddress, status: GattStatus, handle: i32) {
814 print_info!(
815 "GATT Descriptor write: addr = {}, status = {}, handle = {}",
816 addr.to_string(),
817 status,
818 handle
819 );
820 }
821
on_notify(&mut self, addr: RawAddress, handle: i32, value: Vec<u8>)822 fn on_notify(&mut self, addr: RawAddress, handle: i32, value: Vec<u8>) {
823 print_info!(
824 "GATT Notification: addr = {}, handle = {}, value = {:?}",
825 addr.to_string(),
826 handle,
827 value
828 );
829 }
830
on_read_remote_rssi(&mut self, addr: RawAddress, rssi: i32, status: GattStatus)831 fn on_read_remote_rssi(&mut self, addr: RawAddress, rssi: i32, status: GattStatus) {
832 print_info!(
833 "Remote RSSI read: addr = {}, rssi = {}, status = {}",
834 addr.to_string(),
835 rssi,
836 status
837 );
838 }
839
on_configure_mtu(&mut self, addr: RawAddress, mtu: i32, status: GattStatus)840 fn on_configure_mtu(&mut self, addr: RawAddress, mtu: i32, status: GattStatus) {
841 print_info!(
842 "MTU configured: addr = {}, mtu = {}, status = {}",
843 addr.to_string(),
844 mtu,
845 status
846 );
847 }
848
on_connection_updated( &mut self, addr: RawAddress, interval: i32, latency: i32, timeout: i32, status: GattStatus, )849 fn on_connection_updated(
850 &mut self,
851 addr: RawAddress,
852 interval: i32,
853 latency: i32,
854 timeout: i32,
855 status: GattStatus,
856 ) {
857 print_info!(
858 "Connection updated: addr = {}, interval = {}, latency = {}, timeout = {}, status = {}",
859 addr.to_string(),
860 interval,
861 latency,
862 timeout,
863 status
864 );
865 }
866
on_service_changed(&mut self, addr: RawAddress)867 fn on_service_changed(&mut self, addr: RawAddress) {
868 print_info!("Service changed for {}", addr.to_string());
869 }
870 }
871
872 impl RPCProxy for BtGattCallback {
get_object_id(&self) -> String873 fn get_object_id(&self) -> String {
874 self.objpath.clone()
875 }
876
export_for_rpc(self: Box<Self>)877 fn export_for_rpc(self: Box<Self>) {
878 let cr = self.dbus_crossroads.clone();
879 let iface = export_bluetooth_gatt_callback_dbus_intf(
880 self.dbus_connection.clone(),
881 &mut cr.lock().unwrap(),
882 Arc::new(Mutex::new(DisconnectWatcher::new())),
883 );
884
885 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
886 }
887 }
888
889 pub(crate) struct BtGattServerCallback {
890 objpath: String,
891 context: Arc<Mutex<ClientContext>>,
892
893 dbus_connection: Arc<SyncConnection>,
894 dbus_crossroads: Arc<Mutex<Crossroads>>,
895 }
896
897 impl BtGattServerCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self898 pub(crate) fn new(
899 objpath: String,
900 context: Arc<Mutex<ClientContext>>,
901 dbus_connection: Arc<SyncConnection>,
902 dbus_crossroads: Arc<Mutex<Crossroads>>,
903 ) -> Self {
904 Self { objpath, context, dbus_connection, dbus_crossroads }
905 }
906 }
907
908 impl IBluetoothGattServerCallback for BtGattServerCallback {
on_server_registered(&mut self, status: GattStatus, server_id: i32)909 fn on_server_registered(&mut self, status: GattStatus, server_id: i32) {
910 print_info!("GATT Server registered status = {}, server_id = {}", status, server_id);
911 }
912
on_server_connection_state(&mut self, server_id: i32, connected: bool, addr: RawAddress)913 fn on_server_connection_state(&mut self, server_id: i32, connected: bool, addr: RawAddress) {
914 print_info!(
915 "GATT server connection with server_id = {}, connected = {}, addr = {}",
916 server_id,
917 connected,
918 addr.to_string()
919 );
920 }
921
on_service_added(&mut self, status: GattStatus, service: BluetoothGattService)922 fn on_service_added(&mut self, status: GattStatus, service: BluetoothGattService) {
923 print_info!("GATT service added with status = {}, service = {:?}", status, service)
924 }
925
on_service_removed(&mut self, status: GattStatus, handle: i32)926 fn on_service_removed(&mut self, status: GattStatus, handle: i32) {
927 print_info!("GATT service removed with status = {}, handle = {:?}", status, handle);
928 }
929
on_characteristic_read_request( &mut self, addr: RawAddress, trans_id: i32, offset: i32, is_long: bool, handle: i32, )930 fn on_characteristic_read_request(
931 &mut self,
932 addr: RawAddress,
933 trans_id: i32,
934 offset: i32,
935 is_long: bool,
936 handle: i32,
937 ) {
938 print_info!(
939 "GATT characteristic read request for addr = {}, trans_id = {}, offset = {}, is_long = {}, handle = {}",
940 addr.to_string(),
941 trans_id,
942 offset,
943 is_long,
944 handle
945 );
946
947 if self.context.lock().unwrap().pending_gatt_request.is_some() {
948 print_info!(
949 "This request will be dropped because the previous one has not been responded to"
950 );
951 return;
952 }
953 self.context.lock().unwrap().pending_gatt_request =
954 Some(GattRequest { address: addr, id: trans_id, offset: offset, value: vec![] });
955 }
956
on_descriptor_read_request( &mut self, addr: RawAddress, trans_id: i32, offset: i32, is_long: bool, handle: i32, )957 fn on_descriptor_read_request(
958 &mut self,
959 addr: RawAddress,
960 trans_id: i32,
961 offset: i32,
962 is_long: bool,
963 handle: i32,
964 ) {
965 print_info!(
966 "GATT descriptor read request for addr = {}, trans_id = {}, offset = {}, is_long = {}, handle = {}",
967 addr.to_string(),
968 trans_id,
969 offset,
970 is_long,
971 handle
972 );
973
974 if self.context.lock().unwrap().pending_gatt_request.is_some() {
975 print_info!(
976 "This request will be dropped because the previous one has not been responded to"
977 );
978 return;
979 }
980 self.context.lock().unwrap().pending_gatt_request =
981 Some(GattRequest { address: addr, id: trans_id, offset: offset, value: vec![] });
982 }
983
on_characteristic_write_request( &mut self, addr: RawAddress, trans_id: i32, offset: i32, len: i32, is_prep: bool, need_rsp: bool, handle: i32, value: Vec<u8>, )984 fn on_characteristic_write_request(
985 &mut self,
986 addr: RawAddress,
987 trans_id: i32,
988 offset: i32,
989 len: i32,
990 is_prep: bool,
991 need_rsp: bool,
992 handle: i32,
993 value: Vec<u8>,
994 ) {
995 print_info!(
996 "GATT characteristic write request for \
997 addr = {}, trans_id = {}, offset = {}, len = {}, is_prep = {}, need_rsp = {}, handle = {}, value = {:?}",
998 addr.to_string(),
999 trans_id,
1000 offset,
1001 len,
1002 is_prep,
1003 need_rsp,
1004 handle,
1005 value
1006 );
1007
1008 if self.context.lock().unwrap().pending_gatt_request.is_some() {
1009 print_info!(
1010 "This request will be dropped because the previous one has not been responded to"
1011 );
1012 return;
1013 }
1014 self.context.lock().unwrap().pending_gatt_request =
1015 Some(GattRequest { address: addr, id: trans_id, offset: offset, value: value });
1016 }
1017
on_descriptor_write_request( &mut self, addr: RawAddress, trans_id: i32, offset: i32, len: i32, is_prep: bool, need_rsp: bool, handle: i32, value: Vec<u8>, )1018 fn on_descriptor_write_request(
1019 &mut self,
1020 addr: RawAddress,
1021 trans_id: i32,
1022 offset: i32,
1023 len: i32,
1024 is_prep: bool,
1025 need_rsp: bool,
1026 handle: i32,
1027 value: Vec<u8>,
1028 ) {
1029 print_info!(
1030 "GATT descriptor write request for \
1031 addr = {}, trans_id = {}, offset = {}, len = {}, is_prep = {}, need_rsp = {}, handle = {}, value = {:?}",
1032 addr.to_string(),
1033 trans_id,
1034 offset,
1035 len,
1036 is_prep,
1037 need_rsp,
1038 handle,
1039 value
1040 );
1041
1042 if self.context.lock().unwrap().pending_gatt_request.is_some() {
1043 print_info!(
1044 "This request will be dropped because the previous one has not been responded to"
1045 );
1046 return;
1047 }
1048 self.context.lock().unwrap().pending_gatt_request =
1049 Some(GattRequest { address: addr, id: trans_id, offset: offset, value: value });
1050 }
1051
on_execute_write(&mut self, addr: RawAddress, trans_id: i32, exec_write: bool)1052 fn on_execute_write(&mut self, addr: RawAddress, trans_id: i32, exec_write: bool) {
1053 print_info!(
1054 "GATT executed write for addr = {}, trans_id = {}, exec_write = {}",
1055 addr.to_string(),
1056 trans_id,
1057 exec_write
1058 );
1059
1060 if self.context.lock().unwrap().pending_gatt_request.is_some() {
1061 print_info!(
1062 "This request will be dropped because the previous one has not been responded to"
1063 );
1064 return;
1065 }
1066 self.context.lock().unwrap().pending_gatt_request =
1067 Some(GattRequest { address: addr, id: trans_id, offset: 0, value: vec![] });
1068 }
1069
on_notification_sent(&mut self, addr: RawAddress, status: GattStatus)1070 fn on_notification_sent(&mut self, addr: RawAddress, status: GattStatus) {
1071 print_info!(
1072 "GATT notification/indication sent for addr = {} with status = {}",
1073 addr.to_string(),
1074 status
1075 );
1076 }
1077
on_mtu_changed(&mut self, addr: RawAddress, mtu: i32)1078 fn on_mtu_changed(&mut self, addr: RawAddress, mtu: i32) {
1079 print_info!("GATT server MTU changed for addr = {}, mtu = {}", addr.to_string(), mtu);
1080 }
1081
on_phy_update( &mut self, addr: RawAddress, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus, )1082 fn on_phy_update(
1083 &mut self,
1084 addr: RawAddress,
1085 tx_phy: LePhy,
1086 rx_phy: LePhy,
1087 status: GattStatus,
1088 ) {
1089 print_info!(
1090 "GATT server phy updated for addr = {}: tx_phy = {:?}, rx_phy = {:?}, status = {}",
1091 addr.to_string(),
1092 tx_phy,
1093 rx_phy,
1094 status
1095 );
1096 }
1097
on_phy_read(&mut self, addr: RawAddress, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus)1098 fn on_phy_read(&mut self, addr: RawAddress, tx_phy: LePhy, rx_phy: LePhy, status: GattStatus) {
1099 print_info!(
1100 "GATT server phy read for addr = {}: tx_phy = {:?}, rx_phy = {:?}, status = {}",
1101 addr.to_string(),
1102 tx_phy,
1103 rx_phy,
1104 status
1105 );
1106 }
1107
on_connection_updated( &mut self, addr: RawAddress, interval: i32, latency: i32, timeout: i32, status: GattStatus, )1108 fn on_connection_updated(
1109 &mut self,
1110 addr: RawAddress,
1111 interval: i32,
1112 latency: i32,
1113 timeout: i32,
1114 status: GattStatus,
1115 ) {
1116 print_info!(
1117 "GATT server connection updated for addr = {}, interval = {}, latency = {}, timeout = {}, status = {}",
1118 addr.to_string(),
1119 interval,
1120 latency,
1121 timeout,
1122 status
1123 );
1124 }
1125
on_subrate_change( &mut self, addr: RawAddress, subrate_factor: i32, latency: i32, cont_num: i32, timeout: i32, status: GattStatus, )1126 fn on_subrate_change(
1127 &mut self,
1128 addr: RawAddress,
1129 subrate_factor: i32,
1130 latency: i32,
1131 cont_num: i32,
1132 timeout: i32,
1133 status: GattStatus,
1134 ) {
1135 print_info!(
1136 "GATT server subrate changed for addr = {}, subrate_factor = {}, latency = {}, cont_num = {}, timeout = {}, status = {}",
1137 addr.to_string(),
1138 subrate_factor,
1139 latency,
1140 cont_num,
1141 timeout,
1142 status
1143 );
1144 }
1145 }
1146
1147 impl RPCProxy for BtGattServerCallback {
get_object_id(&self) -> String1148 fn get_object_id(&self) -> String {
1149 self.objpath.clone()
1150 }
1151
export_for_rpc(self: Box<Self>)1152 fn export_for_rpc(self: Box<Self>) {
1153 let cr = self.dbus_crossroads.clone();
1154 let iface = export_gatt_server_callback_dbus_intf(
1155 self.dbus_connection.clone(),
1156 &mut cr.lock().unwrap(),
1157 Arc::new(Mutex::new(DisconnectWatcher::new())),
1158 );
1159
1160 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
1161 }
1162 }
1163
1164 pub(crate) struct BtSocketManagerCallback {
1165 objpath: String,
1166 context: Arc<Mutex<ClientContext>>,
1167 dbus_connection: Arc<SyncConnection>,
1168 dbus_crossroads: Arc<Mutex<Crossroads>>,
1169 }
1170
1171 impl BtSocketManagerCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self1172 pub(crate) fn new(
1173 objpath: String,
1174 context: Arc<Mutex<ClientContext>>,
1175 dbus_connection: Arc<SyncConnection>,
1176 dbus_crossroads: Arc<Mutex<Crossroads>>,
1177 ) -> Self {
1178 Self { objpath, context, dbus_connection, dbus_crossroads }
1179 }
1180
start_socket_schedule(&mut self, socket: BluetoothSocket)1181 fn start_socket_schedule(&mut self, socket: BluetoothSocket) {
1182 let SocketSchedule { num_frame, send_interval, disconnect_delay } =
1183 match self.context.lock().unwrap().socket_test_schedule {
1184 Some(s) => s,
1185 None => return,
1186 };
1187
1188 let mut fd = match socket.fd {
1189 Some(fd) => fd,
1190 None => {
1191 print_error!("incoming connection fd is None. Unable to send data");
1192 return;
1193 }
1194 };
1195
1196 tokio::spawn(async move {
1197 for i in 0..num_frame {
1198 fd.write_all(SOCKET_TEST_WRITE).ok();
1199 print_info!("data sent: {}", i + 1);
1200 tokio::time::sleep(send_interval).await;
1201 }
1202
1203 // dump any incoming data
1204 let interval = 100;
1205 for _d in (0..=disconnect_delay.as_millis()).step_by(interval) {
1206 let mut buf = [0; 128];
1207 let sz = fd.read(&mut buf).unwrap();
1208 let data = buf[..sz].to_vec();
1209 if sz > 0 {
1210 print_info!("received {} bytes: {:?}", sz, data);
1211 }
1212 tokio::time::sleep(Duration::from_millis(interval as u64)).await;
1213 }
1214
1215 //|fd| is dropped automatically when the scope ends.
1216 });
1217 }
1218 }
1219
1220 impl IBluetoothSocketManagerCallbacks for BtSocketManagerCallback {
on_incoming_socket_ready(&mut self, socket: BluetoothServerSocket, status: BtStatus)1221 fn on_incoming_socket_ready(&mut self, socket: BluetoothServerSocket, status: BtStatus) {
1222 if status != BtStatus::Success {
1223 print_error!(
1224 "Incoming socket {} failed to be ready, type = {:?}, flags = {}, status = {:?}",
1225 socket.id,
1226 socket.sock_type,
1227 socket.flags,
1228 status,
1229 );
1230 return;
1231 }
1232
1233 print_info!(
1234 "Socket {} ready, details: {:?}, flags = {}, psm = {:?}, channel = {:?}, name = {:?}, uuid = {:?}",
1235 socket.id,
1236 socket.sock_type,
1237 socket.flags,
1238 socket.psm,
1239 socket.channel,
1240 socket.name,
1241 socket.uuid,
1242 );
1243
1244 let callback_id = self.context.lock().unwrap().socket_manager_callback_id.clone().unwrap();
1245
1246 self.context.lock().unwrap().run_callback(Box::new(move |context| {
1247 let status = context.lock().unwrap().socket_manager_dbus.as_mut().unwrap().accept(
1248 callback_id,
1249 socket.id,
1250 None,
1251 );
1252 if status != BtStatus::Success {
1253 print_error!("Failed to accept socket {}, status = {:?}", socket.id, status);
1254 return;
1255 }
1256 print_info!("Requested for accepting socket {}", socket.id);
1257 }));
1258 }
1259
on_incoming_socket_closed(&mut self, listener_id: SocketId, reason: BtStatus)1260 fn on_incoming_socket_closed(&mut self, listener_id: SocketId, reason: BtStatus) {
1261 print_info!("Socket {} closed, reason = {:?}", listener_id, reason);
1262 }
1263
on_handle_incoming_connection( &mut self, listener_id: SocketId, connection: BluetoothSocket, )1264 fn on_handle_incoming_connection(
1265 &mut self,
1266 listener_id: SocketId,
1267 connection: BluetoothSocket,
1268 ) {
1269 print_info!("Socket {} connected", listener_id);
1270 self.start_socket_schedule(connection);
1271 }
1272
on_outgoing_connection_result( &mut self, connecting_id: SocketId, result: BtStatus, socket: Option<BluetoothSocket>, )1273 fn on_outgoing_connection_result(
1274 &mut self,
1275 connecting_id: SocketId,
1276 result: BtStatus,
1277 socket: Option<BluetoothSocket>,
1278 ) {
1279 if let Some(s) = socket {
1280 print_info!("Connection success on {}: {:?} for {}", connecting_id, result, s);
1281 self.start_socket_schedule(s);
1282 } else {
1283 print_info!("Connection failed on {}: {:?}", connecting_id, result);
1284 }
1285 }
1286 }
1287
1288 impl RPCProxy for BtSocketManagerCallback {
get_object_id(&self) -> String1289 fn get_object_id(&self) -> String {
1290 self.objpath.clone()
1291 }
1292
export_for_rpc(self: Box<Self>)1293 fn export_for_rpc(self: Box<Self>) {
1294 let cr = self.dbus_crossroads.clone();
1295 let iface = export_socket_callback_dbus_intf(
1296 self.dbus_connection.clone(),
1297 &mut cr.lock().unwrap(),
1298 Arc::new(Mutex::new(DisconnectWatcher::new())),
1299 );
1300 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
1301 }
1302 }
1303
1304 /// Callback container for suspend interface callbacks.
1305 pub(crate) struct SuspendCallback {
1306 objpath: String,
1307
1308 dbus_connection: Arc<SyncConnection>,
1309 dbus_crossroads: Arc<Mutex<Crossroads>>,
1310 }
1311
1312 impl SuspendCallback {
new( objpath: String, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self1313 pub(crate) fn new(
1314 objpath: String,
1315 dbus_connection: Arc<SyncConnection>,
1316 dbus_crossroads: Arc<Mutex<Crossroads>>,
1317 ) -> Self {
1318 Self { objpath, dbus_connection, dbus_crossroads }
1319 }
1320 }
1321
1322 impl ISuspendCallback for SuspendCallback {
1323 // TODO(b/224606285): Implement suspend utils in btclient.
on_callback_registered(&mut self, _callback_id: u32)1324 fn on_callback_registered(&mut self, _callback_id: u32) {}
on_suspend_ready(&mut self, _suspend_id: i32)1325 fn on_suspend_ready(&mut self, _suspend_id: i32) {}
on_resumed(&mut self, _suspend_id: i32)1326 fn on_resumed(&mut self, _suspend_id: i32) {}
1327 }
1328
1329 impl RPCProxy for SuspendCallback {
get_object_id(&self) -> String1330 fn get_object_id(&self) -> String {
1331 self.objpath.clone()
1332 }
1333
export_for_rpc(self: Box<Self>)1334 fn export_for_rpc(self: Box<Self>) {
1335 let cr = self.dbus_crossroads.clone();
1336 let iface = export_suspend_callback_dbus_intf(
1337 self.dbus_connection.clone(),
1338 &mut cr.lock().unwrap(),
1339 Arc::new(Mutex::new(DisconnectWatcher::new())),
1340 );
1341 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
1342 }
1343 }
1344
1345 /// Callback container for suspend interface callbacks.
1346 pub(crate) struct QACallback {
1347 objpath: String,
1348 _context: Arc<Mutex<ClientContext>>,
1349 dbus_connection: Arc<SyncConnection>,
1350 dbus_crossroads: Arc<Mutex<Crossroads>>,
1351 }
1352
1353 impl QACallback {
new( objpath: String, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self1354 pub(crate) fn new(
1355 objpath: String,
1356 _context: Arc<Mutex<ClientContext>>,
1357 dbus_connection: Arc<SyncConnection>,
1358 dbus_crossroads: Arc<Mutex<Crossroads>>,
1359 ) -> Self {
1360 Self { objpath, _context, dbus_connection, dbus_crossroads }
1361 }
1362 }
1363
1364 impl IBluetoothQACallback for QACallback {
on_fetch_discoverable_mode_completed(&mut self, mode: bt_topshim::btif::BtDiscMode)1365 fn on_fetch_discoverable_mode_completed(&mut self, mode: bt_topshim::btif::BtDiscMode) {
1366 print_info!("Discoverable mode: {:?}", mode);
1367 }
1368
on_fetch_connectable_completed(&mut self, connectable: bool)1369 fn on_fetch_connectable_completed(&mut self, connectable: bool) {
1370 print_info!("Connectable mode: {:?}", connectable);
1371 }
1372
on_set_connectable_completed(&mut self, succeed: bool)1373 fn on_set_connectable_completed(&mut self, succeed: bool) {
1374 print_info!(
1375 "Set connectable mode: {}",
1376 match succeed {
1377 true => "succeeded",
1378 false => "failed",
1379 }
1380 );
1381 }
1382
on_fetch_alias_completed(&mut self, alias: String)1383 fn on_fetch_alias_completed(&mut self, alias: String) {
1384 print_info!("Alias: {}", alias);
1385 }
1386
on_get_hid_report_completed(&mut self, status: BtStatus)1387 fn on_get_hid_report_completed(&mut self, status: BtStatus) {
1388 print_info!("Get HID report: {:?}", status);
1389 }
1390
on_set_hid_report_completed(&mut self, status: BtStatus)1391 fn on_set_hid_report_completed(&mut self, status: BtStatus) {
1392 print_info!("Set HID report: {:?}", status);
1393 }
1394
on_send_hid_data_completed(&mut self, status: BtStatus)1395 fn on_send_hid_data_completed(&mut self, status: BtStatus) {
1396 print_info!("Send HID data: {:?}", status);
1397 }
1398 }
1399
1400 impl RPCProxy for QACallback {
get_object_id(&self) -> String1401 fn get_object_id(&self) -> String {
1402 self.objpath.clone()
1403 }
1404
export_for_rpc(self: Box<Self>)1405 fn export_for_rpc(self: Box<Self>) {
1406 let cr = self.dbus_crossroads.clone();
1407 let iface = export_qa_callback_dbus_intf(
1408 self.dbus_connection.clone(),
1409 &mut cr.lock().unwrap(),
1410 Arc::new(Mutex::new(DisconnectWatcher::new())),
1411 );
1412 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
1413 }
1414 }
1415
1416 pub(crate) struct MediaCallback {
1417 objpath: String,
1418 context: Arc<Mutex<ClientContext>>,
1419
1420 dbus_connection: Arc<SyncConnection>,
1421 dbus_crossroads: Arc<Mutex<Crossroads>>,
1422 }
1423
1424 impl MediaCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self1425 pub(crate) fn new(
1426 objpath: String,
1427 context: Arc<Mutex<ClientContext>>,
1428 dbus_connection: Arc<SyncConnection>,
1429 dbus_crossroads: Arc<Mutex<Crossroads>>,
1430 ) -> Self {
1431 Self { objpath, context, dbus_connection, dbus_crossroads }
1432 }
1433 }
1434
timestamp_to_string(ts_in_us: u64) -> String1435 fn timestamp_to_string(ts_in_us: u64) -> String {
1436 i64::try_from(ts_in_us)
1437 .and_then(|ts| Ok(Utc.timestamp_nanos(ts * 1000).to_rfc3339()))
1438 .unwrap_or("UNKNOWN".to_string())
1439 }
1440
1441 impl IBluetoothMediaCallback for MediaCallback {
1442 // TODO(b/333341411): implement callbacks for client as necessary
on_lea_group_connected(&mut self, _group_id: i32, _name: String)1443 fn on_lea_group_connected(&mut self, _group_id: i32, _name: String) {}
on_lea_group_disconnected(&mut self, _group_id: i32)1444 fn on_lea_group_disconnected(&mut self, _group_id: i32) {}
on_lea_group_status(&mut self, _group_id: i32, _status: BtLeAudioGroupStatus)1445 fn on_lea_group_status(&mut self, _group_id: i32, _status: BtLeAudioGroupStatus) {}
on_lea_group_node_status( &mut self, _addr: RawAddress, _group_id: i32, _status: BtLeAudioGroupNodeStatus, )1446 fn on_lea_group_node_status(
1447 &mut self,
1448 _addr: RawAddress,
1449 _group_id: i32,
1450 _status: BtLeAudioGroupNodeStatus,
1451 ) {
1452 }
on_lea_audio_conf( &mut self, _direction: u8, _group_id: i32, _snk_audio_location: u32, _src_audio_location: u32, _avail_cont: u16, )1453 fn on_lea_audio_conf(
1454 &mut self,
1455 _direction: u8,
1456 _group_id: i32,
1457 _snk_audio_location: u32,
1458 _src_audio_location: u32,
1459 _avail_cont: u16,
1460 ) {
1461 }
on_lea_unicast_monitor_mode_status( &mut self, _direction: BtLeAudioDirection, _status: BtLeAudioUnicastMonitorModeStatus, )1462 fn on_lea_unicast_monitor_mode_status(
1463 &mut self,
1464 _direction: BtLeAudioDirection,
1465 _status: BtLeAudioUnicastMonitorModeStatus,
1466 ) {
1467 }
on_lea_group_stream_status(&mut self, _group_id: i32, _status: BtLeAudioGroupStreamStatus)1468 fn on_lea_group_stream_status(&mut self, _group_id: i32, _status: BtLeAudioGroupStreamStatus) {}
on_lea_vc_connected(&mut self, _addr: RawAddress, _group_id: i32)1469 fn on_lea_vc_connected(&mut self, _addr: RawAddress, _group_id: i32) {}
on_lea_group_volume_changed(&mut self, _group_id: i32, _volume: u8)1470 fn on_lea_group_volume_changed(&mut self, _group_id: i32, _volume: u8) {}
on_bluetooth_audio_device_added(&mut self, _device: BluetoothAudioDevice)1471 fn on_bluetooth_audio_device_added(&mut self, _device: BluetoothAudioDevice) {}
on_bluetooth_audio_device_removed(&mut self, _addr: RawAddress)1472 fn on_bluetooth_audio_device_removed(&mut self, _addr: RawAddress) {}
on_absolute_volume_supported_changed(&mut self, _supported: bool)1473 fn on_absolute_volume_supported_changed(&mut self, _supported: bool) {}
on_absolute_volume_changed(&mut self, _volume: u8)1474 fn on_absolute_volume_changed(&mut self, _volume: u8) {}
on_hfp_volume_changed(&mut self, _volume: u8, _addr: RawAddress)1475 fn on_hfp_volume_changed(&mut self, _volume: u8, _addr: RawAddress) {}
on_hfp_audio_disconnected(&mut self, _addr: RawAddress)1476 fn on_hfp_audio_disconnected(&mut self, _addr: RawAddress) {}
on_hfp_debug_dump( &mut self, active: bool, codec_id: u16, total_num_decoded_frames: i32, pkt_loss_ratio: f64, begin_ts: u64, end_ts: u64, pkt_status_in_hex: String, pkt_status_in_binary: String, )1477 fn on_hfp_debug_dump(
1478 &mut self,
1479 active: bool,
1480 codec_id: u16,
1481 total_num_decoded_frames: i32,
1482 pkt_loss_ratio: f64,
1483 begin_ts: u64,
1484 end_ts: u64,
1485 pkt_status_in_hex: String,
1486 pkt_status_in_binary: String,
1487 ) {
1488 // Invoke run_callback so that the callback can be handled through
1489 // ForegroundActions::RunCallback in main.rs.
1490 self.context.lock().unwrap().run_callback(Box::new(move |_context| {
1491 let is_wbs = codec_id == HfpCodecId::MSBC as u16;
1492 let is_swb = codec_id == HfpCodecId::LC3 as u16;
1493 let dump = if active && (is_wbs || is_swb) {
1494 let mut to_split_binary = pkt_status_in_binary.clone();
1495 let mut wrapped_binary = String::new();
1496 while to_split_binary.len() > BINARY_PACKET_STATUS_WRAP {
1497 let remaining = to_split_binary.split_off(BINARY_PACKET_STATUS_WRAP);
1498 wrapped_binary.push_str(&to_split_binary);
1499 wrapped_binary.push('\n');
1500 to_split_binary = remaining;
1501 }
1502 wrapped_binary.push_str(&to_split_binary);
1503 format!(
1504 "\n--------{} packet loss--------\n\
1505 Decoded Packets: {}, Packet Loss Ratio: {} \n\
1506 {} [begin]\n\
1507 {} [end]\n\
1508 In Hex format:\n\
1509 {}\n\
1510 In binary format:\n\
1511 {}",
1512 if is_wbs { "WBS" } else { "SWB" },
1513 total_num_decoded_frames,
1514 pkt_loss_ratio,
1515 timestamp_to_string(begin_ts),
1516 timestamp_to_string(end_ts),
1517 pkt_status_in_hex,
1518 wrapped_binary
1519 )
1520 } else {
1521 "".to_string()
1522 };
1523
1524 print_info!(
1525 "\n--------HFP debug dump---------\n\
1526 HFP SCO: {}, Codec: {}\
1527 {}
1528 ",
1529 if active { "active" } else { "inactive" },
1530 if is_wbs {
1531 "mSBC"
1532 } else if is_swb {
1533 "LC3"
1534 } else {
1535 "CVSD"
1536 },
1537 dump
1538 );
1539 }));
1540 }
1541 }
1542
1543 impl RPCProxy for MediaCallback {
get_object_id(&self) -> String1544 fn get_object_id(&self) -> String {
1545 self.objpath.clone()
1546 }
1547
export_for_rpc(self: Box<Self>)1548 fn export_for_rpc(self: Box<Self>) {
1549 let cr = self.dbus_crossroads.clone();
1550 let iface = export_bluetooth_media_callback_dbus_intf(
1551 self.dbus_connection.clone(),
1552 &mut cr.lock().unwrap(),
1553 Arc::new(Mutex::new(DisconnectWatcher::new())),
1554 );
1555 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
1556 }
1557 }
1558
1559 pub(crate) struct TelephonyCallback {
1560 objpath: String,
1561 _context: Arc<Mutex<ClientContext>>,
1562
1563 dbus_connection: Arc<SyncConnection>,
1564 dbus_crossroads: Arc<Mutex<Crossroads>>,
1565 }
1566
1567 impl TelephonyCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self1568 pub(crate) fn new(
1569 objpath: String,
1570 context: Arc<Mutex<ClientContext>>,
1571 dbus_connection: Arc<SyncConnection>,
1572 dbus_crossroads: Arc<Mutex<Crossroads>>,
1573 ) -> Self {
1574 Self { objpath, _context: context, dbus_connection, dbus_crossroads }
1575 }
1576 }
1577
1578 impl IBluetoothTelephonyCallback for TelephonyCallback {
on_telephony_event(&mut self, addr: RawAddress, event: u8, call_state: u8)1579 fn on_telephony_event(&mut self, addr: RawAddress, event: u8, call_state: u8) {
1580 print_info!(
1581 "Telephony event changed: [{}] event {} state: {}",
1582 addr.to_string(),
1583 event,
1584 call_state
1585 );
1586 }
1587 }
1588
1589 impl RPCProxy for TelephonyCallback {
get_object_id(&self) -> String1590 fn get_object_id(&self) -> String {
1591 self.objpath.clone()
1592 }
1593
export_for_rpc(self: Box<Self>)1594 fn export_for_rpc(self: Box<Self>) {
1595 let cr = self.dbus_crossroads.clone();
1596 let iface = export_bluetooth_telephony_callback_dbus_intf(
1597 self.dbus_connection.clone(),
1598 &mut cr.lock().unwrap(),
1599 Arc::new(Mutex::new(DisconnectWatcher::new())),
1600 );
1601 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
1602 }
1603 }
1604
1605 pub(crate) struct BatteryManagerCallback {
1606 objpath: String,
1607 context: Arc<Mutex<ClientContext>>,
1608
1609 dbus_connection: Arc<SyncConnection>,
1610 dbus_crossroads: Arc<Mutex<Crossroads>>,
1611 }
1612
1613 impl BatteryManagerCallback {
new( objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self1614 pub(crate) fn new(
1615 objpath: String,
1616 context: Arc<Mutex<ClientContext>>,
1617 dbus_connection: Arc<SyncConnection>,
1618 dbus_crossroads: Arc<Mutex<Crossroads>>,
1619 ) -> Self {
1620 Self { objpath, context, dbus_connection, dbus_crossroads }
1621 }
1622 }
1623
1624 impl IBatteryManagerCallback for BatteryManagerCallback {
on_battery_info_updated(&mut self, remote_address: RawAddress, battery_set: BatterySet)1625 fn on_battery_info_updated(&mut self, remote_address: RawAddress, battery_set: BatterySet) {
1626 let address = remote_address.to_string();
1627 if self.context.lock().unwrap().battery_address_filter.contains(&address) {
1628 if battery_set.batteries.len() == 0 {
1629 print_info!(
1630 "Battery info for address '{}' updated with empty battery set. \
1631 The batteries for this device may have been removed.",
1632 address.clone()
1633 );
1634 return;
1635 }
1636 print_info!(
1637 "Battery data for '{}' from source '{}' and uuid '{}' changed to:",
1638 address.clone(),
1639 battery_set.source_uuid.clone(),
1640 battery_set.source_info.clone()
1641 );
1642 for battery in battery_set.batteries {
1643 print_info!(" {}%, variant: '{}'", battery.percentage, battery.variant);
1644 }
1645 }
1646 }
1647 }
1648
1649 impl RPCProxy for BatteryManagerCallback {
get_object_id(&self) -> String1650 fn get_object_id(&self) -> String {
1651 self.objpath.clone()
1652 }
1653
export_for_rpc(self: Box<Self>)1654 fn export_for_rpc(self: Box<Self>) {
1655 let cr = self.dbus_crossroads.clone();
1656 let iface = export_battery_manager_callback_dbus_intf(
1657 self.dbus_connection.clone(),
1658 &mut cr.lock().unwrap(),
1659 Arc::new(Mutex::new(DisconnectWatcher::new())),
1660 );
1661 cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self)));
1662 }
1663 }
1664