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

Commit 3cfe4e40 authored by Ajay Panicker's avatar Ajay Panicker Committed by Myles Watson
Browse files

packet: Add the PDL Packet Generator

Test: bluetooth_packet_parser_test
Change-Id: Ia741e608aebff7b55d005a37e0f0eaeae63767a8
parent a16ac3f7
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -113,6 +113,27 @@ cc_test {
    },
}

cc_test {
    name: "bluetooth_packet_parser_test",
    test_suites: ["device-tests"],
    defaults: [
        "gd_defaults",
        "gd_clang_coverage_bin",
    ],
    host_supported: true,
    srcs: [
        ":BluetoothPacketSources",
        ":BluetoothPacketParserTestPacketTestSources",
    ],
    generated_headers : [
        "BluetoothPacketParserTestPacketPdlGen_h",
    ],
    sanitize: {
        address: true,
        cfi: true,
    },
}

cc_benchmark {
    name: "bluetooth_benchmark_gd",
    defaults: ["gd_defaults"],
+30 −0
Original line number Diff line number Diff line
cc_binary_host  {
  name: "bluetooth_packetgen",
  srcs: [
    "fields/body_field.cc",
    "fields/enum_field.cc",
    "fields/fixed_field.cc",
    "fields/group_field.cc",
    "fields/packet_field.cc",
    "fields/payload_field.cc",
    "fields/reserved_field.cc",
    "fields/scalar_field.cc",
    "fields/size_field.cc",
    "enum_def.cc",
    "enum_gen.cc",
    "packet_def.cc",
    "main.cc",
    "language_y.yy",
    "language_l.ll",
  ],

  cppflags: [
    "-Wno-implicit-fallthrough",
    "-fno-exceptions",
    "-O0",
  ],
  ldflags: [
    "-fuse-ld=ld",
    "-O0",
  ],
}
+43 −0
Original line number Diff line number Diff line
This file just contains some notes about the design and usage of the PDL language.

-------
 TERMS
-------
.pdl
  The file type that defines packet definitions. You may think of each pdl file
  as its own translation unit.

Packet Views and Builders
  Generated from a packet definition. Views are used to validate packets and
  extract the fields that are defined in the pdl file.  Builders check the input
  arguments and can be serialized.

-------------
 LIMITATIONS
-------------
  - Size fields for a variable length field MUST come before the definition
    of said field.

  - Payload fields must be byte-aligned unless they have an unknown size.
    Body fields are allowed to not be byte aligned.

  - No conditionals

  - Can not have to fields with the same name anywhere in the in an inheritence chain

  - Can't handle size for Body type fields yet since they might not be byte aligned.

-------
 NOTES
-------
All Field names should be in CamelCase. Field names matching type names is supported.

The payload keyword generates a getter but body doesn't. Therefore, a payload must be byte aligned.
Supports constraints on grandparents
Supports multiple constraints
Every field handles its own generation.
One pdl file will result in one header file with all the packets

Things to cover -
  Constraints
  Inheritence vs Contains
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <deque>
#include <map>
#include <optional>

#include "enum_def.h"
#include "enum_gen.h"
#include "packet_def.h"

class Declarations {
 public:
  void AddEnumDef(std::string name, EnumDef def) {
    enum_defs_.insert(std::pair(name, def));
    enum_defs_queue_.push_back(std::pair(name, def));
  }

  EnumDef* GetEnumDef(const std::string& name) {
    auto it = enum_defs_.find(name);
    if (it == enum_defs_.end()) {
      return nullptr;
    }

    return &(it->second);
  }

  void AddPacketDef(std::string name, PacketDef def) {
    packet_defs_.insert(std::pair(name, def));
    packet_defs_queue_.push_back(std::pair(name, def));
  }

  PacketDef* GetPacketDef(const std::string& name) {
    auto it = packet_defs_.find(name);
    if (it == packet_defs_.end()) {
      return nullptr;
    }

    return &(it->second);
  }

  void AddGroupDef(std::string name, FieldList* group_def) {
    group_defs_.insert(std::pair(name, group_def));
  }

  FieldList* GetGroupDef(std::string name) {
    if (group_defs_.find(name) == group_defs_.end()) {
      return nullptr;
    }

    return group_defs_.at(name);
  }

  std::map<std::string, FieldList*> group_defs_;

  std::map<std::string, EnumDef> enum_defs_;
  std::deque<std::pair<std::string, EnumDef>> enum_defs_queue_;
  std::map<std::string, PacketDef> packet_defs_;
  std::deque<std::pair<std::string, PacketDef>> packet_defs_queue_;
  bool is_little_endian;
};
+42 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "enum_def.h"

#include <iostream>
#include <map>

#include "util.h"

EnumDef::EnumDef(std::string name, int size) : name_(name), size_(size){};

void EnumDef::AddEntry(std::string name, uint32_t value) {
  if (value > util::GetMaxValueForBits(size_)) {
    std::cerr << __func__ << ": Value provided is greater than max possible value for enum. " << name_ << "\n";
    abort();
  }

  constants_.insert(std::pair(value, name));
  entries_.insert(name);
}

bool EnumDef::HasEntry(std::string name) const {
  return entries_.count(name) != 0;
}

std::string EnumDef::GetTypeName() const {
  return name_;
}
Loading