Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dfbee396 authored by Zach Johnson's avatar Zach Johnson
Browse files

rusty-gd: split HAL into control & acl

this way the ACL can bypass the HCI layer entirely

Bug: 171749953
Tag: #gd-refactor
Test: gd/cert/run --rhost SimpleHalTest
Change-Id: Iee6c37a7ffab39546d07a915e80900e748103fea
parent 9eb03a94
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
//! BT HCI HAL facade

use crate::Hal;
use crate::{AclHal, ControlHal};
use bt_common::GrpcFacade;
use bt_facade_proto::common::Data;
use bt_facade_proto::empty::Empty;
@@ -20,15 +20,16 @@ module! {
}

#[provides]
async fn provide_facade(hal: Hal, rt: Arc<Runtime>) -> HciHalFacadeService {
    HciHalFacadeService { rt, hal }
async fn provide_facade(control: ControlHal, acl: AclHal, rt: Arc<Runtime>) -> HciHalFacadeService {
    HciHalFacadeService { rt, control, acl }
}

/// HCI HAL facade service
#[derive(Clone, Stoppable)]
pub struct HciHalFacadeService {
    rt: Arc<Runtime>,
    hal: Hal,
    control: ControlHal,
    acl: AclHal,
}

impl GrpcFacade for HciHalFacadeService {
@@ -39,7 +40,7 @@ impl GrpcFacade for HciHalFacadeService {

impl HciHalFacade for HciHalFacadeService {
    fn send_command(&mut self, _ctx: RpcContext<'_>, mut data: Data, sink: UnarySink<Empty>) {
        let cmd_tx = self.hal.cmd_tx.clone();
        let cmd_tx = self.control.tx.clone();
        self.rt.block_on(async move {
            cmd_tx.send(CommandPacket::parse(&data.take_payload()).unwrap()).await.unwrap();
        });
@@ -47,7 +48,7 @@ impl HciHalFacade for HciHalFacadeService {
    }

    fn send_acl(&mut self, _ctx: RpcContext<'_>, mut data: Data, sink: UnarySink<Empty>) {
        let acl_tx = self.hal.acl_tx.clone();
        let acl_tx = self.acl.tx.clone();
        self.rt.block_on(async move {
            acl_tx.send(AclPacket::parse(&data.take_payload()).unwrap()).await.unwrap();
        });
@@ -68,7 +69,7 @@ impl HciHalFacade for HciHalFacadeService {
        _: Empty,
        mut sink: ServerStreamingSink<Data>,
    ) {
        let evt_rx = self.hal.evt_rx.clone();
        let evt_rx = self.control.rx.clone();
        self.rt.spawn(async move {
            while let Some(event) = evt_rx.lock().await.recv().await {
                let mut output = Data::default();
@@ -79,7 +80,7 @@ impl HciHalFacade for HciHalFacadeService {
    }

    fn stream_acl(&mut self, _ctx: RpcContext<'_>, _: Empty, mut sink: ServerStreamingSink<Data>) {
        let acl_rx = self.hal.acl_rx.clone();
        let acl_rx = self.acl.rx.clone();
        self.rt.spawn(async move {
            while let Some(acl) = acl_rx.lock().await.recv().await {
                let mut output = Data::default();
+3 −19
Original line number Diff line number Diff line
@@ -12,12 +12,8 @@ pub mod snoop;
#[cfg(target_os = "android")]
mod hidl_hal;

use bt_packets::hci::{AclPacket, CommandPacket, EventPacket};
use gddi::{module, Stoppable};
use std::sync::Arc;
use gddi::module;
use thiserror::Error;
use tokio::sync::mpsc::{Receiver, Sender};
use tokio::sync::Mutex;

#[cfg(target_os = "android")]
module! {
@@ -41,20 +37,8 @@ module! {
/// H4 packet header size
const H4_HEADER_SIZE: usize = 1;

/// HAL interface
/// This is used by the HCI module to send commands to the
/// HAL and receive events from the HAL
#[derive(Clone, Stoppable)]
pub struct Hal {
    /// Transmit end of a channel used to send HCI commands
    pub cmd_tx: Sender<CommandPacket>,
    /// Receive end of a channel used to receive HCI events
    pub evt_rx: Arc<Mutex<Receiver<EventPacket>>>,
    /// Transmit end of a channel used to send ACL data
    pub acl_tx: Sender<AclPacket>,
    /// Receive end of a channel used to receive ACL data
    pub acl_rx: Arc<Mutex<Receiver<AclPacket>>>,
}
pub use snoop::AclHal;
pub use snoop::ControlHal;

mod internal {
    use bt_packets::hci::{AclPacket, CommandPacket, EventPacket};
+30 −8
Original line number Diff line number Diff line
//! BT snoop logger

use crate::internal::RawHal;
use crate::Hal;
use bt_common::sys_prop;
use bt_packets::hci::{AclPacket, CommandPacket, EventPacket};
use bytes::{BufMut, Bytes, BytesMut};
use gddi::{module, provides, Stoppable};
use gddi::{module, part_out, provides, Stoppable};
use log::error;
use std::convert::TryFrom;
use std::sync::Arc;
@@ -14,9 +13,34 @@ use tokio::fs::{remove_file, rename, File};
use tokio::io::AsyncWriteExt;
use tokio::runtime::Runtime;
use tokio::select;
use tokio::sync::mpsc::{channel, UnboundedReceiver};
use tokio::sync::mpsc::{channel, Receiver, Sender, UnboundedReceiver};
use tokio::sync::Mutex;

#[part_out]
#[derive(Clone, Stoppable)]
struct Hal {
    control: ControlHal,
    acl: AclHal,
}

/// Command & event tx/rx
#[derive(Clone, Stoppable)]
pub struct ControlHal {
    /// Transmit end
    pub tx: Sender<CommandPacket>,
    /// Receive end
    pub rx: Arc<Mutex<Receiver<EventPacket>>>,
}

/// Acl tx/rx
#[derive(Clone, Stoppable)]
pub struct AclHal {
    /// Transmit end
    pub tx: Sender<AclPacket>,
    /// Receive end
    pub rx: Arc<Mutex<Receiver<AclPacket>>>,
}

/// The different modes snoop logging can be in
#[derive(Clone)]
pub enum SnoopMode {
@@ -91,7 +115,7 @@ fn get_configured_snoop_mode() -> String {
module! {
    snoop_module,
    providers {
        Hal => provide_snooped_hal,
        parts Hal => provide_snooped_hal,
    },
}

@@ -127,10 +151,8 @@ async fn provide_snooped_hal(config: SnoopConfig, raw_hal: RawHal, rt: Arc<Runti
    });

    Hal {
        cmd_tx: cmd_down_tx,
        evt_rx: Arc::new(Mutex::new(evt_up_rx)),
        acl_tx: acl_down_tx,
        acl_rx: Arc::new(Mutex::new(acl_up_rx)),
        control: ControlHal { tx: cmd_down_tx, rx: Arc::new(Mutex::new(evt_up_rx)) },
        acl: AclHal { tx: acl_down_tx, rx: Arc::new(Mutex::new(acl_up_rx)) },
    }
}

+4 −3
Original line number Diff line number Diff line
//! HCI layer facade

use crate::{EventRegistry, HciForAcl, RawCommandSender};
use crate::{EventRegistry, RawCommandSender};
use bt_common::GrpcFacade;
use bt_facade_proto::common::Data;
use bt_facade_proto::empty::Empty;
use bt_facade_proto::hci_facade::EventRequest;
use bt_facade_proto::hci_facade_grpc::{create_hci_facade, HciFacade};
use bt_hal::AclHal;
use bt_packets::hci::{
    AclPacket, CommandPacket, EventCode, EventPacket, LeMetaEventPacket, SubeventCode,
};
@@ -29,7 +30,7 @@ module! {
async fn provide_facade(
    commands: RawCommandSender,
    events: EventRegistry,
    acl: HciForAcl,
    acl: AclHal,
    rt: Arc<Runtime>,
) -> HciFacadeService {
    let (from_hci_evt_tx, to_grpc_evt_rx) = channel::<EventPacket>(10);
@@ -51,7 +52,7 @@ async fn provide_facade(
pub struct HciFacadeService {
    commands: RawCommandSender,
    events: EventRegistry,
    acl: HciForAcl,
    acl: AclHal,
    rt: Arc<Runtime>,
    from_hci_evt_tx: Sender<EventPacket>,
    to_grpc_evt_rx: Arc<Mutex<Receiver<EventPacket>>>,
+7 −22
Original line number Diff line number Diff line
@@ -11,14 +11,14 @@ pub use bt_hci_custom_types::*;
pub use controller::ControllerExports;

use bt_common::time::Alarm;
use bt_hal::Hal;
use bt_hal::ControlHal;
use bt_packets::hci::EventChild::{
    CommandComplete, CommandStatus, LeMetaEvent, MaxSlotsChange, PageScanRepetitionModeChange,
    VendorSpecificEvent,
};
use bt_packets::hci::{
    AclPacket, CommandExpectations, CommandPacket, ErrorCode, EventCode, EventPacket,
    LeMetaEventPacket, ResetBuilder, SubeventCode,
    CommandExpectations, CommandPacket, ErrorCode, EventCode, EventPacket, LeMetaEventPacket,
    ResetBuilder, SubeventCode,
};
use error::Result;
use gddi::{module, part_out, provides, Stoppable};
@@ -47,11 +47,10 @@ struct Hci {
    raw_commands: RawCommandSender,
    commands: CommandSender,
    events: EventRegistry,
    acl: HciForAcl,
}

#[provides]
async fn provide_hci(hal: Hal, rt: Arc<Runtime>) -> Hci {
async fn provide_hci(control: ControlHal, rt: Arc<Runtime>) -> Hci {
    let (cmd_tx, cmd_rx) = channel::<QueuedCommand>(10);
    let evt_handlers = Arc::new(Mutex::new(HashMap::new()));
    let le_evt_handlers = Arc::new(Mutex::new(HashMap::new()));
@@ -59,8 +58,8 @@ async fn provide_hci(hal: Hal, rt: Arc<Runtime>) -> Hci {
    rt.spawn(dispatch(
        evt_handlers.clone(),
        le_evt_handlers.clone(),
        hal.evt_rx,
        hal.cmd_tx,
        control.rx,
        control.tx,
        cmd_rx,
    ));

@@ -72,12 +71,7 @@ async fn provide_hci(hal: Hal, rt: Arc<Runtime>) -> Hci {
        "reset did not complete successfully"
    );

    Hci {
        raw_commands,
        commands,
        events: EventRegistry { evt_handlers, le_evt_handlers },
        acl: HciForAcl { tx: hal.acl_tx, rx: hal.acl_rx },
    }
    Hci { raw_commands, commands, events: EventRegistry { evt_handlers, le_evt_handlers } }
}

#[derive(Debug)]
@@ -120,15 +114,6 @@ impl CommandSender {
    }
}

/// Exposes the ACL send/receive interface
#[derive(Clone, Stoppable)]
pub struct HciForAcl {
    /// Transmit end
    pub tx: Sender<AclPacket>,
    /// Receive end
    pub rx: Arc<Mutex<Receiver<AclPacket>>>,
}

/// Provides ability to register and unregister for HCI events
#[derive(Clone, Stoppable)]
pub struct EventRegistry {
Loading