blob: 457c6736bd356cb4d963cc5e6bd15951d89ca65e [file] [log] [blame]
Junxiao Shi65f1a712014-11-20 14:59:36 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * 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.
20 */
21
22#include "nfd-forwarder-status.hpp"
23#include "encoding/tlv-nfd.hpp"
24#include "encoding/block-helpers.hpp"
25#include "util/concepts.hpp"
26
27namespace ndn {
28namespace nfd {
29
30//BOOST_CONCEPT_ASSERT((boost::EqualityComparable<ForwarderStatus>));
31BOOST_CONCEPT_ASSERT((WireEncodable<ForwarderStatus>));
32BOOST_CONCEPT_ASSERT((WireDecodable<ForwarderStatus>));
33static_assert(std::is_base_of<tlv::Error, ForwarderStatus::Error>::value,
34 "ForwarderStatus::Error must inherit from tlv::Error");
35
36ForwarderStatus::ForwarderStatus()
37 : m_nfdVersion(0)
38 , m_startTimestamp(time::system_clock::TimePoint::min())
39 , m_currentTimestamp(time::system_clock::TimePoint::min())
40 , m_nNameTreeEntries(0)
41 , m_nFibEntries(0)
42 , m_nPitEntries(0)
43 , m_nMeasurementsEntries(0)
44 , m_nCsEntries(0)
45 , m_nInInterests(0)
46 , m_nInDatas(0)
47 , m_nOutInterests(0)
48 , m_nOutDatas(0)
49{
50}
51
52ForwarderStatus::ForwarderStatus(const Block& payload)
53{
54 this->wireDecode(payload);
55}
56
57template<bool T>
58size_t
59ForwarderStatus::wireEncode(EncodingImpl<T>& encoder) const
60{
61 size_t totalLength = 0;
62
63 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NOutDatas,
64 m_nOutDatas);
65 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NOutInterests,
66 m_nOutInterests);
67 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NInDatas,
68 m_nInDatas);
69 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NInInterests,
70 m_nInInterests);
71 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NCsEntries,
72 m_nCsEntries);
73 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NMeasurementsEntries,
74 m_nMeasurementsEntries);
75 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NPitEntries,
76 m_nPitEntries);
77 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NFibEntries,
78 m_nFibEntries);
79 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NNameTreeEntries,
80 m_nNameTreeEntries);
81 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::CurrentTimestamp,
82 time::toUnixTimestamp(m_currentTimestamp).count());
83 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::StartTimestamp,
84 time::toUnixTimestamp(m_startTimestamp).count());
85 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NfdVersion,
86 m_nfdVersion);
87
88 totalLength += encoder.prependVarNumber(totalLength);
89 totalLength += encoder.prependVarNumber(tlv::Content);
90 return totalLength;
91}
92
93template size_t
94ForwarderStatus::wireEncode<true>(EncodingImpl<true>& block) const;
95
96template size_t
97ForwarderStatus::wireEncode<false>(EncodingImpl<false>& block) const;
98
99const Block&
100ForwarderStatus::wireEncode() const
101{
102 if (m_wire.hasWire())
103 return m_wire;
104
105 EncodingEstimator estimator;
106 size_t estimatedSize = wireEncode(estimator);
107
108 EncodingBuffer buffer(estimatedSize, 0);
109 wireEncode(buffer);
110
111 m_wire = buffer.block();
112 return m_wire;
113}
114
115void
116ForwarderStatus::wireDecode(const Block& block)
117{
118 if (block.type() != tlv::Content) {
119 throw Error("expecting Content block for Status payload");
120 }
121 m_wire = block;
122 m_wire.parse();
123 Block::element_const_iterator val = m_wire.elements_begin();
124
125 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NfdVersion) {
126 m_nfdVersion = static_cast<int>(readNonNegativeInteger(*val));
127 ++val;
128 }
129 else {
130 throw Error("missing required NfdVersion field");
131 }
132
133 if (val != m_wire.elements_end() && val->type() == tlv::nfd::StartTimestamp) {
134 m_startTimestamp = time::fromUnixTimestamp(time::milliseconds(readNonNegativeInteger(*val)));
135 ++val;
136 }
137 else {
138 throw Error("missing required StartTimestamp field");
139 }
140
141 if (val != m_wire.elements_end() && val->type() == tlv::nfd::CurrentTimestamp) {
142 m_currentTimestamp = time::fromUnixTimestamp(time::milliseconds(readNonNegativeInteger(*val)));
143 ++val;
144 }
145 else {
146 throw Error("missing required CurrentTimestamp field");
147 }
148
149 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NNameTreeEntries) {
150 m_nNameTreeEntries = static_cast<size_t>(readNonNegativeInteger(*val));
151 ++val;
152 }
153 else {
154 throw Error("missing required NNameTreeEntries field");
155 }
156
157 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NFibEntries) {
158 m_nFibEntries = static_cast<size_t>(readNonNegativeInteger(*val));
159 ++val;
160 }
161 else {
162 throw Error("missing required NFibEntries field");
163 }
164
165 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NPitEntries) {
166 m_nPitEntries = static_cast<size_t>(readNonNegativeInteger(*val));
167 ++val;
168 }
169 else {
170 throw Error("missing required NPitEntries field");
171 }
172
173 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NMeasurementsEntries) {
174 m_nMeasurementsEntries = static_cast<size_t>(readNonNegativeInteger(*val));
175 ++val;
176 }
177 else {
178 throw Error("missing required NMeasurementsEntries field");
179 }
180
181 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NCsEntries) {
182 m_nCsEntries = static_cast<size_t>(readNonNegativeInteger(*val));
183 ++val;
184 }
185 else {
186 throw Error("missing required NCsEntries field");
187 }
188
189 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInInterests) {
190 m_nInInterests = static_cast<uint64_t>(readNonNegativeInteger(*val));
191 ++val;
192 }
193 else {
194 throw Error("missing required NInInterests field");
195 }
196
197 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInDatas) {
198 m_nInDatas = static_cast<uint64_t>(readNonNegativeInteger(*val));
199 ++val;
200 }
201 else {
202 throw Error("missing required NInDatas field");
203 }
204
205 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutInterests) {
206 m_nOutInterests = static_cast<uint64_t>(readNonNegativeInteger(*val));
207 ++val;
208 }
209 else {
210 throw Error("missing required NOutInterests field");
211 }
212
213 if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutDatas) {
214 m_nOutDatas = static_cast<uint64_t>(readNonNegativeInteger(*val));
215 ++val;
216 }
217 else {
218 throw Error("missing required NOutDatas field");
219 }
220}
221
222ForwarderStatus&
223ForwarderStatus::setNfdVersion(int nfdVersion)
224{
225 m_wire.reset();
226 m_nfdVersion = nfdVersion;
227 return *this;
228}
229
230ForwarderStatus&
231ForwarderStatus::setStartTimestamp(const time::system_clock::TimePoint& startTimestamp)
232{
233 m_wire.reset();
234 m_startTimestamp = startTimestamp;
235 return *this;
236}
237
238ForwarderStatus&
239ForwarderStatus::setCurrentTimestamp(const time::system_clock::TimePoint& currentTimestamp)
240{
241 m_wire.reset();
242 m_currentTimestamp = currentTimestamp;
243 return *this;
244}
245
246ForwarderStatus&
247ForwarderStatus::setNNameTreeEntries(size_t nNameTreeEntries)
248{
249 m_wire.reset();
250 m_nNameTreeEntries = nNameTreeEntries;
251 return *this;
252}
253
254ForwarderStatus&
255ForwarderStatus::setNFibEntries(size_t nFibEntries)
256{
257 m_wire.reset();
258 m_nFibEntries = nFibEntries;
259 return *this;
260}
261
262ForwarderStatus&
263ForwarderStatus::setNPitEntries(size_t nPitEntries)
264{
265 m_wire.reset();
266 m_nPitEntries = nPitEntries;
267 return *this;
268}
269
270ForwarderStatus&
271ForwarderStatus::setNMeasurementsEntries(size_t nMeasurementsEntries)
272{
273 m_wire.reset();
274 m_nMeasurementsEntries = nMeasurementsEntries;
275 return *this;
276}
277
278ForwarderStatus&
279ForwarderStatus::setNCsEntries(size_t nCsEntries)
280{
281 m_wire.reset();
282 m_nCsEntries = nCsEntries;
283 return *this;
284}
285
286ForwarderStatus&
287ForwarderStatus::setNInInterests(uint64_t nInInterests)
288{
289 m_wire.reset();
290 m_nInInterests = nInInterests;
291 return *this;
292}
293
294ForwarderStatus&
295ForwarderStatus::setNInDatas(uint64_t nInDatas)
296{
297 m_wire.reset();
298 m_nInDatas = nInDatas;
299 return *this;
300}
301
302ForwarderStatus&
303ForwarderStatus::setNOutInterests(uint64_t nOutInterests)
304{
305 m_wire.reset();
306 m_nOutInterests = nOutInterests;
307 return *this;
308}
309
310ForwarderStatus&
311ForwarderStatus::setNOutDatas(uint64_t nOutDatas)
312{
313 m_wire.reset();
314 m_nOutDatas = nOutDatas;
315 return *this;
316}
317
318} // namespace nfd
319} // namespace ndn