blob: 8578e43c279ba482d48091e226e94bf5785fbccc [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)
hilata198cadb2014-02-15 23:46:19 -060082{
83}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070084
85Nfdc::~Nfdc()
hilata198cadb2014-02-15 23:46:19 -060086{
87}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070088
hilata198cadb2014-02-15 23:46:19 -060089bool
hilata54e4eaf2014-04-10 23:38:33 -050090Nfdc::dispatch(const std::string& command)
hilata198cadb2014-02-15 23:46:19 -060091{
Obaiddca50792014-04-24 18:38:40 -050092 if (command == "add-nexthop") {
93 if (m_nOptions != 2)
hilata54e4eaf2014-04-10 23:38:33 -050094 return false;
Obaiddca50792014-04-24 18:38:40 -050095 fibAddNextHop();
hilata198cadb2014-02-15 23:46:19 -060096 }
97 else if (command == "remove-nexthop") {
hilata54e4eaf2014-04-10 23:38:33 -050098 if (m_nOptions != 2)
hilata198cadb2014-02-15 23:46:19 -060099 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500100 fibRemoveNextHop();
hilata198cadb2014-02-15 23:46:19 -0600101 }
Obaiddca50792014-04-24 18:38:40 -0500102 else if (command == "register") {
103 if (m_nOptions != 2)
104 return false;
105 ribRegisterPrefix();
106 }
107 else if (command == "unregister") {
108 if (m_nOptions != 2)
109 return false;
110 ribUnregisterPrefix();
111 }
hilata198cadb2014-02-15 23:46:19 -0600112 else if (command == "create") {
hilata54e4eaf2014-04-10 23:38:33 -0500113 if (m_nOptions != 1)
hilata198cadb2014-02-15 23:46:19 -0600114 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500115 faceCreate();
hilata198cadb2014-02-15 23:46:19 -0600116 }
117 else if (command == "destroy") {
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 faceDestroy();
hilata198cadb2014-02-15 23:46:19 -0600121 }
hilata141eaae2014-03-13 19:54:47 -0500122 else if (command == "set-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500123 if (m_nOptions != 2)
hilata141eaae2014-03-13 19:54:47 -0500124 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500125 strategyChoiceSet();
hilata141eaae2014-03-13 19:54:47 -0500126 }
127 else if (command == "unset-strategy") {
hilata54e4eaf2014-04-10 23:38:33 -0500128 if (m_nOptions != 1)
hilata141eaae2014-03-13 19:54:47 -0500129 return false;
hilata54e4eaf2014-04-10 23:38:33 -0500130 strategyChoiceUnset();
hilata141eaae2014-03-13 19:54:47 -0500131 }
hilata198cadb2014-02-15 23:46:19 -0600132 else
133 usage(m_programName);
134
135 return true;
136}
hilata198cadb2014-02-15 23:46:19 -0600137
hilata198cadb2014-02-15 23:46:19 -0600138namespace {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700139
140inline bool
hilata198cadb2014-02-15 23:46:19 -0600141isValidUri(const std::string& input)
142{
143 // an extended regex to support the validation of uri structure
144 // boost::regex e("^[a-z0-9]+-?+[a-z0-9]+\\:\\/\\/.*");
145 boost::regex e("^[a-z0-9]+\\:.*");
146 return boost::regex_match(input, e);
147}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700148
hilata198cadb2014-02-15 23:46:19 -0600149} // anonymous namespace
150
151void
Obaiddca50792014-04-24 18:38:40 -0500152Nfdc::fibAddNextHop()
hilata198cadb2014-02-15 23:46:19 -0600153{
Obaiddca50792014-04-24 18:38:40 -0500154 m_name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700155 ControlParameters parameters;
156 parameters
Obaiddca50792014-04-24 18:38:40 -0500157 .setName(m_name)
158 .setCost(m_cost);
hilata54e4eaf2014-04-10 23:38:33 -0500159
Obaiddca50792014-04-24 18:38:40 -0500160 if (!isValidUri(m_commandLineArguments[1])) {
161 try { //So the uri is not valid, may be a faceId is provided.
162 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
163 }
164 catch (const std::exception& e) {
165 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
166 return;
167 }
168 parameters.setFaceId(m_faceId);
169 fibAddNextHop(parameters);
hilata54e4eaf2014-04-10 23:38:33 -0500170 }
Obaiddca50792014-04-24 18:38:40 -0500171 else {
172 ControlParameters faceParameters;
173 faceParameters.setUri(m_commandLineArguments[1]);
hilata54e4eaf2014-04-10 23:38:33 -0500174
Obaiddca50792014-04-24 18:38:40 -0500175 m_controller.start<FaceCreateCommand>(faceParameters,
176 bind(&Nfdc::fibAddNextHop, this, _1),
177 bind(&Nfdc::onError, this, _1, _2,
178 "Face creation failed"));
179 }
180}
181
182void
183Nfdc::fibAddNextHop(const ControlParameters& faceCreateResult)
184{
185 ControlParameters ribParameters;
186 ribParameters
187 .setName(m_name)
188 .setCost(m_cost)
189 .setFaceId(faceCreateResult.getFaceId());
190
191 m_controller.start<FibAddNextHopCommand>(ribParameters,
192 bind(&Nfdc::onSuccess, this, _1,
193 "Nexthop insertion succeeded"),
194 bind(&Nfdc::onError, this, _1, _2,
195 "Nexthop insertion failed"));
hilata54e4eaf2014-04-10 23:38:33 -0500196}
197
198void
199Nfdc::fibRemoveNextHop()
200{
Obaiddca50792014-04-24 18:38:40 -0500201 m_name = m_commandLineArguments[0];
202 try {
203 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
204 }
205 catch (const std::exception& e) {
206 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
207 return;
208 }
hilata54e4eaf2014-04-10 23:38:33 -0500209
210 ControlParameters parameters;
211 parameters
Obaiddca50792014-04-24 18:38:40 -0500212 .setName(m_name)
213 .setFaceId(m_faceId);
hilata54e4eaf2014-04-10 23:38:33 -0500214
Obaiddca50792014-04-24 18:38:40 -0500215 m_controller.start<FibRemoveNextHopCommand>(parameters,
216 bind(&Nfdc::onSuccess, this, _1,
217 "Nexthop removal succeeded"),
218 bind(&Nfdc::onError, this, _1, _2,
219 "Nexthop removal failed"));
220}
221
222void
223Nfdc::ribRegisterPrefix()
224{
225 m_name = m_commandLineArguments[0];
226 ControlParameters parameters;
227 parameters
228 .setName(m_name)
229 .setCost(m_cost)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500230 .setFlags(m_flags)
Alexander Afanasyevf67cf082014-07-18 16:47:29 -0700231 .setOrigin(m_origin);
232
233 if (m_expires != DEFAULT_EXPIRATION_PERIOD)
234 parameters.setExpirationPeriod(m_expires);
Obaiddca50792014-04-24 18:38:40 -0500235
236 if (!isValidUri(m_commandLineArguments[1])) {
237 try { //So the uri is not valid, may be a faceId is provided.
238 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
239 }
240 catch (const std::exception& e) {
241 std::cerr << "No valid faceUri or faceId is provided"<< std::endl;
242 return;
243 }
244 parameters.setFaceId(m_faceId);
245 ribRegisterPrefix(parameters);
246 }
247 else {
248 ControlParameters faceParameters;
249 faceParameters.setUri(m_commandLineArguments[1]);
250
251 m_controller.start<FaceCreateCommand>(faceParameters,
252 bind(&Nfdc::ribRegisterPrefix, this, _1),
253 bind(&Nfdc::onError, this, _1, _2,
254 "Face creation failed"));
255 }
256}
257
258void
259Nfdc::ribRegisterPrefix(const ControlParameters& faceCreateResult)
260{
261 ControlParameters ribParameters;
262 ribParameters
263 .setName(m_name)
264 .setCost(m_cost)
265 .setFlags(m_flags)
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500266 .setOrigin(m_origin)
Obaiddca50792014-04-24 18:38:40 -0500267 .setFaceId(faceCreateResult.getFaceId());
268
Alexander Afanasyevf67cf082014-07-18 16:47:29 -0700269 if (m_expires != DEFAULT_EXPIRATION_PERIOD)
270 ribParameters.setExpirationPeriod(m_expires);
271
Obaiddca50792014-04-24 18:38:40 -0500272 m_controller.start<RibRegisterCommand>(ribParameters,
273 bind(&Nfdc::onSuccess, this, _1,
274 "Successful in name registration"),
275 bind(&Nfdc::onError, this, _1, _2,
276 "Failed in name registration"));
277}
278
279void
280Nfdc::ribUnregisterPrefix()
281{
282 m_name = m_commandLineArguments[0];
283 try {
284 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[1]);
285 }
286 catch (const std::exception& e) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500287 std::cerr << "No valid faceId is provided" << std::endl;
Obaiddca50792014-04-24 18:38:40 -0500288 return;
289 }
290
291 ControlParameters parameters;
292 parameters
293 .setName(m_name)
Syed Obaidf93f9d92014-06-22 13:50:48 -0500294 .setFaceId(m_faceId)
295 .setOrigin(m_origin);
Obaiddca50792014-04-24 18:38:40 -0500296
297 m_controller.start<RibUnregisterCommand>(parameters,
298 bind(&Nfdc::onSuccess, this, _1,
299 "Successful in unregistering name"),
300 bind(&Nfdc::onError, this, _1, _2,
301 "Failed in unregistering name"));
hilata54e4eaf2014-04-10 23:38:33 -0500302}
303
304void
305Nfdc::faceCreate()
306{
307 if (!isValidUri(m_commandLineArguments[0]))
308 throw Error("invalid uri format");
309
310 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500311 parameters.setUri(m_commandLineArguments[0]);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700312
Obaiddca50792014-04-24 18:38:40 -0500313 m_controller.start<FaceCreateCommand>(parameters,
314 bind(&Nfdc::onSuccess, this, _1,
315 "Face creation succeeded"),
316 bind(&Nfdc::onError, this, _1, _2,
317 "Face creation failed"));
hilata198cadb2014-02-15 23:46:19 -0600318}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700319
hilata198cadb2014-02-15 23:46:19 -0600320void
hilata54e4eaf2014-04-10 23:38:33 -0500321Nfdc::faceDestroy()
hilata198cadb2014-02-15 23:46:19 -0600322{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700323 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500324 if (!isValidUri(m_commandLineArguments[0])) {
325 try { //So the uri is not valid, may be a faceId is provided.
326 m_faceId = boost::lexical_cast<int>(m_commandLineArguments[0]);
327 }
328 catch (const std::exception& e) {
329 std::cerr << "No valid faceUri or faceId is provided" << std::endl;
330 return;
331 }
332 parameters.setFaceId(m_faceId);
333 faceDestroy(parameters);
334 }
335 else{
336 ControlParameters faceParameters;
337 faceParameters.setUri(m_commandLineArguments[0]);
338 m_controller.start<FaceCreateCommand>(faceParameters,
339 bind(&Nfdc::faceDestroy, this, _1),
340 bind(&Nfdc::onError, this, _1, _2,
341 "Face destroy failed"));
342 }
343}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700344
Obaiddca50792014-04-24 18:38:40 -0500345void
346Nfdc::faceDestroy(const ControlParameters& faceCreateResult)
347{
348 ControlParameters faceParameters;
349 faceParameters.setFaceId(faceCreateResult.getFaceId());
350
351 m_controller.start<FaceDestroyCommand>(faceParameters,
352 bind(&Nfdc::onSuccess, this, _1,
353 "Face destroy succeeded"),
354 bind(&Nfdc::onError, this, _1, _2,
355 "Face destroy failed"));
hilata198cadb2014-02-15 23:46:19 -0600356}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700357
hilata141eaae2014-03-13 19:54:47 -0500358void
hilata54e4eaf2014-04-10 23:38:33 -0500359Nfdc::strategyChoiceSet()
hilata141eaae2014-03-13 19:54:47 -0500360{
hilata54e4eaf2014-04-10 23:38:33 -0500361 const std::string& name = m_commandLineArguments[0];
362 const std::string& strategy = m_commandLineArguments[1];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700363
364 ControlParameters parameters;
365 parameters
366 .setName(name)
367 .setStrategy(strategy);
368
Obaiddca50792014-04-24 18:38:40 -0500369 m_controller.start<StrategyChoiceSetCommand>(parameters,
370 bind(&Nfdc::onSuccess, this, _1,
371 "Successfully set strategy choice"),
372 bind(&Nfdc::onError, this, _1, _2,
373 "Failed to set strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500374}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700375
hilata141eaae2014-03-13 19:54:47 -0500376void
hilata54e4eaf2014-04-10 23:38:33 -0500377Nfdc::strategyChoiceUnset()
hilata141eaae2014-03-13 19:54:47 -0500378{
hilata54e4eaf2014-04-10 23:38:33 -0500379 const std::string& name = m_commandLineArguments[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700380
381 ControlParameters parameters;
Obaiddca50792014-04-24 18:38:40 -0500382 parameters.setName(name);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700383
Obaiddca50792014-04-24 18:38:40 -0500384 m_controller.start<StrategyChoiceUnsetCommand>(parameters,
385 bind(&Nfdc::onSuccess, this, _1,
386 "Successfully unset strategy choice"),
387 bind(&Nfdc::onError, this, _1, _2,
388 "Failed to unset strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500389}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700390
hilata198cadb2014-02-15 23:46:19 -0600391void
Obaiddca50792014-04-24 18:38:40 -0500392Nfdc::onSuccess(const ControlParameters& commandSuccessResult, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600393{
Obaiddca50792014-04-24 18:38:40 -0500394 std::cout << message << ": " << commandSuccessResult << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600395}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700396
hilata198cadb2014-02-15 23:46:19 -0600397void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700398Nfdc::onError(uint32_t code, const std::string& error, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600399{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700400 std::ostringstream os;
401 os << message << ": " << error << " (code: " << code << ")";
402 throw Error(os.str());
hilata141eaae2014-03-13 19:54:47 -0500403}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700404
Obaiddca50792014-04-24 18:38:40 -0500405
406
hilata141eaae2014-03-13 19:54:47 -0500407} // namespace nfdc
hilata198cadb2014-02-15 23:46:19 -0600408
409int
410main(int argc, char** argv)
411{
412 ndn::Face face;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700413 nfdc::Nfdc p(face);
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800414
hilata198cadb2014-02-15 23:46:19 -0600415 p.m_programName = argv[0];
hilata54e4eaf2014-04-10 23:38:33 -0500416
Obaiddca50792014-04-24 18:38:40 -0500417 if (argc < 2) {
418 usage(p.m_programName);
419 return 0;
420 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700421
Obaiddca50792014-04-24 18:38:40 -0500422 if (!strcmp(argv[1], "-h")) {
423 usage(p.m_programName);
424 return 0;
425 }
426
Alexander Afanasyevb47d5382014-05-05 14:35:03 -0700427 if (!strcmp(argv[1], "-V")) {
428 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
429 return 0;
430 }
431
Junxiao Shi22295032014-04-29 22:57:40 -0700432 ::optind = 2; //start reading options from 2nd argument i.e. Command
Obaiddca50792014-04-24 18:38:40 -0500433 int opt;
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500434 while ((opt = ::getopt(argc, argv, "ICc:e:o:")) != -1) {
Obaiddca50792014-04-24 18:38:40 -0500435 switch (opt) {
436 case 'I':
437 p.m_flags = p.m_flags & ~(nfdc::ROUTE_FLAG_CHILD_INHERIT);
438 break;
439
440 case 'C':
441 p.m_flags = p.m_flags | nfdc::ROUTE_FLAG_CAPTURE;
442 break;
443
444 case 'c':
445 try {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500446 p.m_cost = boost::lexical_cast<uint64_t>(::optarg);
Obaiddca50792014-04-24 18:38:40 -0500447 }
Junxiao Shi22295032014-04-29 22:57:40 -0700448 catch (boost::bad_lexical_cast&) {
Syed Obaid4ae0ce32014-06-17 13:59:20 -0500449 std::cerr << "Error: cost must be in unsigned integer format" << std::endl;
450 return 1;
451 }
452 break;
453
454 case 'e':
455 uint64_t expires;
456 try {
457 expires = boost::lexical_cast<uint64_t>(::optarg);
458 }
459 catch (boost::bad_lexical_cast&) {
460 std::cerr << "Error: expiration time must be in unsigned integer format" << std::endl;
461 return 1;
462 }
463 p.m_expires = ndn::time::milliseconds(expires);
464 break;
465
466 case 'o':
467 try {
468 p.m_origin = boost::lexical_cast<uint64_t>(::optarg);
469 }
470 catch (boost::bad_lexical_cast&) {
471 std::cerr << "Error: origin must be in unsigned integer format" << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600472 return 1;
Obaiddca50792014-04-24 18:38:40 -0500473 }
474 break;
Junxiao Shi22295032014-04-29 22:57:40 -0700475
Obaiddca50792014-04-24 18:38:40 -0500476 default:
477 usage(p.m_programName);
478 return 1;
hilata198cadb2014-02-15 23:46:19 -0600479 }
480 }
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800481
Junxiao Shi22295032014-04-29 22:57:40 -0700482 if (argc == ::optind) {
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800483 usage(p.m_programName);
484 return 1;
485 }
486
hilata198cadb2014-02-15 23:46:19 -0600487 try {
Junxiao Shi22295032014-04-29 22:57:40 -0700488 p.m_commandLineArguments = argv + ::optind;
489 p.m_nOptions = argc - ::optind;
Obaiddca50792014-04-24 18:38:40 -0500490
491 //argv[1] points to the command, so pass it to the dispatch
492 bool isOk = p.dispatch(argv[1]);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700493 if (!isOk) {
hilata198cadb2014-02-15 23:46:19 -0600494 usage(p.m_programName);
495 return 1;
496 }
hilata198cadb2014-02-15 23:46:19 -0600497 face.processEvents();
498 }
499 catch (const std::exception& e) {
500 std::cerr << "ERROR: " << e.what() << std::endl;
501 return 2;
502 }
503 return 0;
504}