blob: b69029c1947cca83425c102ab2cea05311eb7837 [file] [log] [blame]
Alexander Afanasyev4a771362014-04-24 21:29:33 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
jeraldabrahamb6dde382014-03-19 18:58:09 -07002/**
Alexander Afanasyev4a771362014-04-24 21:29:33 -07003 * Copyright (c) 2014, Regents of the University of California,
4 * 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
jeraldabrahamb6dde382014-03-19 18:58:09 -070010 *
Alexander Afanasyev4a771362014-04-24 21:29:33 -070011 * 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 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
jeraldabrahamb6dde382014-03-19 18:58:09 -070026 */
27
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070028#include "version.hpp"
29
Alexander Afanasyev4a771362014-04-24 21:29:33 -070030#include <ndn-cxx/face.hpp>
31#include <ndn-cxx/name.hpp>
32#include <ndn-cxx/interest.hpp>
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070033#include <ndn-cxx/encoding/buffer-stream.hpp>
jeraldabrahamb6dde382014-03-19 18:58:09 -070034
Alexander Afanasyev4a771362014-04-24 21:29:33 -070035#include <ndn-cxx/management/nfd-forwarder-status.hpp>
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030036#include <ndn-cxx/management/nfd-channel-status.hpp>
37#include <ndn-cxx/management/nfd-face-status.hpp>
38#include <ndn-cxx/management/nfd-fib-entry.hpp>
39#include <ndn-cxx/management/nfd-strategy-choice.hpp>
jeraldabrahamb6dde382014-03-19 18:58:09 -070040
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070041#include <boost/algorithm/string/replace.hpp>
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030042#include <list>
Alexander Afanasyevb3893c92014-05-15 01:49:54 -070043
jeraldabrahamb6dde382014-03-19 18:58:09 -070044namespace ndn {
45
46class NfdStatus
47{
48public:
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -070049 explicit
jeraldabrahamb6dde382014-03-19 18:58:09 -070050 NfdStatus(char* toolName)
51 : m_toolName(toolName)
52 , m_needVersionRetrieval(false)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030053 , m_needChannelStatusRetrieval(false)
jeraldabrahamb6dde382014-03-19 18:58:09 -070054 , m_needFaceStatusRetrieval(false)
55 , m_needFibEnumerationRetrieval(false)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030056 , m_needStrategyChoiceRetrieval(false)
57 , m_isOutputXml(false)
jeraldabrahamb6dde382014-03-19 18:58:09 -070058 {
59 }
60
61 void
62 usage()
63 {
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070064 std::cout << "Usage: \n " << m_toolName << " [options]\n\n"
65 "Show NFD version and status information\n\n"
66 "Options:\n"
67 " [-h] - print this help message\n"
jeraldabrahamb6dde382014-03-19 18:58:09 -070068 " [-v] - retrieve version information\n"
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030069 " [-c] - retrieve channel status information\n"
jeraldabrahamb6dde382014-03-19 18:58:09 -070070 " [-f] - retrieve face status information\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070071 " [-b] - retrieve FIB information\n"
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030072 " [-s] - retrieve configured strategy choice for NDN namespaces\n"
Chengyu Fan514ed5e2014-04-17 13:07:30 -060073 " [-x] - retrieve NFD status information in XML format\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070074 "\n"
75 " [-V] - show version information of nfd-status and exit\n"
76 "\n"
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070077 "If no options are provided, all information is retrieved.\n"
Chengyu Fan514ed5e2014-04-17 13:07:30 -060078 "If -x is provided, other options(v, f and b) are ignored, and all information is retrieved in XML format.\n"
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -070079 ;
jeraldabrahamb6dde382014-03-19 18:58:09 -070080 }
81
82 void
83 enableVersionRetrieval()
84 {
85 m_needVersionRetrieval = true;
86 }
87
88 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +030089 enableChannelStatusRetrieval()
90 {
91 m_needChannelStatusRetrieval = true;
92 }
93
94 void
jeraldabrahamb6dde382014-03-19 18:58:09 -070095 enableFaceStatusRetrieval()
96 {
97 m_needFaceStatusRetrieval = true;
98 }
99
100 void
101 enableFibEnumerationRetrieval()
102 {
103 m_needFibEnumerationRetrieval = true;
104 }
105
106 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300107 enableStrategyChoiceRetrieval()
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600108 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300109 m_needStrategyChoiceRetrieval = true;
110 }
111
112 void
113 enableXmlOutput()
114 {
115 m_isOutputXml = true;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600116 }
117
118 void
jeraldabrahamb6dde382014-03-19 18:58:09 -0700119 onTimeout()
120 {
121 std::cerr << "Request timed out" << std::endl;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300122
123 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700124 }
125
126 void
127 fetchSegments(const Data& data, void (NfdStatus::*onDone)())
128 {
129 m_buffer->write((const char*)data.getContent().value(),
130 data.getContent().value_size());
131
132 uint64_t currentSegment = data.getName().get(-1).toSegment();
133
134 const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
135 if (finalBlockId.empty() ||
136 finalBlockId.toSegment() > currentSegment)
137 {
138 m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
139 bind(&NfdStatus::fetchSegments, this, _2, onDone),
140 bind(&NfdStatus::onTimeout, this));
141 }
142 else
143 {
144 return (this->*onDone)();
145 }
146 }
147
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300148 void
149 escapeSpecialCharacters(std::string *data)
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600150 {
151 using boost::algorithm::replace_all;
152 replace_all(*data, "&", "&amp;");
153 replace_all(*data, "\"", "&quot;");
154 replace_all(*data, "\'", "&apos;");
155 replace_all(*data, "<", "&lt;");
156 replace_all(*data, ">", "&gt;");
157 }
158
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300159 //////////////////////////////////////////////////////////////////////////////////
160 //////////////////////////////////////////////////////////////////////////////////
161
162 void
163 fetchVersionInformation()
164 {
165 Interest interest("/localhost/nfd/status");
166 interest.setChildSelector(1);
167 interest.setMustBeFresh(true);
168 m_face.expressInterest(
169 interest,
170 bind(&NfdStatus::afterFetchedVersionInformation, this, _2),
171 bind(&NfdStatus::onTimeout, this));
172 }
173
jeraldabrahamb6dde382014-03-19 18:58:09 -0700174 void
175 afterFetchedVersionInformation(const Data& data)
176 {
Junxiao Shi88d69372014-03-28 11:52:39 -0700177 nfd::ForwarderStatus status(data.getContent());
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300178 if (m_isOutputXml)
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600179 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600180 std::cout << "<generalStatus>";
181 std::cout << "<version>"
182 << status.getNfdVersion() << "</version>";
183 std::cout << "<startTime>"
184 << time::toString(status.getStartTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
185 << "</startTime>";
186 std::cout << "<currentTime>"
187 << time::toString(status.getCurrentTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
188 << "</currentTime>";
189 std::cout << "<uptime>PT"
190 << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
191 - status.getStartTimestamp()).count()
192 << "S</uptime>";
193 std::cout << "<nNameTreeEntries>" << status.getNNameTreeEntries()
194 << "</nNameTreeEntries>";
195 std::cout << "<nFibEntries>" << status.getNFibEntries()
196 << "</nFibEntries>";
197 std::cout << "<nPitEntries>" << status.getNPitEntries()
198 << "</nPitEntries>";
199 std::cout << "<nMeasurementsEntries>" << status.getNMeasurementsEntries()
200 << "</nMeasurementsEntries>";
201 std::cout << "<nCsEntries>" << status.getNCsEntries()
202 << "</nCsEntries>";
203 std::cout << "<packetCounters>";
204 std::cout << "<incomingPackets>";
205 std::cout << "<nInterests>" << status.getNInInterests()
206 << "</nInterests>";
207 std::cout << "<nDatas>" << status.getNInDatas()
208 << "</nDatas>";
209 std::cout << "</incomingPackets>";
210 std::cout << "<outgoingPackets>";
211 std::cout << "<nInterests>" << status.getNOutInterests()
212 << "</nInterests>";
213 std::cout << "<nDatas>" << status.getNOutDatas()
214 << "</nDatas>";
215 std::cout << "</outgoingPackets>";
216 std::cout << "</packetCounters>";
217 std::cout << "</generalStatus>";
218 }
219 else
220 {
221 std::cout << "General NFD status:" << std::endl;
222 std::cout << " version="
223 << status.getNfdVersion() << std::endl;
224 std::cout << " startTime="
225 << time::toIsoString(status.getStartTimestamp()) << std::endl;
226 std::cout << " currentTime="
227 << time::toIsoString(status.getCurrentTimestamp()) << std::endl;
228 std::cout << " uptime="
229 << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
230 - status.getStartTimestamp()) << std::endl;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700231
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600232 std::cout << " nNameTreeEntries=" << status.getNNameTreeEntries() << std::endl;
233 std::cout << " nFibEntries=" << status.getNFibEntries() << std::endl;
234 std::cout << " nPitEntries=" << status.getNPitEntries() << std::endl;
235 std::cout << " nMeasurementsEntries=" << status.getNMeasurementsEntries() << std::endl;
236 std::cout << " nCsEntries=" << status.getNCsEntries() << std::endl;
237 std::cout << " nInInterests=" << status.getNInInterests() << std::endl;
238 std::cout << " nOutInterests=" << status.getNOutInterests() << std::endl;
239 std::cout << " nInDatas=" << status.getNInDatas() << std::endl;
240 std::cout << " nOutDatas=" << status.getNOutDatas() << std::endl;
241 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300242
243 runNextStep();
244 }
245
246 //////////////////////////////////////////////////////////////////////////////////
247 //////////////////////////////////////////////////////////////////////////////////
248
249 void
250 fetchChannelStatusInformation()
251 {
252 m_buffer = make_shared<OBufferStream>();
253
254 Interest interest("/localhost/nfd/faces/channels");
255 interest.setChildSelector(1);
256 interest.setMustBeFresh(true);
257
258 m_face.expressInterest(interest,
259 bind(&NfdStatus::fetchSegments, this, _2,
260 &NfdStatus::afterFetchedChannelStatusInformation),
261 bind(&NfdStatus::onTimeout, this));
jeraldabrahamb6dde382014-03-19 18:58:09 -0700262 }
263
264 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300265 afterFetchedChannelStatusInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700266 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300267 ConstBufferPtr buf = m_buffer->buf();
268 if (m_isOutputXml)
269 {
270 std::cout << "<channels>";
271
272 Block block;
273 size_t offset = 0;
274 while (offset < buf->size())
275 {
276 bool ok = Block::fromBuffer(buf, offset, block);
277 if (!ok)
278 {
279 std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
280 break;
281 }
282
283 offset += block.size();
284
285 nfd::ChannelStatus channelStatus(block);
286
287 std::cout << "<channel>";
288
289 std::string localUri(channelStatus.getLocalUri());
290 escapeSpecialCharacters(&localUri);
291 std::cout << "<localUri>" << localUri << "</localUri>";
292 std::cout << "</channel>";
293 }
294 std::cout << "</channels>";
295 }
296 else
297 {
298 std::cout << "Channels:" << std::endl;
299
300 Block block;
301 size_t offset = 0;
302 while (offset < buf->size())
303 {
304 bool ok = Block::fromBuffer(buf, offset, block);
305 if (!ok)
306 {
307 std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
308 break;
309 }
310
311 offset += block.size();
312
313 nfd::ChannelStatus channelStatus(block);
314 std::cout << " " << channelStatus.getLocalUri() << std::endl;
315 }
316 }
317
318 runNextStep();
319 }
320
321 //////////////////////////////////////////////////////////////////////////////////
322 //////////////////////////////////////////////////////////////////////////////////
323
324 void
325 fetchFaceStatusInformation()
326 {
327 m_buffer = make_shared<OBufferStream>();
328
329 Interest interest("/localhost/nfd/faces/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700330 interest.setChildSelector(1);
331 interest.setMustBeFresh(true);
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300332
333 m_face.expressInterest(interest,
334 bind(&NfdStatus::fetchSegments, this, _2,
335 &NfdStatus::afterFetchedFaceStatusInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700336 bind(&NfdStatus::onTimeout, this));
337 }
338
339 void
340 afterFetchedFaceStatusInformation()
341 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700342 ConstBufferPtr buf = m_buffer->buf();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300343 if (m_isOutputXml)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700344 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600345 std::cout << "<faces>";
346
347 Block block;
348 size_t offset = 0;
349 while (offset < buf->size())
jeraldabrahamb6dde382014-03-19 18:58:09 -0700350 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600351 bool ok = Block::fromBuffer(buf, offset, block);
352 if (!ok)
353 {
354 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
355 break;
356 }
357
358 offset += block.size();
359
360 nfd::FaceStatus faceStatus(block);
361
362 std::cout << "<face>";
363 std::cout << "<faceId>" << faceStatus.getFaceId() << "</faceId>";
364
365 std::string remoteUri(faceStatus.getRemoteUri());
366 escapeSpecialCharacters(&remoteUri);
367 std::cout << "<remoteUri>" << remoteUri << "</remoteUri>";
368
369 std::string localUri(faceStatus.getLocalUri());
370 escapeSpecialCharacters(&localUri);
371 std::cout << "<localUri>" << localUri << "</localUri>";
372 std::cout << "<packetCounters>";
373 std::cout << "<incomingPackets>";
374 std::cout << "<nInterests>" << faceStatus.getNInInterests()
375 << "</nInterests>";
376 std::cout << "<nDatas>" << faceStatus.getNInInterests()
377 << "</nDatas>";
378 std::cout << "</incomingPackets>";
379 std::cout << "<outgoingPackets>";
380 std::cout << "<nInterests>" << faceStatus.getNOutInterests()
381 << "</nInterests>";
382 std::cout << "<nDatas>" << faceStatus.getNOutInterests()
383 << "</nDatas>";
384 std::cout << "</outgoingPackets>";
385 std::cout << "</packetCounters>";
386 std::cout << "</face>";
jeraldabrahamb6dde382014-03-19 18:58:09 -0700387 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600388 std::cout << "</faces>";
jeraldabrahamb6dde382014-03-19 18:58:09 -0700389 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600390 else
391 {
392 std::cout << "Faces:" << std::endl;
393
394 Block block;
395 size_t offset = 0;
396 while (offset < buf->size())
397 {
398 bool ok = Block::fromBuffer(buf, offset, block);
399 if (!ok)
400 {
401 std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
402 break;
403 }
404
405 offset += block.size();
406
407 nfd::FaceStatus faceStatus(block);
408
409 std::cout << " faceid=" << faceStatus.getFaceId()
410 << " remote=" << faceStatus.getRemoteUri()
411 << " local=" << faceStatus.getLocalUri()
412 << " counters={"
413 << "in={" << faceStatus.getNInInterests() << "i "
414 << faceStatus.getNInDatas() << "d}"
415 << " out={" << faceStatus.getNOutInterests() << "i "
416 << faceStatus.getNOutDatas() << "d}"
417 << "}" << std::endl;
418 }
419 }
jeraldabrahamb6dde382014-03-19 18:58:09 -0700420
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300421 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700422 }
423
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300424 //////////////////////////////////////////////////////////////////////////////////
425 //////////////////////////////////////////////////////////////////////////////////
426
jeraldabrahamb6dde382014-03-19 18:58:09 -0700427 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300428 fetchFibEnumerationInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700429 {
430 m_buffer = make_shared<OBufferStream>();
431
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300432 Interest interest("/localhost/nfd/fib/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700433 interest.setChildSelector(1);
434 interest.setMustBeFresh(true);
jeraldabrahamb6dde382014-03-19 18:58:09 -0700435 m_face.expressInterest(interest,
436 bind(&NfdStatus::fetchSegments, this, _2,
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300437 &NfdStatus::afterFetchedFibEnumerationInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700438 bind(&NfdStatus::onTimeout, this));
439 }
440
441 void
442 afterFetchedFibEnumerationInformation()
443 {
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700444 ConstBufferPtr buf = m_buffer->buf();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300445 if (m_isOutputXml)
jeraldabrahamb6dde382014-03-19 18:58:09 -0700446 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600447 std::cout << "<fib>";
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700448
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600449 Block block;
450 size_t offset = 0;
451 while (offset < buf->size())
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700452 {
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600453 bool ok = Block::fromBuffer(buf, offset, block);
454 if (!ok)
455 {
456 std::cerr << "ERROR: cannot decode FibEntry TLV";
457 break;
458 }
459 offset += block.size();
460
461 nfd::FibEntry fibEntry(block);
462
463 std::cout << "<fibEntry>";
464 std::string prefix(fibEntry.getPrefix().toUri());
465 escapeSpecialCharacters(&prefix);
466 std::cout << "<prefix>" << prefix << "</prefix>";
467 std::cout << "<nextHops>";
468 for (std::list<nfd::NextHopRecord>::const_iterator
469 nextHop = fibEntry.getNextHopRecords().begin();
470 nextHop != fibEntry.getNextHopRecords().end();
471 ++nextHop)
472 {
473 std::cout << "<nextHop>" ;
474 std::cout << "<faceId>" << nextHop->getFaceId() << "</faceId>";
475 std::cout << "<cost>" << nextHop->getCost() << "</cost>";
476 std::cout << "</nextHop>";
477 }
478 std::cout << "</nextHops>";
479 std::cout << "</fibEntry>";
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700480 }
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600481
482 std::cout << "</fib>";
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600483 }
484 else
485 {
486 std::cout << "FIB:" << std::endl;
487
488 Block block;
489 size_t offset = 0;
490 while (offset < buf->size())
491 {
492 bool ok = Block::fromBuffer(buf, offset, block);
493 if (!ok)
494 {
495 std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
496 break;
497 }
498 offset += block.size();
499
500 nfd::FibEntry fibEntry(block);
501
502 std::cout << " " << fibEntry.getPrefix() << " nexthops={";
503 for (std::list<nfd::NextHopRecord>::const_iterator
504 nextHop = fibEntry.getNextHopRecords().begin();
505 nextHop != fibEntry.getNextHopRecords().end();
506 ++nextHop)
507 {
508 if (nextHop != fibEntry.getNextHopRecords().begin())
509 std::cout << ", ";
510 std::cout << "faceid=" << nextHop->getFaceId()
511 << " (cost=" << nextHop->getCost() << ")";
512 }
513 std::cout << "}" << std::endl;
514 }
jeraldabrahamb6dde382014-03-19 18:58:09 -0700515 }
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300516
517 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700518 }
519
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300520 //////////////////////////////////////////////////////////////////////////////////
521 //////////////////////////////////////////////////////////////////////////////////
522
jeraldabrahamb6dde382014-03-19 18:58:09 -0700523 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300524 fetchStrategyChoiceInformation()
jeraldabrahamb6dde382014-03-19 18:58:09 -0700525 {
526 m_buffer = make_shared<OBufferStream>();
527
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300528 Interest interest("/localhost/nfd/strategy-choice/list");
jeraldabrahamb6dde382014-03-19 18:58:09 -0700529 interest.setChildSelector(1);
530 interest.setMustBeFresh(true);
531 m_face.expressInterest(interest,
532 bind(&NfdStatus::fetchSegments, this, _2,
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300533 &NfdStatus::afterFetchedStrategyChoiceInformationInformation),
jeraldabrahamb6dde382014-03-19 18:58:09 -0700534 bind(&NfdStatus::onTimeout, this));
535 }
536
537 void
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300538 afterFetchedStrategyChoiceInformationInformation()
539 {
540 ConstBufferPtr buf = m_buffer->buf();
541 if (m_isOutputXml)
542 {
543 std::cout << "<strategyChoices>";
544
545 Block block;
546 size_t offset = 0;
547 while (offset < buf->size())
548 {
549 bool ok = Block::fromBuffer(buf, offset, block);
550 if (!ok)
551 {
552 std::cerr << "ERROR: cannot decode StrategyChoice TLV";
553 break;
554 }
555 offset += block.size();
556
557 nfd::StrategyChoice strategyChoice(block);
558
559 std::cout << "<strategyChoice>";
560
561 std::string name(strategyChoice.getName().toUri());
562 escapeSpecialCharacters(&name);
563 std::cout << "<namespace>" << name << "</namespace>";
564 std::cout << "<strategy>";
565
566 std::string strategy(strategyChoice.getStrategy().toUri());
567 escapeSpecialCharacters(&strategy);
568
569 std::cout << "<name>" << strategy << "</name>";
570 std::cout << "</strategy>";
571 std::cout << "</strategyChoice>";
572 }
573
574 std::cout << "</strategyChoices>";
575 }
576 else
577 {
578 std::cout << "Strategy choices:" << std::endl;
579
580 Block block;
581 size_t offset = 0;
582 while (offset < buf->size())
583 {
584 bool ok = Block::fromBuffer(buf, offset, block);
585 if (!ok)
586 {
587 std::cerr << "ERROR: cannot decode StrategyChoice TLV" << std::endl;
588 break;
589 }
590 offset += block.size();
591
592 nfd::StrategyChoice strategyChoice(block);
593
594 std::cout << " " << strategyChoice.getName()
595 << " strategy=" << strategyChoice.getStrategy() << std::endl;
596 }
597 }
598
599 runNextStep();
600 }
601
602 void
jeraldabrahamb6dde382014-03-19 18:58:09 -0700603 fetchInformation()
604 {
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300605 if (m_isOutputXml ||
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600606 (!m_needVersionRetrieval &&
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300607 !m_needChannelStatusRetrieval &&
608 !m_needFaceStatusRetrieval &&
609 !m_needFibEnumerationRetrieval &&
610 !m_needStrategyChoiceRetrieval))
jeraldabrahamb6dde382014-03-19 18:58:09 -0700611 {
612 enableVersionRetrieval();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300613 enableChannelStatusRetrieval();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700614 enableFaceStatusRetrieval();
615 enableFibEnumerationRetrieval();
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300616 enableStrategyChoiceRetrieval();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700617 }
618
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300619 if (m_isOutputXml)
620 m_fetchSteps.push_back(bind(&NfdStatus::printXmlHeader, this));
621
jeraldabrahamb6dde382014-03-19 18:58:09 -0700622 if (m_needVersionRetrieval)
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300623 m_fetchSteps.push_back(bind(&NfdStatus::fetchVersionInformation, this));
jeraldabrahamb6dde382014-03-19 18:58:09 -0700624
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300625 if (m_needChannelStatusRetrieval)
626 m_fetchSteps.push_back(bind(&NfdStatus::fetchChannelStatusInformation, this));
627
628 if (m_needFaceStatusRetrieval)
629 m_fetchSteps.push_back(bind(&NfdStatus::fetchFaceStatusInformation, this));
630
631 if (m_needFibEnumerationRetrieval)
632 m_fetchSteps.push_back(bind(&NfdStatus::fetchFibEnumerationInformation, this));
633
634 if (m_needStrategyChoiceRetrieval)
635 m_fetchSteps.push_back(bind(&NfdStatus::fetchStrategyChoiceInformation, this));
636
637 if (m_isOutputXml)
638 m_fetchSteps.push_back(bind(&NfdStatus::printXmlFooter, this));
639
640 runNextStep();
jeraldabrahamb6dde382014-03-19 18:58:09 -0700641 m_face.processEvents();
642 }
643
644private:
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300645 void
646 printXmlHeader()
647 {
648 std::cout << "<?xml version=\"1.0\"?>";
649 std::cout << "<nfdStatus xmlns=\"ndn:/localhost/nfd/status/1\">";
650
651 runNextStep();
652 }
653
654 void
655 printXmlFooter()
656 {
657 std::cout << "</nfdStatus>";
658
659 runNextStep();
660 }
661
662 void
663 runNextStep()
664 {
665 if (m_fetchSteps.empty())
666 return;
667
668 function<void()> nextStep = m_fetchSteps.front();
669 m_fetchSteps.pop_front();
670 nextStep();
671 }
672
673private:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700674 std::string m_toolName;
675 bool m_needVersionRetrieval;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300676 bool m_needChannelStatusRetrieval;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700677 bool m_needFaceStatusRetrieval;
678 bool m_needFibEnumerationRetrieval;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300679 bool m_needStrategyChoiceRetrieval;
680 bool m_isOutputXml;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700681 Face m_face;
682
683 shared_ptr<OBufferStream> m_buffer;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300684
685 std::deque<function<void()> > m_fetchSteps;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700686};
687
688}
689
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700690int main(int argc, char* argv[])
jeraldabrahamb6dde382014-03-19 18:58:09 -0700691{
692 int option;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700693 ndn::NfdStatus nfdStatus(argv[0]);
jeraldabrahamb6dde382014-03-19 18:58:09 -0700694
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300695 while ((option = getopt(argc, argv, "hvcfbsxV")) != -1) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700696 switch (option) {
697 case 'h':
698 nfdStatus.usage();
Alexander Afanasyev60a7ba52014-03-23 11:23:06 -0700699 return 0;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700700 case 'v':
701 nfdStatus.enableVersionRetrieval();
702 break;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300703 case 'c':
704 nfdStatus.enableChannelStatusRetrieval();
705 break;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700706 case 'f':
707 nfdStatus.enableFaceStatusRetrieval();
708 break;
709 case 'b':
710 nfdStatus.enableFibEnumerationRetrieval();
711 break;
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300712 case 's':
713 nfdStatus.enableStrategyChoiceRetrieval();
714 break;
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600715 case 'x':
Alexander Afanasyev0417d2a2014-06-08 10:56:43 +0300716 nfdStatus.enableXmlOutput();
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600717 break;
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700718 case 'V':
719 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
720 return 0;
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700721 default:
jeraldabrahamb6dde382014-03-19 18:58:09 -0700722 nfdStatus.usage();
723 return 1;
jeraldabrahamb6dde382014-03-19 18:58:09 -0700724 }
725 }
726
727 try {
728 nfdStatus.fetchInformation();
729 }
Alexander Afanasyev7b7dfdd2014-03-21 13:57:54 -0700730 catch (std::exception& e) {
jeraldabrahamb6dde382014-03-19 18:58:09 -0700731 std::cerr << "ERROR: " << e.what() << std::endl;
732 return 2;
733 }
734
735 return 0;
736}