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