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