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