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