blob: dcb228cabcb6359b257fef960f399f73db86b2ef [file] [log] [blame]
hilata198cadb2014-02-15 23:46:19 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Syed Obaid4ae0ce32014-06-17 13:59:20 -05003 * 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
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Syed Obaid4ae0ce32014-06-17 13:59:20 -050024 */
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070025
hilata198cadb2014-02-15 23:46:19 -060026#include "nfdc.hpp"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070027#include "version.hpp"
28
hilata198cadb2014-02-15 23:46:19 -060029#include <boost/lexical_cast.hpp>
30#include <boost/algorithm/string.hpp>
31#include <boost/algorithm/string/regex_find_format.hpp>
32#include <boost/regex.hpp>
33
Chengyu Fan27be0b02014-11-24 20:52:53 -070034#include <ndn-cxx/management/nfd-face-query-filter.hpp>
35#include <ndn-cxx/management/nfd-face-status.hpp>
36#include <ndn-cxx/util/segment-fetcher.hpp>
37
hilata198cadb2014-02-15 23:46:19 -060038void
39usage(const char* programName)
40{
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070041 std::cout << "Usage:\n" << programName << " [-h] [-V] COMMAND [<Command Options>]\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070042 " -h print usage and exit\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070043 " -V print version and exit\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070044 "\n"
Obaiddca50792014-04-24 18:38:40 -050045 " COMMAND can be one of the following:\n"
Syed Obaid4ae0ce32014-06-17 13:59:20 -050046 " register [-I] [-C] [-c cost] [-e expiration time] [-o origin] name <faceId | faceUri>\n"
Obaiddca50792014-04-24 18:38:40 -050047 " register name to the given faceId or faceUri\n"
48 " -I: unset CHILD_INHERIT flag\n"
49 " -C: set CAPTURE flag\n"
Syed Obaid818e8a62014-07-02 18:24:11 -050050 " -c: specify cost (default 0)\n"
51 " -e: specify expiration time in ms\n"
52 " (by default the entry remains in FIB for the lifetime of the associated face)\n"
Syed Obaid4ae0ce32014-06-17 13:59:20 -050053 " -o: specify origin\n"
Syed Obaid818e8a62014-07-02 18:24:11 -050054 " 0 for Local producer applications, 128 for NLSR, 255(default) for static routes\n"
Chengyu Fan27be0b02014-11-24 20:52:53 -070055 " unregister [-o origin] name <faceId | faceUri>\n"
Obaiddca50792014-04-24 18:38:40 -050056 " unregister name from the given faceId\n"
57 " create <faceUri> \n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070058 " Create a face in one of the following formats:\n"
59 " UDP unicast: udp[4|6]://<remote-IP-or-host>[:<remote-port>]\n"
60 " TCP: tcp[4|6]://<remote-IP-or-host>[:<remote-port>] \n"
Obaiddca50792014-04-24 18:38:40 -050061 " destroy <faceId | faceUri> \n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070062 " Destroy a face\n"
63 " set-strategy <name> <strategy> \n"
64 " Set the strategy for a namespace \n"
65 " unset-strategy <name> \n"
66 " Unset the strategy for a namespace \n"
hilata6ee6e072014-04-20 17:10:18 -050067 " add-nexthop [-c <cost>] <name> <faceId | faceUri>\n"
68 " Add a nexthop to a FIB entry\n"
Syed Obaid818e8a62014-07-02 18:24:11 -050069 " -c: specify cost (default 0)\n"
Chengyu Fan27be0b02014-11-24 20:52:53 -070070 " remove-nexthop <name> <faceId | faceUri> \n"
hilata6ee6e072014-04-20 17:10:18 -050071 " Remove a nexthop from a FIB entry\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070072 << std::endl;
hilata198cadb2014-02-15 23:46:19 -060073}
74
75namespace nfdc {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070076
Junxiao Shicd55cde2014-11-13 16:03:24 -070077using std::bind;
Davide Pesaventoab1e8f22014-10-21 22:45:33 +020078
Syed Obaid818e8a62014-07-02 18:24:11 -050079const ndn::time::milliseconds Nfdc::DEFAULT_EXPIRATION_PERIOD = ndn::time::milliseconds::max();
Syed Obaid4ae0ce32014-06-17 13:59:20 -050080const uint64_t Nfdc::DEFAULT_COST = 0;
81
Chengyu Fan27be0b02014-11-24 20:52:53 -070082Nfdc::FaceIdFetcher::FaceIdFetcher(ndn::Face& face,
83 Controller& controller,
84 bool allowCreate,
85 const SuccessCallback& onSucceed,
86 const FailureCallback& onFail)
87 : m_face(face)
88 , m_controller(controller)
89 , m_allowCreate(allowCreate)
90 , m_onSucceed(onSucceed)
91 , m_onFail(onFail)
92{
93}
94
95void
96Nfdc::FaceIdFetcher::start(ndn::Face& face,
97 Controller& controller,
98 const std::string& input,
99 bool allowCreate,
100 const SuccessCallback& onSucceed,
101 const FailureCallback& onFail)
102{
103 // 1. Try parse input as FaceId, if input is FaceId, succeed with parsed FaceId
104 // 2. Try parse input as FaceUri, if input is not FaceUri, fail
105 // 3. Canonize faceUri
106 // 4. If canonization fails, fail
107 // 5. Query for face
108 // 6. If query succeeds and finds a face, succeed with found FaceId
109 // 7. Create face
110 // 8. If face creation succeeds, succeed with created FaceId
111 // 9. Fail
112
113 boost::regex e("^[a-z0-9]+\\:.*");
114 if (!boost::regex_match(input, e)) {
115 try
116 {
117 u_int32_t faceId = boost::lexical_cast<uint32_t>(input);
118 onSucceed(faceId);
119 return;
120 }
121 catch (boost::bad_lexical_cast&)
122 {
123 onFail("No valid faceId or faceUri is provided");
124 return;
125 }
126 }
127 else {
128 ndn::util::FaceUri faceUri;
129 if (!faceUri.parse(input)) {
130 onFail("FaceUri parse failed");
131 return;
132 }
133
134 auto fetcher = new FaceIdFetcher(std::ref(face), std::ref(controller),
135 allowCreate, onSucceed, onFail);
136
137 fetcher->startGetFaceId(faceUri);
138 }
139}
140
141void
142Nfdc::FaceIdFetcher::startGetFaceId(const ndn::util::FaceUri& faceUri)
143{
144 faceUri.canonize(bind(&FaceIdFetcher::onCanonizeSuccess, this, _1),
145 bind(&FaceIdFetcher::onCanonizeFailure, this, _1),
146 m_face.getIoService(), ndn::time::seconds(4));
147}
148
149void
150Nfdc::FaceIdFetcher::onCanonizeSuccess(const ndn::util::FaceUri& canonicalUri)
151{
152 ndn::Name queryName("/localhost/nfd/faces/query");
153 ndn::nfd::FaceQueryFilter queryFilter;
154 queryFilter.setRemoteUri(canonicalUri.toString());
155 queryName.append(queryFilter.wireEncode());
156
157 ndn::Interest interestPacket(queryName);
158 interestPacket.setMustBeFresh(true);
159 interestPacket.setInterestLifetime(ndn::time::milliseconds(4000));
160 auto interest = std::make_shared<ndn::Interest>(interestPacket);
161
162 ndn::util::SegmentFetcher::fetch(m_face, *interest,
163 ndn::util::DontVerifySegment(),
164 bind(&FaceIdFetcher::onQuerySuccess,
165 this, _1, canonicalUri),
166 bind(&FaceIdFetcher::onQueryFailure,
167 this, _1, canonicalUri));
168}
169
170void
171Nfdc::FaceIdFetcher::onCanonizeFailure(const std::string& reason)
172{
173 fail("Canonize faceUri failed : " + reason);
174}
175
176void
177Nfdc::FaceIdFetcher::onQuerySuccess(const ndn::ConstBufferPtr& data,
178 const ndn::util::FaceUri& canonicalUri)
179{
180 size_t offset = 0;
181 ndn::Block block;
182 bool ok = ndn::Block::fromBuffer(data, offset, block);
183
184 if (!ok) {
185 if (m_allowCreate) {
186 startFaceCreate(canonicalUri);
187 }
188 else {
189 fail("Fail to find faceId");
190 }
191 }
192 else {
193 try {
194 FaceStatus status(block);
195 succeed(status.getFaceId());
196 }
197 catch (const ndn::tlv::Error& e) {
198 std::string errorMessage(e.what());
199 fail("ERROR: " + errorMessage);
200 }
201 }
202}
203
204void
205Nfdc::FaceIdFetcher::onQueryFailure(uint32_t errorCode,
206 const ndn::util::FaceUri& canonicalUri)
207{
208 std::stringstream ss;
209 ss << "Cannot fetch data (code " << errorCode << ")";
210 fail(ss.str());
211}
212
213void
214Nfdc::FaceIdFetcher::onFaceCreateError(uint32_t code,
215 const std::string& error,
216 const std::string& message)
217{
218 std::stringstream ss;
219 ss << message << " : " << error << " (code " << code << ")";
220 fail(ss.str());
221}
222
223void
224Nfdc::FaceIdFetcher::startFaceCreate(const ndn::util::FaceUri& canonicalUri)
225{
226 ControlParameters parameters;
227 parameters.setUri(canonicalUri.toString());
228
229 m_controller.start<FaceCreateCommand>(parameters,
230 [this] (const ControlParameters& result) {
231 succeed(result.getFaceId());
232 },
233 bind(&FaceIdFetcher::onFaceCreateError, this, _1, _2,
234 "Face creation failed"));
235}
236
237void
238Nfdc::FaceIdFetcher::succeed(uint32_t faceId)
239{
240 m_onSucceed(faceId);
241 delete this;
242}
243
244void
245Nfdc::FaceIdFetcher::fail(const std::string& reason)
246{
247 m_onFail(reason);
248 delete this;
249}
250
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700251Nfdc::Nfdc(ndn::Face& face)
Obaiddca50792014-04-24 18:38:40 -0500252 : m_flags(ROUTE_FLAG_CHILD_INHERIT)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500253 , m_cost(DEFAULT_COST)
254 , m_origin(ROUTE_ORIGIN_STATIC)
255 , m_expires(DEFAULT_EXPIRATION_PERIOD)
Chengyu Fan27be0b02014-11-24 20:52:53 -0700256 , m_face(face)
Junxiao Shi8e273ca2014-11-12 00:42:29 -0700257 , m_controller(face, m_keyChain)
Chengyu Fandae25302014-10-16 11:40:11 -0600258 , m_ioService(face.getIoService())
hilata198cadb2014-02-15 23:46:19 -0600259{
260}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700261
262Nfdc::~Nfdc()
hilata198cadb2014-02-15 23:46:19 -0600263{
264}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700265
hilata198cadb2014-02-15 23:46:19 -0600266bool
hilata54e4eaf2014-04-10 23:38:33 -0500267Nfdc::dispatch(const std::string& command)
hilata198cadb2014-02-15 23:46:19 -0600268{
Obaiddca50792014-04-24 18:38:40 -0500269 if (command == "add-nexthop") {
270 if (m_nOptions != 2)
hilata54e4eaf2014-04-10 23:38:33 -0500271 return false;
Obaiddca50792014-04-24 18:38:40 -0500272 fibAddNextHop();
hilata198cadb2014-02-15 23:46:19 -0600273 }
274 else if (command == "remove-nexthop") {
hilata54e4eaf2014-04-10 23:38:33 -0500275 if (m_nOptions != 2)
hilata198cadb2014-02-15 23:46:19 -0600276 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500277 fibRemoveNextHop();
hilata198cadb2014-02-15 23:46:19 -0600278 }
Obaiddca50792014-04-24 18:38:40 -0500279 else if (command == "register") {
280 if (m_nOptions != 2)
281 return false;
282 ribRegisterPrefix();
283 }
284 else if (command == "unregister") {
285 if (m_nOptions != 2)
286 return false;
287 ribUnregisterPrefix();
288 }
hilata198cadb2014-02-15 23:46:19 -0600289 else if (command == "create") {
hilata54e4eaf2014-04-10 23:38:33 -0500290 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600291 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500292 faceCreate();
hilata198cadb2014-02-15 23:46:19 -0600293 }
294 else if (command == "destroy") {
hilata54e4eaf2014-04-10 23:38:33 -0500295 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600296 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500297 faceDestroy();
hilata198cadb2014-02-15 23:46:19 -0600298 }
hilata141eaae2014-03-13 19:54:47 -0500299 else if (command == "set-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500300 if (m_nOptions != 2)
hilata141eaae2014-03-13 19:54:47 -0500301 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500302 strategyChoiceSet();
hilata141eaae2014-03-13 19:54:47 -0500303 }
304 else if (command == "unset-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500305 if (m_nOptions != 1)
hilata141eaae2014-03-13 19:54:47 -0500306 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500307 strategyChoiceUnset();
hilata141eaae2014-03-13 19:54:47 -0500308 }
hilata198cadb2014-02-15 23:46:19 -0600309 else
310 usage(m_programName);
311
312 return true;
313}
hilata198cadb2014-02-15 23:46:19 -0600314
hilata198cadb2014-02-15 23:46:19 -0600315void
Obaiddca50792014-04-24 18:38:40 -0500316Nfdc::fibAddNextHop()
hilata198cadb2014-02-15 23:46:19 -0600317{
Obaiddca50792014-04-24 18:38:40 -0500318 m_name = m_commandLineArguments[0];
Chengyu Fan27be0b02014-11-24 20:52:53 -0700319 const std::string& faceName = m_commandLineArguments[1];
hilata54e4eaf2014-04-10 23:38:33 -0500320
Chengyu Fan27be0b02014-11-24 20:52:53 -0700321 FaceIdFetcher::start(m_face, m_controller, faceName, true,
322 [this] (const uint32_t faceId) {
323 ControlParameters parameters;
324 parameters
325 .setName(m_name)
326 .setCost(m_cost)
327 .setFaceId(faceId);
hilata54e4eaf2014-04-10 23:38:33 -0500328
Chengyu Fan27be0b02014-11-24 20:52:53 -0700329 m_controller
330 .start<FibAddNextHopCommand>(parameters,
331 bind(&Nfdc::onSuccess, this, _1,
332 "Nexthop insertion succeeded"),
333 bind(&Nfdc::onError, this, _1, _2,
334 "Nexthop insertion failed"));
335 },
336 bind(&Nfdc::onObtainFaceIdFailure, this, _1));
hilata54e4eaf2014-04-10 23:38:33 -0500337}
338
339void
340Nfdc::fibRemoveNextHop()
341{
Obaiddca50792014-04-24 18:38:40 -0500342 m_name = m_commandLineArguments[0];
Chengyu Fan27be0b02014-11-24 20:52:53 -0700343 const std::string& faceName = m_commandLineArguments[1];
hilata54e4eaf2014-04-10 23:38:33 -0500344
Chengyu Fan27be0b02014-11-24 20:52:53 -0700345 FaceIdFetcher::start(m_face, m_controller, faceName, false,
346 [this] (const uint32_t faceId) {
347 ControlParameters parameters;
348 parameters
349 .setName(m_name)
350 .setFaceId(faceId);
hilata54e4eaf2014-04-10 23:38:33 -0500351
Chengyu Fan27be0b02014-11-24 20:52:53 -0700352 m_controller
353 .start<FibRemoveNextHopCommand>(parameters,
354 bind(&Nfdc::onSuccess, this, _1,
355 "Nexthop removal succeeded"),
356 bind(&Nfdc::onError, this, _1, _2,
357 "Nexthop removal failed"));
358 },
359 bind(&Nfdc::onObtainFaceIdFailure, this, _1));
Obaiddca50792014-04-24 18:38:40 -0500360}
361
362void
363Nfdc::ribRegisterPrefix()
364{
365 m_name = m_commandLineArguments[0];
Chengyu Fan27be0b02014-11-24 20:52:53 -0700366 const std::string& faceName = m_commandLineArguments[1];
Alexander Afanasyevf67cf082014-07-18 16:47:29 -0700367
Chengyu Fan27be0b02014-11-24 20:52:53 -0700368 FaceIdFetcher::start(m_face, m_controller, faceName, true,
369 [this] (const uint32_t faceId) {
370 ControlParameters parameters;
371 parameters
372 .setName(m_name)
373 .setCost(m_cost)
374 .setFlags(m_flags)
375 .setOrigin(m_origin)
376 .setFaceId(faceId);
Obaiddca50792014-04-24 18:38:40 -0500377
Chengyu Fan27be0b02014-11-24 20:52:53 -0700378 if (m_expires != DEFAULT_EXPIRATION_PERIOD)
379 parameters.setExpirationPeriod(m_expires);
Obaiddca50792014-04-24 18:38:40 -0500380
Chengyu Fan27be0b02014-11-24 20:52:53 -0700381 m_controller
382 .start<RibRegisterCommand>(parameters,
383 bind(&Nfdc::onSuccess, this, _1,
384 "Successful in name registration"),
385 bind(&Nfdc::onError, this, _1, _2,
386 "Failed in name registration"));
387 },
388 bind(&Nfdc::onObtainFaceIdFailure, this, _1));
Obaiddca50792014-04-24 18:38:40 -0500389}
390
391void
392Nfdc::ribUnregisterPrefix()
393{
394 m_name = m_commandLineArguments[0];
Chengyu Fan27be0b02014-11-24 20:52:53 -0700395 const std::string& faceName = m_commandLineArguments[1];
Obaiddca50792014-04-24 18:38:40 -0500396
Chengyu Fan27be0b02014-11-24 20:52:53 -0700397 FaceIdFetcher::start(m_face, m_controller, faceName, false,
398 [this] (const uint32_t faceId) {
399 ControlParameters parameters;
400 parameters
401 .setName(m_name)
402 .setFaceId(faceId)
403 .setOrigin(m_origin);
Obaiddca50792014-04-24 18:38:40 -0500404
Chengyu Fan27be0b02014-11-24 20:52:53 -0700405 m_controller
406 .start<RibUnregisterCommand>(parameters,
407 bind(&Nfdc::onSuccess, this, _1,
408 "Successful in unregistering name"),
409 bind(&Nfdc::onError, this, _1, _2,
410 "Failed in unregistering name"));
411 },
412 bind(&Nfdc::onObtainFaceIdFailure, this, _1));
hilata54e4eaf2014-04-10 23:38:33 -0500413}
414
415void
Chengyu Fandae25302014-10-16 11:40:11 -0600416Nfdc::onCanonizeFailure(const std::string& reason)
417{
418 std::cerr << reason << std::endl;
419}
420
421void
Chengyu Fan27be0b02014-11-24 20:52:53 -0700422Nfdc::onObtainFaceIdFailure(const std::string& message)
423{
424 std::cerr << "Obtain faceId failure: " << message << std::endl;
425}
426
427void
hilata54e4eaf2014-04-10 23:38:33 -0500428Nfdc::faceCreate()
429{
Chengyu Fan27be0b02014-11-24 20:52:53 -0700430 boost::regex e("^[a-z0-9]+\\:.*");
431 if (!boost::regex_match(m_commandLineArguments[0], e))
hilata54e4eaf2014-04-10 23:38:33 -0500432 throw Error("invalid uri format");
433
Chengyu Fandae25302014-10-16 11:40:11 -0600434 ndn::util::FaceUri faceUri;
435 faceUri.parse(m_commandLineArguments[0]);
436
437 faceUri.canonize(bind(&Nfdc::startFaceCreate, this, _1),
438 bind(&Nfdc::onCanonizeFailure, this, _1),
439 m_ioService, ndn::time::seconds(4));
440}
441
442void
443Nfdc::startFaceCreate(const ndn::util::FaceUri& canonicalUri)
444{
hilata54e4eaf2014-04-10 23:38:33 -0500445 ControlParameters parameters;
Chengyu Fandae25302014-10-16 11:40:11 -0600446 parameters.setUri(canonicalUri.toString());
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700447
Obaiddca50792014-04-24 18:38:40 -0500448 m_controller.start<FaceCreateCommand>(parameters,
449 bind(&Nfdc::onSuccess, this, _1,
450 "Face creation succeeded"),
451 bind(&Nfdc::onError, this, _1, _2,
452 "Face creation failed"));
hilata198cadb2014-02-15 23:46:19 -0600453}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700454
hilata198cadb2014-02-15 23:46:19 -0600455void
hilata54e4eaf2014-04-10 23:38:33 -0500456Nfdc::faceDestroy()
hilata198cadb2014-02-15 23:46:19 -0600457{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700458 ControlParameters parameters;
Chengyu Fan27be0b02014-11-24 20:52:53 -0700459 const std::string& faceName = m_commandLineArguments[0];
Chengyu Fandae25302014-10-16 11:40:11 -0600460
Chengyu Fan27be0b02014-11-24 20:52:53 -0700461 FaceIdFetcher::start(m_face, m_controller, faceName, false,
462 [this] (const uint32_t faceId) {
463 ControlParameters faceParameters;
464 faceParameters.setFaceId(faceId);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700465
Chengyu Fan27be0b02014-11-24 20:52:53 -0700466 m_controller.start<FaceDestroyCommand>(faceParameters,
467 bind(&Nfdc::onSuccess, this, _1,
468 "Face destroy succeeded"),
469 bind(&Nfdc::onError, this, _1, _2,
470 "Face destroy failed"));
471 },
472 bind(&Nfdc::onObtainFaceIdFailure, this, _1));
hilata198cadb2014-02-15 23:46:19 -0600473}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700474
hilata141eaae2014-03-13 19:54:47 -0500475void
hilata54e4eaf2014-04-10 23:38:33 -0500476Nfdc::strategyChoiceSet()
hilata141eaae2014-03-13 19:54:47 -0500477{
hilata54e4eaf2014-04-10 23:38:33 -0500478 const std::string& name = m_commandLineArguments[0];
479 const std::string& strategy = m_commandLineArguments[1];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700480
481 ControlParameters parameters;
482 parameters
483 .setName(name)
484 .setStrategy(strategy);
485
Obaiddca50792014-04-24 18:38:40 -0500486 m_controller.start<StrategyChoiceSetCommand>(parameters,
487 bind(&Nfdc::onSuccess, this, _1,
488 "Successfully set strategy choice"),
489 bind(&Nfdc::onError, this, _1, _2,
490 "Failed to set strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500491}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700492
hilata141eaae2014-03-13 19:54:47 -0500493void
hilata54e4eaf2014-04-10 23:38:33 -0500494Nfdc::strategyChoiceUnset()
hilata141eaae2014-03-13 19:54:47 -0500495{
hilata54e4eaf2014-04-10 23:38:33 -0500496 const std::string& name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700497
498 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500499 parameters.setName(name);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700500
Obaiddca50792014-04-24 18:38:40 -0500501 m_controller.start<StrategyChoiceUnsetCommand>(parameters,
502 bind(&Nfdc::onSuccess, this, _1,
503 "Successfully unset strategy choice"),
504 bind(&Nfdc::onError, this, _1, _2,
505 "Failed to unset strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500506}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700507
hilata198cadb2014-02-15 23:46:19 -0600508void
Obaiddca50792014-04-24 18:38:40 -0500509Nfdc::onSuccess(const ControlParameters& commandSuccessResult, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600510{
Obaiddca50792014-04-24 18:38:40 -0500511 std::cout << message << ": " << commandSuccessResult << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600512}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700513
hilata198cadb2014-02-15 23:46:19 -0600514void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700515Nfdc::onError(uint32_t code, const std::string& error, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600516{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700517 std::ostringstream os;
518 os << message << ": " << error << " (code: " << code << ")";
519 throw Error(os.str());
hilata141eaae2014-03-13 19:54:47 -0500520}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700521
hilata141eaae2014-03-13 19:54:47 -0500522} // namespace nfdc
hilata198cadb2014-02-15 23:46:19 -0600523
524int
525main(int argc, char** argv)
526{
527 ndn::Face face;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700528 nfdc::Nfdc p(face);
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800529
hilata198cadb2014-02-15 23:46:19 -0600530 p.m_programName = argv[0];
hilata54e4eaf2014-04-10 23:38:33 -0500531
Obaiddca50792014-04-24 18:38:40 -0500532 if (argc < 2) {
533 usage(p.m_programName);
534 return 0;
535 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700536
Obaiddca50792014-04-24 18:38:40 -0500537 if (!strcmp(argv[1], "-h")) {
538 usage(p.m_programName);
539 return 0;
540 }
541
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700542 if (!strcmp(argv[1], "-V")) {
543 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
544 return 0;
545 }
546
Junxiao Shi22295032014-04-29 22:57:40 -0700547 ::optind = 2; //start reading options from 2nd argument i.e. Command
Obaiddca50792014-04-24 18:38:40 -0500548 int opt;
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500549 while ((opt = ::getopt(argc, argv, "ICc:e:o:")) != -1) {
Obaiddca50792014-04-24 18:38:40 -0500550 switch (opt) {
551 case 'I':
552 p.m_flags = p.m_flags & ~(nfdc::ROUTE_FLAG_CHILD_INHERIT);
553 break;
554
555 case 'C':
556 p.m_flags = p.m_flags | nfdc::ROUTE_FLAG_CAPTURE;
557 break;
558
559 case 'c':
560 try {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500561 p.m_cost = boost::lexical_cast<uint64_t>(::optarg);
Obaiddca50792014-04-24 18:38:40 -0500562 }
Junxiao Shi22295032014-04-29 22:57:40 -0700563 catch (boost::bad_lexical_cast&) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500564 std::cerr << "Error: cost must be in unsigned integer format" << std::endl;
565 return 1;
566 }
567 break;
568
569 case 'e':
570 uint64_t expires;
571 try {
572 expires = boost::lexical_cast<uint64_t>(::optarg);
573 }
574 catch (boost::bad_lexical_cast&) {
575 std::cerr << "Error: expiration time must be in unsigned integer format" << std::endl;
576 return 1;
577 }
578 p.m_expires = ndn::time::milliseconds(expires);
579 break;
580
581 case 'o':
582 try {
583 p.m_origin = boost::lexical_cast<uint64_t>(::optarg);
584 }
585 catch (boost::bad_lexical_cast&) {
586 std::cerr << "Error: origin must be in unsigned integer format" << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600587 return 1;
Obaiddca50792014-04-24 18:38:40 -0500588 }
589 break;
Junxiao Shi22295032014-04-29 22:57:40 -0700590
Obaiddca50792014-04-24 18:38:40 -0500591 default:
592 usage(p.m_programName);
593 return 1;
hilata198cadb2014-02-15 23:46:19 -0600594 }
595 }
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800596
Junxiao Shi22295032014-04-29 22:57:40 -0700597 if (argc == ::optind) {
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800598 usage(p.m_programName);
599 return 1;
600 }
601
hilata198cadb2014-02-15 23:46:19 -0600602 try {
Junxiao Shi22295032014-04-29 22:57:40 -0700603 p.m_commandLineArguments = argv + ::optind;
604 p.m_nOptions = argc - ::optind;
Obaiddca50792014-04-24 18:38:40 -0500605
606 //argv[1] points to the command, so pass it to the dispatch
607 bool isOk = p.dispatch(argv[1]);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700608 if (!isOk) {
hilata198cadb2014-02-15 23:46:19 -0600609 usage(p.m_programName);
610 return 1;
611 }
hilata198cadb2014-02-15 23:46:19 -0600612 face.processEvents();
613 }
614 catch (const std::exception& e) {
615 std::cerr << "ERROR: " << e.what() << std::endl;
616 return 2;
617 }
618 return 0;
619}