blob: 4d9d3a2c5aeff0ecee8abc4a662aa7ca28c5c7f3 [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"
Eric Newberryd656aff2020-04-03 00:30:38 -070027#include "canonizer.hpp"
Junxiao Shi05dd4442017-02-06 22:50:07 +000028#include "find-face.hpp"
Junxiao Shi38f4ce92016-08-04 10:01:52 +000029
Davide Pesaventoa9b09b62022-06-04 14:07:25 -040030#include <boost/lexical_cast/try_lexical_convert.hpp>
31
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040032namespace nfd::tools::nfdc {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000033
34void
Junxiao Shi1f481fa2017-01-26 15:14:43 +000035FaceModule::registerCommands(CommandParser& parser)
36{
Junxiao Shi36e54292017-02-17 18:43:16 +000037 CommandDefinition defFaceList("face", "list");
38 defFaceList
39 .setTitle("print face list")
40 .addArg("remote", ArgValueType::FACE_URI, Required::NO, Positional::YES)
41 .addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO)
42 .addArg("scheme", ArgValueType::STRING, Required::NO, Positional::NO, "scheme");
43 parser.addCommand(defFaceList, &FaceModule::list);
Davide Pesaventod2147442018-02-19 23:58:17 -050044 parser.addAlias("face", "list", "");
Junxiao Shi36e54292017-02-17 18:43:16 +000045
Junxiao Shi1f481fa2017-01-26 15:14:43 +000046 CommandDefinition defFaceShow("face", "show");
47 defFaceShow
48 .setTitle("show face information")
49 .addArg("id", ArgValueType::UNSIGNED, Required::YES, Positional::YES);
50 parser.addCommand(defFaceShow, &FaceModule::show);
Junxiao Shi1d7fef52017-02-02 05:33:14 +000051
52 CommandDefinition defFaceCreate("face", "create");
53 defFaceCreate
54 .setTitle("create a face")
55 .addArg("remote", ArgValueType::FACE_URI, Required::YES, Positional::YES)
Junxiao Shi0d976922017-04-01 14:35:21 +000056 .addArg("persistency", ArgValueType::FACE_PERSISTENCY, Required::NO, Positional::YES)
Eric Newberry84d3adc2017-08-09 23:31:40 -040057 .addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO)
Eric Newberryde332452018-01-30 11:45:32 -070058 .addArg("reliability", ArgValueType::BOOLEAN, Required::NO, Positional::NO)
59 .addArg("congestion-marking", ArgValueType::BOOLEAN, Required::NO, Positional::NO)
60 .addArg("congestion-marking-interval", ArgValueType::UNSIGNED, Required::NO, Positional::NO)
Eric Newberry4f8dd962018-06-17 21:32:07 -070061 .addArg("default-congestion-threshold", ArgValueType::UNSIGNED, Required::NO, Positional::NO)
Eric Newberry13ff2592020-03-06 17:32:29 -080062 .addArg("mtu", ArgValueType::STRING, Required::NO, Positional::NO);
Junxiao Shi1d7fef52017-02-02 05:33:14 +000063 parser.addCommand(defFaceCreate, &FaceModule::create);
Junxiao Shi05dd4442017-02-06 22:50:07 +000064
65 CommandDefinition defFaceDestroy("face", "destroy");
66 defFaceDestroy
67 .setTitle("destroy a face")
68 .addArg("face", ArgValueType::FACE_ID_OR_URI, Required::YES, Positional::YES);
69 parser.addCommand(defFaceDestroy, &FaceModule::destroy);
Junxiao Shi1f481fa2017-01-26 15:14:43 +000070}
71
72void
Junxiao Shi36e54292017-02-17 18:43:16 +000073FaceModule::list(ExecuteContext& ctx)
74{
75 auto remoteUri = ctx.args.getOptional<FaceUri>("remote");
76 auto localUri = ctx.args.getOptional<FaceUri>("local");
77 auto uriScheme = ctx.args.getOptional<std::string>("scheme");
78
79 FaceQueryFilter filter;
80 if (remoteUri) {
81 filter.setRemoteUri(remoteUri->toString());
82 }
83 if (localUri) {
84 filter.setLocalUri(localUri->toString());
85 }
86 if (uriScheme) {
87 filter.setUriScheme(*uriScheme);
88 }
89
90 FindFace findFace(ctx);
91 FindFace::Code res = findFace.execute(filter, true);
92
93 ctx.exitCode = static_cast<int>(res);
94 switch (res) {
95 case FindFace::Code::OK:
96 for (const FaceStatus& item : findFace.getResults()) {
97 formatItemText(ctx.out, item, false);
98 ctx.out << '\n';
99 }
100 break;
101 case FindFace::Code::ERROR:
102 case FindFace::Code::NOT_FOUND:
103 case FindFace::Code::CANONIZE_ERROR:
104 ctx.err << findFace.getErrorReason() << '\n';
105 break;
106 default:
107 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
108 break;
109 }
110}
111
112void
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000113FaceModule::show(ExecuteContext& ctx)
114{
115 uint64_t faceId = ctx.args.get<uint64_t>("id");
116
Junxiao Shi8f803f22017-02-10 03:04:28 +0000117 FindFace findFace(ctx);
118 FindFace::Code res = findFace.execute(faceId);
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000119
Junxiao Shi8f803f22017-02-10 03:04:28 +0000120 ctx.exitCode = static_cast<int>(res);
121 switch (res) {
122 case FindFace::Code::OK:
123 formatItemText(ctx.out, findFace.getFaceStatus(), true);
124 break;
125 case FindFace::Code::ERROR:
126 case FindFace::Code::NOT_FOUND:
127 ctx.err << findFace.getErrorReason() << '\n';
128 break;
129 default:
130 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
131 break;
132 }
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000133}
134
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000135/** \brief order persistency in NONE < ON_DEMAND < PERSISTENCY < PERMANENT
136 */
137static bool
138persistencyLessThan(FacePersistency x, FacePersistency y)
139{
140 switch (x) {
141 case FacePersistency::FACE_PERSISTENCY_NONE:
142 return y != FacePersistency::FACE_PERSISTENCY_NONE;
143 case FacePersistency::FACE_PERSISTENCY_ON_DEMAND:
144 return y == FacePersistency::FACE_PERSISTENCY_PERSISTENT ||
145 y == FacePersistency::FACE_PERSISTENCY_PERMANENT;
146 case FacePersistency::FACE_PERSISTENCY_PERSISTENT:
147 return y == FacePersistency::FACE_PERSISTENCY_PERMANENT;
148 case FacePersistency::FACE_PERSISTENCY_PERMANENT:
149 return false;
150 }
151 return static_cast<int>(x) < static_cast<int>(y);
152}
153
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000154void
155FaceModule::create(ExecuteContext& ctx)
156{
Junxiao Shi0d976922017-04-01 14:35:21 +0000157 auto remoteUri = ctx.args.get<FaceUri>("remote");
158 auto localUri = ctx.args.getOptional<FaceUri>("local");
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000159 auto persistency = ctx.args.get<FacePersistency>("persistency", FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400160 auto lpReliability = ctx.args.getTribool("reliability");
Eric Newberryde332452018-01-30 11:45:32 -0700161 auto congestionMarking = ctx.args.getTribool("congestion-marking");
162 auto baseCongestionMarkingIntervalMs = ctx.args.getOptional<uint64_t>("congestion-marking-interval");
163 auto defaultCongestionThreshold = ctx.args.getOptional<uint64_t>("default-congestion-threshold");
Eric Newberry13ff2592020-03-06 17:32:29 -0800164 auto mtuArg = ctx.args.getOptional<std::string>("mtu");
165
166 // 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 -0400167 std::optional<uint64_t> mtu;
Eric Newberry13ff2592020-03-06 17:32:29 -0800168 if (mtuArg == "auto") {
169 mtu = std::numeric_limits<uint64_t>::max();
170 }
171 else if (mtuArg) {
172 // boost::lexical_cast<uint64_t> will accept negative numbers
173 int64_t v = -1;
174 if (!boost::conversion::try_lexical_convert<int64_t>(*mtuArg, v) || v < 0) {
175 ctx.exitCode = 2;
176 ctx.err << "MTU must either be a non-negative integer or 'auto'\n";
177 return;
178 }
179
180 mtu = static_cast<uint64_t>(v);
181 }
Eric Newberry84d3adc2017-08-09 23:31:40 -0400182
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400183 std::optional<FaceUri> canonicalRemote;
184 std::optional<FaceUri> canonicalLocal;
Junxiao Shi0d976922017-04-01 14:35:21 +0000185
Eric Newberryd656aff2020-04-03 00:30:38 -0700186 auto updateFace = [&] (ControlParameters respParams, ControlParameters resp) {
Eric Newberry84d3adc2017-08-09 23:31:40 -0400187 // faces/update response does not have FaceUris, copy from faces/create response
188 resp.setLocalUri(respParams.getLocalUri())
189 .setUri(respParams.getUri());
Eric Newberryd656aff2020-04-03 00:30:38 -0700190 printSuccess(ctx.out, "face-updated", resp);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400191 };
192
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000193 auto handle409 = [&] (const ControlResponse& resp) {
194 ControlParameters respParams(resp.getBody());
Eric Newberryd656aff2020-04-03 00:30:38 -0700195 if (respParams.getUri() != canonicalRemote->toString()) {
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000196 // we are conflicting with a different face, which is a general error
197 return false;
198 }
199
Eric Newberry13ff2592020-03-06 17:32:29 -0800200 bool isChangingParams = false;
201 ControlParameters params;
202 params.setFaceId(respParams.getFaceId());
203
Eric Newberry4f8dd962018-06-17 21:32:07 -0700204 if (mtu && (!respParams.hasMtu() || respParams.getMtu() != *mtu)) {
Eric Newberry13ff2592020-03-06 17:32:29 -0800205 isChangingParams = true;
206 params.setMtu(*mtu);
Eric Newberry4f8dd962018-06-17 21:32:07 -0700207 }
Eric Newberry13ff2592020-03-06 17:32:29 -0800208
209 if (persistencyLessThan(respParams.getFacePersistency(), persistency)) {
210 isChangingParams = true;
211 params.setFacePersistency(persistency);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000212 }
Eric Newberryde332452018-01-30 11:45:32 -0700213
Eric Newberry13ff2592020-03-06 17:32:29 -0800214 if (!boost::logic::indeterminate(lpReliability) &&
215 lpReliability != respParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
216 isChangingParams = true;
217 params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, bool(lpReliability));
218 }
Eric Newberryde332452018-01-30 11:45:32 -0700219
Eric Newberry13ff2592020-03-06 17:32:29 -0800220 if (!boost::logic::indeterminate(congestionMarking) &&
221 congestionMarking != respParams.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
222 isChangingParams = true;
223 params.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, bool(congestionMarking));
224 }
Eric Newberryde332452018-01-30 11:45:32 -0700225
Eric Newberry13ff2592020-03-06 17:32:29 -0800226 if (baseCongestionMarkingIntervalMs) {
227 isChangingParams = true;
228 params.setBaseCongestionMarkingInterval(time::milliseconds(*baseCongestionMarkingIntervalMs));
229 }
Eric Newberryde332452018-01-30 11:45:32 -0700230
Eric Newberry13ff2592020-03-06 17:32:29 -0800231 if (defaultCongestionThreshold) {
232 isChangingParams = true;
233 params.setDefaultCongestionThreshold(*defaultCongestionThreshold);
234 }
235
236 if (isChangingParams) {
Eric Newberry84d3adc2017-08-09 23:31:40 -0400237 ctx.controller.start<ndn::nfd::FaceUpdateCommand>(
Eric Newberry13ff2592020-03-06 17:32:29 -0800238 params,
Davide Pesavento412c9822021-07-02 00:21:05 -0400239 [=, &updateFace] (const auto& cp) { updateFace(respParams, cp); },
Eric Newberry13ff2592020-03-06 17:32:29 -0800240 ctx.makeCommandFailureHandler("updating face"),
241 ctx.makeCommandOptions());
Eric Newberry84d3adc2017-08-09 23:31:40 -0400242 }
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000243 else {
Eric Newberry84d3adc2017-08-09 23:31:40 -0400244 // don't do anything
Eric Newberryd656aff2020-04-03 00:30:38 -0700245 printSuccess(ctx.out, "face-exists", respParams);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000246 }
Eric Newberry13ff2592020-03-06 17:32:29 -0800247
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000248 return true;
249 };
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000250
Junxiao Shi0d976922017-04-01 14:35:21 +0000251 auto doCreateFace = [&] {
252 ControlParameters params;
Eric Newberryd656aff2020-04-03 00:30:38 -0700253 params.setUri(canonicalRemote->toString());
Junxiao Shi0d976922017-04-01 14:35:21 +0000254 if (canonicalLocal) {
255 params.setLocalUri(canonicalLocal->toString());
256 }
257 params.setFacePersistency(persistency);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400258 if (!boost::logic::indeterminate(lpReliability)) {
Davide Pesaventofa2aa502019-03-22 13:30:02 -0400259 params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, bool(lpReliability));
Eric Newberry84d3adc2017-08-09 23:31:40 -0400260 }
Eric Newberryde332452018-01-30 11:45:32 -0700261 if (!boost::logic::indeterminate(congestionMarking)) {
Davide Pesaventofa2aa502019-03-22 13:30:02 -0400262 params.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, bool(congestionMarking));
Eric Newberryde332452018-01-30 11:45:32 -0700263 }
264 if (baseCongestionMarkingIntervalMs) {
265 params.setBaseCongestionMarkingInterval(time::milliseconds(*baseCongestionMarkingIntervalMs));
266 }
267 if (defaultCongestionThreshold) {
268 params.setDefaultCongestionThreshold(*defaultCongestionThreshold);
269 }
Eric Newberry4f8dd962018-06-17 21:32:07 -0700270 if (mtu) {
271 params.setMtu(*mtu);
272 }
Junxiao Shi0d976922017-04-01 14:35:21 +0000273
274 ctx.controller.start<ndn::nfd::FaceCreateCommand>(
275 params,
Eric Newberryd656aff2020-04-03 00:30:38 -0700276 [&] (const ControlParameters& resp) {
277 printSuccess(ctx.out, "face-created", resp);
278 },
Junxiao Shi0d976922017-04-01 14:35:21 +0000279 [&] (const ControlResponse& resp) {
280 if (resp.getCode() == 409 && handle409(resp)) {
281 return;
282 }
283 ctx.makeCommandFailureHandler("creating face")(resp); // invoke general error handler
284 },
285 ctx.makeCommandOptions());
286 };
287
Eric Newberryd656aff2020-04-03 00:30:38 -0700288 std::string error;
289 std::tie(canonicalRemote, error) = canonize(ctx, remoteUri);
290 if (canonicalRemote) {
291 // RemoteUri canonization successful
292 if (localUri) {
293 std::tie(canonicalLocal, error) = canonize(ctx, *localUri);
294 if (canonicalLocal) {
295 // LocalUri canonization successful
Junxiao Shi0d976922017-04-01 14:35:21 +0000296 doCreateFace();
297 }
Eric Newberryd656aff2020-04-03 00:30:38 -0700298 else {
299 // LocalUri canonization failure
300 auto canonizationError = canonizeErrorHelper(*localUri, error, "local FaceUri");
301 ctx.exitCode = static_cast<int>(canonizationError.first);
302 ctx.err << canonizationError.second << '\n';
303 }
304 }
305 else {
306 doCreateFace();
307 }
308 }
309 else {
310 // RemoteUri canonization failure
311 auto canonizationError = canonizeErrorHelper(remoteUri, error, "remote FaceUri");
312 ctx.exitCode = static_cast<int>(canonizationError.first);
313 ctx.err << canonizationError.second << '\n';
314 }
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000315
316 ctx.face.processEvents();
317}
318
319void
Junxiao Shi05dd4442017-02-06 22:50:07 +0000320FaceModule::destroy(ExecuteContext& ctx)
321{
Junxiao Shi05dd4442017-02-06 22:50:07 +0000322 FindFace findFace(ctx);
Davide Pesavento8b663a92018-11-21 22:57:20 -0500323 FindFace::Code res = findFace.execute(ctx.args.at("face"));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000324
325 ctx.exitCode = static_cast<int>(res);
326 switch (res) {
327 case FindFace::Code::OK:
328 break;
329 case FindFace::Code::ERROR:
330 case FindFace::Code::CANONIZE_ERROR:
331 case FindFace::Code::NOT_FOUND:
332 ctx.err << findFace.getErrorReason() << '\n';
333 return;
334 case FindFace::Code::AMBIGUOUS:
335 ctx.err << "Multiple faces match specified remote FaceUri. Re-run the command with a FaceId:";
336 findFace.printDisambiguation(ctx.err, FindFace::DisambiguationStyle::LOCAL_URI);
337 ctx.err << '\n';
338 return;
339 default:
340 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
341 return;
342 }
343
344 const FaceStatus& face = findFace.getFaceStatus();
345
346 ctx.controller.start<ndn::nfd::FaceDestroyCommand>(
347 ControlParameters().setFaceId(face.getFaceId()),
348 [&] (const ControlParameters& resp) {
Eric Newberryd656aff2020-04-03 00:30:38 -0700349 // We can't use printSuccess because some face attributes come from FaceStatus not ControlResponse
Junxiao Shi05dd4442017-02-06 22:50:07 +0000350 ctx.out << "face-destroyed ";
351 text::ItemAttributes ia;
352 ctx.out << ia("id") << face.getFaceId()
353 << ia("local") << face.getLocalUri()
354 << ia("remote") << face.getRemoteUri()
Eric Newberryde332452018-01-30 11:45:32 -0700355 << ia("persistency") << face.getFacePersistency();
356 printFaceParams(ctx.out, ia, resp);
Junxiao Shi05dd4442017-02-06 22:50:07 +0000357 },
358 ctx.makeCommandFailureHandler("destroying face"),
359 ctx.makeCommandOptions());
360
361 ctx.face.processEvents();
362}
363
364void
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000365FaceModule::fetchStatus(Controller& controller,
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400366 const std::function<void()>& onSuccess,
Junxiao Shi29b41282016-08-22 03:47:02 +0000367 const Controller::DatasetFailCallback& onFailure,
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000368 const CommandOptions& options)
369{
370 controller.fetch<ndn::nfd::FaceDataset>(
371 [this, onSuccess] (const std::vector<FaceStatus>& result) {
372 m_status = result;
373 onSuccess();
374 },
375 onFailure, options);
376}
377
378void
379FaceModule::formatStatusXml(std::ostream& os) const
380{
381 os << "<faces>";
382 for (const FaceStatus& item : m_status) {
383 this->formatItemXml(os, item);
384 }
385 os << "</faces>";
386}
387
388void
389FaceModule::formatItemXml(std::ostream& os, const FaceStatus& item) const
390{
391 os << "<face>";
392
393 os << "<faceId>" << item.getFaceId() << "</faceId>";
394 os << "<remoteUri>" << xml::Text{item.getRemoteUri()} << "</remoteUri>";
395 os << "<localUri>" << xml::Text{item.getLocalUri()} << "</localUri>";
396
397 if (item.hasExpirationPeriod()) {
398 os << "<expirationPeriod>" << xml::formatDuration(item.getExpirationPeriod())
399 << "</expirationPeriod>";
400 }
401 os << "<faceScope>" << item.getFaceScope() << "</faceScope>";
402 os << "<facePersistency>" << item.getFacePersistency() << "</facePersistency>";
403 os << "<linkType>" << item.getLinkType() << "</linkType>";
404
Eric Newberryde332452018-01-30 11:45:32 -0700405 if (!item.hasBaseCongestionMarkingInterval() && !item.hasDefaultCongestionThreshold()) {
406 os << "<congestion/>";
407 }
408 else {
409 os << "<congestion>";
410 if (item.hasBaseCongestionMarkingInterval()) {
411 os << "<baseMarkingInterval>" << xml::formatDuration(item.getBaseCongestionMarkingInterval())
412 << "</baseMarkingInterval>";
413 }
414 if (item.hasDefaultCongestionThreshold()) {
415 os << "<defaultThreshold>" << item.getDefaultCongestionThreshold() << "</defaultThreshold>";
416 }
417 os << "</congestion>";
418 }
419
Eric Newberry4f8dd962018-06-17 21:32:07 -0700420 if (item.hasMtu()) {
421 os << "<mtu>" << item.getMtu() << "</mtu>";
422 }
423
Eric Newberry6d932e82016-11-24 05:05:43 +0000424 if (item.getFlags() == 0) {
425 os << "<flags/>";
426 }
427 else {
428 os << "<flags>";
Junxiao Shi7a36ac72018-03-21 15:23:22 +0000429 os << xml::Flag{"localFieldsEnabled", item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)};
430 os << xml::Flag{"lpReliabilityEnabled", item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)};
431 os << xml::Flag{"congestionMarkingEnabled", item.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)};
Eric Newberry6d932e82016-11-24 05:05:43 +0000432 os << "</flags>";
433 }
434
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000435 os << "<packetCounters>";
436 os << "<incomingPackets>"
437 << "<nInterests>" << item.getNInInterests() << "</nInterests>"
Junxiao Shif03d4792017-04-06 16:41:22 +0000438 << "<nData>" << item.getNInData() << "</nData>"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000439 << "<nNacks>" << item.getNInNacks() << "</nNacks>"
440 << "</incomingPackets>";
441 os << "<outgoingPackets>"
442 << "<nInterests>" << item.getNOutInterests() << "</nInterests>"
Junxiao Shif03d4792017-04-06 16:41:22 +0000443 << "<nData>" << item.getNOutData() << "</nData>"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000444 << "<nNacks>" << item.getNOutNacks() << "</nNacks>"
445 << "</outgoingPackets>";
446 os << "</packetCounters>";
447
448 os << "<byteCounters>";
449 os << "<incomingBytes>" << item.getNInBytes() << "</incomingBytes>";
450 os << "<outgoingBytes>" << item.getNOutBytes() << "</outgoingBytes>";
451 os << "</byteCounters>";
452
453 os << "</face>";
454}
455
456void
457FaceModule::formatStatusText(std::ostream& os) const
458{
459 os << "Faces:\n";
460 for (const FaceStatus& item : m_status) {
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000461 os << " ";
462 formatItemText(os, item, false);
463 os << '\n';
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000464 }
465}
466
467void
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000468FaceModule::formatItemText(std::ostream& os, const FaceStatus& item, bool wantMultiLine)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000469{
Eric Newberryde332452018-01-30 11:45:32 -0700470 text::ItemAttributes ia(wantMultiLine, 10);
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000471
472 os << ia("faceid") << item.getFaceId();
473 os << ia("remote") << item.getRemoteUri();
474 os << ia("local") << item.getLocalUri();
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000475
476 if (item.hasExpirationPeriod()) {
Eric Newberryde332452018-01-30 11:45:32 -0700477 os << ia("expires") << text::formatDuration<time::seconds>(item.getExpirationPeriod());
478 }
479
480 if (item.hasBaseCongestionMarkingInterval() || item.hasDefaultCongestionThreshold()) {
481 os << ia("congestion") << "{";
482 text::Separator congestionSep("", " ");
483 if (item.hasBaseCongestionMarkingInterval()) {
484 os << congestionSep << "base-marking-interval="
485 << text::formatDuration<time::milliseconds>(item.getBaseCongestionMarkingInterval());
486 }
487 if (item.hasDefaultCongestionThreshold()) {
488 os << congestionSep << "default-threshold=" << item.getDefaultCongestionThreshold() << "B";
489 }
490 os << "}";
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000491 }
492
Eric Newberry4f8dd962018-06-17 21:32:07 -0700493 if (item.hasMtu()) {
494 os << ia("mtu") << item.getMtu();
495 }
496
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000497 os << ia("counters")
498 << "{in={"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000499 << item.getNInInterests() << "i "
Junxiao Shif03d4792017-04-06 16:41:22 +0000500 << item.getNInData() << "d "
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000501 << item.getNInNacks() << "n "
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000502 << item.getNInBytes() << "B} "
503 << "out={"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000504 << item.getNOutInterests() << "i "
Junxiao Shif03d4792017-04-06 16:41:22 +0000505 << item.getNOutData() << "d "
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000506 << item.getNOutNacks() << "n "
507 << item.getNOutBytes() << "B}}";
508
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000509 os << ia("flags") << '{';
510 text::Separator flagSep("", " ");
511 os << flagSep << item.getFaceScope();
512 os << flagSep << item.getFacePersistency();
513 os << flagSep << item.getLinkType();
Eric Newberry6d932e82016-11-24 05:05:43 +0000514 if (item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)) {
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000515 os << flagSep << "local-fields";
Eric Newberry6d932e82016-11-24 05:05:43 +0000516 }
Eric Newberry84d3adc2017-08-09 23:31:40 -0400517 if (item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
518 os << flagSep << "lp-reliability";
519 }
Eric Newberryde332452018-01-30 11:45:32 -0700520 if (item.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
521 os << flagSep << "congestion-marking";
522 }
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000523 os << '}';
Eric Newberry6d932e82016-11-24 05:05:43 +0000524
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000525 os << ia.end();
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000526}
527
Eric Newberryde332452018-01-30 11:45:32 -0700528void
Eric Newberryd656aff2020-04-03 00:30:38 -0700529FaceModule::printSuccess(std::ostream& os,
530 const std::string& actionSummary,
531 const ControlParameters& resp)
532{
533 text::ItemAttributes ia;
534 os << actionSummary << ' '
535 << ia("id") << resp.getFaceId()
536 << ia("local") << resp.getLocalUri()
537 << ia("remote") << resp.getUri()
538 << ia("persistency") << resp.getFacePersistency();
539 printFaceParams(os, ia, resp);
540}
541
542void
Eric Newberryde332452018-01-30 11:45:32 -0700543FaceModule::printFaceParams(std::ostream& os, text::ItemAttributes& ia, const ControlParameters& resp)
544{
Junxiao Shi8dc473a2018-03-02 15:10:18 +0000545 os << ia("reliability") << text::OnOff{resp.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)}
546 << ia("congestion-marking") << text::OnOff{resp.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)};
Eric Newberryde332452018-01-30 11:45:32 -0700547 if (resp.hasBaseCongestionMarkingInterval()) {
548 os << ia("congestion-marking-interval")
549 << text::formatDuration<time::milliseconds>(resp.getBaseCongestionMarkingInterval());
550 }
551 if (resp.hasDefaultCongestionThreshold()) {
552 os << ia("default-congestion-threshold") << resp.getDefaultCongestionThreshold() << "B";
553 }
Eric Newberry4f8dd962018-06-17 21:32:07 -0700554 if (resp.hasMtu()) {
555 os << ia("mtu") << resp.getMtu();
556 }
Eric Newberryde332452018-01-30 11:45:32 -0700557 os << '\n';
558}
559
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400560} // namespace nfd::tools::nfdc