Loading system/gd/Android.bp +16 −0 Original line number Diff line number Diff line Loading @@ -548,6 +548,22 @@ rust_library { ], } rust_test_host { name: "libbt_packets_test", defaults: ["gd_rust_defaults"], srcs: ["rust/packets/lib.rs", ":BluetoothGeneratedPackets_rust"], test_suites: ["general-tests"], edition: "2018", proc_macros: ["libnum_derive"], rustlibs: [ "libbytes", "libnum_traits", "libthiserror", "libbt_hci_custom_types", "liblog_rust", ], } // Generates binary schema data to be bundled and source file generated genrule { name: "BluetoothGeneratedDumpsysBinarySchema_bfbs", Loading system/gd/hci/hci_packets.pdl +9 −0 Original line number Diff line number Diff line Loading @@ -1601,10 +1601,19 @@ packet SetEventMaskComplete : CommandComplete (command_op_code = SET_EVENT_MASK) packet Reset : Command (op_code = RESET) { } test Reset { "\x03\x0c\x00", } packet ResetComplete : CommandComplete (command_op_code = RESET) { status : ErrorCode, } test ResetComplete { "\x0e\x04\x01\x03\x0c\x00", "\x0e\x04\x01\x03\x0c\x01", // unknown command } enum FilterType : 8 { CLEAR_ALL_FILTERS = 0x00, INQUIRY_RESULT = 0x01, Loading system/gd/packet/parser/language_l.ll +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ string_literal \".*\" "enum" { return(token::ENUM); } "group" { return(token::GROUP); } "packet" { return(token::PACKET); } "test" { return(token::TEST); } "struct" { return(token::STRUCT); } "little_endian_packets" { yylval->integer = 1; Loading system/gd/packet/parser/language_y.yy +51 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ StructDef* struct_definition_value; std::set<std::string*>* test_cases_t; std::string* test_case_t; std::map<std::string, std::variant<int64_t, std::string>>* constraint_list_t; std::pair<std::string, std::variant<int64_t, std::string>>* constraint_t; } Loading @@ -70,6 +73,7 @@ %token CHECKSUM "checksum" %token CHECKSUM_START "checksum_start" %token PADDING "padding" %token TEST "test" %type<enum_definition> enum_definition %type<enumeration_values> enumeration_list Loading @@ -92,6 +96,10 @@ %type<struct_definition_value> struct_definition; %type<test_cases_t> test_definition; %type<test_cases_t> test_case_list; %type<test_case_t> test_case; %type<constraint_list_t> constraint_list; %type<constraint_t> constraint; %destructor { std::cout << "DESTROYING STRING " << *$$ << "\n"; delete $$; } IDENTIFIER STRING SIZE_MODIFIER Loading Loading @@ -141,6 +149,10 @@ declaration { // All actions are handled in custom_field_definition } | test_definition { // All actions are handled in test_definition } enum_definition : ENUM IDENTIFIER ':' INTEGER '{' enumeration_list ',' '}' Loading Loading @@ -211,6 +223,44 @@ custom_field_definition delete $3; } test_definition : TEST IDENTIFIER '{' test_case_list ',' '}' { auto&& packet_name = *$2; DEBUG() << "Test Declared: name=" << *$2 << "\n"; auto packet = decls->GetPacketDef(packet_name); if (packet == nullptr) { ERRORLOC(LOC) << "Could not find packet " << packet_name << "\n"; } for (const auto& t : *$4) { packet->AddTestCase(*t); } delete $2; delete $4; } test_case_list : test_case { DEBUG() << "Test case with comma\n"; $$ = new std::set<std::string*>(); $$->insert($1); } | test_case_list ',' test_case { DEBUG() << "Test case with list\n"; $$ = $1; $$->insert($3); } test_case : STRING { DEBUG() << "Test Case: name=" << *$1 << "\n"; $$ = $1; } struct_definition : STRUCT IDENTIFIER '{' field_definition_list '}' { Loading Loading @@ -340,7 +390,7 @@ packet_definition auto parent_packet = decls->GetPacketDef(parent_packet_name); if (parent_packet == nullptr) { ERRORLOC(LOC) << "Could not find packet " << parent_packet_name << " used as parent for " << packet_name; << " used as parent for " << packet_name << "\n"; } auto packet_definition = new PacketDef(std::move(packet_name), std::move(field_definition_list), parent_packet); Loading system/gd/packet/parser/packet_def.cc +68 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "packet_def.h" #include <iomanip> #include <list> #include <set> Loading Loading @@ -1217,19 +1218,81 @@ void PacketDef::GenRustBuilderStructImpls(std::ostream& s) const { s << "}\n"; s << "}\n"; lineage = GetAncestors(); for (auto it = lineage.begin(); it != lineage.end(); it++) { auto def = *it; s << "impl Into<" << def->name_ << "Packet> for " << name_ << "Builder {"; s << " fn into(self) -> " << def->name_ << "Packet { self.build().into() }"; for (const auto ancestor : GetAncestors()) { s << "impl Into<" << ancestor->name_ << "Packet> for " << name_ << "Builder {"; s << " fn into(self) -> " << ancestor->name_ << "Packet { self.build().into() }"; s << "}\n"; } } void PacketDef::GenRustBuilderTest(std::ostream& s) const { auto lineage = GetAncestors(); lineage.push_back(this); if (!lineage.empty() && !test_cases_.empty()) { s << "macro_rules! " << util::CamelCaseToUnderScore(name_) << "_builder_tests { "; s << "($($name:ident: $byte_string:expr,)*) => {"; s << "$("; s << "\n#[test]\n"; s << "pub fn $name() { "; s << "let raw_bytes = $byte_string;"; for (size_t i = 0; i < lineage.size(); i++) { s << "/* (" << i << ") */\n"; if (i == 0) { s << "match " << lineage[i]->name_ << "Packet::parse(raw_bytes) {"; s << "Ok(" << util::CamelCaseToUnderScore(lineage[i]->name_) << "_packet) => {"; s << "match " << util::CamelCaseToUnderScore(lineage[i]->name_) << "_packet.specialize() {"; } else if (i != lineage.size() - 1) { s << lineage[i - 1]->name_ << "Child::" << lineage[i]->name_ << "("; s << util::CamelCaseToUnderScore(lineage[i]->name_) << "_packet) => {"; s << "match " << util::CamelCaseToUnderScore(lineage[i]->name_) << "_packet.specialize() {"; } else { s << lineage[i - 1]->name_ << "Child::" << lineage[i]->name_ << "(packet) => {"; s << "let rebuilder = " << lineage[i]->name_ << "Builder {"; FieldList params = GetParamList().GetFieldsWithoutTypes({ BodyField::kFieldType, }); for (const auto param : params) { s << param->GetName() << " : packet." << util::CamelCaseToUnderScore(param->GetGetterFunctionName()) << "(),"; } s << "};"; s << "let rebuilder_base : " << lineage[0]->name_ << "Packet = rebuilder.into();"; s << "let rebuilder_bytes : &[u8] = &rebuilder_base.to_bytes();"; s << "assert_eq!(rebuilder_bytes, raw_bytes);"; s << "}"; } } for (size_t i = 1; i < lineage.size(); i++) { s << "_ => {"; s << "println!(\"Couldn't parse " << util::CamelCaseToUnderScore(lineage[lineage.size() - i]->name_); s << "{:02x?}\", " << util::CamelCaseToUnderScore(lineage[lineage.size() - i - 1]->name_) << "_packet); "; s << "}}}"; } s << ","; s << "Err(e) => panic!(\"could not parse " << lineage[0]->name_ << ": {:?} {:02x?}\", e, raw_bytes),"; s << "}"; s << "}"; s << ")*"; s << "}"; s << "}"; s << util::CamelCaseToUnderScore(name_) << "_builder_tests! { "; int number = 0; for (const auto& test_case : test_cases_) { s << util::CamelCaseToUnderScore(name_) << "_builder_test_"; s << std::setfill('0') << std::setw(2) << number++ << ": "; s << "b\"" << test_case << "\","; } s << "}"; s << "\n"; } } void PacketDef::GenRustDef(std::ostream& s) const { GenRustChildEnums(s); GenRustStructDeclarations(s); GenRustStructImpls(s); GenRustAccessStructImpls(s); GenRustBuilderStructImpls(s); GenRustBuilderTest(s); } Loading
system/gd/Android.bp +16 −0 Original line number Diff line number Diff line Loading @@ -548,6 +548,22 @@ rust_library { ], } rust_test_host { name: "libbt_packets_test", defaults: ["gd_rust_defaults"], srcs: ["rust/packets/lib.rs", ":BluetoothGeneratedPackets_rust"], test_suites: ["general-tests"], edition: "2018", proc_macros: ["libnum_derive"], rustlibs: [ "libbytes", "libnum_traits", "libthiserror", "libbt_hci_custom_types", "liblog_rust", ], } // Generates binary schema data to be bundled and source file generated genrule { name: "BluetoothGeneratedDumpsysBinarySchema_bfbs", Loading
system/gd/hci/hci_packets.pdl +9 −0 Original line number Diff line number Diff line Loading @@ -1601,10 +1601,19 @@ packet SetEventMaskComplete : CommandComplete (command_op_code = SET_EVENT_MASK) packet Reset : Command (op_code = RESET) { } test Reset { "\x03\x0c\x00", } packet ResetComplete : CommandComplete (command_op_code = RESET) { status : ErrorCode, } test ResetComplete { "\x0e\x04\x01\x03\x0c\x00", "\x0e\x04\x01\x03\x0c\x01", // unknown command } enum FilterType : 8 { CLEAR_ALL_FILTERS = 0x00, INQUIRY_RESULT = 0x01, Loading
system/gd/packet/parser/language_l.ll +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ string_literal \".*\" "enum" { return(token::ENUM); } "group" { return(token::GROUP); } "packet" { return(token::PACKET); } "test" { return(token::TEST); } "struct" { return(token::STRUCT); } "little_endian_packets" { yylval->integer = 1; Loading
system/gd/packet/parser/language_y.yy +51 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ StructDef* struct_definition_value; std::set<std::string*>* test_cases_t; std::string* test_case_t; std::map<std::string, std::variant<int64_t, std::string>>* constraint_list_t; std::pair<std::string, std::variant<int64_t, std::string>>* constraint_t; } Loading @@ -70,6 +73,7 @@ %token CHECKSUM "checksum" %token CHECKSUM_START "checksum_start" %token PADDING "padding" %token TEST "test" %type<enum_definition> enum_definition %type<enumeration_values> enumeration_list Loading @@ -92,6 +96,10 @@ %type<struct_definition_value> struct_definition; %type<test_cases_t> test_definition; %type<test_cases_t> test_case_list; %type<test_case_t> test_case; %type<constraint_list_t> constraint_list; %type<constraint_t> constraint; %destructor { std::cout << "DESTROYING STRING " << *$$ << "\n"; delete $$; } IDENTIFIER STRING SIZE_MODIFIER Loading Loading @@ -141,6 +149,10 @@ declaration { // All actions are handled in custom_field_definition } | test_definition { // All actions are handled in test_definition } enum_definition : ENUM IDENTIFIER ':' INTEGER '{' enumeration_list ',' '}' Loading Loading @@ -211,6 +223,44 @@ custom_field_definition delete $3; } test_definition : TEST IDENTIFIER '{' test_case_list ',' '}' { auto&& packet_name = *$2; DEBUG() << "Test Declared: name=" << *$2 << "\n"; auto packet = decls->GetPacketDef(packet_name); if (packet == nullptr) { ERRORLOC(LOC) << "Could not find packet " << packet_name << "\n"; } for (const auto& t : *$4) { packet->AddTestCase(*t); } delete $2; delete $4; } test_case_list : test_case { DEBUG() << "Test case with comma\n"; $$ = new std::set<std::string*>(); $$->insert($1); } | test_case_list ',' test_case { DEBUG() << "Test case with list\n"; $$ = $1; $$->insert($3); } test_case : STRING { DEBUG() << "Test Case: name=" << *$1 << "\n"; $$ = $1; } struct_definition : STRUCT IDENTIFIER '{' field_definition_list '}' { Loading Loading @@ -340,7 +390,7 @@ packet_definition auto parent_packet = decls->GetPacketDef(parent_packet_name); if (parent_packet == nullptr) { ERRORLOC(LOC) << "Could not find packet " << parent_packet_name << " used as parent for " << packet_name; << " used as parent for " << packet_name << "\n"; } auto packet_definition = new PacketDef(std::move(packet_name), std::move(field_definition_list), parent_packet); Loading
system/gd/packet/parser/packet_def.cc +68 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include "packet_def.h" #include <iomanip> #include <list> #include <set> Loading Loading @@ -1217,19 +1218,81 @@ void PacketDef::GenRustBuilderStructImpls(std::ostream& s) const { s << "}\n"; s << "}\n"; lineage = GetAncestors(); for (auto it = lineage.begin(); it != lineage.end(); it++) { auto def = *it; s << "impl Into<" << def->name_ << "Packet> for " << name_ << "Builder {"; s << " fn into(self) -> " << def->name_ << "Packet { self.build().into() }"; for (const auto ancestor : GetAncestors()) { s << "impl Into<" << ancestor->name_ << "Packet> for " << name_ << "Builder {"; s << " fn into(self) -> " << ancestor->name_ << "Packet { self.build().into() }"; s << "}\n"; } } void PacketDef::GenRustBuilderTest(std::ostream& s) const { auto lineage = GetAncestors(); lineage.push_back(this); if (!lineage.empty() && !test_cases_.empty()) { s << "macro_rules! " << util::CamelCaseToUnderScore(name_) << "_builder_tests { "; s << "($($name:ident: $byte_string:expr,)*) => {"; s << "$("; s << "\n#[test]\n"; s << "pub fn $name() { "; s << "let raw_bytes = $byte_string;"; for (size_t i = 0; i < lineage.size(); i++) { s << "/* (" << i << ") */\n"; if (i == 0) { s << "match " << lineage[i]->name_ << "Packet::parse(raw_bytes) {"; s << "Ok(" << util::CamelCaseToUnderScore(lineage[i]->name_) << "_packet) => {"; s << "match " << util::CamelCaseToUnderScore(lineage[i]->name_) << "_packet.specialize() {"; } else if (i != lineage.size() - 1) { s << lineage[i - 1]->name_ << "Child::" << lineage[i]->name_ << "("; s << util::CamelCaseToUnderScore(lineage[i]->name_) << "_packet) => {"; s << "match " << util::CamelCaseToUnderScore(lineage[i]->name_) << "_packet.specialize() {"; } else { s << lineage[i - 1]->name_ << "Child::" << lineage[i]->name_ << "(packet) => {"; s << "let rebuilder = " << lineage[i]->name_ << "Builder {"; FieldList params = GetParamList().GetFieldsWithoutTypes({ BodyField::kFieldType, }); for (const auto param : params) { s << param->GetName() << " : packet." << util::CamelCaseToUnderScore(param->GetGetterFunctionName()) << "(),"; } s << "};"; s << "let rebuilder_base : " << lineage[0]->name_ << "Packet = rebuilder.into();"; s << "let rebuilder_bytes : &[u8] = &rebuilder_base.to_bytes();"; s << "assert_eq!(rebuilder_bytes, raw_bytes);"; s << "}"; } } for (size_t i = 1; i < lineage.size(); i++) { s << "_ => {"; s << "println!(\"Couldn't parse " << util::CamelCaseToUnderScore(lineage[lineage.size() - i]->name_); s << "{:02x?}\", " << util::CamelCaseToUnderScore(lineage[lineage.size() - i - 1]->name_) << "_packet); "; s << "}}}"; } s << ","; s << "Err(e) => panic!(\"could not parse " << lineage[0]->name_ << ": {:?} {:02x?}\", e, raw_bytes),"; s << "}"; s << "}"; s << ")*"; s << "}"; s << "}"; s << util::CamelCaseToUnderScore(name_) << "_builder_tests! { "; int number = 0; for (const auto& test_case : test_cases_) { s << util::CamelCaseToUnderScore(name_) << "_builder_test_"; s << std::setfill('0') << std::setw(2) << number++ << ": "; s << "b\"" << test_case << "\","; } s << "}"; s << "\n"; } } void PacketDef::GenRustDef(std::ostream& s) const { GenRustChildEnums(s); GenRustStructDeclarations(s); GenRustStructImpls(s); GenRustAccessStructImpls(s); GenRustBuilderStructImpls(s); GenRustBuilderTest(s); }