• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! HCI Hardware Abstraction Layer
2 //! Supports sending HCI commands to the HAL and receving
3 //! HCI events from the HAL
4 
5 pub mod facade;
6 pub mod rootcanal_hal;
7 pub mod snoop;
8 
9 #[cfg(target_os = "android")]
10 mod hidl_hal;
11 
12 use gddi::module;
13 use thiserror::Error;
14 
15 #[cfg(target_os = "android")]
16 module! {
17     hal_module,
18     submodules {
19         facade::hal_facade_module,
20         hidl_hal::hidl_hal_module,
21         snoop::snoop_module,
22     },
23 }
24 
25 #[cfg(not(target_os = "android"))]
26 module! {
27     hal_module,
28     submodules {
29         facade::hal_facade_module,
30         rootcanal_hal::rootcanal_hal_module,
31         snoop::snoop_module,
32     },
33 }
34 /// H4 packet header size
35 const H4_HEADER_SIZE: usize = 1;
36 
37 pub use snoop::{AclHal, ControlHal, IsoHal, ScoHal};
38 
39 mod internal {
40     use bt_packets::hci::{AclPacket, CommandPacket, EventPacket, IsoPacket, ScoPacket};
41     use gddi::Stoppable;
42     use std::sync::Arc;
43     use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
44     use tokio::sync::Mutex;
45 
46     #[derive(Clone, Stoppable)]
47     pub struct RawHal {
48         pub cmd_tx: UnboundedSender<CommandPacket>,
49         pub evt_rx: Arc<Mutex<UnboundedReceiver<EventPacket>>>,
50         pub acl_tx: UnboundedSender<AclPacket>,
51         pub acl_rx: Arc<Mutex<UnboundedReceiver<AclPacket>>>,
52         pub iso_tx: UnboundedSender<IsoPacket>,
53         pub iso_rx: Arc<Mutex<UnboundedReceiver<IsoPacket>>>,
54         pub sco_tx: UnboundedSender<ScoPacket>,
55         pub sco_rx: Arc<Mutex<UnboundedReceiver<ScoPacket>>>,
56     }
57 
58     pub struct InnerHal {
59         pub cmd_rx: UnboundedReceiver<CommandPacket>,
60         pub evt_tx: UnboundedSender<EventPacket>,
61         pub acl_rx: UnboundedReceiver<AclPacket>,
62         pub acl_tx: UnboundedSender<AclPacket>,
63         pub sco_rx: UnboundedReceiver<ScoPacket>,
64         pub sco_tx: UnboundedSender<ScoPacket>,
65         pub iso_rx: UnboundedReceiver<IsoPacket>,
66         pub iso_tx: UnboundedSender<IsoPacket>,
67     }
68 
69     impl InnerHal {
new() -> (RawHal, Self)70         pub fn new() -> (RawHal, Self) {
71             let (cmd_tx, cmd_rx) = unbounded_channel();
72             let (evt_tx, evt_rx) = unbounded_channel();
73             let (acl_down_tx, acl_down_rx) = unbounded_channel();
74             let (sco_down_tx, sco_down_rx) = unbounded_channel();
75             let (iso_down_tx, iso_down_rx) = unbounded_channel();
76             let (acl_up_tx, acl_up_rx) = unbounded_channel();
77             let (sco_up_tx, sco_up_rx) = unbounded_channel();
78             let (iso_up_tx, iso_up_rx) = unbounded_channel();
79             (
80                 RawHal {
81                     cmd_tx,
82                     evt_rx: Arc::new(Mutex::new(evt_rx)),
83                     acl_tx: acl_down_tx,
84                     acl_rx: Arc::new(Mutex::new(acl_up_rx)),
85                     sco_tx: sco_down_tx,
86                     sco_rx: Arc::new(Mutex::new(sco_up_rx)),
87                     iso_tx: iso_down_tx,
88                     iso_rx: Arc::new(Mutex::new(iso_up_rx)),
89                 },
90                 Self {
91                     cmd_rx,
92                     evt_tx,
93                     acl_rx: acl_down_rx,
94                     acl_tx: acl_up_tx,
95                     sco_rx: sco_down_rx,
96                     sco_tx: sco_up_tx,
97                     iso_rx: iso_down_rx,
98                     iso_tx: iso_up_tx,
99                 },
100             )
101         }
102     }
103 }
104 
105 /// Result type
106 type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
107 
108 /// Errors that can be encountered while dealing with the HAL
109 #[derive(Error, Debug)]
110 pub enum HalError {
111     /// Invalid rootcanal host error
112     #[error("Invalid rootcanal host")]
113     InvalidAddressError,
114     /// Error while connecting to rootcanal
115     #[error("Connection to rootcanal failed: {0}")]
116     RootcanalConnectError(#[from] tokio::io::Error),
117 }
118