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

Commit 85343dd7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "GD Rust: Add SCO support" am: 420ea7cf

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/1965901

Change-Id: I375c7bc7ce3c5b5468246500f8b6a09d7cdba4c7
parents 155d27d6 420ea7cf
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
//! BT HCI HAL facade

use crate::hal::{AclHal, ControlHal, IsoHal};
use crate::hal::{AclHal, ControlHal, IsoHal, ScoHal};
use bt_common::GrpcFacade;
use bt_facade_helpers::RxAdapter;
use bt_facade_proto::common::Data;
use bt_facade_proto::empty::Empty;
use bt_facade_proto::hal_facade_grpc::{create_hci_hal_facade, HciHalFacade};
use bt_packets::hci::{AclPacket, CommandPacket, EventPacket, IsoPacket};
use bt_packets::hci::{AclPacket, CommandPacket, EventPacket, IsoPacket, ScoPacket};
use gddi::{module, provides, Stoppable};
use grpcio::*;

@@ -18,14 +18,21 @@ module! {
}

#[provides]
async fn provide_facade(control: ControlHal, acl: AclHal, iso: IsoHal) -> HciHalFacadeService {
async fn provide_facade(
    control: ControlHal,
    acl: AclHal,
    iso: IsoHal,
    sco: ScoHal,
) -> HciHalFacadeService {
    HciHalFacadeService {
        evt_rx: RxAdapter::from_arc(control.rx.clone()),
        acl_rx: RxAdapter::from_arc(acl.rx.clone()),
        iso_rx: RxAdapter::from_arc(iso.rx.clone()),
        sco_rx: RxAdapter::from_arc(sco.rx.clone()),
        control,
        acl,
        iso,
        sco,
    }
}

@@ -35,9 +42,11 @@ pub struct HciHalFacadeService {
    evt_rx: RxAdapter<EventPacket>,
    acl_rx: RxAdapter<AclPacket>,
    iso_rx: RxAdapter<IsoPacket>,
    sco_rx: RxAdapter<ScoPacket>,
    control: ControlHal,
    acl: AclHal,
    iso: IsoHal,
    sco: ScoHal,
}

impl GrpcFacade for HciHalFacadeService {
@@ -63,8 +72,12 @@ impl HciHalFacade for HciHalFacadeService {
        });
    }

    fn send_sco(&mut self, _ctx: RpcContext<'_>, _sco: Data, _sink: UnarySink<Empty>) {
        unimplemented!()
    fn send_sco(&mut self, ctx: RpcContext<'_>, mut data: Data, sink: UnarySink<Empty>) {
        let sco_tx = self.sco.tx.clone();
        ctx.spawn(async move {
            sco_tx.send(ScoPacket::parse(&data.take_payload()).unwrap()).await.unwrap();
            sink.success(Empty::default()).await.unwrap();
        });
    }

    fn send_iso(&mut self, ctx: RpcContext<'_>, mut data: Data, sink: UnarySink<Empty>) {
@@ -83,8 +96,8 @@ impl HciHalFacade for HciHalFacadeService {
        self.acl_rx.stream_grpc(ctx, sink);
    }

    fn stream_sco(&mut self, _ctx: RpcContext<'_>, _: Empty, _sink: ServerStreamingSink<Data>) {
        unimplemented!()
    fn stream_sco(&mut self, ctx: RpcContext<'_>, _: Empty, sink: ServerStreamingSink<Data>) {
        self.sco_rx.stream_grpc(ctx, sink);
    }

    fn stream_iso(&mut self, ctx: RpcContext<'_>, _: Empty, sink: ServerStreamingSink<Data>) {
+18 −3
Original line number Diff line number Diff line
//! Implementation of the HAl that talks to BT controller over Android's HIDL
use crate::hal::internal::{InnerHal, RawHal};
use bt_packets::hci::{AclPacket, CommandPacket, EventPacket, IsoPacket, Packet};
use bt_packets::hci::{AclPacket, CommandPacket, EventPacket, IsoPacket, Packet, ScoPacket};
use gddi::{module, provides};
use std::sync::Arc;
use std::sync::Mutex;
@@ -24,11 +24,17 @@ async fn provide_hidl_hal(rt: Arc<Runtime>) -> RawHal {
        evt_tx: inner_hal.evt_tx,
        acl_tx: inner_hal.acl_tx,
        iso_tx: inner_hal.iso_tx,
        sco_tx: inner_hal.sco_tx,
    });
    ffi::start_hal();
    init_rx.recv().await.unwrap();

    rt.spawn(dispatch_outgoing(inner_hal.cmd_rx, inner_hal.acl_rx, inner_hal.iso_rx));
    rt.spawn(dispatch_outgoing(
        inner_hal.cmd_rx,
        inner_hal.acl_rx,
        inner_hal.iso_rx,
        inner_hal.sco_rx,
    ));

    raw_hal
}
@@ -61,6 +67,7 @@ struct Callbacks {
    evt_tx: UnboundedSender<EventPacket>,
    acl_tx: UnboundedSender<AclPacket>,
    iso_tx: UnboundedSender<IsoPacket>,
    sco_tx: UnboundedSender<ScoPacket>,
}

lazy_static! {
@@ -89,7 +96,13 @@ fn on_acl(data: &[u8]) {
    }
}

fn on_sco(_data: &[u8]) {}
fn on_sco(data: &[u8]) {
    let callbacks = CALLBACKS.lock().unwrap();
    match ScoPacket::parse(data) {
        Ok(p) => callbacks.as_ref().unwrap().sco_tx.send(p).unwrap(),
        Err(e) => log::error!("failure to parse incoming SCO: {:?} data: {:02x?}", e, data),
    }
}

fn on_iso(data: &[u8]) {
    let callbacks = CALLBACKS.lock().unwrap();
@@ -103,12 +116,14 @@ async fn dispatch_outgoing(
    mut cmd_rx: UnboundedReceiver<CommandPacket>,
    mut acl_rx: UnboundedReceiver<AclPacket>,
    mut iso_rx: UnboundedReceiver<IsoPacket>,
    mut sco_rx: UnboundedReceiver<ScoPacket>,
) {
    loop {
        select! {
            Some(cmd) = cmd_rx.recv() => ffi::send_command(&cmd.to_bytes()),
            Some(acl) = acl_rx.recv() => ffi::send_acl(&acl.to_bytes()),
            Some(iso) = iso_rx.recv() => ffi::send_iso(&iso.to_bytes()),
            Some(sco) = sco_rx.recv() => ffi::send_sco(&sco.to_bytes()),
            else => break,
        }
    }
+32 −4
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@

use crate::hal::internal::{InnerHal, RawHal};
use crate::hal::{Result, H4_HEADER_SIZE};
use bt_packets::hci::{AclPacket, CommandPacket, EventPacket, IsoPacket, Packet};
use bt_packets::hci::{AclPacket, CommandPacket, EventPacket, IsoPacket, Packet, ScoPacket};
use bytes::{BufMut, Bytes, BytesMut};
use gddi::{module, provides, Stoppable};
use num_derive::{FromPrimitive, ToPrimitive};
@@ -27,7 +27,7 @@ enum HciPacketType {
}

const SIZE_OF_EVENT_HEADER: usize = 2;
const _SIZE_OF_SCO_HEADER: usize = 3;
const SIZE_OF_SCO_HEADER: usize = 3;
const SIZE_OF_ACL_HEADER: usize = 4;
const SIZE_OF_ISO_HEADER: usize = 4;

@@ -46,8 +46,20 @@ async fn provide_rootcanal_hal(config: RootcanalConfig, rt: Arc<Runtime>) -> Raw
        .expect("unable to create stream to rootcanal")
        .into_split();

    rt.spawn(dispatch_incoming(inner_hal.evt_tx, inner_hal.acl_tx, inner_hal.iso_tx, reader));
    rt.spawn(dispatch_outgoing(inner_hal.cmd_rx, inner_hal.acl_rx, inner_hal.iso_rx, writer));
    rt.spawn(dispatch_incoming(
        inner_hal.evt_tx,
        inner_hal.acl_tx,
        inner_hal.iso_tx,
        inner_hal.sco_tx,
        reader,
    ));
    rt.spawn(dispatch_outgoing(
        inner_hal.cmd_rx,
        inner_hal.acl_rx,
        inner_hal.iso_rx,
        inner_hal.sco_rx,
        writer,
    ));

    raw_hal
}
@@ -75,6 +87,7 @@ async fn dispatch_incoming<R>(
    evt_tx: UnboundedSender<EventPacket>,
    acl_tx: UnboundedSender<AclPacket>,
    iso_tx: UnboundedSender<IsoPacket>,
    sco_tx: UnboundedSender<ScoPacket>,
    reader: R,
) -> Result<()>
where
@@ -124,6 +137,19 @@ where
                Ok(p) => iso_tx.send(p).unwrap(),
                Err(e) => log::error!("dropping invalid ISO packet: {}: {:02x}", e, frozen),
            }
        } else if buffer[0] == HciPacketType::Sco as u8 {
            buffer.resize(SIZE_OF_SCO_HEADER, 0);
            reader.read_exact(&mut buffer).await?;
            let len: usize = buffer[2].into();
            let mut payload = buffer.split_off(SIZE_OF_SCO_HEADER);
            payload.resize(len, 0);
            reader.read_exact(&mut payload).await?;
            buffer.unsplit(payload);
            let frozen = buffer.freeze();
            match ScoPacket::parse(&frozen) {
                Ok(p) => sco_tx.send(p).unwrap(),
                Err(e) => log::error!("dropping invalid SCO packet: {}: {:02x}", e, frozen),
            }
        }
    }
}
@@ -133,6 +159,7 @@ async fn dispatch_outgoing<W>(
    mut cmd_rx: UnboundedReceiver<CommandPacket>,
    mut acl_rx: UnboundedReceiver<AclPacket>,
    mut iso_rx: UnboundedReceiver<IsoPacket>,
    mut sco_rx: UnboundedReceiver<ScoPacket>,
    mut writer: W,
) -> Result<()>
where
@@ -143,6 +170,7 @@ where
            Some(cmd) = cmd_rx.recv() => write_with_type(&mut writer, HciPacketType::Command, cmd.to_bytes()).await?,
            Some(acl) = acl_rx.recv() => write_with_type(&mut writer, HciPacketType::Acl, acl.to_bytes()).await?,
            Some(iso) = iso_rx.recv() => write_with_type(&mut writer, HciPacketType::Iso, iso.to_bytes()).await?,
            Some(sco) = sco_rx.recv() => write_with_type(&mut writer, HciPacketType::Sco, sco.to_bytes()).await?,
            else => break,
        }
    }