control-parameters.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2023 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 
26 
27 namespace ndn::nfd {
28 
30  : m_hasFields(CONTROL_PARAMETER_UBOUND)
31 {
32 }
33 
35  : m_hasFields(CONTROL_PARAMETER_UBOUND)
36 {
37  wireDecode(block);
38 }
39 
40 template<encoding::Tag TAG>
41 size_t
43 {
44  size_t totalLength = 0;
45 
46  if (this->hasMtu()) {
47  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Mtu, m_mtu);
48  }
49  if (this->hasDefaultCongestionThreshold()) {
51  m_defaultCongestionThreshold);
52  }
55  m_baseCongestionMarkingInterval.count());
56  }
57  if (this->hasFacePersistency()) {
58  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FacePersistency, m_facePersistency);
59  }
60  if (this->hasExpirationPeriod()) {
62  m_expirationPeriod.count());
63  }
64  if (this->hasStrategy()) {
65  totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
66  }
67  if (this->hasMask()) {
68  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Mask, m_mask);
69  }
70  if (this->hasFlags()) {
71  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Flags, m_flags);
72  }
73  if (this->hasCount()) {
74  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Count, m_count);
75  }
76  if (this->hasCapacity()) {
77  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Capacity, m_capacity);
78  }
79  if (this->hasCost()) {
80  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
81  }
82  if (this->hasOrigin()) {
83  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Origin, m_origin);
84  }
85  if (this->hasLocalUri()) {
86  totalLength += prependStringBlock(encoder, tlv::nfd::LocalUri, m_localUri);
87  }
88  if (this->hasUri()) {
89  totalLength += prependStringBlock(encoder, tlv::nfd::Uri, m_uri);
90  }
91  if (this->hasFaceId()) {
92  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
93  }
94  if (this->hasName()) {
95  totalLength += m_name.wireEncode(encoder);
96  }
97 
98  totalLength += encoder.prependVarNumber(totalLength);
99  totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
100  return totalLength;
101 }
102 
104 
105 Block
107 {
108  if (m_wire.hasWire())
109  return m_wire;
110 
111  EncodingEstimator estimator;
112  size_t estimatedSize = wireEncode(estimator);
113 
114  EncodingBuffer buffer(estimatedSize, 0);
115  wireEncode(buffer);
116 
117  m_wire = buffer.block();
118  return m_wire;
119 }
120 
121 void
123 {
124  if (block.type() != tlv::nfd::ControlParameters) {
125  NDN_THROW(Error("ControlParameters", block.type()));
126  }
127 
128  m_wire = block;
129  m_wire.parse();
131 
132  val = m_wire.find(tlv::Name);
133  m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
134  if (this->hasName()) {
135  m_name.wireDecode(*val);
136  }
137 
138  val = m_wire.find(tlv::nfd::FaceId);
139  m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
140  if (this->hasFaceId()) {
141  m_faceId = readNonNegativeInteger(*val);
142  }
143 
144  val = m_wire.find(tlv::nfd::Uri);
145  m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
146  if (this->hasUri()) {
147  m_uri = readString(*val);
148  }
149 
150  val = m_wire.find(tlv::nfd::LocalUri);
151  m_hasFields[CONTROL_PARAMETER_LOCAL_URI] = val != m_wire.elements_end();
152  if (this->hasLocalUri()) {
153  m_localUri = readString(*val);
154  }
155 
156  val = m_wire.find(tlv::nfd::Origin);
157  m_hasFields[CONTROL_PARAMETER_ORIGIN] = val != m_wire.elements_end();
158  if (this->hasOrigin()) {
159  m_origin = readNonNegativeIntegerAs<RouteOrigin>(*val);
160  }
161 
162  val = m_wire.find(tlv::nfd::Cost);
163  m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
164  if (this->hasCost()) {
165  m_cost = readNonNegativeInteger(*val);
166  }
167 
168  val = m_wire.find(tlv::nfd::Capacity);
169  m_hasFields[CONTROL_PARAMETER_CAPACITY] = val != m_wire.elements_end();
170  if (this->hasCapacity()) {
171  m_capacity = readNonNegativeInteger(*val);
172  }
173 
174  val = m_wire.find(tlv::nfd::Count);
175  m_hasFields[CONTROL_PARAMETER_COUNT] = val != m_wire.elements_end();
176  if (this->hasCount()) {
177  m_count = readNonNegativeInteger(*val);
178  }
179 
180  val = m_wire.find(tlv::nfd::Flags);
181  m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
182  if (this->hasFlags()) {
183  m_flags = readNonNegativeInteger(*val);
184  }
185 
186  val = m_wire.find(tlv::nfd::Mask);
187  m_hasFields[CONTROL_PARAMETER_MASK] = val != m_wire.elements_end();
188  if (this->hasMask()) {
189  m_mask = readNonNegativeInteger(*val);
190  }
191 
192  val = m_wire.find(tlv::nfd::Strategy);
193  m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
194  if (this->hasStrategy()) {
195  val->parse();
196  if (val->elements().empty()) {
197  NDN_THROW(Error("Expecting Strategy/Name"));
198  }
199  else {
200  m_strategy.wireDecode(*val->elements_begin());
201  }
202  }
203 
204  val = m_wire.find(tlv::nfd::ExpirationPeriod);
205  m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = val != m_wire.elements_end();
206  if (this->hasExpirationPeriod()) {
207  m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
208  }
209 
210  val = m_wire.find(tlv::nfd::FacePersistency);
211  m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = val != m_wire.elements_end();
212  if (this->hasFacePersistency()) {
213  m_facePersistency = readNonNegativeIntegerAs<FacePersistency>(*val);
214  }
215 
218  if (this->hasBaseCongestionMarkingInterval()) {
219  m_baseCongestionMarkingInterval = time::nanoseconds(readNonNegativeInteger(*val));
220  }
221 
223  m_hasFields[CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD] = val != m_wire.elements_end();
224  if (this->hasDefaultCongestionThreshold()) {
225  m_defaultCongestionThreshold = readNonNegativeInteger(*val);
226  }
227 
228  val = m_wire.find(tlv::nfd::Mtu);
229  m_hasFields[CONTROL_PARAMETER_MTU] = val != m_wire.elements_end();
230  if (this->hasMtu()) {
231  m_mtu = readNonNegativeInteger(*val);
232  }
233 }
234 
235 bool
237 {
238  if (bit >= 64) {
239  NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
240  }
241 
242  if (!hasMask()) {
243  return false;
244  }
245 
246  return getMask() & (1 << bit);
247 }
248 
249 bool
251 {
252  if (bit >= 64) {
253  NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
254  }
255 
256  if (!hasFlags()) {
257  return false;
258  }
259 
260  return getFlags() & (1 << bit);
261 }
262 
264 ControlParameters::setFlagBit(size_t bit, bool value, bool wantMask/* = true*/)
265 {
266  if (bit >= 64) {
267  NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
268  }
269 
270  uint64_t flags = hasFlags() ? getFlags() : 0;
271  if (value) {
272  flags |= (1 << bit);
273  }
274  else {
275  flags &= ~(1 << bit);
276  }
277  setFlags(flags);
278 
279  if (wantMask) {
280  uint64_t mask = hasMask() ? getMask() : 0;
281  mask |= (1 << bit);
282  setMask(mask);
283  }
284 
285  return *this;
286 }
287 
290 {
291  if (bit >= 64) {
292  NDN_THROW(std::out_of_range("bit must be within range [0, 64)"));
293  }
294 
295  uint64_t mask = hasMask() ? getMask() : 0;
296  mask &= ~(1 << bit);
297  if (mask == 0) {
298  unsetMask();
299  unsetFlags();
300  }
301  else {
302  setMask(mask);
303  }
304 
305  return *this;
306 }
307 
308 std::ostream&
309 operator<<(std::ostream& os, const ControlParameters& parameters)
310 {
311  os << "ControlParameters(";
312 
313  if (parameters.hasName()) {
314  os << "Name: " << parameters.getName() << ", ";
315  }
316 
317  if (parameters.hasFaceId()) {
318  os << "FaceId: " << parameters.getFaceId() << ", ";
319  }
320 
321  if (parameters.hasUri()) {
322  os << "Uri: " << parameters.getUri() << ", ";
323  }
324 
325  if (parameters.hasLocalUri()) {
326  os << "LocalUri: " << parameters.getLocalUri() << ", ";
327  }
328 
329  if (parameters.hasOrigin()) {
330  os << "Origin: " << parameters.getOrigin() << ", ";
331  }
332 
333  if (parameters.hasCost()) {
334  os << "Cost: " << parameters.getCost() << ", ";
335  }
336 
337  if (parameters.hasCapacity()) {
338  os << "Capacity: " << parameters.getCapacity() << ", ";
339  }
340 
341  if (parameters.hasCount()) {
342  os << "Count: " << parameters.getCount() << ", ";
343  }
344 
345  if (parameters.hasFlags()) {
346  os << "Flags: " << AsHex{parameters.getFlags()} << ", ";
347  }
348 
349  if (parameters.hasMask()) {
350  os << "Mask: " << AsHex{parameters.getMask()} << ", ";
351  }
352 
353  if (parameters.hasStrategy()) {
354  os << "Strategy: " << parameters.getStrategy() << ", ";
355  }
356 
357  if (parameters.hasExpirationPeriod()) {
358  os << "ExpirationPeriod: " << parameters.getExpirationPeriod() << ", ";
359  }
360 
361  if (parameters.hasFacePersistency()) {
362  os << "FacePersistency: " << parameters.getFacePersistency() << ", ";
363  }
364 
365  if (parameters.hasBaseCongestionMarkingInterval()) {
366  os << "BaseCongestionMarkingInterval: " << parameters.getBaseCongestionMarkingInterval() << ", ";
367  }
368 
369  if (parameters.hasDefaultCongestionThreshold()) {
370  os << "DefaultCongestionThreshold: " << parameters.getDefaultCongestionThreshold() << ", ";
371  }
372 
373  if (parameters.hasMtu()) {
374  os << "Mtu: " << parameters.getMtu() << ", ";
375  }
376 
377  os << ")";
378  return os;
379 }
380 
381 } // namespace ndn::nfd
Helper class to convert a number to hexadecimal format, for use with stream insertion operators.
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
element_container::const_iterator element_const_iterator
Definition: block.hpp:51
element_const_iterator find(uint32_t type) const
Find the first sub-element of the specified TLV-TYPE.
Definition: block.cpp:425
element_const_iterator elements_end() const noexcept
Equivalent to elements().end().
Definition: block.hpp:442
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition: block.hpp:205
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition: block.hpp:275
void parse() const
Parse TLV-VALUE into sub-elements.
Definition: block.cpp:326
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Prepend wire encoding to encoder.
Definition: name.cpp:92
void wireDecode(const Block &wire)
Decode name from wire encoding.
Definition: name.cpp:125
Represents parameters in a ControlCommand request or response.
void wireDecode(const Block &wire) final
ControlParameters & unsetFlags()
ControlParameters & unsetMask()
ControlParameters & unsetFlagBit(size_t bit)
Disable a bit in Mask.
uint64_t getDefaultCongestionThreshold() const
Get default congestion threshold (measured in bytes).
FacePersistency getFacePersistency() const
const std::string & getUri() const
ControlParameters & setFlagBit(size_t bit, bool value, bool wantMask=true)
Set a bit in Flags.
ControlParameters & setFlags(uint64_t flags)
bool hasFlagBit(size_t bit) const
const std::string & getLocalUri() const
const Name & getStrategy() const
const time::milliseconds & getExpirationPeriod() const
ControlParameters & setMask(uint64_t mask)
bool getFlagBit(size_t bit) const
time::nanoseconds getBaseCongestionMarkingInterval() const
uint64_t getMtu() const
Get MTU (measured in bytes).
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
#define NDN_THROW(e)
Definition: exception.hpp:56
@ CONTROL_PARAMETER_FACE_PERSISTENCY
@ CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD
@ CONTROL_PARAMETER_EXPIRATION_PERIOD
@ CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL
EncodingImpl< EstimatorTag > EncodingEstimator
size_t prependNestedBlock(EncodingImpl< TAG > &encoder, uint32_t type, const U &value)
Prepend a TLV element containing a nested TLV element.
uint64_t readNonNegativeInteger(const Block &block)
Read a non-negative integer from a TLV element.
size_t prependNonNegativeIntegerBlock(EncodingImpl< TAG > &encoder, uint32_t type, uint64_t value)
Prepend a TLV element containing a non-negative integer.
size_t prependStringBlock(EncodingImpl< TAG > &encoder, uint32_t type, std::string_view value)
Prepend a TLV element containing a string.
std::string readString(const Block &block)
Read the TLV-VALUE of a TLV element as a string.
EncodingImpl< EncoderTag > EncodingBuffer
Contains classes and functions related to the NFD Management protocol.
std::ostream & operator<<(std::ostream &os, FaceScope faceScope)
::boost::chrono::milliseconds milliseconds
Definition: time.hpp:52
::boost::chrono::nanoseconds nanoseconds
Definition: time.hpp:54
@ BaseCongestionMarkingInterval
Definition: tlv-nfd.hpp:70
@ ControlParameters
Definition: tlv-nfd.hpp:35
@ DefaultCongestionThreshold
Definition: tlv-nfd.hpp:71
@ ExpirationPeriod
Definition: tlv-nfd.hpp:45
@ Name
Definition: tlv.hpp:71