face-status.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2018 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 "face-status.hpp"
25 #include "encoding/tlv-nfd.hpp"
26 #include "util/concepts.hpp"
27 #include "util/string-helper.hpp"
28 
29 namespace ndn {
30 namespace nfd {
31 
32 BOOST_CONCEPT_ASSERT((StatusDatasetItem<FaceStatus>));
33 
35  : m_nInInterests(0)
36  , m_nInData(0)
37  , m_nInNacks(0)
38  , m_nOutInterests(0)
39  , m_nOutData(0)
40  , m_nOutNacks(0)
41  , m_nInBytes(0)
42  , m_nOutBytes(0)
43 {
44 }
45 
47 {
48  this->wireDecode(block);
49 }
50 
51 template<encoding::Tag TAG>
52 size_t
53 FaceStatus::wireEncode(EncodingImpl<TAG>& encoder) const
54 {
55  size_t totalLength = 0;
56 
57  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Flags, m_flags);
58  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NOutBytes, m_nOutBytes);
59  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NInBytes, m_nInBytes);
60  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NOutNacks, m_nOutNacks);
61  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NOutData, m_nOutData);
62  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NOutInterests, m_nOutInterests);
63  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NInNacks, m_nInNacks);
64  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NInData, m_nInData);
65  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NInInterests, m_nInInterests);
66  if (m_defaultCongestionThreshold) {
68  *m_defaultCongestionThreshold);
69  }
70  if (m_baseCongestionMarkingInterval) {
72  m_baseCongestionMarkingInterval->count());
73  }
77  if (m_expirationPeriod) {
79  m_expirationPeriod->count());
80  }
81  totalLength += prependStringBlock(encoder, tlv::nfd::LocalUri, m_localUri);
82  totalLength += prependStringBlock(encoder, tlv::nfd::Uri, m_remoteUri);
84 
85  totalLength += encoder.prependVarNumber(totalLength);
86  totalLength += encoder.prependVarNumber(tlv::nfd::FaceStatus);
87  return totalLength;
88 }
89 
91 
92 const Block&
94 {
95  if (m_wire.hasWire())
96  return m_wire;
97 
98  EncodingEstimator estimator;
99  size_t estimatedSize = wireEncode(estimator);
100 
101  EncodingBuffer buffer(estimatedSize, 0);
102  wireEncode(buffer);
103 
104  m_wire = buffer.block();
105  return m_wire;
106 }
107 
108 void
110 {
111  if (block.type() != tlv::nfd::FaceStatus) {
112  BOOST_THROW_EXCEPTION(Error("expecting FaceStatus block"));
113  }
114  m_wire = block;
115  m_wire.parse();
117 
118  if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceId) {
120  ++val;
121  }
122  else {
123  BOOST_THROW_EXCEPTION(Error("missing required FaceId field"));
124  }
125 
126  if (val != m_wire.elements_end() && val->type() == tlv::nfd::Uri) {
127  m_remoteUri = readString(*val);
128  ++val;
129  }
130  else {
131  BOOST_THROW_EXCEPTION(Error("missing required Uri field"));
132  }
133 
134  if (val != m_wire.elements_end() && val->type() == tlv::nfd::LocalUri) {
135  m_localUri = readString(*val);
136  ++val;
137  }
138  else {
139  BOOST_THROW_EXCEPTION(Error("missing required LocalUri field"));
140  }
141 
142  if (val != m_wire.elements_end() && val->type() == tlv::nfd::ExpirationPeriod) {
143  m_expirationPeriod.emplace(readNonNegativeInteger(*val));
144  ++val;
145  }
146  else {
147  m_expirationPeriod = nullopt;
148  }
149 
150  if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceScope) {
151  m_faceScope = readNonNegativeIntegerAs<FaceScope>(*val);
152  ++val;
153  }
154  else {
155  BOOST_THROW_EXCEPTION(Error("missing required FaceScope field"));
156  }
157 
158  if (val != m_wire.elements_end() && val->type() == tlv::nfd::FacePersistency) {
159  m_facePersistency = readNonNegativeIntegerAs<FacePersistency>(*val);
160  ++val;
161  }
162  else {
163  BOOST_THROW_EXCEPTION(Error("missing required FacePersistency field"));
164  }
165 
166  if (val != m_wire.elements_end() && val->type() == tlv::nfd::LinkType) {
167  m_linkType = readNonNegativeIntegerAs<LinkType>(*val);
168  ++val;
169  }
170  else {
171  BOOST_THROW_EXCEPTION(Error("missing required LinkType field"));
172  }
173 
174  if (val != m_wire.elements_end() && val->type() == tlv::nfd::BaseCongestionMarkingInterval) {
175  m_baseCongestionMarkingInterval.emplace(readNonNegativeInteger(*val));
176  ++val;
177  }
178  else {
179  m_baseCongestionMarkingInterval = nullopt;
180  }
181 
182  if (val != m_wire.elements_end() && val->type() == tlv::nfd::DefaultCongestionThreshold) {
183  m_defaultCongestionThreshold = readNonNegativeInteger(*val);
184  ++val;
185  }
186  else {
187  m_defaultCongestionThreshold = nullopt;
188  }
189 
190  if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInInterests) {
191  m_nInInterests = readNonNegativeInteger(*val);
192  ++val;
193  }
194  else {
195  BOOST_THROW_EXCEPTION(Error("missing required NInInterests field"));
196  }
197 
198  if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInData) {
199  m_nInData = readNonNegativeInteger(*val);
200  ++val;
201  }
202  else {
203  BOOST_THROW_EXCEPTION(Error("missing required NInData field"));
204  }
205 
206  if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInNacks) {
207  m_nInNacks = readNonNegativeInteger(*val);
208  ++val;
209  }
210  else {
211  BOOST_THROW_EXCEPTION(Error("missing required NInNacks field"));
212  }
213 
214  if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutInterests) {
215  m_nOutInterests = readNonNegativeInteger(*val);
216  ++val;
217  }
218  else {
219  BOOST_THROW_EXCEPTION(Error("missing required NOutInterests field"));
220  }
221 
222  if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutData) {
223  m_nOutData = readNonNegativeInteger(*val);
224  ++val;
225  }
226  else {
227  BOOST_THROW_EXCEPTION(Error("missing required NOutData field"));
228  }
229 
230  if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutNacks) {
231  m_nOutNacks = readNonNegativeInteger(*val);
232  ++val;
233  }
234  else {
235  BOOST_THROW_EXCEPTION(Error("missing required NOutNacks field"));
236  }
237 
238  if (val != m_wire.elements_end() && val->type() == tlv::nfd::NInBytes) {
239  m_nInBytes = readNonNegativeInteger(*val);
240  ++val;
241  }
242  else {
243  BOOST_THROW_EXCEPTION(Error("missing required NInBytes field"));
244  }
245 
246  if (val != m_wire.elements_end() && val->type() == tlv::nfd::NOutBytes) {
247  m_nOutBytes = readNonNegativeInteger(*val);
248  ++val;
249  }
250  else {
251  BOOST_THROW_EXCEPTION(Error("missing required NOutBytes field"));
252  }
253 
254  if (val != m_wire.elements_end() && val->type() == tlv::nfd::Flags) {
256  ++val;
257  }
258  else {
259  BOOST_THROW_EXCEPTION(Error("missing required Flags field"));
260  }
261 }
262 
263 FaceStatus&
264 FaceStatus::setExpirationPeriod(time::milliseconds expirationPeriod)
265 {
266  m_wire.reset();
267  m_expirationPeriod = expirationPeriod;
268  return *this;
269 }
270 
271 FaceStatus&
273 {
274  m_wire.reset();
275  m_expirationPeriod = nullopt;
276  return *this;
277 }
278 
279 FaceStatus&
281 {
282  m_wire.reset();
283  m_baseCongestionMarkingInterval = interval;
284  return *this;
285 }
286 
287 FaceStatus&
289 {
290  m_wire.reset();
291  m_baseCongestionMarkingInterval = nullopt;
292  return *this;
293 }
294 
295 FaceStatus&
297 {
298  m_wire.reset();
299  m_defaultCongestionThreshold = threshold;
300  return *this;
301 }
302 
303 FaceStatus&
305 {
306  m_wire.reset();
307  m_defaultCongestionThreshold = nullopt;
308  return *this;
309 }
310 
311 FaceStatus&
312 FaceStatus::setNInInterests(uint64_t nInInterests)
313 {
314  m_wire.reset();
315  m_nInInterests = nInInterests;
316  return *this;
317 }
318 
319 FaceStatus&
320 FaceStatus::setNInData(uint64_t nInData)
321 {
322  m_wire.reset();
323  m_nInData = nInData;
324  return *this;
325 }
326 
327 FaceStatus&
328 FaceStatus::setNInNacks(uint64_t nInNacks)
329 {
330  m_wire.reset();
331  m_nInNacks = nInNacks;
332  return *this;
333 }
334 
335 FaceStatus&
336 FaceStatus::setNOutInterests(uint64_t nOutInterests)
337 {
338  m_wire.reset();
339  m_nOutInterests = nOutInterests;
340  return *this;
341 }
342 
343 FaceStatus&
344 FaceStatus::setNOutData(uint64_t nOutData)
345 {
346  m_wire.reset();
347  m_nOutData = nOutData;
348  return *this;
349 }
350 
351 FaceStatus&
352 FaceStatus::setNOutNacks(uint64_t nOutNacks)
353 {
354  m_wire.reset();
355  m_nOutNacks = nOutNacks;
356  return *this;
357 }
358 
359 FaceStatus&
360 FaceStatus::setNInBytes(uint64_t nInBytes)
361 {
362  m_wire.reset();
363  m_nInBytes = nInBytes;
364  return *this;
365 }
366 
367 FaceStatus&
368 FaceStatus::setNOutBytes(uint64_t nOutBytes)
369 {
370  m_wire.reset();
371  m_nOutBytes = nOutBytes;
372  return *this;
373 }
374 
375 bool
376 operator==(const FaceStatus& a, const FaceStatus& b)
377 {
378  return a.getFaceId() == b.getFaceId() &&
379  a.getRemoteUri() == b.getRemoteUri() &&
380  a.getLocalUri() == b.getLocalUri() &&
381  a.getFaceScope() == b.getFaceScope() &&
383  a.getLinkType() == b.getLinkType() &&
384  a.getFlags() == b.getFlags() &&
393  a.getNInInterests() == b.getNInInterests() &&
394  a.getNInData() == b.getNInData() &&
395  a.getNInNacks() == b.getNInNacks() &&
396  a.getNOutInterests() == b.getNOutInterests() &&
397  a.getNOutData() == b.getNOutData() &&
398  a.getNOutNacks() == b.getNOutNacks() &&
399  a.getNInBytes() == b.getNInBytes() &&
400  a.getNOutBytes() == b.getNOutBytes();
401 }
402 
403 std::ostream&
404 operator<<(std::ostream& os, const FaceStatus& status)
405 {
406  os << "Face(FaceId: " << status.getFaceId() << ",\n"
407  << " RemoteUri: " << status.getRemoteUri() << ",\n"
408  << " LocalUri: " << status.getLocalUri() << ",\n";
409 
410  if (status.hasExpirationPeriod()) {
411  os << " ExpirationPeriod: " << status.getExpirationPeriod() << ",\n";
412  }
413  else {
414  os << " ExpirationPeriod: infinite,\n";
415  }
416 
417  os << " FaceScope: " << status.getFaceScope() << ",\n"
418  << " FacePersistency: " << status.getFacePersistency() << ",\n"
419  << " LinkType: " << status.getLinkType() << ",\n";
420 
421  if (status.hasBaseCongestionMarkingInterval()) {
422  os << " BaseCongestionMarkingInterval: " << status.getBaseCongestionMarkingInterval() << ",\n";
423  }
424 
425  if (status.hasDefaultCongestionThreshold()) {
426  os << " DefaultCongestionThreshold: " << status.getDefaultCongestionThreshold() << " bytes,\n";
427  }
428 
429  os << " Flags: " << AsHex{status.getFlags()} << ",\n"
430  << " Counters: {Interests: {in: " << status.getNInInterests() << ", "
431  << "out: " << status.getNOutInterests() << "},\n"
432  << " Data: {in: " << status.getNInData() << ", "
433  << "out: " << status.getNOutData() << "},\n"
434  << " Nacks: {in: " << status.getNInNacks() << ", "
435  << "out: " << status.getNOutNacks() << "},\n"
436  << " bytes: {in: " << status.getNInBytes() << ", "
437  << "out: " << status.getNOutBytes() << "}}\n";
438 
439  return os << " )";
440 }
441 
442 } // namespace nfd
443 } // namespace ndn
constexpr nullopt_t nullopt
uint64_t getNInNacks() const
void wireDecode(const Block &wire)
decode FaceStatus
LinkType getLinkType() const
Copyright (c) 2013-2017 Regents of the University of California.
Definition: common.hpp:66
bool hasDefaultCongestionThreshold() const
size_t prependNonNegativeIntegerBlock(EncodingImpl< TAG > &encoder, uint32_t type, uint64_t value)
Prepend a TLV element containing a non-negative integer.
uint64_t getFlags() const
bool hasExpirationPeriod() const
Definition: face-status.hpp:62
FaceScope getFaceScope() const
Definition: face-traits.hpp:93
element_container::const_iterator element_const_iterator
Definition: block.hpp:47
time::milliseconds getExpirationPeriod() const
Definition: face-status.hpp:68
Helper class to convert a number to hexadecimal format, for use with stream insertion operators...
FaceStatus & unsetDefaultCongestionThreshold()
Represents a TLV element of NDN packet format.
Definition: block.hpp:42
size_t prependStringBlock(EncodingImpl< TAG > &encoder, uint32_t type, const std::string &value)
Prepend a TLV element containing a string.
std::string readString(const Block &block)
Read TLV-VALUE of a TLV element as a string.
uint64_t getDefaultCongestionThreshold() const
get default congestion threshold (measured in bytes)
FaceStatus & setNOutBytes(uint64_t nOutBytes)
FaceStatus & setNOutInterests(uint64_t nOutInterests)
void emplace(Args &&...args)
uint64_t readNonNegativeInteger(const Block &block)
Read a non-negative integer from a TLV element.
bool hasBaseCongestionMarkingInterval() const
Definition: face-status.hpp:81
FaceStatus & setExpirationPeriod(time::milliseconds expirationPeriod)
FaceStatus & setNInInterests(uint64_t nInInterests)
FaceStatus & setNInBytes(uint64_t nInBytes)
FaceStatus & unsetBaseCongestionMarkingInterval()
FaceStatus & unsetExpirationPeriod()
uint64_t getNInInterests() const
FaceStatus & setNInNacks(uint64_t nInNacks)
time::nanoseconds getBaseCongestionMarkingInterval() const
Definition: face-status.hpp:87
FaceStatus & setNOutData(uint64_t nOutData)
bool operator==(const ChannelStatus &a, const ChannelStatus &b)
represents an item in NFD Face dataset
Definition: face-status.hpp:36
uint64_t getNOutData() const
uint64_t getFaceId() const
Definition: face-traits.hpp:51
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
std::ostream & operator<<(std::ostream &os, FaceScope faceScope)
void reset()
Reset wire buffer of the element.
Definition: block.cpp:258
const std::string & getLocalUri() const
Definition: face-traits.hpp:79
uint64_t getNOutBytes() const
void parse() const
Parse TLV-VALUE into sub elements.
Definition: block.cpp:336
const std::string & getRemoteUri() const
Definition: face-traits.hpp:65
uint32_t type() const
Get TLV-TYPE.
Definition: block.hpp:235
uint64_t getNOutInterests() const
FaceStatus & setBaseCongestionMarkingInterval(time::nanoseconds interval)
FacePersistency getFacePersistency() const
FaceStatus & setNOutNacks(uint64_t nOutNacks)
uint64_t getNInBytes() const
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.cpp:252
uint64_t getNInData() const
element_const_iterator elements_end() const
Equivalent to elements().end()
Definition: block.hpp:363
FaceStatus & setNInData(uint64_t nInData)
element_const_iterator elements_begin() const
Equivalent to elements().begin()
Definition: block.hpp:355
const Block & wireEncode() const
encode FaceStatus
Definition: face-status.cpp:93
uint64_t getNOutNacks() const
EncodingImpl< EncoderTag > EncodingBuffer
EncodingImpl< EstimatorTag > EncodingEstimator
FaceStatus & setDefaultCongestionThreshold(uint64_t threshold)
set default congestion threshold (measured in bytes)