• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Adapter service facade
2 
3 use bt_topshim::btif;
4 use bt_topshim::btif::{BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface};
5 
6 use bt_topshim_facade_protobuf::empty::Empty;
7 use bt_topshim_facade_protobuf::facade::{
8     EventType, FetchEventsRequest, FetchEventsResponse, SetDiscoveryModeRequest,
9     SetDiscoveryModeResponse, ToggleStackRequest, ToggleStackResponse,
10 };
11 use bt_topshim_facade_protobuf::facade_grpc::{create_adapter_service, AdapterService};
12 use futures::sink::SinkExt;
13 use grpcio::*;
14 
15 use std::sync::{Arc, Mutex};
16 use tokio::runtime::Runtime;
17 use tokio::sync::mpsc;
18 use tokio::sync::Mutex as TokioMutex;
get_bt_dispatcher( btif: Arc<Mutex<BluetoothInterface>>, tx: mpsc::Sender<BaseCallbacks>, ) -> BaseCallbacksDispatcher19 fn get_bt_dispatcher(
20     btif: Arc<Mutex<BluetoothInterface>>,
21     tx: mpsc::Sender<BaseCallbacks>,
22 ) -> BaseCallbacksDispatcher {
23     BaseCallbacksDispatcher {
24         dispatch: Box::new(move |cb: BaseCallbacks| {
25             if tx.clone().try_send(cb.clone()).is_err() {
26                 println!("Cannot send event {:?}", cb);
27             }
28             match cb {
29                 BaseCallbacks::AdapterState(state) => {
30                     println!("State changed to {:?}", state);
31                 }
32                 BaseCallbacks::SspRequest(addr, _, _, variant, passkey) => {
33                     btif.lock().unwrap().ssp_reply(&addr, variant, 1, passkey);
34                 }
35                 _ => (),
36             }
37         }),
38     }
39 }
40 
41 /// Main object for Adapter facade service
42 #[derive(Clone)]
43 pub struct AdapterServiceImpl {
44     #[allow(dead_code)]
45     rt: Arc<Runtime>,
46     btif_intf: Arc<Mutex<BluetoothInterface>>,
47     event_rx: Arc<TokioMutex<mpsc::Receiver<BaseCallbacks>>>,
48     #[allow(dead_code)]
49     event_tx: mpsc::Sender<BaseCallbacks>,
50 }
51 
52 impl AdapterServiceImpl {
53     /// Create a new instance of the root facade service
create(rt: Arc<Runtime>, btif_intf: Arc<Mutex<BluetoothInterface>>) -> grpcio::Service54     pub fn create(rt: Arc<Runtime>, btif_intf: Arc<Mutex<BluetoothInterface>>) -> grpcio::Service {
55         let (event_tx, rx) = mpsc::channel(10);
56         btif_intf.lock().unwrap().initialize(
57             get_bt_dispatcher(btif_intf.clone(), event_tx.clone()),
58             vec!["INIT_gd_hci=true".to_string()],
59         );
60         create_adapter_service(Self {
61             rt,
62             btif_intf,
63             event_rx: Arc::new(TokioMutex::new(rx)),
64             event_tx,
65         })
66     }
67 }
68 
69 impl AdapterService for AdapterServiceImpl {
fetch_events( &mut self, ctx: RpcContext<'_>, _req: FetchEventsRequest, mut sink: ServerStreamingSink<FetchEventsResponse>, )70     fn fetch_events(
71         &mut self,
72         ctx: RpcContext<'_>,
73         _req: FetchEventsRequest,
74         mut sink: ServerStreamingSink<FetchEventsResponse>,
75     ) {
76         let rx = self.event_rx.clone();
77         ctx.spawn(async move {
78             while let Some(event) = rx.lock().await.recv().await {
79                 match event {
80                     BaseCallbacks::AdapterState(_state) => {
81                         let mut rsp = FetchEventsResponse::new();
82                         rsp.event_type = EventType::ADAPTER_STATE;
83                         rsp.data = "ON".to_string();
84                         sink.send((rsp, WriteFlags::default())).await.unwrap();
85                     }
86                     BaseCallbacks::SspRequest(_, _, _, _, _) => {}
87                     _ => (),
88                 }
89             }
90         })
91     }
92 
toggle_stack( &mut self, ctx: RpcContext<'_>, req: ToggleStackRequest, sink: UnarySink<ToggleStackResponse>, )93     fn toggle_stack(
94         &mut self,
95         ctx: RpcContext<'_>,
96         req: ToggleStackRequest,
97         sink: UnarySink<ToggleStackResponse>,
98     ) {
99         match req.start_stack {
100             true => self.btif_intf.lock().unwrap().enable(),
101             false => self.btif_intf.lock().unwrap().disable(),
102         };
103         ctx.spawn(async move {
104             sink.success(ToggleStackResponse::default()).await.unwrap();
105         })
106     }
107 
set_discovery_mode( &mut self, ctx: RpcContext<'_>, _req: SetDiscoveryModeRequest, sink: UnarySink<SetDiscoveryModeResponse>, )108     fn set_discovery_mode(
109         &mut self,
110         ctx: RpcContext<'_>,
111         _req: SetDiscoveryModeRequest,
112         sink: UnarySink<SetDiscoveryModeResponse>,
113     ) {
114         self.btif_intf.lock().unwrap().set_adapter_property(
115             btif::BluetoothProperty::AdapterScanMode(btif::BtScanMode::Connectable),
116         );
117 
118         ctx.spawn(async move {
119             sink.success(SetDiscoveryModeResponse::default()).await.unwrap();
120         })
121     }
122 
clear_event_filter(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>)123     fn clear_event_filter(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>) {
124         self.btif_intf.lock().unwrap().clear_event_filter();
125         ctx.spawn(async move {
126             sink.success(Empty::default()).await.unwrap();
127         })
128     }
129 }
130