face: Implementing new "isOnDemand" flag

This flags replaces isPermanent flag in datagram faces, but with the
reversed logic (isPermanent = !isOnDemand)

Change-Id: I37ba604e5f105ca95a79a08b8cfc3d640df8b412
Refs: #1376
diff --git a/daemon/face/datagram-face.hpp b/daemon/face/datagram-face.hpp
index 4b75a0e..6a7accb 100644
--- a/daemon/face/datagram-face.hpp
+++ b/daemon/face/datagram-face.hpp
@@ -16,10 +16,17 @@
 {
 public:
   typedef T protocol;
-  
+
+  /** \brief Construct datagram face
+   *
+   * \param uri         FaceUri for the face
+   * \param socket      Protocol-specific socket for the created face
+   * \param isOnDemand  If true, the face can be closed after it remains
+   *                    unused for a certain amount of time.
+   */
   DatagramFace(const FaceUri& uri,
                const shared_ptr<typename protocol::socket>& socket,
-               bool isPermanent);
+               bool isOnDemand);
 
   virtual
   ~DatagramFace();
@@ -42,12 +49,6 @@
   handleReceive(const boost::system::error_code& error,
                 size_t nBytesReceived);
 
-  void
-  setPermanent(bool isPermanent);
-  
-  bool
-  isPermanent() const;
-
   /**
    * \brief Set m_hasBeenUsedRecently to false
    */
@@ -56,9 +57,11 @@
   
   bool
   hasBeenUsedRecently() const;
+
+  void
+  setOnDemand(bool isOnDemand);
   
 protected:
-
   void
   receiveDatagram(const uint8_t* buffer,
                   size_t nBytesReceived,
@@ -74,27 +77,21 @@
   shared_ptr<typename protocol::socket> m_socket;
   uint8_t m_inputBuffer[MAX_NDN_PACKET_SIZE];
 
-  /**
-   * If false, the face can be closed after it remains unused for a certain
-   * amount of time
-   */
-  bool m_isPermanent;
-  
   bool m_hasBeenUsedRecently;
 
   NFD_LOG_INCLASS_DECLARE();
-
 };
 
 template <class T>
 inline
 DatagramFace<T>::DatagramFace(const FaceUri& uri,
                               const shared_ptr<typename DatagramFace::protocol::socket>& socket,
-                              bool isPermanent)
+                              bool isOnDemand)
   : Face(uri)
   , m_socket(socket)
-  , m_isPermanent(isPermanent)
 {
+  setOnDemand(isOnDemand);
+
   m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
                           bind(&DatagramFace<T>::handleReceive, this, _1, _2));
 }
@@ -298,16 +295,9 @@
 
 template <class T>
 inline void
-DatagramFace<T>::setPermanent(bool isPermanent)
+DatagramFace<T>::setOnDemand(bool isOnDemand)
 {
-  m_isPermanent = isPermanent;
-}
-
-template <class T>
-inline bool
-DatagramFace<T>::isPermanent() const
-{
-  return m_isPermanent;
+  Face::setOnDemand(isOnDemand);
 }
 
 template <class T>
diff --git a/daemon/face/face.cpp b/daemon/face/face.cpp
index 1fb1109..08853aa 100644
--- a/daemon/face/face.cpp
+++ b/daemon/face/face.cpp
@@ -22,6 +22,7 @@
   : m_id(INVALID_FACEID)
   , m_isLocal(isLocal)
   , m_uri(uri)
+  , m_isOnDemand(false)
 {
   onReceiveInterest += bind(&increaseCounter<Interest>, _1, boost::ref(m_counters.getInInterest()));
   onReceiveData     += bind(&increaseCounter<Data>,     _1, boost::ref(m_counters.getInData()));
@@ -74,7 +75,7 @@
 Face::decodeAndDispatchInput(const Block& element)
 {
   /// \todo Ensure lazy field decoding process
-  
+
   if (element.type() == tlv::Interest)
     {
       shared_ptr<Interest> i = make_shared<Interest>();
@@ -89,7 +90,7 @@
     }
   else
     return false;
-  
+
   return true;
 }
 
diff --git a/daemon/face/face.hpp b/daemon/face/face.hpp
index 1efcb35..e1ef2f8 100644
--- a/daemon/face/face.hpp
+++ b/daemon/face/face.hpp
@@ -106,6 +106,11 @@
   virtual bool
   isUp() const;
 
+  /** \brief Get whether face is created on demand or explicitly via FaceManagement protocol
+   */
+  bool
+  isOnDemand() const;
+
   const FaceCounters&
   getCounters() const;
 
@@ -120,6 +125,9 @@
   FaceCounters&
   getMutableCounters();
 
+  void
+  setOnDemand(bool isOnDemand);
+
 private:
   void
   setId(FaceId faceId);
@@ -130,6 +138,7 @@
   bool m_isLocal; // for scoping purposes
   FaceCounters m_counters;
   FaceUri m_uri;
+  bool m_isOnDemand;
 
   // allow setting FaceId
   friend class FaceTable;
@@ -160,6 +169,18 @@
   return m_uri;
 }
 
+inline void
+Face::setOnDemand(bool isOnDemand)
+{
+  m_isOnDemand = isOnDemand;
+}
+
+inline bool
+Face::isOnDemand() const
+{
+  return m_isOnDemand;
+}
+
 } // namespace nfd
 
 #endif // NFD_FACE_FACE_HPP
diff --git a/daemon/face/multicast-udp-face.cpp b/daemon/face/multicast-udp-face.cpp
index 62b20eb..f0e752b 100644
--- a/daemon/face/multicast-udp-face.cpp
+++ b/daemon/face/multicast-udp-face.cpp
@@ -12,7 +12,7 @@
 
 
 MulticastUdpFace::MulticastUdpFace(const shared_ptr<MulticastUdpFace::protocol::socket>& socket)
-  : DatagramFace<protocol>(FaceUri(socket->local_endpoint()), socket, true)
+  : DatagramFace<protocol>(FaceUri(socket->local_endpoint()), socket, false)
 {
   NFD_LOG_DEBUG("Face creation. Multicast group: "
                 << m_socket->local_endpoint());
diff --git a/daemon/face/stream-face.hpp b/daemon/face/stream-face.hpp
index a623665..f6c008a 100644
--- a/daemon/face/stream-face.hpp
+++ b/daemon/face/stream-face.hpp
@@ -26,7 +26,8 @@
    */
   explicit
   StreamFace(const FaceUri& uri,
-             const shared_ptr<typename protocol::socket>& socket);
+             const shared_ptr<typename protocol::socket>& socket,
+             bool isOnDemand);
 
   virtual
   ~StreamFace();
@@ -99,11 +100,13 @@
 template<class T, class FaceBase>
 inline
 StreamFace<T, FaceBase>::StreamFace(const FaceUri& uri,
-                                    const shared_ptr<typename StreamFace::protocol::socket>& socket)
+                                    const shared_ptr<typename StreamFace::protocol::socket>& socket,
+                                    bool isOnDemand)
   : FaceBase(uri)
   , m_socket(socket)
   , m_inputBufferSize(0)
 {
+  FaceBase::setOnDemand(isOnDemand);
   StreamFaceValidator<T, FaceBase>::validateSocket(*socket);
   m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
                           bind(&StreamFace<T, FaceBase>::handleReceive, this, _1, _2));
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index c27f1df..28fdfa5 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -112,15 +112,16 @@
 
 void
 TcpChannel::createFace(const shared_ptr<ip::tcp::socket>& socket,
-                       const FaceCreatedCallback& onFaceCreated)
+                       const FaceCreatedCallback& onFaceCreated,
+                       bool isOnDemand)
 {
   tcp::Endpoint remoteEndpoint = socket->remote_endpoint();
 
   shared_ptr<Face> face;
   if (socket->local_endpoint().address().is_loopback())
-    face = make_shared<TcpLocalFace>(boost::cref(socket));
+    face = make_shared<TcpLocalFace>(boost::cref(socket), isOnDemand);
   else
-    face = make_shared<TcpFace>(boost::cref(socket));
+    face = make_shared<TcpFace>(boost::cref(socket), isOnDemand);
 
   face->onFail += bind(&TcpChannel::afterFaceFailed, this, remoteEndpoint);
 
@@ -164,7 +165,7 @@
 
   NFD_LOG_DEBUG("[" << m_localEndpoint << "] "
                 "<< Connection from " << socket->remote_endpoint());
-  createFace(socket, onFaceCreated);
+  createFace(socket, onFaceCreated, true);
 }
 
 void
@@ -193,7 +194,7 @@
   NFD_LOG_DEBUG("[" << m_localEndpoint << "] "
                 ">> Connection to " << socket->remote_endpoint());
 
-  createFace(socket, onFaceCreated);
+  createFace(socket, onFaceCreated, false);
 }
 
 void
diff --git a/daemon/face/tcp-channel.hpp b/daemon/face/tcp-channel.hpp
index 61a9c05..3c56cb1 100644
--- a/daemon/face/tcp-channel.hpp
+++ b/daemon/face/tcp-channel.hpp
@@ -88,7 +88,8 @@
 private:
   void
   createFace(const shared_ptr<boost::asio::ip::tcp::socket>& socket,
-             const FaceCreatedCallback& onFaceCreated);
+             const FaceCreatedCallback& onFaceCreated,
+             bool isOnDemand);
 
   void
   afterFaceFailed(tcp::Endpoint &endpoint);
diff --git a/daemon/face/tcp-face.cpp b/daemon/face/tcp-face.cpp
index 6f85a21..c543011 100644
--- a/daemon/face/tcp-face.cpp
+++ b/daemon/face/tcp-face.cpp
@@ -16,15 +16,15 @@
 NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(StreamFace,
                                                 TcpLocalFace::protocol, LocalFace, "TcpLocalFace");
 
-TcpFace::TcpFace(const shared_ptr<TcpFace::protocol::socket>& socket)
-  : StreamFace<protocol>(FaceUri(socket->remote_endpoint()), socket)
+TcpFace::TcpFace(const shared_ptr<TcpFace::protocol::socket>& socket, bool isOnDemand)
+  : StreamFace<protocol>(FaceUri(socket->remote_endpoint()), socket, isOnDemand)
 {
 }
 
 //
 
-TcpLocalFace::TcpLocalFace(const shared_ptr<TcpLocalFace::protocol::socket>& socket)
-  : StreamFace<protocol, LocalFace>(FaceUri(socket->remote_endpoint()), socket)
+TcpLocalFace::TcpLocalFace(const shared_ptr<TcpLocalFace::protocol::socket>& socket, bool isOnDemand)
+  : StreamFace<protocol, LocalFace>(FaceUri(socket->remote_endpoint()), socket, isOnDemand)
 {
 }
 
diff --git a/daemon/face/tcp-face.hpp b/daemon/face/tcp-face.hpp
index 1686403..92ab627 100644
--- a/daemon/face/tcp-face.hpp
+++ b/daemon/face/tcp-face.hpp
@@ -22,7 +22,7 @@
   typedef boost::asio::ip::tcp protocol;
 
   explicit
-  TcpFace(const shared_ptr<protocol::socket>& socket);
+  TcpFace(const shared_ptr<protocol::socket>& socket, bool isOnDemand);
 };
 
 //
@@ -38,7 +38,7 @@
   typedef boost::asio::ip::tcp protocol;
 
   explicit
-  TcpLocalFace(const shared_ptr<protocol::socket>& socket);
+  TcpLocalFace(const shared_ptr<protocol::socket>& socket, bool isOnDemand);
 };
 
 
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 9151830..390b412 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -80,7 +80,7 @@
 {
   ChannelFaceMap::iterator i = m_channelFaces.find(remoteEndpoint);
   if (i != m_channelFaces.end()) {
-    i->second->setPermanent(true);
+    i->second->setOnDemand(false);
     onFaceCreated(i->second);
     return;
   }
@@ -104,7 +104,7 @@
     throw Error("Failed to properly configure the socket. Check the address ("
                 + std::string(e.what()) + ")");
   }
-  createFace(clientSocket, onFaceCreated, true);
+  createFace(clientSocket, onFaceCreated, false);
 }
 
 void
@@ -157,11 +157,11 @@
 shared_ptr<UdpFace>
 UdpChannel::createFace(const shared_ptr<ip::udp::socket>& socket,
                        const FaceCreatedCallback& onFaceCreated,
-                       bool isPermanent)
+                       bool isOnDemand)
 {
   udp::Endpoint remoteEndpoint = socket->remote_endpoint();
 
-  shared_ptr<UdpFace> face = make_shared<UdpFace>(boost::cref(socket), isPermanent);
+  shared_ptr<UdpFace> face = make_shared<UdpFace>(boost::cref(socket), isOnDemand);
   face->onFail += bind(&UdpChannel::afterFaceFailed, this, remoteEndpoint);
 
   onFaceCreated(face);
@@ -204,7 +204,7 @@
 
     face = createFace(clientSocket,
                       onFaceCreatedNewPeerCallback,
-                      false);
+                      true);
   }
 
   //Passing the message to the correspondent face
@@ -233,7 +233,7 @@
   while (next != m_channelFaces.end()) {
     ChannelFaceMap::iterator it = next;
     next++;
-    if (!it->second->isPermanent() &&
+    if (it->second->isOnDemand() &&
         !it->second->hasBeenUsedRecently()) {
       //face has been idle since the last time closeIdleFaces
       //has been called. Going to close it
diff --git a/daemon/face/udp-channel.hpp b/daemon/face/udp-channel.hpp
index 26c6cae..0243dd6 100644
--- a/daemon/face/udp-channel.hpp
+++ b/daemon/face/udp-channel.hpp
@@ -96,7 +96,7 @@
   shared_ptr<UdpFace>
   createFace(const shared_ptr<boost::asio::ip::udp::socket>& socket,
              const FaceCreatedCallback& onFaceCreated,
-             bool isPermanent);
+             bool isOnDemand);
   void
   afterFaceFailed(udp::Endpoint& endpoint);
 
@@ -152,7 +152,7 @@
   bool m_isListening;
   
   /**
-   * \brief every time m_idleFaceTimeout expires all the idle (and not permanent)
+   * \brief every time m_idleFaceTimeout expires all the idle (and on-demand)
    *        faces will be removed
    */
   time::seconds m_idleFaceTimeout;
diff --git a/daemon/face/udp-face.cpp b/daemon/face/udp-face.cpp
index d9ba1f3..7de4d34 100644
--- a/daemon/face/udp-face.cpp
+++ b/daemon/face/udp-face.cpp
@@ -11,10 +11,10 @@
 NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(DatagramFace, UdpFace::protocol, "UdpFace");
 
 UdpFace::UdpFace(const shared_ptr<UdpFace::protocol::socket>& socket,
-                 bool isPermanent)
+                 bool isOnDemand)
   : DatagramFace<protocol>(FaceUri(socket->remote_endpoint()),
                            socket,
-                           isPermanent)
+                           isOnDemand)
 {
 }
 
diff --git a/daemon/face/udp-face.hpp b/daemon/face/udp-face.hpp
index 038c7c3..6c1e3a8 100644
--- a/daemon/face/udp-face.hpp
+++ b/daemon/face/udp-face.hpp
@@ -22,7 +22,7 @@
   typedef boost::asio::ip::udp protocol;
 
   UdpFace(const shared_ptr<protocol::socket>& socket,
-          bool isPermanent);
+          bool isOnDemand);
 
   //@todo if needed by other datagramFaces, it could be moved to datagram-face.hpp
   /**
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 5fcfd1c..7352a99 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -60,7 +60,7 @@
 
 shared_ptr<MulticastUdpFace>
 UdpFactory::createMulticastFace(const udp::Endpoint& localEndpoint,
-                                       const udp::Endpoint& multicastEndpoint)
+                                const udp::Endpoint& multicastEndpoint)
 {
   //checking if the local and musticast endpoint are already in use for a multicast face
   shared_ptr<MulticastUdpFace> multicastFace = findMulticastFace(localEndpoint);
diff --git a/daemon/face/unix-stream-face.cpp b/daemon/face/unix-stream-face.cpp
index 43e2369..2753f57 100644
--- a/daemon/face/unix-stream-face.cpp
+++ b/daemon/face/unix-stream-face.cpp
@@ -16,7 +16,7 @@
                                                 "UnixStreamFace");
 
 UnixStreamFace::UnixStreamFace(const shared_ptr<UnixStreamFace::protocol::socket>& socket)
-  : StreamFace<protocol, LocalFace>(FaceUri(socket->local_endpoint()), socket)
+  : StreamFace<protocol, LocalFace>(FaceUri(socket->local_endpoint()), socket, true)
 {
 }
 
diff --git a/daemon/face/unix-stream-face.hpp b/daemon/face/unix-stream-face.hpp
index 8492f54..02ccbb5 100644
--- a/daemon/face/unix-stream-face.hpp
+++ b/daemon/face/unix-stream-face.hpp
@@ -25,7 +25,6 @@
 public:
   typedef boost::asio::local::stream_protocol protocol;
 
-  explicit
   UnixStreamFace(const shared_ptr<protocol::socket>& socket);
 };
 
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index e4769ff..28f8a16 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -655,7 +655,9 @@
 {
   ndn::nfd::FaceEventNotification faceCreated(ndn::nfd::FACE_EVENT_CREATED,
                                               face->getId(),
-                                              face->getUri().toString());
+                                              face->getUri().toString(),
+                                              (face->isLocal() ? ndn::nfd::FACE_IS_LOCAL : 0) |
+                                              (face->isOnDemand() ? ndn::nfd::FACE_IS_ON_DEMAND : 0));
 
   m_notificationStream.postNotification(faceCreated);
 }
@@ -665,7 +667,9 @@
 {
   ndn::nfd::FaceEventNotification faceDestroyed(ndn::nfd::FACE_EVENT_DESTROYED,
                                                 face->getId(),
-                                                face->getUri().toString());
+                                                face->getUri().toString(),
+                                                (face->isLocal() ? ndn::nfd::FACE_IS_LOCAL : 0) |
+                                                (face->isOnDemand() ? ndn::nfd::FACE_IS_ON_DEMAND : 0));
 
   m_notificationStream.postNotification(faceDestroyed);
 }
diff --git a/tests/face/ethernet.cpp b/tests/face/ethernet.cpp
index 2e731bf..4859da2 100644
--- a/tests/face/ethernet.cpp
+++ b/tests/face/ethernet.cpp
@@ -74,6 +74,8 @@
     factory.createMulticastFace(interfaces[0], ethernet::getDefaultMulticastAddress());
 
   BOOST_REQUIRE(static_cast<bool>(face));
+
+  BOOST_CHECK(!face->isOnDemand());
   BOOST_CHECK_EQUAL(face->isLocal(), false);
   BOOST_CHECK_EQUAL(face->getUri().toString(),
                     "ether://" + interfaces[0] + "/" +
diff --git a/tests/face/tcp.cpp b/tests/face/tcp.cpp
index 38ee797..d908804 100644
--- a/tests/face/tcp.cpp
+++ b/tests/face/tcp.cpp
@@ -182,6 +182,9 @@
   BOOST_REQUIRE(static_cast<bool>(m_face1));
   BOOST_REQUIRE(static_cast<bool>(m_face2));
 
+  BOOST_CHECK(m_face1->isOnDemand());
+  BOOST_CHECK(!m_face2->isOnDemand());
+
   BOOST_CHECK_EQUAL(m_face2->getUri().toString(), "tcp4://127.0.0.1:20070");
   // face1 has an unknown URI, since the source port is automatically chosen by OS
 
diff --git a/tests/face/udp.cpp b/tests/face/udp.cpp
index d4983bf..ea9d1cc 100644
--- a/tests/face/udp.cpp
+++ b/tests/face/udp.cpp
@@ -839,6 +839,7 @@
                       "UdpChannel error: cannot connect or cannot accept connection");
 
   m_face2->sendInterest(interest1);
+  BOOST_CHECK(!m_face2->isOnDemand());
 
   BOOST_CHECK_MESSAGE(m_limitedIo.run(2,//1 send + 1 listen return
                                       time::seconds(1)) == LimitedIo::EXCEED_OPS,
@@ -865,6 +866,7 @@
   BOOST_CHECK_EQUAL(channel1->size(), 1);
   BOOST_CHECK_EQUAL(channel2->size(), 1);
   BOOST_REQUIRE(static_cast<bool>(m_face1));
+  BOOST_CHECK(m_face1->isOnDemand());
   
   channel1->connect("127.0.0.1", "20071",
                     bind(&EndToEndFixture::channel1_onFaceCreatedNoCheck, this, _1),
@@ -873,6 +875,8 @@
   BOOST_CHECK_MESSAGE(m_limitedIo.run(1,//1 connect
                                       time::seconds(1)) == LimitedIo::EXCEED_OPS,
                       "UdpChannel error: cannot connect");
+
+  BOOST_CHECK(!m_face1->isOnDemand());
   
   //the connect should have set m_face1 as permanent face,
   //but it shouln't have created any additional faces
diff --git a/tests/mgmt/face-manager.cpp b/tests/mgmt/face-manager.cpp
index cca3671..45a609f 100644
--- a/tests/mgmt/face-manager.cpp
+++ b/tests/mgmt/face-manager.cpp
@@ -1039,7 +1039,8 @@
 
   ndn::nfd::FaceEventNotification expectedFaceEvent(ndn::nfd::FACE_EVENT_CREATED,
                                                     1,
-                                                    dummy->getUri().toString());
+                                                    dummy->getUri().toString(),
+                                                    0);
 
   Block encodedResultOptions(resultOptions.wireEncode());
 
@@ -1099,7 +1100,7 @@
 
   ndn::nfd::FaceEventNotification expectedFaceEvent(ndn::nfd::FACE_EVENT_DESTROYED,
                                                     dummy->getId(),
-                                                    dummy->getUri().toString());
+                                                    dummy->getUri().toString(), 0);
 
   getFace()->onReceiveData +=
     bind(&FaceFixture::callbackDispatch, this, _1,