1 //! Bluetooth testing root facade service
2 
3 use bt_facade_proto::rootservice::*;
4 use bt_facade_proto::rootservice_grpc::{create_root_facade, RootFacade};
5 use bt_hal::facade::HciHalFacadeService;
6 use bt_hci::controller_facade::ControllerFacadeService;
7 use bt_hci::facade::HciFacadeService;
8 use bt_main::Stack;
9 use futures::executor::block_on;
10 use grpcio::*;
11 use std::sync::Arc;
12 use tokio::runtime::Runtime;
13 use tokio::sync::mpsc::{channel, Sender};
14 use tokio::sync::oneshot;
15 
16 /// Bluetooth testing root facade service
17 #[derive(Clone)]
18 pub struct RootFacadeService {
19     rt: Arc<Runtime>,
20     manager: FacadeServiceManager,
21 }
22 
23 impl RootFacadeService {
24     /// Create a new instance of the root facade service
create( rt: Arc<Runtime>, grpc_port: u16, rootcanal_port: Option<u16>, snoop_path: Option<String>, ) -> grpcio::Service25     pub fn create(
26         rt: Arc<Runtime>,
27         grpc_port: u16,
28         rootcanal_port: Option<u16>,
29         snoop_path: Option<String>,
30     ) -> grpcio::Service {
31         create_root_facade(Self {
32             rt: rt.clone(),
33             manager: FacadeServiceManager::create(rt, grpc_port, rootcanal_port, snoop_path),
34         })
35     }
36 }
37 
38 impl RootFacade for RootFacadeService {
start_stack( &mut self, _ctx: RpcContext<'_>, req: StartStackRequest, sink: UnarySink<StartStackResponse>, )39     fn start_stack(
40         &mut self,
41         _ctx: RpcContext<'_>,
42         req: StartStackRequest,
43         sink: UnarySink<StartStackResponse>,
44     ) {
45         self.rt.block_on(self.manager.start(req)).unwrap();
46         sink.success(StartStackResponse::default());
47     }
48 
stop_stack( &mut self, _ctx: RpcContext<'_>, _req: StopStackRequest, sink: UnarySink<StopStackResponse>, )49     fn stop_stack(
50         &mut self,
51         _ctx: RpcContext<'_>,
52         _req: StopStackRequest,
53         sink: UnarySink<StopStackResponse>,
54     ) {
55         self.rt.block_on(self.manager.stop()).unwrap();
56         sink.success(StopStackResponse::default());
57     }
58 }
59 
60 #[derive(Debug)]
61 enum LifecycleCommand {
62     Start { req: StartStackRequest, done: oneshot::Sender<()> },
63     Stop { done: oneshot::Sender<()> },
64 }
65 
66 #[derive(Clone)]
67 struct FacadeServiceManager {
68     lifecycle_tx: Sender<LifecycleCommand>,
69 }
70 
71 struct FacadeServer {
72     server: Server,
73     stack: Stack,
74 }
75 
76 impl FacadeServer {
start(stack: Stack, req: StartStackRequest, grpc_port: u16) -> Self77     async fn start(stack: Stack, req: StartStackRequest, grpc_port: u16) -> Self {
78         let mut services = Vec::new();
79         match req.get_module_under_test() {
80             BluetoothModule::HAL => {
81                 services.push(stack.get_grpc::<HciHalFacadeService>().await);
82             }
83             BluetoothModule::HCI => {
84                 services.push(stack.get_grpc::<HciFacadeService>().await);
85             }
86             BluetoothModule::HCI_INTERFACES => {
87                 services.push(stack.get_grpc::<HciFacadeService>().await);
88                 services.push(stack.get_grpc::<ControllerFacadeService>().await);
89             }
90             _ => unimplemented!(),
91         }
92 
93         let env = Arc::new(Environment::new(2));
94         let mut builder = ServerBuilder::new(env).bind("0.0.0.0", grpc_port);
95         for service in services {
96             builder = builder.register_service(service);
97         }
98 
99         let mut server = builder.build().unwrap();
100         server.start();
101 
102         Self { server, stack }
103     }
104 
stop(&mut self)105     async fn stop(&mut self) {
106         self.server.shutdown().await.unwrap();
107         self.stack.stop().await;
108     }
109 }
110 
111 /// Result type
112 type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
113 
114 impl FacadeServiceManager {
create( rt: Arc<Runtime>, grpc_port: u16, rootcanal_port: Option<u16>, snoop_path: Option<String>, ) -> Self115     fn create(
116         rt: Arc<Runtime>,
117         grpc_port: u16,
118         rootcanal_port: Option<u16>,
119         snoop_path: Option<String>,
120     ) -> Self {
121         let (tx, mut rx) = channel::<LifecycleCommand>(1);
122         let local_rt = rt.clone();
123         rt.spawn(async move {
124             let mut server: Option<FacadeServer> = None;
125             while let Some(cmd) = rx.recv().await {
126                 match cmd {
127                     LifecycleCommand::Start { req, done } => {
128                         let stack = Stack::new(local_rt.clone()).await;
129                         stack.set_rootcanal_port(rootcanal_port).await;
130                         stack.configure_snoop(snoop_path.clone()).await;
131                         server = Some(FacadeServer::start(stack, req, grpc_port).await);
132                         done.send(()).unwrap();
133                     }
134                     LifecycleCommand::Stop { done } => {
135                         if let Some(s) = &mut server {
136                             block_on(s.stop());
137                             server = None;
138                         }
139                         done.send(()).unwrap();
140                     }
141                 }
142             }
143         });
144 
145         Self { lifecycle_tx: tx }
146     }
147 
start(&self, req: StartStackRequest) -> Result<()>148     async fn start(&self, req: StartStackRequest) -> Result<()> {
149         let (tx, rx) = oneshot::channel();
150         self.lifecycle_tx.send(LifecycleCommand::Start { req, done: tx }).await?;
151         rx.await?;
152         Ok(())
153     }
154 
stop(&self) -> Result<()>155     async fn stop(&self) -> Result<()> {
156         let (tx, rx) = oneshot::channel();
157         self.lifecycle_tx.send(LifecycleCommand::Stop { done: tx }).await?;
158         rx.await?;
159         Ok(())
160     }
161 }
162