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