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