blob: c2c8d78e411e2c634a7e152dcd7e48eda4962699 [file] [log] [blame]
//! BT HCI HAL facade
use crate::hal::{AclHal, ControlHal, IsoHal};
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::hal_facade_grpc::{create_hci_hal_facade, HciHalFacade};
use bt_packets::hci::{AclPacket, CommandPacket, EventPacket, IsoPacket};
use gddi::{module, provides, Stoppable};
use grpcio::*;
module! {
hal_facade_module,
providers {
HciHalFacadeService => provide_facade,
}
}
#[provides]
async fn provide_facade(control: ControlHal, acl: AclHal, iso: IsoHal) -> HciHalFacadeService {
HciHalFacadeService {
evt_rx: RxAdapter::from_arc(control.rx.clone()),
acl_rx: RxAdapter::from_arc(acl.rx.clone()),
iso_rx: RxAdapter::from_arc(iso.rx.clone()),
control,
acl,
iso,
}
}
/// HCI HAL facade service
#[derive(Clone, Stoppable)]
pub struct HciHalFacadeService {
evt_rx: RxAdapter<EventPacket>,
acl_rx: RxAdapter<AclPacket>,
iso_rx: RxAdapter<IsoPacket>,
control: ControlHal,
acl: AclHal,
iso: IsoHal,
}
impl GrpcFacade for HciHalFacadeService {
fn into_grpc(self) -> grpcio::Service {
create_hci_hal_facade(self)
}
}
impl HciHalFacade for HciHalFacadeService {
fn send_command(&mut self, ctx: RpcContext<'_>, mut data: Data, sink: UnarySink<Empty>) {
let cmd_tx = self.control.tx.clone();
ctx.spawn(async move {
cmd_tx.send(CommandPacket::parse(&data.take_payload()).unwrap()).await.unwrap();
sink.success(Empty::default()).await.unwrap();
});
}
fn send_acl(&mut self, ctx: RpcContext<'_>, mut data: Data, sink: UnarySink<Empty>) {
let acl_tx = self.acl.tx.clone();
ctx.spawn(async move {
acl_tx.send(AclPacket::parse(&data.take_payload()).unwrap()).await.unwrap();
sink.success(Empty::default()).await.unwrap();
});
}
fn send_sco(&mut self, _ctx: RpcContext<'_>, _sco: Data, _sink: UnarySink<Empty>) {
unimplemented!()
}
fn send_iso(&mut self, ctx: RpcContext<'_>, mut data: Data, sink: UnarySink<Empty>) {
let iso_tx = self.iso.tx.clone();
ctx.spawn(async move {
iso_tx.send(IsoPacket::parse(&data.take_payload()).unwrap()).await.unwrap();
sink.success(Empty::default()).await.unwrap();
});
}
fn stream_events(&mut self, ctx: RpcContext<'_>, _: Empty, sink: ServerStreamingSink<Data>) {
self.evt_rx.stream_grpc(ctx, sink);
}
fn stream_acl(&mut self, ctx: RpcContext<'_>, _: Empty, sink: ServerStreamingSink<Data>) {
self.acl_rx.stream_grpc(ctx, sink);
}
fn stream_sco(&mut self, _ctx: RpcContext<'_>, _: Empty, _sink: ServerStreamingSink<Data>) {
unimplemented!()
}
fn stream_iso(&mut self, ctx: RpcContext<'_>, _: Empty, sink: ServerStreamingSink<Data>) {
self.iso_rx.stream_grpc(ctx, sink);
}
}