OSDN Git Service

rusty-gd: integrate rusty packets into existing code
authorZach Johnson <zachoverflow@google.com>
Sun, 13 Dec 2020 04:11:26 +0000 (20:11 -0800)
committerZach Johnson <zachoverflow@google.com>
Thu, 17 Dec 2020 19:51:45 +0000 (11:51 -0800)
still gotta wait for parsing to land for this to officially work, but
this allows us to play with the ergonomics independently based on what
compiles..

next CLs will start to improve the ergos.

some ergos improved this CL.

Bug: 171749953
Tag: #gd-refactor
Test: gd/cert/run --rhost SimpleHalTest
Change-Id: I5eadd7619c5d392c2dd03331c5d604d9a52a1687

15 files changed:
gd/packet/parser/enum_gen.cc
gd/packet/parser/gen_rust.cc
gd/packet/parser/packet_def.cc
gd/packet/parser/struct_def.cc
gd/rust/hal/Android.bp
gd/rust/hal/src/facade.rs
gd/rust/hal/src/hidl_hal.rs
gd/rust/hal/src/lib.rs
gd/rust/hal/src/rootcanal_hal.rs
gd/rust/hal/src/snoop.rs
gd/rust/hci/Android.bp
gd/rust/hci/src/facade.rs
gd/rust/hci/src/lib.rs
gd/rust/packet/Android.bp [deleted file]
gd/rust/packet/src/lib.rs [deleted file]

index 4580efc..05975db 100644 (file)
@@ -61,7 +61,7 @@ void EnumGen::GenLogging(std::ostream& stream) {
 }
 
 void EnumGen::GenRustDef(std::ostream& stream) {
-  stream << "#[derive(FromPrimitive, ToPrimitive)]\n";
+  stream << "#[derive(FromPrimitive, ToPrimitive, Debug, Hash, Eq, PartialEq, Clone, Copy)]\n";
   stream << "pub enum " << e_.name_ << " {";
   for (const auto& pair : e_.constants_) {
     stream << util::ConstantCaseToCamelCase(pair.second) << " = 0x" << std::hex << pair.first << std::dec << ",";
index 85b5391..d9bb89a 100644 (file)
@@ -27,7 +27,7 @@ use num_derive::{FromPrimitive, ToPrimitive};
 use num_traits::{FromPrimitive, ToPrimitive};
 use std::convert::TryInto;
 use thiserror::Error;
-use std::rc::Rc;
+use std::sync::Arc;
 
 type Result<T> = std::result::Result<T, Error>;
 
index 826a828..d6e5ac9 100644 (file)
@@ -742,12 +742,14 @@ void PacketDef::GenBuilderConstructor(std::ostream& s) const {
 
 void PacketDef::GenRustChildEnums(std::ostream& s) const {
   if (!children_.empty()) {
+    s << "#[derive(Debug)] ";
     s << "enum " << name_ << "DataChild {";
     for (const auto& child : children_) {
-      s << child->name_ << "(Rc<" << child->name_ << "Data>),";
+      s << child->name_ << "(Arc<" << child->name_ << "Data>),";
     }
     s << "None,";
     s << "}\n";
+    s << "#[derive(Debug)] ";
     s << "pub enum " << name_ << "Child {";
     for (const auto& child : children_) {
       s << child->name_ << "(" << child->name_ << "Packet),";
@@ -758,6 +760,7 @@ void PacketDef::GenRustChildEnums(std::ostream& s) const {
 }
 
 void PacketDef::GenRustStructDeclarations(std::ostream& s) const {
+  s << "#[derive(Debug)] ";
   s << "struct " << name_ << "Data {";
 
   // Generate struct fields
@@ -768,16 +771,18 @@ void PacketDef::GenRustStructDeclarations(std::ostream& s) const {
   s << "}\n";
 
   // Generate accessor struct
+  s << "#[derive(Debug, Clone)] ";
   s << "pub struct " << name_ << "Packet {";
   auto lineage = GetAncestors();
   lineage.push_back(this);
   for (auto it = lineage.begin(); it != lineage.end(); it++) {
     auto def = *it;
-    s << util::CamelCaseToUnderScore(def->name_) << ": Rc<" << def->name_ << "Data>,";
+    s << util::CamelCaseToUnderScore(def->name_) << ": Arc<" << def->name_ << "Data>,";
   }
   s << "}\n";
 
   // Generate builder struct
+  s << "#[derive(Debug)] ";
   s << "pub struct " << name_ << "Builder {";
   auto params = GetParamList().GetFieldsWithoutTypes({
       PayloadField::kFieldType,
@@ -943,7 +948,7 @@ void PacketDef::GenRustAccessStructImpls(std::ostream& s) const {
   s << "impl " << name_ << "Packet {";
   if (parent_ == nullptr) {
     s << "pub fn parse(bytes: &[u8]) -> Result<Self> { ";
-    s << "Ok(Self::new(Rc::new(" << name_ << "Data::parse(bytes)?)))";
+    s << "Ok(Self::new(Arc::new(" << name_ << "Data::parse(bytes)?)))";
     s << "}";
   }
   auto root = GetRootDef();
@@ -956,11 +961,11 @@ void PacketDef::GenRustAccessStructImpls(std::ostream& s) const {
   s << "}\n";
 
   if (!children_.empty()) {
-    s << " pub fn specialize(self) -> " << name_ << "Child {";
-    s << " match self." << util::CamelCaseToUnderScore(name_) << ".child {";
+    s << " pub fn specialize(&self) -> " << name_ << "Child {";
+    s << " match &self." << util::CamelCaseToUnderScore(name_) << ".child {";
     for (const auto& child : children_) {
       s << name_ << "DataChild::" << child->name_ << "(_) => " << name_ << "Child::" << child->name_ << "("
-        << child->name_ << "Packet::new(self." << root_accessor << ")),";
+        << child->name_ << "Packet::new(self." << root_accessor << ".clone())),";
     }
     s << name_ << "DataChild::None => " << name_ << "Child::None,";
     s << "}}";
@@ -969,7 +974,7 @@ void PacketDef::GenRustAccessStructImpls(std::ostream& s) const {
   lineage.push_back(this);
   const ParentDef* prev = nullptr;
 
-  s << " fn new(root: Rc<" << root->name_ << "Data>) -> Self {";
+  s << " fn new(root: Arc<" << root->name_ << "Data>) -> Self {";
   for (auto it = lineage.begin(); it != lineage.end(); it++) {
     auto def = *it;
     auto accessor_name = util::CamelCaseToUnderScore(def->name_);
@@ -1044,7 +1049,7 @@ void PacketDef::GenRustBuilderStructImpls(std::ostream& s) const {
     });
 
     auto accessor_name = util::CamelCaseToUnderScore(ancestor->name_);
-    s << "let " << accessor_name << "= Rc::new(" << ancestor->name_ << "Data {";
+    s << "let " << accessor_name << "= Arc::new(" << ancestor->name_ << "Data {";
     for (auto field : fields) {
       auto constraint = all_constraints.find(field->GetName());
       s << field->GetName() << ": ";
index 5c6a670..baeaa5b 100644 (file)
@@ -358,6 +358,7 @@ void StructDef::GenRustSizeField(std::ostream& s) const {
 }
 
 void StructDef::GenRustDeclarations(std::ostream& s) const {
+  s << "#[derive(Debug)] ";
   s << "pub struct " << name_ << "{";
 
   // Generate struct fields
index feeb9fa..3429683 100644 (file)
@@ -5,8 +5,8 @@ rust_library {
     srcs: ["src/lib.rs"],
     edition: "2018",
     rustlibs: [
-        "libbt_packet",
         "libbt_facade_proto",
+        "libbt_packets",
         "libbytes",
         "libfutures",
         "libthiserror",
@@ -19,6 +19,10 @@ rust_library {
         "liblazy_static",
         "liblog_rust",
         "libbt_common",
+        "libnum_traits",
+    ],
+    proc_macros: [
+        "libnum_derive",
     ],
     target: {
         android: {
index 889e855..77f1a4f 100644 (file)
@@ -5,7 +5,7 @@ use bt_common::GrpcFacade;
 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_packet::{HciCommand, HciEvent, RawPacket};
+use bt_packets::hci;
 use futures::sink::SinkExt;
 use gddi::{module, provides, Stoppable};
 use grpcio::*;
@@ -35,10 +35,10 @@ async fn provide_facade(hal_exports: HalExports, rt: Arc<Runtime>) -> HciHalFaca
 #[derive(Clone, Stoppable)]
 pub struct HciHalFacadeService {
     rt: Arc<Runtime>,
-    cmd_tx: mpsc::Sender<HciCommand>,
-    evt_rx: Arc<Mutex<mpsc::Receiver<HciEvent>>>,
-    acl_tx: mpsc::Sender<RawPacket>,
-    acl_rx: Arc<Mutex<mpsc::Receiver<HciEvent>>>,
+    cmd_tx: mpsc::Sender<hci::CommandPacket>,
+    evt_rx: Arc<Mutex<mpsc::Receiver<hci::EventPacket>>>,
+    acl_tx: mpsc::Sender<hci::AclPacket>,
+    acl_rx: Arc<Mutex<mpsc::Receiver<hci::AclPacket>>>,
 }
 
 impl GrpcFacade for HciHalFacadeService {
@@ -51,7 +51,7 @@ impl HciHalFacade for HciHalFacadeService {
     fn send_command(&mut self, _ctx: RpcContext<'_>, mut data: Data, sink: UnarySink<Empty>) {
         let cmd_tx = self.cmd_tx.clone();
         self.rt.block_on(async move {
-            cmd_tx.send(data.take_payload().into()).await.unwrap();
+            cmd_tx.send(hci::CommandPacket::parse(&data.take_payload()).unwrap()).await.unwrap();
         });
         sink.success(Empty::default());
     }
@@ -59,7 +59,7 @@ impl HciHalFacade for HciHalFacadeService {
     fn send_acl(&mut self, _ctx: RpcContext<'_>, mut data: Data, sink: UnarySink<Empty>) {
         let acl_tx = self.acl_tx.clone();
         self.rt.block_on(async move {
-            acl_tx.send(data.take_payload().into()).await.unwrap();
+            acl_tx.send(hci::AclPacket::parse(&data.take_payload()).unwrap()).await.unwrap();
         });
         sink.success(Empty::default());
     }
@@ -82,7 +82,7 @@ impl HciHalFacade for HciHalFacadeService {
         self.rt.spawn(async move {
             while let Some(event) = evt_rx.lock().await.recv().await {
                 let mut output = Data::default();
-                output.set_payload(event.to_vec());
+                output.set_payload(event.to_bytes().to_vec());
                 sink.send((output, WriteFlags::default())).await.unwrap();
             }
         });
@@ -93,7 +93,7 @@ impl HciHalFacade for HciHalFacadeService {
         self.rt.spawn(async move {
             while let Some(acl) = acl_rx.lock().await.recv().await {
                 let mut output = Data::default();
-                output.set_payload(acl.to_vec());
+                output.set_payload(acl.to_bytes().to_vec());
                 sink.send((output, WriteFlags::default())).await.unwrap();
             }
         });
index 9faf291..febd3ea 100644 (file)
@@ -1,7 +1,6 @@
 //! Implementation of the HAl that talks to BT controller over Android's HIDL
 use crate::internal::{Hal, RawHalExports};
-use bt_packet::{HciCommand, HciEvent, RawPacket};
-use bytes::Bytes;
+use bt_packets::hci;
 use gddi::{module, provides};
 use std::sync::Arc;
 use std::sync::Mutex;
@@ -54,8 +53,8 @@ mod ffi {
 
 struct Callbacks {
     init_tx: UnboundedSender<()>,
-    evt_tx: UnboundedSender<HciEvent>,
-    acl_tx: UnboundedSender<RawPacket>,
+    evt_tx: UnboundedSender<hci::EventPacket>,
+    acl_tx: UnboundedSender<hci::AclPacket>,
 }
 
 lazy_static! {
@@ -73,7 +72,7 @@ fn on_event(data: &[u8]) {
         .as_ref()
         .unwrap()
         .evt_tx
-        .send(Bytes::copy_from_slice(data))
+        .send(hci::EventPacket::parse(data).unwrap())
         .unwrap();
 }
 
@@ -83,20 +82,20 @@ fn on_acl(data: &[u8]) {
         .as_ref()
         .unwrap()
         .acl_tx
-        .send(Bytes::copy_from_slice(data))
+        .send(hci::AclPacket::parse(data).unwrap())
         .unwrap();
 }
 
 fn on_sco(_data: &[u8]) {}
 
 async fn dispatch_outgoing(
-    mut cmd_rx: UnboundedReceiver<HciCommand>,
-    mut acl_rx: UnboundedReceiver<RawPacket>,
+    mut cmd_rx: UnboundedReceiver<hci::CommandPacket>,
+    mut acl_rx: UnboundedReceiver<hci::AclPacket>,
 ) {
     loop {
         select! {
-            Some(cmd) = cmd_rx.recv() => ffi::send_command(&cmd),
-            Some(acl) = acl_rx.recv() => ffi::send_acl(&acl),
+            Some(cmd) = cmd_rx.recv() => ffi::send_command(&cmd.to_bytes()),
+            Some(acl) = acl_rx.recv() => ffi::send_acl(&acl.to_bytes()),
             else => break,
         }
     }
index 6a6ca1c..2a51859 100644 (file)
@@ -12,7 +12,7 @@ pub mod snoop;
 #[cfg(target_os = "android")]
 mod hidl_hal;
 
-use bt_packet::{HciCommand, HciEvent, RawPacket};
+use bt_packets::hci;
 use gddi::{module, Stoppable};
 use std::sync::Arc;
 use thiserror::Error;
@@ -47,17 +47,17 @@ const H4_HEADER_SIZE: usize = 1;
 #[derive(Clone, Stoppable)]
 pub struct HalExports {
     /// Transmit end of a channel used to send HCI commands
-    pub cmd_tx: Sender<HciCommand>,
+    pub cmd_tx: Sender<hci::CommandPacket>,
     /// Receive end of a channel used to receive HCI events
-    pub evt_rx: Arc<Mutex<Receiver<HciEvent>>>,
+    pub evt_rx: Arc<Mutex<Receiver<hci::EventPacket>>>,
     /// Transmit end of a channel used to send ACL data
-    pub acl_tx: Sender<RawPacket>,
+    pub acl_tx: Sender<hci::AclPacket>,
     /// Receive end of a channel used to receive ACL data
-    pub acl_rx: Arc<Mutex<Receiver<RawPacket>>>,
+    pub acl_rx: Arc<Mutex<Receiver<hci::AclPacket>>>,
 }
 
 mod internal {
-    use bt_packet::{HciCommand, HciEvent, RawPacket};
+    use bt_packets::hci;
     use gddi::Stoppable;
     use std::sync::Arc;
     use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
@@ -65,17 +65,17 @@ mod internal {
 
     #[derive(Clone, Stoppable)]
     pub struct RawHalExports {
-        pub cmd_tx: UnboundedSender<HciCommand>,
-        pub evt_rx: Arc<Mutex<UnboundedReceiver<HciEvent>>>,
-        pub acl_tx: UnboundedSender<RawPacket>,
-        pub acl_rx: Arc<Mutex<UnboundedReceiver<RawPacket>>>,
+        pub cmd_tx: UnboundedSender<hci::CommandPacket>,
+        pub evt_rx: Arc<Mutex<UnboundedReceiver<hci::EventPacket>>>,
+        pub acl_tx: UnboundedSender<hci::AclPacket>,
+        pub acl_rx: Arc<Mutex<UnboundedReceiver<hci::AclPacket>>>,
     }
 
     pub struct Hal {
-        pub cmd_rx: UnboundedReceiver<HciCommand>,
-        pub evt_tx: UnboundedSender<HciEvent>,
-        pub acl_rx: UnboundedReceiver<RawPacket>,
-        pub acl_tx: UnboundedSender<RawPacket>,
+        pub cmd_rx: UnboundedReceiver<hci::CommandPacket>,
+        pub evt_tx: UnboundedSender<hci::EventPacket>,
+        pub acl_rx: UnboundedReceiver<hci::AclPacket>,
+        pub acl_tx: UnboundedSender<hci::AclPacket>,
     }
 
     impl Hal {
index 5cd8b81..26bf12a 100644 (file)
@@ -4,7 +4,7 @@
 
 use crate::internal::{Hal, RawHalExports};
 use crate::{Result, H4_HEADER_SIZE};
-use bt_packet::{HciCommand, HciEvent, HciPacketHeaderSize, HciPacketType, RawPacket};
+use bt_packets::hci;
 use bytes::{BufMut, Bytes, BytesMut};
 use gddi::{module, provides, Stoppable};
 use std::net::{IpAddr, SocketAddr};
@@ -15,6 +15,22 @@ use tokio::net::TcpStream;
 use tokio::runtime::Runtime;
 use tokio::select;
 use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
+use num_derive::{FromPrimitive, ToPrimitive};
+
+#[derive(FromPrimitive, ToPrimitive)]
+enum HciPacketType {
+    Command = 0x01,
+    Acl = 0x02,
+    Sco = 0x03,
+    Event = 0x04,
+}
+
+#[derive(FromPrimitive, ToPrimitive)]
+enum HciPacketHeaderSize {
+    Event = 2,
+    Sco = 3,
+    Acl = 4,
+}
 
 module! {
     rootcanal_hal_module,
@@ -60,8 +76,8 @@ impl RootcanalConfig {
 
 /// Send HCI events received from the HAL to the HCI layer
 async fn dispatch_incoming<R>(
-    evt_tx: UnboundedSender<HciEvent>,
-    acl_tx: UnboundedSender<RawPacket>,
+    evt_tx: UnboundedSender<hci::EventPacket>,
+    acl_tx: UnboundedSender<hci::AclPacket>,
     reader: R,
 ) -> Result<()>
 where
@@ -80,7 +96,7 @@ where
             payload.resize(len, 0);
             reader.read_exact(&mut payload).await?;
             buffer.unsplit(payload);
-            evt_tx.send(buffer.freeze()).unwrap();
+            evt_tx.send(hci::EventPacket::parse(&buffer.freeze()).unwrap()).unwrap();
         } else if buffer[0] == HciPacketType::Acl as u8 {
             buffer.resize(HciPacketHeaderSize::Acl as usize, 0);
             reader.read_exact(&mut buffer).await?;
@@ -89,15 +105,15 @@ where
             payload.resize(len, 0);
             reader.read_exact(&mut payload).await?;
             buffer.unsplit(payload);
-            acl_tx.send(buffer.freeze()).unwrap();
+            acl_tx.send(hci::AclPacket::parse(&buffer.freeze()).unwrap()).unwrap();
         }
     }
 }
 
 /// Send commands received from the HCI later to rootcanal
 async fn dispatch_outgoing<W>(
-    mut cmd_rx: UnboundedReceiver<HciCommand>,
-    mut acl_rx: UnboundedReceiver<RawPacket>,
+    mut cmd_rx: UnboundedReceiver<hci::CommandPacket>,
+    mut acl_rx: UnboundedReceiver<hci::AclPacket>,
     mut writer: W,
 ) -> Result<()>
 where
@@ -105,8 +121,8 @@ where
 {
     loop {
         select! {
-            Some(cmd) = cmd_rx.recv() => write_with_type(&mut writer, HciPacketType::Command, cmd).await?,
-            Some(acl) = acl_rx.recv() => write_with_type(&mut writer, HciPacketType::Acl, acl).await?,
+            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?,
             else => break,
         }
     }
index db6e2c2..0bf625b 100644 (file)
@@ -3,7 +3,6 @@
 use crate::internal::RawHalExports;
 use crate::HalExports;
 use bt_common::sys_prop;
-use bt_packet::{HciCommand, HciEvent, RawPacket};
 use bytes::{BufMut, Bytes, BytesMut};
 use gddi::{module, provides, Stoppable};
 use log::error;
@@ -16,6 +15,7 @@ use tokio::runtime::Runtime;
 use tokio::select;
 use tokio::sync::mpsc::{channel, UnboundedReceiver};
 use tokio::sync::Mutex;
+use bt_packets::hci;
 
 /// The different modes snoop logging can be in
 #[derive(Clone)]
@@ -103,10 +103,10 @@ async fn provide_snooped_hal(
     hal_exports: RawHalExports,
     rt: Arc<Runtime>,
 ) -> HalExports {
-    let (cmd_down_tx, mut cmd_down_rx) = channel::<HciCommand>(10);
-    let (evt_up_tx, evt_up_rx) = channel::<HciEvent>(10);
-    let (acl_down_tx, mut acl_down_rx) = channel::<RawPacket>(10);
-    let (acl_up_tx, acl_up_rx) = channel::<RawPacket>(10);
+    let (cmd_down_tx, mut cmd_down_rx) = channel::<hci::CommandPacket>(10);
+    let (evt_up_tx, evt_up_rx) = channel::<hci::EventPacket>(10);
+    let (acl_down_tx, mut acl_down_rx) = channel::<hci::AclPacket>(10);
+    let (acl_up_tx, acl_up_rx) = channel::<hci::AclPacket>(10);
 
     rt.spawn(async move {
         let mut logger = SnoopLogger::new(config).await;
@@ -114,19 +114,19 @@ async fn provide_snooped_hal(
             select! {
                 Some(evt) = consume(&hal_exports.evt_rx) => {
                     evt_up_tx.send(evt.clone()).await.unwrap();
-                    logger.log(Type::Evt, Direction::Up, evt).await;
+                    logger.log(Type::Evt, Direction::Up, evt.to_bytes()).await;
                 },
                 Some(cmd) = cmd_down_rx.recv() => {
                     hal_exports.cmd_tx.send(cmd.clone()).unwrap();
-                    logger.log(Type::Cmd, Direction::Down, cmd).await;
+                    logger.log(Type::Cmd, Direction::Down, cmd.to_bytes()).await;
                 },
                 Some(acl) = acl_down_rx.recv() => {
                     hal_exports.acl_tx.send(acl.clone()).unwrap();
-                    logger.log(Type::Acl, Direction::Down, acl).await;
+                    logger.log(Type::Acl, Direction::Down, acl.to_bytes()).await;
                 },
                 Some(acl) = consume(&hal_exports.acl_rx) => {
                     acl_up_tx.send(acl.clone()).await.unwrap();
-                    logger.log(Type::Acl, Direction::Up, acl).await;
+                    logger.log(Type::Acl, Direction::Up, acl.to_bytes()).await;
                 }
             }
         }
index 8a2d3e0..f0865b1 100644 (file)
@@ -7,7 +7,7 @@ rust_library {
     rustlibs: [
         "libbt_hal",
         "libbt_facade_proto",
-        "libbt_packet",
+        "libbt_packets",
         "libbytes",
         "libfutures",
         "libgrpcio",
index a76280a..3c89ba6 100644 (file)
@@ -6,7 +6,7 @@ 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_layer_facade, HciLayerFacade};
-use bt_packet::HciEvent;
+use bt_packets::hci;
 use futures::sink::SinkExt;
 use gddi::{module, provides, Stoppable};
 use grpcio::*;
@@ -14,6 +14,7 @@ use std::sync::Arc;
 use tokio::runtime::Runtime;
 use tokio::sync::mpsc::{channel, Receiver, Sender};
 use tokio::sync::Mutex;
+use num_traits::FromPrimitive;
 
 module! {
     facade_module,
@@ -24,7 +25,7 @@ module! {
 
 #[provides]
 async fn provide_facade(hci_exports: HciExports, rt: Arc<Runtime>) -> HciLayerFacadeService {
-    let (from_hci_evt_tx, to_grpc_evt_rx) = channel::<HciEvent>(10);
+    let (from_hci_evt_tx, to_grpc_evt_rx) = channel::<hci::EventPacket>(10);
     HciLayerFacadeService {
         hci_exports,
         rt,
@@ -38,8 +39,8 @@ async fn provide_facade(hci_exports: HciExports, rt: Arc<Runtime>) -> HciLayerFa
 pub struct HciLayerFacadeService {
     hci_exports: HciExports,
     rt: Arc<Runtime>,
-    from_hci_evt_tx: Sender<HciEvent>,
-    to_grpc_evt_rx: Arc<Mutex<Receiver<HciEvent>>>,
+    from_hci_evt_tx: Sender<hci::EventPacket>,
+    to_grpc_evt_rx: Arc<Mutex<Receiver<hci::EventPacket>>>,
 }
 
 impl GrpcFacade for HciLayerFacadeService {
@@ -55,8 +56,10 @@ impl HciLayerFacade for HciLayerFacadeService {
         mut data: Data,
         sink: UnarySink<Empty>,
     ) {
-        self.rt
-            .block_on(self.hci_exports.enqueue_command_with_complete(data.take_payload().into()));
+        self.rt.block_on(
+            self.hci_exports
+                .enqueue_command_with_complete(hci::CommandPacket::parse(&data.take_payload()).unwrap()),
+        );
         sink.success(Empty::default());
     }
 
@@ -66,15 +69,17 @@ impl HciLayerFacade for HciLayerFacadeService {
         mut data: Data,
         sink: UnarySink<Empty>,
     ) {
-        self.rt
-            .block_on(self.hci_exports.enqueue_command_with_complete(data.take_payload().into()));
+        self.rt.block_on(
+            self.hci_exports
+                .enqueue_command_with_complete(hci::CommandPacket::parse(&data.take_payload()).unwrap()),
+        );
         sink.success(Empty::default());
     }
 
     fn request_event(&mut self, _ctx: RpcContext<'_>, code: EventRequest, sink: UnarySink<Empty>) {
         self.rt.block_on(
             self.hci_exports
-                .register_event_handler(code.get_code() as u8, self.from_hci_evt_tx.clone()),
+                .register_event_handler(hci::EventCode::from_u32(code.get_code()).unwrap(), self.from_hci_evt_tx.clone()),
         );
         sink.success(Empty::default());
     }
@@ -91,7 +96,7 @@ impl HciLayerFacade for HciLayerFacadeService {
     fn send_acl(&mut self, _ctx: RpcContext<'_>, mut packet: Data, sink: UnarySink<Empty>) {
         let acl_tx = self.hci_exports.acl_tx.clone();
         self.rt.block_on(async move {
-            acl_tx.send(packet.take_payload().into()).await.unwrap();
+            acl_tx.send(hci::AclPacket::parse(&packet.take_payload()).unwrap()).await.unwrap();
         });
         sink.success(Empty::default());
     }
@@ -107,7 +112,7 @@ impl HciLayerFacade for HciLayerFacadeService {
         self.rt.spawn(async move {
             while let Some(event) = evt_rx.lock().await.recv().await {
                 let mut evt = Data::default();
-                evt.set_payload(event.to_vec());
+                evt.set_payload(event.to_bytes().to_vec());
                 resp.send((evt, WriteFlags::default())).await.unwrap();
             }
         });
@@ -133,7 +138,7 @@ impl HciLayerFacade for HciLayerFacadeService {
         self.rt.spawn(async move {
             while let Some(data) = acl_rx.lock().await.recv().await {
                 let mut packet = Data::default();
-                packet.set_payload(data.to_vec());
+                packet.set_payload(data.to_bytes().to_vec());
                 resp.send((packet, WriteFlags::default())).await.unwrap();
             }
         });
index 38a98e7..07c1474 100644 (file)
@@ -7,7 +7,8 @@ pub mod error;
 pub mod facade;
 
 use bt_hal::HalExports;
-use bt_packet::{HciCommand, HciEvent, RawPacket};
+use bt_packets::hci;
+use bt_packets::hci::EventChild::{CommandStatus,CommandComplete};
 use error::Result;
 use gddi::{module, provides, Stoppable};
 use std::collections::HashMap;
@@ -52,30 +53,30 @@ async fn provide_hci(hal_exports: HalExports, rt: Arc<Runtime>) -> HciExports {
 /// to the command is received
 #[derive(Debug)]
 struct Command {
-    cmd: HciCommand,
-    fut: oneshot::Sender<HciCommand>,
+    cmd: hci::CommandPacket,
+    fut: oneshot::Sender<hci::EventPacket>,
 }
 
 #[derive(Debug)]
 struct PendingCommand {
-    opcode: u16,
-    fut: oneshot::Sender<HciCommand>,
+    opcode: hci::OpCode,
+    fut: oneshot::Sender<hci::EventPacket>,
 }
 
 /// HCI interface
 #[derive(Clone, Stoppable)]
 pub struct HciExports {
     cmd_tx: Sender<Command>,
-    evt_handlers: Arc<Mutex<HashMap<u8, Sender<HciEvent>>>>,
+    evt_handlers: Arc<Mutex<HashMap<hci::EventCode, Sender<hci::EventPacket>>>>,
     /// Transmit end of a channel used to send ACL data
-    pub acl_tx: Sender<RawPacket>,
+    pub acl_tx: Sender<hci::AclPacket>,
     /// Receive end of a channel used to receive ACL data
-    pub acl_rx: Arc<Mutex<Receiver<RawPacket>>>,
+    pub acl_rx: Arc<Mutex<Receiver<hci::AclPacket>>>,
 }
 
 impl HciExports {
-    async fn send(&mut self, cmd: HciCommand) -> Result<HciEvent> {
-        let (tx, rx) = oneshot::channel::<HciEvent>();
+    async fn send(&mut self, cmd: hci::CommandPacket) -> Result<hci::EventPacket> {
+        let (tx, rx) = oneshot::channel::<hci::EventPacket>();
         self.cmd_tx.send(Command { cmd, fut: tx }).await?;
         let event = rx.await?;
         Ok(event)
@@ -83,43 +84,55 @@ impl HciExports {
 
     /// Enqueue an HCI command expecting a command complete
     /// response from the controller
-    pub async fn enqueue_command_with_complete(&mut self, cmd: HciCommand) -> HciEvent {
+    pub async fn enqueue_command_with_complete(&mut self, cmd: hci::CommandPacket) -> hci::EventPacket {
         self.send(cmd).await.unwrap()
     }
 
     /// Enqueue an HCI command expecting a status response
     /// from the controller
-    pub async fn enqueue_command_with_status(&mut self, cmd: HciCommand) -> HciEvent {
+    pub async fn enqueue_command_with_status(&mut self, cmd: hci::CommandPacket) -> hci::EventPacket {
         self.send(cmd).await.unwrap()
     }
 
     /// Indicate interest in specific HCI events
-    pub async fn register_event_handler(&mut self, evt_code: u8, sender: Sender<HciEvent>) {
+    pub async fn register_event_handler(&mut self, evt_code: hci::EventCode, sender: Sender<hci::EventPacket>) {
         self.evt_handlers.lock().await.insert(evt_code, sender);
     }
 }
 
 async fn dispatch(
-    evt_handlers: Arc<Mutex<HashMap<u8, Sender<HciEvent>>>>,
-    evt_rx: Arc<Mutex<Receiver<HciEvent>>>,
-    cmd_tx: Sender<HciCommand>,
+    evt_handlers: Arc<Mutex<HashMap<hci::EventCode, Sender<hci::EventPacket>>>>,
+    evt_rx: Arc<Mutex<Receiver<hci::EventPacket>>>,
+    cmd_tx: Sender<hci::CommandPacket>,
     mut cmd_rx: Receiver<Command>,
 ) {
     let mut pending_cmds: Vec<PendingCommand> = Vec::new();
     loop {
         select! {
             Some(evt) = consume(&evt_rx) => {
-                let opcode = bt_packet::get_evt_opcode(&evt).unwrap();
-                let evt_code = bt_packet::get_evt_code(&evt).unwrap();
-                if let Some(pending_cmd) = remove_first(&mut pending_cmds, |entry| entry.opcode == opcode) {
-                    pending_cmd.fut.send(evt).unwrap();
-                } else if let Some(sender) = evt_handlers.lock().await.get(&evt_code) {
-                    sender.send(evt).await.unwrap();
+                match evt.specialize() {
+                    CommandStatus(evt) => {
+                        let opcode = *evt.get_command_op_code();
+                        if let Some(pending_cmd) = remove_first(&mut pending_cmds, |entry| entry.opcode == opcode) {
+                            pending_cmd.fut.send(evt.into()).unwrap();
+                        }
+                    },
+                    CommandComplete(evt) => {
+                        let opcode = *evt.get_command_op_code();
+                        if let Some(pending_cmd) = remove_first(&mut pending_cmds, |entry| entry.opcode == opcode) {
+                            pending_cmd.fut.send(evt.into()).unwrap();
+                        }
+                    },
+                    _ => {
+                        if let Some(sender) = evt_handlers.lock().await.get(evt.get_event_code()) {
+                            sender.send(evt).await.unwrap();
+                        }
+                    },
                 }
             },
             Some(cmd) = cmd_rx.recv() => {
                 pending_cmds.push(PendingCommand {
-                    opcode: bt_packet::get_cmd_opcode(&cmd.cmd).unwrap(),
+                    opcode: *cmd.cmd.get_op_code(),
                     fut: cmd.fut,
                 });
                 cmd_tx.send(cmd.cmd).await.unwrap();
@@ -129,7 +142,7 @@ async fn dispatch(
     }
 }
 
-async fn consume(evt_rx: &Arc<Mutex<Receiver<HciEvent>>>) -> Option<HciEvent> {
+async fn consume(evt_rx: &Arc<Mutex<Receiver<hci::EventPacket>>>) -> Option<hci::EventPacket> {
     evt_rx.lock().await.recv().await
 }
 
diff --git a/gd/rust/packet/Android.bp b/gd/rust/packet/Android.bp
deleted file mode 100644 (file)
index c487dbc..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-rust_library {
-    name: "libbt_packet",
-    defaults: ["gd_rust_defaults"],
-    // has rustc warnings
-    crate_name: "bt_packet",
-    srcs: ["src/lib.rs"],
-    edition: "2018",
-    rustlibs: [
-        "libbytes",
-        "libnum_traits",
-    ],
-    proc_macros: [
-        "libnum_derive",
-    ],
-}
diff --git a/gd/rust/packet/src/lib.rs b/gd/rust/packet/src/lib.rs
deleted file mode 100644 (file)
index 20c751f..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-//! HCI packet representation
-//! This is temporary and will be replaced by a shim that uses
-//! existing C++ packet code through CXX
-
-use bytes::Bytes;
-use num_derive::{FromPrimitive, ToPrimitive};
-
-/// Packet types
-#[derive(FromPrimitive, ToPrimitive)]
-pub enum HciPacketType {
-    /// HCI command packet
-    Command = 0x01,
-    /// ACL data packet
-    Acl = 0x02,
-    /// SCO data packet
-    Sco = 0x03,
-    /// HCI event packet
-    Event = 0x04,
-}
-
-/// Header size (in bytes) for each packet type
-#[derive(FromPrimitive, ToPrimitive)]
-pub enum HciPacketHeaderSize {
-    /// HCI Event packet header size
-    Event = 2,
-    /// SCO packet header size
-    Sco = 3,
-    /// ACL packet header size
-    Acl = 4,
-}
-
-/// Raw packet
-pub type RawPacket = Bytes;
-
-/// HCI command packet
-pub type HciCommand = Bytes;
-
-/// Gets the 16-bit opcode for an HCI command
-pub fn get_cmd_opcode(cmd: &HciCommand) -> Option<u16> {
-    let b0 = ((cmd[0] as u16) << 8) as u16;
-    let b1 = (cmd[1] as u16) as u16;
-    Some(b0 | b1)
-}
-
-/// HCI event packet
-pub type HciEvent = Bytes;
-
-/// Gets the HCI command opcode corresponding to an event
-pub fn get_evt_opcode(event: &HciEvent) -> Option<u16> {
-    let b0 = ((event[3] as u16) << 8) as u16;
-    let b1 = (event[4] as u16) as u16;
-    Some(b0 | b1)
-}
-
-/// Gets the event code for an HCI event
-pub fn get_evt_code(event: &HciEvent) -> Option<u8> {
-    Some(event[0])
-}
-
-/// Packet bytes for each packet type
-#[derive(Debug)]
-pub enum HciPacket {
-    /// HCI command
-    Command(HciCommand),
-    /// ACL packet
-    Acl(RawPacket),
-    /// SCO packet
-    Sco(RawPacket),
-    /// HCI event
-    Event(HciEvent),
-}