1 //! Hci shim
2 
3 use crate::bridge::ffi;
4 use bt_facade_helpers::U8SliceRunnable;
5 use bt_hci::facade::HciFacadeService;
6 use bt_packets::hci::{AclPacket, CommandPacket, Packet};
7 use std::sync::Arc;
8 use tokio::runtime::Runtime;
9 
10 // we take ownership when we get the callbacks
11 unsafe impl Send for ffi::u8SliceCallback {}
12 unsafe impl Send for ffi::u8SliceOnceCallback {}
13 
14 struct CallbackWrapper {
15     cb: cxx::UniquePtr<ffi::u8SliceCallback>,
16 }
17 
18 impl U8SliceRunnable for CallbackWrapper {
run(&self, data: &[u8])19     fn run(&self, data: &[u8]) {
20         self.cb.Run(data);
21     }
22 }
23 
24 pub struct Hci {
25     internal: HciFacadeService,
26     rt: Arc<Runtime>,
27 }
28 
29 impl Hci {
new(rt: Arc<Runtime>, internal: HciFacadeService) -> Self30     pub fn new(rt: Arc<Runtime>, internal: HciFacadeService) -> Self {
31         Self { rt, internal }
32     }
33 }
34 
hci_send_command( hci: &mut Hci, data: &[u8], callback: cxx::UniquePtr<ffi::u8SliceOnceCallback>, )35 pub fn hci_send_command(
36     hci: &mut Hci,
37     data: &[u8],
38     callback: cxx::UniquePtr<ffi::u8SliceOnceCallback>,
39 ) {
40     log::error!("sending command: {:02x?}", data);
41     match CommandPacket::parse(data) {
42         Ok(packet) => {
43             let mut commands = hci.internal.commands.clone();
44             hci.rt.spawn(async move {
45                 let resp = commands.send(packet).await.unwrap();
46                 callback.Run(&resp.to_bytes());
47             });
48         }
49         Err(e) => panic!("could not parse command: {:?} {:02x?}", e, data),
50     }
51 }
52 
hci_send_acl(hci: &mut Hci, data: &[u8])53 pub fn hci_send_acl(hci: &mut Hci, data: &[u8]) {
54     match AclPacket::parse(data) {
55         Ok(packet) => {
56             let tx = hci.internal.acl_tx.clone();
57             hci.rt.spawn(async move {
58                 tx.send(packet).await.unwrap();
59             });
60         }
61         Err(e) => panic!("could not parse acl: {:?} {:02x?}", e, data),
62     }
63 }
64 
hci_register_event(hci: &mut Hci, event: u8)65 pub fn hci_register_event(hci: &mut Hci, event: u8) {
66     let mut hci_facade = hci.internal.clone();
67     hci.rt.spawn(async move {
68         hci_facade.register_event(event.into()).await;
69     });
70 }
71 
hci_register_le_event(hci: &mut Hci, subevent: u8)72 pub fn hci_register_le_event(hci: &mut Hci, subevent: u8) {
73     let mut hci_facade = hci.internal.clone();
74     hci.rt.spawn(async move {
75         hci_facade.register_le_event(subevent.into()).await;
76     });
77 }
78 
hci_set_acl_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>)79 pub fn hci_set_acl_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>) {
80     hci.internal.acl_rx.stream_runnable(&hci.rt, CallbackWrapper { cb });
81 }
82 
hci_set_evt_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>)83 pub fn hci_set_evt_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>) {
84     hci.internal.evt_rx.stream_runnable(&hci.rt, CallbackWrapper { cb });
85 }
86 
hci_set_le_evt_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>)87 pub fn hci_set_le_evt_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>) {
88     hci.internal.le_evt_rx.stream_runnable(&hci.rt, CallbackWrapper { cb });
89 }
90