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/command-arguments.hpp b/tools/nfdc/command-arguments.hpp
index 49e7419..13aef61 100644
--- a/tools/nfdc/command-arguments.hpp
+++ b/tools/nfdc/command-arguments.hpp
@@ -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,
@@ -28,8 +28,11 @@
#include "core/common.hpp"
#include "status-report.hpp"
+
#include <ndn-cxx/encoding/nfd-constants.hpp>
+
#include <boost/any.hpp>
+#include <boost/logic/tribool.hpp>
namespace nfd {
namespace tools {
@@ -65,6 +68,19 @@
}
return boost::any_cast<T>(i->second);
}
+
+ /** \brief get an optional boolean argument as tribool
+ * \return the argument value, or boost::logic::indeterminate if the argument is omitted on command line
+ */
+ boost::logic::tribool
+ getTribool(const std::string& key) const
+ {
+ auto value = getOptional<bool>(key);
+ if (value) {
+ return *value;
+ }
+ return boost::logic::indeterminate;
+ }
};
} // namespace nfdc
diff --git a/tools/nfdc/command-definition.cpp b/tools/nfdc/command-definition.cpp
index a2ceb33..27b30f2 100644
--- a/tools/nfdc/command-definition.cpp
+++ b/tools/nfdc/command-definition.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,
@@ -40,6 +40,8 @@
return os << "none";
case ArgValueType::ANY:
return os << "any";
+ case ArgValueType::BOOLEAN:
+ return os << "boolean";
case ArgValueType::UNSIGNED:
return os << "non-negative integer";
case ArgValueType::STRING:
@@ -68,6 +70,8 @@
return "";
case ArgValueType::ANY:
return "args";
+ case ArgValueType::BOOLEAN:
+ return "bool";
case ArgValueType::UNSIGNED:
return "uint";
case ArgValueType::STRING:
@@ -138,7 +142,7 @@
const Arg& arg = namedArg->second;
if (arg.valueType == ArgValueType::NONE) {
ca[arg.name] = true;
- NDN_LOG_TRACE(token << " is a boolean argument");
+ NDN_LOG_TRACE(token << " is a no-param argument");
}
else if (i + 1 >= tokens.size()) {
BOOST_THROW_EXCEPTION(Error(arg.name + ": " + arg.metavar + " is missing"));
@@ -212,6 +216,18 @@
return ca;
}
+static bool
+parseBoolean(const std::string& s)
+{
+ if (s == "on" || s == "true" || s == "enabled" || s == "yes" || s == "1") {
+ return true;
+ }
+ if (s == "off" || s == "false" || s == "disabled" || s == "no" || s == "0") {
+ return false;
+ }
+ BOOST_THROW_EXCEPTION(std::invalid_argument("unrecognized boolean value '" + s + "'"));
+}
+
static FacePersistency
parseFacePersistency(const std::string& s)
{
@@ -221,7 +237,7 @@
if (s == "permanent") {
return FacePersistency::FACE_PERSISTENCY_PERMANENT;
}
- BOOST_THROW_EXCEPTION(std::invalid_argument("unrecognized FacePersistency"));
+ BOOST_THROW_EXCEPTION(std::invalid_argument("unrecognized FacePersistency '" + s + "'"));
}
boost::any
@@ -233,11 +249,15 @@
BOOST_ASSERT(false);
return boost::any();
+ case ArgValueType::BOOLEAN: {
+ return parseBoolean(token);
+ }
+
case ArgValueType::UNSIGNED: {
// boost::lexical_cast<uint64_t> will accept negative number
int64_t v = boost::lexical_cast<int64_t>(token);
if (v < 0) {
- BOOST_THROW_EXCEPTION(std::out_of_range("value is negative"));
+ BOOST_THROW_EXCEPTION(std::out_of_range("value '" + token + "' is negative"));
}
return static_cast<uint64_t>(v);
}
diff --git a/tools/nfdc/command-definition.hpp b/tools/nfdc/command-definition.hpp
index 7d8c8f0..5661ff2 100644
--- a/tools/nfdc/command-definition.hpp
+++ b/tools/nfdc/command-definition.hpp
@@ -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,
@@ -49,6 +49,12 @@
*/
ANY,
+ /** \brief boolean
+ *
+ * The argument appears in CommandArguments as bool.
+ */
+ BOOLEAN,
+
/** \brief non-negative integer
*
* The argument appears in CommandArguments as uint64_t.
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();
diff --git a/tools/nfdc/status-report.cpp b/tools/nfdc/status-report.cpp
index ff3e8a6..01ad5c6 100644
--- a/tools/nfdc/status-report.cpp
+++ b/tools/nfdc/status-report.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2017, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -39,7 +39,7 @@
if (s == "text") {
return ReportFormat::TEXT;
}
- BOOST_THROW_EXCEPTION(std::invalid_argument("unrecognized ReportFormat"));
+ BOOST_THROW_EXCEPTION(std::invalid_argument("unrecognized ReportFormat '" + s + "'"));
}
std::ostream&
@@ -64,7 +64,7 @@
Module& module = *sections[i];
module.fetchStatus(
controller,
- [] {},
+ []{},
[i, &errorCode] (uint32_t code, const std::string& reason) {
errorCode = i * 1000000 + code;
},