mgmt: move Flags field from FaceStatus to FaceTraits

refs #3732

Change-Id: I20ce5b608b6238d2c0c05db125ce261edd846dab
diff --git a/src/mgmt/nfd/face-event-notification.cpp b/src/mgmt/nfd/face-event-notification.cpp
index a65c7ba..a322ae9 100644
--- a/src/mgmt/nfd/face-event-notification.cpp
+++ b/src/mgmt/nfd/face-event-notification.cpp
@@ -50,6 +50,8 @@
   size_t totalLength = 0;
 
   totalLength += prependNonNegativeIntegerBlock(encoder,
+                 tlv::nfd::Flags, m_flags);
+  totalLength += prependNonNegativeIntegerBlock(encoder,
                  tlv::nfd::LinkType, m_linkType);
   totalLength += prependNonNegativeIntegerBlock(encoder,
                  tlv::nfd::FacePersistency, m_facePersistency);
@@ -150,6 +152,13 @@
   else {
     BOOST_THROW_EXCEPTION(Error("missing required LinkType field"));
   }
+
+  if (val != m_wire.elements_end() && val->type() == tlv::nfd::Flags) {
+    m_flags = readNonNegativeInteger(*val);
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("missing required Flags field"));
+  }
 }
 
 FaceEventNotification&
@@ -192,8 +201,13 @@
      << "LocalUri: " << notification.getLocalUri() << ", "
      << "FaceScope: " << notification.getFaceScope() << ", "
      << "FacePersistency: " << notification.getFacePersistency() << ", "
-     << "LinkType: " << notification.getLinkType()
-     << ")";
+     << "LinkType: " << notification.getLinkType() << ", ";
+
+  auto osFlags = os.flags();
+  os << "Flags: " << std::showbase << std::hex << notification.getFlags();
+  os.flags(osFlags);
+
+  os << ")";
   return os;
 }
 
diff --git a/src/mgmt/nfd/face-status.cpp b/src/mgmt/nfd/face-status.cpp
index 584208c..d54f072 100644
--- a/src/mgmt/nfd/face-status.cpp
+++ b/src/mgmt/nfd/face-status.cpp
@@ -43,7 +43,6 @@
   , m_nOutNacks(0)
   , m_nInBytes(0)
   , m_nOutBytes(0)
-  , m_flags(0)
 {
 }
 
@@ -334,43 +333,6 @@
   return *this;
 }
 
-FaceStatus&
-FaceStatus::setFlags(uint64_t flags)
-{
-  m_wire.reset();
-  m_flags = flags;
-  return *this;
-}
-
-bool
-FaceStatus::getFlagBit(size_t bit) const
-{
-  if (bit >= 64) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
-  }
-
-  return m_flags & (1 << bit);
-}
-
-FaceStatus&
-FaceStatus::setFlagBit(size_t bit, bool value)
-{
-  if (bit >= 64) {
-    BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
-  }
-
-  m_wire.reset();
-
-  if (value) {
-    m_flags |= (1 << bit);
-  }
-  else {
-    m_flags &= ~(1 << bit);
-  }
-
-  return *this;
-}
-
 void
 FaceStatus::wireReset() const
 {
diff --git a/src/mgmt/nfd/face-status.hpp b/src/mgmt/nfd/face-status.hpp
index a2ea259..4f20e53 100644
--- a/src/mgmt/nfd/face-status.hpp
+++ b/src/mgmt/nfd/face-status.hpp
@@ -147,21 +147,6 @@
   FaceStatus&
   setNOutBytes(uint64_t nOutBytes);
 
-  uint64_t
-  getFlags() const
-  {
-    return m_flags;
-  }
-
-  FaceStatus&
-  setFlags(uint64_t flags);
-
-  bool
-  getFlagBit(size_t bit) const;
-
-  FaceStatus&
-  setFlagBit(size_t bit, bool value);
-
 protected:
   void
   wireReset() const;
@@ -177,7 +162,6 @@
   uint64_t m_nOutNacks;
   uint64_t m_nInBytes;
   uint64_t m_nOutBytes;
-  uint64_t m_flags;
 
   mutable Block m_wire;
 };
diff --git a/src/mgmt/nfd/face-traits.hpp b/src/mgmt/nfd/face-traits.hpp
index d9422c3..48c2624 100644
--- a/src/mgmt/nfd/face-traits.hpp
+++ b/src/mgmt/nfd/face-traits.hpp
@@ -51,6 +51,7 @@
     , m_faceScope(FACE_SCOPE_NON_LOCAL)
     , m_facePersistency(FACE_PERSISTENCY_PERSISTENT)
     , m_linkType(LINK_TYPE_POINT_TO_POINT)
+    , m_flags(0x0)
   {
   }
 
@@ -138,6 +139,49 @@
     return static_cast<C&>(*this);
   }
 
+  uint64_t
+  getFlags() const
+  {
+    return m_flags;
+  }
+
+  C&
+  setFlags(uint64_t flags)
+  {
+    wireReset();
+    m_flags = flags;
+    return static_cast<C&>(*this);
+  }
+
+  bool
+  getFlagBit(size_t bit) const
+  {
+    if (bit >= 64) {
+      BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
+    }
+
+    return m_flags & (1 << bit);
+  }
+
+  C&
+  setFlagBit(size_t bit, bool value)
+  {
+    if (bit >= 64) {
+      BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
+    }
+
+    wireReset();
+
+    if (value) {
+      m_flags |= (1 << bit);
+    }
+    else {
+      m_flags &= ~(1 << bit);
+    }
+
+    return static_cast<C&>(*this);
+  }
+
 protected:
   virtual void
   wireReset() const = 0;
@@ -149,6 +193,7 @@
   FaceScope m_faceScope;
   FacePersistency  m_facePersistency;
   LinkType m_linkType;
+  uint64_t m_flags;
 };
 
 } // namespace nfd
diff --git a/tests/unit-tests/mgmt/nfd/face-event-notification.t.cpp b/tests/unit-tests/mgmt/nfd/face-event-notification.t.cpp
index c356603..09f024b 100644
--- a/tests/unit-tests/mgmt/nfd/face-event-notification.t.cpp
+++ b/tests/unit-tests/mgmt/nfd/face-event-notification.t.cpp
@@ -69,7 +69,8 @@
                .setLocalUri("tcp4://192.0.2.2:6363")
                .setFaceScope(FACE_SCOPE_LOCAL)
                .setFacePersistency(FACE_PERSISTENCY_ON_DEMAND)
-               .setLinkType(LINK_TYPE_MULTI_ACCESS);
+               .setLinkType(LINK_TYPE_MULTI_ACCESS)
+               .setFlags(0x3);
   Block wire;
   BOOST_REQUIRE_NO_THROW(wire = notification1.wireEncode());
 
@@ -79,13 +80,13 @@
   //   printf("0x%02x, ", *it);
   // }
   static const uint8_t expected[] = {
-    0xc0, 0x3e, 0xc1, 0x01, 0x01, 0x69, 0x01, 0x14, 0x72, 0x16,
+    0xc0, 0x41, 0xc1, 0x01, 0x01, 0x69, 0x01, 0x14, 0x72, 0x16,
     0x74, 0x63, 0x70, 0x34, 0x3a, 0x2f, 0x2f, 0x31, 0x39, 0x32,
     0x2e, 0x30, 0x2e, 0x32, 0x2e, 0x31, 0x3a, 0x35, 0x35, 0x35,
     0x35, 0x35, 0x81, 0x15, 0x74, 0x63, 0x70, 0x34, 0x3a, 0x2f,
     0x2f, 0x31, 0x39, 0x32, 0x2e, 0x30, 0x2e, 0x32, 0x2e, 0x32,
     0x3a, 0x36, 0x33, 0x36, 0x33, 0x84, 0x01, 0x01, 0x85, 0x01,
-    0x01, 0x86, 0x01, 0x01,
+    0x01, 0x86, 0x01, 0x01, 0x6c, 0x01, 0x03,
   };
   BOOST_REQUIRE_EQUAL_COLLECTIONS(expected, expected + sizeof(expected),
                                   wire.begin(), wire.end());
@@ -99,6 +100,7 @@
   BOOST_CHECK_EQUAL(notification1.getFaceScope(), notification2.getFaceScope());
   BOOST_CHECK_EQUAL(notification1.getFacePersistency(), notification2.getFacePersistency());
   BOOST_CHECK_EQUAL(notification1.getLinkType(), notification2.getLinkType());
+  BOOST_CHECK_EQUAL(notification1.getFlags(), notification2.getFlags());
 
   std::ostringstream os;
   os << notification2;
@@ -109,7 +111,8 @@
                               "LocalUri: tcp4://192.0.2.2:6363, "
                               "FaceScope: local, "
                               "FacePersistency: on-demand, "
-                              "LinkType: multi-access)");
+                              "LinkType: multi-access, "
+                              "Flags: 0x3)");
 }
 
 BOOST_AUTO_TEST_CASE(EncodeDestroyed)
@@ -121,7 +124,8 @@
                .setLocalUri("tcp4://192.0.2.2:6363")
                .setFaceScope(FACE_SCOPE_LOCAL)
                .setFacePersistency(FACE_PERSISTENCY_ON_DEMAND)
-               .setLinkType(LINK_TYPE_MULTI_ACCESS);
+               .setLinkType(LINK_TYPE_MULTI_ACCESS)
+               .setFlags(0x4);
   Block wire;
   BOOST_REQUIRE_NO_THROW(wire = notification1.wireEncode());
 
@@ -131,13 +135,13 @@
   //   printf("0x%02x, ", *it);
   // }
   static const uint8_t expected[] = {
-    0xc0, 0x3e, 0xc1, 0x01, 0x02, 0x69, 0x01, 0x14, 0x72, 0x16,
+    0xc0, 0x41, 0xc1, 0x01, 0x02, 0x69, 0x01, 0x14, 0x72, 0x16,
     0x74, 0x63, 0x70, 0x34, 0x3a, 0x2f, 0x2f, 0x31, 0x39, 0x32,
     0x2e, 0x30, 0x2e, 0x32, 0x2e, 0x31, 0x3a, 0x35, 0x35, 0x35,
     0x35, 0x35, 0x81, 0x15, 0x74, 0x63, 0x70, 0x34, 0x3a, 0x2f,
     0x2f, 0x31, 0x39, 0x32, 0x2e, 0x30, 0x2e, 0x32, 0x2e, 0x32,
     0x3a, 0x36, 0x33, 0x36, 0x33, 0x84, 0x01, 0x01, 0x85, 0x01,
-    0x01, 0x86, 0x01, 0x01,
+    0x01, 0x86, 0x01, 0x01, 0x6c, 0x01, 0x04,
   };
   BOOST_REQUIRE_EQUAL_COLLECTIONS(expected, expected + sizeof(expected),
                                   wire.begin(), wire.end());
@@ -151,6 +155,7 @@
   BOOST_CHECK_EQUAL(notification1.getFaceScope(), notification2.getFaceScope());
   BOOST_CHECK_EQUAL(notification1.getFacePersistency(), notification2.getFacePersistency());
   BOOST_CHECK_EQUAL(notification1.getLinkType(), notification2.getLinkType());
+  BOOST_CHECK_EQUAL(notification1.getFlags(), notification2.getFlags());
 
   std::ostringstream os;
   os << notification2;
@@ -161,7 +166,8 @@
                               "LocalUri: tcp4://192.0.2.2:6363, "
                               "FaceScope: local, "
                               "FacePersistency: on-demand, "
-                              "LinkType: multi-access)");
+                              "LinkType: multi-access, "
+                              "Flags: 0x4)");
 }
 
 BOOST_AUTO_TEST_CASE(EncodeUp)
@@ -173,7 +179,8 @@
                .setLocalUri("tcp4://192.0.2.2:6363")
                .setFaceScope(FACE_SCOPE_LOCAL)
                .setFacePersistency(FACE_PERSISTENCY_ON_DEMAND)
-               .setLinkType(LINK_TYPE_MULTI_ACCESS);
+               .setLinkType(LINK_TYPE_MULTI_ACCESS)
+               .setFlags(0x05);
   Block wire;
   BOOST_REQUIRE_NO_THROW(wire = notification1.wireEncode());
 
@@ -183,13 +190,13 @@
   //   printf("0x%02x, ", *it);
   // }
   static const uint8_t expected[] = {
-    0xc0, 0x3e, 0xc1, 0x01, 0x03, 0x69, 0x01, 0x14, 0x72, 0x16,
+    0xc0, 0x41, 0xc1, 0x01, 0x03, 0x69, 0x01, 0x14, 0x72, 0x16,
     0x74, 0x63, 0x70, 0x34, 0x3a, 0x2f, 0x2f, 0x31, 0x39, 0x32,
     0x2e, 0x30, 0x2e, 0x32, 0x2e, 0x31, 0x3a, 0x35, 0x35, 0x35,
     0x35, 0x35, 0x81, 0x15, 0x74, 0x63, 0x70, 0x34, 0x3a, 0x2f,
     0x2f, 0x31, 0x39, 0x32, 0x2e, 0x30, 0x2e, 0x32, 0x2e, 0x32,
     0x3a, 0x36, 0x33, 0x36, 0x33, 0x84, 0x01, 0x01, 0x85, 0x01,
-    0x01, 0x86, 0x01, 0x01,
+    0x01, 0x86, 0x01, 0x01, 0x6c, 0x01, 0x05,
   };
   BOOST_REQUIRE_EQUAL_COLLECTIONS(expected, expected + sizeof(expected),
                                   wire.begin(), wire.end());
@@ -213,7 +220,8 @@
                               "LocalUri: tcp4://192.0.2.2:6363, "
                               "FaceScope: local, "
                               "FacePersistency: on-demand, "
-                              "LinkType: multi-access)");
+                              "LinkType: multi-access, "
+                              "Flags: 0x5)");
 }
 
 BOOST_AUTO_TEST_CASE(EncodeDown)
@@ -225,7 +233,8 @@
                .setLocalUri("tcp4://192.0.2.2:6363")
                .setFaceScope(FACE_SCOPE_LOCAL)
                .setFacePersistency(FACE_PERSISTENCY_ON_DEMAND)
-               .setLinkType(LINK_TYPE_MULTI_ACCESS);
+               .setLinkType(LINK_TYPE_MULTI_ACCESS)
+               .setFlags(0x06);
   Block wire;
   BOOST_REQUIRE_NO_THROW(wire = notification1.wireEncode());
 
@@ -235,13 +244,13 @@
   //   printf("0x%02x, ", *it);
   // }
   static const uint8_t expected[] = {
-    0xc0, 0x3e, 0xc1, 0x01, 0x04, 0x69, 0x01, 0x14, 0x72, 0x16,
+    0xc0, 0x41, 0xc1, 0x01, 0x04, 0x69, 0x01, 0x14, 0x72, 0x16,
     0x74, 0x63, 0x70, 0x34, 0x3a, 0x2f, 0x2f, 0x31, 0x39, 0x32,
     0x2e, 0x30, 0x2e, 0x32, 0x2e, 0x31, 0x3a, 0x35, 0x35, 0x35,
     0x35, 0x35, 0x81, 0x15, 0x74, 0x63, 0x70, 0x34, 0x3a, 0x2f,
     0x2f, 0x31, 0x39, 0x32, 0x2e, 0x30, 0x2e, 0x32, 0x2e, 0x32,
     0x3a, 0x36, 0x33, 0x36, 0x33, 0x84, 0x01, 0x01, 0x85, 0x01,
-    0x01, 0x86, 0x01, 0x01,
+    0x01, 0x86, 0x01, 0x01, 0x6c, 0x01, 0x06,
   };
   BOOST_REQUIRE_EQUAL_COLLECTIONS(expected, expected + sizeof(expected),
                                   wire.begin(), wire.end());
@@ -265,7 +274,8 @@
                               "LocalUri: tcp4://192.0.2.2:6363, "
                               "FaceScope: local, "
                               "FacePersistency: on-demand, "
-                              "LinkType: multi-access)");
+                              "LinkType: multi-access, "
+                              "Flags: 0x6)");
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestFaceEventNotification