blob: ce34d362650062fb89505a449ede38a2b170eb6d [file] [log] [blame]
Junxiao Shi5109dee2014-03-27 19:40:30 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
Junxiao Shi5109dee2014-03-27 19:40:30 -070011 */
12
13#ifndef NDN_MANAGEMENT_NFD_FORWARDER_STATUS_HPP
14#define NDN_MANAGEMENT_NFD_FORWARDER_STATUS_HPP
15
16#include "../encoding/tlv-nfd.hpp"
Junxiao Shi5109dee2014-03-27 19:40:30 -070017#include "../encoding/encoding-buffer.hpp"
18
19namespace ndn {
20namespace nfd {
21
22/** \brief represents NFD Forwarder Status
23 * \sa http://redmine.named-data.net/projects/nfd/wiki/ForwarderStatus
24 */
25class ForwarderStatus
26{
27public:
28 class Error : public Tlv::Error
29 {
30 public:
31 explicit
32 Error(const std::string& what)
33 : Tlv::Error(what)
34 {
35 }
36 };
37
38 ForwarderStatus();
39
40 explicit
41 ForwarderStatus(const Block& payload)
42 {
43 this->wireDecode(payload);
44 }
45
46 /** \brief prepend ForwarderStatus as a Content block to the encoder
47 *
48 * The outermost Content element isn't part of ForwardStatus structure.
49 */
50 template<bool T>
51 size_t
52 wireEncode(EncodingImpl<T>& encoder) const;
53
54 /** \brief encode ForwarderStatus as a Content block
55 *
56 * The outermost Content element isn't part of ForwardStatus structure.
57 */
58 const Block&
59 wireEncode() const;
60
61 /** \brief decode ForwarderStatus from a Content block
62 *
63 * The outermost Content element isn't part of ForwardStatus structure.
64 */
65 void
66 wireDecode(const Block& wire);
67
68public: // getters & setters
69 int
70 getNfdVersion() const
71 {
72 return m_nfdVersion;
73 }
74
75 ForwarderStatus&
76 setNfdVersion(int nfdVersion)
77 {
78 m_wire.reset();
79 m_nfdVersion = nfdVersion;
80 return *this;
81 }
82
83 const time::system_clock::TimePoint&
84 getStartTimestamp() const
85 {
86 return m_startTimestamp;
87 }
88
89 ForwarderStatus&
90 setStartTimestamp(const time::system_clock::TimePoint& startTimestamp)
91 {
92 m_wire.reset();
93 m_startTimestamp = startTimestamp;
94 return *this;
95 }
96
97 const time::system_clock::TimePoint&
98 getCurrentTimestamp() const
99 {
100 return m_currentTimestamp;
101 }
102
103 ForwarderStatus&
104 setCurrentTimestamp(const time::system_clock::TimePoint& currentTimestamp)
105 {
106 m_wire.reset();
107 m_currentTimestamp = currentTimestamp;
108 return *this;
109 }
110
111 size_t
112 getNNameTreeEntries() const
113 {
114 return m_nNameTreeEntries;
115 }
116
117 ForwarderStatus&
118 setNNameTreeEntries(size_t nNameTreeEntries)
119 {
120 m_wire.reset();
121 m_nNameTreeEntries = nNameTreeEntries;
122 return *this;
123 }
124
125 size_t
126 getNFibEntries() const
127 {
128 return m_nFibEntries;
129 }
130
131 ForwarderStatus&
132 setNFibEntries(size_t nFibEntries)
133 {
134 m_wire.reset();
135 m_nFibEntries = nFibEntries;
136 return *this;
137 }
138
139 size_t
140 getNPitEntries() const
141 {
142 return m_nPitEntries;
143 }
144
145 ForwarderStatus&
146 setNPitEntries(size_t nPitEntries)
147 {
148 m_wire.reset();
149 m_nPitEntries = nPitEntries;
150 return *this;
151 }
152
153 size_t
154 getNMeasurementsEntries() const
155 {
156 return m_nMeasurementsEntries;
157 }
158
159 ForwarderStatus&
160 setNMeasurementsEntries(size_t nMeasurementsEntries)
161 {
162 m_wire.reset();
163 m_nMeasurementsEntries = nMeasurementsEntries;
164 return *this;
165 }
166
167 size_t
168 getNCsEntries() const
169 {
170 return m_nCsEntries;
171 }
172
173 ForwarderStatus&
174 setNCsEntries(size_t nCsEntries)
175 {
176 m_wire.reset();
177 m_nCsEntries = nCsEntries;
178 return *this;
179 }
180
181 uint64_t
182 getNInInterests() const
183 {
184 return m_nInInterests;
185 }
186
187 ForwarderStatus&
188 setNInInterests(uint64_t nInInterests)
189 {
190 m_wire.reset();
191 m_nInInterests = nInInterests;
192 return *this;
193 }
194
195 uint64_t
196 getNInDatas() const
197 {
198 return m_nInDatas;
199 }
200
201 ForwarderStatus&
202 setNInDatas(uint64_t nInDatas)
203 {
204 m_wire.reset();
205 m_nInDatas = nInDatas;
206 return *this;
207 }
208
209 uint64_t
210 getNOutInterests() const
211 {
212 return m_nOutInterests;
213 }
214
215 ForwarderStatus&
216 setNOutInterests(uint64_t nOutInterests)
217 {
218 m_wire.reset();
219 m_nOutInterests = nOutInterests;
220 return *this;
221 }
222
223 uint64_t
224 getNOutDatas() const
225 {
226 return m_nOutDatas;
227 }
228
229 ForwarderStatus&
230 setNOutDatas(uint64_t nOutDatas)
231 {
232 m_wire.reset();
233 m_nOutDatas = nOutDatas;
234 return *this;
235 }
236
237private:
238 int m_nfdVersion;
239 time::system_clock::TimePoint m_startTimestamp;
240 time::system_clock::TimePoint m_currentTimestamp;
241 size_t m_nNameTreeEntries;
242 size_t m_nFibEntries;
243 size_t m_nPitEntries;
244 size_t m_nMeasurementsEntries;
245 size_t m_nCsEntries;
246 uint64_t m_nInInterests;
247 uint64_t m_nInDatas;
248 uint64_t m_nOutInterests;
249 uint64_t m_nOutDatas;
250
251 mutable Block m_wire;
252};
253
254inline
255ForwarderStatus::ForwarderStatus()
256 : m_nfdVersion(0)
257 , m_startTimestamp(time::system_clock::TimePoint::min())
258 , m_currentTimestamp(time::system_clock::TimePoint::min())
259 , m_nNameTreeEntries(0)
260 , m_nFibEntries(0)
261 , m_nPitEntries(0)
262 , m_nMeasurementsEntries(0)
263 , m_nCsEntries(0)
264 , m_nInInterests(0)
265 , m_nInDatas(0)
266 , m_nOutInterests(0)
267 , m_nOutDatas(0)
Junxiao Shi7b1ba1a2014-03-29 01:01:56 -0700268{
269}
Junxiao Shi5109dee2014-03-27 19:40:30 -0700270
271template<bool T>
272inline size_t
273ForwarderStatus::wireEncode(EncodingImpl<T>& encoder) const
274{
275 size_t totalLength = 0;
276
277 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NOutDatas,
278 m_nOutDatas);
279 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NOutInterests,
280 m_nOutInterests);
281 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NInDatas,
282 m_nInDatas);
283 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NInInterests,
284 m_nInInterests);
285 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NCsEntries,
286 m_nCsEntries);
287 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NMeasurementsEntries,
288 m_nMeasurementsEntries);
289 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NPitEntries,
290 m_nPitEntries);
291 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NFibEntries,
292 m_nFibEntries);
293 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NNameTreeEntries,
294 m_nNameTreeEntries);
295 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::CurrentTimestamp,
296 time::toUnixTimestamp(m_currentTimestamp).count());
297 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::StartTimestamp,
298 time::toUnixTimestamp(m_startTimestamp).count());
299 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NfdVersion,
300 m_nfdVersion);
301
302 totalLength += encoder.prependVarNumber(totalLength);
303 totalLength += encoder.prependVarNumber(Tlv::Content);
304 return totalLength;
305}
306
307inline const Block&
308ForwarderStatus::wireEncode() const
309{
310 if (m_wire.hasWire())
311 return m_wire;
312
313 EncodingEstimator estimator;
314 size_t estimatedSize = wireEncode(estimator);
315
316 EncodingBuffer buffer(estimatedSize, 0);
317 wireEncode(buffer);
318
319 m_wire = buffer.block();
320 return m_wire;
321}
322
323inline void
324ForwarderStatus::wireDecode(const Block& block)
325{
Junxiao Shi5109dee2014-03-27 19:40:30 -0700326 if (block.type() != Tlv::Content) {
Junxiao Shi7b1ba1a2014-03-29 01:01:56 -0700327 throw Error("expecting Content block for Status payload");
Junxiao Shi5109dee2014-03-27 19:40:30 -0700328 }
329 m_wire = block;
330 m_wire.parse();
331 Block::element_const_iterator val = m_wire.elements_begin();
332
333 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NfdVersion) {
334 m_nfdVersion = static_cast<int>(readNonNegativeInteger(*val));
335 ++val;
336 }
337 else {
338 throw Error("missing required NfdVersion field");
339 }
340
341 if (val != m_wire.elements_end() && val->type() == tlv::nfd::StartTimestamp) {
342 m_startTimestamp = time::fromUnixTimestamp(time::milliseconds(readNonNegativeInteger(*val)));
343 ++val;
344 }
345 else {
346 throw Error("missing required StartTimestamp field");
347 }
348
349 if (val != m_wire.elements_end() && val->type() == tlv::nfd::CurrentTimestamp) {
350 m_currentTimestamp = time::fromUnixTimestamp(time::milliseconds(readNonNegativeInteger(*val)));
351 ++val;
352 }
353 else {
354 throw Error("missing required CurrentTimestamp field");
355 }
356
357 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NNameTreeEntries) {
358 m_nNameTreeEntries = static_cast<size_t>(readNonNegativeInteger(*val));
359 ++val;
360 }
361 else {
362 throw Error("missing required NNameTreeEntries field");
363 }
364
365 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NFibEntries) {
366 m_nFibEntries = static_cast<size_t>(readNonNegativeInteger(*val));
367 ++val;
368 }
369 else {
370 throw Error("missing required NFibEntries field");
371 }
372
373 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NPitEntries) {
374 m_nPitEntries = static_cast<size_t>(readNonNegativeInteger(*val));
375 ++val;
376 }
377 else {
378 throw Error("missing required NPitEntries field");
379 }
380
381 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NMeasurementsEntries) {
382 m_nMeasurementsEntries = static_cast<size_t>(readNonNegativeInteger(*val));
383 ++val;
384 }
385 else {
386 throw Error("missing required NMeasurementsEntries field");
387 }
388
389 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NCsEntries) {
390 m_nCsEntries = static_cast<size_t>(readNonNegativeInteger(*val));
391 ++val;
392 }
393 else {
394 throw Error("missing required NCsEntries field");
395 }
396
397 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInInterests) {
398 m_nInInterests = static_cast<uint64_t>(readNonNegativeInteger(*val));
399 ++val;
400 }
401 else {
402 throw Error("missing required NInInterests field");
403 }
404
405 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInDatas) {
406 m_nInDatas = static_cast<uint64_t>(readNonNegativeInteger(*val));
407 ++val;
408 }
409 else {
410 throw Error("missing required NInDatas field");
411 }
412
413 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutInterests) {
414 m_nOutInterests = static_cast<uint64_t>(readNonNegativeInteger(*val));
415 ++val;
416 }
417 else {
418 throw Error("missing required NOutInterests field");
419 }
420
421 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutDatas) {
422 m_nOutDatas = static_cast<uint64_t>(readNonNegativeInteger(*val));
423 ++val;
424 }
425 else {
426 throw Error("missing required NOutDatas field");
427 }
428}
429
430} // namespace nfd
431} // namespace ndn
432
433#endif // NDN_MANAGEMENT_NFD_FORWARDER_STATUS_HPP