summaryrefslogtreecommitdiff
path: root/system/gd/rust/stack/src/hal/mod.rs
blob: 3e42ced085d260e2927e69ca562ec16abd9787f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! HCI Hardware Abstraction Layer
//! Supports sending HCI commands to the HAL and receving
//! HCI events from the HAL

pub mod facade;
pub mod rootcanal_hal;
pub mod snoop;

#[cfg(target_os = "android")]
mod hidl_hal;

use gddi::module;
use thiserror::Error;

#[cfg(target_os = "android")]
module! {
    hal_module,
    submodules {
        facade::hal_facade_module,
        hidl_hal::hidl_hal_module,
        snoop::snoop_module,
    },
}

#[cfg(not(target_os = "android"))]
module! {
    hal_module,
    submodules {
        facade::hal_facade_module,
        rootcanal_hal::rootcanal_hal_module,
        snoop::snoop_module,
    },
}
/// H4 packet header size
const H4_HEADER_SIZE: usize = 1;

pub use snoop::{AclHal, ControlHal, IsoHal, ScoHal};

mod internal {
    use bt_packets::hci::{AclPacket, CommandPacket, EventPacket, IsoPacket, ScoPacket};
    use gddi::Stoppable;
    use std::sync::Arc;
    use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
    use tokio::sync::Mutex;

    #[derive(Clone, Stoppable)]
    pub struct RawHal {
        pub cmd_tx: UnboundedSender<CommandPacket>,
        pub evt_rx: Arc<Mutex<UnboundedReceiver<EventPacket>>>,
        pub acl_tx: UnboundedSender<AclPacket>,
        pub acl_rx: Arc<Mutex<UnboundedReceiver<AclPacket>>>,
        pub iso_tx: UnboundedSender<IsoPacket>,
        pub iso_rx: Arc<Mutex<UnboundedReceiver<IsoPacket>>>,
        pub sco_tx: UnboundedSender<ScoPacket>,
        pub sco_rx: Arc<Mutex<UnboundedReceiver<ScoPacket>>>,
    }

    pub struct InnerHal {
        pub cmd_rx: UnboundedReceiver<CommandPacket>,
        pub evt_tx: UnboundedSender<EventPacket>,
        pub acl_rx: UnboundedReceiver<AclPacket>,
        pub acl_tx: UnboundedSender<AclPacket>,
        pub sco_rx: UnboundedReceiver<ScoPacket>,
        pub sco_tx: UnboundedSender<ScoPacket>,
        pub iso_rx: UnboundedReceiver<IsoPacket>,
        pub iso_tx: UnboundedSender<IsoPacket>,
    }

    impl InnerHal {
        pub fn new() -> (RawHal, Self) {
            let (cmd_tx, cmd_rx) = unbounded_channel();
            let (evt_tx, evt_rx) = unbounded_channel();
            let (acl_down_tx, acl_down_rx) = unbounded_channel();
            let (sco_down_tx, sco_down_rx) = unbounded_channel();
            let (iso_down_tx, iso_down_rx) = unbounded_channel();
            let (acl_up_tx, acl_up_rx) = unbounded_channel();
            let (sco_up_tx, sco_up_rx) = unbounded_channel();
            let (iso_up_tx, iso_up_rx) = unbounded_channel();
            (
                RawHal {
                    cmd_tx,
                    evt_rx: Arc::new(Mutex::new(evt_rx)),
                    acl_tx: acl_down_tx,
                    acl_rx: Arc::new(Mutex::new(acl_up_rx)),
                    sco_tx: sco_down_tx,
                    sco_rx: Arc::new(Mutex::new(sco_up_rx)),
                    iso_tx: iso_down_tx,
                    iso_rx: Arc::new(Mutex::new(iso_up_rx)),
                },
                Self {
                    cmd_rx,
                    evt_tx,
                    acl_rx: acl_down_rx,
                    acl_tx: acl_up_tx,
                    sco_rx: sco_down_rx,
                    sco_tx: sco_up_tx,
                    iso_rx: iso_down_rx,
                    iso_tx: iso_up_tx,
                },
            )
        }
    }
}

/// Result type
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;

/// Errors that can be encountered while dealing with the HAL
#[derive(Error, Debug)]
pub enum HalError {
    /// Invalid rootcanal host error
    #[error("Invalid rootcanal host")]
    InvalidAddressError,
    /// Error while connecting to rootcanal
    #[error("Connection to rootcanal failed: {0}")]
    RootcanalConnectError(#[from] tokio::io::Error),
}