OSDN Git Service

rusty-packets: generate sample enums and make this work end to end
authorZach Johnson <zachoverflow@google.com>
Sat, 21 Nov 2020 00:57:33 +0000 (16:57 -0800)
committerZach Johnson <zachoverflow@google.com>
Sat, 21 Nov 2020 00:58:36 +0000 (16:58 -0800)
Bug: 171749953
Tag: #gd-refactor
Test: gd/cert/run --rhost SimpleHalTest
Change-Id: I9467b6871b3072a64d06bcd8b79887bc6e85c010

gd/Android.bp
gd/hci/hci_packets.pdl
gd/packet/parser/enum_gen.cc
gd/packet/parser/enum_gen.h
gd/packet/parser/gen_rust.cc
gd/packet/parser/util.h
gd/rust/hal/Android.bp
gd/rust/packets/lib.rs [new file with mode: 0644]

index a561d1e..9d9cea9 100644 (file)
@@ -448,6 +448,28 @@ genrule {
     ],
 }
 
+genrule {
+    name: "BluetoothGeneratedPackets_rust",
+    tools: [
+        "bluetooth_packetgen",
+    ],
+    cmd: "$(location bluetooth_packetgen) --include=system/bt/gd --out=$(genDir) $(in) --rust",
+    srcs: [
+        "hci/hci_packets.pdl",
+    ],
+    out: [
+        "hci/hci_packets.rs",
+    ],
+}
+
+rust_library {
+    name: "libbt_packets",
+    crate_name: "bt_packets",
+    srcs: ["rust/packets/lib.rs", ":BluetoothGeneratedPackets_rust"],
+    edition: "2018",
+    host_supported: true,
+}
+
 // Generates binary schema data to be bundled and source file generated
 genrule {
     name: "BluetoothGeneratedDumpsysBinarySchema_bfbs",
index 2297ffb..cae343f 100644 (file)
@@ -4622,7 +4622,7 @@ packet VendorSpecificEvent : EventPacket (event_code = VENDOR_SPECIFIC) {
   _payload_,
 }
 
-enum qualityReportId : 8 {
+enum QualityReportId : 8 {
   MONITOR_MODE = 0x01,
   APPROACH_LSTO = 0x02,
   A2DP_AUDIO_CHOPPY = 0x03,
@@ -4634,7 +4634,7 @@ enum qualityReportId : 8 {
 }
 
 packet BqrEvent : VendorSpecificEvent (subevent_code = BQR_EVENT) {
-  quality_report_id : qualityReportId,
+  quality_report_id : QualityReportId,
   _payload_,
 }
 
index 4bd5a26..8ef9646 100644 (file)
@@ -59,3 +59,11 @@ void EnumGen::GenLogging(std::ostream& stream) {
   stream << "  return os << " << e_.name_ << "Text(param);";
   stream << "}\n";
 }
+
+void EnumGen::GenRustDef(std::ostream& stream) {
+  stream << "pub enum " << e_.name_ << " {";
+  for (const auto& pair : e_.constants_) {
+    stream << util::ConstantCaseToCamelCase(pair.second) << " = 0x" << std::hex << pair.first << std::dec << ",";
+  }
+  stream << "}";
+}
index be16559..5586dfc 100644 (file)
@@ -31,5 +31,7 @@ class EnumGen {
 
   void GenLogging(std::ostream& stream);
 
+  void GenRustDef(std::ostream& stream);
+
   EnumDef e_;
 };
index f39b061..8dd3f2d 100644 (file)
@@ -20,7 +20,7 @@
 #include "declarations.h"
 
 bool generate_rust_source_one_file(
-    __attribute__((unused)) const Declarations& decls,
+    const Declarations& decls,
     const std::filesystem::path& input_file,
     const std::filesystem::path& include_dir,
     const std::filesystem::path& out_dir,
@@ -43,7 +43,16 @@ bool generate_rust_source_one_file(
     return false;
   }
 
-  out_file << "// @generated rust packets from " << input_file.filename().string();
+  out_file << "// @generated rust packets from " << input_file.filename().string() << "\n\n";
+
+  for (const auto& e : decls.type_defs_queue_) {
+    if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) {
+      const auto* enum_def = dynamic_cast<const EnumDef*>(e.second);
+      EnumGen gen(*enum_def);
+      gen.GenRustDef(out_file);
+      out_file << "\n\n";
+    }
+  }
 
   out_file.close();
   return true;
index a8b881d..52946f0 100644 (file)
@@ -103,6 +103,31 @@ inline std::string UnderscoreToCamelCase(std::string value) {
   return camel_case.str();
 }
 
+inline std::string ConstantCaseToCamelCase(std::string value) {
+  if (value[0] < 'A' || value[0] > 'Z') {
+    ERROR() << value << " doesn't look like CONSTANT_CASE";
+  }
+
+  std::ostringstream camel_case;
+
+  bool capitalize = true;
+  for (unsigned char c : value) {
+    if (c == '_') {
+      capitalize = true;
+    } else {
+      if (capitalize) {
+        c = std::toupper(c);
+        capitalize = false;
+      } else {
+        c = std::tolower(c);
+      }
+      camel_case << c;
+    }
+  }
+
+  return camel_case.str();
+}
+
 inline bool IsEnumCase(std::string value) {
   if (value[0] < 'A' || value[0] > 'Z') {
     return false;
index e6b5999..99d8e07 100644 (file)
@@ -12,6 +12,7 @@ rust_library {
         "libgrpcio",
         "libtokio",
         "libprotobuf",
+        "libbt_packets",
     ],
     host_supported: true,
 }
diff --git a/gd/rust/packets/lib.rs b/gd/rust/packets/lib.rs
new file mode 100644 (file)
index 0000000..f28fe1d
--- /dev/null
@@ -0,0 +1,9 @@
+//! reimport of generated packets (to go away once rust_genrule exists)
+
+#![allow(clippy::all)]
+#![allow(unused)]
+#![allow(missing_docs)]
+
+pub mod hci {
+    include!(concat!(env!("OUT_DIR"), "/hci_packets.rs"));
+}