[ndnSIM] face: Emulation mode of ndn::Face

Change-Id: Ib345978575104afa436296d2f5a824a39e3a9780
diff --git a/src/face.cpp b/src/face.cpp
index 98581b3..433453c 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -20,6 +20,10 @@
  */
 
 #include "face.hpp"
+
+#include "ns3/log.h"
+NS_LOG_COMPONENT_DEFINE("ndn-cxx.Face");
+
 #include "detail/face-impl.hpp"
 
 #include "encoding/tlv.hpp"
@@ -29,106 +33,28 @@
 #include "util/random.hpp"
 #include "util/face-uri.hpp"
 
+#include "ns3/ndnSIM/helper/ndn-stack-helper.hpp"
+
 namespace ndn {
 
 Face::Face()
-  : m_internalIoService(new boost::asio::io_service())
-  , m_ioService(*m_internalIoService)
-  , m_internalKeyChain(new KeyChain())
-  , m_impl(new Impl(*this))
+  : m_impl(new Impl(*this))
 {
-  construct(*m_internalKeyChain);
+  construct();
 }
 
-Face::Face(boost::asio::io_service& ioService)
-  : m_ioService(ioService)
-  , m_internalKeyChain(new KeyChain())
-  , m_impl(new Impl(*this))
+Face::Face(boost::asio::io_service&)
+  : m_impl(new Impl(*this))
 {
-  construct(*m_internalKeyChain);
-}
-
-Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
-  : m_internalIoService(new boost::asio::io_service())
-  , m_ioService(*m_internalIoService)
-  , m_internalKeyChain(new KeyChain())
-  , m_impl(new Impl(*this))
-{
-  construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
-}
-
-Face::Face(const shared_ptr<Transport>& transport)
-  : m_internalIoService(new boost::asio::io_service())
-  , m_ioService(*m_internalIoService)
-  , m_internalKeyChain(new KeyChain())
-  , m_impl(new Impl(*this))
-{
-  construct(transport, *m_internalKeyChain);
-}
-
-Face::Face(const shared_ptr<Transport>& transport,
-           boost::asio::io_service& ioService)
-  : m_ioService(ioService)
-  , m_internalKeyChain(new KeyChain())
-  , m_impl(new Impl(*this))
-{
-  construct(transport, *m_internalKeyChain);
-}
-
-Face::Face(shared_ptr<Transport> transport,
-           boost::asio::io_service& ioService,
-           KeyChain& keyChain)
-  : m_ioService(ioService)
-  , m_internalKeyChain(nullptr)
-  , m_impl(new Impl(*this))
-{
-  construct(transport, keyChain);
+  construct();
 }
 
 void
-Face::construct(KeyChain& keyChain)
+Face::construct()
 {
-  // transport=unix:///var/run/nfd.sock
-  // transport=tcp://localhost:6363
+  static ::ndn::KeyChain keyChain("pib-dummy", "tpm-dummy");
 
-  ConfigFile config;
-  const auto& transportType = config.getParsedConfiguration()
-                                .get_optional<std::string>("transport");
-  if (!transportType) {
-    // transport not specified, use default Unix transport.
-    construct(UnixTransport::create(config), keyChain);
-    return;
-  }
-
-  unique_ptr<util::FaceUri> uri;
-  try {
-    uri.reset(new util::FaceUri(*transportType));
-  }
-  catch (const util::FaceUri::Error& error) {
-    BOOST_THROW_EXCEPTION(ConfigFile::Error(error.what()));
-  }
-
-  const std::string protocol = uri->getScheme();
-
-  if (protocol == "unix") {
-    construct(UnixTransport::create(config), keyChain);
-  }
-  else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6") {
-    construct(TcpTransport::create(config), keyChain);
-  }
-  else {
-    BOOST_THROW_EXCEPTION(ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\""));
-  }
-}
-
-void
-Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
-{
-  m_nfdController.reset(new nfd::Controller(*this, keyChain));
-
-  m_transport = transport;
-
-  m_impl->ensureConnected(false);
+  m_nfdController.reset(new nfd::Controller(*this, ns3::ndn::StackHelper::getKeyChain()));
 }
 
 Face::~Face() = default;
@@ -136,14 +62,12 @@
 const PendingInterestId*
 Face::expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout)
 {
+  NS_LOG_INFO (">> Interest: " << interest.getName());
+
   shared_ptr<Interest> interestToExpress = make_shared<Interest>(interest);
-
-  // Use `interestToExpress` to avoid wire format creation for the original Interest
-  if (interestToExpress->wireEncode().size() > MAX_NDN_PACKET_SIZE)
-    BOOST_THROW_EXCEPTION(Error("Interest size exceeds maximum limit"));
-
-  // If the same ioService thread, dispatch directly calls the method
-  m_ioService.dispatch([=] { m_impl->asyncExpressInterest(interestToExpress, onData, onTimeout); });
+  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] {
+      m_impl->asyncExpressInterest(interestToExpress, onData, onTimeout);
+    });
 
   return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
 }
@@ -154,36 +78,37 @@
                       const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
 {
   return expressInterest(Interest(tmpl)
-                         .setName(name)
-                         .setNonce(0),
+                           .setName(name)
+                           .setNonce(0),
                          onData, onTimeout);
 }
 
 void
 Face::put(const Data& data)
 {
-  // Use original `data`, since wire format should already exist for the original Data
-  if (data.wireEncode().size() > MAX_NDN_PACKET_SIZE)
-    BOOST_THROW_EXCEPTION(Error("Data size exceeds maximum limit"));
+  NS_LOG_INFO (">> Data: " << data.getName());
 
   shared_ptr<const Data> dataPtr;
   try {
     dataPtr = data.shared_from_this();
   }
   catch (const bad_weak_ptr& e) {
-    std::cerr << "Face::put WARNING: the supplied Data should be created using make_shared<Data>()"
-              << std::endl;
+    NS_LOG_INFO("Face::put WARNING: the supplied Data should be created using make_shared<Data>()");
     dataPtr = make_shared<Data>(data);
   }
 
-  // If the same ioService thread, dispatch directly calls the method
-  m_ioService.dispatch([=] { m_impl->asyncPutData(dataPtr); });
+  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] {
+      m_impl->asyncPutData(dataPtr);
+    });
 }
 
 void
 Face::removePendingInterest(const PendingInterestId* pendingInterestId)
 {
-  m_ioService.post([=] { m_impl->asyncRemovePendingInterest(pendingInterestId); });
+  m_impl->m_scheduler.scheduleEvent(time::seconds(0),
+                                    [=] {
+                                      m_impl->asyncRemovePendingInterest(pendingInterestId);
+                                    });
 }
 
 size_t
@@ -194,46 +119,49 @@
 
 const RegisteredPrefixId*
 Face::setInterestFilter(const InterestFilter& interestFilter,
-                  const OnInterest& onInterest,
-                  const RegisterPrefixFailureCallback& onFailure,
-                  const security::SigningInfo& signingInfo,
-                  uint64_t flags)
+                        const OnInterest& onInterest,
+                        const RegisterPrefixFailureCallback& onFailure,
+                        const security::SigningInfo& signingInfo,
+                        uint64_t flags)
 {
-    return setInterestFilter(interestFilter,
-                             onInterest,
-                             RegisterPrefixSuccessCallback(),
-                             onFailure,
-                             signingInfo,
-                             flags);
+  return setInterestFilter(interestFilter,
+                           onInterest,
+                           RegisterPrefixSuccessCallback(),
+                           onFailure,
+                           signingInfo,
+                           flags);
 }
 
 const RegisteredPrefixId*
 Face::setInterestFilter(const InterestFilter& interestFilter,
-                  const OnInterest& onInterest,
-                  const RegisterPrefixSuccessCallback& onSuccess,
-                  const RegisterPrefixFailureCallback& onFailure,
-                  const security::SigningInfo& signingInfo,
-                  uint64_t flags)
+                        const OnInterest& onInterest,
+                        const RegisterPrefixSuccessCallback& onSuccess,
+                        const RegisterPrefixFailureCallback& onFailure,
+                        const security::SigningInfo& signingInfo,
+                        uint64_t flags)
 {
-    shared_ptr<InterestFilterRecord> filter =
-      make_shared<InterestFilterRecord>(interestFilter, onInterest);
+  shared_ptr<InterestFilterRecord> filter =
+    make_shared<InterestFilterRecord>(interestFilter, onInterest);
 
-    nfd::CommandOptions options;
-    options.setSigningInfo(signingInfo);
+  nfd::CommandOptions options;
+  options.setSigningInfo(signingInfo);
 
-    return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
-                                  onSuccess, onFailure,
-                                  flags, options);
+  return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
+                                onSuccess, onFailure,
+                                flags, options);
 }
 
 const InterestFilterId*
 Face::setInterestFilter(const InterestFilter& interestFilter,
                         const OnInterest& onInterest)
 {
+  NS_LOG_INFO("Set Interest Filter << " << interestFilter);
+
   shared_ptr<InterestFilterRecord> filter =
     make_shared<InterestFilterRecord>(interestFilter, onInterest);
 
-  getIoService().post([=] { m_impl->asyncSetInterestFilter(filter); });
+  m_impl->m_scheduler.scheduleEvent(time::seconds(0),
+                                    [=] { m_impl->asyncSetInterestFilter(filter); });
 
   return reinterpret_cast<const InterestFilterId*>(filter.get());
 }
@@ -304,21 +232,22 @@
 
 const RegisteredPrefixId*
 Face::registerPrefix(const Name& prefix,
-               const RegisterPrefixSuccessCallback& onSuccess,
-               const RegisterPrefixFailureCallback& onFailure,
-               const security::SigningInfo& signingInfo,
-               uint64_t flags)
+                     const RegisterPrefixSuccessCallback& onSuccess,
+                     const RegisterPrefixFailureCallback& onFailure,
+                     const security::SigningInfo& signingInfo,
+                     uint64_t flags)
 {
 
-    nfd::CommandOptions options;
-    options.setSigningInfo(signingInfo);
+  nfd::CommandOptions options;
+  options.setSigningInfo(signingInfo);
 
-    return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
-                                  onSuccess, onFailure,
-                                  flags, options);
+  return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
+                                onSuccess, onFailure,
+                                flags, options);
 }
 
 #ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
+
 const RegisteredPrefixId*
 Face::registerPrefix(const Name& prefix,
                      const RegisterPrefixSuccessCallback& onSuccess,
@@ -350,15 +279,18 @@
 void
 Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
 {
-  m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,
-                                                       UnregisterPrefixSuccessCallback(),
-                                                       UnregisterPrefixFailureCallback()); });
+  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] {
+      m_impl->asyncUnregisterPrefix(registeredPrefixId,
+                                    UnregisterPrefixSuccessCallback(),
+                                    UnregisterPrefixFailureCallback()); });
 }
 
 void
 Face::unsetInterestFilter(const InterestFilterId* interestFilterId)
 {
-  m_ioService.post([=] { m_impl->asyncUnsetInterestFilter(interestFilterId); });
+  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] {
+      m_impl->asyncUnsetInterestFilter(interestFilterId);
+    });
 }
 
 void
@@ -366,89 +298,26 @@
                        const UnregisterPrefixSuccessCallback& onSuccess,
                        const UnregisterPrefixFailureCallback& onFailure)
 {
-  m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,onSuccess, onFailure); });
+  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] {
+      m_impl->asyncUnregisterPrefix(registeredPrefixId,onSuccess, onFailure);
+    });
 }
 
 void
 Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
                     bool keepThread/* = false*/)
 {
-  if (m_ioService.stopped()) {
-    m_ioService.reset(); // ensure that run()/poll() will do some work
-  }
-
-  try {
-    if (timeout < time::milliseconds::zero()) {
-        // do not block if timeout is negative, but process pending events
-        m_ioService.poll();
-        return;
-      }
-
-    if (timeout > time::milliseconds::zero()) {
-      boost::asio::io_service& ioService = m_ioService;
-      unique_ptr<boost::asio::io_service::work>& work = m_impl->m_ioServiceWork;
-      m_impl->m_processEventsTimeoutEvent =
-        m_impl->m_scheduler.scheduleEvent(timeout, [&ioService, &work] {
-            ioService.stop();
-            work.reset();
-          });
-    }
-
-    if (keepThread) {
-      // work will ensure that m_ioService is running until work object exists
-      m_impl->m_ioServiceWork.reset(new boost::asio::io_service::work(m_ioService));
-    }
-
-    m_ioService.run();
-  }
-  catch (...) {
-    m_impl->m_ioServiceWork.reset();
-    m_impl->m_pendingInterestTable.clear();
-    m_impl->m_registeredPrefixTable.clear();
-    throw;
-  }
 }
 
 void
 Face::shutdown()
 {
-  m_ioService.post([this] { this->asyncShutdown(); });
-}
+  m_impl->m_scheduler.scheduleEvent(time::seconds(0), [=] {
+      m_impl->m_pendingInterestTable.clear();
+      m_impl->m_registeredPrefixTable.clear();
 
-void
-Face::asyncShutdown()
-{
-  m_impl->m_pendingInterestTable.clear();
-  m_impl->m_registeredPrefixTable.clear();
-
-  if (m_transport->isConnected())
-    m_transport->close();
-
-  m_impl->m_ioServiceWork.reset();
-}
-
-void
-Face::onReceiveElement(const Block& blockFromDaemon)
-{
-  const Block& block = nfd::LocalControlHeader::getPayload(blockFromDaemon);
-
-  if (block.type() == tlv::Interest)
-    {
-      shared_ptr<Interest> interest = make_shared<Interest>(block);
-      if (&block != &blockFromDaemon)
-        interest->getLocalControlHeader().wireDecode(blockFromDaemon);
-
-      m_impl->processInterestFilters(*interest);
-    }
-  else if (block.type() == tlv::Data)
-    {
-      shared_ptr<Data> data = make_shared<Data>(block);
-      if (&block != &blockFromDaemon)
-        data->getLocalControlHeader().wireDecode(blockFromDaemon);
-
-      m_impl->satisfyPendingInterests(*data);
-    }
-  // ignore any other type
+      m_impl->m_nfdFace->close();
+    });
 }
 
 } // namespace ndn