1use core::cell::RefCell;
5use core::future::poll_fn;
6use core::mem::MaybeUninit;
7use core::task::Poll;
8
9use bt_hci::cmd::controller_baseband::{
10 HostBufferSize, HostNumberOfCompletedPackets, Reset, SetControllerToHostFlowControl, SetEventMask,
11 SetEventMaskPage2,
12};
13use bt_hci::cmd::info::ReadBdAddr;
14use bt_hci::cmd::le::{
15 LeConnUpdate, LeCreateConnCancel, LeEnableEncryption, LeLongTermKeyRequestReply, LeReadBufferSize,
16 LeReadFilterAcceptListSize, LeSetAdvEnable, LeSetEventMask, LeSetExtAdvEnable, LeSetExtScanEnable, LeSetRandomAddr,
17 LeSetScanEnable,
18};
19use bt_hci::cmd::link_control::Disconnect;
20use bt_hci::cmd::{AsyncCmd, SyncCmd};
21use bt_hci::controller::{blocking, Controller, ControllerCmdAsync, ControllerCmdSync};
22use bt_hci::data::{AclBroadcastFlag, AclPacket, AclPacketBoundary};
23use bt_hci::event::le::LeEvent;
24use bt_hci::event::{Event, Vendor};
25use bt_hci::param::{
26 AddrKind, AdvHandle, AdvSet, BdAddr, ConnHandle, DisconnectReason, EventMask, EventMaskPage2, FilterDuplicates,
27 LeConnRole, LeEventMask, Status,
28};
29use bt_hci::{ControllerToHostPacket, FromHciBytes, WriteHci};
30use embassy_futures::select::{select3, select4, Either3, Either4};
31use embassy_sync::once_lock::OnceLock;
32use embassy_sync::waitqueue::WakerRegistration;
33#[cfg(feature = "gatt")]
34use embassy_sync::{blocking_mutex::raw::NoopRawMutex, channel::Channel};
35use embassy_time::Duration;
36use futures::pin_mut;
37
38use crate::att::{AttClient, AttServer};
39use crate::channel_manager::{ChannelManager, ChannelStorage};
40use crate::command::CommandState;
41use crate::connection::ConnectionEvent;
42use crate::connection_manager::{ConnectionManager, ConnectionStorage, PacketGrant};
43use crate::cursor::WriteCursor;
44use crate::pdu::Pdu;
45#[cfg(feature = "security")]
46use crate::security_manager::SecurityEventData;
47use crate::types::l2cap::{
48 L2capHeader, L2capSignal, L2capSignalHeader, L2CAP_CID_ATT, L2CAP_CID_DYN_START, L2CAP_CID_LE_U_SECURITY_MANAGER,
49 L2CAP_CID_LE_U_SIGNAL,
50};
51use crate::{att, Address, BleHostError, Error, PacketPool, Stack};
52
53pub(crate) struct BleHost<'d, T, P: PacketPool> {
61 initialized: OnceLock<InitialState>,
62 metrics: RefCell<HostMetrics>,
63 pub(crate) address: Option<Address>,
64 pub(crate) controller: T,
65 pub(crate) connections: ConnectionManager<'d, P>,
66 pub(crate) channels: ChannelManager<'d, P>,
67 #[cfg(feature = "gatt")]
68 pub(crate) att_client: Channel<NoopRawMutex, (ConnHandle, Pdu<P::Packet>), { crate::config::L2CAP_RX_QUEUE_SIZE }>,
69 pub(crate) advertise_state: AdvState<'d>,
70 pub(crate) advertise_command_state: CommandState<bool>,
71 pub(crate) connect_command_state: CommandState<bool>,
72 pub(crate) scan_command_state: CommandState<bool>,
73}
74
75#[derive(Clone, Copy)]
76pub(crate) struct InitialState {
77 acl_max: usize,
78}
79
80#[cfg_attr(feature = "defmt", derive(defmt::Format))]
81#[derive(Clone, Copy, Debug)]
82pub(crate) enum AdvHandleState {
83 None,
84 Advertising(AdvHandle),
85 Terminated(AdvHandle),
86}
87
88pub(crate) struct AdvInnerState<'d> {
89 handles: &'d mut [AdvHandleState],
90 waker: WakerRegistration,
91}
92
93pub(crate) struct AdvState<'d> {
94 state: RefCell<AdvInnerState<'d>>,
95}
96
97impl<'d> AdvState<'d> {
98 pub(crate) fn new(handles: &'d mut [AdvHandleState]) -> Self {
99 Self {
100 state: RefCell::new(AdvInnerState {
101 handles,
102 waker: WakerRegistration::new(),
103 }),
104 }
105 }
106
107 pub(crate) fn reset(&self) {
108 let mut state = self.state.borrow_mut();
109 for entry in state.handles.iter_mut() {
110 *entry = AdvHandleState::None;
111 }
112 state.waker.wake();
113 }
114
115 pub(crate) fn terminate(&self, handle: AdvHandle) {
117 let mut state = self.state.borrow_mut();
118 for entry in state.handles.iter_mut() {
119 match entry {
120 AdvHandleState::Advertising(h) if *h == handle => {
121 *entry = AdvHandleState::Terminated(handle);
122 }
123 _ => {}
124 }
125 }
126 state.waker.wake();
127 }
128
129 pub(crate) fn len(&self) -> usize {
130 let state = self.state.borrow();
131 state.handles.len()
132 }
133
134 pub(crate) fn start(&self, sets: &[AdvSet]) {
135 let mut state = self.state.borrow_mut();
136 assert!(sets.len() <= state.handles.len());
137 for handle in state.handles.iter_mut() {
138 *handle = AdvHandleState::None;
139 }
140
141 for (idx, entry) in sets.iter().enumerate() {
142 state.handles[idx] = AdvHandleState::Advertising(entry.adv_handle);
143 }
144 }
145
146 pub async fn wait(&self) {
147 poll_fn(|cx| {
148 let mut state = self.state.borrow_mut();
149 state.waker.register(cx.waker());
150
151 let mut terminated = 0;
152 for entry in state.handles.iter() {
153 match entry {
154 AdvHandleState::Terminated(_) => {
155 terminated += 1;
156 }
157 AdvHandleState::None => {
158 terminated += 1;
159 }
160 _ => {}
161 }
162 }
163 if terminated == state.handles.len() {
164 Poll::Ready(())
165 } else {
166 Poll::Pending
167 }
168 })
169 .await;
170 }
171}
172
173#[derive(Default, Clone)]
175pub struct HostMetrics {
176 pub connect_events: u32,
178 pub disconnect_events: u32,
180 pub rx_errors: u32,
182}
183
184impl<'d, T, P> BleHost<'d, T, P>
185where
186 T: Controller,
187 P: PacketPool,
188{
189 #[allow(clippy::too_many_arguments)]
194 pub(crate) fn new(
195 controller: T,
196 connections: &'d mut [ConnectionStorage<P::Packet>],
197 channels: &'d mut [ChannelStorage<P::Packet>],
198 advertise_handles: &'d mut [AdvHandleState],
199 ) -> Self {
200 Self {
201 address: None,
202 initialized: OnceLock::new(),
203 metrics: RefCell::new(HostMetrics::default()),
204 controller,
205 connections: ConnectionManager::new(connections, P::MTU as u16 - 4),
206 channels: ChannelManager::new(channels),
207 #[cfg(feature = "gatt")]
208 att_client: Channel::new(),
209 advertise_state: AdvState::new(advertise_handles),
210 advertise_command_state: CommandState::new(),
211 scan_command_state: CommandState::new(),
212 connect_command_state: CommandState::new(),
213 }
214 }
215
216 pub(crate) async fn command<C>(&self, cmd: C) -> Result<C::Return, BleHostError<T::Error>>
218 where
219 C: SyncCmd,
220 T: ControllerCmdSync<C>,
221 {
222 let _ = self.initialized.get().await;
223 let ret = cmd.exec(&self.controller).await?;
224 Ok(ret)
225 }
226
227 pub(crate) async fn async_command<C>(&self, cmd: C) -> Result<(), BleHostError<T::Error>>
229 where
230 C: AsyncCmd,
231 T: ControllerCmdAsync<C>,
232 {
233 let _ = self.initialized.get().await;
234 cmd.exec(&self.controller).await?;
235 Ok(())
236 }
237
238 fn handle_connection(
239 &self,
240 status: Status,
241 handle: ConnHandle,
242 peer_addr_kind: AddrKind,
243 peer_addr: BdAddr,
244 role: LeConnRole,
245 ) -> bool {
246 match status.to_result() {
247 Ok(_) => {
248 if let Err(err) = self.connections.connect(handle, peer_addr_kind, peer_addr, role) {
249 warn!("Error establishing connection: {:?}", err);
250 return false;
251 } else {
252 #[cfg(feature = "defmt")]
253 trace!(
254 "[host] connection with handle {:?} established to {:02x}",
255 handle,
256 peer_addr
257 );
258
259 #[cfg(feature = "log")]
260 trace!(
261 "[host] connection with handle {:?} established to {:02x?}",
262 handle,
263 peer_addr
264 );
265 let mut m = self.metrics.borrow_mut();
266 m.connect_events = m.connect_events.wrapping_add(1);
267 }
268 }
269 Err(bt_hci::param::Error::ADV_TIMEOUT) => {
270 self.advertise_state.reset();
271 }
272 Err(bt_hci::param::Error::UNKNOWN_CONN_IDENTIFIER) => {
273 warn!("[host] connect cancelled");
274 self.connect_command_state.canceled();
275 }
276 Err(e) => {
277 warn!("Error connection complete event: {:?}", e);
278 self.connect_command_state.canceled();
279 }
280 }
281 true
282 }
283
284 fn handle_acl(&self, acl: AclPacket<'_>) -> Result<(), Error> {
285 self.connections.received(acl.handle())?;
286 let handle = acl.handle();
287 let (header, pdu) = match acl.boundary_flag() {
288 AclPacketBoundary::FirstFlushable => {
289 let (header, data) = L2capHeader::from_hci_bytes(acl.data())?;
290
291 if header.channel < L2CAP_CID_DYN_START
293 && !(&[L2CAP_CID_LE_U_SIGNAL, L2CAP_CID_ATT, L2CAP_CID_LE_U_SECURITY_MANAGER]
294 .contains(&header.channel))
295 {
296 warn!("[host] unsupported l2cap channel id {}", header.channel);
297 return Err(Error::NotSupported);
298 }
299
300 if header.channel == L2CAP_CID_LE_U_SIGNAL {
302 assert!(data.len() == header.length as usize);
303 self.channels.signal(acl.handle(), data)?;
304 return Ok(());
305 }
306
307 if header.length as usize != data.len() {
309 #[cfg(feature = "l2cap-sdu-reassembly-optimization")]
311 if header.channel >= L2CAP_CID_DYN_START {
312 self.channels.received(header.channel, 1)?;
314
315 self.connections.reassembly(acl.handle(), |p| {
316 let r = if !p.in_progress() {
317 let (first, payload) = data.split_at(2);
319 let len: u16 = u16::from_le_bytes([first[0], first[1]]);
320 let Some(packet) = P::allocate() else {
321 warn!("[host] no memory for packets on channel {}", header.channel);
322 return Err(Error::OutOfMemory);
323 };
324 p.init(header.channel, len, packet)?;
325 p.update(payload)?
326 } else {
327 p.update(data)?
328 };
329 if r.is_some() {
331 Err(Error::InvalidState)
332 } else {
333 Ok(())
334 }
335 })?;
336 return Ok(());
337 }
338
339 let Some(packet) = P::allocate() else {
340 warn!("[host] no memory for packets on channel {}", header.channel);
341 return Err(Error::OutOfMemory);
342 };
343 self.connections.reassembly(acl.handle(), |p| {
344 p.init(header.channel, header.length, packet)?;
345 let r = p.update(data)?;
346 if r.is_some() {
347 Err(Error::InvalidState)
348 } else {
349 Ok(())
350 }
351 })?;
352 return Ok(());
353 } else {
354 #[allow(unused_mut)]
355 let mut result = None;
356
357 #[cfg(feature = "l2cap-sdu-reassembly-optimization")]
358 if header.channel >= L2CAP_CID_DYN_START {
359 self.channels.received(header.channel, 1)?;
361
362 if let Some((state, pdu)) = self.connections.reassembly(acl.handle(), |p| {
363 if !p.in_progress() {
364 let (first, payload) = data.split_at(2);
365 let len: u16 = u16::from_le_bytes([first[0], first[1]]);
366
367 let Some(packet) = P::allocate() else {
368 warn!("[host] no memory for packets on channel {}", header.channel);
369 return Err(Error::OutOfMemory);
370 };
371 p.init(header.channel, len, packet)?;
372 p.update(payload)
373 } else {
374 p.update(data)
375 }
376 })? {
377 result.replace((state, pdu));
378 } else {
379 return Ok(());
380 }
381 }
382
383 if let Some((state, pdu)) = result {
384 (state, pdu)
385 } else {
386 let Some(packet) = P::allocate() else {
387 warn!("[host] no memory for packets on channel {}", header.channel);
388 return Err(Error::OutOfMemory);
389 };
390 let result = self.connections.reassembly(acl.handle(), |p| {
391 p.init(header.channel, header.length, packet)?;
392 p.update(data)
393 })?;
394 let Some((state, pdu)) = result else {
395 return Err(Error::InvalidState);
396 };
397 (state, pdu)
398 }
399 }
400 }
401 AclPacketBoundary::Continuing => {
403 if let Some((header, p)) = self.connections.reassembly(acl.handle(), |p| {
405 if !p.in_progress() {
406 warn!(
407 "[host] unexpected continuation fragment of length {} for handle {}: {:?}",
408 acl.data().len(),
409 acl.handle().raw(),
410 p
411 );
412 return Err(Error::InvalidState);
413 }
414 p.update(acl.data())
415 })? {
416 (header, p)
417 } else {
418 return Ok(());
420 }
421 }
422 other => {
423 warn!("Unexpected boundary flag: {:?}!", other);
424 return Err(Error::NotSupported);
425 }
426 };
427
428 match header.channel {
429 L2CAP_CID_ATT => {
430 let a = att::Att::decode(pdu.as_ref());
433 if let Ok(att::Att::Client(AttClient::Request(att::AttReq::ExchangeMtu { mtu }))) = a {
434 let mtu = self.connections.exchange_att_mtu(acl.handle(), mtu);
435
436 let rsp = att::Att::Server(AttServer::Response(att::AttRsp::ExchangeMtu { mtu }));
437 let l2cap = L2capHeader {
438 channel: L2CAP_CID_ATT,
439 length: 3,
440 };
441
442 let mut packet = pdu.into_inner();
443 let mut w = WriteCursor::new(packet.as_mut());
444 w.write_hci(&l2cap)?;
445 w.write(rsp)?;
446
447 info!("[host] agreed att MTU of {}", mtu);
448 let len = w.len();
449 self.connections.try_outbound(acl.handle(), Pdu::new(packet, len))?;
450 } else if let Ok(att::Att::Server(AttServer::Response(att::AttRsp::ExchangeMtu { mtu }))) = a {
451 info!("[host] remote agreed att MTU of {}", mtu);
452 self.connections.exchange_att_mtu(acl.handle(), mtu);
453 } else {
454 #[cfg(feature = "gatt")]
455 match a {
456 Ok(att::Att::Client(_)) => {
457 self.connections.post_gatt(acl.handle(), pdu)?;
458 }
459 Ok(att::Att::Server(_)) => {
460 if let Err(e) = self.att_client.try_send((acl.handle(), pdu)) {
461 return Err(Error::OutOfMemory);
462 }
463 }
464 Err(e) => {
465 warn!("Error decoding attribute payload: {:?}", e);
466 }
467 }
468 #[cfg(not(feature = "gatt"))]
469 return Err(Error::NotSupported);
470 }
471 }
472 L2CAP_CID_LE_U_SIGNAL => {
473 panic!("le signalling channel was fragmented, impossible!");
474 }
475 L2CAP_CID_LE_U_SECURITY_MANAGER => {
476 self.connections.handle_security_channel(acl.handle(), pdu)?;
477 }
478 other if other >= L2CAP_CID_DYN_START => match self.channels.dispatch(header.channel, pdu) {
479 Ok(_) => {}
480 Err(e) => {
481 warn!("Error dispatching l2cap packet to channel: {:?}", e);
482 return Err(e);
483 }
484 },
485 chan => {
486 debug!(
487 "[host] conn {:?} attempted to use unsupported l2cap channel {}, ignoring",
488 acl.handle(),
489 chan
490 );
491 return Ok(());
492 }
493 }
494 Ok(())
495 }
496
497 pub(crate) async fn l2cap_signal<D: L2capSignal>(
499 &self,
500 conn: ConnHandle,
501 identifier: u8,
502 signal: &D,
503 p_buf: &mut [u8],
504 ) -> Result<(), BleHostError<T::Error>> {
505 let header = L2capSignalHeader {
511 identifier,
512 code: D::code(),
513 length: signal.size() as u16,
514 };
515 let l2cap = L2capHeader {
516 channel: D::channel(),
517 length: header.size() as u16 + header.length,
518 };
519
520 let mut w = WriteCursor::new(p_buf);
521 w.write_hci(&l2cap)?;
522 w.write_hci(&header)?;
523 w.write_hci(signal)?;
524
525 let mut sender = self.l2cap(conn, w.len() as u16, 1).await?;
526 sender.send(w.finish()).await?;
527
528 Ok(())
529 }
530
531 pub(crate) async fn l2cap(
536 &self,
537 handle: ConnHandle,
538 len: u16,
539 n_packets: u16,
540 ) -> Result<L2capSender<'_, 'd, T, P::Packet>, BleHostError<T::Error>> {
541 let acl_max = self.initialized.get().await.acl_max as u16;
543 let len = len + (4 * n_packets);
544 let n_acl = len.div_ceil(acl_max);
545 let grant = poll_fn(|cx| self.connections.poll_request_to_send(handle, n_acl as usize, Some(cx))).await?;
546 Ok(L2capSender {
547 controller: &self.controller,
548 handle,
549 grant,
550 fragment_size: acl_max,
551 })
552 }
553
554 pub(crate) fn try_l2cap(
559 &self,
560 handle: ConnHandle,
561 len: u16,
562 n_packets: u16,
563 ) -> Result<L2capSender<'_, 'd, T, P::Packet>, BleHostError<T::Error>> {
564 let acl_max = self.initialized.try_get().map(|i| i.acl_max).unwrap_or(27) as u16;
565 let len = len + (4 * n_packets);
566 let n_acl = len.div_ceil(acl_max);
567 let grant = match self.connections.poll_request_to_send(handle, n_acl as usize, None) {
568 Poll::Ready(res) => res?,
569 Poll::Pending => {
570 return Err(Error::Busy.into());
571 }
572 };
573 Ok(L2capSender {
574 controller: &self.controller,
575 handle,
576 grant,
577 fragment_size: acl_max,
578 })
579 }
580
581 pub(crate) fn metrics<F: FnOnce(&HostMetrics) -> R, R>(&self, f: F) -> R {
583 let m = self.metrics.borrow();
584 f(&m)
585 }
586
587 pub(crate) fn log_status(&self, verbose: bool) {
589 let m = self.metrics.borrow();
590 debug!("[host] connect events: {}", m.connect_events);
591 debug!("[host] disconnect events: {}", m.disconnect_events);
592 debug!("[host] rx errors: {}", m.rx_errors);
593 self.connections.log_status(verbose);
594 self.channels.log_status(verbose);
595 }
596}
597
598pub struct Runner<'d, C, P: PacketPool> {
600 rx: RxRunner<'d, C, P>,
601 control: ControlRunner<'d, C, P>,
602 tx: TxRunner<'d, C, P>,
603}
604
605pub struct RxRunner<'d, C, P: PacketPool> {
607 stack: &'d Stack<'d, C, P>,
608}
609
610pub struct ControlRunner<'d, C, P: PacketPool> {
612 stack: &'d Stack<'d, C, P>,
613}
614
615pub struct TxRunner<'d, C, P: PacketPool> {
617 stack: &'d Stack<'d, C, P>,
618}
619
620pub trait EventHandler {
622 fn on_vendor(&self, vendor: &Vendor) {}
624 #[cfg(feature = "scan")]
626 fn on_adv_reports(&self, reports: bt_hci::param::LeAdvReportsIter) {}
627 #[cfg(feature = "scan")]
629 fn on_ext_adv_reports(&self, reports: bt_hci::param::LeExtAdvReportsIter) {}
630}
631
632struct DummyHandler;
633impl EventHandler for DummyHandler {}
634
635impl<'d, C: Controller, P: PacketPool> Runner<'d, C, P> {
636 pub(crate) fn new(stack: &'d Stack<'d, C, P>) -> Self {
637 Self {
638 rx: RxRunner { stack },
639 control: ControlRunner { stack },
640 tx: TxRunner { stack },
641 }
642 }
643
644 pub fn split(self) -> (RxRunner<'d, C, P>, ControlRunner<'d, C, P>, TxRunner<'d, C, P>) {
646 (self.rx, self.control, self.tx)
647 }
648
649 pub async fn run(&mut self) -> Result<(), BleHostError<C::Error>>
651 where
652 C: ControllerCmdSync<Disconnect>
653 + ControllerCmdSync<SetEventMask>
654 + ControllerCmdSync<SetEventMaskPage2>
655 + ControllerCmdSync<LeSetEventMask>
656 + ControllerCmdSync<LeSetRandomAddr>
657 + ControllerCmdSync<HostBufferSize>
658 + ControllerCmdAsync<LeConnUpdate>
659 + ControllerCmdSync<LeReadFilterAcceptListSize>
660 + ControllerCmdSync<SetControllerToHostFlowControl>
661 + ControllerCmdSync<Reset>
662 + ControllerCmdSync<LeCreateConnCancel>
663 + ControllerCmdSync<LeSetScanEnable>
664 + ControllerCmdSync<LeSetExtScanEnable>
665 + for<'t> ControllerCmdSync<LeSetAdvEnable>
666 + for<'t> ControllerCmdSync<LeSetExtAdvEnable<'t>>
667 + for<'t> ControllerCmdSync<HostNumberOfCompletedPackets<'t>>
668 + ControllerCmdSync<LeReadBufferSize>
669 + ControllerCmdSync<LeLongTermKeyRequestReply>
670 + ControllerCmdAsync<LeEnableEncryption>
671 + ControllerCmdSync<ReadBdAddr>,
672 {
673 let dummy = DummyHandler;
674 self.run_with_handler(&dummy).await
675 }
676
677 pub async fn run_with_handler<E: EventHandler>(&mut self, event_handler: &E) -> Result<(), BleHostError<C::Error>>
679 where
680 C: ControllerCmdSync<Disconnect>
681 + ControllerCmdSync<SetEventMask>
682 + ControllerCmdSync<SetEventMaskPage2>
683 + ControllerCmdSync<LeSetEventMask>
684 + ControllerCmdSync<LeSetRandomAddr>
685 + ControllerCmdSync<LeReadFilterAcceptListSize>
686 + ControllerCmdSync<HostBufferSize>
687 + ControllerCmdAsync<LeConnUpdate>
688 + ControllerCmdSync<SetControllerToHostFlowControl>
689 + for<'t> ControllerCmdSync<LeSetAdvEnable>
690 + for<'t> ControllerCmdSync<LeSetExtAdvEnable<'t>>
691 + for<'t> ControllerCmdSync<HostNumberOfCompletedPackets<'t>>
692 + ControllerCmdSync<LeSetScanEnable>
693 + ControllerCmdSync<LeSetExtScanEnable>
694 + ControllerCmdSync<Reset>
695 + ControllerCmdSync<LeCreateConnCancel>
696 + ControllerCmdSync<LeReadBufferSize>
697 + ControllerCmdSync<LeLongTermKeyRequestReply>
698 + ControllerCmdAsync<LeEnableEncryption>
699 + ControllerCmdSync<ReadBdAddr>,
700 {
701 let control_fut = self.control.run();
702 let rx_fut = self.rx.run_with_handler(event_handler);
703 let tx_fut = self.tx.run();
704 pin_mut!(control_fut, rx_fut, tx_fut);
705 match select3(&mut tx_fut, &mut rx_fut, &mut control_fut).await {
706 Either3::First(result) => {
707 trace!("[host] tx_fut exit");
708 result
709 }
710 Either3::Second(result) => {
711 trace!("[host] rx_fut exit");
712 result
713 }
714 Either3::Third(result) => {
715 trace!("[host] control_fut exit");
716 result
717 }
718 }
719 }
720}
721
722impl<'d, C: Controller, P: PacketPool> RxRunner<'d, C, P> {
723 pub async fn run(&mut self) -> Result<(), BleHostError<C::Error>>
725 where
726 C: ControllerCmdSync<Disconnect>,
727 {
728 let dummy = DummyHandler;
729 self.run_with_handler(&dummy).await
730 }
731
732 pub async fn run_with_handler<E: EventHandler>(&mut self, event_handler: &E) -> Result<(), BleHostError<C::Error>>
735 where
736 C: ControllerCmdSync<Disconnect>,
737 {
738 const MAX_HCI_PACKET_LEN: usize = 259;
739 let host = &self.stack.host;
740 loop {
743 let mut rx = [0u8; MAX_HCI_PACKET_LEN];
745 let result = host.controller.read(&mut rx).await;
751 match result {
754 Ok(ControllerToHostPacket::Acl(acl)) => match host.handle_acl(acl) {
755 Ok(_) => {}
756 Err(e) => {
757 warn!(
758 "[host] encountered error processing ACL data for {:?}: {:?}",
759 acl.handle(),
760 e
761 );
762
763 match e {
764 Error::InvalidState | Error::Disconnected => {
765 warn!("[host] requesting {:?} to be disconnected", acl.handle());
766 host.connections.log_status(true);
767 host.connections.request_handle_disconnect(
768 acl.handle(),
769 DisconnectReason::RemoteUserTerminatedConn,
770 );
771 }
772 _ => {}
773 }
774
775 let mut m = host.metrics.borrow_mut();
776 m.rx_errors = m.rx_errors.wrapping_add(1);
777 }
778 },
779 Ok(ControllerToHostPacket::Event(event)) => {
780 match event {
781 Event::Le(ref le_event) => match le_event {
782 LeEvent::LeConnectionComplete(e) => {
783 if !host.handle_connection(e.status, e.handle, e.peer_addr_kind, e.peer_addr, e.role) {
784 let _ = host
785 .command(Disconnect::new(
786 e.handle,
787 DisconnectReason::RemoteDeviceTerminatedConnLowResources,
788 ))
789 .await;
790 host.connect_command_state.canceled();
791 }
792 }
793 LeEvent::LeEnhancedConnectionComplete(e) => {
794 if !host.handle_connection(e.status, e.handle, e.peer_addr_kind, e.peer_addr, e.role) {
795 let _ = host
796 .command(Disconnect::new(
797 e.handle,
798 DisconnectReason::RemoteDeviceTerminatedConnLowResources,
799 ))
800 .await;
801 host.connect_command_state.canceled();
802 }
803 }
804 LeEvent::LeScanTimeout(_) => {}
805 LeEvent::LeAdvertisingSetTerminated(set) => {
806 host.advertise_state.terminate(set.adv_handle);
807 }
808 LeEvent::LeExtendedAdvertisingReport(data) => {
809 #[cfg(feature = "scan")]
810 {
811 event_handler.on_ext_adv_reports(data.reports.iter());
812 }
813 }
814 LeEvent::LeAdvertisingReport(data) => {
815 #[cfg(feature = "scan")]
816 {
817 event_handler.on_adv_reports(data.reports.iter());
818 }
819 }
820 LeEvent::LeLongTermKeyRequest(_) => {
821 host.connections.handle_security_hci_event(event)?;
822 }
823 LeEvent::LePhyUpdateComplete(event) => {
824 if let Err(e) = event.status.to_result() {
825 warn!("[host] error updating phy for {:?}: {:?}", event.handle, e);
826 } else {
827 let _ = host.connections.post_handle_event(
828 event.handle,
829 ConnectionEvent::PhyUpdated {
830 tx_phy: event.tx_phy,
831 rx_phy: event.rx_phy,
832 },
833 );
834 }
835 }
836 LeEvent::LeConnectionUpdateComplete(event) => {
837 if let Err(e) = event.status.to_result() {
838 warn!(
839 "[host] error updating connection parameters for {:?}: {:?}",
840 event.handle, e
841 );
842 } else {
843 let _ = host.connections.post_handle_event(
844 event.handle,
845 ConnectionEvent::ConnectionParamsUpdated {
846 conn_interval: Duration::from_micros(event.conn_interval.as_micros()),
847 peripheral_latency: event.peripheral_latency,
848 supervision_timeout: Duration::from_micros(
849 event.supervision_timeout.as_micros(),
850 ),
851 },
852 );
853 }
854 }
855 _ => {
856 warn!("Unknown LE event!");
857 }
858 },
859 Event::DisconnectionComplete(e) => {
860 let handle = e.handle;
861 let reason = if let Err(e) = e.status.to_result() {
862 info!("[host] disconnection event on handle {}, status: {:?}", handle.raw(), e);
863 None
864 } else if let Err(err) = e.reason.to_result() {
865 info!(
866 "[host] disconnection event on handle {}, reason: {:?}",
867 handle.raw(),
868 err
869 );
870 Some(e.reason)
871 } else {
872 info!("[host] disconnection event on handle {}", handle.raw());
873 None
874 }
875 .unwrap_or(Status::UNSPECIFIED);
876 let _ = host.connections.disconnected(handle, reason);
877 let _ = host.channels.disconnected(handle);
878 let mut m = host.metrics.borrow_mut();
879 m.disconnect_events = m.disconnect_events.wrapping_add(1);
880 }
881 Event::NumberOfCompletedPackets(c) => {
882 for entry in c.completed_packets.iter() {
884 match (entry.handle(), entry.num_completed_packets()) {
885 (Ok(handle), Ok(completed)) => {
886 let _ = host.connections.confirm_sent(handle, completed as usize);
887 }
888 (Ok(handle), Err(e)) => {
889 warn!("[host] error processing completed packets for {:?}: {:?}", handle, e);
890 }
891 _ => {}
892 }
893 }
894 }
895 Event::Vendor(vendor) => {
896 event_handler.on_vendor(&vendor);
897 }
898 Event::EncryptionChangeV1(_) => {
899 host.connections.handle_security_hci_event(event)?;
900 }
901 _ => {}
903 }
904 }
905 Ok(_) => {}
907 Err(e) => {
908 return Err(BleHostError::Controller(e));
909 }
910 }
911 }
912 }
913}
914
915impl<'d, C: Controller, P: PacketPool> ControlRunner<'d, C, P> {
916 pub async fn run(&mut self) -> Result<(), BleHostError<C::Error>>
918 where
919 C: ControllerCmdSync<Disconnect>
920 + ControllerCmdSync<SetEventMask>
921 + ControllerCmdSync<SetEventMaskPage2>
922 + ControllerCmdSync<LeSetEventMask>
923 + ControllerCmdSync<LeSetRandomAddr>
924 + ControllerCmdSync<HostBufferSize>
925 + ControllerCmdAsync<LeConnUpdate>
926 + ControllerCmdSync<LeReadFilterAcceptListSize>
927 + ControllerCmdSync<SetControllerToHostFlowControl>
928 + ControllerCmdSync<Reset>
929 + ControllerCmdSync<LeCreateConnCancel>
930 + for<'t> ControllerCmdSync<LeSetAdvEnable>
931 + for<'t> ControllerCmdSync<LeSetExtAdvEnable<'t>>
932 + ControllerCmdSync<LeSetScanEnable>
933 + ControllerCmdSync<LeSetExtScanEnable>
934 + for<'t> ControllerCmdSync<HostNumberOfCompletedPackets<'t>>
935 + ControllerCmdSync<LeReadBufferSize>
936 + ControllerCmdSync<LeLongTermKeyRequestReply>
937 + ControllerCmdAsync<LeEnableEncryption>
938 + ControllerCmdSync<ReadBdAddr>,
939 {
940 let host = &self.stack.host;
941 Reset::new().exec(&host.controller).await?;
942
943 if let Some(addr) = host.address {
944 LeSetRandomAddr::new(addr.addr).exec(&host.controller).await?;
945 }
946
947 SetEventMask::new(
948 EventMask::new()
949 .enable_le_meta(true)
950 .enable_conn_request(true)
951 .enable_conn_complete(true)
952 .enable_hardware_error(true)
953 .enable_disconnection_complete(true)
954 .enable_encryption_change_v1(true),
955 )
956 .exec(&host.controller)
957 .await?;
958
959 SetEventMaskPage2::new(EventMaskPage2::new().enable_encryption_change_v2(true))
960 .exec(&host.controller)
961 .await?;
962
963 LeSetEventMask::new(
964 LeEventMask::new()
965 .enable_le_conn_complete(true)
966 .enable_le_enhanced_conn_complete(true)
967 .enable_le_conn_update_complete(true)
968 .enable_le_adv_set_terminated(true)
969 .enable_le_adv_report(true)
970 .enable_le_scan_timeout(true)
971 .enable_le_ext_adv_report(true)
972 .enable_le_long_term_key_request(true)
973 .enable_le_phy_update_complete(true),
974 )
975 .exec(&host.controller)
976 .await?;
977
978 info!(
979 "[host] using packet pool with MTU {} capacity {}",
980 P::MTU,
981 P::capacity(),
982 );
983
984 let ret = LeReadFilterAcceptListSize::new().exec(&host.controller).await?;
985 info!("[host] filter accept list size: {}", ret);
986
987 let ret = LeReadBufferSize::new().exec(&host.controller).await?;
988 info!(
989 "[host] setting txq to {}, fragmenting at {}",
990 ret.total_num_le_acl_data_packets as usize, ret.le_acl_data_packet_length as usize
991 );
992 host.connections
993 .set_link_credits(ret.total_num_le_acl_data_packets as usize);
994
995 const ACL_LEN: u16 = 255;
996 const ACL_N: u16 = 1;
997 info!(
998 "[host] configuring host buffers ({} packets of size {})",
999 ACL_N, ACL_LEN,
1000 );
1001 HostBufferSize::new(ACL_LEN, 0, ACL_N, 0).exec(&host.controller).await?;
1002
1003 let _ = host.initialized.init(InitialState {
1014 acl_max: ret.le_acl_data_packet_length as usize,
1015 });
1016 info!("[host] initialized");
1017
1018 let device_address = host.command(ReadBdAddr::new()).await?;
1019 if *device_address.raw() != [0, 0, 0, 0, 0, 0] {
1020 let device_address = Address {
1021 kind: AddrKind::PUBLIC,
1022 addr: device_address,
1023 };
1024 info!("[host] Device Address {}", device_address);
1025 if host.address.is_none() {
1026 #[cfg(feature = "security")]
1027 host.connections.security_manager.set_local_address(device_address);
1028 }
1029 }
1030
1031 loop {
1032 match select3(
1033 poll_fn(|cx| host.connections.poll_disconnecting(Some(cx))),
1034 poll_fn(|cx| host.channels.poll_disconnecting(Some(cx))),
1035 select4(
1036 poll_fn(|cx| host.connect_command_state.poll_cancelled(cx)),
1037 poll_fn(|cx| host.advertise_command_state.poll_cancelled(cx)),
1038 poll_fn(|cx| host.scan_command_state.poll_cancelled(cx)),
1039 #[cfg(feature = "security")]
1040 {
1041 host.connections.poll_security_events()
1042 },
1043 #[cfg(not(feature = "security"))]
1044 {
1045 poll_fn(|cx| Poll::<()>::Pending)
1046 },
1047 ),
1048 )
1049 .await
1050 {
1051 Either3::First(request) => {
1052 trace!("[host] poll disconnecting links");
1053 match host.command(Disconnect::new(request.handle(), request.reason())).await {
1054 Ok(_) => {}
1055 Err(BleHostError::BleHost(Error::Hci(bt_hci::param::Error::UNKNOWN_CONN_IDENTIFIER))) => {}
1056 Err(e) => {
1057 return Err(e);
1058 }
1059 }
1060 request.confirm();
1061 }
1062 Either3::Second(request) => {
1063 trace!("[host] poll disconnecting channels");
1064 match request.send(host).await {
1065 Ok(_) => {}
1066 Err(BleHostError::BleHost(Error::Hci(bt_hci::param::Error::UNKNOWN_CONN_IDENTIFIER))) => {}
1067 Err(BleHostError::BleHost(Error::NotFound)) => {}
1068 Err(e) => {
1069 return Err(e);
1070 }
1071 }
1072 request.confirm();
1073 }
1074 Either3::Third(states) => match states {
1075 Either4::First(_) => {
1076 trace!("[host] cancel connection create");
1077 if host.command(LeCreateConnCancel::new()).await.is_err() {
1079 warn!("[host] error cancelling connection");
1080 }
1081 host.connect_command_state.canceled();
1083 }
1084 Either4::Second(ext) => {
1085 trace!("[host] disabling advertising");
1086 if ext {
1087 host.command(LeSetExtAdvEnable::new(false, &[])).await?
1088 } else {
1089 host.command(LeSetAdvEnable::new(false)).await?
1090 }
1091 host.advertise_command_state.canceled();
1092 }
1093 Either4::Third(ext) => {
1094 trace!("[host] disabling scanning");
1095 if ext {
1096 host.command(LeSetExtScanEnable::new(
1098 false,
1099 FilterDuplicates::Disabled,
1100 bt_hci::param::Duration::from_secs(0),
1101 bt_hci::param::Duration::from_secs(0),
1102 ))
1103 .await?;
1104 } else {
1105 host.command(LeSetScanEnable::new(false, false)).await?;
1106 }
1107 host.scan_command_state.canceled();
1108 }
1109 Either4::Fourth(request) => {
1110 #[cfg(feature = "security")]
1111 {
1112 let event_data = match request {
1113 Ok(e) => e,
1114 Err(_) => SecurityEventData::Timeout,
1115 };
1116 host.connections.handle_security_event(host, event_data).await?;
1117 }
1118 }
1119 },
1120 }
1121 }
1122 }
1123}
1124
1125impl<'d, C: Controller, P: PacketPool> TxRunner<'d, C, P> {
1126 pub async fn run(&mut self) -> Result<(), BleHostError<C::Error>> {
1128 let host = &self.stack.host;
1129 let params = host.initialized.get().await;
1130 loop {
1131 let (conn, pdu) = host.connections.outbound().await;
1132 match host.l2cap(conn, pdu.len() as u16, 1).await {
1133 Ok(mut sender) => {
1134 if let Err(e) = sender.send(pdu.as_ref()).await {
1135 warn!("[host] error sending outbound pdu");
1136 return Err(e);
1137 }
1138 }
1139 Err(BleHostError::BleHost(Error::NotFound)) => {
1140 warn!("[host] unable to send data to disconnected host (ignored)");
1141 }
1142 Err(BleHostError::BleHost(Error::Disconnected)) => {
1143 warn!("[host] unable to send data to disconnected host (ignored)");
1144 }
1145 Err(e) => {
1146 warn!("[host] error requesting sending outbound pdu");
1147 return Err(e);
1148 }
1149 }
1150 }
1151 }
1152}
1153
1154pub struct L2capSender<'a, 'd, T: Controller, P> {
1155 pub(crate) controller: &'a T,
1156 pub(crate) handle: ConnHandle,
1157 pub(crate) grant: PacketGrant<'a, 'd, P>,
1158 pub(crate) fragment_size: u16,
1159}
1160
1161impl<'a, 'd, T: Controller, P> L2capSender<'a, 'd, T, P> {
1162 pub(crate) fn try_send(&mut self, pdu: &[u8]) -> Result<(), BleHostError<T::Error>>
1163 where
1164 T: blocking::Controller,
1165 {
1166 let mut pbf = AclPacketBoundary::FirstNonFlushable;
1167 for chunk in pdu.chunks(self.fragment_size as usize) {
1173 let acl = AclPacket::new(self.handle, pbf, AclBroadcastFlag::PointToPoint, chunk);
1174 match self.controller.try_write_acl_data(&acl) {
1176 Ok(result) => {
1177 self.grant.confirm(1);
1178 }
1179 Err(blocking::TryError::Busy) => {
1180 warn!("hci: acl data send busy");
1181 return Err(Error::Busy.into());
1182 }
1183 Err(blocking::TryError::Error(e)) => return Err(BleHostError::Controller(e)),
1184 }
1185 pbf = AclPacketBoundary::Continuing;
1186 }
1187 Ok(())
1188 }
1189
1190 pub(crate) async fn send(&mut self, pdu: &[u8]) -> Result<(), BleHostError<T::Error>> {
1191 let mut pbf = AclPacketBoundary::FirstNonFlushable;
1197 for chunk in pdu.chunks(self.fragment_size as usize) {
1198 let acl = AclPacket::new(self.handle, pbf, AclBroadcastFlag::PointToPoint, chunk);
1199 self.controller
1201 .write_acl_data(&acl)
1202 .await
1203 .map_err(BleHostError::Controller)?;
1204 self.grant.confirm(1);
1205 pbf = AclPacketBoundary::Continuing;
1206 }
1207 Ok(())
1208 }
1209}
1210
1211#[must_use = "to delay the drop handler invocation to the end of the scope"]
1213pub struct OnDrop<F: FnOnce()> {
1214 f: MaybeUninit<F>,
1215}
1216
1217impl<F: FnOnce()> OnDrop<F> {
1218 pub fn new(f: F) -> Self {
1220 Self { f: MaybeUninit::new(f) }
1221 }
1222
1223 pub fn defuse(self) {
1225 core::mem::forget(self)
1226 }
1227}
1228
1229impl<F: FnOnce()> Drop for OnDrop<F> {
1230 fn drop(&mut self) {
1231 unsafe { self.f.as_ptr().read()() }
1232 }
1233}