1 //! Adapter service facade
2 
3 use bt_topshim::btif;
4 use bt_topshim::btif::{BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BtIoCap};
5 
6 use crate::utils::converters::{bluetooth_property_to_event_data, event_data_from_string};
7 use bt_topshim_facade_protobuf::empty::Empty;
8 use bt_topshim_facade_protobuf::facade::{
9     EventType, FetchEventsRequest, FetchEventsResponse, SetDefaultEventMaskExceptRequest,
10     SetDiscoveryModeRequest, SetDiscoveryModeResponse, SetLocalIoCapsRequest,
11     SetLocalIoCapsResponse, ToggleDiscoveryRequest, ToggleDiscoveryResponse, ToggleStackRequest,
12     ToggleStackResponse,
13 };
14 use bt_topshim_facade_protobuf::facade_grpc::{create_adapter_service, AdapterService};
15 use futures::sink::SinkExt;
16 use grpcio::*;
17 use num_traits::cast::FromPrimitive;
18 
19 use std::sync::{Arc, Mutex};
20 use tokio::runtime::Runtime;
21 use tokio::sync::mpsc;
22 use tokio::sync::Mutex as TokioMutex;
23 
get_bt_dispatcher( btif: Arc<Mutex<BluetoothInterface>>, tx: mpsc::Sender<BaseCallbacks>, ) -> BaseCallbacksDispatcher24 fn get_bt_dispatcher(
25     btif: Arc<Mutex<BluetoothInterface>>,
26     tx: mpsc::Sender<BaseCallbacks>,
27 ) -> BaseCallbacksDispatcher {
28     BaseCallbacksDispatcher {
29         dispatch: Box::new(move |cb: BaseCallbacks| {
30             if tx.clone().try_send(cb.clone()).is_err() {
31                 println!("Cannot send event {:?}", cb);
32             }
33             match cb {
34                 BaseCallbacks::AdapterState(state) => {
35                     println!("State changed to {:?}", state);
36                 }
37                 BaseCallbacks::SspRequest(addr, variant, passkey) => {
38                     println!(
39                         "SSP Request made for address {:?} with variant {:?} and passkey {:?}",
40                         addr.to_string(),
41                         variant,
42                         passkey
43                     );
44                     btif.lock().unwrap().ssp_reply(&addr, variant, 1, passkey);
45                 }
46                 BaseCallbacks::AdapterProperties(status, _, properties) => {
47                     println!(
48                         "Adapter attributes changed, status = {:?}, properties = {:?}",
49                         status, properties
50                     );
51                 }
52                 BaseCallbacks::DiscoveryState(state) => {
53                     println!("Discovery state changed, state = {:?}, ", state);
54                 }
55                 BaseCallbacks::DeviceFound(_, properties) => {
56                     println!("Device found with properties : {:?}", properties)
57                 }
58                 BaseCallbacks::BondState(_, address, state, _) => {
59                     println!(
60                         "Device in state {:?} with device address {}",
61                         state,
62                         address.to_string()
63                     );
64                 }
65                 _ => (),
66             }
67         }),
68     }
69 }
70 
71 /// Main object for Adapter facade service
72 #[derive(Clone)]
73 pub struct AdapterServiceImpl {
74     #[allow(dead_code)]
75     rt: Arc<Runtime>,
76     btif_intf: Arc<Mutex<BluetoothInterface>>,
77     event_rx: Arc<TokioMutex<mpsc::Receiver<BaseCallbacks>>>,
78     #[allow(dead_code)]
79     event_tx: mpsc::Sender<BaseCallbacks>,
80 }
81 
encode_hex(bytes: &[u8]) -> String82 fn encode_hex(bytes: &[u8]) -> String {
83     let mut s = String::with_capacity(2 * bytes.len());
84     for &b in bytes {
85         let bstr: String = format!("{:02X}", b);
86         s.push_str(&bstr);
87     }
88     s
89 }
90 
91 impl AdapterServiceImpl {
92     /// Create a new instance of the root facade service
create(rt: Arc<Runtime>, btif_intf: Arc<Mutex<BluetoothInterface>>) -> grpcio::Service93     pub fn create(rt: Arc<Runtime>, btif_intf: Arc<Mutex<BluetoothInterface>>) -> grpcio::Service {
94         let (event_tx, rx) = mpsc::channel(10);
95         btif_intf.lock().unwrap().initialize(
96             get_bt_dispatcher(btif_intf.clone(), event_tx.clone()),
97             vec!["INIT_gd_hci=true".to_string()],
98         );
99         create_adapter_service(Self {
100             rt,
101             btif_intf,
102             event_rx: Arc::new(TokioMutex::new(rx)),
103             event_tx,
104         })
105     }
106 }
107 
108 impl AdapterService for AdapterServiceImpl {
fetch_events( &mut self, ctx: RpcContext<'_>, _req: FetchEventsRequest, mut sink: ServerStreamingSink<FetchEventsResponse>, )109     fn fetch_events(
110         &mut self,
111         ctx: RpcContext<'_>,
112         _req: FetchEventsRequest,
113         mut sink: ServerStreamingSink<FetchEventsResponse>,
114     ) {
115         let rx = self.event_rx.clone();
116         ctx.spawn(async move {
117             while let Some(event) = rx.lock().await.recv().await {
118                 match event {
119                     BaseCallbacks::AdapterState(_state) => {
120                         let mut rsp = FetchEventsResponse::new();
121                         rsp.event_type = EventType::ADAPTER_STATE.into();
122                         rsp.params.insert(
123                             String::from("state"),
124                             event_data_from_string(String::from("ON")),
125                         );
126                         sink.send((rsp, WriteFlags::default())).await.unwrap();
127                     }
128                     BaseCallbacks::SspRequest(_, _, _) => {}
129                     BaseCallbacks::LeRandCallback(random) => {
130                         let mut rsp = FetchEventsResponse::new();
131                         rsp.event_type = EventType::LE_RAND.into();
132                         rsp.params.insert(
133                             String::from("data"),
134                             event_data_from_string(random.to_string()),
135                         );
136                         sink.send((rsp, WriteFlags::default())).await.unwrap();
137                     }
138                     BaseCallbacks::GenerateLocalOobData(transport, data) => {
139                         let mut rsp = FetchEventsResponse::new();
140                         rsp.event_type = EventType::GENERATE_LOCAL_OOB_DATA.into();
141                         rsp.params.insert(
142                             String::from("is_valid"),
143                             event_data_from_string(String::from(if data.is_valid {
144                                 "1"
145                             } else {
146                                 "0"
147                             })),
148                         );
149                         rsp.params.insert(
150                             String::from("transport"),
151                             event_data_from_string(format!("{}", transport)),
152                         );
153                         rsp.params.insert(
154                             String::from("address"),
155                             event_data_from_string(encode_hex(&data.address)),
156                         );
157                         rsp.params.insert(
158                             String::from("confirmation"),
159                             event_data_from_string(encode_hex(&data.c)),
160                         );
161                         rsp.params.insert(
162                             String::from("randomizer"),
163                             event_data_from_string(encode_hex(&data.r)),
164                         );
165                         sink.send((rsp, WriteFlags::default())).await.unwrap();
166                     }
167                     BaseCallbacks::AdapterProperties(status, _, properties) => {
168                         let mut rsp = FetchEventsResponse::new();
169                         rsp.event_type = EventType::ADAPTER_PROPERTY.into();
170                         rsp.params.insert(
171                             String::from("status"),
172                             event_data_from_string(format!("{:?}", status)),
173                         );
174                         for property in properties.clone() {
175                             let (key, event_data) = bluetooth_property_to_event_data(property);
176                             if key == "skip" {
177                                 continue;
178                             }
179                             rsp.params.insert(key, event_data);
180                         }
181                         sink.send((rsp, WriteFlags::default())).await.unwrap();
182                     }
183                     BaseCallbacks::DiscoveryState(state) => {
184                         let mut rsp = FetchEventsResponse::new();
185                         rsp.event_type = EventType::DISCOVERY_STATE.into();
186                         rsp.params.insert(
187                             String::from("discovery_state"),
188                             event_data_from_string(format!("{:?}", state)),
189                         );
190                         sink.send((rsp, WriteFlags::default())).await.unwrap();
191                     }
192                     BaseCallbacks::DeviceFound(_, properties) => {
193                         let mut rsp = FetchEventsResponse::new();
194                         rsp.event_type = EventType::DEVICE_FOUND.into();
195                         for property in properties.clone() {
196                             let (key, event_data) = bluetooth_property_to_event_data(property);
197                             if key == "skip" {
198                                 continue;
199                             }
200                             rsp.params.insert(key, event_data);
201                         }
202                         sink.send((rsp, WriteFlags::default())).await.unwrap();
203                     }
204                     BaseCallbacks::BondState(_, address, state, _) => {
205                         let mut rsp = FetchEventsResponse::new();
206                         rsp.event_type = EventType::BOND_STATE.into();
207                         rsp.params.insert(
208                             String::from("bond_state"),
209                             event_data_from_string(format!("{:?}", state)),
210                         );
211                         rsp.params.insert(
212                             String::from("address"),
213                             event_data_from_string(address.to_string()),
214                         );
215                         sink.send((rsp, WriteFlags::default())).await.unwrap();
216                     }
217                     _ => (),
218                 }
219             }
220         })
221     }
222 
toggle_stack( &mut self, ctx: RpcContext<'_>, req: ToggleStackRequest, sink: UnarySink<ToggleStackResponse>, )223     fn toggle_stack(
224         &mut self,
225         ctx: RpcContext<'_>,
226         req: ToggleStackRequest,
227         sink: UnarySink<ToggleStackResponse>,
228     ) {
229         match req.start_stack {
230             true => self.btif_intf.lock().unwrap().enable(),
231             false => self.btif_intf.lock().unwrap().disable(),
232         };
233         ctx.spawn(async move {
234             sink.success(ToggleStackResponse::default()).await.unwrap();
235         })
236     }
237 
set_discovery_mode( &mut self, ctx: RpcContext<'_>, req: SetDiscoveryModeRequest, sink: UnarySink<SetDiscoveryModeResponse>, )238     fn set_discovery_mode(
239         &mut self,
240         ctx: RpcContext<'_>,
241         req: SetDiscoveryModeRequest,
242         sink: UnarySink<SetDiscoveryModeResponse>,
243     ) {
244         let scan_mode = if req.enable_inquiry_scan {
245             btif::BtScanMode::ConnectableDiscoverable
246         } else if req.enable_page_scan {
247             btif::BtScanMode::Connectable
248         } else {
249             btif::BtScanMode::None_
250         };
251         let status = self
252             .btif_intf
253             .lock()
254             .unwrap()
255             .set_adapter_property(btif::BluetoothProperty::AdapterScanMode(scan_mode));
256 
257         let mut resp = SetDiscoveryModeResponse::new();
258         resp.status = status;
259         ctx.spawn(async move {
260             sink.success(resp).await.unwrap();
261         })
262     }
263 
clear_event_filter(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>)264     fn clear_event_filter(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>) {
265         self.btif_intf.lock().unwrap().clear_event_filter();
266         ctx.spawn(async move {
267             sink.success(Empty::default()).await.unwrap();
268         })
269     }
270 
clear_event_mask(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>)271     fn clear_event_mask(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>) {
272         self.btif_intf.lock().unwrap().clear_event_mask();
273         ctx.spawn(async move {
274             sink.success(Empty::default()).await.unwrap();
275         })
276     }
277 
clear_filter_accept_list( &mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>, )278     fn clear_filter_accept_list(
279         &mut self,
280         ctx: RpcContext<'_>,
281         _req: Empty,
282         sink: UnarySink<Empty>,
283     ) {
284         self.btif_intf.lock().unwrap().clear_filter_accept_list();
285         ctx.spawn(async move {
286             sink.success(Empty::default()).await.unwrap();
287         })
288     }
289 
disconnect_all_acls(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>)290     fn disconnect_all_acls(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>) {
291         self.btif_intf.lock().unwrap().disconnect_all_acls();
292         ctx.spawn(async move {
293             sink.success(Empty::default()).await.unwrap();
294         })
295     }
296 
le_rand(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>)297     fn le_rand(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>) {
298         self.btif_intf.lock().unwrap().le_rand();
299         ctx.spawn(async move {
300             sink.success(Empty::default()).await.unwrap();
301         })
302     }
303 
allow_wake_by_hid(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>)304     fn allow_wake_by_hid(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>) {
305         self.btif_intf.lock().unwrap().allow_wake_by_hid();
306         ctx.spawn(async move {
307             sink.success(Empty::default()).await.unwrap();
308         })
309     }
310 
restore_filter_accept_list( &mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>, )311     fn restore_filter_accept_list(
312         &mut self,
313         ctx: RpcContext<'_>,
314         _req: Empty,
315         sink: UnarySink<Empty>,
316     ) {
317         self.btif_intf.lock().unwrap().restore_filter_accept_list();
318         ctx.spawn(async move {
319             sink.success(Empty::default()).await.unwrap();
320         })
321     }
322 
set_default_event_mask_except( &mut self, ctx: RpcContext<'_>, req: SetDefaultEventMaskExceptRequest, sink: UnarySink<Empty>, )323     fn set_default_event_mask_except(
324         &mut self,
325         ctx: RpcContext<'_>,
326         req: SetDefaultEventMaskExceptRequest,
327         sink: UnarySink<Empty>,
328     ) {
329         self.btif_intf.lock().unwrap().set_default_event_mask_except(req.mask, req.le_mask);
330         ctx.spawn(async move {
331             sink.success(Empty::default()).await.unwrap();
332         })
333     }
334 
set_event_filter_inquiry_result_all_devices( &mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>, )335     fn set_event_filter_inquiry_result_all_devices(
336         &mut self,
337         ctx: RpcContext<'_>,
338         _req: Empty,
339         sink: UnarySink<Empty>,
340     ) {
341         self.btif_intf.lock().unwrap().set_event_filter_inquiry_result_all_devices();
342         ctx.spawn(async move {
343             sink.success(Empty::default()).await.unwrap();
344         })
345     }
346 
set_event_filter_connection_setup_all_devices( &mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>, )347     fn set_event_filter_connection_setup_all_devices(
348         &mut self,
349         ctx: RpcContext<'_>,
350         _req: Empty,
351         sink: UnarySink<Empty>,
352     ) {
353         self.btif_intf.lock().unwrap().set_event_filter_connection_setup_all_devices();
354         ctx.spawn(async move {
355             sink.success(Empty::default()).await.unwrap();
356         })
357     }
358 
set_local_io_caps( &mut self, ctx: RpcContext<'_>, req: SetLocalIoCapsRequest, sink: UnarySink<SetLocalIoCapsResponse>, )359     fn set_local_io_caps(
360         &mut self,
361         ctx: RpcContext<'_>,
362         req: SetLocalIoCapsRequest,
363         sink: UnarySink<SetLocalIoCapsResponse>,
364     ) {
365         let status = self.btif_intf.lock().unwrap().set_adapter_property(
366             btif::BluetoothProperty::LocalIoCaps(
367                 BtIoCap::from_i32(req.io_capability).unwrap_or(BtIoCap::Unknown),
368             ),
369         );
370         let mut resp = SetLocalIoCapsResponse::new();
371         resp.status = status;
372         ctx.spawn(async move {
373             sink.success(resp).await.unwrap();
374         })
375     }
376 
toggle_discovery( &mut self, ctx: RpcContext<'_>, req: ToggleDiscoveryRequest, sink: UnarySink<ToggleDiscoveryResponse>, )377     fn toggle_discovery(
378         &mut self,
379         ctx: RpcContext<'_>,
380         req: ToggleDiscoveryRequest,
381         sink: UnarySink<ToggleDiscoveryResponse>,
382     ) {
383         let status = match req.is_start {
384             true => self.btif_intf.lock().unwrap().start_discovery(),
385             false => self.btif_intf.lock().unwrap().cancel_discovery(),
386         };
387         let mut resp = ToggleDiscoveryResponse::new();
388         resp.status = status;
389         ctx.spawn(async move {
390             sink.success(resp).await.unwrap();
391         })
392     }
393 }
394