blob: 123cdb58656480a107292f867d96e7f22b01654a [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
Syed Obaid818e8a62014-07-02 18:24:11 -050073const ndn::time::milliseconds Nfdc::DEFAULT_EXPIRATION_PERIOD = ndn::time::milliseconds::max();
Syed Obaid4ae0ce32014-06-17 13:59:20 -050074const uint64_t Nfdc::DEFAULT_COST = 0;
75
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070076Nfdc::Nfdc(ndn::Face& face)
Obaiddca50792014-04-24 18:38:40 -050077 : m_flags(ROUTE_FLAG_CHILD_INHERIT)
Syed Obaid4ae0ce32014-06-17 13:59:20 -050078 , m_cost(DEFAULT_COST)
79 , m_origin(ROUTE_ORIGIN_STATIC)
80 , m_expires(DEFAULT_EXPIRATION_PERIOD)
Obaiddca50792014-04-24 18:38:40 -050081 , m_controller(face)
Chengyu Fandae25302014-10-16 11:40:11 -060082 , m_ioService(face.getIoService())
hilata198cadb2014-02-15 23:46:19 -060083{
84}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070085
86Nfdc::~Nfdc()
hilata198cadb2014-02-15 23:46:19 -060087{
88}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070089
hilata198cadb2014-02-15 23:46:19 -060090bool
hilata54e4eaf2014-04-10 23:38:33 -050091Nfdc::dispatch(const std::string& command)
hilata198cadb2014-02-15 23:46:19 -060092{
Obaiddca50792014-04-24 18:38:40 -050093 if (command == "add-nexthop") {
94 if (m_nOptions != 2)
hilata54e4eaf2014-04-10 23:38:33 -050095 return false;
Obaiddca50792014-04-24 18:38:40 -050096 fibAddNextHop();
hilata198cadb2014-02-15 23:46:19 -060097 }
98 else if (command == "remove-nexthop") {
hilata54e4eaf2014-04-10 23:38:33 -050099 if (m_nOptions != 2)
hilata198cadb2014-02-15 23:46:19 -0600100 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500101 fibRemoveNextHop();
hilata198cadb2014-02-15 23:46:19 -0600102 }
Obaiddca50792014-04-24 18:38:40 -0500103 else if (command == "register") {
104 if (m_nOptions != 2)
105 return false;
106 ribRegisterPrefix();
107 }
108 else if (command == "unregister") {
109 if (m_nOptions != 2)
110 return false;
111 ribUnregisterPrefix();
112 }
hilata198cadb2014-02-15 23:46:19 -0600113 else if (command == "create") {
hilata54e4eaf2014-04-10 23:38:33 -0500114 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600115 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500116 faceCreate();
hilata198cadb2014-02-15 23:46:19 -0600117 }
118 else if (command == "destroy") {
hilata54e4eaf2014-04-10 23:38:33 -0500119 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600120 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500121 faceDestroy();
hilata198cadb2014-02-15 23:46:19 -0600122 }
hilata141eaae2014-03-13 19:54:47 -0500123 else if (command == "set-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500124 if (m_nOptions != 2)
hilata141eaae2014-03-13 19:54:47 -0500125 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500126 strategyChoiceSet();
hilata141eaae2014-03-13 19:54:47 -0500127 }
128 else if (command == "unset-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500129 if (m_nOptions != 1)
hilata141eaae2014-03-13 19:54:47 -0500130 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500131 strategyChoiceUnset();
hilata141eaae2014-03-13 19:54:47 -0500132 }
hilata198cadb2014-02-15 23:46:19 -0600133 else
134 usage(m_programName);
135
136 return true;
137}
hilata198cadb2014-02-15 23:46:19 -0600138
hilata198cadb2014-02-15 23:46:19 -0600139namespace {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700140
141inline bool
hilata198cadb2014-02-15 23:46:19 -0600142isValidUri(const std::string& input)
143{
144 // an extended regex to support the validation of uri structure
145 // boost::regex e("^[a-z0-9]+-?+[a-z0-9]+\\:\\/\\/.*");
146 boost::regex e("^[a-z0-9]+\\:.*");
147 return boost::regex_match(input, e);
148}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700149
hilata198cadb2014-02-15 23:46:19 -0600150} // anonymous namespace
151
152void
Obaiddca50792014-04-24 18:38:40 -0500153Nfdc::fibAddNextHop()
hilata198cadb2014-02-15 23:46:19 -0600154{
Obaiddca50792014-04-24 18:38:40 -0500155 m_name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700156 ControlParameters parameters;
157 parameters
Obaiddca50792014-04-24 18:38:40 -0500158 .setName(m_name)
159 .setCost(m_cost);
hilata54e4eaf2014-04-10 23:38:33 -0500160
Obaiddca50792014-04-24 18:38:40 -0500161 if (!isValidUri(m_commandLineArguments[1])) {
162 try { //So the uri is not valid, may be a faceId is provided.
163 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
164 }
165 catch (const std::exception& e) {
166 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
167 return;
168 }
169 parameters.setFaceId(m_faceId);
170 fibAddNextHop(parameters);
hilata54e4eaf2014-04-10 23:38:33 -0500171 }
Obaiddca50792014-04-24 18:38:40 -0500172 else {
Chengyu Fandae25302014-10-16 11:40:11 -0600173 ndn::util::FaceUri faceUri;
174 faceUri.parse(m_commandLineArguments[1]);
hilata54e4eaf2014-04-10 23:38:33 -0500175
Chengyu Fandae25302014-10-16 11:40:11 -0600176 faceUri.canonize(bind(&Nfdc::startFibAddNextHop, this, _1),
177 bind(&Nfdc::onCanonizeFailure, this, _1),
178 m_ioService, ndn::time::seconds(4));
Obaiddca50792014-04-24 18:38:40 -0500179 }
180}
181
182void
Chengyu Fandae25302014-10-16 11:40:11 -0600183Nfdc::startFibAddNextHop(const ndn::util::FaceUri& canonicalUri)
184{
185 ControlParameters parameters;
186 parameters.setUri(canonicalUri.toString());
187
188 m_controller.start<FaceCreateCommand>(parameters,
189 bind(&Nfdc::fibAddNextHop, this, _1),
190 bind(&Nfdc::onError, this, _1, _2,
191 "Face creation failed"));
192}
193
194void
Obaiddca50792014-04-24 18:38:40 -0500195Nfdc::fibAddNextHop(const ControlParameters& faceCreateResult)
196{
197 ControlParameters ribParameters;
198 ribParameters
199 .setName(m_name)
200 .setCost(m_cost)
201 .setFaceId(faceCreateResult.getFaceId());
202
203 m_controller.start<FibAddNextHopCommand>(ribParameters,
204 bind(&Nfdc::onSuccess, this, _1,
205 "Nexthop insertion succeeded"),
206 bind(&Nfdc::onError, this, _1, _2,
207 "Nexthop insertion failed"));
hilata54e4eaf2014-04-10 23:38:33 -0500208}
209
210void
211Nfdc::fibRemoveNextHop()
212{
Obaiddca50792014-04-24 18:38:40 -0500213 m_name = m_commandLineArguments[0];
214 try {
215 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
216 }
217 catch (const std::exception& e) {
218 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
219 return;
220 }
hilata54e4eaf2014-04-10 23:38:33 -0500221
222 ControlParameters parameters;
223 parameters
Obaiddca50792014-04-24 18:38:40 -0500224 .setName(m_name)
225 .setFaceId(m_faceId);
hilata54e4eaf2014-04-10 23:38:33 -0500226
Obaiddca50792014-04-24 18:38:40 -0500227 m_controller.start<FibRemoveNextHopCommand>(parameters,
228 bind(&Nfdc::onSuccess, this, _1,
229 "Nexthop removal succeeded"),
230 bind(&Nfdc::onError, this, _1, _2,
231 "Nexthop removal failed"));
232}
233
234void
235Nfdc::ribRegisterPrefix()
236{
237 m_name = m_commandLineArguments[0];
238 ControlParameters parameters;
239 parameters
240 .setName(m_name)
241 .setCost(m_cost)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500242 .setFlags(m_flags)
Alexander Afanasyevf67cf082014-07-18 16:47:29 -0700243 .setOrigin(m_origin);
244
245 if (m_expires != DEFAULT_EXPIRATION_PERIOD)
246 parameters.setExpirationPeriod(m_expires);
Obaiddca50792014-04-24 18:38:40 -0500247
248 if (!isValidUri(m_commandLineArguments[1])) {
249 try { //So the uri is not valid, may be a faceId is provided.
250 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
251 }
252 catch (const std::exception& e) {
253 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
254 return;
255 }
256 parameters.setFaceId(m_faceId);
257 ribRegisterPrefix(parameters);
258 }
259 else {
Chengyu Fandae25302014-10-16 11:40:11 -0600260 ndn::util::FaceUri faceUri;
261 faceUri.parse(m_commandLineArguments[1]);
Obaiddca50792014-04-24 18:38:40 -0500262
Chengyu Fandae25302014-10-16 11:40:11 -0600263 faceUri.canonize(bind(&Nfdc::startRibRegisterPrefix, this, _1),
264 bind(&Nfdc::onCanonizeFailure, this, _1),
265 m_ioService, ndn::time::seconds(4));
Obaiddca50792014-04-24 18:38:40 -0500266 }
267}
268
269void
Chengyu Fandae25302014-10-16 11:40:11 -0600270Nfdc::startRibRegisterPrefix(const ndn::util::FaceUri& canonicalUri)
271{
272 ControlParameters parameters;
273 parameters.setUri(canonicalUri.toString());
274
275 m_controller.start<FaceCreateCommand>(parameters,
276 bind(&Nfdc::ribRegisterPrefix, this, _1),
277 bind(&Nfdc::onError, this, _1, _2,
278 "Face creation failed"));
279}
280
281void
Obaiddca50792014-04-24 18:38:40 -0500282Nfdc::ribRegisterPrefix(const ControlParameters& faceCreateResult)
283{
284 ControlParameters ribParameters;
285 ribParameters
286 .setName(m_name)
287 .setCost(m_cost)
288 .setFlags(m_flags)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500289 .setOrigin(m_origin)
Obaiddca50792014-04-24 18:38:40 -0500290 .setFaceId(faceCreateResult.getFaceId());
291
Alexander Afanasyevf67cf082014-07-18 16:47:29 -0700292 if (m_expires != DEFAULT_EXPIRATION_PERIOD)
293 ribParameters.setExpirationPeriod(m_expires);
294
Obaiddca50792014-04-24 18:38:40 -0500295 m_controller.start<RibRegisterCommand>(ribParameters,
296 bind(&Nfdc::onSuccess, this, _1,
297 "Successful in name registration"),
298 bind(&Nfdc::onError, this, _1, _2,
299 "Failed in name registration"));
300}
301
302void
303Nfdc::ribUnregisterPrefix()
304{
305 m_name = m_commandLineArguments[0];
306 try {
307 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
308 }
309 catch (const std::exception& e) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500310 std::cerr << "No valid faceId is provided" << std::endl;
Obaiddca50792014-04-24 18:38:40 -0500311 return;
312 }
313
314 ControlParameters parameters;
315 parameters
316 .setName(m_name)
Syed Obaidf93f9d92014-06-22 13:50:48 -0500317 .setFaceId(m_faceId)
318 .setOrigin(m_origin);
Obaiddca50792014-04-24 18:38:40 -0500319
320 m_controller.start<RibUnregisterCommand>(parameters,
321 bind(&Nfdc::onSuccess, this, _1,
322 "Successful in unregistering name"),
323 bind(&Nfdc::onError, this, _1, _2,
324 "Failed in unregistering name"));
hilata54e4eaf2014-04-10 23:38:33 -0500325}
326
327void
Chengyu Fandae25302014-10-16 11:40:11 -0600328Nfdc::onCanonizeFailure(const std::string& reason)
329{
330 std::cerr << reason << std::endl;
331}
332
333void
hilata54e4eaf2014-04-10 23:38:33 -0500334Nfdc::faceCreate()
335{
336 if (!isValidUri(m_commandLineArguments[0]))
337 throw Error("invalid uri format");
338
Chengyu Fandae25302014-10-16 11:40:11 -0600339 ndn::util::FaceUri faceUri;
340 faceUri.parse(m_commandLineArguments[0]);
341
342 faceUri.canonize(bind(&Nfdc::startFaceCreate, this, _1),
343 bind(&Nfdc::onCanonizeFailure, this, _1),
344 m_ioService, ndn::time::seconds(4));
345}
346
347void
348Nfdc::startFaceCreate(const ndn::util::FaceUri& canonicalUri)
349{
hilata54e4eaf2014-04-10 23:38:33 -0500350 ControlParameters parameters;
Chengyu Fandae25302014-10-16 11:40:11 -0600351 parameters.setUri(canonicalUri.toString());
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700352
Obaiddca50792014-04-24 18:38:40 -0500353 m_controller.start<FaceCreateCommand>(parameters,
354 bind(&Nfdc::onSuccess, this, _1,
355 "Face creation succeeded"),
356 bind(&Nfdc::onError, this, _1, _2,
357 "Face creation failed"));
hilata198cadb2014-02-15 23:46:19 -0600358}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700359
hilata198cadb2014-02-15 23:46:19 -0600360void
hilata54e4eaf2014-04-10 23:38:33 -0500361Nfdc::faceDestroy()
hilata198cadb2014-02-15 23:46:19 -0600362{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700363 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500364 if (!isValidUri(m_commandLineArguments[0])) {
365 try { //So the uri is not valid, may be a faceId is provided.
366 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[0]);
367 }
368 catch (const std::exception& e) {
369 std::cerr << "No valid faceUri or faceId is provided" << std::endl;
370 return;
371 }
372 parameters.setFaceId(m_faceId);
373 faceDestroy(parameters);
374 }
375 else{
Chengyu Fandae25302014-10-16 11:40:11 -0600376 ndn::util::FaceUri faceUri;
377 faceUri.parse(m_commandLineArguments[0]);
378
379 faceUri.canonize(bind(&Nfdc::startFaceDestroy, this, _1),
380 bind(&Nfdc::onCanonizeFailure, this, _1),
381 m_ioService, ndn::time::seconds(4));
Obaiddca50792014-04-24 18:38:40 -0500382 }
383}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700384
Obaiddca50792014-04-24 18:38:40 -0500385void
Chengyu Fandae25302014-10-16 11:40:11 -0600386Nfdc::startFaceDestroy(const ndn::util::FaceUri& canonicalUri)
387{
388 ControlParameters parameters;
389 parameters.setUri(canonicalUri.toString());
390
391 m_controller.start<FaceCreateCommand>(parameters,
392 bind(&Nfdc::faceDestroy, this, _1),
393 bind(&Nfdc::onError, this, _1, _2,
394 "Face destroy failed"));
395}
396
397void
Obaiddca50792014-04-24 18:38:40 -0500398Nfdc::faceDestroy(const ControlParameters& faceCreateResult)
399{
400 ControlParameters faceParameters;
401 faceParameters.setFaceId(faceCreateResult.getFaceId());
402
403 m_controller.start<FaceDestroyCommand>(faceParameters,
404 bind(&Nfdc::onSuccess, this, _1,
405 "Face destroy succeeded"),
406 bind(&Nfdc::onError, this, _1, _2,
407 "Face destroy failed"));
hilata198cadb2014-02-15 23:46:19 -0600408}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700409
hilata141eaae2014-03-13 19:54:47 -0500410void
hilata54e4eaf2014-04-10 23:38:33 -0500411Nfdc::strategyChoiceSet()
hilata141eaae2014-03-13 19:54:47 -0500412{
hilata54e4eaf2014-04-10 23:38:33 -0500413 const std::string& name = m_commandLineArguments[0];
414 const std::string& strategy = m_commandLineArguments[1];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700415
416 ControlParameters parameters;
417 parameters
418 .setName(name)
419 .setStrategy(strategy);
420
Obaiddca50792014-04-24 18:38:40 -0500421 m_controller.start<StrategyChoiceSetCommand>(parameters,
422 bind(&Nfdc::onSuccess, this, _1,
423 "Successfully set strategy choice"),
424 bind(&Nfdc::onError, this, _1, _2,
425 "Failed to set strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500426}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700427
hilata141eaae2014-03-13 19:54:47 -0500428void
hilata54e4eaf2014-04-10 23:38:33 -0500429Nfdc::strategyChoiceUnset()
hilata141eaae2014-03-13 19:54:47 -0500430{
hilata54e4eaf2014-04-10 23:38:33 -0500431 const std::string& name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700432
433 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500434 parameters.setName(name);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700435
Obaiddca50792014-04-24 18:38:40 -0500436 m_controller.start<StrategyChoiceUnsetCommand>(parameters,
437 bind(&Nfdc::onSuccess, this, _1,
438 "Successfully unset strategy choice"),
439 bind(&Nfdc::onError, this, _1, _2,
440 "Failed to unset strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500441}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700442
hilata198cadb2014-02-15 23:46:19 -0600443void
Obaiddca50792014-04-24 18:38:40 -0500444Nfdc::onSuccess(const ControlParameters& commandSuccessResult, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600445{
Obaiddca50792014-04-24 18:38:40 -0500446 std::cout << message << ": " << commandSuccessResult << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600447}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700448
hilata198cadb2014-02-15 23:46:19 -0600449void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700450Nfdc::onError(uint32_t code, const std::string& error, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600451{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700452 std::ostringstream os;
453 os << message << ": " << error << " (code: " << code << ")";
454 throw Error(os.str());
hilata141eaae2014-03-13 19:54:47 -0500455}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700456
Obaiddca50792014-04-24 18:38:40 -0500457
458
hilata141eaae2014-03-13 19:54:47 -0500459} // namespace nfdc
hilata198cadb2014-02-15 23:46:19 -0600460
461int
462main(int argc, char** argv)
463{
464 ndn::Face face;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700465 nfdc::Nfdc p(face);
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800466
hilata198cadb2014-02-15 23:46:19 -0600467 p.m_programName = argv[0];
hilata54e4eaf2014-04-10 23:38:33 -0500468
Obaiddca50792014-04-24 18:38:40 -0500469 if (argc < 2) {
470 usage(p.m_programName);
471 return 0;
472 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700473
Obaiddca50792014-04-24 18:38:40 -0500474 if (!strcmp(argv[1], "-h")) {
475 usage(p.m_programName);
476 return 0;
477 }
478
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700479 if (!strcmp(argv[1], "-V")) {
480 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
481 return 0;
482 }
483
Junxiao Shi22295032014-04-29 22:57:40 -0700484 ::optind = 2; //start reading options from 2nd argument i.e. Command
Obaiddca50792014-04-24 18:38:40 -0500485 int opt;
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500486 while ((opt = ::getopt(argc, argv, "ICc:e:o:")) != -1) {
Obaiddca50792014-04-24 18:38:40 -0500487 switch (opt) {
488 case 'I':
489 p.m_flags = p.m_flags & ~(nfdc::ROUTE_FLAG_CHILD_INHERIT);
490 break;
491
492 case 'C':
493 p.m_flags = p.m_flags | nfdc::ROUTE_FLAG_CAPTURE;
494 break;
495
496 case 'c':
497 try {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500498 p.m_cost = boost::lexical_cast<uint64_t>(::optarg);
Obaiddca50792014-04-24 18:38:40 -0500499 }
Junxiao Shi22295032014-04-29 22:57:40 -0700500 catch (boost::bad_lexical_cast&) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500501 std::cerr << "Error: cost must be in unsigned integer format" << std::endl;
502 return 1;
503 }
504 break;
505
506 case 'e':
507 uint64_t expires;
508 try {
509 expires = boost::lexical_cast<uint64_t>(::optarg);
510 }
511 catch (boost::bad_lexical_cast&) {
512 std::cerr << "Error: expiration time must be in unsigned integer format" << std::endl;
513 return 1;
514 }
515 p.m_expires = ndn::time::milliseconds(expires);
516 break;
517
518 case 'o':
519 try {
520 p.m_origin = boost::lexical_cast<uint64_t>(::optarg);
521 }
522 catch (boost::bad_lexical_cast&) {
523 std::cerr << "Error: origin must be in unsigned integer format" << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600524 return 1;
Obaiddca50792014-04-24 18:38:40 -0500525 }
526 break;
Junxiao Shi22295032014-04-29 22:57:40 -0700527
Obaiddca50792014-04-24 18:38:40 -0500528 default:
529 usage(p.m_programName);
530 return 1;
hilata198cadb2014-02-15 23:46:19 -0600531 }
532 }
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800533
Junxiao Shi22295032014-04-29 22:57:40 -0700534 if (argc == ::optind) {
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800535 usage(p.m_programName);
536 return 1;
537 }
538
hilata198cadb2014-02-15 23:46:19 -0600539 try {
Junxiao Shi22295032014-04-29 22:57:40 -0700540 p.m_commandLineArguments = argv + ::optind;
541 p.m_nOptions = argc - ::optind;
Obaiddca50792014-04-24 18:38:40 -0500542
543 //argv[1] points to the command, so pass it to the dispatch
544 bool isOk = p.dispatch(argv[1]);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700545 if (!isOk) {
hilata198cadb2014-02-15 23:46:19 -0600546 usage(p.m_programName);
547 return 1;
548 }
hilata198cadb2014-02-15 23:46:19 -0600549 face.processEvents();
550 }
551 catch (const std::exception& e) {
552 std::cerr << "ERROR: " << e.what() << std::endl;
553 return 2;
554 }
555 return 0;
556}