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