1 //! Fluoride/GD Bluetooth stack.
2 //!
3 //! This crate provides the API implementation of the Fluoride/GD Bluetooth stack, independent of
4 //! any RPC projection.
5 
6 #[macro_use]
7 extern crate num_derive;
8 
9 pub mod bluetooth;
10 pub mod bluetooth_gatt;
11 
12 use bt_topshim::btif::ffi;
13 use bt_topshim::btif::BtState;
14 
15 use std::convert::TryInto;
16 use std::fmt::{Debug, Formatter, Result};
17 use std::sync::{Arc, Mutex};
18 
19 use tokio::sync::mpsc::channel;
20 use tokio::sync::mpsc::{Receiver, Sender};
21 
22 use crate::bluetooth::{Bluetooth, BtifBluetoothCallbacks};
23 
24 /// Represents a Bluetooth address.
25 // TODO: Add support for LE random addresses.
26 #[derive(Copy, Clone)]
27 pub struct BDAddr {
28     val: [u8; 6],
29 }
30 
31 impl Debug for BDAddr {
fmt(&self, f: &mut Formatter<'_>) -> Result32     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
33         f.write_fmt(format_args!(
34             "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
35             self.val[0], self.val[1], self.val[2], self.val[3], self.val[4], self.val[5]
36         ))
37     }
38 }
39 
40 impl ToString for BDAddr {
to_string(&self) -> String41     fn to_string(&self) -> String {
42         String::from(format!(
43             "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
44             self.val[0], self.val[1], self.val[2], self.val[3], self.val[4], self.val[5]
45         ))
46     }
47 }
48 
49 impl BDAddr {
50     /// Constructs a BDAddr from a vector of 6 bytes.
from_byte_vec(raw_addr: &Vec<u8>) -> BDAddr51     fn from_byte_vec(raw_addr: &Vec<u8>) -> BDAddr {
52         BDAddr { val: raw_addr.clone().try_into().unwrap() }
53     }
54 }
55 
56 /// Message types that are sent to the stack main dispatch loop.
57 pub enum Message {
58     BluetoothAdapterStateChanged(BtState),
59     BluetoothAdapterPropertiesChanged(i32, i32, Vec<ffi::BtProperty>),
60     BluetoothCallbackDisconnected(u32),
61 }
62 
63 /// Umbrella class for the Bluetooth stack.
64 pub struct Stack {}
65 
66 impl Stack {
67     /// Creates an mpsc channel for passing messages to the main dispatch loop.
create_channel() -> (Sender<Message>, Receiver<Message>)68     pub fn create_channel() -> (Sender<Message>, Receiver<Message>) {
69         channel::<Message>(1)
70     }
71 
72     /// Runs the main dispatch loop.
dispatch(mut rx: Receiver<Message>, bluetooth: Arc<Mutex<Bluetooth>>)73     pub async fn dispatch(mut rx: Receiver<Message>, bluetooth: Arc<Mutex<Bluetooth>>) {
74         loop {
75             let m = rx.recv().await;
76 
77             if m.is_none() {
78                 eprintln!("Message dispatch loop quit");
79                 break;
80             }
81 
82             match m.unwrap() {
83                 Message::BluetoothAdapterStateChanged(state) => {
84                     bluetooth.lock().unwrap().adapter_state_changed(state);
85                 }
86 
87                 Message::BluetoothAdapterPropertiesChanged(status, num_properties, properties) => {
88                     bluetooth.lock().unwrap().adapter_properties_changed(
89                         status,
90                         num_properties,
91                         properties,
92                     );
93                 }
94 
95                 Message::BluetoothCallbackDisconnected(id) => {
96                     bluetooth.lock().unwrap().callback_disconnected(id);
97                 }
98             }
99         }
100     }
101 }
102 
103 /// Signifies that the object may be a proxy to a remote RPC object.
104 ///
105 /// An object that implements RPCProxy trait signifies that the object may be a proxy to a remote
106 /// RPC object. Therefore the object may be disconnected and thus should implement
107 /// `register_disconnect` to let others observe the disconnection event.
108 pub trait RPCProxy {
register_disconnect(&mut self, f: Box<dyn Fn() + Send>)109     fn register_disconnect(&mut self, f: Box<dyn Fn() + Send>);
110 }
111