blob: fd2fbc3f2bf0e6e34e2030ff1a498e4f2647e4b6 [file] [log] [blame]
hilata198cadb2014-02-15 23:46:19 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6#include "nfdc.hpp"
7#include <boost/lexical_cast.hpp>
8#include <boost/algorithm/string.hpp>
9#include <boost/algorithm/string/regex_find_format.hpp>
10#include <boost/regex.hpp>
11
12void
13usage(const char* programName)
14{
15 std::cout << "Usage:\n" << programName << " [-h] COMMAND\n"
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070016 " -h print usage and exit\n"
17 "\n"
18 " COMMAND can be one of following:\n"
19 " add-nexthop <name> <faceId> [<cost>]\n"
20 " Add a nexthop to a FIB entry\n"
21 " remove-nexthop <name> <faceId> \n"
22 " Remove a nexthop from a FIB entry\n"
23 " create <uri> \n"
24 " Create a face in one of the following formats:\n"
25 " UDP unicast: udp[4|6]://<remote-IP-or-host>[:<remote-port>]\n"
26 " TCP: tcp[4|6]://<remote-IP-or-host>[:<remote-port>] \n"
27 " destroy <faceId> \n"
28 " Destroy a face\n"
29 " set-strategy <name> <strategy> \n"
30 " Set the strategy for a namespace \n"
31 " unset-strategy <name> \n"
32 " Unset the strategy for a namespace \n"
33 << std::endl;
hilata198cadb2014-02-15 23:46:19 -060034}
35
36namespace nfdc {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070037
38Nfdc::Nfdc(ndn::Face& face)
39 : m_controller(face)
hilata198cadb2014-02-15 23:46:19 -060040{
41}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070042
43Nfdc::~Nfdc()
hilata198cadb2014-02-15 23:46:19 -060044{
45}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070046
hilata198cadb2014-02-15 23:46:19 -060047bool
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070048Nfdc::dispatch(const std::string& command, const char* commandOptions[], int nOptions)
hilata198cadb2014-02-15 23:46:19 -060049{
hilatadc947ec2014-03-10 12:48:31 -050050 if (command == "add-nexthop") {
hilata198cadb2014-02-15 23:46:19 -060051 if (nOptions == 2)
52 fibAddNextHop(commandOptions, false);
53 else if (nOptions == 3)
54 fibAddNextHop(commandOptions, true);
55 else
56 return false;
57 }
58 else if (command == "remove-nexthop") {
59 if (nOptions != 2)
60 return false;
61 fibRemoveNextHop(commandOptions);
62 }
hilata198cadb2014-02-15 23:46:19 -060063 else if (command == "create") {
64 if (nOptions != 1)
65 return false;
66 faceCreate(commandOptions);
67 }
68 else if (command == "destroy") {
69 if (nOptions != 1)
70 return false;
71 faceDestroy(commandOptions);
72 }
hilata141eaae2014-03-13 19:54:47 -050073 else if (command == "set-strategy") {
74 if (nOptions != 2)
75 return false;
76 strategyChoiceSet(commandOptions);
77 }
78 else if (command == "unset-strategy") {
79 if (nOptions != 1)
80 return false;
81 strategyChoiceUnset(commandOptions);
82 }
hilata198cadb2014-02-15 23:46:19 -060083 else
84 usage(m_programName);
85
86 return true;
87}
hilata198cadb2014-02-15 23:46:19 -060088
89void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070090Nfdc::fibAddNextHop(const char* commandOptions[], bool hasCost)
hilata198cadb2014-02-15 23:46:19 -060091{
hilata198cadb2014-02-15 23:46:19 -060092 const std::string& name = commandOptions[0];
93 const int faceId = boost::lexical_cast<int>(commandOptions[1]);
94
Alexander Afanasyev352e14e2014-03-27 16:02:12 -070095 ControlParameters parameters;
96 parameters
97 .setName(name)
98 .setFaceId(faceId);
hilata198cadb2014-02-15 23:46:19 -060099
100 if (hasCost)
101 {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700102 const uint64_t cost = boost::lexical_cast<uint64_t>(commandOptions[2]);
103 parameters.setCost(cost);
hilata198cadb2014-02-15 23:46:19 -0600104 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700105
106 m_controller.start<FibAddNextHopCommand>(
107 parameters,
108 bind(&Nfdc::onSuccess, this, _1, "Nexthop insertion succeeded"),
109 bind(&Nfdc::onError, this, _1, _2, "Nexthop insertion failed"));
hilata198cadb2014-02-15 23:46:19 -0600110}
111
112void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700113Nfdc::fibRemoveNextHop(const char* commandOptions[])
hilata198cadb2014-02-15 23:46:19 -0600114{
115 const std::string& name = commandOptions[0];
116 const int faceId = boost::lexical_cast<int>(commandOptions[1]);
hilata198cadb2014-02-15 23:46:19 -0600117
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700118 ControlParameters parameters;
119 parameters
120 .setName(name)
121 .setFaceId(faceId);
122
123 m_controller.start<FibRemoveNextHopCommand>(
124 parameters,
125 bind(&Nfdc::onSuccess, this, _1, "Nexthop removal succeeded"),
126 bind(&Nfdc::onError, this, _1, _2, "Nexthop removal failed"));
hilata198cadb2014-02-15 23:46:19 -0600127}
hilata9b27e692014-02-25 15:43:19 -0600128
hilata198cadb2014-02-15 23:46:19 -0600129namespace {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700130
131inline bool
hilata198cadb2014-02-15 23:46:19 -0600132isValidUri(const std::string& input)
133{
134 // an extended regex to support the validation of uri structure
135 // boost::regex e("^[a-z0-9]+-?+[a-z0-9]+\\:\\/\\/.*");
136 boost::regex e("^[a-z0-9]+\\:.*");
137 return boost::regex_match(input, e);
138}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700139
hilata198cadb2014-02-15 23:46:19 -0600140} // anonymous namespace
141
142void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700143Nfdc::faceCreate(const char* commandOptions[])
hilata198cadb2014-02-15 23:46:19 -0600144{
hilata198cadb2014-02-15 23:46:19 -0600145 const std::string& uri = commandOptions[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700146 if (!isValidUri(uri))
hilata198cadb2014-02-15 23:46:19 -0600147 throw Error("invalid uri format");
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700148
149 ControlParameters parameters;
150 parameters
151 .setUri(uri);
152
153 m_controller.start<FaceCreateCommand>(
154 parameters,
155 bind(&Nfdc::onSuccess, this, _1, "Face creation succeeded"),
156 bind(&Nfdc::onError, this, _1, _2, "Face creation failed"));
hilata198cadb2014-02-15 23:46:19 -0600157}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700158
hilata198cadb2014-02-15 23:46:19 -0600159void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700160Nfdc::faceDestroy(const char* commandOptions[])
hilata198cadb2014-02-15 23:46:19 -0600161{
hilata198cadb2014-02-15 23:46:19 -0600162 const int faceId = boost::lexical_cast<int>(commandOptions[0]);
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700163
164 ControlParameters parameters;
165 parameters
166 .setFaceId(faceId);
167
168 m_controller.start<FaceDestroyCommand>(
169 parameters,
170 bind(&Nfdc::onSuccess, this, _1, "Face destroy succeeded"),
171 bind(&Nfdc::onError, this, _1, _2, "Face destroy failed"));
hilata198cadb2014-02-15 23:46:19 -0600172}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700173
hilata141eaae2014-03-13 19:54:47 -0500174void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700175Nfdc::strategyChoiceSet(const char* commandOptions[])
hilata141eaae2014-03-13 19:54:47 -0500176{
177 const std::string& name = commandOptions[0];
178 const std::string& strategy = commandOptions[1];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700179
180 ControlParameters parameters;
181 parameters
182 .setName(name)
183 .setStrategy(strategy);
184
185 m_controller.start<StrategyChoiceSetCommand>(
186 parameters,
187 bind(&Nfdc::onSuccess, this, _1, "Successfully set strategy choice"),
188 bind(&Nfdc::onError, this, _1, _2, "Failed to set strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500189}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700190
hilata141eaae2014-03-13 19:54:47 -0500191void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700192Nfdc::strategyChoiceUnset(const char* commandOptions[])
hilata141eaae2014-03-13 19:54:47 -0500193{
194 const std::string& name = commandOptions[0];
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700195
196 ControlParameters parameters;
197 parameters
198 .setName(name);
199
200 m_controller.start<StrategyChoiceUnsetCommand>(
201 parameters,
202 bind(&Nfdc::onSuccess, this, _1, "Successfully unset strategy choice"),
203 bind(&Nfdc::onError, this, _1, _2, "Failed to unset strategy choice"));
hilata141eaae2014-03-13 19:54:47 -0500204}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700205
hilata198cadb2014-02-15 23:46:19 -0600206void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700207Nfdc::onSuccess(const ControlParameters& parameters, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600208{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700209 std::cout << message << ": " << parameters << std::endl;
hilata198cadb2014-02-15 23:46:19 -0600210}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700211
hilata198cadb2014-02-15 23:46:19 -0600212void
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700213Nfdc::onError(uint32_t code, const std::string& error, const std::string& message)
hilata198cadb2014-02-15 23:46:19 -0600214{
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700215 std::ostringstream os;
216 os << message << ": " << error << " (code: " << code << ")";
217 throw Error(os.str());
hilata141eaae2014-03-13 19:54:47 -0500218}
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700219
hilata141eaae2014-03-13 19:54:47 -0500220} // namespace nfdc
hilata198cadb2014-02-15 23:46:19 -0600221
222int
223main(int argc, char** argv)
224{
225 ndn::Face face;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700226 nfdc::Nfdc p(face);
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800227
hilata198cadb2014-02-15 23:46:19 -0600228 p.m_programName = argv[0];
229 int opt;
230 while ((opt = getopt(argc, argv, "h")) != -1) {
231 switch (opt) {
232 case 'h':
233 usage(p.m_programName);
234 return 0;
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700235
hilata198cadb2014-02-15 23:46:19 -0600236 default:
237 usage(p.m_programName);
238 return 1;
239 }
240 }
Alexander Afanasyev9f935b82014-02-24 15:14:22 -0800241
242 if (argc == optind) {
243 usage(p.m_programName);
244 return 1;
245 }
246
hilata198cadb2014-02-15 23:46:19 -0600247 try {
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700248 bool isOk = p.dispatch(argv[optind],
249 const_cast<const char**>(argv + optind + 1),
250 argc - optind - 1);
251 if (!isOk) {
hilata198cadb2014-02-15 23:46:19 -0600252 usage(p.m_programName);
253 return 1;
254 }
Alexander Afanasyev352e14e2014-03-27 16:02:12 -0700255
hilata198cadb2014-02-15 23:46:19 -0600256 face.processEvents();
257 }
258 catch (const std::exception& e) {
259 std::cerr << "ERROR: " << e.what() << std::endl;
260 return 2;
261 }
262 return 0;
263}