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