blob: 136a4f9eb3d4835bb9e3954da295f8b3cb820c06 [file] [log] [blame]
Junxiao Shi38f4ce92016-08-04 10:01:52 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberry84d3adc2017-08-09 23:31:40 -04002/*
Davide Pesaventob7bfcb92022-05-22 23:55:23 -04003 * Copyright (c) 2014-2022, Regents of the University of California,
Junxiao Shi38f4ce92016-08-04 10:01:52 +00004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
Junxiao Shi38f4ce92016-08-04 10:01:52 +000026#include "face-module.hpp"
Davide Pesavento990620a2022-06-05 00:25:53 -040027#include "face-helpers.hpp"
Junxiao Shi38f4ce92016-08-04 10:01:52 +000028
Davide Pesaventoa9b09b62022-06-04 14:07:25 -040029#include <boost/lexical_cast/try_lexical_convert.hpp>
30
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040031namespace nfd::tools::nfdc {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000032
33void
Junxiao Shi1f481fa2017-01-26 15:14:43 +000034FaceModule::registerCommands(CommandParser& parser)
35{
Junxiao Shi36e54292017-02-17 18:43:16 +000036 CommandDefinition defFaceList("face", "list");
37 defFaceList
38 .setTitle("print face list")
39 .addArg("remote", ArgValueType::FACE_URI, Required::NO, Positional::YES)
40 .addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO)
41 .addArg("scheme", ArgValueType::STRING, Required::NO, Positional::NO, "scheme");
42 parser.addCommand(defFaceList, &FaceModule::list);
Davide Pesaventod2147442018-02-19 23:58:17 -050043 parser.addAlias("face", "list", "");
Junxiao Shi36e54292017-02-17 18:43:16 +000044
Junxiao Shi1f481fa2017-01-26 15:14:43 +000045 CommandDefinition defFaceShow("face", "show");
46 defFaceShow
47 .setTitle("show face information")
48 .addArg("id", ArgValueType::UNSIGNED, Required::YES, Positional::YES);
49 parser.addCommand(defFaceShow, &FaceModule::show);
Junxiao Shi1d7fef52017-02-02 05:33:14 +000050
51 CommandDefinition defFaceCreate("face", "create");
52 defFaceCreate
53 .setTitle("create a face")
54 .addArg("remote", ArgValueType::FACE_URI, Required::YES, Positional::YES)
Junxiao Shi0d976922017-04-01 14:35:21 +000055 .addArg("persistency", ArgValueType::FACE_PERSISTENCY, Required::NO, Positional::YES)
Eric Newberry84d3adc2017-08-09 23:31:40 -040056 .addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO)
Eric Newberryde332452018-01-30 11:45:32 -070057 .addArg("reliability", ArgValueType::BOOLEAN, Required::NO, Positional::NO)
58 .addArg("congestion-marking", ArgValueType::BOOLEAN, Required::NO, Positional::NO)
59 .addArg("congestion-marking-interval", ArgValueType::UNSIGNED, Required::NO, Positional::NO)
Eric Newberry4f8dd962018-06-17 21:32:07 -070060 .addArg("default-congestion-threshold", ArgValueType::UNSIGNED, Required::NO, Positional::NO)
Eric Newberry13ff2592020-03-06 17:32:29 -080061 .addArg("mtu", ArgValueType::STRING, Required::NO, Positional::NO);
Junxiao Shi1d7fef52017-02-02 05:33:14 +000062 parser.addCommand(defFaceCreate, &FaceModule::create);
Junxiao Shi05dd4442017-02-06 22:50:07 +000063
64 CommandDefinition defFaceDestroy("face", "destroy");
65 defFaceDestroy
66 .setTitle("destroy a face")
67 .addArg("face", ArgValueType::FACE_ID_OR_URI, Required::YES, Positional::YES);
68 parser.addCommand(defFaceDestroy, &FaceModule::destroy);
Junxiao Shi1f481fa2017-01-26 15:14:43 +000069}
70
71void
Junxiao Shi36e54292017-02-17 18:43:16 +000072FaceModule::list(ExecuteContext& ctx)
73{
74 auto remoteUri = ctx.args.getOptional<FaceUri>("remote");
75 auto localUri = ctx.args.getOptional<FaceUri>("local");
76 auto uriScheme = ctx.args.getOptional<std::string>("scheme");
77
78 FaceQueryFilter filter;
79 if (remoteUri) {
80 filter.setRemoteUri(remoteUri->toString());
81 }
82 if (localUri) {
83 filter.setLocalUri(localUri->toString());
84 }
85 if (uriScheme) {
86 filter.setUriScheme(*uriScheme);
87 }
88
89 FindFace findFace(ctx);
90 FindFace::Code res = findFace.execute(filter, true);
91
92 ctx.exitCode = static_cast<int>(res);
93 switch (res) {
94 case FindFace::Code::OK:
95 for (const FaceStatus& item : findFace.getResults()) {
96 formatItemText(ctx.out, item, false);
97 ctx.out << '\n';
98 }
99 break;
100 case FindFace::Code::ERROR:
101 case FindFace::Code::NOT_FOUND:
102 case FindFace::Code::CANONIZE_ERROR:
103 ctx.err << findFace.getErrorReason() << '\n';
104 break;
105 default:
106 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
107 break;
108 }
109}
110
111void
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000112FaceModule::show(ExecuteContext& ctx)
113{
114 uint64_t faceId = ctx.args.get<uint64_t>("id");
115
Junxiao Shi8f803f22017-02-10 03:04:28 +0000116 FindFace findFace(ctx);
117 FindFace::Code res = findFace.execute(faceId);
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000118
Junxiao Shi8f803f22017-02-10 03:04:28 +0000119 ctx.exitCode = static_cast<int>(res);
120 switch (res) {
121 case FindFace::Code::OK:
122 formatItemText(ctx.out, findFace.getFaceStatus(), true);
123 break;
124 case FindFace::Code::ERROR:
125 case FindFace::Code::NOT_FOUND:
126 ctx.err << findFace.getErrorReason() << '\n';
127 break;
128 default:
129 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
130 break;
131 }
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000132}
133
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400134/** \brief Order persistency in NONE < ON_DEMAND < PERSISTENCY < PERMANENT.
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000135 */
136static bool
137persistencyLessThan(FacePersistency x, FacePersistency y)
138{
139 switch (x) {
140 case FacePersistency::FACE_PERSISTENCY_NONE:
141 return y != FacePersistency::FACE_PERSISTENCY_NONE;
142 case FacePersistency::FACE_PERSISTENCY_ON_DEMAND:
143 return y == FacePersistency::FACE_PERSISTENCY_PERSISTENT ||
144 y == FacePersistency::FACE_PERSISTENCY_PERMANENT;
145 case FacePersistency::FACE_PERSISTENCY_PERSISTENT:
146 return y == FacePersistency::FACE_PERSISTENCY_PERMANENT;
147 case FacePersistency::FACE_PERSISTENCY_PERMANENT:
148 return false;
149 }
150 return static_cast<int>(x) < static_cast<int>(y);
151}
152
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000153void
154FaceModule::create(ExecuteContext& ctx)
155{
Junxiao Shi0d976922017-04-01 14:35:21 +0000156 auto remoteUri = ctx.args.get<FaceUri>("remote");
157 auto localUri = ctx.args.getOptional<FaceUri>("local");
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000158 auto persistency = ctx.args.get<FacePersistency>("persistency", FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400159 auto lpReliability = ctx.args.getTribool("reliability");
Eric Newberryde332452018-01-30 11:45:32 -0700160 auto congestionMarking = ctx.args.getTribool("congestion-marking");
161 auto baseCongestionMarkingIntervalMs = ctx.args.getOptional<uint64_t>("congestion-marking-interval");
162 auto defaultCongestionThreshold = ctx.args.getOptional<uint64_t>("default-congestion-threshold");
Eric Newberry13ff2592020-03-06 17:32:29 -0800163 auto mtuArg = ctx.args.getOptional<std::string>("mtu");
164
165 // MTU is nominally a uint64_t, but can be the string value 'auto' to unset an override MTU
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400166 std::optional<uint64_t> mtu;
Eric Newberry13ff2592020-03-06 17:32:29 -0800167 if (mtuArg == "auto") {
168 mtu = std::numeric_limits<uint64_t>::max();
169 }
170 else if (mtuArg) {
171 // boost::lexical_cast<uint64_t> will accept negative numbers
172 int64_t v = -1;
173 if (!boost::conversion::try_lexical_convert<int64_t>(*mtuArg, v) || v < 0) {
174 ctx.exitCode = 2;
175 ctx.err << "MTU must either be a non-negative integer or 'auto'\n";
176 return;
177 }
178
179 mtu = static_cast<uint64_t>(v);
180 }
Eric Newberry84d3adc2017-08-09 23:31:40 -0400181
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400182 std::optional<FaceUri> canonicalRemote;
183 std::optional<FaceUri> canonicalLocal;
Junxiao Shi0d976922017-04-01 14:35:21 +0000184
Eric Newberryd656aff2020-04-03 00:30:38 -0700185 auto updateFace = [&] (ControlParameters respParams, ControlParameters resp) {
Eric Newberry84d3adc2017-08-09 23:31:40 -0400186 // faces/update response does not have FaceUris, copy from faces/create response
187 resp.setLocalUri(respParams.getLocalUri())
188 .setUri(respParams.getUri());
Eric Newberryd656aff2020-04-03 00:30:38 -0700189 printSuccess(ctx.out, "face-updated", resp);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400190 };
191
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000192 auto handle409 = [&] (const ControlResponse& resp) {
193 ControlParameters respParams(resp.getBody());
Eric Newberryd656aff2020-04-03 00:30:38 -0700194 if (respParams.getUri() != canonicalRemote->toString()) {
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000195 // we are conflicting with a different face, which is a general error
196 return false;
197 }
198
Eric Newberry13ff2592020-03-06 17:32:29 -0800199 bool isChangingParams = false;
200 ControlParameters params;
201 params.setFaceId(respParams.getFaceId());
202
Eric Newberry4f8dd962018-06-17 21:32:07 -0700203 if (mtu && (!respParams.hasMtu() || respParams.getMtu() != *mtu)) {
Eric Newberry13ff2592020-03-06 17:32:29 -0800204 isChangingParams = true;
205 params.setMtu(*mtu);
Eric Newberry4f8dd962018-06-17 21:32:07 -0700206 }
Eric Newberry13ff2592020-03-06 17:32:29 -0800207
208 if (persistencyLessThan(respParams.getFacePersistency(), persistency)) {
209 isChangingParams = true;
210 params.setFacePersistency(persistency);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000211 }
Eric Newberryde332452018-01-30 11:45:32 -0700212
Eric Newberry13ff2592020-03-06 17:32:29 -0800213 if (!boost::logic::indeterminate(lpReliability) &&
214 lpReliability != respParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
215 isChangingParams = true;
216 params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, bool(lpReliability));
217 }
Eric Newberryde332452018-01-30 11:45:32 -0700218
Eric Newberry13ff2592020-03-06 17:32:29 -0800219 if (!boost::logic::indeterminate(congestionMarking) &&
220 congestionMarking != respParams.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
221 isChangingParams = true;
222 params.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, bool(congestionMarking));
223 }
Eric Newberryde332452018-01-30 11:45:32 -0700224
Eric Newberry13ff2592020-03-06 17:32:29 -0800225 if (baseCongestionMarkingIntervalMs) {
226 isChangingParams = true;
227 params.setBaseCongestionMarkingInterval(time::milliseconds(*baseCongestionMarkingIntervalMs));
228 }
Eric Newberryde332452018-01-30 11:45:32 -0700229
Eric Newberry13ff2592020-03-06 17:32:29 -0800230 if (defaultCongestionThreshold) {
231 isChangingParams = true;
232 params.setDefaultCongestionThreshold(*defaultCongestionThreshold);
233 }
234
235 if (isChangingParams) {
Eric Newberry84d3adc2017-08-09 23:31:40 -0400236 ctx.controller.start<ndn::nfd::FaceUpdateCommand>(
Eric Newberry13ff2592020-03-06 17:32:29 -0800237 params,
Davide Pesavento412c9822021-07-02 00:21:05 -0400238 [=, &updateFace] (const auto& cp) { updateFace(respParams, cp); },
Eric Newberry13ff2592020-03-06 17:32:29 -0800239 ctx.makeCommandFailureHandler("updating face"),
240 ctx.makeCommandOptions());
Eric Newberry84d3adc2017-08-09 23:31:40 -0400241 }
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000242 else {
Eric Newberry84d3adc2017-08-09 23:31:40 -0400243 // don't do anything
Eric Newberryd656aff2020-04-03 00:30:38 -0700244 printSuccess(ctx.out, "face-exists", respParams);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000245 }
Eric Newberry13ff2592020-03-06 17:32:29 -0800246
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000247 return true;
248 };
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000249
Junxiao Shi0d976922017-04-01 14:35:21 +0000250 auto doCreateFace = [&] {
251 ControlParameters params;
Eric Newberryd656aff2020-04-03 00:30:38 -0700252 params.setUri(canonicalRemote->toString());
Junxiao Shi0d976922017-04-01 14:35:21 +0000253 if (canonicalLocal) {
254 params.setLocalUri(canonicalLocal->toString());
255 }
256 params.setFacePersistency(persistency);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400257 if (!boost::logic::indeterminate(lpReliability)) {
Davide Pesaventofa2aa502019-03-22 13:30:02 -0400258 params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, bool(lpReliability));
Eric Newberry84d3adc2017-08-09 23:31:40 -0400259 }
Eric Newberryde332452018-01-30 11:45:32 -0700260 if (!boost::logic::indeterminate(congestionMarking)) {
Davide Pesaventofa2aa502019-03-22 13:30:02 -0400261 params.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, bool(congestionMarking));
Eric Newberryde332452018-01-30 11:45:32 -0700262 }
263 if (baseCongestionMarkingIntervalMs) {
264 params.setBaseCongestionMarkingInterval(time::milliseconds(*baseCongestionMarkingIntervalMs));
265 }
266 if (defaultCongestionThreshold) {
267 params.setDefaultCongestionThreshold(*defaultCongestionThreshold);
268 }
Eric Newberry4f8dd962018-06-17 21:32:07 -0700269 if (mtu) {
270 params.setMtu(*mtu);
271 }
Junxiao Shi0d976922017-04-01 14:35:21 +0000272
273 ctx.controller.start<ndn::nfd::FaceCreateCommand>(
274 params,
Eric Newberryd656aff2020-04-03 00:30:38 -0700275 [&] (const ControlParameters& resp) {
276 printSuccess(ctx.out, "face-created", resp);
277 },
Junxiao Shi0d976922017-04-01 14:35:21 +0000278 [&] (const ControlResponse& resp) {
279 if (resp.getCode() == 409 && handle409(resp)) {
280 return;
281 }
282 ctx.makeCommandFailureHandler("creating face")(resp); // invoke general error handler
283 },
284 ctx.makeCommandOptions());
285 };
286
Eric Newberryd656aff2020-04-03 00:30:38 -0700287 std::string error;
288 std::tie(canonicalRemote, error) = canonize(ctx, remoteUri);
289 if (canonicalRemote) {
290 // RemoteUri canonization successful
291 if (localUri) {
292 std::tie(canonicalLocal, error) = canonize(ctx, *localUri);
293 if (canonicalLocal) {
294 // LocalUri canonization successful
Junxiao Shi0d976922017-04-01 14:35:21 +0000295 doCreateFace();
296 }
Eric Newberryd656aff2020-04-03 00:30:38 -0700297 else {
298 // LocalUri canonization failure
299 auto canonizationError = canonizeErrorHelper(*localUri, error, "local FaceUri");
300 ctx.exitCode = static_cast<int>(canonizationError.first);
301 ctx.err << canonizationError.second << '\n';
302 }
303 }
304 else {
305 doCreateFace();
306 }
307 }
308 else {
309 // RemoteUri canonization failure
310 auto canonizationError = canonizeErrorHelper(remoteUri, error, "remote FaceUri");
311 ctx.exitCode = static_cast<int>(canonizationError.first);
312 ctx.err << canonizationError.second << '\n';
313 }
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000314
315 ctx.face.processEvents();
316}
317
318void
Junxiao Shi05dd4442017-02-06 22:50:07 +0000319FaceModule::destroy(ExecuteContext& ctx)
320{
Junxiao Shi05dd4442017-02-06 22:50:07 +0000321 FindFace findFace(ctx);
Davide Pesavento8b663a92018-11-21 22:57:20 -0500322 FindFace::Code res = findFace.execute(ctx.args.at("face"));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000323
324 ctx.exitCode = static_cast<int>(res);
325 switch (res) {
326 case FindFace::Code::OK:
327 break;
328 case FindFace::Code::ERROR:
329 case FindFace::Code::CANONIZE_ERROR:
330 case FindFace::Code::NOT_FOUND:
331 ctx.err << findFace.getErrorReason() << '\n';
332 return;
333 case FindFace::Code::AMBIGUOUS:
334 ctx.err << "Multiple faces match specified remote FaceUri. Re-run the command with a FaceId:";
335 findFace.printDisambiguation(ctx.err, FindFace::DisambiguationStyle::LOCAL_URI);
336 ctx.err << '\n';
337 return;
338 default:
339 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
340 return;
341 }
342
343 const FaceStatus& face = findFace.getFaceStatus();
344
345 ctx.controller.start<ndn::nfd::FaceDestroyCommand>(
346 ControlParameters().setFaceId(face.getFaceId()),
347 [&] (const ControlParameters& resp) {
Eric Newberryd656aff2020-04-03 00:30:38 -0700348 // We can't use printSuccess because some face attributes come from FaceStatus not ControlResponse
Junxiao Shi05dd4442017-02-06 22:50:07 +0000349 ctx.out << "face-destroyed ";
350 text::ItemAttributes ia;
351 ctx.out << ia("id") << face.getFaceId()
352 << ia("local") << face.getLocalUri()
353 << ia("remote") << face.getRemoteUri()
Eric Newberryde332452018-01-30 11:45:32 -0700354 << ia("persistency") << face.getFacePersistency();
355 printFaceParams(ctx.out, ia, resp);
Junxiao Shi05dd4442017-02-06 22:50:07 +0000356 },
357 ctx.makeCommandFailureHandler("destroying face"),
358 ctx.makeCommandOptions());
359
360 ctx.face.processEvents();
361}
362
363void
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000364FaceModule::fetchStatus(Controller& controller,
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400365 const std::function<void()>& onSuccess,
Junxiao Shi29b41282016-08-22 03:47:02 +0000366 const Controller::DatasetFailCallback& onFailure,
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000367 const CommandOptions& options)
368{
369 controller.fetch<ndn::nfd::FaceDataset>(
Davide Pesavento990620a2022-06-05 00:25:53 -0400370 [this, onSuccess] (const auto& result) {
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000371 m_status = result;
372 onSuccess();
373 },
374 onFailure, options);
375}
376
377void
378FaceModule::formatStatusXml(std::ostream& os) const
379{
380 os << "<faces>";
381 for (const FaceStatus& item : m_status) {
382 this->formatItemXml(os, item);
383 }
384 os << "</faces>";
385}
386
387void
388FaceModule::formatItemXml(std::ostream& os, const FaceStatus& item) const
389{
390 os << "<face>";
391
392 os << "<faceId>" << item.getFaceId() << "</faceId>";
393 os << "<remoteUri>" << xml::Text{item.getRemoteUri()} << "</remoteUri>";
394 os << "<localUri>" << xml::Text{item.getLocalUri()} << "</localUri>";
395
396 if (item.hasExpirationPeriod()) {
397 os << "<expirationPeriod>" << xml::formatDuration(item.getExpirationPeriod())
398 << "</expirationPeriod>";
399 }
400 os << "<faceScope>" << item.getFaceScope() << "</faceScope>";
401 os << "<facePersistency>" << item.getFacePersistency() << "</facePersistency>";
402 os << "<linkType>" << item.getLinkType() << "</linkType>";
403
Eric Newberryde332452018-01-30 11:45:32 -0700404 if (!item.hasBaseCongestionMarkingInterval() && !item.hasDefaultCongestionThreshold()) {
405 os << "<congestion/>";
406 }
407 else {
408 os << "<congestion>";
409 if (item.hasBaseCongestionMarkingInterval()) {
410 os << "<baseMarkingInterval>" << xml::formatDuration(item.getBaseCongestionMarkingInterval())
411 << "</baseMarkingInterval>";
412 }
413 if (item.hasDefaultCongestionThreshold()) {
414 os << "<defaultThreshold>" << item.getDefaultCongestionThreshold() << "</defaultThreshold>";
415 }
416 os << "</congestion>";
417 }
418
Eric Newberry4f8dd962018-06-17 21:32:07 -0700419 if (item.hasMtu()) {
420 os << "<mtu>" << item.getMtu() << "</mtu>";
421 }
422
Eric Newberry6d932e82016-11-24 05:05:43 +0000423 if (item.getFlags() == 0) {
424 os << "<flags/>";
425 }
426 else {
427 os << "<flags>";
Junxiao Shi7a36ac72018-03-21 15:23:22 +0000428 os << xml::Flag{"localFieldsEnabled", item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)};
429 os << xml::Flag{"lpReliabilityEnabled", item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)};
430 os << xml::Flag{"congestionMarkingEnabled", item.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)};
Eric Newberry6d932e82016-11-24 05:05:43 +0000431 os << "</flags>";
432 }
433
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000434 os << "<packetCounters>";
435 os << "<incomingPackets>"
436 << "<nInterests>" << item.getNInInterests() << "</nInterests>"
Junxiao Shif03d4792017-04-06 16:41:22 +0000437 << "<nData>" << item.getNInData() << "</nData>"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000438 << "<nNacks>" << item.getNInNacks() << "</nNacks>"
439 << "</incomingPackets>";
440 os << "<outgoingPackets>"
441 << "<nInterests>" << item.getNOutInterests() << "</nInterests>"
Junxiao Shif03d4792017-04-06 16:41:22 +0000442 << "<nData>" << item.getNOutData() << "</nData>"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000443 << "<nNacks>" << item.getNOutNacks() << "</nNacks>"
444 << "</outgoingPackets>";
445 os << "</packetCounters>";
446
447 os << "<byteCounters>";
448 os << "<incomingBytes>" << item.getNInBytes() << "</incomingBytes>";
449 os << "<outgoingBytes>" << item.getNOutBytes() << "</outgoingBytes>";
450 os << "</byteCounters>";
451
452 os << "</face>";
453}
454
455void
456FaceModule::formatStatusText(std::ostream& os) const
457{
458 os << "Faces:\n";
459 for (const FaceStatus& item : m_status) {
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000460 os << " ";
461 formatItemText(os, item, false);
462 os << '\n';
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000463 }
464}
465
466void
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000467FaceModule::formatItemText(std::ostream& os, const FaceStatus& item, bool wantMultiLine)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000468{
Eric Newberryde332452018-01-30 11:45:32 -0700469 text::ItemAttributes ia(wantMultiLine, 10);
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000470
471 os << ia("faceid") << item.getFaceId();
472 os << ia("remote") << item.getRemoteUri();
473 os << ia("local") << item.getLocalUri();
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000474
475 if (item.hasExpirationPeriod()) {
Eric Newberryde332452018-01-30 11:45:32 -0700476 os << ia("expires") << text::formatDuration<time::seconds>(item.getExpirationPeriod());
477 }
478
479 if (item.hasBaseCongestionMarkingInterval() || item.hasDefaultCongestionThreshold()) {
480 os << ia("congestion") << "{";
481 text::Separator congestionSep("", " ");
482 if (item.hasBaseCongestionMarkingInterval()) {
483 os << congestionSep << "base-marking-interval="
484 << text::formatDuration<time::milliseconds>(item.getBaseCongestionMarkingInterval());
485 }
486 if (item.hasDefaultCongestionThreshold()) {
487 os << congestionSep << "default-threshold=" << item.getDefaultCongestionThreshold() << "B";
488 }
489 os << "}";
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000490 }
491
Eric Newberry4f8dd962018-06-17 21:32:07 -0700492 if (item.hasMtu()) {
493 os << ia("mtu") << item.getMtu();
494 }
495
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000496 os << ia("counters")
497 << "{in={"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000498 << item.getNInInterests() << "i "
Junxiao Shif03d4792017-04-06 16:41:22 +0000499 << item.getNInData() << "d "
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000500 << item.getNInNacks() << "n "
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000501 << item.getNInBytes() << "B} "
502 << "out={"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000503 << item.getNOutInterests() << "i "
Junxiao Shif03d4792017-04-06 16:41:22 +0000504 << item.getNOutData() << "d "
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000505 << item.getNOutNacks() << "n "
506 << item.getNOutBytes() << "B}}";
507
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000508 os << ia("flags") << '{';
509 text::Separator flagSep("", " ");
510 os << flagSep << item.getFaceScope();
511 os << flagSep << item.getFacePersistency();
512 os << flagSep << item.getLinkType();
Eric Newberry6d932e82016-11-24 05:05:43 +0000513 if (item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)) {
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000514 os << flagSep << "local-fields";
Eric Newberry6d932e82016-11-24 05:05:43 +0000515 }
Eric Newberry84d3adc2017-08-09 23:31:40 -0400516 if (item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
517 os << flagSep << "lp-reliability";
518 }
Eric Newberryde332452018-01-30 11:45:32 -0700519 if (item.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
520 os << flagSep << "congestion-marking";
521 }
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000522 os << '}';
Eric Newberry6d932e82016-11-24 05:05:43 +0000523
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000524 os << ia.end();
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000525}
526
Eric Newberryde332452018-01-30 11:45:32 -0700527void
Eric Newberryd656aff2020-04-03 00:30:38 -0700528FaceModule::printSuccess(std::ostream& os,
529 const std::string& actionSummary,
530 const ControlParameters& resp)
531{
532 text::ItemAttributes ia;
533 os << actionSummary << ' '
534 << ia("id") << resp.getFaceId()
535 << ia("local") << resp.getLocalUri()
536 << ia("remote") << resp.getUri()
537 << ia("persistency") << resp.getFacePersistency();
538 printFaceParams(os, ia, resp);
539}
540
541void
Eric Newberryde332452018-01-30 11:45:32 -0700542FaceModule::printFaceParams(std::ostream& os, text::ItemAttributes& ia, const ControlParameters& resp)
543{
Junxiao Shi8dc473a2018-03-02 15:10:18 +0000544 os << ia("reliability") << text::OnOff{resp.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)}
545 << ia("congestion-marking") << text::OnOff{resp.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)};
Eric Newberryde332452018-01-30 11:45:32 -0700546 if (resp.hasBaseCongestionMarkingInterval()) {
547 os << ia("congestion-marking-interval")
548 << text::formatDuration<time::milliseconds>(resp.getBaseCongestionMarkingInterval());
549 }
550 if (resp.hasDefaultCongestionThreshold()) {
551 os << ia("default-congestion-threshold") << resp.getDefaultCongestionThreshold() << "B";
552 }
Eric Newberry4f8dd962018-06-17 21:32:07 -0700553 if (resp.hasMtu()) {
554 os << ia("mtu") << resp.getMtu();
555 }
Eric Newberryde332452018-01-30 11:45:32 -0700556 os << '\n';
557}
558
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400559} // namespace nfd::tools::nfdc