model+helper: Converting L3Protocol and StackHelper to use NFD codebase
diff --git a/model/ndn-l3-protocol.cpp b/model/ndn-l3-protocol.cpp
index 4ea8189..f383477 100644
--- a/model/ndn-l3-protocol.cpp
+++ b/model/ndn-l3-protocol.cpp
@@ -1,4 +1,4 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:ni -*- */
 /*
  * Copyright (c) 2011 University of California, Los Angeles
  *
@@ -33,10 +33,24 @@
 #include "ns3/random-variable.h"
 
 #include "ndn-face.hpp"
+
 #include "ndn-net-device-face.hpp"
+#include "../helper/ndn-stack-helper.hpp"
 
 #include <boost/foreach.hpp>
 
+#include "ns3/ndnSIM/NFD/daemon/fw/forwarder.hpp"
+#include "ns3/ndnSIM/NFD/daemon/mgmt/internal-face.hpp"
+#include "ns3/ndnSIM/NFD/daemon/mgmt/fib-manager.hpp"
+#include "ns3/ndnSIM/NFD/daemon/mgmt/face-manager.hpp"
+#include "ns3/ndnSIM/NFD/daemon/mgmt/strategy-choice-manager.hpp"
+#include "ns3/ndnSIM/NFD/daemon/mgmt/status-server.hpp"
+
+#include "ns3/ndnSIM/NFD/daemon/face/null-face.hpp"
+#include "ns3/ndnSIM/NFD/core/config-file.hpp"
+#include "ns3/ndnSIM/NFD/daemon/mgmt/general-config-section.hpp"
+#include "ns3/ndnSIM/NFD/daemon/mgmt/tables-config-section.hpp"
+
 NS_LOG_COMPONENT_DEFINE("ndn.L3Protocol");
 
 namespace ns3 {
@@ -55,14 +69,34 @@
       .SetGroupName("ndn")
       .SetParent<Object>()
       .AddConstructor<L3Protocol>()
-    ;
-      // .AddAttribute("FaceList", "List of faces associated with ndn stack", ObjectVectorValue(),
-      //               MakeObjectVectorAccessor(&L3Protocol::m_faces),
-      //               MakeObjectVectorChecker<Face>());
+
+      .AddTraceSource("OutInterests", "OutInterests",
+                      MakeTraceSourceAccessor(&L3Protocol::m_outInterests))
+      .AddTraceSource("InInterests", "InInterests",
+                      MakeTraceSourceAccessor(&L3Protocol::m_inInterests))
+
+      ////////////////////////////////////////////////////////////////////
+
+      .AddTraceSource("OutData", "OutData", MakeTraceSourceAccessor(&L3Protocol::m_outData))
+      .AddTraceSource("InData", "InData", MakeTraceSourceAccessor(&L3Protocol::m_inData));
   return tid;
 }
 
+class L3Protocol::Impl {
+private:
+  friend class L3Protocol;
+
+  shared_ptr<nfd::Forwarder> m_forwarder;
+
+  shared_ptr<nfd::InternalFace> m_internalFace;
+  shared_ptr<nfd::FibManager> m_fibManager;
+  shared_ptr<nfd::FaceManager> m_faceManager;
+  shared_ptr<nfd::StrategyChoiceManager> m_strategyChoiceManager;
+  shared_ptr<nfd::StatusServer> m_statusServer;
+};
+
 L3Protocol::L3Protocol()
+  : m_impl(new Impl())
 {
   NS_LOG_FUNCTION(this);
 }
@@ -72,6 +106,75 @@
   NS_LOG_FUNCTION(this);
 }
 
+void
+L3Protocol::initialize()
+{
+  m_impl->m_forwarder = make_shared<nfd::Forwarder>();
+
+  initializeManagement();
+
+  m_impl->m_forwarder->getFaceTable().addReserved(make_shared<nfd::NullFace>(), nfd::FACEID_NULL);
+  m_impl->m_forwarder->getFaceTable().addReserved(make_shared<nfd::NullFace>(
+                                                    FaceUri("contentstore://")),
+                                                  nfd::FACEID_CONTENT_STORE);
+}
+
+void
+L3Protocol::initializeManagement()
+{
+  m_impl->m_internalFace = make_shared<nfd::InternalFace>();
+
+  m_impl->m_fibManager =
+    make_shared<nfd::FibManager>(ref(m_impl->m_forwarder->getFib()),
+                                 bind(&nfd::Forwarder::getFace, m_impl->m_forwarder.get(), _1),
+                                 m_impl->m_internalFace, std::ref(StackHelper::getKeyChain()));
+
+  m_impl->m_faceManager =
+    make_shared<nfd::FaceManager>(ref(m_impl->m_forwarder->getFaceTable()), m_impl->m_internalFace,
+                                  std::ref(StackHelper::getKeyChain()));
+
+  m_impl->m_strategyChoiceManager =
+    make_shared<nfd::StrategyChoiceManager>(ref(m_impl->m_forwarder->getStrategyChoice()),
+                                            m_impl->m_internalFace,
+                                            std::ref(StackHelper::getKeyChain()));
+
+  m_impl->m_statusServer =
+    make_shared<nfd::StatusServer>(m_impl->m_internalFace, ref(*m_impl->m_forwarder),
+                                   std::ref(StackHelper::getKeyChain()));
+
+  nfd::TablesConfigSection tablesConfig(m_impl->m_forwarder->getCs(),
+                                        m_impl->m_forwarder->getPit(),
+                                        m_impl->m_forwarder->getFib(),
+                                        m_impl->m_forwarder->getStrategyChoice(),
+                                        m_impl->m_forwarder->getMeasurements());
+
+  m_impl->m_forwarder->getFaceTable().addReserved(m_impl->m_internalFace,
+                                                  nfd::FACEID_INTERNAL_FACE);
+
+  // add FIB entry for NFD Management Protocol
+  shared_ptr<::nfd::fib::Entry> entry =
+    m_impl->m_forwarder->getFib().insert("/localhost/nfd").first;
+  entry->addNextHop(m_impl->m_internalFace, 0);
+}
+
+shared_ptr<nfd::Forwarder>
+L3Protocol::getForwarder()
+{
+  return m_impl->m_forwarder;
+}
+
+shared_ptr<nfd::FibManager>
+L3Protocol::getFibManager()
+{
+  return m_impl->m_fibManager;
+}
+
+shared_ptr<nfd::StrategyChoiceManager>
+L3Protocol::getStrategyChoiceManager()
+{
+  return m_impl->m_strategyChoiceManager;
+}
+
 /*
  * This method is called by AddAgregate and completes the aggregation
  * by setting the node in the ndn stack
@@ -79,14 +182,13 @@
 void
 L3Protocol::NotifyNewAggregate()
 {
-  // not really efficient, but this will work only once
-  if (m_node == 0) {
+  if (m_node == nullptr) {
     m_node = GetObject<Node>();
-    if (m_node != 0) {
+    if (m_node != nullptr) {
     }
   }
 
-  Object::NotifyNewAggregate ();
+  Object::NotifyNewAggregate();
 }
 
 void
@@ -99,43 +201,52 @@
   Object::DoDispose();
 }
 
-uint32_t
-L3Protocol::AddFace(const shared_ptr<Face>& face)
+nfd::FaceId
+L3Protocol::addFace(shared_ptr<Face> face)
 {
-  NS_LOG_FUNCTION(this << &face);
+  NS_LOG_FUNCTION(this << face.get());
 
-  return 0;
+  m_impl->m_forwarder->addFace(face);
+
+  // Connect Signals to TraceSource
+  face->onReceiveInterest +=
+    [this, face](const Interest& interest) { this->m_inInterests(interest, *face); };
+
+  face->onSendInterest +=
+    [this, face](const Interest& interest) { this->m_outInterests(interest, *face); };
+
+  face->onReceiveData += [this, face](const Data& data) { this->m_inData(data, *face); };
+
+  face->onSendData += [this, face](const Data& data) { this->m_outData(data, *face); };
+
+  return face->getId();
 }
 
-void
-L3Protocol::RemoveFace(shared_ptr<Face> face)
+// void
+// L3Protocol::removeFace(shared_ptr<Face> face)
+// {
+//   NS_LOG_FUNCTION(this << std::cref(*face));
+// }
+
+shared_ptr<Face>
+L3Protocol::getFaceById(nfd::FaceId id) const
 {
-  NS_LOG_FUNCTION(this << std::cref(*face));
+  return m_impl->m_forwarder->getFaceTable().get(id);
 }
 
 shared_ptr<Face>
-L3Protocol::GetFace(uint32_t index) const
+L3Protocol::getFaceByNetDevice(Ptr<NetDevice> netDevice) const
 {
-  return nullptr;
-}
+  for (const auto& i : m_impl->m_forwarder->getFaceTable()) {
+    shared_ptr<NetDeviceFace> netDeviceFace = std::dynamic_pointer_cast<NetDeviceFace>(i);
+    if (netDeviceFace == nullptr)
+      continue;
 
-shared_ptr<Face>
-L3Protocol::GetFaceById(uint32_t index) const
-{
+    if (netDeviceFace->GetNetDevice() == netDevice)
+      return i;
+  }
   return nullptr;
 }
 
-shared_ptr<Face>
-L3Protocol::GetFaceByNetDevice(Ptr<NetDevice> netDevice) const
-{
-  return nullptr;
-}
-
-uint32_t
-L3Protocol::GetNFaces(void) const
-{
-  return 0;
-}
-
 } // namespace ndn
 } // namespace ns3