1 //! Host Controller Interface (HCI)
2
3 /// HCI controller info
4 pub mod controller;
5 /// Controller facade service
6 pub mod controller_facade;
7 /// HCI errors
8 pub mod error;
9 /// HCI layer facade service
10 pub mod facade;
11
12 pub use bt_hci_custom_types::*;
13 pub use controller::ControllerExports;
14
15 use bt_common::time::Alarm;
16 use bt_hal::ControlHal;
17 use bt_packets::hci::EventChild::{
18 CommandComplete, CommandStatus, LeMetaEvent, MaxSlotsChange, PageScanRepetitionModeChange,
19 VendorSpecificEvent,
20 };
21 use bt_packets::hci::{
22 CommandExpectations, CommandPacket, ErrorCode, EventCode, EventPacket, LeMetaEventPacket,
23 ResetBuilder, SubeventCode,
24 };
25 use error::Result;
26 use gddi::{module, part_out, provides, Stoppable};
27 use log::error;
28 use std::collections::HashMap;
29 use std::sync::Arc;
30 use std::time::Duration;
31 use tokio::runtime::Runtime;
32 use tokio::select;
33 use tokio::sync::mpsc::{channel, Receiver, Sender};
34 use tokio::sync::{oneshot, Mutex};
35
36 module! {
37 hci_module,
38 submodules {
39 facade::facade_module,
40 controller_facade::controller_facade_module,
41 controller::controller_module,
42 },
43 providers {
44 parts Hci => provide_hci,
45 },
46 }
47
48 #[part_out]
49 #[derive(Clone, Stoppable)]
50 struct Hci {
51 raw_commands: RawCommandSender,
52 commands: CommandSender,
53 events: EventRegistry,
54 }
55
56 #[provides]
provide_hci(control: ControlHal, rt: Arc<Runtime>) -> Hci57 async fn provide_hci(control: ControlHal, rt: Arc<Runtime>) -> Hci {
58 let (cmd_tx, cmd_rx) = channel::<QueuedCommand>(10);
59 let evt_handlers = Arc::new(Mutex::new(HashMap::new()));
60 let le_evt_handlers = Arc::new(Mutex::new(HashMap::new()));
61
62 rt.spawn(dispatch(
63 evt_handlers.clone(),
64 le_evt_handlers.clone(),
65 control.rx,
66 control.tx,
67 cmd_rx,
68 ));
69
70 let raw_commands = RawCommandSender { cmd_tx };
71 let mut commands = CommandSender { raw: raw_commands.clone() };
72
73 assert!(
74 commands.send(ResetBuilder {}).await.get_status() == ErrorCode::Success,
75 "reset did not complete successfully"
76 );
77
78 Hci { raw_commands, commands, events: EventRegistry { evt_handlers, le_evt_handlers } }
79 }
80
81 #[derive(Debug)]
82 struct QueuedCommand {
83 cmd: CommandPacket,
84 fut: oneshot::Sender<EventPacket>,
85 }
86
87 /// Sends raw commands. Only useful for facades & shims, or wrapped as a CommandSender.
88 #[derive(Clone, Stoppable)]
89 pub struct RawCommandSender {
90 cmd_tx: Sender<QueuedCommand>,
91 }
92
93 impl RawCommandSender {
94 /// Send a command, but does not automagically associate the expected returning event type.
95 ///
96 /// Only really useful for facades & shims.
send(&mut self, cmd: CommandPacket) -> Result<EventPacket>97 pub async fn send(&mut self, cmd: CommandPacket) -> Result<EventPacket> {
98 let (tx, rx) = oneshot::channel::<EventPacket>();
99 self.cmd_tx.send(QueuedCommand { cmd, fut: tx }).await?;
100 let event = rx.await?;
101 Ok(event)
102 }
103 }
104
105 /// Sends commands to the controller
106 #[derive(Clone, Stoppable)]
107 pub struct CommandSender {
108 raw: RawCommandSender,
109 }
110
111 impl CommandSender {
112 /// Send a command to the controller, getting an expected response back
send<T: Into<CommandPacket> + CommandExpectations>( &mut self, cmd: T, ) -> T::ResponseType113 pub async fn send<T: Into<CommandPacket> + CommandExpectations>(
114 &mut self,
115 cmd: T,
116 ) -> T::ResponseType {
117 T::_to_response_type(self.raw.send(cmd.into()).await.unwrap())
118 }
119 }
120
121 /// Provides ability to register and unregister for HCI events
122 #[derive(Clone, Stoppable)]
123 pub struct EventRegistry {
124 evt_handlers: Arc<Mutex<HashMap<EventCode, Sender<EventPacket>>>>,
125 le_evt_handlers: Arc<Mutex<HashMap<SubeventCode, Sender<LeMetaEventPacket>>>>,
126 }
127
128 impl EventRegistry {
129 /// Indicate interest in specific HCI events
register(&mut self, code: EventCode, sender: Sender<EventPacket>)130 pub async fn register(&mut self, code: EventCode, sender: Sender<EventPacket>) {
131 match code {
132 EventCode::CommandStatus
133 | EventCode::CommandComplete
134 | EventCode::LeMetaEvent
135 | EventCode::PageScanRepetitionModeChange
136 | EventCode::MaxSlotsChange
137 | EventCode::VendorSpecific => panic!("{:?} is a protected event", code),
138 _ => {
139 assert!(
140 self.evt_handlers.lock().await.insert(code, sender).is_none(),
141 "A handler for {:?} is already registered",
142 code
143 );
144 }
145 }
146 }
147
148 /// Remove interest in specific HCI events
unregister(&mut self, code: EventCode)149 pub async fn unregister(&mut self, code: EventCode) {
150 self.evt_handlers.lock().await.remove(&code);
151 }
152
153 /// Indicate interest in specific LE events
register_le(&mut self, code: SubeventCode, sender: Sender<LeMetaEventPacket>)154 pub async fn register_le(&mut self, code: SubeventCode, sender: Sender<LeMetaEventPacket>) {
155 assert!(
156 self.le_evt_handlers.lock().await.insert(code, sender).is_none(),
157 "A handler for {:?} is already registered",
158 code
159 );
160 }
161
162 /// Remove interest in specific LE events
unregister_le(&mut self, code: SubeventCode)163 pub async fn unregister_le(&mut self, code: SubeventCode) {
164 self.le_evt_handlers.lock().await.remove(&code);
165 }
166 }
167
dispatch( evt_handlers: Arc<Mutex<HashMap<EventCode, Sender<EventPacket>>>>, le_evt_handlers: Arc<Mutex<HashMap<SubeventCode, Sender<LeMetaEventPacket>>>>, evt_rx: Arc<Mutex<Receiver<EventPacket>>>, cmd_tx: Sender<CommandPacket>, mut cmd_rx: Receiver<QueuedCommand>, )168 async fn dispatch(
169 evt_handlers: Arc<Mutex<HashMap<EventCode, Sender<EventPacket>>>>,
170 le_evt_handlers: Arc<Mutex<HashMap<SubeventCode, Sender<LeMetaEventPacket>>>>,
171 evt_rx: Arc<Mutex<Receiver<EventPacket>>>,
172 cmd_tx: Sender<CommandPacket>,
173 mut cmd_rx: Receiver<QueuedCommand>,
174 ) {
175 let mut pending: Option<QueuedCommand> = None;
176 let mut hci_timeout = Alarm::new();
177 loop {
178 select! {
179 Some(evt) = consume(&evt_rx) => {
180 match evt.specialize() {
181 CommandStatus(evt) => {
182 hci_timeout.cancel();
183 let this_opcode = evt.get_command_op_code();
184 match pending.take() {
185 Some(QueuedCommand{cmd, fut}) if cmd.get_op_code() == this_opcode => {
186 if let Err(e) = fut.send(evt.into()) {
187 error!("failure dispatching command status {:?}", e);
188 }
189 },
190 Some(QueuedCommand{cmd, ..}) => panic!("Waiting for {:?}, got {:?}", cmd.get_op_code(), this_opcode),
191 None => panic!("Unexpected status event with opcode {:?}", this_opcode),
192 }
193 },
194 CommandComplete(evt) => {
195 hci_timeout.cancel();
196 let this_opcode = evt.get_command_op_code();
197 match pending.take() {
198 Some(QueuedCommand{cmd, fut}) if cmd.get_op_code() == this_opcode => {
199 if let Err(e) = fut.send(evt.into()) {
200 error!("failure dispatching command complete {:?}", e);
201 }
202 },
203 Some(QueuedCommand{cmd, ..}) => panic!("Waiting for {:?}, got {:?}", cmd.get_op_code(), this_opcode),
204 None => panic!("Unexpected complete event with opcode {:?}", this_opcode),
205 }
206 },
207 LeMetaEvent(evt) => {
208 let code = evt.get_subevent_code();
209 match le_evt_handlers.lock().await.get(&code) {
210 Some(sender) => {
211 if let Err(e) = sender.send(evt).await {
212 error!("le meta event channel closed {:?}", e);
213 }
214 },
215 None => panic!("Unhandled le subevent {:?}", code),
216 }
217 },
218 PageScanRepetitionModeChange(_) => {},
219 MaxSlotsChange(_) => {},
220 VendorSpecificEvent(_) => {},
221 _ => {
222 let code = evt.get_event_code();
223 match evt_handlers.lock().await.get(&code) {
224 Some(sender) => {
225 if let Err(e) = sender.send(evt).await {
226 error!("hci event channel closed {:?}", e);
227 }
228 },
229 None if code == EventCode::NumberOfCompletedPackets =>{},
230 None => panic!("Unhandled event {:?}", code),
231 }
232 },
233 }
234 },
235 Some(queued) = cmd_rx.recv(), if pending.is_none() => {
236 if let Err(e) = cmd_tx.send(queued.cmd.clone()).await {
237 error!("command queue closed: {:?}", e);
238 }
239 hci_timeout.reset(Duration::from_secs(2));
240 pending = Some(queued);
241 },
242 _ = hci_timeout.expired() => panic!("Timed out waiting for {:?}", pending.unwrap().cmd.get_op_code()),
243 else => break,
244 }
245 }
246 }
247
consume(evt_rx: &Arc<Mutex<Receiver<EventPacket>>>) -> Option<EventPacket>248 async fn consume(evt_rx: &Arc<Mutex<Receiver<EventPacket>>>) -> Option<EventPacket> {
249 evt_rx.lock().await.recv().await
250 }
251