face: refactor NullFace as LinkService+Transport

refs #3278

Change-Id: I424f70f9402823d58d097671bab8c0c2dc4f2d3b
diff --git a/daemon/face/null-face.cpp b/daemon/face/null-face.cpp
index 5d55693..2c409a7 100644
--- a/daemon/face/null-face.cpp
+++ b/daemon/face/null-face.cpp
@@ -1,12 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014,  Regents of the University of California,
- *                      Arizona Board of Regents,
- *                      Colorado State University,
- *                      University Pierre & Marie Curie, Sorbonne University,
- *                      Washington University in St. Louis,
- *                      Beijing Institute of Technology,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -24,31 +24,26 @@
  */
 
 #include "null-face.hpp"
+#include "lp-face-wrapper.hpp"
+#include "generic-link-service.hpp"
+#include "internal-transport.hpp"
 
 namespace nfd {
+namespace face {
 
-// FIB might restrict creating a nexthop record toward non-local face in /localhost namespace.
-// NullFace has isLocal=true to enable creating a "blackhole" FIB entry under /localhost.
+// FIB could restrict creating a nexthop record toward non-local face in /localhost namespace.
+// NullFace has scope=local to enable creating a "blackhole" FIB entry under /localhost.
 
-NullFace::NullFace(const FaceUri& uri)
-  : Face(uri, uri, true)
+shared_ptr<Face>
+makeNullFace(const FaceUri& uri)
 {
+  auto face = make_unique<LpFace>(make_unique<GenericLinkService>(),
+                                  make_unique<InternalForwarderTransport>(uri, uri, ndn::nfd::FACE_SCOPE_LOCAL));
+  auto faceW = make_shared<LpFaceWrapper>(std::move(face));
+  // TODO#3172 eliminate wrapper
+
+  return faceW;
 }
 
-void
-NullFace::sendInterest(const Interest& interest)
-{
-}
-
-void
-NullFace::sendData(const Data& data)
-{
-}
-
-void
-NullFace::close()
-{
-  this->fail("close");
-}
-
+} // namespace face
 } // namespace nfd
diff --git a/daemon/face/null-face.hpp b/daemon/face/null-face.hpp
index a4e3977..a07b26c 100644
--- a/daemon/face/null-face.hpp
+++ b/daemon/face/null-face.hpp
@@ -1,12 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014,  Regents of the University of California,
- *                      Arizona Board of Regents,
- *                      Colorado State University,
- *                      University Pierre & Marie Curie, Sorbonne University,
- *                      Washington University in St. Louis,
- *                      Beijing Institute of Technology,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -29,26 +29,14 @@
 #include "face.hpp"
 
 namespace nfd {
+namespace face {
 
-/**
- * \brief a Face that has no underlying transport and drops every packet
+/** \return a Face that has no underlying transport and drops every packet
  */
-class NullFace : public Face
-{
-public:
-  explicit
-  NullFace(const FaceUri& uri = FaceUri("null://"));
+shared_ptr<Face>
+makeNullFace(const FaceUri& uri = FaceUri("null://"));
 
-  void
-  sendInterest(const Interest& interest) DECL_OVERRIDE;
-
-  void
-  sendData(const Data& data) DECL_OVERRIDE;
-
-  void
-  close() DECL_OVERRIDE;
-};
-
+} // namespace face
 } // namespace nfd
 
 #endif // NFD_DAEMON_FACE_NULL_FACE_HPP
diff --git a/daemon/nfd.cpp b/daemon/nfd.cpp
index 2676a3a..bcc5926 100644
--- a/daemon/nfd.cpp
+++ b/daemon/nfd.cpp
@@ -90,9 +90,9 @@
 
   initializeManagement();
 
-  m_forwarder->getFaceTable().addReserved(make_shared<NullFace>(), FACEID_NULL);
-  m_forwarder->getFaceTable().addReserved(make_shared<NullFace>(FaceUri("contentstore://")),
-                                          FACEID_CONTENT_STORE);
+  FaceTable& faceTable = m_forwarder->getFaceTable();
+  faceTable.addReserved(face::makeNullFace(), FACEID_NULL);
+  faceTable.addReserved(face::makeNullFace(FaceUri("contentstore://")), FACEID_CONTENT_STORE);
 
   PrivilegeHelper::drop();
 
diff --git a/tests/daemon/face/null-face.t.cpp b/tests/daemon/face/null-face.t.cpp
index 83dfbf4..fbc5312 100644
--- a/tests/daemon/face/null-face.t.cpp
+++ b/tests/daemon/face/null-face.t.cpp
@@ -24,17 +24,36 @@
  */
 
 #include "face/null-face.hpp"
+#include "face/lp-face-wrapper.hpp"
+#include "transport-properties.hpp"
 
 #include "tests/test-common.hpp"
 
 namespace nfd {
+namespace face {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(FaceNullFace, BaseFixture)
+using namespace nfd::tests;
+
+BOOST_AUTO_TEST_SUITE(Face)
+BOOST_FIXTURE_TEST_SUITE(TestNullFace, BaseFixture)
+
+using nfd::Face;
+
+BOOST_AUTO_TEST_CASE(StaticProperties)
+{
+  shared_ptr<Face> faceW = makeNullFace(FaceUri("testnull://hhppt12sy"));
+  LpFace* face = static_pointer_cast<LpFaceWrapper>(faceW)->getLpFace();
+  checkStaticPropertiesInitialized(*face->getTransport());
+
+  BOOST_CHECK_EQUAL(face->getLocalUri(), FaceUri("testnull://hhppt12sy"));
+  BOOST_CHECK_EQUAL(face->getRemoteUri(), FaceUri("testnull://hhppt12sy"));
+  BOOST_CHECK_EQUAL(face->getScope(), ndn::nfd::FACE_SCOPE_LOCAL);
+}
 
 BOOST_AUTO_TEST_CASE(Send)
 {
-  shared_ptr<NullFace> face = make_shared<NullFace>();
+  shared_ptr<Face> face = makeNullFace();
 
   shared_ptr<Interest> interest = makeInterest("/A");
   BOOST_CHECK_NO_THROW(face->sendInterest(*interest));
@@ -45,7 +64,9 @@
   BOOST_CHECK_NO_THROW(face->close());
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestNullFace
+BOOST_AUTO_TEST_SUITE_END() // Face
 
 } // namespace tests
+} // namespace face
 } // namespace nfd