You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.5 KiB

//! Hci shim
use crate::bridge::ffi;
use bt_facade_helpers::U8SliceRunnable;
use bt_hci::facade::HciFacadeService;
use bt_packets::hci::{AclPacket, CommandPacket, Packet};
use std::sync::Arc;
use tokio::runtime::Runtime;
// we take ownership when we get the callbacks
unsafe impl Send for ffi::u8SliceCallback {}
unsafe impl Send for ffi::u8SliceOnceCallback {}
struct CallbackWrapper {
cb: cxx::UniquePtr<ffi::u8SliceCallback>,
}
impl U8SliceRunnable for CallbackWrapper {
fn run(&self, data: &[u8]) {
self.cb.Run(data);
}
}
pub struct Hci {
internal: HciFacadeService,
rt: Arc<Runtime>,
}
impl Hci {
pub fn new(rt: Arc<Runtime>, internal: HciFacadeService) -> Self {
Self { rt, internal }
}
}
pub fn hci_send_command(
hci: &mut Hci,
data: &[u8],
callback: cxx::UniquePtr<ffi::u8SliceOnceCallback>,
) {
log::error!("sending command: {:02x?}", data);
match CommandPacket::parse(data) {
Ok(packet) => {
let mut commands = hci.internal.commands.clone();
hci.rt.spawn(async move {
let resp = commands.send(packet).await.unwrap();
callback.Run(&resp.to_bytes());
});
}
Err(e) => panic!("could not parse command: {:?} {:02x?}", e, data),
}
}
pub fn hci_send_acl(hci: &mut Hci, data: &[u8]) {
match AclPacket::parse(data) {
Ok(packet) => {
let tx = hci.internal.acl_tx.clone();
hci.rt.spawn(async move {
tx.send(packet).await.unwrap();
});
}
Err(e) => panic!("could not parse acl: {:?} {:02x?}", e, data),
}
}
pub fn hci_register_event(hci: &mut Hci, event: u8) {
let mut hci_facade = hci.internal.clone();
hci.rt.spawn(async move {
hci_facade.register_event(event.into()).await;
});
}
pub fn hci_register_le_event(hci: &mut Hci, subevent: u8) {
let mut hci_facade = hci.internal.clone();
hci.rt.spawn(async move {
hci_facade.register_le_event(subevent.into()).await;
});
}
pub fn hci_set_acl_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>) {
hci.internal.acl_rx.stream_runnable(&hci.rt, CallbackWrapper { cb });
}
pub fn hci_set_evt_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>) {
hci.internal.evt_rx.stream_runnable(&hci.rt, CallbackWrapper { cb });
}
pub fn hci_set_le_evt_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>) {
hci.internal.le_evt_rx.stream_runnable(&hci.rt, CallbackWrapper { cb });
}