tools: add reliability option to nfdc face create

add LpReliability flag to FaceManager face status output

refs #4004

Change-Id: Ibcdfe7ff0fc9790cbcc4f2aa5e57e27b8a76023c
diff --git a/tools/nfdc/face-module.cpp b/tools/nfdc/face-module.cpp
index 39ca5c2..1a88229 100644
--- a/tools/nfdc/face-module.cpp
+++ b/tools/nfdc/face-module.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -53,7 +53,8 @@
     .setTitle("create a face")
     .addArg("remote", ArgValueType::FACE_URI, Required::YES, Positional::YES)
     .addArg("persistency", ArgValueType::FACE_PERSISTENCY, Required::NO, Positional::YES)
-    .addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO);
+    .addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO)
+    .addArg("reliability", ArgValueType::BOOLEAN, Required::NO, Positional::NO);
   parser.addCommand(defFaceCreate, &FaceModule::create);
 
   CommandDefinition defFaceDestroy("face", "destroy");
@@ -151,6 +152,8 @@
   auto remoteUri = ctx.args.get<FaceUri>("remote");
   auto localUri = ctx.args.getOptional<FaceUri>("local");
   auto persistency = ctx.args.get<FacePersistency>("persistency", FacePersistency::FACE_PERSISTENCY_PERSISTENT);
+  auto lpReliability = ctx.args.getTribool("reliability");
+
   FaceUri canonicalRemote;
   ndn::optional<FaceUri> canonicalLocal;
 
@@ -166,9 +169,17 @@
             << ia("local") << resp.getLocalUri()
             << ia("remote") << resp.getUri()
             << ia("persistency") << resp.getFacePersistency()
+            << ia("reliability") << (resp.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) ? "on" : "off")
             << '\n';
   };
 
+  auto updateFace = [&printPositiveResult] (ControlParameters respParams, ControlParameters resp) {
+    // faces/update response does not have FaceUris, copy from faces/create response
+    resp.setLocalUri(respParams.getLocalUri())
+        .setUri(respParams.getUri());
+    printPositiveResult("face-updated", resp);
+  };
+
   auto handle409 = [&] (const ControlResponse& resp) {
     ControlParameters respParams(resp.getBody());
     if (respParams.getUri() != canonicalRemote.toString()) {
@@ -178,19 +189,39 @@
 
     if (persistencyLessThan(respParams.getFacePersistency(), persistency)) {
       // need to upgrade persistency
+      ControlParameters params;
+      params.setFaceId(respParams.getFaceId()).setFacePersistency(persistency);
+      if (!boost::logic::indeterminate(lpReliability)) {
+        params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, lpReliability);
+      }
       ctx.controller.start<ndn::nfd::FaceUpdateCommand>(
-          ControlParameters().setFaceId(respParams.getFaceId()).setFacePersistency(persistency),
-          [respParams, &printPositiveResult] (ControlParameters resp2) {
-            // faces/update response does not have FaceUris, copy from faces/create response
-            resp2.setLocalUri(respParams.getLocalUri())
-                 .setUri(respParams.getUri());
-            printPositiveResult("face-updated", resp2);
-          },
+          params,
+          bind(updateFace, respParams, _1),
           ctx.makeCommandFailureHandler("upgrading face persistency"),
           ctx.makeCommandOptions());
     }
+    else if (lpReliability && !respParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
+      // enable reliability
+      ControlParameters params;
+      params.setFaceId(respParams.getFaceId()).setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true);
+      ctx.controller.start<ndn::nfd::FaceUpdateCommand>(
+          params,
+          bind(updateFace, respParams, _1),
+          ctx.makeCommandFailureHandler("enabling reliability"),
+          ctx.makeCommandOptions());
+    }
+    else if (!lpReliability && respParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
+      // disable reliability
+      ControlParameters params;
+      params.setFaceId(respParams.getFaceId()).setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, false);
+      ctx.controller.start<ndn::nfd::FaceUpdateCommand>(
+          params,
+          bind(updateFace, respParams, _1),
+          ctx.makeCommandFailureHandler("disabling reliability"),
+          ctx.makeCommandOptions());
+    }
     else {
-      // don't downgrade persistency
+      // don't do anything
       printPositiveResult("face-exists", respParams);
     }
     return true;
@@ -203,6 +234,9 @@
       params.setLocalUri(canonicalLocal->toString());
     }
     params.setFacePersistency(persistency);
+    if (!boost::logic::indeterminate(lpReliability)) {
+      params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, lpReliability);
+    }
 
     ctx.controller.start<ndn::nfd::FaceCreateCommand>(
       params,
@@ -275,7 +309,9 @@
       ctx.out << ia("id") << face.getFaceId()
               << ia("local") << face.getLocalUri()
               << ia("remote") << face.getRemoteUri()
-              << ia("persistency") << face.getFacePersistency() << '\n';
+              << ia("persistency") << face.getFacePersistency()
+              << ia("reliability") << (resp.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) ? "on" : "off")
+              << '\n';
     },
     ctx.makeCommandFailureHandler("destroying face"),
     ctx.makeCommandOptions());
@@ -332,6 +368,9 @@
     if (item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)) {
       os << "<localFieldsEnabled/>";
     }
+    if (item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
+      os << "<lpReliabilityEnabled/>";
+    }
     os << "</flags>";
   }
 
@@ -400,6 +439,9 @@
   if (item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)) {
     os << flagSep << "local-fields";
   }
+  if (item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
+    os << flagSep << "lp-reliability";
+  }
   os << '}';
 
   os << ia.end();