face: face refactoring completion

* delete old Face
* rename LpFace as Face
* eliminate LpFaceWrapper and use new Face

refs #3172

Change-Id: I08c3a5dfb4cc1b9834b30cccd9ab634535d0608c
diff --git a/daemon/face/face.hpp b/daemon/face/face.hpp
index d964ef1..d783dd0 100644
--- a/daemon/face/face.hpp
+++ b/daemon/face/face.hpp
@@ -23,27 +23,23 @@
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef NFD_DAEMON_FACE_FACE_HPP
-#define NFD_DAEMON_FACE_FACE_HPP
+#ifndef NFD_DAEMON_FACE_HPP
+#define NFD_DAEMON_FACE_HPP
 
-#include "common.hpp"
-#include "core/logger.hpp"
+#include "transport.hpp"
+#include "link-service.hpp"
 #include "face-counters.hpp"
-#include "old-face-counters.hpp"
 #include "face-log.hpp"
 
-#include <ndn-cxx/management/nfd-face-status.hpp>
-
 namespace nfd {
+namespace face {
 
-/** \class FaceId
- *  \brief identifies a face
+/** \brief identifies a face
  */
-typedef int FaceId;
+typedef uint64_t FaceId;
 
 /// indicates an invalid FaceId
-const FaceId INVALID_FACEID = -1;
-
+const FaceId INVALID_FACEID = 0;
 /// identifies the InternalFace used in management
 const FaceId FACEID_INTERNAL_FACE = 1;
 /// identifies a packet comes from the ContentStore
@@ -53,169 +49,169 @@
 /// upper bound of reserved FaceIds
 const FaceId FACEID_RESERVED_MAX = 255;
 
-
-/** \brief represents a face
+/** \brief indicates the state of a face
  */
-class Face : noncopyable, public enable_shared_from_this<Face>
+typedef TransportState FaceState;
+
+/** \brief generalization of a network interface
+ *
+ *  A face generalizes a network interface.
+ *  It provides best-effort network-layer packet delivery services
+ *  on a physical interface, an overlay tunnel, or a link to a local application.
+ *
+ *  A face combines two parts: LinkService and Transport.
+ *  Transport is the lower part, which provides best-effort TLV block deliveries.
+ *  LinkService is the upper part, which translates between network-layer packets
+ *  and TLV blocks, and may provide additional services such as fragmentation and reassembly.
+ */
+class Face
+#ifndef WITH_TESTS
+DECL_CLASS_FINAL
+#endif
+  : public enable_shared_from_this<Face>, noncopyable
 {
 public:
-  /**
-   * \brief Face-related error
+  Face(unique_ptr<LinkService> service, unique_ptr<Transport> transport);
+
+  LinkService*
+  getLinkService();
+
+  Transport*
+  getTransport();
+
+public: // upper interface connected to forwarding
+  /** \brief sends Interest on Face
    */
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
+  void
+  sendInterest(const Interest& interest);
 
-  Face(const FaceUri& remoteUri, const FaceUri& localUri,
-       bool isLocal = false, bool isMultiAccess = false);
-
-  virtual
-  ~Face();
-
-  /// fires when an Interest is received
-  signal::Signal<Face, Interest> onReceiveInterest;
-
-  /// fires when a Data is received
-  signal::Signal<Face, Data> onReceiveData;
-
-  /// fires when a Nack is received
-  signal::Signal<Face, lp::Nack> onReceiveNack;
-
-  /// fires when an Interest is sent out
-  signal::Signal<Face, Interest> onSendInterest;
-
-  /// fires when a Data is sent out
-  signal::Signal<Face, Data> onSendData;
-
-  /// fires when a Nack is sent out
-  signal::Signal<Face, lp::Nack> onSendNack;
-
-  /// fires when face disconnects or fails to perform properly
-  signal::Signal<Face, std::string/*reason*/> onFail;
-
-  /// send an Interest
-  virtual void
-  sendInterest(const Interest& interest) = 0;
-
-  /// send a Data
-  virtual void
-  sendData(const Data& data) = 0;
-
-  /// send a Nack
-  virtual void
-  sendNack(const ndn::lp::Nack& nack)
-  {
-  }
-
-  /** \brief Close the face
-   *
-   *  This terminates all communication on the face and cause
-   *  onFail() method event to be invoked
+  /** \brief sends Data on Face
    */
-  virtual void
-  close() = 0;
+  void
+  sendData(const Data& data);
 
-public: // attributes
+  /** \brief sends Nack on Face
+   */
+  void
+  sendNack(const lp::Nack& nack);
+
+  /** \brief signals on Interest received
+   */
+  signal::Signal<LinkService, Interest>& afterReceiveInterest;
+
+  /** \brief signals on Data received
+   */
+  signal::Signal<LinkService, Data>& afterReceiveData;
+
+  /** \brief signals on Nack received
+   */
+  signal::Signal<LinkService, lp::Nack>& afterReceiveNack;
+
+public: // static properties
+  /** \return face ID
+   */
   FaceId
   getId() const;
 
-  /** \brief Get the description
-   */
-  const std::string&
-  getDescription() const;
-
-  /** \brief Set the face description
-   *
-   *  This is typically invoked by management on set description command
+  /** \brief sets face ID
+   *  \note Normally, this should only be invoked by FaceTable.
    */
   void
-  setDescription(const std::string& description);
+  setId(FaceId id);
 
-  /** \brief Get whether face is connected to a local app
+  /** \return a FaceUri representing local endpoint
    */
-  bool
-  isLocal() const;
+  FaceUri
+  getLocalUri() const;
 
-  /** \brief Get the persistency setting
+  /** \return a FaceUri representing remote endpoint
+   */
+  FaceUri
+  getRemoteUri() const;
+
+  /** \return whether face is local or non-local for scope control purpose
+   */
+  ndn::nfd::FaceScope
+  getScope() const;
+
+  /** \return face persistency setting
    */
   ndn::nfd::FacePersistency
   getPersistency() const;
 
-  // 'virtual' to allow override in LpFaceWrapper
-  virtual void
-  setPersistency(ndn::nfd::FacePersistency persistency);
-
-  /** \brief Get whether packets sent by this face may reach multiple peers
-   */
-  bool
-  isMultiAccess() const;
-
-  /** \brief Get whether underlying communication is up
-   *
-   *  In this base class this property is always true.
-   */
-  virtual bool
-  isUp() const;
-
-  virtual const face::FaceCounters&
-  getCounters() const;
-
-  /** \return a FaceUri that represents the remote endpoint
-   */
-  const FaceUri&
-  getRemoteUri() const;
-
-  /** \return a FaceUri that represents the local endpoint (NFD side)
-   */
-  const FaceUri&
-  getLocalUri() const;
-
-protected:
-  bool
-  decodeAndDispatchInput(const Block& element);
-
-  /** \brief fail the face and raise onFail event if it's UP; otherwise do nothing
+  /** \brief changes face persistency setting
    */
   void
-  fail(const std::string& reason);
+  setPersistency(ndn::nfd::FacePersistency persistency);
 
-  OldFaceCounters&
-  getMutableCounters();
+  /** \return whether face is point-to-point or multi-access
+   */
+  ndn::nfd::LinkType
+  getLinkType() const;
 
-  DECLARE_SIGNAL_EMIT(onReceiveInterest)
-  DECLARE_SIGNAL_EMIT(onReceiveData)
-  DECLARE_SIGNAL_EMIT(onReceiveNack)
-  DECLARE_SIGNAL_EMIT(onSendInterest)
-  DECLARE_SIGNAL_EMIT(onSendData)
-  DECLARE_SIGNAL_EMIT(onSendNack)
+public: // dynamic properties
+  /** \return face state
+   */
+  FaceState
+  getState() const;
 
-  // this method should be used only by the FaceTable
-  // 'virtual' to allow override in LpFaceWrapper
-  virtual void
-  setId(FaceId faceId);
+  /** \brief signals after face state changed
+   */
+  signal::Signal<Transport, FaceState/*old*/, FaceState/*new*/>& afterStateChange;
+
+  /** \brief request the face to be closed
+   *
+   *  This operation is effective only if face is in UP or DOWN state,
+   *  otherwise it has no effect.
+   *  The face changes state to CLOSING, and performs cleanup procedure.
+   *  The state will be changed to CLOSED when cleanup is complete, which may
+   *  happen synchronously or asynchronously.
+   *
+   *  \warning the face must not be deallocated until its state changes to CLOSED
+   */
+  void
+  close();
+
+  const FaceCounters&
+  getCounters() const;
 
 private:
   FaceId m_id;
-  std::string m_description;
-  OldFaceCounters m_counters;
-  face::FaceCounters m_countersWrapper;
-  const FaceUri m_remoteUri;
-  const FaceUri m_localUri;
-  const bool m_isLocal;
-  ndn::nfd::FacePersistency m_persistency;
-  const bool m_isMultiAccess;
-  bool m_isFailed;
-
-  // allow setting FaceId
-  friend class FaceTable;
+  unique_ptr<LinkService> m_service;
+  unique_ptr<Transport> m_transport;
+  FaceCounters m_counters;
 };
 
+inline LinkService*
+Face::getLinkService()
+{
+  return m_service.get();
+}
+
+inline Transport*
+Face::getTransport()
+{
+  return m_transport.get();
+}
+
+inline void
+Face::sendInterest(const Interest& interest)
+{
+  m_service->sendInterest(interest);
+}
+
+inline void
+Face::sendData(const Data& data)
+{
+  m_service->sendData(data);
+}
+
+inline void
+Face::sendNack(const lp::Nack& nack)
+{
+  m_service->sendNack(nack);
+}
+
 inline FaceId
 Face::getId() const
 {
@@ -223,81 +219,80 @@
 }
 
 inline void
-Face::setId(FaceId faceId)
+Face::setId(FaceId id)
 {
-  m_id = faceId;
+  m_id = id;
 }
 
-inline const std::string&
-Face::getDescription() const
+inline FaceUri
+Face::getLocalUri() const
 {
-  return m_description;
+  return m_transport->getLocalUri();
 }
 
-inline void
-Face::setDescription(const std::string& description)
+inline FaceUri
+Face::getRemoteUri() const
 {
-  m_description = description;
+  return m_transport->getRemoteUri();
 }
 
-inline bool
-Face::isLocal() const
+inline ndn::nfd::FaceScope
+Face::getScope() const
 {
-  return m_isLocal;
+  return m_transport->getScope();
 }
 
 inline ndn::nfd::FacePersistency
 Face::getPersistency() const
 {
-  return m_persistency;
+  return m_transport->getPersistency();
 }
 
 inline void
 Face::setPersistency(ndn::nfd::FacePersistency persistency)
 {
-  m_persistency = persistency;
+  return m_transport->setPersistency(persistency);
 }
 
-inline bool
-Face::isMultiAccess() const
+inline ndn::nfd::LinkType
+Face::getLinkType() const
 {
-  return m_isMultiAccess;
+  return m_transport->getLinkType();
 }
 
-inline const face::FaceCounters&
+inline FaceState
+Face::getState() const
+{
+  return m_transport->getState();
+}
+
+inline void
+Face::close()
+{
+  m_transport->close();
+}
+
+inline const FaceCounters&
 Face::getCounters() const
 {
-  return m_countersWrapper;
-}
-
-inline OldFaceCounters&
-Face::getMutableCounters()
-{
   return m_counters;
 }
 
-inline const FaceUri&
-Face::getRemoteUri() const
-{
-  return m_remoteUri;
-}
-
-inline const FaceUri&
-Face::getLocalUri() const
-{
-  return m_localUri;
-}
+std::ostream&
+operator<<(std::ostream& os, const FaceLogHelper<Face>& flh);
 
 template<typename T>
 typename std::enable_if<std::is_base_of<Face, T>::value, std::ostream&>::type
-operator<<(std::ostream& os, const face::FaceLogHelper<T>& flh)
+operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
 {
-  const Face& face = flh.obj;
-  os << "[id=" << face.getId() << ",local=" << face.getLocalUri() <<
-        ",remote=" << face.getRemoteUri() << "] ";
-  return os;
+  return os << FaceLogHelper<Face>(flh.obj);
 }
 
+} // namespace face
+
+using face::FaceId;
+using face::Face;
+
 } // namespace nfd
 
-#endif // NFD_DAEMON_FACE_FACE_HPP
+#endif // NFD_DAEMON_FACE_HPP