trouble_host/
host.rs

1//! BleHost
2//!
3//! The host module contains the main entry point for the TrouBLE host.
4use 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
53/// A BLE Host.
54///
55/// The BleHost holds the runtime state of the host, and is the entry point
56/// for all interactions with the controller.
57///
58/// The host performs connection management, l2cap channel management, and
59/// multiplexes events and data across connections and l2cap channels.
60pub(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    // Terminate handle
116    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/// Host metrics
174#[derive(Default, Clone)]
175pub struct HostMetrics {
176    /// How many connect events have been received.
177    pub connect_events: u32,
178    /// How many disconnect events have been received.
179    pub disconnect_events: u32,
180    /// How many errors processing received data.
181    pub rx_errors: u32,
182}
183
184impl<'d, T, P> BleHost<'d, T, P>
185where
186    T: Controller,
187    P: PacketPool,
188{
189    /// Create a new instance of the BLE host.
190    ///
191    /// The host requires a HCI driver (a particular HCI-compatible controller implementing the required traits), and
192    /// a reference to resources that are created outside the host but which the host is the only accessor of.
193    #[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    /// Run a HCI command and return the response.
217    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    /// Run an async HCI command where the response will generate an event later.
228    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                // Ignore channels we don't support
292                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                // Avoids using the packet buffer for signalling packets
301                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                // We must be prepared to receive fragments.
308                if header.length as usize != data.len() {
309                    // Dynamic channels can be optimized.
310                    #[cfg(feature = "l2cap-sdu-reassembly-optimization")]
311                    if header.channel >= L2CAP_CID_DYN_START {
312                        // This is the start of the frame, so make sure to adjust the credits.
313                        self.channels.received(header.channel, 1)?;
314
315                        self.connections.reassembly(acl.handle(), |p| {
316                            let r = if !p.in_progress() {
317                                // Init the new assembly assuming the length of the SDU.
318                                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                            // Something is wrong if assembly was finished since we've not received the last fragment.
330                            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                        // This is a complete L2CAP K-frame, so make sure to adjust the credits.
360                        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            // Next (potentially last) in a fragment
402            AclPacketBoundary::Continuing => {
403                // Get the existing fragment
404                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                    // Do not process yet
419                    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                // Handle ATT MTU exchange here since it doesn't strictly require
431                // gatt to be enabled.
432                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    // Send l2cap signal payload
498    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        //trace!(
506        //    "[l2cap] sending control signal (req = {}) signal: {:?}",
507        //    identifier,
508        //    signal
509        //);
510        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    // Request to an L2CAP payload of len to the HCI controller for a connection.
532    //
533    // This function will request the appropriate number of ACL packets to be sent and
534    // the returned sender will handle fragmentation.
535    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        // Take into account l2cap header.
542        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    // Request to an L2CAP payload of len to the HCI controller for a connection.
555    //
556    // This function will request the appropriate number of ACL packets to be sent and
557    // the returned sender will handle fragmentation.
558    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    /// Read current host metrics
582    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    /// Log status information of the host
588    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
598/// Runs the host with the given controller.
599pub 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
605/// The receiver part of the host runner.
606pub struct RxRunner<'d, C, P: PacketPool> {
607    stack: &'d Stack<'d, C, P>,
608}
609
610/// The control part of the host runner.
611pub struct ControlRunner<'d, C, P: PacketPool> {
612    stack: &'d Stack<'d, C, P>,
613}
614
615/// The transmit part of the host runner.
616pub struct TxRunner<'d, C, P: PacketPool> {
617    stack: &'d Stack<'d, C, P>,
618}
619
620/// Event handler.
621pub trait EventHandler {
622    /// Handle vendor events
623    fn on_vendor(&self, vendor: &Vendor) {}
624    /// Handle advertising reports
625    #[cfg(feature = "scan")]
626    fn on_adv_reports(&self, reports: bt_hci::param::LeAdvReportsIter) {}
627    /// Handle extended advertising reports
628    #[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    /// Split the runner into separate independent async tasks
645    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    /// Run the host.
650    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    /// Run the host with a vendor event handler for custom events.
678    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    /// Run the receive loop that polls the controller for events.
724    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    /// Runs the receive loop that pools the controller for events, dispatching
733    /// vendor events to the provided closure.
734    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        // use embassy_time::Instant;
741        // let mut last = Instant::now();
742        loop {
743            // Task handling receiving data from the controller.
744            let mut rx = [0u8; MAX_HCI_PACKET_LEN];
745            // let now = Instant::now();
746            // let elapsed = (now - last).as_millis();
747            // if elapsed >= 1 {
748            //     trace!("[host] time since last poll was {} us", elapsed);
749            // }
750            let result = host.controller.read(&mut rx).await;
751            // last = Instant::now();
752            //        trace!("[host] polling took {} ms", (polled - started).as_millis());
753            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                            // Explicitly ignoring for now
883                            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                        // Ignore
902                        _ => {}
903                    }
904                }
905                // Ignore
906                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    /// Run the control loop for the host
917    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        /*
1004                #[cfg(feature = "controller-host-flow-control")]
1005                {
1006                    info!("[host] enabling flow control");
1007                    SetControllerToHostFlowControl::new(ControllerToHostFlowControl::AclOnSyncOff)
1008                        .exec(&host.controller)
1009                        .await?;
1010                }
1011        */
1012
1013        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                        // trace!("[host] cancelling create connection");
1078                        if host.command(LeCreateConnCancel::new()).await.is_err() {
1079                            warn!("[host] error cancelling connection");
1080                        }
1081                        // Signal to ensure no one is stuck
1082                        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                            // TODO: A bit opinionated but not more than before
1097                            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    /// Run the transmit loop for the host.
1127    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        //info!(
1168        //    "[host] fragmenting PDU of size {} into {} sized fragments",
1169        //    pdu.len(),
1170        //    self.fragment_size
1171        //);
1172        for chunk in pdu.chunks(self.fragment_size as usize) {
1173            let acl = AclPacket::new(self.handle, pbf, AclBroadcastFlag::PointToPoint, chunk);
1174            // info!("Sent ACL {:?}", acl);
1175            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        //info!(
1192        //    "[host] fragmenting PDU of size {} into {} sized fragments",
1193        //    pdu.len(),
1194        //    self.fragment_size
1195        //);
1196        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            // info!("Sent ACL {:?}", acl);
1200            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/// A type to delay the drop handler invocation.
1212#[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    /// Create a new instance.
1219    pub fn new(f: F) -> Self {
1220        Self { f: MaybeUninit::new(f) }
1221    }
1222
1223    /// Prevent drop handler from running.
1224    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}