blob: 51a12d9edb8657822165c27afab8419fc4bab80c [file] [log] [blame]
jeraldabraham8d840002014-03-16 19:52:09 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2014 University of Arizona.
4 *
5 * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
6 */
7
8#include <boost/utility.hpp>
9
10#include <ndn-cpp-dev/face.hpp>
11#include <ndn-cpp-dev/security/key-chain.hpp>
12
13namespace ndntlvpoke {
14
15class NdnTlvPoke : boost::noncopyable
16{
17
18public:
19
20 explicit
21 NdnTlvPoke(char* programName)
22 : m_programName(programName)
23 , m_isForceDataSet(false)
24 , m_isUseDigestSha256Set(false)
25 , m_isLastAsFinalBlockIdSet(false)
26 , m_freshnessPeriod(-1)
27 , m_timeout(-1)
28 , m_isDataSent(false)
29 {
30 }
31
32 void
33 usage()
34 {
35 std::cout << "\n Usage:\n " << m_programName << " "
36 "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
37 " Reads payload from stdin and sends it to local NDN forwarder as a "
38 "single Data packet\n"
39 " [-f] - force, send Data without waiting for Interest\n"
40 " [-D] - use DigestSha256 signing method instead of "
41 "SignatureSha256WithRsa\n"
42 " [-i identity] - set identity to be used for signing\n"
43 " [-F] - set FinalBlockId to the last component of Name\n"
44 " [-x] - set FreshnessPeriod in milliseconds\n"
45 " [-w timeout] - set Timeout in milliseconds\n"
46 " [-h] - print help and exit\n\n";
47 exit(1);
48 }
49
50 void
51 setForceData()
52 {
53 m_isForceDataSet = true;
54 }
55
56 void
57 setUseDigestSha256()
58 {
59 m_isUseDigestSha256Set = true;
60 }
61
62 void
63 setIdentityName(char* identityName)
64 {
65 m_identityName = ndn::make_shared<ndn::Name>(identityName);
66 }
67
68 void
69 setLastAsFinalBlockId()
70 {
71 m_isLastAsFinalBlockIdSet = true;
72 }
73
74 void
75 setFreshnessPeriod(int freshnessPeriod)
76 {
77 if (freshnessPeriod < 0)
78 usage();
79 m_freshnessPeriod = freshnessPeriod;
80 }
81
82 void
83 setTimeout(int timeout)
84 {
85 if (timeout < 0)
86 usage();
87 m_timeout = timeout;
88 }
89
90 void
91 setPrefixName(char* prefixName)
92 {
93 m_prefixName = ndn::Name(prefixName);
94 }
95
96 ndn::Milliseconds
97 getDefaultTimeout()
98 {
99 return 10000;
100 }
101
102 ndn::Data
103 createDataPacket()
104 {
105 ndn::Data dataPacket(m_prefixName);
106 std::stringstream payloadStream;
107 payloadStream << std::cin.rdbuf();
108 std::string payload = payloadStream.str();
109 dataPacket.setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
110 if (m_freshnessPeriod >= 0)
111 dataPacket.setFreshnessPeriod(m_freshnessPeriod);
112 if (m_isLastAsFinalBlockIdSet)
113 {
114 if (!m_prefixName.empty())
115 dataPacket.setFinalBlockId(m_prefixName.get(-1));
116 else
117 {
118 std::cerr << "Name Provided Has 0 Components" << std::endl;
119 exit(1);
120 }
121 }
122 if (m_isUseDigestSha256Set)
123 m_keyChain.signWithSha256(dataPacket);
124 else
125 {
126 if (!static_cast<bool>(m_identityName))
127 m_keyChain.sign(dataPacket);
128 else
129 m_keyChain.signByIdentity(dataPacket, *m_identityName);
130 }
131 return dataPacket;
132 }
133
134 void
135 onInterest(const ndn::Name& name,
136 const ndn::Interest& interest,
137 const ndn::Data& dataPacket)
138 {
139 m_face.put(dataPacket);
140 m_isDataSent = true;
141 m_face.shutdown();
142 }
143
144 void
145 onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
146 {
147 std::cerr << "Prefix Registration Failure." << std::endl;
148 std::cerr << "Reason = " << reason << std::endl;
149 }
150
151 void
152 run()
153 {
154 try
155 {
156 ndn::Data dataPacket = createDataPacket();
157 if (m_isForceDataSet)
158 {
159 m_face.put(dataPacket);
160 m_isDataSent = true;
161 }
162 else
163 {
164 m_face.setInterestFilter(m_prefixName,
165 ndn::func_lib::bind(&NdnTlvPoke::onInterest,
166 this, _1, _2, dataPacket),
167 ndn::func_lib::bind(&NdnTlvPoke::onRegisterFailed,
168 this, _1, _2));
169 }
170 if (m_timeout < 0)
171 m_face.processEvents(getDefaultTimeout());
172 else
173 m_face.processEvents(m_timeout);
174 }
175 catch (std::exception& e)
176 {
177 std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
178 exit(1);
179 }
180 }
181
182 bool
183 isDataSent() const
184 {
185 return m_isDataSent;
186 }
187
188private:
189
190 ndn::KeyChain m_keyChain;
191 std::string m_programName;
192 bool m_isForceDataSet;
193 bool m_isUseDigestSha256Set;
194 ndn::shared_ptr<ndn::Name> m_identityName;
195 bool m_isLastAsFinalBlockIdSet;
196 ndn::Milliseconds m_freshnessPeriod;
197 ndn::Milliseconds m_timeout;
198 ndn::Name m_prefixName;
199 bool m_isDataSent;
200 ndn::Face m_face;
201
202};
203
204}
205
206int
207main(int argc, char* argv[])
208{
209 int option;
210 ndntlvpoke::NdnTlvPoke ndnTlvPoke(argv[0]);
211 while ((option = getopt(argc, argv, "hfDi:Fx:w:")) != -1)
212 {
213 switch (option) {
214 case 'h':
215 ndnTlvPoke.usage();
216 break;
217 case 'f':
218 ndnTlvPoke.setForceData();
219 break;
220 case 'D':
221 ndnTlvPoke.setUseDigestSha256();
222 break;
223 case 'i':
224 ndnTlvPoke.setIdentityName(optarg);
225 break;
226 case 'F':
227 ndnTlvPoke.setLastAsFinalBlockId();
228 break;
229 case 'x':
230 ndnTlvPoke.setFreshnessPeriod(atoi(optarg));
231 break;
232 case 'w':
233 ndnTlvPoke.setTimeout(atoi(optarg));
234 break;
235 default:
236 ndnTlvPoke.usage();
237 break;
238 }
239 }
240
241 argc -= optind;
242 argv += optind;
243
244 if (argv[0] == 0)
245 ndnTlvPoke.usage();
246
247 ndnTlvPoke.setPrefixName(argv[0]);
248 ndnTlvPoke.run();
249
250 if (ndnTlvPoke.isDataSent())
251 return 0;
252 else
253 return 1;
254}