management: Finalizing LocalControlHeader implementation

IncomingFaceId and NextHopFaceId are now fully supported for specifying
to be efficiently sent towards the forwarding daemon, and to be
automatically decoded from incoming packet from the forwarding daemon.

The current implementation limits exactly one LocalControlHeader for
Interest/Data packet instance. This is not exactly correct (especially
inside NFD), where the same Interest is expected to have multiple
LocalControlHeader (for each individual local face).  The following
commits will fix this problem.

Change-Id: Ia6b124ed12271136d071f4822f13634897ce3228
refs: #1170
diff --git a/src/face.cpp b/src/face.cpp
index aef13af..3f95cf9 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -17,7 +17,6 @@
 
 #include "management/ndnd-controller.hpp"
 #include "management/nfd-controller.hpp"
-#include "encoding/tlv-nfd-control.hpp"
 
 namespace ndn {
 
@@ -100,13 +99,13 @@
 }
 
 void
-Face::asyncExpressInterest(const shared_ptr<const Interest> &interest,
+Face::asyncExpressInterest(const shared_ptr<const Interest>& interest,
                            const OnData& onData, const OnTimeout& onTimeout)
 {
   m_pendingInterestTable.push_back(shared_ptr<PendingInterest>(new PendingInterest
-                                                              (interest, onData, onTimeout)));
+                                                               (interest, onData, onTimeout)));
 
-  m_transport->send(interest->wireEncode());
+  m_transport->send(interest->getLocalControlHeader().wireEncode(*interest));
 
   if (!m_pitTimeoutCheckTimerActive) {
     m_pitTimeoutCheckTimerActive = true;
@@ -120,12 +119,11 @@
 {
   if (!m_transport->isConnected())
     m_transport->connect(*m_ioService,
-                        bind(&Face::onReceiveElement, this, _1));
+                         bind(&Face::onReceiveElement, this, _1));
 
-  m_transport->send(data.wireEncode());
+  m_transport->send(data.getLocalControlHeader().wireEncode(data));
 }
 
-
 void
 Face::removePendingInterest(const PendingInterestId *pendingInterestId)
 {
@@ -289,18 +287,16 @@
 
 
 void
-Face::onReceiveElement(const Block &blockFromDaemon)
+Face::onReceiveElement(const Block& blockFromDaemon)
 {
-  Block block = blockFromDaemon;
-  uint64_t incomingFaceId = std::numeric_limits<uint64_t>::max();
-  if (block.type() == tlv::nfd_control::LocalControlHeader)
-    block = wireDecodeLocalControlHeader(block, incomingFaceId);
-  
+  const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
+
   if (block.type() == Tlv::Interest)
     {
       shared_ptr<Interest> interest(new Interest());
       interest->wireDecode(block);
-      interest->setIncomingFaceId(incomingFaceId);
+      if (&block != &blockFromDaemon)
+        interest->getLocalControlHeader().wireDecode(blockFromDaemon);
 
       RegisteredPrefixTable::iterator entry = getEntryForRegisteredPrefix(interest->getName());
       if (entry != m_registeredPrefixTable.end()) {
@@ -311,7 +307,8 @@
     {
       shared_ptr<Data> data(new Data());
       data->wireDecode(block);
-      data->setIncomingFaceId(incomingFaceId);
+      if (&block != &blockFromDaemon)
+        data->getLocalControlHeader().wireDecode(blockFromDaemon);
 
       PendingInterestTable::iterator entry = getEntryIndexForExpressedInterest(data->getName());
       if (entry != m_pendingInterestTable.end()) {
@@ -369,42 +366,4 @@
   return longestPrefix;
 }
 
-Block
-Face::wireEncodeLocalControlHeader(const Block& blockWithoutHeader, uint64_t nextHopFaceId)
-{
-  Block localControlHeader = Block(tlv::nfd_control::LocalControlHeader);
-  Block localControlInfo = Block(tlv::nfd_control::LocalControlInfo);
-
-  localControlInfo.push_back
-    (nonNegativeIntegerBlock(tlv::nfd_control::NextHopFaceId, nextHopFaceId));
-
-  localControlHeader.push_back(localControlInfo);
-  localControlHeader.push_back(blockWithoutHeader);
-
-  localControlHeader.encode();
-  return localControlHeader;
-}
-
-Block
-Face::wireDecodeLocalControlHeader(const Block& blockWithHeader, uint64_t& incomingFaceId)
-{
-  blockWithHeader.parse();
-  if (blockWithHeader.elements_size() != 2 ||
-      blockWithHeader.elements_begin()->type() != tlv::nfd_control::LocalControlInfo)
-    {
-      return Block();
-    }
-
-  const Block& localControlInfo = *blockWithHeader.elements_begin();
-  localControlInfo.parse();
-
-  Block::element_const_iterator i = localControlInfo.find(tlv::nfd_control::IncomingFaceId);
-  if (i != localControlInfo.elements_end())
-    {
-      incomingFaceId = readNonNegativeInteger(*i);
-    }
-
-  return *blockWithHeader.elements().rbegin();
-}
-
 } // namespace ndn