blob: 546009681f148499c888576b37f5ea8e017946b3 [file] [log] [blame]
Junxiao Shi2ac79d92015-03-23 11:16:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * 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
10 *
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/>.
24 *
25 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
26 */
27
28#include "version.hpp"
29
30#include <boost/noncopyable.hpp>
31
32#include <ndn-cxx/face.hpp>
33
34namespace ndntlvpeek {
35
36class NdnTlvPeek : boost::noncopyable
37{
38public:
39 explicit
40 NdnTlvPeek(char* programName)
41 : m_programName(programName)
42 , m_mustBeFresh(false)
43 , m_isChildSelectorRightmost(false)
44 , m_minSuffixComponents(-1)
45 , m_maxSuffixComponents(-1)
46 , m_interestLifetime(-1)
47 , m_isPayloadOnlySet(false)
48 , m_timeout(-1)
49 , m_prefixName("")
50 , m_isDataReceived(false)
51 {
52 }
53
54 void
55 usage()
56 {
57 std::cout << "\n Usage:\n " << m_programName << " "
58 "[-f] [-r] [-m min] [-M max] [-l lifetime] [-p] [-w timeout] ndn:/name\n"
59 " Get one data item matching the name prefix and write it to stdout\n"
60 " [-f] - set MustBeFresh\n"
61 " [-r] - set ChildSelector to select rightmost child\n"
62 " [-m min] - set MinSuffixComponents\n"
63 " [-M max] - set MaxSuffixComponents\n"
64 " [-l lifetime] - set InterestLifetime in time::milliseconds\n"
65 " [-p] - print payload only, not full packet\n"
66 " [-w timeout] - set Timeout in time::milliseconds\n"
67 " [-h] - print help and exit\n"
68 " [-V] - print version and exit\n"
69 "\n";
70 exit(1);
71 }
72
73 void
74 setMustBeFresh()
75 {
76 m_mustBeFresh = true;
77 }
78
79 void
80 setRightmostChildSelector()
81 {
82 m_isChildSelectorRightmost = true;
83 }
84
85 void
86 setMinSuffixComponents(int minSuffixComponents)
87 {
88 if (minSuffixComponents < 0)
89 usage();
90 m_minSuffixComponents = minSuffixComponents;
91 }
92
93 void
94 setMaxSuffixComponents(int maxSuffixComponents)
95 {
96 if (maxSuffixComponents < 0)
97 usage();
98 m_maxSuffixComponents = maxSuffixComponents;
99 }
100
101 void
102 setInterestLifetime(int interestLifetime)
103 {
104 if (interestLifetime < 0)
105 usage();
106 m_interestLifetime = ndn::time::milliseconds(interestLifetime);
107 }
108
109 void
110 setPayloadOnly()
111 {
112 m_isPayloadOnlySet = true;
113 }
114
115 void
116 setTimeout(int timeout)
117 {
118 if (timeout < 0)
119 usage();
120 m_timeout = ndn::time::milliseconds(timeout);
121 }
122
123 void
124 setPrefixName(char* prefixName)
125 {
126 m_prefixName = prefixName;
127 if (m_prefixName.length() == 0)
128 usage();
129 }
130
131 ndn::time::milliseconds
132 getDefaultInterestLifetime()
133 {
134 return ndn::time::seconds(4);
135 }
136
137 ndn::Interest
138 createInterestPacket()
139 {
140 ndn::Name interestName(m_prefixName);
141 ndn::Interest interestPacket(interestName);
142 if (m_mustBeFresh)
143 interestPacket.setMustBeFresh(true);
144 if (m_isChildSelectorRightmost)
145 interestPacket.setChildSelector(1);
146 if (m_minSuffixComponents >= 0)
147 interestPacket.setMinSuffixComponents(m_minSuffixComponents);
148 if (m_maxSuffixComponents >= 0)
149 interestPacket.setMaxSuffixComponents(m_maxSuffixComponents);
150 if (m_interestLifetime < ndn::time::milliseconds::zero())
151 interestPacket.setInterestLifetime(getDefaultInterestLifetime());
152 else
153 interestPacket.setInterestLifetime(m_interestLifetime);
154 return interestPacket;
155 }
156
157 void
158 onData(const ndn::Interest& interest, ndn::Data& data)
159 {
160 m_isDataReceived = true;
161 if (m_isPayloadOnlySet)
162 {
163 const ndn::Block& block = data.getContent();
164 std::cout.write(reinterpret_cast<const char*>(block.value()), block.value_size());
165 }
166 else
167 {
168 const ndn::Block& block = data.wireEncode();
169 std::cout.write(reinterpret_cast<const char*>(block.wire()), block.size());
170 }
171 }
172
173 void
174 onTimeout(const ndn::Interest& interest)
175 {
176 }
177
178 void
179 run()
180 {
181 try
182 {
183 m_face.expressInterest(createInterestPacket(),
184 bind(&NdnTlvPeek::onData, this, _1, _2),
185 bind(&NdnTlvPeek::onTimeout, this, _1));
186 if (m_timeout < ndn::time::milliseconds::zero())
187 {
188 if (m_interestLifetime < ndn::time::milliseconds::zero())
189 m_face.processEvents(getDefaultInterestLifetime());
190 else
191 m_face.processEvents(m_interestLifetime);
192 }
193 else
194 m_face.processEvents(m_timeout);
195 }
196 catch (std::exception& e)
197 {
198 std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
199 exit(1);
200 }
201 }
202
203 bool
204 isDataReceived() const
205 {
206 return m_isDataReceived;
207 }
208
209private:
210
211 std::string m_programName;
212 bool m_mustBeFresh;
213 bool m_isChildSelectorRightmost;
214 int m_minSuffixComponents;
215 int m_maxSuffixComponents;
216 ndn::time::milliseconds m_interestLifetime;
217 bool m_isPayloadOnlySet;
218 ndn::time::milliseconds m_timeout;
219 std::string m_prefixName;
220 bool m_isDataReceived;
221 ndn::Face m_face;
222};
223
224}
225
226int
227main(int argc, char* argv[])
228{
229 ndntlvpeek::NdnTlvPeek ndnTlvPeek(argv[0]);
230 int option;
231 while ((option = getopt(argc, argv, "hfrm:M:l:pw:V")) != -1) {
232 switch (option) {
233 case 'h':
234 ndnTlvPeek.usage();
235 break;
236 case 'f':
237 ndnTlvPeek.setMustBeFresh();
238 break;
239 case 'r':
240 ndnTlvPeek.setRightmostChildSelector();
241 break;
242 case 'm':
243 ndnTlvPeek.setMinSuffixComponents(atoi(optarg));
244 break;
245 case 'M':
246 ndnTlvPeek.setMaxSuffixComponents(atoi(optarg));
247 break;
248 case 'l':
249 ndnTlvPeek.setInterestLifetime(atoi(optarg));
250 break;
251 case 'p':
252 ndnTlvPeek.setPayloadOnly();
253 break;
254 case 'w':
255 ndnTlvPeek.setTimeout(atoi(optarg));
256 break;
257 case 'V':
258 std::cout << NFD_VERSION_BUILD_STRING << std::endl;
259 return 0;
260 default:
261 ndnTlvPeek.usage();
262 break;
263 }
264 }
265
266 argc -= optind;
267 argv += optind;
268
269 if (argv[0] == 0)
270 ndnTlvPeek.usage();
271
272 ndnTlvPeek.setPrefixName(argv[0]);
273 ndnTlvPeek.run();
274
275 if (ndnTlvPeek.isDataReceived())
276 return 0;
277 else
278 return 1;
279}