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