face: use ndn-cxx's RttEstimator in LpReliability

Refs: #4887
Change-Id: Iaf8b04e33de363bae2c99f10f3866773c900f30d
diff --git a/daemon/face/lp-reliability.cpp b/daemon/face/lp-reliability.cpp
index f19f713..4489f6c 100644
--- a/daemon/face/lp-reliability.cpp
+++ b/daemon/face/lp-reliability.cpp
@@ -36,7 +36,6 @@
   , m_linkService(linkService)
   , m_firstUnackedFrag(m_unackedFrags.begin())
   , m_lastTxSeqNo(-1) // set to "-1" to start TxSequence numbers at 0
-  , m_isIdleAckTimerRunning(false)
 {
   BOOST_ASSERT(m_linkService != nullptr);
   BOOST_ASSERT(m_options.idleAckTimerPeriod > 0_ns);
@@ -48,7 +47,7 @@
   BOOST_ASSERT(options.idleAckTimerPeriod > 0_ns);
 
   if (m_options.isEnabled && !options.isEnabled) {
-    this->stopIdleAckTimer();
+    m_idleAckTimer.cancel();
   }
 
   m_options = options;
@@ -81,7 +80,7 @@
                                                  std::forward_as_tuple(txSeq),
                                                  std::forward_as_tuple(frag));
     unackedFragsIt->second.sendTime = sendTime;
-    unackedFragsIt->second.rtoTimer = getScheduler().schedule(m_rto.computeRto(),
+    unackedFragsIt->second.rtoTimer = getScheduler().schedule(m_rttEst.getEstimatedRto(),
                                                               [=] { onLpPacketLost(txSeq); });
     unackedFragsIt->second.netPkt = netPkt;
 
@@ -114,8 +113,8 @@
     frag.rtoTimer.cancel();
 
     if (frag.retxCount == 0) {
-      // This sequence had no retransmissions, so use it to calculate the RTO
-      m_rto.addMeasurement(time::duration_cast<RttEstimator::Duration>(now - frag.sendTime));
+      // This sequence had no retransmissions, so use it to estimate the RTO
+      m_rttEst.addMeasurement(now - frag.sendTime, 1);
     }
 
     // Look for frags with TxSequence numbers < ackSeq (allowing for wraparound) and consider them
@@ -136,7 +135,7 @@
     // Resend or fail fragments considered lost. Potentially increment the start of the window.
     for (lp::Sequence txSeq : lostLpPackets) {
       if (removedLpPackets.find(txSeq) == removedLpPackets.end()) {
-        auto removedThisTxSeq = this->onLpPacketLost(txSeq);
+        auto removedThisTxSeq = onLpPacketLost(txSeq);
         for (auto removedTxSeq : removedThisTxSeq) {
           removedLpPackets.insert(removedTxSeq);
         }
@@ -147,9 +146,7 @@
   // If packet has Fragment and TxSequence fields, extract TxSequence and add to AckQueue
   if (pkt.has<lp::FragmentField>() && pkt.has<lp::TxSequenceField>()) {
     m_ackQueue.push(pkt.get<lp::TxSequenceField>());
-    if (!m_isIdleAckTimerRunning) {
-      this->startIdleAckTimer();
-    }
+    startIdleAckTimer();
   }
 }
 
@@ -168,7 +165,7 @@
 
   while (!m_ackQueue.empty()) {
     lp::Sequence ackSeq = m_ackQueue.front();
-    // Ack size = Ack TLV-TYPE (3 octets) + TLV-LENGTH (1 octet) + uint64_t (8 octets)
+    // Ack size = Ack TLV-TYPE (3 octets) + TLV-LENGTH (1 octet) + lp::Sequence (8 octets)
     const ssize_t ackSize = tlv::sizeOfVarNumber(lp::tlv::Ack) +
                             tlv::sizeOfVarNumber(sizeof(lp::Sequence)) +
                             sizeof(lp::Sequence);
@@ -197,25 +194,18 @@
 void
 LpReliability::startIdleAckTimer()
 {
-  BOOST_ASSERT(!m_isIdleAckTimerRunning);
-  m_isIdleAckTimerRunning = true;
+  if (m_idleAckTimer) {
+    // timer is already running, do nothing
+    return;
+  }
 
   m_idleAckTimer = getScheduler().schedule(m_options.idleAckTimerPeriod, [this] {
     while (!m_ackQueue.empty()) {
       m_linkService->requestIdlePacket(0);
     }
-
-    m_isIdleAckTimerRunning = false;
   });
 }
 
-void
-LpReliability::stopIdleAckTimer()
-{
-  m_idleAckTimer.cancel();
-  m_isIdleAckTimerRunning = false;
-}
-
 std::vector<lp::Sequence>
 LpReliability::findLostLpPackets(LpReliability::UnackedFrags::iterator ackIt)
 {
@@ -305,7 +295,8 @@
     m_linkService->sendLpPacket(lp::Packet(newTxFrag.pkt), 0);
 
     // Start RTO timer for this sequence
-    newTxFrag.rtoTimer = getScheduler().schedule(m_rto.computeRto(), [=] { onLpPacketLost(newTxSeq); });
+    newTxFrag.rtoTimer = getScheduler().schedule(m_rttEst.getEstimatedRto(),
+                                                 [=] { onLpPacketLost(newTxSeq); });
   }
 
   return removedThisTxSeq;
diff --git a/daemon/face/lp-reliability.hpp b/daemon/face/lp-reliability.hpp
index 5018730..ca8f360 100644
--- a/daemon/face/lp-reliability.hpp
+++ b/daemon/face/lp-reliability.hpp
@@ -26,10 +26,11 @@
 #ifndef NFD_DAEMON_FACE_LP_RELIABILITY_HPP
 #define NFD_DAEMON_FACE_LP_RELIABILITY_HPP
 
-#include "core/rtt-estimator.hpp"
+#include "core/common.hpp"
 
 #include <ndn-cxx/lp/packet.hpp>
 #include <ndn-cxx/lp/sequence.hpp>
+#include <ndn-cxx/util/rtt-estimator.hpp>
 
 #include <queue>
 
@@ -126,11 +127,6 @@
   void
   startIdleAckTimer();
 
-  /** \brief cancel the idle Ack timer
-   */
-  void
-  stopIdleAckTimer();
-
   /** \brief find and mark as lost fragments where a configurable number of Acks
    *         (\p m_options.seqNumLossThreshold) have been received for greater TxSequence numbers
    *  \param ackIt iterator pointing to acknowledged fragment
@@ -198,8 +194,10 @@
   };
 
 public:
-  /// TxSequence TLV-TYPE (3 octets) + TxSequence TLV-LENGTH (1 octet) + sizeof(lp::Sequence)
-  static constexpr size_t RESERVED_HEADER_SPACE = 3 + 1 + sizeof(lp::Sequence);
+  /// TxSequence TLV-TYPE (3 octets) + TLV-LENGTH (1 octet) + lp::Sequence (8 octets)
+  static constexpr size_t RESERVED_HEADER_SPACE = tlv::sizeOfVarNumber(lp::tlv::TxSequence) +
+                                                  tlv::sizeOfVarNumber(sizeof(lp::Sequence)) +
+                                                  sizeof(lp::Sequence);
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   Options m_options;
@@ -214,8 +212,7 @@
   std::queue<lp::Sequence> m_ackQueue;
   lp::Sequence m_lastTxSeqNo;
   scheduler::ScopedEventId m_idleAckTimer;
-  bool m_isIdleAckTimerRunning;
-  RttEstimator m_rto;
+  ndn::util::RttEstimator m_rttEst;
 };
 
 } // namespace face
diff --git a/tests/daemon/face/lp-reliability.t.cpp b/tests/daemon/face/lp-reliability.t.cpp
index 5e73c03..e814042 100644
--- a/tests/daemon/face/lp-reliability.t.cpp
+++ b/tests/daemon/face/lp-reliability.t.cpp
@@ -40,8 +40,6 @@
 
 using namespace nfd::tests;
 
-BOOST_AUTO_TEST_SUITE(Face)
-
 class DummyLpReliabilityLinkService : public GenericLinkService
 {
 public:
@@ -58,11 +56,11 @@
       Interest interest("/test/prefix");
       interest.setCanBePrefix(false);
       lp::Packet pkt;
-      pkt.add<lp::FragmentField>(make_pair(interest.wireEncode().begin(), interest.wireEncode().end()));
+      pkt.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
       m_reliability.handleOutgoing(frags, std::move(pkt), true);
     }
 
-    for (lp::Packet frag : frags) {
+    for (auto frag : frags) {
       this->sendLpPacket(std::move(frag), 0);
     }
   }
@@ -116,9 +114,7 @@
   netPktHasUnackedFrag(const shared_ptr<LpReliability::NetPkt>& netPkt, lp::Sequence txSeq)
   {
     return std::any_of(netPkt->unackedFrags.begin(), netPkt->unackedFrags.end(),
-                       [txSeq] (const LpReliability::UnackedFrags::iterator& frag) {
-                         return frag->first == txSeq;
-                       });
+                       [txSeq] (auto fragIt) { return fragIt->first == txSeq; });
   }
 
   /** \brief make an LpPacket with fragment of specified size
@@ -134,7 +130,7 @@
     lp::Packet pkt;
     ndn::Buffer buf(payloadSize);
     std::memcpy(buf.data(), &pktNo, sizeof(pktNo));
-    pkt.set<lp::FragmentField>(make_pair(buf.cbegin(), buf.cend()));
+    pkt.set<lp::FragmentField>({buf.cbegin(), buf.cend()});
     return pkt;
   }
 
@@ -164,6 +160,7 @@
   LpReliability* reliability;
 };
 
+BOOST_AUTO_TEST_SUITE(Face)
 BOOST_FIXTURE_TEST_SUITE(TestLpReliability, LpReliabilityFixture)
 
 BOOST_AUTO_TEST_CASE(SendNoFragmentField)
@@ -715,7 +712,7 @@
 
 BOOST_AUTO_TEST_CASE(ProcessIncomingPacket)
 {
-  BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(!reliability->m_idleAckTimer);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
 
   lp::Packet pkt1 = makeFrag(100, 40);
@@ -723,7 +720,7 @@
 
   reliability->processIncomingPacket(pkt1);
 
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
   BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 1);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
 
@@ -732,14 +729,14 @@
 
   reliability->processIncomingPacket(pkt2);
 
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
   BOOST_REQUIRE_EQUAL(reliability->m_ackQueue.size(), 2);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 765432);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 234567);
 
   // T+5ms
   advanceClocks(1_ms, 5);
-  BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(!reliability->m_idleAckTimer);
 }
 
 BOOST_AUTO_TEST_CASE(PiggybackAcks)
@@ -820,38 +817,38 @@
 
 BOOST_AUTO_TEST_CASE(StartIdleAckTimer)
 {
-  BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(!reliability->m_idleAckTimer);
 
   lp::Packet pkt1 = makeFrag(1, 100);
   pkt1.add<lp::TxSequenceField>(12);
   reliability->processIncomingPacket({pkt1});
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
 
   // T+1ms
   advanceClocks(1_ms, 1);
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
 
   lp::Packet pkt2 = makeFrag(2, 100);
   pkt2.add<lp::TxSequenceField>(13);
   reliability->processIncomingPacket({pkt2});
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
 
   // T+5ms
   advanceClocks(1_ms, 4);
-  BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(!reliability->m_idleAckTimer);
 
   lp::Packet pkt3 = makeFrag(3, 100);
   pkt3.add<lp::TxSequenceField>(15);
   reliability->processIncomingPacket({pkt3});
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
 
   // T+9ms
   advanceClocks(1_ms, 4);
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
 
   // T+10ms
   advanceClocks(1_ms, 1);
-  BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(!reliability->m_idleAckTimer);
 }
 
 BOOST_AUTO_TEST_CASE(IdleAckTimer)
@@ -862,13 +859,13 @@
     reliability->m_ackQueue.push(i);
     expectedAcks.insert(i);
   }
-  BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(!reliability->m_idleAckTimer);
   reliability->startIdleAckTimer();
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
 
   // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
   advanceClocks(1_ms, 4);
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
@@ -876,7 +873,7 @@
 
   // T+5ms: idle ack timer expires, IDLE packet generated
   advanceClocks(1_ms, 1);
-  BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(!reliability->m_idleAckTimer);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
   BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
 
@@ -898,13 +895,13 @@
     reliability->m_ackQueue.push(i);
     expectedAcks.insert(i);
   }
-  BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(!reliability->m_idleAckTimer);
   reliability->startIdleAckTimer();
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
 
   // T+4ms: idle ack timer has not yet expired, no IDLE packet generated
   advanceClocks(1_ms, 4);
-  BOOST_CHECK(reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(reliability->m_idleAckTimer);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 500);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.front(), 1000);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.back(), 1499);
@@ -912,7 +909,7 @@
 
   // T+5ms: idle ack timer expires, IDLE packets generated
   advanceClocks(1_ms, 1);
-  BOOST_CHECK(!reliability->m_isIdleAckTimerRunning);
+  BOOST_CHECK(!reliability->m_idleAckTimer);
   BOOST_CHECK_EQUAL(reliability->m_ackQueue.size(), 0);
 
   // MTU is 1500. LpPacket TL occupies 4 octets. Each Ack header is 12 octets. There are room for