blob: bfae68483d6843e4e7d24ec14956fdcf5efaccbf [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
Davide Pesaventoab1e8f22014-10-21 22:45:33 +020073using ndn::bind;
74using ndn::_1;
75using ndn::_2;
76
Syed Obaid818e8a62014-07-02 18:24:11 -050077const ndn::time::milliseconds Nfdc::DEFAULT_EXPIRATION_PERIOD = ndn::time::milliseconds::max();
Syed Obaid4ae0ce32014-06-17 13:59:20 -050078const uint64_t Nfdc::DEFAULT_COST = 0;
79
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070080Nfdc::Nfdc(ndn::Face& face)
Obaiddca50792014-04-24 18:38:40 -050081 : m_flags(ROUTE_FLAG_CHILD_INHERIT)
Syed Obaid4ae0ce32014-06-17 13:59:20 -050082 , m_cost(DEFAULT_COST)
83 , m_origin(ROUTE_ORIGIN_STATIC)
84 , m_expires(DEFAULT_EXPIRATION_PERIOD)
Junxiao Shi8e273ca2014-11-12 00:42:29 -070085 , m_controller(face, m_keyChain)
Chengyu Fandae25302014-10-16 11:40:11 -060086 , m_ioService(face.getIoService())
hilata198cadb2014-02-15 23:46:19 -060087{
88}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070089
90Nfdc::~Nfdc()
hilata198cadb2014-02-15 23:46:19 -060091{
92}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070093
hilata198cadb2014-02-15 23:46:19 -060094bool
hilata54e4eaf2014-04-10 23:38:33 -050095Nfdc::dispatch(const std::string& command)
hilata198cadb2014-02-15 23:46:19 -060096{
Obaiddca50792014-04-24 18:38:40 -050097 if (command == "add-nexthop") {
98 if (m_nOptions != 2)
hilata54e4eaf2014-04-10 23:38:33 -050099 return false;
Obaiddca50792014-04-24 18:38:40 -0500100 fibAddNextHop();
hilata198cadb2014-02-15 23:46:19 -0600101 }
102 else if (command == "remove-nexthop") {
hilata54e4eaf2014-04-10 23:38:33 -0500103 if (m_nOptions != 2)
hilata198cadb2014-02-15 23:46:19 -0600104 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500105 fibRemoveNextHop();
hilata198cadb2014-02-15 23:46:19 -0600106 }
Obaiddca50792014-04-24 18:38:40 -0500107 else if (command == "register") {
108 if (m_nOptions != 2)
109 return false;
110 ribRegisterPrefix();
111 }
112 else if (command == "unregister") {
113 if (m_nOptions != 2)
114 return false;
115 ribUnregisterPrefix();
116 }
hilata198cadb2014-02-15 23:46:19 -0600117 else if (command == "create") {
hilata54e4eaf2014-04-10 23:38:33 -0500118 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600119 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500120 faceCreate();
hilata198cadb2014-02-15 23:46:19 -0600121 }
122 else if (command == "destroy") {
hilata54e4eaf2014-04-10 23:38:33 -0500123 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600124 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500125 faceDestroy();
hilata198cadb2014-02-15 23:46:19 -0600126 }
hilata141eaae2014-03-13 19:54:47 -0500127 else if (command == "set-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500128 if (m_nOptions != 2)
hilata141eaae2014-03-13 19:54:47 -0500129 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500130 strategyChoiceSet();
hilata141eaae2014-03-13 19:54:47 -0500131 }
132 else if (command == "unset-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500133 if (m_nOptions != 1)
hilata141eaae2014-03-13 19:54:47 -0500134 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500135 strategyChoiceUnset();
hilata141eaae2014-03-13 19:54:47 -0500136 }
hilata198cadb2014-02-15 23:46:19 -0600137 else
138 usage(m_programName);
139
140 return true;
141}
hilata198cadb2014-02-15 23:46:19 -0600142
hilata198cadb2014-02-15 23:46:19 -0600143namespace {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700144
145inline bool
hilata198cadb2014-02-15 23:46:19 -0600146isValidUri(const std::string& input)
147{
148 // an extended regex to support the validation of uri structure
149 // boost::regex e("^[a-z0-9]+-?+[a-z0-9]+\\:\\/\\/.*");
150 boost::regex e("^[a-z0-9]+\\:.*");
151 return boost::regex_match(input, e);
152}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700153
hilata198cadb2014-02-15 23:46:19 -0600154} // anonymous namespace
155
156void
Obaiddca50792014-04-24 18:38:40 -0500157Nfdc::fibAddNextHop()
hilata198cadb2014-02-15 23:46:19 -0600158{
Obaiddca50792014-04-24 18:38:40 -0500159 m_name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700160 ControlParameters parameters;
161 parameters
Obaiddca50792014-04-24 18:38:40 -0500162 .setName(m_name)
163 .setCost(m_cost);
hilata54e4eaf2014-04-10 23:38:33 -0500164
Obaiddca50792014-04-24 18:38:40 -0500165 if (!isValidUri(m_commandLineArguments[1])) {
166 try { //So the uri is not valid, may be a faceId is provided.
167 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
168 }
169 catch (const std::exception& e) {
170 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
171 return;
172 }
173 parameters.setFaceId(m_faceId);
174 fibAddNextHop(parameters);
hilata54e4eaf2014-04-10 23:38:33 -0500175 }
Obaiddca50792014-04-24 18:38:40 -0500176 else {
Chengyu Fandae25302014-10-16 11:40:11 -0600177 ndn::util::FaceUri faceUri;
178 faceUri.parse(m_commandLineArguments[1]);
hilata54e4eaf2014-04-10 23:38:33 -0500179
Chengyu Fandae25302014-10-16 11:40:11 -0600180 faceUri.canonize(bind(&Nfdc::startFibAddNextHop, this, _1),
181 bind(&Nfdc::onCanonizeFailure, this, _1),
182 m_ioService, ndn::time::seconds(4));
Obaiddca50792014-04-24 18:38:40 -0500183 }
184}
185
186void
Chengyu Fandae25302014-10-16 11:40:11 -0600187Nfdc::startFibAddNextHop(const ndn::util::FaceUri& canonicalUri)
188{
189 ControlParameters parameters;
190 parameters.setUri(canonicalUri.toString());
191
192 m_controller.start<FaceCreateCommand>(parameters,
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200193 [this](const ControlParameters& result) {
194 fibAddNextHop(result);
195 },
Chengyu Fandae25302014-10-16 11:40:11 -0600196 bind(&Nfdc::onError, this, _1, _2,
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200197 "Face creation failed"));
Chengyu Fandae25302014-10-16 11:40:11 -0600198}
199
200void
Obaiddca50792014-04-24 18:38:40 -0500201Nfdc::fibAddNextHop(const ControlParameters& faceCreateResult)
202{
203 ControlParameters ribParameters;
204 ribParameters
205 .setName(m_name)
206 .setCost(m_cost)
207 .setFaceId(faceCreateResult.getFaceId());
208
209 m_controller.start<FibAddNextHopCommand>(ribParameters,
210 bind(&Nfdc::onSuccess, this, _1,
211 "Nexthop insertion succeeded"),
212 bind(&Nfdc::onError, this, _1, _2,
213 "Nexthop insertion failed"));
hilata54e4eaf2014-04-10 23:38:33 -0500214}
215
216void
217Nfdc::fibRemoveNextHop()
218{
Obaiddca50792014-04-24 18:38:40 -0500219 m_name = m_commandLineArguments[0];
220 try {
221 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
222 }
223 catch (const std::exception& e) {
224 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
225 return;
226 }
hilata54e4eaf2014-04-10 23:38:33 -0500227
228 ControlParameters parameters;
229 parameters
Obaiddca50792014-04-24 18:38:40 -0500230 .setName(m_name)
231 .setFaceId(m_faceId);
hilata54e4eaf2014-04-10 23:38:33 -0500232
Obaiddca50792014-04-24 18:38:40 -0500233 m_controller.start<FibRemoveNextHopCommand>(parameters,
234 bind(&Nfdc::onSuccess, this, _1,
235 "Nexthop removal succeeded"),
236 bind(&Nfdc::onError, this, _1, _2,
237 "Nexthop removal failed"));
238}
239
240void
241Nfdc::ribRegisterPrefix()
242{
243 m_name = m_commandLineArguments[0];
244 ControlParameters parameters;
245 parameters
246 .setName(m_name)
247 .setCost(m_cost)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500248 .setFlags(m_flags)
Alexander Afanasyevf67cf082014-07-18 16:47:29 -0700249 .setOrigin(m_origin);
250
251 if (m_expires != DEFAULT_EXPIRATION_PERIOD)
252 parameters.setExpirationPeriod(m_expires);
Obaiddca50792014-04-24 18:38:40 -0500253
254 if (!isValidUri(m_commandLineArguments[1])) {
255 try { //So the uri is not valid, may be a faceId is provided.
256 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
257 }
258 catch (const std::exception& e) {
259 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
260 return;
261 }
262 parameters.setFaceId(m_faceId);
263 ribRegisterPrefix(parameters);
264 }
265 else {
Chengyu Fandae25302014-10-16 11:40:11 -0600266 ndn::util::FaceUri faceUri;
267 faceUri.parse(m_commandLineArguments[1]);
Obaiddca50792014-04-24 18:38:40 -0500268
Chengyu Fandae25302014-10-16 11:40:11 -0600269 faceUri.canonize(bind(&Nfdc::startRibRegisterPrefix, this, _1),
270 bind(&Nfdc::onCanonizeFailure, this, _1),
271 m_ioService, ndn::time::seconds(4));
Obaiddca50792014-04-24 18:38:40 -0500272 }
273}
274
275void
Chengyu Fandae25302014-10-16 11:40:11 -0600276Nfdc::startRibRegisterPrefix(const ndn::util::FaceUri& canonicalUri)
277{
278 ControlParameters parameters;
279 parameters.setUri(canonicalUri.toString());
280
281 m_controller.start<FaceCreateCommand>(parameters,
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200282 [this](const ControlParameters& result) {
283 ribRegisterPrefix(result);
284 },
Chengyu Fandae25302014-10-16 11:40:11 -0600285 bind(&Nfdc::onError, this, _1, _2,
286 "Face creation failed"));
287}
288
289void
Obaiddca50792014-04-24 18:38:40 -0500290Nfdc::ribRegisterPrefix(const ControlParameters& faceCreateResult)
291{
292 ControlParameters ribParameters;
293 ribParameters
294 .setName(m_name)
295 .setCost(m_cost)
296 .setFlags(m_flags)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500297 .setOrigin(m_origin)
Obaiddca50792014-04-24 18:38:40 -0500298 .setFaceId(faceCreateResult.getFaceId());
299
Alexander Afanasyevf67cf082014-07-18 16:47:29 -0700300 if (m_expires != DEFAULT_EXPIRATION_PERIOD)
301 ribParameters.setExpirationPeriod(m_expires);
302
Obaiddca50792014-04-24 18:38:40 -0500303 m_controller.start<RibRegisterCommand>(ribParameters,
304 bind(&Nfdc::onSuccess, this, _1,
305 "Successful in name registration"),
306 bind(&Nfdc::onError, this, _1, _2,
307 "Failed in name registration"));
308}
309
310void
311Nfdc::ribUnregisterPrefix()
312{
313 m_name = m_commandLineArguments[0];
314 try {
315 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
316 }
317 catch (const std::exception& e) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500318 std::cerr << "No valid faceId is provided" << std::endl;
Obaiddca50792014-04-24 18:38:40 -0500319 return;
320 }
321
322 ControlParameters parameters;
323 parameters
324 .setName(m_name)
Syed Obaidf93f9d92014-06-22 13:50:48 -0500325 .setFaceId(m_faceId)
326 .setOrigin(m_origin);
Obaiddca50792014-04-24 18:38:40 -0500327
328 m_controller.start<RibUnregisterCommand>(parameters,
329 bind(&Nfdc::onSuccess, this, _1,
330 "Successful in unregistering name"),
331 bind(&Nfdc::onError, this, _1, _2,
332 "Failed in unregistering name"));
hilata54e4eaf2014-04-10 23:38:33 -0500333}
334
335void
Chengyu Fandae25302014-10-16 11:40:11 -0600336Nfdc::onCanonizeFailure(const std::string& reason)
337{
338 std::cerr << reason << std::endl;
339}
340
341void
hilata54e4eaf2014-04-10 23:38:33 -0500342Nfdc::faceCreate()
343{
344 if (!isValidUri(m_commandLineArguments[0]))
345 throw Error("invalid uri format");
346
Chengyu Fandae25302014-10-16 11:40:11 -0600347 ndn::util::FaceUri faceUri;
348 faceUri.parse(m_commandLineArguments[0]);
349
350 faceUri.canonize(bind(&Nfdc::startFaceCreate, this, _1),
351 bind(&Nfdc::onCanonizeFailure, this, _1),
352 m_ioService, ndn::time::seconds(4));
353}
354
355void
356Nfdc::startFaceCreate(const ndn::util::FaceUri& canonicalUri)
357{
hilata54e4eaf2014-04-10 23:38:33 -0500358 ControlParameters parameters;
Chengyu Fandae25302014-10-16 11:40:11 -0600359 parameters.setUri(canonicalUri.toString());
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700360
Obaiddca50792014-04-24 18:38:40 -0500361 m_controller.start<FaceCreateCommand>(parameters,
362 bind(&Nfdc::onSuccess, this, _1,
363 "Face creation succeeded"),
364 bind(&Nfdc::onError, this, _1, _2,
365 "Face creation failed"));
hilata198cadb2014-02-15 23:46:19 -0600366}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700367
hilata198cadb2014-02-15 23:46:19 -0600368void
hilata54e4eaf2014-04-10 23:38:33 -0500369Nfdc::faceDestroy()
hilata198cadb2014-02-15 23:46:19 -0600370{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700371 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500372 if (!isValidUri(m_commandLineArguments[0])) {
373 try { //So the uri is not valid, may be a faceId is provided.
374 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[0]);
375 }
376 catch (const std::exception& e) {
377 std::cerr << "No valid faceUri or faceId is provided" << std::endl;
378 return;
379 }
380 parameters.setFaceId(m_faceId);
381 faceDestroy(parameters);
382 }
383 else{
Chengyu Fandae25302014-10-16 11:40:11 -0600384 ndn::util::FaceUri faceUri;
385 faceUri.parse(m_commandLineArguments[0]);
386
387 faceUri.canonize(bind(&Nfdc::startFaceDestroy, this, _1),
388 bind(&Nfdc::onCanonizeFailure, this, _1),
389 m_ioService, ndn::time::seconds(4));
Obaiddca50792014-04-24 18:38:40 -0500390 }
391}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700392
Obaiddca50792014-04-24 18:38:40 -0500393void
Chengyu Fandae25302014-10-16 11:40:11 -0600394Nfdc::startFaceDestroy(const ndn::util::FaceUri& canonicalUri)
395{
396 ControlParameters parameters;
397 parameters.setUri(canonicalUri.toString());
398
399 m_controller.start<FaceCreateCommand>(parameters,
Davide Pesaventoab1e8f22014-10-21 22:45:33 +0200400 [this](const ControlParameters& result) {
401 faceDestroy(result);
402 },
Chengyu Fandae25302014-10-16 11:40:11 -0600403 bind(&Nfdc::onError, this, _1, _2,
404 "Face destroy failed"));
405}
406
407void
Obaiddca50792014-04-24 18:38:40 -0500408Nfdc::faceDestroy(const ControlParameters& faceCreateResult)
409{
410 ControlParameters faceParameters;
411 faceParameters.setFaceId(faceCreateResult.getFaceId());
412
413 m_controller.start<FaceDestroyCommand>(faceParameters,
414 bind(&Nfdc::onSuccess, this, _1,
415 "Face destroy succeeded"),
416 bind(&Nfdc::onError, this, _1, _2,
417 "Face destroy failed"));
hilata198cadb2014-02-15 23:46:19 -0600418}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700419
hilata141eaae2014-03-13 19:54:47 -0500420void
hilata54e4eaf2014-04-10 23:38:33 -0500421Nfdc::strategyChoiceSet()
hilata141eaae2014-03-13 19:54:47 -0500422{
hilata54e4eaf2014-04-10 23:38:33 -0500423 const std::string& name = m_commandLineArguments[0];
424 const std::string& strategy = m_commandLineArguments[1];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700425
426 ControlParameters parameters;
427 parameters
428 .setName(name)
429 .setStrategy(strategy);
430
Obaiddca50792014-04-24 18:38:40 -0500431 m_controller.start<StrategyChoiceSetCommand>(parameters,
432 bind(&Nfdc::onSuccess, this, _1,
433 "Successfully set strategy choice"),
434 bind(&Nfdc::onError, this, _1, _2,
435 "Failed to set strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500436}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700437
hilata141eaae2014-03-13 19:54:47 -0500438void
hilata54e4eaf2014-04-10 23:38:33 -0500439Nfdc::strategyChoiceUnset()
hilata141eaae2014-03-13 19:54:47 -0500440{
hilata54e4eaf2014-04-10 23:38:33 -0500441 const std::string& name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700442
443 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500444 parameters.setName(name);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700445
Obaiddca50792014-04-24 18:38:40 -0500446 m_controller.start<StrategyChoiceUnsetCommand>(parameters,
447 bind(&Nfdc::onSuccess, this, _1,
448 "Successfully unset strategy choice"),
449 bind(&Nfdc::onError, this, _1, _2,
450 "Failed to unset strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500451}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700452
hilata198cadb2014-02-15 23:46:19 -0600453void
Obaiddca50792014-04-24 18:38:40 -0500454Nfdc::onSuccess(const ControlParameters& commandSuccessResult, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600455{
Obaiddca50792014-04-24 18:38:40 -0500456 std::cout << message << ": " << commandSuccessResult << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600457}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700458
hilata198cadb2014-02-15 23:46:19 -0600459void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700460Nfdc::onError(uint32_t code, const std::string& error, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600461{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700462 std::ostringstream os;
463 os << message << ": " << error << " (code: " << code << ")";
464 throw Error(os.str());
hilata141eaae2014-03-13 19:54:47 -0500465}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700466
Obaiddca50792014-04-24 18:38:40 -0500467
468
hilata141eaae2014-03-13 19:54:47 -0500469} // namespace nfdc
hilata198cadb2014-02-15 23:46:19 -0600470
471int
472main(int argc, char** argv)
473{
474 ndn::Face face;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700475 nfdc::Nfdc p(face);
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800476
hilata198cadb2014-02-15 23:46:19 -0600477 p.m_programName = argv[0];
hilata54e4eaf2014-04-10 23:38:33 -0500478
Obaiddca50792014-04-24 18:38:40 -0500479 if (argc < 2) {
480 usage(p.m_programName);
481 return 0;
482 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700483
Obaiddca50792014-04-24 18:38:40 -0500484 if (!strcmp(argv[1], "-h")) {
485 usage(p.m_programName);
486 return 0;
487 }
488
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700489 if (!strcmp(argv[1], "-V")) {
490 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
491 return 0;
492 }
493
Junxiao Shi22295032014-04-29 22:57:40 -0700494 ::optind = 2; //start reading options from 2nd argument i.e. Command
Obaiddca50792014-04-24 18:38:40 -0500495 int opt;
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500496 while ((opt = ::getopt(argc, argv, "ICc:e:o:")) != -1) {
Obaiddca50792014-04-24 18:38:40 -0500497 switch (opt) {
498 case 'I':
499 p.m_flags = p.m_flags & ~(nfdc::ROUTE_FLAG_CHILD_INHERIT);
500 break;
501
502 case 'C':
503 p.m_flags = p.m_flags | nfdc::ROUTE_FLAG_CAPTURE;
504 break;
505
506 case 'c':
507 try {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500508 p.m_cost = boost::lexical_cast<uint64_t>(::optarg);
Obaiddca50792014-04-24 18:38:40 -0500509 }
Junxiao Shi22295032014-04-29 22:57:40 -0700510 catch (boost::bad_lexical_cast&) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500511 std::cerr << "Error: cost must be in unsigned integer format" << std::endl;
512 return 1;
513 }
514 break;
515
516 case 'e':
517 uint64_t expires;
518 try {
519 expires = boost::lexical_cast<uint64_t>(::optarg);
520 }
521 catch (boost::bad_lexical_cast&) {
522 std::cerr << "Error: expiration time must be in unsigned integer format" << std::endl;
523 return 1;
524 }
525 p.m_expires = ndn::time::milliseconds(expires);
526 break;
527
528 case 'o':
529 try {
530 p.m_origin = boost::lexical_cast<uint64_t>(::optarg);
531 }
532 catch (boost::bad_lexical_cast&) {
533 std::cerr << "Error: origin must be in unsigned integer format" << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600534 return 1;
Obaiddca50792014-04-24 18:38:40 -0500535 }
536 break;
Junxiao Shi22295032014-04-29 22:57:40 -0700537
Obaiddca50792014-04-24 18:38:40 -0500538 default:
539 usage(p.m_programName);
540 return 1;
hilata198cadb2014-02-15 23:46:19 -0600541 }
542 }
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800543
Junxiao Shi22295032014-04-29 22:57:40 -0700544 if (argc == ::optind) {
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800545 usage(p.m_programName);
546 return 1;
547 }
548
hilata198cadb2014-02-15 23:46:19 -0600549 try {
Junxiao Shi22295032014-04-29 22:57:40 -0700550 p.m_commandLineArguments = argv + ::optind;
551 p.m_nOptions = argc - ::optind;
Obaiddca50792014-04-24 18:38:40 -0500552
553 //argv[1] points to the command, so pass it to the dispatch
554 bool isOk = p.dispatch(argv[1]);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700555 if (!isOk) {
hilata198cadb2014-02-15 23:46:19 -0600556 usage(p.m_programName);
557 return 1;
558 }
hilata198cadb2014-02-15 23:46:19 -0600559 face.processEvents();
560 }
561 catch (const std::exception& e) {
562 std::cerr << "ERROR: " << e.what() << std::endl;
563 return 2;
564 }
565 return 0;
566}