mgmt: add Flags field to FaceStatus

refs #3732

Change-Id: I933c1471a185fd96777e6935c6810210868b0765
diff --git a/src/mgmt/nfd/face-status.cpp b/src/mgmt/nfd/face-status.cpp
index bdc7404..584208c 100644
--- a/src/mgmt/nfd/face-status.cpp
+++ b/src/mgmt/nfd/face-status.cpp
@@ -43,6 +43,7 @@
   , m_nOutNacks(0)
   , m_nInBytes(0)
   , m_nOutBytes(0)
+  , m_flags(0)
 {
 }
 
@@ -58,6 +59,8 @@
   size_t totalLength = 0;
 
   totalLength += prependNonNegativeIntegerBlock(encoder,
+                 tlv::nfd::Flags, m_flags);
+  totalLength += prependNonNegativeIntegerBlock(encoder,
                  tlv::nfd::NOutBytes, m_nOutBytes);
   totalLength += prependNonNegativeIntegerBlock(encoder,
                  tlv::nfd::NInBytes, m_nInBytes);
@@ -248,6 +251,14 @@
   else {
     BOOST_THROW_EXCEPTION(Error("missing required NOutBytes field"));
   }
+
+  if (val != m_wire.elements_end() && val->type() == tlv::nfd::Flags) {
+    m_flags = readNonNegativeInteger(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("missing required Flags field"));
+  }
 }
 
 FaceStatus&
@@ -323,6 +334,43 @@
   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
 {
@@ -346,8 +394,13 @@
 
   os << "FaceScope: " << status.getFaceScope() << ",\n"
      << "FacePersistency: " << status.getFacePersistency() << ",\n"
-     << "LinkType: " << status.getLinkType() << ",\n"
-     << "Counters: { Interests: {in: " << status.getNInInterests() << ", "
+     << "LinkType: " << status.getLinkType() << ",\n";
+
+  auto osFlags = os.flags();
+  os << "Flags: " << std::showbase << std::hex << status.getFlags() << ",\n";
+  os.flags(osFlags);
+
+  os << "Counters: { Interests: {in: " << status.getNInInterests() << ", "
      << "out: " << status.getNOutInterests() << "},\n"
      << "            Data: {in: " << status.getNInDatas() << ", "
      << "out: " << status.getNOutDatas() << "},\n"
diff --git a/src/mgmt/nfd/face-status.hpp b/src/mgmt/nfd/face-status.hpp
index 4f20e53..a2ea259 100644
--- a/src/mgmt/nfd/face-status.hpp
+++ b/src/mgmt/nfd/face-status.hpp
@@ -147,6 +147,21 @@
   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;
@@ -162,6 +177,7 @@
   uint64_t m_nOutNacks;
   uint64_t m_nInBytes;
   uint64_t m_nOutBytes;
+  uint64_t m_flags;
 
   mutable Block m_wire;
 };