1 //! Floss Bluetooth stack.
2 //!
3 //! This crate provides the API implementation of the Fluoride/GD Bluetooth
4 //! stack, independent of any RPC projection.
5 
6 pub mod async_helper;
7 pub mod battery_manager;
8 pub mod battery_provider_manager;
9 pub mod battery_service;
10 pub mod bluetooth;
11 pub mod bluetooth_admin;
12 pub mod bluetooth_adv;
13 pub mod bluetooth_gatt;
14 pub mod bluetooth_logging;
15 pub mod bluetooth_media;
16 pub mod bluetooth_qa;
17 pub mod callbacks;
18 pub mod dis;
19 pub mod socket_manager;
20 pub mod suspend;
21 pub mod uuid;
22 
23 use bluetooth_qa::{BluetoothQA, IBluetoothQA};
24 use log::debug;
25 use num_derive::{FromPrimitive, ToPrimitive};
26 use std::sync::{Arc, Mutex};
27 use tokio::sync::mpsc::channel;
28 use tokio::sync::mpsc::{Receiver, Sender};
29 use tokio::time::{sleep, Duration};
30 
31 use crate::battery_manager::{BatteryManager, BatterySet};
32 use crate::battery_provider_manager::BatteryProviderManager;
33 use crate::battery_service::{BatteryService, BatteryServiceActions};
34 use crate::bluetooth::{
35     dispatch_base_callbacks, dispatch_hid_host_callbacks, dispatch_sdp_callbacks, Bluetooth,
36     BluetoothDevice, DelayedActions, IBluetooth,
37 };
38 use crate::bluetooth_admin::{BluetoothAdmin, IBluetoothAdmin};
39 use crate::bluetooth_adv::{dispatch_le_adv_callbacks, AdvertiserActions};
40 use crate::bluetooth_gatt::{
41     dispatch_gatt_client_callbacks, dispatch_gatt_server_callbacks, dispatch_le_scanner_callbacks,
42     dispatch_le_scanner_inband_callbacks, BluetoothGatt, GattActions,
43 };
44 use crate::bluetooth_media::{BluetoothMedia, MediaActions};
45 use crate::dis::{DeviceInformation, ServiceCallbacks};
46 use crate::socket_manager::{BluetoothSocketManager, SocketActions};
47 use crate::suspend::Suspend;
48 use bt_topshim::{
49     btif::{BaseCallbacks, BtTransport, RawAddress},
50     profiles::{
51         a2dp::A2dpCallbacks,
52         avrcp::AvrcpCallbacks,
53         csis::CsisClientCallbacks,
54         gatt::GattAdvCallbacks,
55         gatt::GattAdvInbandCallbacks,
56         gatt::GattClientCallbacks,
57         gatt::GattScannerCallbacks,
58         gatt::GattScannerInbandCallbacks,
59         gatt::GattServerCallbacks,
60         hfp::HfpCallbacks,
61         hid_host::{BthhReportType, HHCallbacks},
62         le_audio::LeAudioClientCallbacks,
63         sdp::SdpCallbacks,
64         vc::VolumeControlCallbacks,
65     },
66 };
67 
68 /// Message types that are sent to the stack main dispatch loop.
69 pub enum Message {
70     /// Remove the DBus API. Call it before other AdapterShutdown.
71     InterfaceShutdown,
72     /// Disable the adapter by calling btif disable.
73     AdapterShutdown,
74     /// Clean up the adapter by calling btif cleanup.
75     Cleanup,
76 
77     // Adapter is enabled and ready.
78     AdapterReady,
79 
80     // Callbacks from libbluetooth
81     A2dp(A2dpCallbacks),
82     Avrcp(AvrcpCallbacks),
83     Base(BaseCallbacks),
84     GattClient(GattClientCallbacks),
85     GattServer(GattServerCallbacks),
86     LeAudioClient(LeAudioClientCallbacks),
87     LeScanner(GattScannerCallbacks),
88     LeScannerInband(GattScannerInbandCallbacks),
89     LeAdvInband(GattAdvInbandCallbacks),
90     LeAdv(GattAdvCallbacks),
91     HidHost(HHCallbacks),
92     Hfp(HfpCallbacks),
93     Sdp(SdpCallbacks),
94     VolumeControl(VolumeControlCallbacks),
95     CsisClient(CsisClientCallbacks),
96     CreateBondWithRetry(BluetoothDevice, BtTransport, u32, Duration),
97 
98     // Actions within the stack
99     Media(MediaActions),
100     MediaCallbackDisconnected(u32),
101     TelephonyCallbackDisconnected(u32),
102 
103     // Client callback disconnections
104     AdapterCallbackDisconnected(u32),
105     ConnectionCallbackDisconnected(u32),
106 
107     // Some delayed actions for the adapter.
108     TriggerUpdateConnectableMode,
109     DelayedAdapterActions(DelayedActions),
110 
111     // Follows IBluetooth's on_device_(dis)connected callback but doesn't require depending on
112     // Bluetooth.
113     OnAclConnected(BluetoothDevice, BtTransport),
114     OnAclDisconnected(BluetoothDevice),
115 
116     // Suspend related
117     SuspendCallbackRegistered(u32),
118     SuspendCallbackDisconnected(u32),
119     SuspendReady(i32),
120     ResumeReady(i32),
121     AudioReconnectOnResumeComplete,
122 
123     // Scanner related
124     ScannerCallbackDisconnected(u32),
125 
126     // Advertising related
127     AdvertiserCallbackDisconnected(u32),
128     AdvertiserActions(AdvertiserActions),
129 
130     SocketManagerActions(SocketActions),
131     SocketManagerCallbackDisconnected(u32),
132 
133     // Battery related
134     BatteryProviderManagerCallbackDisconnected(u32),
135     BatteryProviderManagerBatteryUpdated(RawAddress, BatterySet),
136     BatteryServiceCallbackDisconnected(u32),
137     BatteryService(BatteryServiceActions),
138     BatteryServiceRefresh,
139     BatteryManagerCallbackDisconnected(u32),
140 
141     GattActions(GattActions),
142     GattClientCallbackDisconnected(u32),
143     GattServerCallbackDisconnected(u32),
144 
145     // Admin policy related
146     AdminCallbackDisconnected(u32),
147     HidHostEnable,
148     AdminPolicyChanged,
149 
150     // Dis callbacks
151     Dis(ServiceCallbacks),
152 
153     // Device removal
154     DisconnectDevice(BluetoothDevice),
155 
156     // Qualification Only
157     QaCallbackDisconnected(u32),
158     QaAddMediaPlayer(String, bool),
159     QaRfcommSendMsc(u8, RawAddress),
160     QaFetchDiscoverableMode,
161     QaFetchConnectable,
162     QaSetConnectable(bool),
163     QaFetchAlias,
164     QaGetHidReport(RawAddress, BthhReportType, u8),
165     QaSetHidReport(RawAddress, BthhReportType, String),
166     QaSendHidData(RawAddress, String),
167 
168     // UHid callbacks
169     UHidHfpOutputCallback(RawAddress, u8, u8),
170     UHidTelephonyUseCallback(RawAddress, bool),
171 }
172 
173 pub enum BluetoothAPI {
174     Adapter,
175     Battery,
176     Media,
177     Gatt,
178 }
179 
180 /// Message types that are sent to the InterfaceManager's dispatch loop.
181 pub enum APIMessage {
182     /// Indicates a subcomponent is ready to receive DBus messages.
183     IsReady(BluetoothAPI),
184     /// Indicates bluetooth is shutting down, so we remove all DBus endpoints.
185     ShutDown,
186 }
187 
188 /// Represents suspend mode of a module.
189 ///
190 /// Being in suspend mode means that the module pauses some activities if required for suspend and
191 /// some subsequent API calls will be blocked with a retryable error.
192 #[derive(FromPrimitive, ToPrimitive, Debug, PartialEq, Clone)]
193 pub enum SuspendMode {
194     Normal = 0,
195     Suspending = 1,
196     Suspended = 2,
197     Resuming = 3,
198 }
199 
200 /// Umbrella class for the Bluetooth stack.
201 pub struct Stack {}
202 
203 impl Stack {
204     /// Creates an mpsc channel for passing messages to the main dispatch loop.
create_channel() -> (Sender<Message>, Receiver<Message>)205     pub fn create_channel() -> (Sender<Message>, Receiver<Message>) {
206         channel::<Message>(1)
207     }
208 
209     /// Runs the main dispatch loop.
dispatch( mut rx: Receiver<Message>, tx: Sender<Message>, api_tx: Sender<APIMessage>, bluetooth: Arc<Mutex<Box<Bluetooth>>>, bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>, battery_service: Arc<Mutex<Box<BatteryService>>>, battery_manager: Arc<Mutex<Box<BatteryManager>>>, battery_provider_manager: Arc<Mutex<Box<BatteryProviderManager>>>, bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>, suspend: Arc<Mutex<Box<Suspend>>>, bluetooth_socketmgr: Arc<Mutex<Box<BluetoothSocketManager>>>, bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>, bluetooth_dis: Arc<Mutex<Box<DeviceInformation>>>, bluetooth_qa: Arc<Mutex<Box<BluetoothQA>>>, )210     pub async fn dispatch(
211         mut rx: Receiver<Message>,
212         tx: Sender<Message>,
213         api_tx: Sender<APIMessage>,
214         bluetooth: Arc<Mutex<Box<Bluetooth>>>,
215         bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
216         battery_service: Arc<Mutex<Box<BatteryService>>>,
217         battery_manager: Arc<Mutex<Box<BatteryManager>>>,
218         battery_provider_manager: Arc<Mutex<Box<BatteryProviderManager>>>,
219         bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
220         suspend: Arc<Mutex<Box<Suspend>>>,
221         bluetooth_socketmgr: Arc<Mutex<Box<BluetoothSocketManager>>>,
222         bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
223         bluetooth_dis: Arc<Mutex<Box<DeviceInformation>>>,
224         bluetooth_qa: Arc<Mutex<Box<BluetoothQA>>>,
225     ) {
226         loop {
227             let m = rx.recv().await;
228 
229             if m.is_none() {
230                 eprintln!("Message dispatch loop quit");
231                 break;
232             }
233 
234             match m.unwrap() {
235                 Message::InterfaceShutdown => {
236                     let txl = api_tx.clone();
237                     tokio::spawn(async move {
238                         let _ = txl.send(APIMessage::ShutDown).await;
239                     });
240                 }
241 
242                 Message::AdapterShutdown => {
243                     bluetooth.lock().unwrap().disable();
244                 }
245 
246                 Message::Cleanup => {
247                     bluetooth.lock().unwrap().cleanup();
248                 }
249 
250                 Message::AdapterReady => {
251                     // Initialize objects that need the adapter to be fully
252                     // enabled before running.
253 
254                     // Register device information service.
255                     bluetooth_dis.lock().unwrap().initialize();
256                 }
257 
258                 Message::A2dp(a) => {
259                     bluetooth_media.lock().unwrap().dispatch_a2dp_callbacks(a);
260                 }
261 
262                 Message::Avrcp(av) => {
263                     bluetooth_media.lock().unwrap().dispatch_avrcp_callbacks(av);
264                 }
265 
266                 Message::Base(b) => {
267                     dispatch_base_callbacks(bluetooth.lock().unwrap().as_mut(), b.clone());
268                     dispatch_base_callbacks(suspend.lock().unwrap().as_mut(), b);
269                 }
270 
271                 // When pairing is busy for any reason, the bond cannot be created.
272                 // Allow retries until it is ready for bonding.
273                 Message::CreateBondWithRetry(device, bt_transport, num_attempts, retry_delay) => {
274                     if num_attempts == 0 {
275                         continue;
276                     }
277 
278                     let mut bt = bluetooth.lock().unwrap();
279                     if !bt.is_pairing_busy() {
280                         bt.create_bond(device, bt_transport);
281                         continue;
282                     }
283 
284                     let txl = tx.clone();
285                     tokio::spawn(async move {
286                         sleep(retry_delay).await;
287                         let _ = txl
288                             .send(Message::CreateBondWithRetry(
289                                 device,
290                                 bt_transport,
291                                 num_attempts - 1,
292                                 retry_delay,
293                             ))
294                             .await;
295                     });
296                 }
297 
298                 Message::GattClient(m) => {
299                     dispatch_gatt_client_callbacks(bluetooth_gatt.lock().unwrap().as_mut(), m);
300                 }
301 
302                 Message::GattServer(m) => {
303                     dispatch_gatt_server_callbacks(bluetooth_gatt.lock().unwrap().as_mut(), m);
304                 }
305 
306                 Message::LeAudioClient(a) => {
307                     bluetooth_media.lock().unwrap().dispatch_le_audio_callbacks(a);
308                 }
309 
310                 Message::VolumeControl(a) => {
311                     bluetooth_media.lock().unwrap().dispatch_vc_callbacks(a);
312                 }
313 
314                 Message::CsisClient(a) => {
315                     bluetooth_media.lock().unwrap().dispatch_csis_callbacks(a);
316                 }
317 
318                 Message::LeScanner(m) => {
319                     dispatch_le_scanner_callbacks(bluetooth_gatt.lock().unwrap().as_mut(), m);
320                 }
321 
322                 Message::LeScannerInband(m) => {
323                     dispatch_le_scanner_inband_callbacks(
324                         bluetooth_gatt.lock().unwrap().as_mut(),
325                         m,
326                     );
327                 }
328 
329                 Message::LeAdvInband(m) => {
330                     debug!("Received LeAdvInband message: {:?}. This is unexpected!", m);
331                 }
332 
333                 Message::LeAdv(m) => {
334                     dispatch_le_adv_callbacks(bluetooth_gatt.lock().unwrap().as_mut(), m);
335                 }
336 
337                 Message::Hfp(hf) => {
338                     bluetooth_media.lock().unwrap().dispatch_hfp_callbacks(hf);
339                 }
340 
341                 Message::HidHost(h) => {
342                     dispatch_hid_host_callbacks(bluetooth.lock().unwrap().as_mut(), h);
343                 }
344 
345                 Message::Sdp(s) => {
346                     dispatch_sdp_callbacks(bluetooth.lock().unwrap().as_mut(), s);
347                 }
348 
349                 Message::Media(action) => {
350                     bluetooth_media.lock().unwrap().dispatch_media_actions(action);
351                 }
352 
353                 Message::MediaCallbackDisconnected(cb_id) => {
354                     bluetooth_media.lock().unwrap().remove_callback(cb_id);
355                 }
356 
357                 Message::TelephonyCallbackDisconnected(cb_id) => {
358                     bluetooth_media.lock().unwrap().remove_telephony_callback(cb_id);
359                 }
360 
361                 Message::AdapterCallbackDisconnected(id) => {
362                     bluetooth.lock().unwrap().adapter_callback_disconnected(id);
363                 }
364 
365                 Message::ConnectionCallbackDisconnected(id) => {
366                     bluetooth.lock().unwrap().connection_callback_disconnected(id);
367                 }
368 
369                 Message::TriggerUpdateConnectableMode => {
370                     let is_listening = bluetooth_socketmgr.lock().unwrap().is_listening();
371                     bluetooth.lock().unwrap().handle_delayed_actions(
372                         DelayedActions::UpdateConnectableMode(is_listening),
373                     );
374                 }
375 
376                 Message::DelayedAdapterActions(action) => {
377                     bluetooth.lock().unwrap().handle_delayed_actions(action);
378                 }
379 
380                 // Any service needing an updated list of devices can have an
381                 // update method triggered from here rather than needing a
382                 // reference to Bluetooth.
383                 Message::OnAclConnected(device, transport) => {
384                     battery_service
385                         .lock()
386                         .unwrap()
387                         .handle_action(BatteryServiceActions::Connect(device, transport));
388                 }
389 
390                 // For battery service, use this to clean up internal handles. GATT connection is
391                 // already dropped if ACL disconnect has occurred.
392                 Message::OnAclDisconnected(device) => {
393                     battery_service
394                         .lock()
395                         .unwrap()
396                         .handle_action(BatteryServiceActions::Disconnect(device));
397                 }
398 
399                 Message::SuspendCallbackRegistered(id) => {
400                     suspend.lock().unwrap().callback_registered(id);
401                 }
402 
403                 Message::SuspendCallbackDisconnected(id) => {
404                     suspend.lock().unwrap().remove_callback(id);
405                 }
406 
407                 Message::SuspendReady(suspend_id) => {
408                     suspend.lock().unwrap().suspend_ready(suspend_id);
409                 }
410 
411                 Message::ResumeReady(suspend_id) => {
412                     suspend.lock().unwrap().resume_ready(suspend_id);
413                 }
414 
415                 Message::AudioReconnectOnResumeComplete => {
416                     suspend.lock().unwrap().audio_reconnect_complete();
417                 }
418 
419                 Message::ScannerCallbackDisconnected(id) => {
420                     bluetooth_gatt.lock().unwrap().remove_scanner_callback(id);
421                 }
422 
423                 Message::AdvertiserCallbackDisconnected(id) => {
424                     bluetooth_gatt.lock().unwrap().remove_adv_callback(id);
425                 }
426 
427                 Message::AdvertiserActions(action) => {
428                     bluetooth_gatt.lock().unwrap().handle_adv_action(action);
429                 }
430 
431                 Message::SocketManagerActions(action) => {
432                     bluetooth_socketmgr.lock().unwrap().handle_actions(action);
433                 }
434                 Message::SocketManagerCallbackDisconnected(id) => {
435                     bluetooth_socketmgr.lock().unwrap().remove_callback(id);
436                 }
437                 Message::BatteryProviderManagerBatteryUpdated(remote_address, battery_set) => {
438                     battery_manager
439                         .lock()
440                         .unwrap()
441                         .handle_battery_updated(remote_address, battery_set);
442                 }
443                 Message::BatteryProviderManagerCallbackDisconnected(id) => {
444                     battery_provider_manager.lock().unwrap().remove_battery_provider_callback(id);
445                 }
446                 Message::BatteryServiceCallbackDisconnected(id) => {
447                     battery_service.lock().unwrap().remove_callback(id);
448                 }
449                 Message::BatteryService(action) => {
450                     battery_service.lock().unwrap().handle_action(action);
451                 }
452                 Message::BatteryServiceRefresh => {
453                     battery_service.lock().unwrap().refresh_all_devices();
454                 }
455                 Message::BatteryManagerCallbackDisconnected(id) => {
456                     battery_manager.lock().unwrap().remove_callback(id);
457                 }
458                 Message::GattActions(action) => {
459                     bluetooth_gatt.lock().unwrap().handle_action(action);
460                 }
461                 Message::GattClientCallbackDisconnected(id) => {
462                     bluetooth_gatt.lock().unwrap().remove_client_callback(id);
463                 }
464                 Message::GattServerCallbackDisconnected(id) => {
465                     bluetooth_gatt.lock().unwrap().remove_server_callback(id);
466                 }
467                 Message::AdminCallbackDisconnected(id) => {
468                     bluetooth_admin.lock().unwrap().unregister_admin_policy_callback(id);
469                 }
470                 Message::HidHostEnable => {
471                     bluetooth.lock().unwrap().enable_hidhost();
472                 }
473                 Message::AdminPolicyChanged => {
474                     bluetooth_socketmgr.lock().unwrap().handle_admin_policy_changed();
475                 }
476                 Message::Dis(callback) => {
477                     bluetooth_dis.lock().unwrap().handle_callbacks(&callback);
478                 }
479                 Message::DisconnectDevice(addr) => {
480                     bluetooth.lock().unwrap().disconnect_all_enabled_profiles(addr);
481                 }
482                 // Qualification Only
483                 Message::QaAddMediaPlayer(name, browsing_supported) => {
484                     bluetooth_media.lock().unwrap().add_player(name, browsing_supported);
485                 }
486                 Message::QaRfcommSendMsc(dlci, addr) => {
487                     bluetooth_socketmgr.lock().unwrap().rfcomm_send_msc(dlci, addr);
488                 }
489                 Message::QaCallbackDisconnected(id) => {
490                     bluetooth_qa.lock().unwrap().unregister_qa_callback(id);
491                 }
492                 Message::QaFetchDiscoverableMode => {
493                     let mode = bluetooth.lock().unwrap().get_discoverable_mode_internal();
494                     bluetooth_qa.lock().unwrap().on_fetch_discoverable_mode_completed(mode);
495                 }
496                 Message::QaFetchConnectable => {
497                     let connectable = bluetooth.lock().unwrap().get_connectable_internal();
498                     bluetooth_qa.lock().unwrap().on_fetch_connectable_completed(connectable);
499                 }
500                 Message::QaSetConnectable(mode) => {
501                     let succeed = bluetooth.lock().unwrap().set_connectable_internal(mode);
502                     bluetooth_qa.lock().unwrap().on_set_connectable_completed(succeed);
503                 }
504                 Message::QaFetchAlias => {
505                     let alias = bluetooth.lock().unwrap().get_alias_internal();
506                     bluetooth_qa.lock().unwrap().on_fetch_alias_completed(alias);
507                 }
508                 Message::QaGetHidReport(addr, report_type, report_id) => {
509                     let status = bluetooth.lock().unwrap().get_hid_report_internal(
510                         addr,
511                         report_type,
512                         report_id,
513                     );
514                     bluetooth_qa.lock().unwrap().on_get_hid_report_completed(status);
515                 }
516                 Message::QaSetHidReport(addr, report_type, report) => {
517                     let status = bluetooth.lock().unwrap().set_hid_report_internal(
518                         addr,
519                         report_type,
520                         report,
521                     );
522                     bluetooth_qa.lock().unwrap().on_set_hid_report_completed(status);
523                 }
524                 Message::QaSendHidData(addr, data) => {
525                     let status = bluetooth.lock().unwrap().send_hid_data_internal(addr, data);
526                     bluetooth_qa.lock().unwrap().on_send_hid_data_completed(status);
527                 }
528 
529                 // UHid callbacks
530                 Message::UHidHfpOutputCallback(addr, id, data) => {
531                     bluetooth_media
532                         .lock()
533                         .unwrap()
534                         .dispatch_uhid_hfp_output_callback(addr, id, data);
535                 }
536 
537                 Message::UHidTelephonyUseCallback(addr, state) => {
538                     bluetooth_media
539                         .lock()
540                         .unwrap()
541                         .dispatch_uhid_telephony_use_callback(addr, state);
542                 }
543             }
544         }
545     }
546 }
547 
548 /// Signifies that the object may be a proxy to a remote RPC object.
549 ///
550 /// An object that implements RPCProxy trait signifies that the object may be a proxy to a remote
551 /// RPC object. Therefore the object may be disconnected and thus should implement
552 /// `register_disconnect` to let others observe the disconnection event.
553 pub trait RPCProxy {
554     /// Registers disconnect observer that will be notified when the remote object is disconnected.
register_disconnect(&mut self, _f: Box<dyn Fn(u32) + Send>) -> u32555     fn register_disconnect(&mut self, _f: Box<dyn Fn(u32) + Send>) -> u32 {
556         0
557     }
558 
559     /// Returns the ID of the object. For example this would be an object path in D-Bus RPC.
get_object_id(&self) -> String560     fn get_object_id(&self) -> String {
561         String::from("")
562     }
563 
564     /// Unregisters callback with this id.
unregister(&mut self, _id: u32) -> bool565     fn unregister(&mut self, _id: u32) -> bool {
566         false
567     }
568 
569     /// Makes this object available for remote call.
export_for_rpc(self: Box<Self>)570     fn export_for_rpc(self: Box<Self>) {}
571 }
572