blob: 432042b1e3e7031c564302f678d149d9d09bacf0 [file] [log] [blame]
Junxiao Shi2ac79d92015-03-23 11:16:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi1688ded2015-03-29 10:09:26 -07003 * Copyright (c) 2014-2015, 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.
10 *
11 * This file is part of ndn-tools (Named Data Networking Essential Tools).
12 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
13 *
14 * ndn-tools 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 * ndn-tools 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 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25/**
Junxiao Shi2ac79d92015-03-23 11:16:18 -070026 * Copyright (c) 2014, Regents of the University of California,
27 * Arizona Board of Regents,
28 * Colorado State University,
29 * University Pierre & Marie Curie, Sorbonne University,
30 * Washington University in St. Louis,
31 * Beijing Institute of Technology,
32 * The University of Memphis
33 *
34 * This file is part of NFD (Named Data Networking Forwarding Daemon).
35 * See AUTHORS.md for complete list of NFD authors and contributors.
36 *
37 * NFD is free software: you can redistribute it and/or modify it under the terms
38 * of the GNU General Public License as published by the Free Software Foundation,
39 * either version 3 of the License, or (at your option) any later version.
40 *
41 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
42 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
43 * PURPOSE. See the GNU General Public License for more details.
44 *
45 * You should have received a copy of the GNU General Public License along with
46 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
47 *
48 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
49 */
50
Junxiao Shi1753afb2015-04-17 20:59:50 -070051#include "core/version.hpp"
Junxiao Shi2ac79d92015-03-23 11:16:18 -070052
Junxiao Shi0c75f992015-03-24 21:39:47 -070053namespace ndn {
54namespace peek {
Junxiao Shi2ac79d92015-03-23 11:16:18 -070055
Junxiao Shi0c75f992015-03-24 21:39:47 -070056class NdnPeek : boost::noncopyable
Junxiao Shi2ac79d92015-03-23 11:16:18 -070057{
58public:
59 explicit
Junxiao Shi0c75f992015-03-24 21:39:47 -070060 NdnPeek(char* programName)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070061 : m_programName(programName)
Junxiao Shie02fb522015-10-18 08:45:09 -070062 , m_isVerbose(false)
Junxiao Shi2ac79d92015-03-23 11:16:18 -070063 , m_mustBeFresh(false)
64 , m_isChildSelectorRightmost(false)
65 , m_minSuffixComponents(-1)
66 , m_maxSuffixComponents(-1)
67 , m_interestLifetime(-1)
68 , m_isPayloadOnlySet(false)
69 , m_timeout(-1)
70 , m_prefixName("")
71 , m_isDataReceived(false)
72 {
73 }
74
75 void
76 usage()
77 {
78 std::cout << "\n Usage:\n " << m_programName << " "
79 "[-f] [-r] [-m min] [-M max] [-l lifetime] [-p] [-w timeout] ndn:/name\n"
80 " Get one data item matching the name prefix and write it to stdout\n"
81 " [-f] - set MustBeFresh\n"
82 " [-r] - set ChildSelector to select rightmost child\n"
83 " [-m min] - set MinSuffixComponents\n"
84 " [-M max] - set MaxSuffixComponents\n"
85 " [-l lifetime] - set InterestLifetime in time::milliseconds\n"
86 " [-p] - print payload only, not full packet\n"
87 " [-w timeout] - set Timeout in time::milliseconds\n"
Junxiao Shie02fb522015-10-18 08:45:09 -070088 " [-v] - verbose output\n"
Junxiao Shi2ac79d92015-03-23 11:16:18 -070089 " [-h] - print help and exit\n"
90 " [-V] - print version and exit\n"
91 "\n";
92 exit(1);
93 }
94
95 void
Junxiao Shie02fb522015-10-18 08:45:09 -070096 setVerbose()
97 {
98 m_isVerbose = true;
99 }
100
101 void
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700102 setMustBeFresh()
103 {
104 m_mustBeFresh = true;
105 }
106
107 void
108 setRightmostChildSelector()
109 {
110 m_isChildSelectorRightmost = true;
111 }
112
113 void
114 setMinSuffixComponents(int minSuffixComponents)
115 {
116 if (minSuffixComponents < 0)
117 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700118
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700119 m_minSuffixComponents = minSuffixComponents;
120 }
121
122 void
123 setMaxSuffixComponents(int maxSuffixComponents)
124 {
125 if (maxSuffixComponents < 0)
126 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700127
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700128 m_maxSuffixComponents = maxSuffixComponents;
129 }
130
131 void
132 setInterestLifetime(int interestLifetime)
133 {
134 if (interestLifetime < 0)
135 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700136
137 m_interestLifetime = time::milliseconds(interestLifetime);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700138 }
139
140 void
141 setPayloadOnly()
142 {
143 m_isPayloadOnlySet = true;
144 }
145
146 void
147 setTimeout(int timeout)
148 {
149 if (timeout < 0)
150 usage();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700151
152 m_timeout = time::milliseconds(timeout);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700153 }
154
155 void
156 setPrefixName(char* prefixName)
157 {
158 m_prefixName = prefixName;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700159
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700160 if (m_prefixName.length() == 0)
161 usage();
162 }
163
Junxiao Shi0c75f992015-03-24 21:39:47 -0700164 time::milliseconds
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700165 getDefaultInterestLifetime()
166 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700167 return time::seconds(4);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700168 }
169
Junxiao Shi0c75f992015-03-24 21:39:47 -0700170 Interest
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700171 createInterestPacket()
172 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700173 Name interestName(m_prefixName);
174 Interest interestPacket(interestName);
175
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700176 if (m_mustBeFresh)
177 interestPacket.setMustBeFresh(true);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700178
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700179 if (m_isChildSelectorRightmost)
180 interestPacket.setChildSelector(1);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700181
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700182 if (m_minSuffixComponents >= 0)
183 interestPacket.setMinSuffixComponents(m_minSuffixComponents);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700184
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700185 if (m_maxSuffixComponents >= 0)
186 interestPacket.setMaxSuffixComponents(m_maxSuffixComponents);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700187
188 if (m_interestLifetime < time::milliseconds::zero())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700189 interestPacket.setInterestLifetime(getDefaultInterestLifetime());
190 else
191 interestPacket.setInterestLifetime(m_interestLifetime);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700192
Junxiao Shie02fb522015-10-18 08:45:09 -0700193 if (m_isVerbose) {
194 std::cerr << "INTEREST: " << interestPacket << std::endl;
195 }
196
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700197 return interestPacket;
198 }
199
200 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700201 onData(const Interest& interest, Data& data)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700202 {
203 m_isDataReceived = true;
Junxiao Shie02fb522015-10-18 08:45:09 -0700204
205 if (m_isVerbose) {
206 std::cerr << "DATA, RTT: "
207 << time::duration_cast<time::milliseconds>(time::steady_clock::now() - m_expressInterestTime).count()
208 << "ms" << std::endl;
209 }
210
Junxiao Shi0c75f992015-03-24 21:39:47 -0700211 if (m_isPayloadOnlySet) {
212 const Block& block = data.getContent();
213 std::cout.write(reinterpret_cast<const char*>(block.value()), block.value_size());
214 }
215 else {
216 const Block& block = data.wireEncode();
217 std::cout.write(reinterpret_cast<const char*>(block.wire()), block.size());
218 }
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700219 }
220
221 void
Junxiao Shi0c75f992015-03-24 21:39:47 -0700222 onTimeout(const Interest& interest)
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700223 {
224 }
225
226 void
227 run()
228 {
Junxiao Shi0c75f992015-03-24 21:39:47 -0700229 try {
230 m_face.expressInterest(createInterestPacket(),
231 bind(&NdnPeek::onData, this, _1, _2),
232 bind(&NdnPeek::onTimeout, this, _1));
Junxiao Shie02fb522015-10-18 08:45:09 -0700233 m_expressInterestTime = time::steady_clock::now();
Junxiao Shi0c75f992015-03-24 21:39:47 -0700234 if (m_timeout < time::milliseconds::zero()) {
Junxiao Shie02fb522015-10-18 08:45:09 -0700235 m_timeout = m_interestLifetime < time::milliseconds::zero() ?
236 getDefaultInterestLifetime() : m_interestLifetime;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700237 }
Junxiao Shie02fb522015-10-18 08:45:09 -0700238 m_face.processEvents(m_timeout);
Junxiao Shi0c75f992015-03-24 21:39:47 -0700239 }
240 catch (std::exception& e) {
Junxiao Shie02fb522015-10-18 08:45:09 -0700241 std::cerr << "ERROR: " << e.what() << std::endl;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700242 exit(1);
243 }
Junxiao Shie02fb522015-10-18 08:45:09 -0700244 if (m_isVerbose && !m_isDataReceived) {
245 std::cerr << "TIMEOUT" << std::endl;
246 }
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700247 }
248
249 bool
250 isDataReceived() const
251 {
252 return m_isDataReceived;
253 }
254
255private:
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700256 std::string m_programName;
Junxiao Shie02fb522015-10-18 08:45:09 -0700257 bool m_isVerbose;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700258 bool m_mustBeFresh;
259 bool m_isChildSelectorRightmost;
260 int m_minSuffixComponents;
261 int m_maxSuffixComponents;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700262 time::milliseconds m_interestLifetime;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700263 bool m_isPayloadOnlySet;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700264 time::milliseconds m_timeout;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700265 std::string m_prefixName;
Junxiao Shie02fb522015-10-18 08:45:09 -0700266 time::steady_clock::TimePoint m_expressInterestTime;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700267 bool m_isDataReceived;
Junxiao Shi0c75f992015-03-24 21:39:47 -0700268 Face m_face;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700269};
270
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700271int
272main(int argc, char* argv[])
273{
Junxiao Shi0c75f992015-03-24 21:39:47 -0700274 NdnPeek program(argv[0]);
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700275 int option;
Junxiao Shie02fb522015-10-18 08:45:09 -0700276 while ((option = getopt(argc, argv, "hvfrm:M:l:pw:V")) != -1) {
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700277 switch (option) {
278 case 'h':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700279 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700280 break;
Junxiao Shie02fb522015-10-18 08:45:09 -0700281 case 'v':
282 program.setVerbose();
283 break;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700284 case 'f':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700285 program.setMustBeFresh();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700286 break;
287 case 'r':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700288 program.setRightmostChildSelector();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700289 break;
290 case 'm':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700291 program.setMinSuffixComponents(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700292 break;
293 case 'M':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700294 program.setMaxSuffixComponents(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700295 break;
296 case 'l':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700297 program.setInterestLifetime(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700298 break;
299 case 'p':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700300 program.setPayloadOnly();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700301 break;
302 case 'w':
Junxiao Shi0c75f992015-03-24 21:39:47 -0700303 program.setTimeout(atoi(optarg));
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700304 break;
305 case 'V':
Junxiao Shi1753afb2015-04-17 20:59:50 -0700306 std::cout << "ndnpeek " << tools::VERSION << std::endl;
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700307 return 0;
308 default:
Junxiao Shi0c75f992015-03-24 21:39:47 -0700309 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700310 break;
311 }
312 }
313
314 argc -= optind;
315 argv += optind;
316
317 if (argv[0] == 0)
Junxiao Shi0c75f992015-03-24 21:39:47 -0700318 program.usage();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700319
Junxiao Shi0c75f992015-03-24 21:39:47 -0700320 program.setPrefixName(argv[0]);
321 program.run();
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700322
Junxiao Shi0c75f992015-03-24 21:39:47 -0700323 if (program.isDataReceived())
Junxiao Shi2ac79d92015-03-23 11:16:18 -0700324 return 0;
325 else
326 return 1;
327}
Junxiao Shi0c75f992015-03-24 21:39:47 -0700328
329} // namespace peek
330} // namespace ndn
331
332int
333main(int argc, char** argv)
334{
335 return ndn::peek::main(argc, argv);
336}