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