blob: decbf7b7b66aaae87bf8267422689bb366b31f8d [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 Pesavento40641272023-03-16 13:31:12 -04003 * Copyright (c) 2014-2023, 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 Pesavento40641272023-03-16 13:31:12 -040029#include <ndn-cxx/mgmt/nfd/status-dataset.hpp>
30
Davide Pesaventoa9b09b62022-06-04 14:07:25 -040031#include <boost/lexical_cast/try_lexical_convert.hpp>
32
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040033namespace nfd::tools::nfdc {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000034
35void
Junxiao Shi1f481fa2017-01-26 15:14:43 +000036FaceModule::registerCommands(CommandParser& parser)
37{
Junxiao Shi36e54292017-02-17 18:43:16 +000038 CommandDefinition defFaceList("face", "list");
39 defFaceList
40 .setTitle("print face list")
41 .addArg("remote", ArgValueType::FACE_URI, Required::NO, Positional::YES)
42 .addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO)
43 .addArg("scheme", ArgValueType::STRING, Required::NO, Positional::NO, "scheme");
44 parser.addCommand(defFaceList, &FaceModule::list);
Davide Pesaventod2147442018-02-19 23:58:17 -050045 parser.addAlias("face", "list", "");
Junxiao Shi36e54292017-02-17 18:43:16 +000046
Junxiao Shi1f481fa2017-01-26 15:14:43 +000047 CommandDefinition defFaceShow("face", "show");
48 defFaceShow
49 .setTitle("show face information")
50 .addArg("id", ArgValueType::UNSIGNED, Required::YES, Positional::YES);
51 parser.addCommand(defFaceShow, &FaceModule::show);
Junxiao Shi1d7fef52017-02-02 05:33:14 +000052
53 CommandDefinition defFaceCreate("face", "create");
54 defFaceCreate
55 .setTitle("create a face")
56 .addArg("remote", ArgValueType::FACE_URI, Required::YES, Positional::YES)
Junxiao Shi0d976922017-04-01 14:35:21 +000057 .addArg("persistency", ArgValueType::FACE_PERSISTENCY, Required::NO, Positional::YES)
Eric Newberry84d3adc2017-08-09 23:31:40 -040058 .addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO)
Eric Newberryde332452018-01-30 11:45:32 -070059 .addArg("reliability", ArgValueType::BOOLEAN, Required::NO, Positional::NO)
60 .addArg("congestion-marking", ArgValueType::BOOLEAN, Required::NO, Positional::NO)
61 .addArg("congestion-marking-interval", ArgValueType::UNSIGNED, Required::NO, Positional::NO)
Eric Newberry4f8dd962018-06-17 21:32:07 -070062 .addArg("default-congestion-threshold", ArgValueType::UNSIGNED, Required::NO, Positional::NO)
Eric Newberry13ff2592020-03-06 17:32:29 -080063 .addArg("mtu", ArgValueType::STRING, Required::NO, Positional::NO);
Junxiao Shi1d7fef52017-02-02 05:33:14 +000064 parser.addCommand(defFaceCreate, &FaceModule::create);
Junxiao Shi05dd4442017-02-06 22:50:07 +000065
66 CommandDefinition defFaceDestroy("face", "destroy");
67 defFaceDestroy
68 .setTitle("destroy a face")
69 .addArg("face", ArgValueType::FACE_ID_OR_URI, Required::YES, Positional::YES);
70 parser.addCommand(defFaceDestroy, &FaceModule::destroy);
Junxiao Shi1f481fa2017-01-26 15:14:43 +000071}
72
73void
Junxiao Shi36e54292017-02-17 18:43:16 +000074FaceModule::list(ExecuteContext& ctx)
75{
76 auto remoteUri = ctx.args.getOptional<FaceUri>("remote");
77 auto localUri = ctx.args.getOptional<FaceUri>("local");
78 auto uriScheme = ctx.args.getOptional<std::string>("scheme");
79
80 FaceQueryFilter filter;
81 if (remoteUri) {
82 filter.setRemoteUri(remoteUri->toString());
83 }
84 if (localUri) {
85 filter.setLocalUri(localUri->toString());
86 }
87 if (uriScheme) {
88 filter.setUriScheme(*uriScheme);
89 }
90
91 FindFace findFace(ctx);
92 FindFace::Code res = findFace.execute(filter, true);
93
94 ctx.exitCode = static_cast<int>(res);
95 switch (res) {
96 case FindFace::Code::OK:
97 for (const FaceStatus& item : findFace.getResults()) {
98 formatItemText(ctx.out, item, false);
99 ctx.out << '\n';
100 }
101 break;
102 case FindFace::Code::ERROR:
103 case FindFace::Code::NOT_FOUND:
104 case FindFace::Code::CANONIZE_ERROR:
105 ctx.err << findFace.getErrorReason() << '\n';
106 break;
107 default:
108 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
109 break;
110 }
111}
112
113void
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000114FaceModule::show(ExecuteContext& ctx)
115{
116 uint64_t faceId = ctx.args.get<uint64_t>("id");
117
Junxiao Shi8f803f22017-02-10 03:04:28 +0000118 FindFace findFace(ctx);
119 FindFace::Code res = findFace.execute(faceId);
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000120
Junxiao Shi8f803f22017-02-10 03:04:28 +0000121 ctx.exitCode = static_cast<int>(res);
122 switch (res) {
123 case FindFace::Code::OK:
124 formatItemText(ctx.out, findFace.getFaceStatus(), true);
125 break;
126 case FindFace::Code::ERROR:
127 case FindFace::Code::NOT_FOUND:
128 ctx.err << findFace.getErrorReason() << '\n';
129 break;
130 default:
131 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
132 break;
133 }
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000134}
135
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400136/** \brief Order persistency in NONE < ON_DEMAND < PERSISTENCY < PERMANENT.
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000137 */
138static bool
139persistencyLessThan(FacePersistency x, FacePersistency y)
140{
141 switch (x) {
142 case FacePersistency::FACE_PERSISTENCY_NONE:
143 return y != FacePersistency::FACE_PERSISTENCY_NONE;
144 case FacePersistency::FACE_PERSISTENCY_ON_DEMAND:
145 return y == FacePersistency::FACE_PERSISTENCY_PERSISTENT ||
146 y == FacePersistency::FACE_PERSISTENCY_PERMANENT;
147 case FacePersistency::FACE_PERSISTENCY_PERSISTENT:
148 return y == FacePersistency::FACE_PERSISTENCY_PERMANENT;
149 case FacePersistency::FACE_PERSISTENCY_PERMANENT:
150 return false;
151 }
152 return static_cast<int>(x) < static_cast<int>(y);
153}
154
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000155void
156FaceModule::create(ExecuteContext& ctx)
157{
Junxiao Shi0d976922017-04-01 14:35:21 +0000158 auto remoteUri = ctx.args.get<FaceUri>("remote");
159 auto localUri = ctx.args.getOptional<FaceUri>("local");
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000160 auto persistency = ctx.args.get<FacePersistency>("persistency", FacePersistency::FACE_PERSISTENCY_PERSISTENT);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400161 auto lpReliability = ctx.args.getTribool("reliability");
Eric Newberryde332452018-01-30 11:45:32 -0700162 auto congestionMarking = ctx.args.getTribool("congestion-marking");
163 auto baseCongestionMarkingIntervalMs = ctx.args.getOptional<uint64_t>("congestion-marking-interval");
164 auto defaultCongestionThreshold = ctx.args.getOptional<uint64_t>("default-congestion-threshold");
Eric Newberry13ff2592020-03-06 17:32:29 -0800165 auto mtuArg = ctx.args.getOptional<std::string>("mtu");
166
167 // 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 -0400168 std::optional<uint64_t> mtu;
Eric Newberry13ff2592020-03-06 17:32:29 -0800169 if (mtuArg == "auto") {
170 mtu = std::numeric_limits<uint64_t>::max();
171 }
172 else if (mtuArg) {
173 // boost::lexical_cast<uint64_t> will accept negative numbers
174 int64_t v = -1;
175 if (!boost::conversion::try_lexical_convert<int64_t>(*mtuArg, v) || v < 0) {
176 ctx.exitCode = 2;
177 ctx.err << "MTU must either be a non-negative integer or 'auto'\n";
178 return;
179 }
180
181 mtu = static_cast<uint64_t>(v);
182 }
Eric Newberry84d3adc2017-08-09 23:31:40 -0400183
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400184 std::optional<FaceUri> canonicalRemote;
185 std::optional<FaceUri> canonicalLocal;
Junxiao Shi0d976922017-04-01 14:35:21 +0000186
Eric Newberryd656aff2020-04-03 00:30:38 -0700187 auto updateFace = [&] (ControlParameters respParams, ControlParameters resp) {
Eric Newberry84d3adc2017-08-09 23:31:40 -0400188 // faces/update response does not have FaceUris, copy from faces/create response
189 resp.setLocalUri(respParams.getLocalUri())
190 .setUri(respParams.getUri());
Eric Newberryd656aff2020-04-03 00:30:38 -0700191 printSuccess(ctx.out, "face-updated", resp);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400192 };
193
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000194 auto handle409 = [&] (const ControlResponse& resp) {
195 ControlParameters respParams(resp.getBody());
Eric Newberryd656aff2020-04-03 00:30:38 -0700196 if (respParams.getUri() != canonicalRemote->toString()) {
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000197 // we are conflicting with a different face, which is a general error
198 return false;
199 }
200
Eric Newberry13ff2592020-03-06 17:32:29 -0800201 bool isChangingParams = false;
202 ControlParameters params;
203 params.setFaceId(respParams.getFaceId());
204
Eric Newberry4f8dd962018-06-17 21:32:07 -0700205 if (mtu && (!respParams.hasMtu() || respParams.getMtu() != *mtu)) {
Eric Newberry13ff2592020-03-06 17:32:29 -0800206 isChangingParams = true;
207 params.setMtu(*mtu);
Eric Newberry4f8dd962018-06-17 21:32:07 -0700208 }
Eric Newberry13ff2592020-03-06 17:32:29 -0800209
210 if (persistencyLessThan(respParams.getFacePersistency(), persistency)) {
211 isChangingParams = true;
212 params.setFacePersistency(persistency);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000213 }
Eric Newberryde332452018-01-30 11:45:32 -0700214
Eric Newberry13ff2592020-03-06 17:32:29 -0800215 if (!boost::logic::indeterminate(lpReliability) &&
216 lpReliability != respParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
217 isChangingParams = true;
218 params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, bool(lpReliability));
219 }
Eric Newberryde332452018-01-30 11:45:32 -0700220
Eric Newberry13ff2592020-03-06 17:32:29 -0800221 if (!boost::logic::indeterminate(congestionMarking) &&
222 congestionMarking != respParams.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
223 isChangingParams = true;
224 params.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, bool(congestionMarking));
225 }
Eric Newberryde332452018-01-30 11:45:32 -0700226
Eric Newberry13ff2592020-03-06 17:32:29 -0800227 if (baseCongestionMarkingIntervalMs) {
228 isChangingParams = true;
229 params.setBaseCongestionMarkingInterval(time::milliseconds(*baseCongestionMarkingIntervalMs));
230 }
Eric Newberryde332452018-01-30 11:45:32 -0700231
Eric Newberry13ff2592020-03-06 17:32:29 -0800232 if (defaultCongestionThreshold) {
233 isChangingParams = true;
234 params.setDefaultCongestionThreshold(*defaultCongestionThreshold);
235 }
236
237 if (isChangingParams) {
Eric Newberry84d3adc2017-08-09 23:31:40 -0400238 ctx.controller.start<ndn::nfd::FaceUpdateCommand>(
Eric Newberry13ff2592020-03-06 17:32:29 -0800239 params,
Davide Pesavento412c9822021-07-02 00:21:05 -0400240 [=, &updateFace] (const auto& cp) { updateFace(respParams, cp); },
Eric Newberry13ff2592020-03-06 17:32:29 -0800241 ctx.makeCommandFailureHandler("updating face"),
242 ctx.makeCommandOptions());
Eric Newberry84d3adc2017-08-09 23:31:40 -0400243 }
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000244 else {
Eric Newberry84d3adc2017-08-09 23:31:40 -0400245 // don't do anything
Eric Newberryd656aff2020-04-03 00:30:38 -0700246 printSuccess(ctx.out, "face-exists", respParams);
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000247 }
Eric Newberry13ff2592020-03-06 17:32:29 -0800248
Yanbiao Li58ba3f92017-02-15 14:27:18 +0000249 return true;
250 };
Junxiao Shi1d7fef52017-02-02 05:33:14 +0000251
Junxiao Shi0d976922017-04-01 14:35:21 +0000252 auto doCreateFace = [&] {
253 ControlParameters params;
Eric Newberryd656aff2020-04-03 00:30:38 -0700254 params.setUri(canonicalRemote->toString());
Junxiao Shi0d976922017-04-01 14:35:21 +0000255 if (canonicalLocal) {
256 params.setLocalUri(canonicalLocal->toString());
257 }
258 params.setFacePersistency(persistency);
Eric Newberry84d3adc2017-08-09 23:31:40 -0400259 if (!boost::logic::indeterminate(lpReliability)) {
Davide Pesaventofa2aa502019-03-22 13:30:02 -0400260 params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, bool(lpReliability));
Eric Newberry84d3adc2017-08-09 23:31:40 -0400261 }
Eric Newberryde332452018-01-30 11:45:32 -0700262 if (!boost::logic::indeterminate(congestionMarking)) {
Davide Pesaventofa2aa502019-03-22 13:30:02 -0400263 params.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, bool(congestionMarking));
Eric Newberryde332452018-01-30 11:45:32 -0700264 }
265 if (baseCongestionMarkingIntervalMs) {
266 params.setBaseCongestionMarkingInterval(time::milliseconds(*baseCongestionMarkingIntervalMs));
267 }
268 if (defaultCongestionThreshold) {
269 params.setDefaultCongestionThreshold(*defaultCongestionThreshold);
270 }
Eric Newberry4f8dd962018-06-17 21:32:07 -0700271 if (mtu) {
272 params.setMtu(*mtu);
273 }
Junxiao Shi0d976922017-04-01 14:35:21 +0000274
275 ctx.controller.start<ndn::nfd::FaceCreateCommand>(
276 params,
Eric Newberryd656aff2020-04-03 00:30:38 -0700277 [&] (const ControlParameters& resp) {
278 printSuccess(ctx.out, "face-created", resp);
279 },
Junxiao Shi0d976922017-04-01 14:35:21 +0000280 [&] (const ControlResponse& resp) {
281 if (resp.getCode() == 409 && handle409(resp)) {
282 return;
283 }
284 ctx.makeCommandFailureHandler("creating face")(resp); // invoke general error handler
285 },
286 ctx.makeCommandOptions());
287 };
288
Eric Newberryd656aff2020-04-03 00:30:38 -0700289 std::string error;
290 std::tie(canonicalRemote, error) = canonize(ctx, remoteUri);
291 if (canonicalRemote) {
292 // RemoteUri canonization successful
293 if (localUri) {
294 std::tie(canonicalLocal, error) = canonize(ctx, *localUri);
295 if (canonicalLocal) {
296 // LocalUri canonization successful
Junxiao Shi0d976922017-04-01 14:35:21 +0000297 doCreateFace();
298 }
Eric Newberryd656aff2020-04-03 00:30:38 -0700299 else {
300 // LocalUri canonization failure
301 auto canonizationError = canonizeErrorHelper(*localUri, error, "local FaceUri");
302 ctx.exitCode = static_cast<int>(canonizationError.first);
303 ctx.err << canonizationError.second << '\n';
304 }
305 }
306 else {
307 doCreateFace();
308 }
309 }
310 else {
311 // RemoteUri canonization failure
312 auto canonizationError = canonizeErrorHelper(remoteUri, error, "remote FaceUri");
313 ctx.exitCode = static_cast<int>(canonizationError.first);
314 ctx.err << canonizationError.second << '\n';
315 }
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000316
317 ctx.face.processEvents();
318}
319
320void
Junxiao Shi05dd4442017-02-06 22:50:07 +0000321FaceModule::destroy(ExecuteContext& ctx)
322{
Junxiao Shi05dd4442017-02-06 22:50:07 +0000323 FindFace findFace(ctx);
Davide Pesavento8b663a92018-11-21 22:57:20 -0500324 FindFace::Code res = findFace.execute(ctx.args.at("face"));
Junxiao Shi05dd4442017-02-06 22:50:07 +0000325
326 ctx.exitCode = static_cast<int>(res);
327 switch (res) {
328 case FindFace::Code::OK:
329 break;
330 case FindFace::Code::ERROR:
331 case FindFace::Code::CANONIZE_ERROR:
332 case FindFace::Code::NOT_FOUND:
333 ctx.err << findFace.getErrorReason() << '\n';
334 return;
335 case FindFace::Code::AMBIGUOUS:
336 ctx.err << "Multiple faces match specified remote FaceUri. Re-run the command with a FaceId:";
337 findFace.printDisambiguation(ctx.err, FindFace::DisambiguationStyle::LOCAL_URI);
338 ctx.err << '\n';
339 return;
340 default:
341 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
342 return;
343 }
344
345 const FaceStatus& face = findFace.getFaceStatus();
346
347 ctx.controller.start<ndn::nfd::FaceDestroyCommand>(
348 ControlParameters().setFaceId(face.getFaceId()),
349 [&] (const ControlParameters& resp) {
Eric Newberryd656aff2020-04-03 00:30:38 -0700350 // We can't use printSuccess because some face attributes come from FaceStatus not ControlResponse
Junxiao Shi05dd4442017-02-06 22:50:07 +0000351 ctx.out << "face-destroyed ";
352 text::ItemAttributes ia;
353 ctx.out << ia("id") << face.getFaceId()
354 << ia("local") << face.getLocalUri()
355 << ia("remote") << face.getRemoteUri()
Eric Newberryde332452018-01-30 11:45:32 -0700356 << ia("persistency") << face.getFacePersistency();
357 printFaceParams(ctx.out, ia, resp);
Junxiao Shi05dd4442017-02-06 22:50:07 +0000358 },
359 ctx.makeCommandFailureHandler("destroying face"),
360 ctx.makeCommandOptions());
361
362 ctx.face.processEvents();
363}
364
365void
Davide Pesavento63b3ae82023-03-24 23:53:24 -0400366FaceModule::fetchStatus(ndn::nfd::Controller& controller,
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400367 const std::function<void()>& onSuccess,
Davide Pesavento63b3ae82023-03-24 23:53:24 -0400368 const ndn::nfd::DatasetFailureCallback& onFailure,
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000369 const CommandOptions& options)
370{
371 controller.fetch<ndn::nfd::FaceDataset>(
Davide Pesavento990620a2022-06-05 00:25:53 -0400372 [this, onSuccess] (const auto& result) {
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000373 m_status = result;
374 onSuccess();
375 },
376 onFailure, options);
377}
378
379void
380FaceModule::formatStatusXml(std::ostream& os) const
381{
382 os << "<faces>";
383 for (const FaceStatus& item : m_status) {
384 this->formatItemXml(os, item);
385 }
386 os << "</faces>";
387}
388
389void
390FaceModule::formatItemXml(std::ostream& os, const FaceStatus& item) const
391{
392 os << "<face>";
393
394 os << "<faceId>" << item.getFaceId() << "</faceId>";
395 os << "<remoteUri>" << xml::Text{item.getRemoteUri()} << "</remoteUri>";
396 os << "<localUri>" << xml::Text{item.getLocalUri()} << "</localUri>";
397
398 if (item.hasExpirationPeriod()) {
399 os << "<expirationPeriod>" << xml::formatDuration(item.getExpirationPeriod())
400 << "</expirationPeriod>";
401 }
402 os << "<faceScope>" << item.getFaceScope() << "</faceScope>";
403 os << "<facePersistency>" << item.getFacePersistency() << "</facePersistency>";
404 os << "<linkType>" << item.getLinkType() << "</linkType>";
405
Eric Newberryde332452018-01-30 11:45:32 -0700406 if (!item.hasBaseCongestionMarkingInterval() && !item.hasDefaultCongestionThreshold()) {
407 os << "<congestion/>";
408 }
409 else {
410 os << "<congestion>";
411 if (item.hasBaseCongestionMarkingInterval()) {
412 os << "<baseMarkingInterval>" << xml::formatDuration(item.getBaseCongestionMarkingInterval())
413 << "</baseMarkingInterval>";
414 }
415 if (item.hasDefaultCongestionThreshold()) {
416 os << "<defaultThreshold>" << item.getDefaultCongestionThreshold() << "</defaultThreshold>";
417 }
418 os << "</congestion>";
419 }
420
Eric Newberry4f8dd962018-06-17 21:32:07 -0700421 if (item.hasMtu()) {
422 os << "<mtu>" << item.getMtu() << "</mtu>";
423 }
424
Eric Newberry6d932e82016-11-24 05:05:43 +0000425 if (item.getFlags() == 0) {
426 os << "<flags/>";
427 }
428 else {
429 os << "<flags>";
Junxiao Shi7a36ac72018-03-21 15:23:22 +0000430 os << xml::Flag{"localFieldsEnabled", item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)};
431 os << xml::Flag{"lpReliabilityEnabled", item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)};
432 os << xml::Flag{"congestionMarkingEnabled", item.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)};
Eric Newberry6d932e82016-11-24 05:05:43 +0000433 os << "</flags>";
434 }
435
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000436 os << "<packetCounters>";
437 os << "<incomingPackets>"
438 << "<nInterests>" << item.getNInInterests() << "</nInterests>"
Junxiao Shif03d4792017-04-06 16:41:22 +0000439 << "<nData>" << item.getNInData() << "</nData>"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000440 << "<nNacks>" << item.getNInNacks() << "</nNacks>"
441 << "</incomingPackets>";
442 os << "<outgoingPackets>"
443 << "<nInterests>" << item.getNOutInterests() << "</nInterests>"
Junxiao Shif03d4792017-04-06 16:41:22 +0000444 << "<nData>" << item.getNOutData() << "</nData>"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000445 << "<nNacks>" << item.getNOutNacks() << "</nNacks>"
446 << "</outgoingPackets>";
447 os << "</packetCounters>";
448
449 os << "<byteCounters>";
450 os << "<incomingBytes>" << item.getNInBytes() << "</incomingBytes>";
451 os << "<outgoingBytes>" << item.getNOutBytes() << "</outgoingBytes>";
452 os << "</byteCounters>";
453
454 os << "</face>";
455}
456
457void
458FaceModule::formatStatusText(std::ostream& os) const
459{
460 os << "Faces:\n";
461 for (const FaceStatus& item : m_status) {
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000462 os << " ";
463 formatItemText(os, item, false);
464 os << '\n';
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000465 }
466}
467
468void
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000469FaceModule::formatItemText(std::ostream& os, const FaceStatus& item, bool wantMultiLine)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000470{
Eric Newberryde332452018-01-30 11:45:32 -0700471 text::ItemAttributes ia(wantMultiLine, 10);
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000472
473 os << ia("faceid") << item.getFaceId();
474 os << ia("remote") << item.getRemoteUri();
475 os << ia("local") << item.getLocalUri();
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000476
477 if (item.hasExpirationPeriod()) {
Eric Newberryde332452018-01-30 11:45:32 -0700478 os << ia("expires") << text::formatDuration<time::seconds>(item.getExpirationPeriod());
479 }
480
481 if (item.hasBaseCongestionMarkingInterval() || item.hasDefaultCongestionThreshold()) {
482 os << ia("congestion") << "{";
483 text::Separator congestionSep("", " ");
484 if (item.hasBaseCongestionMarkingInterval()) {
485 os << congestionSep << "base-marking-interval="
486 << text::formatDuration<time::milliseconds>(item.getBaseCongestionMarkingInterval());
487 }
488 if (item.hasDefaultCongestionThreshold()) {
489 os << congestionSep << "default-threshold=" << item.getDefaultCongestionThreshold() << "B";
490 }
491 os << "}";
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000492 }
493
Eric Newberry4f8dd962018-06-17 21:32:07 -0700494 if (item.hasMtu()) {
495 os << ia("mtu") << item.getMtu();
496 }
497
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000498 os << ia("counters")
499 << "{in={"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000500 << item.getNInInterests() << "i "
Junxiao Shif03d4792017-04-06 16:41:22 +0000501 << item.getNInData() << "d "
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000502 << item.getNInNacks() << "n "
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000503 << item.getNInBytes() << "B} "
504 << "out={"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000505 << item.getNOutInterests() << "i "
Junxiao Shif03d4792017-04-06 16:41:22 +0000506 << item.getNOutData() << "d "
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000507 << item.getNOutNacks() << "n "
508 << item.getNOutBytes() << "B}}";
509
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000510 os << ia("flags") << '{';
511 text::Separator flagSep("", " ");
512 os << flagSep << item.getFaceScope();
513 os << flagSep << item.getFacePersistency();
514 os << flagSep << item.getLinkType();
Eric Newberry6d932e82016-11-24 05:05:43 +0000515 if (item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)) {
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000516 os << flagSep << "local-fields";
Eric Newberry6d932e82016-11-24 05:05:43 +0000517 }
Eric Newberry84d3adc2017-08-09 23:31:40 -0400518 if (item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
519 os << flagSep << "lp-reliability";
520 }
Eric Newberryde332452018-01-30 11:45:32 -0700521 if (item.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
522 os << flagSep << "congestion-marking";
523 }
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000524 os << '}';
Eric Newberry6d932e82016-11-24 05:05:43 +0000525
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000526 os << ia.end();
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000527}
528
Eric Newberryde332452018-01-30 11:45:32 -0700529void
Eric Newberryd656aff2020-04-03 00:30:38 -0700530FaceModule::printSuccess(std::ostream& os,
531 const std::string& actionSummary,
532 const ControlParameters& resp)
533{
534 text::ItemAttributes ia;
535 os << actionSummary << ' '
536 << ia("id") << resp.getFaceId()
537 << ia("local") << resp.getLocalUri()
538 << ia("remote") << resp.getUri()
539 << ia("persistency") << resp.getFacePersistency();
540 printFaceParams(os, ia, resp);
541}
542
543void
Eric Newberryde332452018-01-30 11:45:32 -0700544FaceModule::printFaceParams(std::ostream& os, text::ItemAttributes& ia, const ControlParameters& resp)
545{
Junxiao Shi8dc473a2018-03-02 15:10:18 +0000546 os << ia("reliability") << text::OnOff{resp.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)}
547 << ia("congestion-marking") << text::OnOff{resp.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)};
Eric Newberryde332452018-01-30 11:45:32 -0700548 if (resp.hasBaseCongestionMarkingInterval()) {
549 os << ia("congestion-marking-interval")
550 << text::formatDuration<time::milliseconds>(resp.getBaseCongestionMarkingInterval());
551 }
552 if (resp.hasDefaultCongestionThreshold()) {
553 os << ia("default-congestion-threshold") << resp.getDefaultCongestionThreshold() << "B";
554 }
Eric Newberry4f8dd962018-06-17 21:32:07 -0700555 if (resp.hasMtu()) {
556 os << ia("mtu") << resp.getMtu();
557 }
Eric Newberryde332452018-01-30 11:45:32 -0700558 os << '\n';
559}
560
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400561} // namespace nfd::tools::nfdc