blob: e96de3e772ec2f465051816bf3aa91438e9aed6b [file] [log] [blame]
Junxiao Shi38f4ce92016-08-04 10:01:52 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi1f481fa2017-01-26 15:14:43 +00003 * Copyright (c) 2014-2017, 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"
Junxiao Shi05dd4442017-02-06 22:50:07 +000027#include "find-face.hpp"
Junxiao Shi38f4ce92016-08-04 10:01:52 +000028#include "format-helpers.hpp"
29
30namespace nfd {
31namespace tools {
Junxiao Shi331ade72016-08-19 14:07:19 +000032namespace nfdc {
Junxiao Shi38f4ce92016-08-04 10:01:52 +000033
34void
Junxiao Shi1f481fa2017-01-26 15:14:43 +000035FaceModule::registerCommands(CommandParser& parser)
36{
37 CommandDefinition defFaceShow("face", "show");
38 defFaceShow
39 .setTitle("show face information")
40 .addArg("id", ArgValueType::UNSIGNED, Required::YES, Positional::YES);
41 parser.addCommand(defFaceShow, &FaceModule::show);
Junxiao Shi1d7fef52017-02-02 05:33:14 +000042
43 CommandDefinition defFaceCreate("face", "create");
44 defFaceCreate
45 .setTitle("create a face")
46 .addArg("remote", ArgValueType::FACE_URI, Required::YES, Positional::YES)
47 .addArg("persistency", ArgValueType::FACE_PERSISTENCY, Required::NO, Positional::YES);
48 parser.addCommand(defFaceCreate, &FaceModule::create);
Junxiao Shi05dd4442017-02-06 22:50:07 +000049
50 CommandDefinition defFaceDestroy("face", "destroy");
51 defFaceDestroy
52 .setTitle("destroy a face")
53 .addArg("face", ArgValueType::FACE_ID_OR_URI, Required::YES, Positional::YES);
54 parser.addCommand(defFaceDestroy, &FaceModule::destroy);
Junxiao Shi1f481fa2017-01-26 15:14:43 +000055}
56
57void
58FaceModule::show(ExecuteContext& ctx)
59{
60 uint64_t faceId = ctx.args.get<uint64_t>("id");
61
Junxiao Shi8f803f22017-02-10 03:04:28 +000062 FindFace findFace(ctx);
63 FindFace::Code res = findFace.execute(faceId);
Junxiao Shi1d7fef52017-02-02 05:33:14 +000064
Junxiao Shi8f803f22017-02-10 03:04:28 +000065 ctx.exitCode = static_cast<int>(res);
66 switch (res) {
67 case FindFace::Code::OK:
68 formatItemText(ctx.out, findFace.getFaceStatus(), true);
69 break;
70 case FindFace::Code::ERROR:
71 case FindFace::Code::NOT_FOUND:
72 ctx.err << findFace.getErrorReason() << '\n';
73 break;
74 default:
75 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
76 break;
77 }
Junxiao Shi1d7fef52017-02-02 05:33:14 +000078}
79
80void
81FaceModule::create(ExecuteContext& ctx)
82{
83 auto faceUri = ctx.args.get<FaceUri>("remote");
84 auto persistency = ctx.args.get<FacePersistency>("persistency", FacePersistency::FACE_PERSISTENCY_PERSISTENT);
85
86 faceUri.canonize(
87 [&] (const FaceUri& canonicalUri) {
88 ctx.controller.start<ndn::nfd::FaceCreateCommand>(
89 ControlParameters().setUri(canonicalUri.toString()).setFacePersistency(persistency),
90 [&] (const ControlParameters& resp) {
91 ctx.out << "face-created ";
92 text::ItemAttributes ia;
93 ctx.out << ia("id") << resp.getFaceId()
94 << ia("remote") << resp.getUri()
95 << ia("persistency") << resp.getFacePersistency() << '\n';
96 ///\todo #3864 display localUri
97 },
98 ctx.makeCommandFailureHandler("creating face"), ///\todo #3232 update persistency upon 409
99 ctx.makeCommandOptions());
100 },
101 [&] (const std::string& canonizeError) {
102 ctx.exitCode = 4;
103 ctx.err << "Error when canonizing FaceUri: " << canonizeError << '\n';
104 },
105 ctx.face.getIoService(), ctx.getTimeout());
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000106
107 ctx.face.processEvents();
108}
109
110void
Junxiao Shi05dd4442017-02-06 22:50:07 +0000111FaceModule::destroy(ExecuteContext& ctx)
112{
113 const boost::any faceIdOrUri = ctx.args.at("face");
114
115 FindFace findFace(ctx);
116 FindFace::Code res = FindFace::Code::ERROR;
117 const uint64_t* faceId = boost::any_cast<uint64_t>(&faceIdOrUri);
118 if (faceId != nullptr) {
119 res = findFace.execute(*faceId);
120 }
121 else {
122 res = findFace.execute(boost::any_cast<FaceUri>(faceIdOrUri));
123 }
124
125 ctx.exitCode = static_cast<int>(res);
126 switch (res) {
127 case FindFace::Code::OK:
128 break;
129 case FindFace::Code::ERROR:
130 case FindFace::Code::CANONIZE_ERROR:
131 case FindFace::Code::NOT_FOUND:
132 ctx.err << findFace.getErrorReason() << '\n';
133 return;
134 case FindFace::Code::AMBIGUOUS:
135 ctx.err << "Multiple faces match specified remote FaceUri. Re-run the command with a FaceId:";
136 findFace.printDisambiguation(ctx.err, FindFace::DisambiguationStyle::LOCAL_URI);
137 ctx.err << '\n';
138 return;
139 default:
140 BOOST_ASSERT_MSG(false, "unexpected FindFace result");
141 return;
142 }
143
144 const FaceStatus& face = findFace.getFaceStatus();
145
146 ctx.controller.start<ndn::nfd::FaceDestroyCommand>(
147 ControlParameters().setFaceId(face.getFaceId()),
148 [&] (const ControlParameters& resp) {
149 ctx.out << "face-destroyed ";
150 text::ItemAttributes ia;
151 ctx.out << ia("id") << face.getFaceId()
152 << ia("local") << face.getLocalUri()
153 << ia("remote") << face.getRemoteUri()
154 << ia("persistency") << face.getFacePersistency() << '\n';
155 },
156 ctx.makeCommandFailureHandler("destroying face"),
157 ctx.makeCommandOptions());
158
159 ctx.face.processEvents();
160}
161
162void
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000163FaceModule::fetchStatus(Controller& controller,
164 const function<void()>& onSuccess,
Junxiao Shi29b41282016-08-22 03:47:02 +0000165 const Controller::DatasetFailCallback& onFailure,
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000166 const CommandOptions& options)
167{
168 controller.fetch<ndn::nfd::FaceDataset>(
169 [this, onSuccess] (const std::vector<FaceStatus>& result) {
170 m_status = result;
171 onSuccess();
172 },
173 onFailure, options);
174}
175
176void
177FaceModule::formatStatusXml(std::ostream& os) const
178{
179 os << "<faces>";
180 for (const FaceStatus& item : m_status) {
181 this->formatItemXml(os, item);
182 }
183 os << "</faces>";
184}
185
186void
187FaceModule::formatItemXml(std::ostream& os, const FaceStatus& item) const
188{
189 os << "<face>";
190
191 os << "<faceId>" << item.getFaceId() << "</faceId>";
192 os << "<remoteUri>" << xml::Text{item.getRemoteUri()} << "</remoteUri>";
193 os << "<localUri>" << xml::Text{item.getLocalUri()} << "</localUri>";
194
195 if (item.hasExpirationPeriod()) {
196 os << "<expirationPeriod>" << xml::formatDuration(item.getExpirationPeriod())
197 << "</expirationPeriod>";
198 }
199 os << "<faceScope>" << item.getFaceScope() << "</faceScope>";
200 os << "<facePersistency>" << item.getFacePersistency() << "</facePersistency>";
201 os << "<linkType>" << item.getLinkType() << "</linkType>";
202
Eric Newberry6d932e82016-11-24 05:05:43 +0000203 if (item.getFlags() == 0) {
204 os << "<flags/>";
205 }
206 else {
207 os << "<flags>";
208 if (item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)) {
209 os << "<localFieldsEnabled/>";
210 }
211 os << "</flags>";
212 }
213
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000214 os << "<packetCounters>";
215 os << "<incomingPackets>"
216 << "<nInterests>" << item.getNInInterests() << "</nInterests>"
217 << "<nDatas>" << item.getNInDatas() << "</nDatas>"
218 << "<nNacks>" << item.getNInNacks() << "</nNacks>"
219 << "</incomingPackets>";
220 os << "<outgoingPackets>"
221 << "<nInterests>" << item.getNOutInterests() << "</nInterests>"
222 << "<nDatas>" << item.getNOutDatas() << "</nDatas>"
223 << "<nNacks>" << item.getNOutNacks() << "</nNacks>"
224 << "</outgoingPackets>";
225 os << "</packetCounters>";
226
227 os << "<byteCounters>";
228 os << "<incomingBytes>" << item.getNInBytes() << "</incomingBytes>";
229 os << "<outgoingBytes>" << item.getNOutBytes() << "</outgoingBytes>";
230 os << "</byteCounters>";
231
232 os << "</face>";
233}
234
235void
236FaceModule::formatStatusText(std::ostream& os) const
237{
238 os << "Faces:\n";
239 for (const FaceStatus& item : m_status) {
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000240 os << " ";
241 formatItemText(os, item, false);
242 os << '\n';
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000243 }
244}
245
246void
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000247FaceModule::formatItemText(std::ostream& os, const FaceStatus& item, bool wantMultiLine)
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000248{
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000249 text::ItemAttributes ia(wantMultiLine, 8);
250
251 os << ia("faceid") << item.getFaceId();
252 os << ia("remote") << item.getRemoteUri();
253 os << ia("local") << item.getLocalUri();
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000254
255 if (item.hasExpirationPeriod()) {
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000256 os << ia("expires") << text::formatDuration(item.getExpirationPeriod());
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000257 }
258
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000259 os << ia("counters")
260 << "{in={"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000261 << item.getNInInterests() << "i "
262 << item.getNInDatas() << "d "
263 << item.getNInNacks() << "n "
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000264 << item.getNInBytes() << "B} "
265 << "out={"
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000266 << item.getNOutInterests() << "i "
267 << item.getNOutDatas() << "d "
268 << item.getNOutNacks() << "n "
269 << item.getNOutBytes() << "B}}";
270
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000271 os << ia("flags") << '{';
272 text::Separator flagSep("", " ");
273 os << flagSep << item.getFaceScope();
274 os << flagSep << item.getFacePersistency();
275 os << flagSep << item.getLinkType();
Eric Newberry6d932e82016-11-24 05:05:43 +0000276 if (item.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)) {
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000277 os << flagSep << "local-fields";
Eric Newberry6d932e82016-11-24 05:05:43 +0000278 }
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000279 os << '}';
Eric Newberry6d932e82016-11-24 05:05:43 +0000280
Junxiao Shi1f481fa2017-01-26 15:14:43 +0000281 os << ia.end();
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000282}
283
Junxiao Shi331ade72016-08-19 14:07:19 +0000284} // namespace nfdc
Junxiao Shi38f4ce92016-08-04 10:01:52 +0000285} // namespace tools
286} // namespace nfd