Merge "Fix cert"
diff --git a/gd/packet/fragmenting_inserter_unittest.cc b/gd/packet/fragmenting_inserter_unittest.cc
index 6179959..c2f1124 100644
--- a/gd/packet/fragmenting_inserter_unittest.cc
+++ b/gd/packet/fragmenting_inserter_unittest.cc
@@ -91,6 +91,36 @@
   ASSERT_EQ(checksum, observer.GetValue());
 }
 
+TEST(FragmentingInserterTest, testMtuBoundaries) {
+  constexpr size_t kPacketSize = 1024;
+  auto counts = RawBuilder();
+  for (size_t i = 0; i < kPacketSize; i++) {
+    counts.AddOctets1(static_cast<uint8_t>(i));
+  }
+
+  std::vector<std::unique_ptr<RawBuilder>> fragments_mtu_is_kPacketSize;
+  FragmentingInserter it(kPacketSize, std::back_insert_iterator(fragments_mtu_is_kPacketSize));
+  counts.Serialize(it);
+  it.finalize();
+  ASSERT_EQ(1, fragments_mtu_is_kPacketSize.size());
+  ASSERT_EQ(kPacketSize, fragments_mtu_is_kPacketSize[0]->size());
+
+  std::vector<std::unique_ptr<RawBuilder>> fragments_mtu_is_less;
+  FragmentingInserter it_less(kPacketSize - 1, std::back_insert_iterator(fragments_mtu_is_less));
+  counts.Serialize(it_less);
+  it_less.finalize();
+  ASSERT_EQ(2, fragments_mtu_is_less.size());
+  ASSERT_EQ(kPacketSize - 1, fragments_mtu_is_less[0]->size());
+  ASSERT_EQ(1, fragments_mtu_is_less[1]->size());
+
+  std::vector<std::unique_ptr<RawBuilder>> fragments_mtu_is_more;
+  FragmentingInserter it_more(kPacketSize + 1, std::back_insert_iterator(fragments_mtu_is_more));
+  counts.Serialize(it_more);
+  it_more.finalize();
+  ASSERT_EQ(1, fragments_mtu_is_more.size());
+  ASSERT_EQ(kPacketSize, fragments_mtu_is_more[0]->size());
+}
+
 constexpr size_t kPacketSize = 128;
 class FragmentingTest : public ::testing::TestWithParam<size_t> {
  public:
diff --git a/gd/packet/parser/fields/custom_field_fixed_size.cc b/gd/packet/parser/fields/custom_field_fixed_size.cc
index 029f0aa..687d48d 100644
--- a/gd/packet/parser/fields/custom_field_fixed_size.cc
+++ b/gd/packet/parser/fields/custom_field_fixed_size.cc
@@ -55,6 +55,10 @@
   // Do nothing.
 }
 
+void CustomFieldFixedSize::GenInserter(std::ostream& s) const {
+  s << "insert(" << GetName() << "_, i);";
+}
+
 void CustomFieldFixedSize::GenValidator(std::ostream&) const {
   // Do nothing.
 }
diff --git a/gd/packet/parser/fields/custom_field_fixed_size.h b/gd/packet/parser/fields/custom_field_fixed_size.h
index bd19eb0..97acff9 100644
--- a/gd/packet/parser/fields/custom_field_fixed_size.h
+++ b/gd/packet/parser/fields/custom_field_fixed_size.h
@@ -37,6 +37,8 @@
 
   virtual void GenParameterValidator(std::ostream&) const override;
 
+  virtual void GenInserter(std::ostream& s) const override;
+
   virtual void GenValidator(std::ostream&) const override;
 
   std::string type_name_;
diff --git a/gd/packet/parser/fields/scalar_field.cc b/gd/packet/parser/fields/scalar_field.cc
index c6d2ecf..320534a 100644
--- a/gd/packet/parser/fields/scalar_field.cc
+++ b/gd/packet/parser/fields/scalar_field.cc
@@ -121,8 +121,6 @@
 void ScalarField::GenInserter(std::ostream& s) const {
   if (GetSize().bits() == 8) {
     s << "i.insert_byte(" << GetName() << "_);";
-  } else if (GetSize().bits() % 8 == 0) {
-    s << "insert(" << GetName() << "_, i);";
   } else {
     s << "insert(" << GetName() << "_, i," << GetSize().bits() << ");";
   }
diff --git a/gd/packet/parser/test/generated_packet_test.cc b/gd/packet/parser/test/generated_packet_test.cc
index 06f60b5..f8454a2 100644
--- a/gd/packet/parser/test/generated_packet_test.cc
+++ b/gd/packet/parser/test/generated_packet_test.cc
@@ -1825,6 +1825,58 @@
     ASSERT_EQ(ltv_vector[i].value_, an_array[i].value_);
   }
 }
+
+vector<uint8_t> byte_sized{
+    0x11,                                            // 1
+    0x21, 0x22,                                      // 2
+    0x31, 0x32, 0x33,                                // 3
+    0x41, 0x42, 0x43, 0x44,                          // 4
+    0x51, 0x52, 0x53, 0x54, 0x55,                    // 5
+    0x61, 0x62, 0x63, 0x64, 0x65, 0x66,              // 6
+    0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,        // 7
+    0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,  // 8
+};
+
+TEST(GeneratedPacketTest, testByteSizedFields) {
+  uint64_t array[9]{
+      0xbadbadbad,
+      0x11,                // 1
+      0x2221,              // 2
+      0x333231,            // 3
+      0x44434241,          // 4
+      0x5554535251,        // 5
+      0x666564636261,      // 6
+      0x77767574737271,    // 7
+      0x8887868584838281,  // 8
+  };
+  auto packet =
+      ByteSizedFieldsBuilder::Create(array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8]);
+  ASSERT_EQ(byte_sized.size(), packet->size());
+
+  std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
+  BitInserter it(*packet_bytes);
+  packet->Serialize(it);
+
+  ASSERT_EQ(byte_sized.size(), packet_bytes->size());
+  for (size_t i = 0; i < byte_sized.size(); i++) {
+    ASSERT_EQ(byte_sized[i], packet_bytes->at(i));
+  }
+
+  PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+  auto view = ByteSizedFieldsView::Create(packet_bytes_view);
+  ASSERT_TRUE(view.IsValid());
+  ASSERT_EQ(array[1], view.GetOne());
+  ASSERT_EQ(array[2], view.GetTwo());
+  ASSERT_EQ(array[3], view.GetThree());
+  ASSERT_EQ(array[4], view.GetFour());
+  ASSERT_EQ(array[5], view.GetFive());
+  ASSERT_EQ(array[6], view.GetSix());
+  ASSERT_EQ(array[7], view.GetSeven());
+  ASSERT_EQ(array[8], view.GetEight());
+}
+
+DEFINE_AND_INSTANTIATE_ByteSizedFieldsReflectionTest(byte_sized);
+
 }  // namespace parser
 }  // namespace packet
 }  // namespace bluetooth
diff --git a/gd/packet/parser/test/test_packets.pdl b/gd/packet/parser/test/test_packets.pdl
index 3c24509..2b612cc 100644
--- a/gd/packet/parser/test/test_packets.pdl
+++ b/gd/packet/parser/test/test_packets.pdl
@@ -394,3 +394,14 @@
   one_array : LengthTypeValueStruct[],
   _padding_[40],
 }
+
+packet ByteSizedFields {
+  one : 8,
+  two : 16,
+  three : 24,
+  four : 32,
+  five : 40,
+  six : 48,
+  seven : 56,
+  eight : 64,
+}
diff --git a/gd/packet/raw_builder.cc b/gd/packet/raw_builder.cc
index ec5159b..ec2ff68 100644
--- a/gd/packet/raw_builder.cc
+++ b/gd/packet/raw_builder.cc
@@ -17,6 +17,7 @@
 #include "packet/raw_builder.h"
 
 #include <algorithm>
+#include <utility>
 
 #include "os/log.h"
 
@@ -27,7 +28,7 @@
 namespace packet {
 
 RawBuilder::RawBuilder(size_t max_bytes) : max_bytes_(max_bytes) {}
-RawBuilder::RawBuilder(std::vector<uint8_t> vec) : max_bytes_(vec.size()), payload_(vec) {}
+RawBuilder::RawBuilder(std::vector<uint8_t> vec) : payload_(std::move(vec)) {}
 
 bool RawBuilder::AddOctets(size_t octets, const vector<uint8_t>& bytes) {
   if (payload_.size() + octets > max_bytes_) return false;
diff --git a/gd/packet/raw_builder.h b/gd/packet/raw_builder.h
index 9b0e959..1c9552a 100644
--- a/gd/packet/raw_builder.h
+++ b/gd/packet/raw_builder.h
@@ -64,7 +64,7 @@
   // - the new size of the payload is still <= |max_bytes_|
   bool AddOctets(size_t octets, uint64_t value);
 
-  size_t max_bytes_{255};
+  size_t max_bytes_{0xffff};
 
   // Underlying containers for storing the actual packet
   std::vector<uint8_t> payload_;
diff --git a/gd/packet/raw_builder_unittest.cc b/gd/packet/raw_builder_unittest.cc
index 5210fb6..64ca0ed 100644
--- a/gd/packet/raw_builder_unittest.cc
+++ b/gd/packet/raw_builder_unittest.cc
@@ -65,5 +65,48 @@
   ASSERT_EQ(count, packet);
 }
 
+TEST(RawBuilderTest, buildStartingWithVector) {
+  std::vector<uint8_t> count_first(count.begin(), count.begin() + 0x8);
+  std::unique_ptr<RawBuilder> count_builder = std::make_unique<RawBuilder>(count_first);
+  count_builder->AddOctets4(0x0b0a0908);
+  count_builder->AddOctets2(0x0d0c);
+  count_builder->AddOctets1(0x0e);
+  count_builder->AddOctets1(0x0f);
+  count_builder->AddOctets8(0x1716151413121110);
+  std::vector<uint8_t> count_last(count.begin() + 0x18, count.end());
+  count_builder->AddOctets(count_last);
+
+  ASSERT_EQ(count.size(), count_builder->size());
+
+  std::vector<uint8_t> packet;
+  BitInserter it(packet);
+
+  count_builder->Serialize(it);
+
+  ASSERT_EQ(count, packet);
+}
+
+TEST(RawBuilderTest, testMaxBytes) {
+  const size_t kMaxBytes = count.size();
+  std::unique_ptr<RawBuilder> count_builder = std::make_unique<RawBuilder>(kMaxBytes);
+  ASSERT_TRUE(count_builder->AddOctets(count));
+  ASSERT_FALSE(count_builder->AddOctets4(0x0b0a0908));
+  ASSERT_FALSE(count_builder->AddOctets2(0x0d0c));
+  ASSERT_FALSE(count_builder->AddOctets1(0x0e));
+  ASSERT_FALSE(count_builder->AddOctets1(0x0f));
+  ASSERT_FALSE(count_builder->AddOctets8(0x1716151413121110));
+  std::vector<uint8_t> count_last(count.begin() + 0x18, count.end());
+  ASSERT_FALSE(count_builder->AddOctets(count_last));
+
+  ASSERT_EQ(count.size(), count_builder->size());
+
+  std::vector<uint8_t> packet;
+  BitInserter it(packet);
+
+  count_builder->Serialize(it);
+
+  ASSERT_EQ(count, packet);
+}
+
 }  // namespace packet
 }  // namespace bluetooth