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

Commit 107159fb authored by Myles Watson's avatar Myles Watson
Browse files

packet: Support fixed-width custom types

Test: bluetooth_packet_parser_test --gtest_filter=*testChildWithAddress*
Change-Id: I73ff7962d99f668b4cbf1b4068bf74d069b9f599
parent 4f3cea53
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ cc_test {
    ],
    host_supported: true,
    srcs: [
        ":BluetoothCommonSources",
        ":BluetoothPacketSources",
        ":BluetoothPacketParserTestPacketTestSources",
    ],
+1 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ class Iterator : public std::iterator<std::random_access_iterator_tag, uint8_t>
  // Get the next sizeof(FixedWidthPODType) bytes and return the filled type
  template <typename FixedWidthPODType>
  FixedWidthPODType extract() {
    static_assert(std::is_pod<FixedWidthPODType>::value, "Iterator::extract requires an fixed type.");
    static_assert(std::is_pod<FixedWidthPODType>::value, "Iterator::extract requires a fixed-width type.");
    FixedWidthPODType extracted_value;
    uint8_t* value_ptr = (uint8_t*)&extracted_value;

+9 −23
Original line number Diff line number Diff line
@@ -22,8 +22,6 @@
#include <memory>
#include <vector>

#include "common/address.h"
#include "common/class_of_device.h"
#include "os/log.h"
#include "packet/base_packet_builder.h"
#include "packet/bit_inserter.h"
@@ -44,21 +42,21 @@ class PacketBuilder : public BasePacketBuilder {

 protected:
  // Write sizeof(FixedWidthIntegerType) bytes using the iterator
  template <typename FixedWidthIntegerType,
            typename std::enable_if<std::is_integral<FixedWidthIntegerType>::value, int>::type = 0>
  void insert(FixedWidthIntegerType value, BitInserter& it) const {
    for (size_t i = 0; i < sizeof(FixedWidthIntegerType); i++) {
  template <typename FixedWidthPODType, typename std::enable_if<std::is_pod<FixedWidthPODType>::value, int>::type = 0>
  void insert(FixedWidthPODType value, BitInserter& it) const {
    uint8_t* raw_bytes = (uint8_t*)&value;
    for (size_t i = 0; i < sizeof(FixedWidthPODType); i++) {
      if (little_endian == true) {
        it.insert_byte(static_cast<uint8_t>(value >> (i * 8)));
        it.insert_byte(raw_bytes[i]);
      } else {
        it.insert_byte(static_cast<uint8_t>(value >> ((sizeof(FixedWidthIntegerType) - i - 1) * 8)));
        it.insert_byte(raw_bytes[sizeof(FixedWidthPODType) - i - 1]);
      }
    }
  }

  // Write num_bits bits using the iterator
  template <typename FixedWidthIntegerType,
            typename std::enable_if<std::is_integral<FixedWidthIntegerType>::value, int>::type = 0>
            typename std::enable_if<std::is_pod<FixedWidthIntegerType>::value, int>::type = 0>
  void insert(FixedWidthIntegerType value, BitInserter& it, size_t num_bits) const {
    ASSERT(num_bits <= (sizeof(FixedWidthIntegerType) * 8));

@@ -85,24 +83,12 @@ class PacketBuilder : public BasePacketBuilder {
  // Write a vector of FixedWidthIntegerType using the iterator
  template <typename FixedWidthIntegerType>
  void insert_vector(const std::vector<FixedWidthIntegerType>& vec, BitInserter& it) const {
    static_assert(std::is_integral<FixedWidthIntegerType>::value,
                  "PacketBuilder::insert requires an integral type vector.");
    static_assert(std::is_pod<FixedWidthIntegerType>::value,
                  "PacketBuilder::insert requires a vector with elements of a fixed-size.");
    for (const auto& element : vec) {
      insert(element, it);
    }
  }

  void insert_address(const common::Address& addr, BitInserter& it) const {
    for (const auto& element : addr.address) {
      insert(element, it);
    }
  }

  void insert_class_of_device(const common::ClassOfDevice& cod, BitInserter& it) const {
    for (const auto& element : cod.cod) {
      insert(element, it);
    }
  }
};

}  // namespace packet
+2 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ cc_binary_host {
  name: "bluetooth_packetgen",
  srcs: [
    "fields/body_field.cc",
    "fields/custom_field.cc",
    "fields/enum_field.cc",
    "fields/fixed_field.cc",
    "fields/group_field.cc",
@@ -10,6 +11,7 @@ cc_binary_host {
    "fields/reserved_field.cc",
    "fields/scalar_field.cc",
    "fields/size_field.cc",
    "custom_field_def.cc",
    "enum_def.cc",
    "enum_gen.cc",
    "packet_def.cc",
+48 −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 "custom_field_def.h"

#include "util.h"

CustomFieldDef::CustomFieldDef(std::string name, std::string include, int size)
    : TypeDef(name, size), include_(include) {
  if (size % 8 != 0) {
    ERROR() << "Custom fields must be byte aligned.";
  }
}

CustomField* CustomFieldDef::GetCustomField(std::string name, ParseLocation loc) const {
  return new CustomField(name, name_, size_, loc);
}

void CustomFieldDef::GenInclude(std::ostream& s) const {
  s << "#include \"" << include_ << util::CamelCaseToUnderScore(GetTypeName()) << ".h\"\n";
}

void CustomFieldDef::GenUsing(std::ostream& s) const {
  s << "using ::bluetooth::";
  for (const auto& c : include_) {
    switch (c) {
      case '/':
        s << "::";
        break;
      default:
        s << c;
    }
  }
  s << GetTypeName() << ";";
}
Loading