lp: add repeatable fields to a packet in the order they were added

refs #3931

Change-Id: I832252712ff45928ab50ff93f5b37bd44807662d
diff --git a/src/lp/packet.cpp b/src/lp/packet.cpp
index 7b71c72..c17f1bd 100644
--- a/src/lp/packet.cpp
+++ b/src/lp/packet.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -130,10 +130,10 @@
 }
 
 bool
-Packet::comparePos(const Block& first, const uint64_t second)
+Packet::comparePos(uint64_t first, const Block& second)
 {
-  detail::FieldInfo firstInfo(first.type());
-  detail::FieldInfo secondInfo(second);
+  detail::FieldInfo firstInfo(first);
+  detail::FieldInfo secondInfo(second.type());
   return detail::compareFieldSortOrder(firstInfo, secondInfo);
 }
 
diff --git a/src/lp/packet.hpp b/src/lp/packet.hpp
index bc35122..e43652d 100644
--- a/src/lp/packet.hpp
+++ b/src/lp/packet.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -165,10 +165,8 @@
     FIELD::encode(buffer, value);
     Block block = buffer.block();
 
-    Block::element_const_iterator pos = std::lower_bound(m_wire.elements_begin(),
-                                                         m_wire.elements_end(),
-                                                         FIELD::TlvType::value,
-                                                         comparePos);
+    auto pos = std::upper_bound(m_wire.elements_begin(), m_wire.elements_end(),
+                                FIELD::TlvType::value, comparePos);
     m_wire.insert(pos, block);
 
     return *this;
@@ -213,7 +211,7 @@
 
 private:
   static bool
-  comparePos(const Block& first, const uint64_t second);
+  comparePos(uint64_t first, const Block& second);
 
 private:
   mutable Block m_wire;
diff --git a/tests/unit-tests/lp/packet.t.cpp b/tests/unit-tests/lp/packet.t.cpp
index 2dd055e..7929487 100644
--- a/tests/unit-tests/lp/packet.t.cpp
+++ b/tests/unit-tests/lp/packet.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -102,11 +102,17 @@
 BOOST_AUTO_TEST_CASE(EncodeSortOrder)
 {
   static const uint8_t expectedBlock[] = {
-    0x64, 0x0a, // LpPacket
+    0x64, 0x19, // LpPacket
           0x52, 0x01, // FragIndex
                 0x00,
           0x53, 0x01, // FragCount
                 0x01,
+          0xfd, 0x03, 0x44, 0x01, // Ack
+                0x02,
+          0xfd, 0x03, 0x44, 0x01, // Ack
+                0x04,
+          0xfd, 0x03, 0x44, 0x01, // Ack
+                0x03,
           0x50, 0x02, // Fragment
                 0x03, 0xe8,
   };
@@ -118,7 +124,10 @@
   Packet packet;
   BOOST_CHECK_NO_THROW(packet.add<FragmentField>(std::make_pair(frag.begin(), frag.end())));
   BOOST_CHECK_NO_THROW(packet.add<FragIndexField>(0));
+  BOOST_CHECK_NO_THROW(packet.add<AckField>(2));
   BOOST_CHECK_NO_THROW(packet.add<FragCountField>(1));
+  BOOST_CHECK_NO_THROW(packet.add<AckField>(4));
+  BOOST_CHECK_NO_THROW(packet.add<AckField>(3));
   Block wire;
   BOOST_REQUIRE_NO_THROW(wire = packet.wireEncode());
   BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
@@ -220,6 +229,28 @@
   BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
 }
 
+BOOST_AUTO_TEST_CASE(DecodeRepeatedRepeatableHeader)
+{
+  static const uint8_t inputBlock[] = {
+    0x64, 0x0f, // LpPacket
+          0xfd, 0x03, 0x44, 0x01, // Ack
+                0x01,
+          0xfd, 0x03, 0x44, 0x01, // Ack
+                0x03,
+          0xfd, 0x03, 0x44, 0x01, // Ack
+                0x02,
+  };
+
+  Packet packet;
+  Block wire(inputBlock, sizeof(inputBlock));
+  BOOST_CHECK_NO_THROW(packet.wireDecode(wire));
+  BOOST_REQUIRE_EQUAL(packet.count<AckField>(), 3);
+  BOOST_CHECK_EQUAL(packet.get<AckField>(), 1);
+  BOOST_CHECK_EQUAL(packet.get<AckField>(0), 1);
+  BOOST_CHECK_EQUAL(packet.get<AckField>(1), 3);
+  BOOST_CHECK_EQUAL(packet.get<AckField>(2), 2);
+}
+
 BOOST_AUTO_TEST_CASE(DecodeRepeatedFragment)
 {
   static const uint8_t inputBlock[] = {