//! HCI layer facade use crate::{EventRegistry, RawCommandSender}; use bt_common::GrpcFacade; use bt_facade_helpers::RxAdapter; use bt_facade_proto::common::Data; use bt_facade_proto::empty::Empty; use bt_facade_proto::hci_facade::EventRequest; use bt_facade_proto::hci_facade_grpc::{create_hci_facade, HciFacade}; use bt_hal::AclHal; use bt_hal::IsoHal; use bt_packets::hci::{ AclPacket, CommandPacket, EventCode, EventPacket, IsoPacket, LeMetaEventPacket, SubeventCode, }; use gddi::{module, provides, Stoppable}; use grpcio::*; use num_traits::FromPrimitive; use tokio::sync::mpsc::{channel, Sender}; module! { facade_module, providers { HciFacadeService => provide_facade, } } #[provides] async fn provide_facade( commands: RawCommandSender, events: EventRegistry, acl: AclHal, iso: IsoHal, ) -> HciFacadeService { let (evt_tx, evt_rx) = channel::(10); let (le_evt_tx, le_evt_rx) = channel::(10); HciFacadeService { commands, events, evt_tx, evt_rx: RxAdapter::new(evt_rx), le_evt_tx, le_evt_rx: RxAdapter::new(le_evt_rx), acl_tx: acl.tx, acl_rx: RxAdapter::from_arc(acl.rx), iso_tx: iso.tx, iso_rx: RxAdapter::from_arc(iso.rx), } } /// HCI layer facade service #[allow(missing_docs)] #[derive(Clone, Stoppable)] pub struct HciFacadeService { pub commands: RawCommandSender, events: EventRegistry, evt_tx: Sender, pub evt_rx: RxAdapter, le_evt_tx: Sender, pub le_evt_rx: RxAdapter, pub acl_tx: Sender, pub acl_rx: RxAdapter, pub iso_tx: Sender, pub iso_rx: RxAdapter, } impl HciFacadeService { /// Register for the event & plug in the channel to get them back on pub async fn register_event(&mut self, code: u32) { self.events.register(EventCode::from_u32(code).unwrap(), self.evt_tx.clone()).await; } /// Register for the le event & plug in the channel to get them back on pub async fn register_le_event(&mut self, code: u32) { self.events .register_le(SubeventCode::from_u32(code).unwrap(), self.le_evt_tx.clone()) .await; } } impl GrpcFacade for HciFacadeService { fn into_grpc(self) -> grpcio::Service { create_hci_facade(self) } } impl HciFacade for HciFacadeService { fn send_command(&mut self, ctx: RpcContext<'_>, mut data: Data, sink: UnarySink) { let packet = CommandPacket::parse(&data.take_payload()).unwrap(); let mut commands = self.commands.clone(); let evt_tx = self.evt_tx.clone(); ctx.spawn(async move { sink.success(Empty::default()).await.unwrap(); let response = commands.send(packet).await.unwrap(); evt_tx.send(response).await.unwrap(); }); } fn request_event(&mut self, ctx: RpcContext<'_>, req: EventRequest, sink: UnarySink) { let mut clone = self.clone(); ctx.spawn(async move { clone.register_event(req.get_code()).await; sink.success(Empty::default()).await.unwrap(); }); } fn request_le_subevent( &mut self, ctx: RpcContext<'_>, req: EventRequest, sink: UnarySink, ) { let mut clone = self.clone(); ctx.spawn(async move { clone.register_le_event(req.get_code()).await; sink.success(Empty::default()).await.unwrap(); }); } fn send_acl(&mut self, ctx: RpcContext<'_>, mut packet: Data, sink: UnarySink) { let acl_tx = self.acl_tx.clone(); ctx.spawn(async move { acl_tx.send(AclPacket::parse(&packet.take_payload()).unwrap()).await.unwrap(); sink.success(Empty::default()).await.unwrap(); }); } fn stream_events(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: ServerStreamingSink) { self.evt_rx.stream_grpc(ctx, sink); } fn stream_le_subevents( &mut self, ctx: RpcContext<'_>, _req: Empty, sink: ServerStreamingSink, ) { self.le_evt_rx.stream_grpc(ctx, sink); } fn stream_acl(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: ServerStreamingSink) { self.acl_rx.stream_grpc(ctx, sink); } }