OSDN Git Service

rusty-gd: implement vector payloads for packets
authorZach Johnson <zachoverflow@google.com>
Mon, 28 Dec 2020 20:50:45 +0000 (12:50 -0800)
committerZach Johnson <zachoverflow@google.com>
Wed, 20 Jan 2021 00:52:20 +0000 (16:52 -0800)
this way, we can get the contents to pass to higher layers from ACL, etc

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

gd/packet/parser/gen_rust.cc
gd/packet/parser/packet_def.cc
gd/packet/parser/parent_def.cc
gd/packet/parser/parent_def.h
gd/rust/acl/src/classic/facade.rs [new file with mode: 0644]

index 6456b8c..0c8ca3e 100644 (file)
@@ -22,7 +22,7 @@
 void generate_rust_packet_preamble(std::ostream& s) {
   s <<
       R"(
-use bytes::{Bytes, BytesMut};
+use bytes::{Bytes, BytesMut, BufMut};
 use num_derive::{FromPrimitive, ToPrimitive};
 use num_traits::{FromPrimitive, ToPrimitive};
 use std::convert::TryInto;
index b11c6ed..1ce5f64 100644 (file)
@@ -741,7 +741,8 @@ void PacketDef::GenBuilderConstructor(std::ostream& s) const {
 }
 
 void PacketDef::GenRustChildEnums(std::ostream& s) const {
-  if (!children_.empty()) {
+  if (HasChildEnums()) {
+    bool payload = fields_.HasPayload();
     s << "#[derive(Debug)] ";
     s << "enum " << name_ << "DataChild {";
     for (const auto& child : children_) {
@@ -750,6 +751,9 @@ void PacketDef::GenRustChildEnums(std::ostream& s) const {
       }
       s << child->name_ << "(Arc<" << child->name_ << "Data>),";
     }
+    if (payload) {
+      s << "Payload(Arc<Vec<u8>>),";
+    }
     s << "None,";
     s << "}\n";
     s << "#[derive(Debug)] ";
@@ -760,6 +764,9 @@ void PacketDef::GenRustChildEnums(std::ostream& s) const {
       }
       s << child->name_ << "(" << child->name_ << "Packet),";
     }
+    if (payload) {
+      s << "Payload(Arc<Vec<u8>>),";
+    }
     s << "None,";
     s << "}\n";
   }
@@ -771,7 +778,7 @@ void PacketDef::GenRustStructDeclarations(std::ostream& s) const {
 
   // Generate struct fields
   GenRustStructFieldNameAndType(s);
-  if (!children_.empty()) {
+  if (HasChildEnums()) {
     s << "child: " << name_ << "DataChild,";
   }
   s << "}\n";
@@ -799,6 +806,9 @@ void PacketDef::GenRustStructDeclarations(std::ostream& s) const {
     param->GenRustNameAndType(s);
     s << ", ";
   }
+  if (fields_.HasPayload()) {
+    s << "pub payload: Option<Vec<u8>>,";
+  }
   s << "}\n";
 }
 
@@ -855,21 +865,6 @@ void PacketDef::GenRustStructSizeField(std::ostream& s) const {
 
 void PacketDef::GenRustStructImpls(std::ostream& s) const {
   s << "impl " << name_ << "Data {";
-  s << "fn new(";
-  bool fields_exist = GenRustStructFieldNameAndType(s);
-  if (!children_.empty()) {
-    s << "child: " << name_ << "DataChild,";
-  }
-  s << ") -> Self { ";
-
-  s << "Self { ";
-  GenRustStructFieldNames(s);
-  if (!children_.empty()) {
-    s << "child";
-  }
-
-  s << "}";
-  s << "}";
 
   // parse function
   if (parent_constraints_.empty() && !children_.empty() && parent_ != nullptr) {
@@ -913,46 +908,50 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const {
 
   if (!children_.empty()) {
     s << "let child = match " << constraint_name << " {";
-  }
 
-  for (const auto& desc : constrained_descendants) {
-    if (desc.first->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) {
-      continue;
-    }
-    auto desc_path = FindPathToDescendant(desc.first->name_);
-    std::reverse(desc_path.begin(), desc_path.end());
-    auto constraint_field = GetParamList().GetField(constraint_name);
-    auto constraint_type = constraint_field->GetFieldType();
-
-    if (constraint_type == EnumField::kFieldType) {
-      auto type = std::get<std::string>(desc.second);
-      auto variant_name = type.substr(type.find("::") + 2, type.length());
-      auto enum_type = type.substr(0, type.find("::"));
-      auto enum_variant = enum_type + "::"
-          + util::UnderscoreToCamelCase(util::ToLowerCase(variant_name));
-      s << enum_variant;
-      s << " => {";
-      s << name_ << "DataChild::";
-      s << desc_path[0]->name_ << "(Arc::new(";
-      if (desc_path[0]->parent_constraints_.empty()) {
-        s << desc_path[0]->name_ << "Data::parse(&bytes[" << payload_offset.bytes() << "..]";
-        s << ", " << enum_variant << ")?))";
-      } else {
-        s << desc_path[0]->name_ << "Data::parse(&bytes[" << payload_offset.bytes() << "..])?))";
+    for (const auto& desc : constrained_descendants) {
+      if (desc.first->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) {
+        continue;
       }
-    } else if (constraint_type == ScalarField::kFieldType) {
-      s << std::get<int64_t>(desc.second) << " => {";
-      s << "unimplemented!();";
+      auto desc_path = FindPathToDescendant(desc.first->name_);
+      std::reverse(desc_path.begin(), desc_path.end());
+      auto constraint_field = GetParamList().GetField(constraint_name);
+      auto constraint_type = constraint_field->GetFieldType();
+
+      if (constraint_type == EnumField::kFieldType) {
+        auto type = std::get<std::string>(desc.second);
+        auto variant_name = type.substr(type.find("::") + 2, type.length());
+        auto enum_type = type.substr(0, type.find("::"));
+        auto enum_variant = enum_type + "::"
+            + util::UnderscoreToCamelCase(util::ToLowerCase(variant_name));
+        s << enum_variant;
+        s << " => {";
+        s << name_ << "DataChild::";
+        s << desc_path[0]->name_ << "(Arc::new(";
+        if (desc_path[0]->parent_constraints_.empty()) {
+          s << desc_path[0]->name_ << "Data::parse(&bytes[" << payload_offset.bytes() << "..]";
+          s << ", " << enum_variant << ")?))";
+        } else {
+          s << desc_path[0]->name_ << "Data::parse(&bytes[" << payload_offset.bytes() << "..])?))";
+        }
+      } else if (constraint_type == ScalarField::kFieldType) {
+        s << std::get<int64_t>(desc.second) << " => {";
+        s << "unimplemented!();";
+      }
+      s << "}\n";
     }
-    s << "}\n";
-  }
 
-  if (!constrained_descendants.empty()) {
-    s << "_ => panic!(\"unexpected value " << "\"),";
-  }
+    if (!constrained_descendants.empty()) {
+      s << "_ => panic!(\"unexpected value " << "\"),";
+    }
 
-  if (!children_.empty()) {
     s << "};\n";
+  } else if (fields_.HasPayload()) {
+    s << "let child = if payload.len() > 0 {";
+    s << name_ << "DataChild::Payload(Arc::new(payload))";
+    s << "} else {";
+    s << name_ << "DataChild::None";
+    s << "};";
   }
 
   s << "Ok(Self {";
@@ -966,7 +965,7 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const {
       FixedScalarField::kFieldType,
   });
 
-  if (fields_exist) {
+  if (fields.size() > 0) {
     for (int i = 0; i < fields.size(); i++) {
       auto field_type = fields[i]->GetFieldType();
       s << fields[i]->GetName();
@@ -974,7 +973,7 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const {
     }
   }
 
-  if (!children_.empty()) {
+  if (HasChildEnums()) {
     s << "child,";
   }
   s << "})\n";
@@ -982,7 +981,7 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const {
 
   // write_to function
   s << "fn write_to(&self, buffer: &mut BytesMut) {";
-  if (fields_exist) {
+  if (fields.size() > 0) {
     s << " buffer.resize(buffer.len() + self.get_size(), 0);";
   }
 
@@ -1007,7 +1006,7 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const {
     field->GenRustWriter(s, start_field_offset, end_field_offset);
   }
 
-  if (!children_.empty()) {
+  if (HasChildEnums()) {
     s << "match &self.child {";
     for (const auto& child : children_) {
       if (child->name_.rfind("LeGetVendorCapabilitiesComplete", 0) == 0) {
@@ -1015,13 +1014,16 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const {
       }
       s << name_ << "DataChild::" << child->name_ << "(value) => value.write_to(buffer),";
     }
+    if (fields_.HasPayload()) {
+      s << name_ << "DataChild::Payload(p) => buffer.put(&p[..]),";
+    }
     s << name_ << "DataChild::None => {}";
     s << "}";
   }
 
   s << "}\n";
 
-  if (fields_exist) {
+  if (fields.size() > 0) {
     s << "pub fn get_size(&self) -> usize {";
     GenRustStructSizeField(s);
     s << "}";
@@ -1061,7 +1063,7 @@ void PacketDef::GenRustAccessStructImpls(std::ostream& s) const {
     s << "}";
   }
 
-  if (!children_.empty()) {
+  if (HasChildEnums()) {
     s << " pub fn specialize(&self) -> " << name_ << "Child {";
     s << " match &self." << util::CamelCaseToUnderScore(name_) << ".child {";
     for (const auto& child : children_) {
@@ -1071,6 +1073,9 @@ void PacketDef::GenRustAccessStructImpls(std::ostream& s) const {
       s << name_ << "DataChild::" << child->name_ << "(_) => " << name_ << "Child::" << child->name_ << "("
         << child->name_ << "Packet::new(self." << root_accessor << ".clone())),";
     }
+    if (fields_.HasPayload()) {
+      s << name_ << "DataChild::Payload(p) => " << name_ << "Child::Payload(p.clone()),";
+    }
     s << name_ << "DataChild::None => " << name_ << "Child::None,";
     s << "}}";
   }
@@ -1190,9 +1195,16 @@ void PacketDef::GenRustBuilderStructImpls(std::ostream& s) const {
       }
       s << ", ";
     }
-    if (!ancestor->children_.empty()) {
+    if (ancestor->HasChildEnums()) {
       if (prev == nullptr) {
-        s << "child: " << name_ << "DataChild::None,";
+        if (ancestor->fields_.HasPayload()) {
+          s << "child: match self.payload { ";
+          s << "None => " << name_ << "DataChild::None,";
+          s << "Some(vec) => " << name_ << "DataChild::Payload(Arc::new(vec)),";
+          s << "},";
+        } else {
+          s << "child: " << name_ << "DataChild::None,";
+        }
       } else {
         s << "child: " << ancestor->name_ << "DataChild::" << prev->name_ << "("
           << util::CamelCaseToUnderScore(prev->name_) << "),";
index ecfd46a..ec912d7 100644 (file)
@@ -565,3 +565,7 @@ std::vector<const ParentDef*> ParentDef::FindPathToDescendant(std::string descen
   }
   return res;
 }
+
+bool ParentDef::HasChildEnums() const {
+  return !children_.empty() || fields_.HasPayload();
+}
index 7a70506..84857e3 100644 (file)
@@ -85,4 +85,6 @@ class ParentDef : public TypeDef {
 
   std::map<std::string, std::variant<int64_t, std::string>> parent_constraints_;
   bool is_little_endian_;
+
+  bool HasChildEnums() const;
 };
diff --git a/gd/rust/acl/src/classic/facade.rs b/gd/rust/acl/src/classic/facade.rs
new file mode 100644 (file)
index 0000000..b96cdad
--- /dev/null
@@ -0,0 +1,62 @@
+//! Classic ACL facade
+
+use crate::classic::AclManager;
+
+module! {
+    facade_module,
+    providers {
+        ClassicAclFacadeService => provide_facade,
+    }
+}
+
+#[provides]
+async fn provide_facade(acl: AclManager) -> ClassicAclFacadeService {
+    ClassicAclFacadeService { acl }
+}
+
+pub struct ClassicAclFacadeService {
+    acl: AclManager,
+}
+
+impl AclManagerFacade for ClassicAclFacadeService {
+    fn create_connection(&mut self, _ctx: RpcContext<'_>, mut _data: ConnectionMsg, _sink: ServerStreamingSink<ConnectionEvent>) {
+        unimplemented!();
+    }
+
+    fn cancel_connection(&mut self, _ctx: RpcContext<'_>, mut _data: ConnectionMsg, _sink: UnarySink<Empty>) {
+        unimplemented!();
+    }
+
+    fn disconnect(&mut self, _ctx: RpcContext<'_>, mut _data: HandleMsg, _sink: UnarySink<Empty>) {
+        unimplemented!();
+    }
+
+    fn disconnect(&mut self, _ctx: RpcContext<'_>, mut _data: PolicyMsg, _sink: UnarySink<Empty>) {
+        unimplemented!();
+    }
+
+    fn authentication_requested(&mut self, _ctx: RpcContext<'_>, mut _data: HandleMsg, _sink: UnarySink<Empty>) {
+        unimplemented!();
+    }
+
+    fn connection_command(&mut self, _ctx: RpcContext<'_>, mut _data: ConnectionCommandMsg, _sink: UnarySink<Empty>) {
+        unimplemented!();
+    }
+
+    fn switch_role(&mut self, _ctx: RpcContext<'_>, mut _data: RoleMsg, _sink: UnarySink<Empty>) {
+        unimplemented!();
+    }
+
+    fn send_acl_data(&mut self, _ctx: RpcContext<'_>, mut _data: AclData, _sink: UnarySink<Empty>) {
+        unimplemented!();
+    }
+
+    fn fetch_acl_data(&mut self, _ctx: RpcContext<'_>, mut _data: HandleMsg, _sink: ServerStreamingSink<AclData>) {
+        unimplemented!();
+    }
+
+    fn fetch_incoming_connection(&mut self, _ctx: RpcContext<'_>, mut _data: Empty, _sink: ServerStreamingSink<ConnectionEvent>) {
+        unimplemented!();
+    }
+}
+