1 //! Main BT lifecycle support 2 #[cfg(target_os = "android")] 3 #[macro_use] 4 extern crate lazy_static; 5 6 pub mod hal; 7 pub mod hci; 8 pub mod link; 9 10 use crate::hal::rootcanal_hal::RootcanalConfig; 11 use crate::hal::snoop::{SnoopConfig, SnoopMode}; 12 use bt_common::GrpcFacade; 13 use gddi::{module, Registry, RegistryBuilder, Stoppable}; 14 use std::sync::Arc; 15 use tokio::runtime::Runtime; 16 17 module! { 18 stack_module, 19 submodules { 20 crate::hal::hal_module, 21 crate::hci::hci_module, 22 } 23 } 24 25 /// Central state manager 26 pub struct Stack { 27 registry: Arc<Registry>, 28 rt: Arc<Runtime>, 29 } 30 31 impl Stack { 32 /// Construct a new Stack new(rt: Arc<Runtime>) -> Self33 pub async fn new(rt: Arc<Runtime>) -> Self { 34 let registry = Arc::new(RegistryBuilder::new().register_module(stack_module).build()); 35 registry.inject(rt.clone()).await; 36 37 Self { registry, rt } 38 } 39 40 /// Helper to set the rootcanal port set_rootcanal_port(&self, port: Option<u16>)41 pub async fn set_rootcanal_port(&self, port: Option<u16>) { 42 if let Some(port) = port { 43 self.registry.inject(RootcanalConfig::new("127.0.0.1", port)).await; 44 } 45 } 46 47 /// Configures snoop with defaults use_default_snoop(&self)48 pub async fn use_default_snoop(&self) { 49 self.configure_snoop(None).await; 50 } 51 52 /// Configures snoop. If the path is provided, full logging is turned on configure_snoop(&self, path: Option<String>)53 pub async fn configure_snoop(&self, path: Option<String>) { 54 let mut config = SnoopConfig::default(); 55 if let Some(path) = path { 56 config.set_path(path); 57 config.set_mode(SnoopMode::Full); 58 } 59 self.registry.inject(config).await; 60 } 61 62 /// Helper forwarding to underlying registry get<T: 'static + Clone + Send + Sync + Stoppable>(&self) -> T63 pub async fn get<T: 'static + Clone + Send + Sync + Stoppable>(&self) -> T { 64 self.registry.get::<T>().await 65 } 66 67 /// Get, but blocks the current thread. get_blocking<T: 'static + Clone + Send + Sync + Stoppable>(&self) -> T68 pub fn get_blocking<T: 'static + Clone + Send + Sync + Stoppable>(&self) -> T { 69 self.rt.block_on(self.get::<T>()) 70 } 71 72 /// Helper to get a grpc service get_grpc<T: 'static + Clone + Send + Sync + GrpcFacade + Stoppable>( &self, ) -> grpcio::Service73 pub async fn get_grpc<T: 'static + Clone + Send + Sync + GrpcFacade + Stoppable>( 74 &self, 75 ) -> grpcio::Service { 76 self.get::<T>().await.into_grpc() 77 } 78 79 /// Stop the stack stop(&mut self)80 pub async fn stop(&mut self) { 81 self.registry.stop_all().await; 82 } 83 84 /// Stop, but blocks the current thread. stop_blocking(&mut self)85 pub fn stop_blocking(&mut self) { 86 let rt = self.rt.clone(); 87 rt.block_on(self.stop()); 88 } 89 90 /// Get a clone of the underlying runtime for this stack get_runtime(&self) -> Arc<Runtime>91 pub fn get_runtime(&self) -> Arc<Runtime> { 92 self.rt.clone() 93 } 94 } 95