1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
//! Hci shim
use crate::bridge::ffi;
use bluetooth_rs::hci::facade::HciFacadeService;
use bt_facade_helpers::U8SliceRunnable;
use bt_packets::hci::{AclPacket, CommandPacket, IsoPacket, Packet, ScoPacket};
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 { internal, rt }
}
}
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_send_sco(hci: &mut Hci, data: &[u8]) {
match ScoPacket::parse(data) {
Ok(packet) => {
let tx = hci.internal.sco_tx.clone();
hci.rt.spawn(async move {
tx.send(packet).await.unwrap();
});
}
Err(e) => panic!("could not parse sco: {:?} {:02x?}", e, data),
}
}
pub fn hci_send_iso(hci: &mut Hci, data: &[u8]) {
match IsoPacket::parse(data) {
Ok(packet) => {
let tx = hci.internal.iso_tx.clone();
hci.rt.spawn(async move {
tx.send(packet).await.unwrap();
});
}
Err(e) => panic!("could not parse iso: {:?} {: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_sco_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>) {
hci.internal.sco_rx.stream_runnable(&hci.rt, CallbackWrapper { cb });
}
pub fn hci_set_iso_callback(hci: &mut Hci, cb: cxx::UniquePtr<ffi::u8SliceCallback>) {
hci.internal.iso_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 });
}
|