blob: 2ecba4d09fdf15867454f5fc7dd0c8c9be2645bb [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
34void
35usage(const char* programName)
36{
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070037 std::cout << "Usage:\n" << programName << " [-h] [-V] COMMAND [<Command Options>]\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070038 " -h print usage and exit\n"
Alexander Afanasyevb47d5382014-05-05 14:35:03 -070039 " -V print version and exit\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070040 "\n"
Obaiddca50792014-04-24 18:38:40 -050041 " COMMAND can be one of the following:\n"
Syed Obaid4ae0ce32014-06-17 13:59:20 -050042 " register [-I] [-C] [-c cost] [-e expiration time] [-o origin] name <faceId | faceUri>\n"
Obaiddca50792014-04-24 18:38:40 -050043 " register name to the given faceId or faceUri\n"
44 " -I: unset CHILD_INHERIT flag\n"
45 " -C: set CAPTURE flag\n"
Syed Obaid818e8a62014-07-02 18:24:11 -050046 " -c: specify cost (default 0)\n"
47 " -e: specify expiration time in ms\n"
48 " (by default the entry remains in FIB for the lifetime of the associated face)\n"
Syed Obaid4ae0ce32014-06-17 13:59:20 -050049 " -o: specify origin\n"
Syed Obaid818e8a62014-07-02 18:24:11 -050050 " 0 for Local producer applications, 128 for NLSR, 255(default) for static routes\n"
Syed Obaidf93f9d92014-06-22 13:50:48 -050051 " unregister [-o origin] name <faceId>\n"
Obaiddca50792014-04-24 18:38:40 -050052 " unregister name from the given faceId\n"
53 " create <faceUri> \n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070054 " Create a face in one of the following formats:\n"
55 " UDP unicast: udp[4|6]://<remote-IP-or-host>[:<remote-port>]\n"
56 " TCP: tcp[4|6]://<remote-IP-or-host>[:<remote-port>] \n"
Obaiddca50792014-04-24 18:38:40 -050057 " destroy <faceId | faceUri> \n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070058 " Destroy a face\n"
59 " set-strategy <name> <strategy> \n"
60 " Set the strategy for a namespace \n"
61 " unset-strategy <name> \n"
62 " Unset the strategy for a namespace \n"
hilata6ee6e072014-04-20 17:10:18 -050063 " add-nexthop [-c <cost>] <name> <faceId | faceUri>\n"
64 " Add a nexthop to a FIB entry\n"
Syed Obaid818e8a62014-07-02 18:24:11 -050065 " -c: specify cost (default 0)\n"
hilata6ee6e072014-04-20 17:10:18 -050066 " remove-nexthop <name> <faceId> \n"
67 " Remove a nexthop from a FIB entry\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070068 << std::endl;
hilata198cadb2014-02-15 23:46:19 -060069}
70
71namespace nfdc {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070072
Junxiao Shicd55cde2014-11-13 16:03:24 -070073using std::bind;
Davide Pesaventoab1e8f22014-10-21 22:45:33 +020074
Syed Obaid818e8a62014-07-02 18:24:11 -050075const ndn::time::milliseconds Nfdc::DEFAULT_EXPIRATION_PERIOD = ndn::time::milliseconds::max();
Syed Obaid4ae0ce32014-06-17 13:59:20 -050076const uint64_t Nfdc::DEFAULT_COST = 0;
77
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070078Nfdc::Nfdc(ndn::Face& face)
Obaiddca50792014-04-24 18:38:40 -050079 : m_flags(ROUTE_FLAG_CHILD_INHERIT)
Syed Obaid4ae0ce32014-06-17 13:59:20 -050080 , m_cost(DEFAULT_COST)
81 , m_origin(ROUTE_ORIGIN_STATIC)
82 , m_expires(DEFAULT_EXPIRATION_PERIOD)
Junxiao Shi8e273ca2014-11-12 00:42:29 -070083 , m_controller(face, m_keyChain)
Chengyu Fandae25302014-10-16 11:40:11 -060084 , m_ioService(face.getIoService())
hilata198cadb2014-02-15 23:46:19 -060085{
86}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070087
88Nfdc::~Nfdc()
hilata198cadb2014-02-15 23:46:19 -060089{
90}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070091
hilata198cadb2014-02-15 23:46:19 -060092bool
hilata54e4eaf2014-04-10 23:38:33 -050093Nfdc::dispatch(const std::string& command)
hilata198cadb2014-02-15 23:46:19 -060094{
Obaiddca50792014-04-24 18:38:40 -050095 if (command == "add-nexthop") {
96 if (m_nOptions != 2)
hilata54e4eaf2014-04-10 23:38:33 -050097 return false;
Obaiddca50792014-04-24 18:38:40 -050098 fibAddNextHop();
hilata198cadb2014-02-15 23:46:19 -060099 }
100 else if (command == "remove-nexthop") {
hilata54e4eaf2014-04-10 23:38:33 -0500101 if (m_nOptions != 2)
hilata198cadb2014-02-15 23:46:19 -0600102 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500103 fibRemoveNextHop();
hilata198cadb2014-02-15 23:46:19 -0600104 }
Obaiddca50792014-04-24 18:38:40 -0500105 else if (command == "register") {
106 if (m_nOptions != 2)
107 return false;
108 ribRegisterPrefix();
109 }
110 else if (command == "unregister") {
111 if (m_nOptions != 2)
112 return false;
113 ribUnregisterPrefix();
114 }
hilata198cadb2014-02-15 23:46:19 -0600115 else if (command == "create") {
hilata54e4eaf2014-04-10 23:38:33 -0500116 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600117 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500118 faceCreate();
hilata198cadb2014-02-15 23:46:19 -0600119 }
120 else if (command == "destroy") {
hilata54e4eaf2014-04-10 23:38:33 -0500121 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600122 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500123 faceDestroy();
hilata198cadb2014-02-15 23:46:19 -0600124 }
hilata141eaae2014-03-13 19:54:47 -0500125 else if (command == "set-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500126 if (m_nOptions != 2)
hilata141eaae2014-03-13 19:54:47 -0500127 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500128 strategyChoiceSet();
hilata141eaae2014-03-13 19:54:47 -0500129 }
130 else if (command == "unset-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500131 if (m_nOptions != 1)
hilata141eaae2014-03-13 19:54:47 -0500132 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500133 strategyChoiceUnset();
hilata141eaae2014-03-13 19:54:47 -0500134 }
hilata198cadb2014-02-15 23:46:19 -0600135 else
136 usage(m_programName);
137
138 return true;
139}
hilata198cadb2014-02-15 23:46:19 -0600140
hilata198cadb2014-02-15 23:46:19 -0600141namespace {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700142
143inline bool
hilata198cadb2014-02-15 23:46:19 -0600144isValidUri(const std::string& input)
145{
146 // an extended regex to support the validation of uri structure
147 // boost::regex e("^[a-z0-9]+-?+[a-z0-9]+\\:\\/\\/.*");
148 boost::regex e("^[a-z0-9]+\\:.*");
149 return boost::regex_match(input, e);
150}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700151
hilata198cadb2014-02-15 23:46:19 -0600152} // anonymous namespace
153
154void
Obaiddca50792014-04-24 18:38:40 -0500155Nfdc::fibAddNextHop()
hilata198cadb2014-02-15 23:46:19 -0600156{
Obaiddca50792014-04-24 18:38:40 -0500157 m_name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700158 ControlParameters parameters;
159 parameters
Obaiddca50792014-04-24 18:38:40 -0500160 .setName(m_name)
161 .setCost(m_cost);
hilata54e4eaf2014-04-10 23:38:33 -0500162
Obaiddca50792014-04-24 18:38:40 -0500163 if (!isValidUri(m_commandLineArguments[1])) {
164 try { //So the uri is not valid, may be a faceId is provided.
165 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
166 }
167 catch (const std::exception& e) {
168 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
169 return;
170 }
171 parameters.setFaceId(m_faceId);
172 fibAddNextHop(parameters);
hilata54e4eaf2014-04-10 23:38:33 -0500173 }
Obaiddca50792014-04-24 18:38:40 -0500174 else {
Chengyu Fandae25302014-10-16 11:40:11 -0600175 ndn::util::FaceUri faceUri;
176 faceUri.parse(m_commandLineArguments[1]);
hilata54e4eaf2014-04-10 23:38:33 -0500177
Chengyu Fandae25302014-10-16 11:40:11 -0600178 faceUri.canonize(bind(&Nfdc::startFibAddNextHop, this, _1),
179 bind(&Nfdc::onCanonizeFailure, this, _1),
180 m_ioService, ndn::time::seconds(4));
Obaiddca50792014-04-24 18:38:40 -0500181 }
182}
183
184void
Chengyu Fandae25302014-10-16 11:40:11 -0600185Nfdc::startFibAddNextHop(const ndn::util::FaceUri& canonicalUri)
186{
187 ControlParameters parameters;
188 parameters.setUri(canonicalUri.toString());
189
190 m_controller.start<FaceCreateCommand>(parameters,
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200191 [this](const ControlParameters& result) {
192 fibAddNextHop(result);
193 },
Chengyu Fandae25302014-10-16 11:40:11 -0600194 bind(&Nfdc::onError, this, _1, _2,
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200195 "Face creation failed"));
Chengyu Fandae25302014-10-16 11:40:11 -0600196}
197
198void
Obaiddca50792014-04-24 18:38:40 -0500199Nfdc::fibAddNextHop(const ControlParameters& faceCreateResult)
200{
201 ControlParameters ribParameters;
202 ribParameters
203 .setName(m_name)
204 .setCost(m_cost)
205 .setFaceId(faceCreateResult.getFaceId());
206
207 m_controller.start<FibAddNextHopCommand>(ribParameters,
208 bind(&Nfdc::onSuccess, this, _1,
209 "Nexthop insertion succeeded"),
210 bind(&Nfdc::onError, this, _1, _2,
211 "Nexthop insertion failed"));
hilata54e4eaf2014-04-10 23:38:33 -0500212}
213
214void
215Nfdc::fibRemoveNextHop()
216{
Obaiddca50792014-04-24 18:38:40 -0500217 m_name = m_commandLineArguments[0];
218 try {
219 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
220 }
221 catch (const std::exception& e) {
222 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
223 return;
224 }
hilata54e4eaf2014-04-10 23:38:33 -0500225
226 ControlParameters parameters;
227 parameters
Obaiddca50792014-04-24 18:38:40 -0500228 .setName(m_name)
229 .setFaceId(m_faceId);
hilata54e4eaf2014-04-10 23:38:33 -0500230
Obaiddca50792014-04-24 18:38:40 -0500231 m_controller.start<FibRemoveNextHopCommand>(parameters,
232 bind(&Nfdc::onSuccess, this, _1,
233 "Nexthop removal succeeded"),
234 bind(&Nfdc::onError, this, _1, _2,
235 "Nexthop removal failed"));
236}
237
238void
239Nfdc::ribRegisterPrefix()
240{
241 m_name = m_commandLineArguments[0];
242 ControlParameters parameters;
243 parameters
244 .setName(m_name)
245 .setCost(m_cost)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500246 .setFlags(m_flags)
Alexander Afanasyevf67cf082014-07-18 16:47:29 -0700247 .setOrigin(m_origin);
248
249 if (m_expires != DEFAULT_EXPIRATION_PERIOD)
250 parameters.setExpirationPeriod(m_expires);
Obaiddca50792014-04-24 18:38:40 -0500251
252 if (!isValidUri(m_commandLineArguments[1])) {
253 try { //So the uri is not valid, may be a faceId is provided.
254 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
255 }
256 catch (const std::exception& e) {
257 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
258 return;
259 }
260 parameters.setFaceId(m_faceId);
261 ribRegisterPrefix(parameters);
262 }
263 else {
Chengyu Fandae25302014-10-16 11:40:11 -0600264 ndn::util::FaceUri faceUri;
265 faceUri.parse(m_commandLineArguments[1]);
Obaiddca50792014-04-24 18:38:40 -0500266
Chengyu Fandae25302014-10-16 11:40:11 -0600267 faceUri.canonize(bind(&Nfdc::startRibRegisterPrefix, this, _1),
268 bind(&Nfdc::onCanonizeFailure, this, _1),
269 m_ioService, ndn::time::seconds(4));
Obaiddca50792014-04-24 18:38:40 -0500270 }
271}
272
273void
Chengyu Fandae25302014-10-16 11:40:11 -0600274Nfdc::startRibRegisterPrefix(const ndn::util::FaceUri& canonicalUri)
275{
276 ControlParameters parameters;
277 parameters.setUri(canonicalUri.toString());
278
279 m_controller.start<FaceCreateCommand>(parameters,
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200280 [this](const ControlParameters& result) {
281 ribRegisterPrefix(result);
282 },
Chengyu Fandae25302014-10-16 11:40:11 -0600283 bind(&Nfdc::onError, this, _1, _2,
284 "Face creation failed"));
285}
286
287void
Obaiddca50792014-04-24 18:38:40 -0500288Nfdc::ribRegisterPrefix(const ControlParameters& faceCreateResult)
289{
290 ControlParameters ribParameters;
291 ribParameters
292 .setName(m_name)
293 .setCost(m_cost)
294 .setFlags(m_flags)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500295 .setOrigin(m_origin)
Obaiddca50792014-04-24 18:38:40 -0500296 .setFaceId(faceCreateResult.getFaceId());
297
Alexander Afanasyevf67cf082014-07-18 16:47:29 -0700298 if (m_expires != DEFAULT_EXPIRATION_PERIOD)
299 ribParameters.setExpirationPeriod(m_expires);
300
Obaiddca50792014-04-24 18:38:40 -0500301 m_controller.start<RibRegisterCommand>(ribParameters,
302 bind(&Nfdc::onSuccess, this, _1,
303 "Successful in name registration"),
304 bind(&Nfdc::onError, this, _1, _2,
305 "Failed in name registration"));
306}
307
308void
309Nfdc::ribUnregisterPrefix()
310{
311 m_name = m_commandLineArguments[0];
312 try {
313 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
314 }
315 catch (const std::exception& e) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500316 std::cerr << "No valid faceId is provided" << std::endl;
Obaiddca50792014-04-24 18:38:40 -0500317 return;
318 }
319
320 ControlParameters parameters;
321 parameters
322 .setName(m_name)
Syed Obaidf93f9d92014-06-22 13:50:48 -0500323 .setFaceId(m_faceId)
324 .setOrigin(m_origin);
Obaiddca50792014-04-24 18:38:40 -0500325
326 m_controller.start<RibUnregisterCommand>(parameters,
327 bind(&Nfdc::onSuccess, this, _1,
328 "Successful in unregistering name"),
329 bind(&Nfdc::onError, this, _1, _2,
330 "Failed in unregistering name"));
hilata54e4eaf2014-04-10 23:38:33 -0500331}
332
333void
Chengyu Fandae25302014-10-16 11:40:11 -0600334Nfdc::onCanonizeFailure(const std::string& reason)
335{
336 std::cerr << reason << std::endl;
337}
338
339void
hilata54e4eaf2014-04-10 23:38:33 -0500340Nfdc::faceCreate()
341{
342 if (!isValidUri(m_commandLineArguments[0]))
343 throw Error("invalid uri format");
344
Chengyu Fandae25302014-10-16 11:40:11 -0600345 ndn::util::FaceUri faceUri;
346 faceUri.parse(m_commandLineArguments[0]);
347
348 faceUri.canonize(bind(&Nfdc::startFaceCreate, this, _1),
349 bind(&Nfdc::onCanonizeFailure, this, _1),
350 m_ioService, ndn::time::seconds(4));
351}
352
353void
354Nfdc::startFaceCreate(const ndn::util::FaceUri& canonicalUri)
355{
hilata54e4eaf2014-04-10 23:38:33 -0500356 ControlParameters parameters;
Chengyu Fandae25302014-10-16 11:40:11 -0600357 parameters.setUri(canonicalUri.toString());
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700358
Obaiddca50792014-04-24 18:38:40 -0500359 m_controller.start<FaceCreateCommand>(parameters,
360 bind(&Nfdc::onSuccess, this, _1,
361 "Face creation succeeded"),
362 bind(&Nfdc::onError, this, _1, _2,
363 "Face creation failed"));
hilata198cadb2014-02-15 23:46:19 -0600364}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700365
hilata198cadb2014-02-15 23:46:19 -0600366void
hilata54e4eaf2014-04-10 23:38:33 -0500367Nfdc::faceDestroy()
hilata198cadb2014-02-15 23:46:19 -0600368{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700369 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500370 if (!isValidUri(m_commandLineArguments[0])) {
371 try { //So the uri is not valid, may be a faceId is provided.
372 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[0]);
373 }
374 catch (const std::exception& e) {
375 std::cerr << "No valid faceUri or faceId is provided" << std::endl;
376 return;
377 }
378 parameters.setFaceId(m_faceId);
379 faceDestroy(parameters);
380 }
381 else{
Chengyu Fandae25302014-10-16 11:40:11 -0600382 ndn::util::FaceUri faceUri;
383 faceUri.parse(m_commandLineArguments[0]);
384
385 faceUri.canonize(bind(&Nfdc::startFaceDestroy, this, _1),
386 bind(&Nfdc::onCanonizeFailure, this, _1),
387 m_ioService, ndn::time::seconds(4));
Obaiddca50792014-04-24 18:38:40 -0500388 }
389}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700390
Obaiddca50792014-04-24 18:38:40 -0500391void
Chengyu Fandae25302014-10-16 11:40:11 -0600392Nfdc::startFaceDestroy(const ndn::util::FaceUri& canonicalUri)
393{
394 ControlParameters parameters;
395 parameters.setUri(canonicalUri.toString());
396
397 m_controller.start<FaceCreateCommand>(parameters,
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200398 [this](const ControlParameters& result) {
399 faceDestroy(result);
400 },
Chengyu Fandae25302014-10-16 11:40:11 -0600401 bind(&Nfdc::onError, this, _1, _2,
402 "Face destroy failed"));
403}
404
405void
Obaiddca50792014-04-24 18:38:40 -0500406Nfdc::faceDestroy(const ControlParameters& faceCreateResult)
407{
408 ControlParameters faceParameters;
409 faceParameters.setFaceId(faceCreateResult.getFaceId());
410
411 m_controller.start<FaceDestroyCommand>(faceParameters,
412 bind(&Nfdc::onSuccess, this, _1,
413 "Face destroy succeeded"),
414 bind(&Nfdc::onError, this, _1, _2,
415 "Face destroy failed"));
hilata198cadb2014-02-15 23:46:19 -0600416}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700417
hilata141eaae2014-03-13 19:54:47 -0500418void
hilata54e4eaf2014-04-10 23:38:33 -0500419Nfdc::strategyChoiceSet()
hilata141eaae2014-03-13 19:54:47 -0500420{
hilata54e4eaf2014-04-10 23:38:33 -0500421 const std::string& name = m_commandLineArguments[0];
422 const std::string& strategy = m_commandLineArguments[1];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700423
424 ControlParameters parameters;
425 parameters
426 .setName(name)
427 .setStrategy(strategy);
428
Obaiddca50792014-04-24 18:38:40 -0500429 m_controller.start<StrategyChoiceSetCommand>(parameters,
430 bind(&Nfdc::onSuccess, this, _1,
431 "Successfully set strategy choice"),
432 bind(&Nfdc::onError, this, _1, _2,
433 "Failed to set strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500434}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700435
hilata141eaae2014-03-13 19:54:47 -0500436void
hilata54e4eaf2014-04-10 23:38:33 -0500437Nfdc::strategyChoiceUnset()
hilata141eaae2014-03-13 19:54:47 -0500438{
hilata54e4eaf2014-04-10 23:38:33 -0500439 const std::string& name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700440
441 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500442 parameters.setName(name);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700443
Obaiddca50792014-04-24 18:38:40 -0500444 m_controller.start<StrategyChoiceUnsetCommand>(parameters,
445 bind(&Nfdc::onSuccess, this, _1,
446 "Successfully unset strategy choice"),
447 bind(&Nfdc::onError, this, _1, _2,
448 "Failed to unset strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500449}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700450
hilata198cadb2014-02-15 23:46:19 -0600451void
Obaiddca50792014-04-24 18:38:40 -0500452Nfdc::onSuccess(const ControlParameters& commandSuccessResult, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600453{
Obaiddca50792014-04-24 18:38:40 -0500454 std::cout << message << ": " << commandSuccessResult << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600455}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700456
hilata198cadb2014-02-15 23:46:19 -0600457void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700458Nfdc::onError(uint32_t code, const std::string& error, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600459{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700460 std::ostringstream os;
461 os << message << ": " << error << " (code: " << code << ")";
462 throw Error(os.str());
hilata141eaae2014-03-13 19:54:47 -0500463}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700464
Obaiddca50792014-04-24 18:38:40 -0500465
466
hilata141eaae2014-03-13 19:54:47 -0500467} // namespace nfdc
hilata198cadb2014-02-15 23:46:19 -0600468
469int
470main(int argc, char** argv)
471{
472 ndn::Face face;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700473 nfdc::Nfdc p(face);
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800474
hilata198cadb2014-02-15 23:46:19 -0600475 p.m_programName = argv[0];
hilata54e4eaf2014-04-10 23:38:33 -0500476
Obaiddca50792014-04-24 18:38:40 -0500477 if (argc < 2) {
478 usage(p.m_programName);
479 return 0;
480 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700481
Obaiddca50792014-04-24 18:38:40 -0500482 if (!strcmp(argv[1], "-h")) {
483 usage(p.m_programName);
484 return 0;
485 }
486
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700487 if (!strcmp(argv[1], "-V")) {
488 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
489 return 0;
490 }
491
Junxiao Shi22295032014-04-29 22:57:40 -0700492 ::optind = 2; //start reading options from 2nd argument i.e. Command
Obaiddca50792014-04-24 18:38:40 -0500493 int opt;
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500494 while ((opt = ::getopt(argc, argv, "ICc:e:o:")) != -1) {
Obaiddca50792014-04-24 18:38:40 -0500495 switch (opt) {
496 case 'I':
497 p.m_flags = p.m_flags & ~(nfdc::ROUTE_FLAG_CHILD_INHERIT);
498 break;
499
500 case 'C':
501 p.m_flags = p.m_flags | nfdc::ROUTE_FLAG_CAPTURE;
502 break;
503
504 case 'c':
505 try {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500506 p.m_cost = boost::lexical_cast<uint64_t>(::optarg);
Obaiddca50792014-04-24 18:38:40 -0500507 }
Junxiao Shi22295032014-04-29 22:57:40 -0700508 catch (boost::bad_lexical_cast&) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500509 std::cerr << "Error: cost must be in unsigned integer format" << std::endl;
510 return 1;
511 }
512 break;
513
514 case 'e':
515 uint64_t expires;
516 try {
517 expires = boost::lexical_cast<uint64_t>(::optarg);
518 }
519 catch (boost::bad_lexical_cast&) {
520 std::cerr << "Error: expiration time must be in unsigned integer format" << std::endl;
521 return 1;
522 }
523 p.m_expires = ndn::time::milliseconds(expires);
524 break;
525
526 case 'o':
527 try {
528 p.m_origin = boost::lexical_cast<uint64_t>(::optarg);
529 }
530 catch (boost::bad_lexical_cast&) {
531 std::cerr << "Error: origin must be in unsigned integer format" << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600532 return 1;
Obaiddca50792014-04-24 18:38:40 -0500533 }
534 break;
Junxiao Shi22295032014-04-29 22:57:40 -0700535
Obaiddca50792014-04-24 18:38:40 -0500536 default:
537 usage(p.m_programName);
538 return 1;
hilata198cadb2014-02-15 23:46:19 -0600539 }
540 }
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800541
Junxiao Shi22295032014-04-29 22:57:40 -0700542 if (argc == ::optind) {
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800543 usage(p.m_programName);
544 return 1;
545 }
546
hilata198cadb2014-02-15 23:46:19 -0600547 try {
Junxiao Shi22295032014-04-29 22:57:40 -0700548 p.m_commandLineArguments = argv + ::optind;
549 p.m_nOptions = argc - ::optind;
Obaiddca50792014-04-24 18:38:40 -0500550
551 //argv[1] points to the command, so pass it to the dispatch
552 bool isOk = p.dispatch(argv[1]);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700553 if (!isOk) {
hilata198cadb2014-02-15 23:46:19 -0600554 usage(p.m_programName);
555 return 1;
556 }
hilata198cadb2014-02-15 23:46:19 -0600557 face.processEvents();
558 }
559 catch (const std::exception& e) {
560 std::cerr << "ERROR: " << e.what() << std::endl;
561 return 2;
562 }
563 return 0;
564}