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(&reg_id);
566             return;
567         }
568         if let Some(s) = context.adv_sets.get_mut(&reg_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