OSDN Git Service

rusty-gd: move hci facade client contents to root server
authorZach Johnson <zachoverflow@google.com>
Thu, 5 Nov 2020 00:41:23 +0000 (16:41 -0800)
committerZach Johnson <zachoverflow@google.com>
Fri, 6 Nov 2020 21:10:24 +0000 (13:10 -0800)
Bug: 171749953
Tag: #gd-refactor
Test: gd/cert/run --rhost
Change-Id: I97ef3f26cb4a8458ebb7a9eda1df0b4391459a1c

gd/rust/facade/Android.bp
gd/rust/facade/src/lib.rs
gd/rust/facade/src/main.rs
gd/rust/hci/Android.bp
gd/rust/hci/src/facade/hci_facade_client.rs [deleted file]
gd/rust/hci/src/facade/hci_facade_main.rs [deleted file]

index 5a523fc..97aee08 100644 (file)
@@ -4,6 +4,8 @@ rust_library {
     srcs: ["src/lib.rs"],
     edition: "2018",
     rustlibs: [
+      "libbt_hal",
+      "libbt_hci",
       "libbt_facade_rootservice_proto",
       "libbt_facade_common_proto",
       "libfutures",
index 9959b1d..482b2f9 100644 (file)
@@ -11,17 +11,26 @@ pub mod empty {
 pub use bt_facade_common_proto::common;
 pub use bt_facade_rootservice_proto::rootservice;
 
+use bt_hal::rootcanal_hal::{RootcanalConfig, RootcanalHal};
+use bt_hci::facade::hci_facade_server::HciLayerFacadeService;
+use bt_hci::Hci;
+
 use tokio::runtime::Runtime;
+use tokio::sync::mpsc::{channel, Sender};
+use tokio::sync::oneshot;
 
 use grpcio::*;
 
 use std::sync::Arc;
 
+use futures::executor::block_on;
+
 /// Bluetooth testing root facade service
 #[derive(Clone)]
 pub struct RootFacadeService {
     /// Tokio runtime
-    pub rt: Arc<Runtime>,
+    rt: Arc<Runtime>,
+    manager: FacadeServiceManager,
 }
 
 use bt_facade_rootservice_proto::rootservice::*;
@@ -30,8 +39,15 @@ use rootservice_grpc::RootFacade;
 
 impl RootFacadeService {
     /// Create a new instance of the root facade service
-    pub fn create(rt: Arc<Runtime>) -> grpcio::Service {
-        create_root_facade(Self { rt })
+    pub fn create(
+        rt: Arc<Runtime>,
+        grpc_port: u16,
+        rootcanal_port: Option<u16>,
+    ) -> grpcio::Service {
+        create_root_facade(Self {
+            rt: rt.clone(),
+            manager: FacadeServiceManager::create(rt, grpc_port, rootcanal_port),
+        })
     }
 }
 
@@ -39,18 +55,110 @@ impl RootFacade for RootFacadeService {
     fn start_stack(
         &mut self,
         _ctx: RpcContext<'_>,
-        mut _cmd: StartStackRequest,
-        _sink: UnarySink<StartStackResponse>,
+        req: StartStackRequest,
+        sink: UnarySink<StartStackResponse>,
     ) {
-        unimplemented!()
+        self.rt.block_on(self.manager.start(req)).unwrap();
+        sink.success(StartStackResponse::default());
     }
 
     fn stop_stack(
         &mut self,
         _ctx: RpcContext<'_>,
-        mut _cmd: StopStackRequest,
-        _sink: UnarySink<StopStackResponse>,
+        _req: StopStackRequest,
+        sink: UnarySink<StopStackResponse>,
     ) {
-        unimplemented!()
+        self.rt.block_on(self.manager.stop()).unwrap();
+        sink.success(StopStackResponse::default());
+    }
+}
+
+#[derive(Debug)]
+enum LifecycleCommand {
+    Start {
+        req: StartStackRequest,
+        done: oneshot::Sender<()>,
+    },
+    Stop {
+        done: oneshot::Sender<()>,
+    },
+}
+
+#[derive(Clone)]
+struct FacadeServiceManager {
+    lifecycle_tx: Sender<LifecycleCommand>,
+}
+
+/// Result type
+type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
+
+impl FacadeServiceManager {
+    fn create(rt: Arc<Runtime>, grpc_port: u16, rootcanal_port: Option<u16>) -> Self {
+        let (tx, mut rx) = channel::<LifecycleCommand>(1);
+        let local_rt = rt.clone();
+        local_rt.spawn(async move {
+            let mut server: Option<Server> = None;
+            while let Some(cmd) = rx.recv().await {
+                match cmd {
+                    LifecycleCommand::Start { req, done } => {
+                        server =
+                            Some(Self::start_internal(&rt, req, grpc_port, rootcanal_port).await);
+                        done.send(()).unwrap();
+                    }
+                    LifecycleCommand::Stop { done } => {
+                        if let Some(s) = &mut server {
+                            block_on(s.shutdown()).unwrap();
+                            server = None;
+                        }
+                        done.send(()).unwrap();
+                    }
+                }
+            }
+        });
+
+        Self { lifecycle_tx: tx }
+    }
+
+    async fn start(&self, req: StartStackRequest) -> Result<()> {
+        let (tx, rx) = oneshot::channel();
+        self.lifecycle_tx
+            .send(LifecycleCommand::Start { req, done: tx })
+            .await?;
+        rx.await?;
+        Ok(())
+    }
+
+    async fn stop(&self) -> Result<()> {
+        let (tx, rx) = oneshot::channel();
+        self.lifecycle_tx
+            .send(LifecycleCommand::Stop { done: tx })
+            .await?;
+        rx.await?;
+        Ok(())
+    }
+
+    // TODO this is messy and needs to be overhauled to support bringing up the stack to partial
+    // layers. Will be cleaned up soon.
+    async fn start_internal(
+        rt: &Arc<Runtime>,
+        _req: StartStackRequest,
+        grpc_port: u16,
+        rootcanal_port: Option<u16>,
+    ) -> Server {
+        let env = Arc::new(Environment::new(2));
+        let hal_exports = RootcanalHal::start(
+            RootcanalConfig::new(rootcanal_port.unwrap(), "127.0.0.1"),
+            Arc::clone(&rt),
+        )
+        .await
+        .unwrap();
+        let hci_exports = Hci::start(hal_exports, Arc::clone(&rt));
+        let mut server = ServerBuilder::new(env)
+            .register_service(HciLayerFacadeService::create(hci_exports, Arc::clone(&rt)))
+            .bind("0.0.0.0", grpc_port)
+            .build()
+            .unwrap();
+        server.start();
+        server
     }
 }
index a480c98..b8100ad 100644 (file)
@@ -72,15 +72,11 @@ async fn async_main(rt: Arc<Runtime>, mut sigint: mpsc::UnboundedReceiver<()>) {
     let root_server_port = value_t!(matches, "root-server-port", u16).unwrap();
     let grpc_port = value_t!(matches, "grpc-port", u16).unwrap();
     let signal_port = value_t!(matches, "signal-port", u16).unwrap();
-
-    println!(
-        "root server port: {}, grpc port: {}, signal port {}",
-        root_server_port, grpc_port, signal_port
-    );
+    let rootcanal_port = value_t!(matches, "rootcanal-port", u16).ok();
 
     let env = Arc::new(Environment::new(2));
     let mut server = ServerBuilder::new(env)
-        .register_service(RootFacadeService::create(rt))
+        .register_service(RootFacadeService::create(rt, grpc_port, rootcanal_port))
         .bind("0.0.0.0", root_server_port)
         .build()
         .unwrap();
index 793f3b1..802949e 100644 (file)
@@ -20,37 +20,3 @@ rust_library {
     ],
     host_supported: true,
 }
-
-rust_binary {
-    name: "hci_facade_client",
-    crate_name: "hci_facade_client",
-    srcs: ["src/facade/hci_facade_client.rs"],
-    edition: "2018",
-    rustlibs: [
-        "libbt_hal",
-        "libbt_hci",
-        "libbytes",
-        "libfutures",
-        "libgrpcio",
-        "libprotobuf",
-        "libtokio",
-    ],
-    host_supported: true,
-}
-
-rust_binary {
-    name: "hci_facade_main",
-    crate_name: "hci_facade_main",
-    srcs: ["src/facade/hci_facade_main.rs"],
-    edition: "2018",
-    rustlibs: [
-        "libbt_hal",
-        "libbt_hci",
-        "libbytes",
-        "libfutures",
-        "libgrpcio",
-        "libprotobuf",
-        "libtokio",
-    ],
-    host_supported: true,
-}
diff --git a/gd/rust/hci/src/facade/hci_facade_client.rs b/gd/rust/hci/src/facade/hci_facade_client.rs
deleted file mode 100644 (file)
index 16c25ef..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-//! A client that connects to HciLayerFacadeService
-
-// TODO(qasimj): This client is temporary and is used for testing only.
-// It will be removed later.
-
-use grpcio::*;
-
-use std::sync::Arc;
-
-use futures::TryStreamExt;
-
-use bt_hci as hci;
-use hci::facade::protos::empty::Empty;
-use hci::facade::protos::facade::{CommandMsg, EventCodeMsg};
-use hci::facade::protos::hci_layer_facade_grpc::HciLayerFacadeClient;
-
-fn new_event_code(code: u32) -> EventCodeMsg {
-    let mut event_code = EventCodeMsg::default();
-    event_code.set_code(code);
-    event_code
-}
-
-fn new_command(bytes: Vec<u8>) -> CommandMsg {
-    let mut cmd = CommandMsg::default();
-    cmd.set_command(bytes);
-    cmd
-}
-
-async fn register_event_handler(
-    client: &HciLayerFacadeClient,
-    event_code: &EventCodeMsg,
-) -> Result<()> {
-    let register_event_handler = client.register_event_handler_async(event_code)?;
-    register_event_handler.await?;
-
-    Ok(())
-}
-
-async fn enqueue_command_with_complete(
-    client: &HciLayerFacadeClient,
-    cmd: &CommandMsg,
-) -> Result<()> {
-    let enqueue = client.enqueue_command_with_complete_async(cmd)?;
-    enqueue.await?;
-    Ok(())
-}
-
-async fn fetch_events(client: &HciLayerFacadeClient) -> Result<()> {
-    let mut fetch_events = client.fetch_events(&Empty::new())?;
-    while let Some(event) = fetch_events.try_next().await? {
-        println!("Received Event: {:?}", event);
-    }
-    Ok(())
-}
-
-async fn async_main() -> Result<()> {
-    let env = Arc::new(Environment::new(2));
-    let channel = ChannelBuilder::new(env).connect("pop-os:8999");
-    let client = HciLayerFacadeClient::new(channel);
-
-    println!("Registering event handler!");
-    register_event_handler(&client, &new_event_code(0x0eu32)).await?;
-
-    let handle = fetch_events(&client);
-    let cmd = &new_command(vec![0x0du8, 0x08, 0x04, 0x07, 0x00, 0x06, 0x00]);
-
-    println!("Enqueue commands");
-    enqueue_command_with_complete(&client, cmd).await.unwrap();
-
-    enqueue_command_with_complete(&client, cmd).await.unwrap();
-
-    println!("Waiting for events...");
-    handle.await.unwrap();
-
-    Ok(())
-}
-
-fn main() {
-    futures::executor::block_on(async_main()).unwrap();
-}
diff --git a/gd/rust/hci/src/facade/hci_facade_main.rs b/gd/rust/hci/src/facade/hci_facade_main.rs
deleted file mode 100644 (file)
index dab436a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-//! A server providing the HciLayerFacadeService
-
-use bt_hal as hal;
-use bt_hci as hci;
-use futures::channel::oneshot;
-use futures::executor::block_on;
-use grpcio::*;
-use hal::rootcanal_hal::{RootcanalConfig, RootcanalHal};
-use hci::facade::hci_facade_server::HciLayerFacadeService;
-use hci::Hci;
-
-use std::io::{self, Read};
-use std::sync::Arc;
-use std::thread;
-
-use tokio::runtime::Runtime;
-
-async fn async_main(rt: Arc<Runtime>) -> Result<()> {
-    let env = Arc::new(Environment::new(2));
-    let hal_exports = RootcanalHal::start(RootcanalConfig::new(6402, "127.0.0.1"), Arc::clone(&rt)).await.unwrap();
-    let hci_exports = Hci::start(hal_exports, Arc::clone(&rt));
-    let mut server = ServerBuilder::new(env)
-        .register_service(HciLayerFacadeService::create(hci_exports, Arc::clone(&rt)))
-        .bind("0.0.0.0", 8999)
-        .build()
-        .unwrap();
-    server.start();
-
-    let (tx, rx) = oneshot::channel();
-
-    thread::spawn(move || {
-        println!("Press ENTER to exit...");
-        let _ = io::stdin().read(&mut [0]).unwrap();
-        tx.send(())
-    });
-    block_on(rx).unwrap();
-    block_on(server.shutdown()).unwrap();
-
-    Ok(())
-}
-
-fn main() {
-    let rt = Arc::new(Runtime::new().unwrap());
-    let runtime = Arc::clone(&rt);
-    runtime.block_on(async_main(rt)).unwrap();
-}