blob: 4d826ef10bddf70c70fde48c961bf1586382d6af [file] [log] [blame]
Junxiao Shi70911652014-08-12 10:14:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi5d75fd92017-08-08 18:09:20 +00002/*
Junxiao Shi22f85682018-01-22 19:23:22 +00003 * Copyright (c) 2013-2018 Regents of the University of California.
Junxiao Shi70911652014-08-12 10:14:24 -07004 *
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
Junxiao Shi7357ef22016-09-07 02:39:37 +000022#include "control-parameters.hpp"
Junxiao Shi65f1a712014-11-20 14:59:36 -070023#include "encoding/block-helpers.hpp"
Junxiao Shi5d75fd92017-08-08 18:09:20 +000024#include "encoding/tlv-nfd.hpp"
Junxiao Shi65f1a712014-11-20 14:59:36 -070025#include "util/concepts.hpp"
Davide Pesaventoe78eeca2017-02-23 23:22:32 -050026#include "util/string-helper.hpp"
Junxiao Shi70911652014-08-12 10:14:24 -070027
28namespace ndn {
29namespace nfd {
30
Junxiao Shi65f1a712014-11-20 14:59:36 -070031//BOOST_CONCEPT_ASSERT((boost::EqualityComparable<ControlParameters>));
32BOOST_CONCEPT_ASSERT((WireEncodable<ControlParameters>));
33BOOST_CONCEPT_ASSERT((WireDecodable<ControlParameters>));
34static_assert(std::is_base_of<tlv::Error, ControlParameters::Error>::value,
35 "ControlParameters::Error must inherit from tlv::Error");
36
Junxiao Shi70911652014-08-12 10:14:24 -070037ControlParameters::ControlParameters()
38 : m_hasFields(CONTROL_PARAMETER_UBOUND)
39{
40}
41
42ControlParameters::ControlParameters(const Block& block)
43 : m_hasFields(CONTROL_PARAMETER_UBOUND)
44{
45 wireDecode(block);
46}
47
Alexander Afanasyev74633892015-02-08 18:08:46 -080048template<encoding::Tag TAG>
Junxiao Shi70911652014-08-12 10:14:24 -070049size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -080050ControlParameters::wireEncode(EncodingImpl<TAG>& encoder) const
Junxiao Shi70911652014-08-12 10:14:24 -070051{
52 size_t totalLength = 0;
53
Eric Newberry3c9bc042018-06-02 17:58:10 -070054 if (this->hasMtu()) {
55 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Mtu, m_mtu);
56 }
Eric Newberry07d05c92018-01-22 16:08:01 -070057 if (this->hasDefaultCongestionThreshold()) {
Davide Pesavento5e2ccca2018-03-06 19:00:15 -050058 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::DefaultCongestionThreshold,
59 m_defaultCongestionThreshold);
Eric Newberry07d05c92018-01-22 16:08:01 -070060 }
61 if (this->hasBaseCongestionMarkingInterval()) {
Davide Pesavento5e2ccca2018-03-06 19:00:15 -050062 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::BaseCongestionMarkingInterval,
63 m_baseCongestionMarkingInterval.count());
Eric Newberry07d05c92018-01-22 16:08:01 -070064 }
Yukai Tud93c5fc2015-08-25 11:37:16 +080065 if (this->hasFacePersistency()) {
Davide Pesavento5e2ccca2018-03-06 19:00:15 -050066 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FacePersistency, m_facePersistency);
Yukai Tud93c5fc2015-08-25 11:37:16 +080067 }
Junxiao Shi70911652014-08-12 10:14:24 -070068 if (this->hasExpirationPeriod()) {
Davide Pesavento5e2ccca2018-03-06 19:00:15 -050069 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::ExpirationPeriod,
70 m_expirationPeriod.count());
Junxiao Shi70911652014-08-12 10:14:24 -070071 }
72 if (this->hasStrategy()) {
73 totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
74 }
Eric Newberryda916d62016-08-11 23:04:34 -070075 if (this->hasMask()) {
76 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Mask, m_mask);
77 }
Junxiao Shi70911652014-08-12 10:14:24 -070078 if (this->hasFlags()) {
79 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Flags, m_flags);
80 }
Davide Pesavento5e2ccca2018-03-06 19:00:15 -050081 if (this->hasCount()) {
82 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Count, m_count);
Junxiao Shidf505382018-03-04 13:40:44 +000083 }
Junxiao Shi22f85682018-01-22 19:23:22 +000084 if (this->hasCapacity()) {
85 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Capacity, m_capacity);
86 }
Junxiao Shi70911652014-08-12 10:14:24 -070087 if (this->hasCost()) {
88 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
89 }
90 if (this->hasOrigin()) {
91 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Origin, m_origin);
92 }
Eric Newberryd7f5b282017-03-28 19:55:20 -070093 if (this->hasLocalUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +000094 totalLength += prependStringBlock(encoder, tlv::nfd::LocalUri, m_localUri);
Eric Newberryd7f5b282017-03-28 19:55:20 -070095 }
Junxiao Shi70911652014-08-12 10:14:24 -070096 if (this->hasUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +000097 totalLength += prependStringBlock(encoder, tlv::nfd::Uri, m_uri);
Junxiao Shi70911652014-08-12 10:14:24 -070098 }
99 if (this->hasFaceId()) {
100 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
101 }
102 if (this->hasName()) {
103 totalLength += m_name.wireEncode(encoder);
104 }
105
106 totalLength += encoder.prependVarNumber(totalLength);
107 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
108 return totalLength;
109}
110
Davide Pesavento88a0d812017-08-19 21:31:42 -0400111NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ControlParameters);
Junxiao Shi70911652014-08-12 10:14:24 -0700112
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700113Block
Junxiao Shi70911652014-08-12 10:14:24 -0700114ControlParameters::wireEncode() const
115{
116 if (m_wire.hasWire())
117 return m_wire;
118
119 EncodingEstimator estimator;
120 size_t estimatedSize = wireEncode(estimator);
121
122 EncodingBuffer buffer(estimatedSize, 0);
123 wireEncode(buffer);
124
125 m_wire = buffer.block();
126 return m_wire;
127}
128
129void
130ControlParameters::wireDecode(const Block& block)
131{
132 if (block.type() != tlv::nfd::ControlParameters) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700133 BOOST_THROW_EXCEPTION(Error("Expecting TLV-TYPE ControlParameters"));
Junxiao Shi70911652014-08-12 10:14:24 -0700134 }
135 m_wire = block;
136 m_wire.parse();
137 Block::element_const_iterator val;
138
139 val = m_wire.find(tlv::Name);
140 m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
141 if (this->hasName()) {
142 m_name.wireDecode(*val);
143 }
144
145 val = m_wire.find(tlv::nfd::FaceId);
146 m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
147 if (this->hasFaceId()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000148 m_faceId = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700149 }
150
151 val = m_wire.find(tlv::nfd::Uri);
152 m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
153 if (this->hasUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000154 m_uri = readString(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700155 }
156
Eric Newberryd7f5b282017-03-28 19:55:20 -0700157 val = m_wire.find(tlv::nfd::LocalUri);
158 m_hasFields[CONTROL_PARAMETER_LOCAL_URI] = val != m_wire.elements_end();
159 if (this->hasLocalUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000160 m_localUri = readString(*val);
Eric Newberryd7f5b282017-03-28 19:55:20 -0700161 }
162
Junxiao Shi70911652014-08-12 10:14:24 -0700163 val = m_wire.find(tlv::nfd::Origin);
164 m_hasFields[CONTROL_PARAMETER_ORIGIN] = val != m_wire.elements_end();
165 if (this->hasOrigin()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000166 m_origin = readNonNegativeIntegerAs<RouteOrigin>(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700167 }
168
169 val = m_wire.find(tlv::nfd::Cost);
170 m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
171 if (this->hasCost()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000172 m_cost = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700173 }
174
Junxiao Shi22f85682018-01-22 19:23:22 +0000175 val = m_wire.find(tlv::nfd::Capacity);
176 m_hasFields[CONTROL_PARAMETER_CAPACITY] = val != m_wire.elements_end();
177 if (this->hasCapacity()) {
178 m_capacity = readNonNegativeInteger(*val);
179 }
180
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500181 val = m_wire.find(tlv::nfd::Count);
182 m_hasFields[CONTROL_PARAMETER_COUNT] = val != m_wire.elements_end();
183 if (this->hasCount()) {
184 m_count = readNonNegativeInteger(*val);
Junxiao Shidf505382018-03-04 13:40:44 +0000185 }
186
Junxiao Shi70911652014-08-12 10:14:24 -0700187 val = m_wire.find(tlv::nfd::Flags);
188 m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
189 if (this->hasFlags()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000190 m_flags = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700191 }
192
Eric Newberryda916d62016-08-11 23:04:34 -0700193 val = m_wire.find(tlv::nfd::Mask);
194 m_hasFields[CONTROL_PARAMETER_MASK] = val != m_wire.elements_end();
195 if (this->hasMask()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000196 m_mask = readNonNegativeInteger(*val);
Eric Newberryda916d62016-08-11 23:04:34 -0700197 }
198
Junxiao Shi70911652014-08-12 10:14:24 -0700199 val = m_wire.find(tlv::nfd::Strategy);
200 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
201 if (this->hasStrategy()) {
202 val->parse();
203 if (val->elements().empty()) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700204 BOOST_THROW_EXCEPTION(Error("Expecting Strategy/Name"));
Junxiao Shi70911652014-08-12 10:14:24 -0700205 }
206 else {
207 m_strategy.wireDecode(*val->elements_begin());
208 }
209 }
210
211 val = m_wire.find(tlv::nfd::ExpirationPeriod);
212 m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = val != m_wire.elements_end();
213 if (this->hasExpirationPeriod()) {
214 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
215 }
Yukai Tud93c5fc2015-08-25 11:37:16 +0800216
217 val = m_wire.find(tlv::nfd::FacePersistency);
218 m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = val != m_wire.elements_end();
219 if (this->hasFacePersistency()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000220 m_facePersistency = readNonNegativeIntegerAs<FacePersistency>(*val);
Yukai Tud93c5fc2015-08-25 11:37:16 +0800221 }
Eric Newberry07d05c92018-01-22 16:08:01 -0700222
223 val = m_wire.find(tlv::nfd::BaseCongestionMarkingInterval);
224 m_hasFields[CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL] = val != m_wire.elements_end();
225 if (this->hasBaseCongestionMarkingInterval()) {
226 m_baseCongestionMarkingInterval = time::nanoseconds(readNonNegativeInteger(*val));
227 }
228
229 val = m_wire.find(tlv::nfd::DefaultCongestionThreshold);
230 m_hasFields[CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD] = val != m_wire.elements_end();
231 if (this->hasDefaultCongestionThreshold()) {
232 m_defaultCongestionThreshold = readNonNegativeInteger(*val);
233 }
Eric Newberry3c9bc042018-06-02 17:58:10 -0700234
235 val = m_wire.find(tlv::nfd::Mtu);
236 m_hasFields[CONTROL_PARAMETER_MTU] = val != m_wire.elements_end();
237 if (this->hasMtu()) {
238 m_mtu = readNonNegativeInteger(*val);
239 }
Junxiao Shi70911652014-08-12 10:14:24 -0700240}
241
Eric Newberryda916d62016-08-11 23:04:34 -0700242bool
243ControlParameters::hasFlagBit(size_t bit) const
244{
245 if (bit >= 64) {
246 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
247 }
248
249 if (!hasMask()) {
250 return false;
251 }
252
253 return getMask() & (1 << bit);
254}
255
256bool
257ControlParameters::getFlagBit(size_t bit) const
258{
259 if (bit >= 64) {
260 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
261 }
262
263 if (!hasFlags()) {
264 return false;
265 }
266
267 return getFlags() & (1 << bit);
268}
269
270ControlParameters&
271ControlParameters::setFlagBit(size_t bit, bool value, bool wantMask/* = true*/)
272{
273 if (bit >= 64) {
274 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
275 }
276
277 uint64_t flags = hasFlags() ? getFlags() : 0;
278 if (value) {
279 flags |= (1 << bit);
280 }
281 else {
282 flags &= ~(1 << bit);
283 }
284 setFlags(flags);
285
286 if (wantMask) {
287 uint64_t mask = hasMask() ? getMask() : 0;
288 mask |= (1 << bit);
289 setMask(mask);
290 }
291
292 return *this;
293}
294
295ControlParameters&
296ControlParameters::unsetFlagBit(size_t bit)
297{
298 if (bit >= 64) {
299 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
300 }
301
302 uint64_t mask = hasMask() ? getMask() : 0;
303 mask &= ~(1 << bit);
304 if (mask == 0) {
305 unsetMask();
306 unsetFlags();
307 }
308 else {
309 setMask(mask);
310 }
311
312 return *this;
313}
314
Junxiao Shi70911652014-08-12 10:14:24 -0700315std::ostream&
316operator<<(std::ostream& os, const ControlParameters& parameters)
317{
318 os << "ControlParameters(";
319
320 if (parameters.hasName()) {
321 os << "Name: " << parameters.getName() << ", ";
322 }
323
324 if (parameters.hasFaceId()) {
325 os << "FaceId: " << parameters.getFaceId() << ", ";
326 }
327
328 if (parameters.hasUri()) {
329 os << "Uri: " << parameters.getUri() << ", ";
330 }
331
Eric Newberryd7f5b282017-03-28 19:55:20 -0700332 if (parameters.hasLocalUri()) {
333 os << "LocalUri: " << parameters.getLocalUri() << ", ";
334 }
335
Junxiao Shi70911652014-08-12 10:14:24 -0700336 if (parameters.hasOrigin()) {
337 os << "Origin: " << parameters.getOrigin() << ", ";
338 }
339
340 if (parameters.hasCost()) {
341 os << "Cost: " << parameters.getCost() << ", ";
342 }
343
Junxiao Shi22f85682018-01-22 19:23:22 +0000344 if (parameters.hasCapacity()) {
345 os << "Capacity: " << parameters.getCapacity() << ", ";
346 }
347
Davide Pesavento5e2ccca2018-03-06 19:00:15 -0500348 if (parameters.hasCount()) {
349 os << "Count: " << parameters.getCount() << ", ";
Junxiao Shidf505382018-03-04 13:40:44 +0000350 }
351
Junxiao Shi70911652014-08-12 10:14:24 -0700352 if (parameters.hasFlags()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500353 os << "Flags: " << AsHex{parameters.getFlags()} << ", ";
Eric Newberryda916d62016-08-11 23:04:34 -0700354 }
355
356 if (parameters.hasMask()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500357 os << "Mask: " << AsHex{parameters.getMask()} << ", ";
Junxiao Shi70911652014-08-12 10:14:24 -0700358 }
359
360 if (parameters.hasStrategy()) {
361 os << "Strategy: " << parameters.getStrategy() << ", ";
362 }
363
364 if (parameters.hasExpirationPeriod()) {
365 os << "ExpirationPeriod: " << parameters.getExpirationPeriod() << ", ";
366 }
367
Yanbiao Licbdacb22016-08-02 16:02:35 +0800368 if (parameters.hasFacePersistency()) {
369 os << "FacePersistency: " << parameters.getFacePersistency() << ", ";
370 }
371
Eric Newberry07d05c92018-01-22 16:08:01 -0700372 if (parameters.hasBaseCongestionMarkingInterval()) {
373 os << "BaseCongestionMarkingInterval: " << parameters.getBaseCongestionMarkingInterval() << ", ";
374 }
375
376 if (parameters.hasDefaultCongestionThreshold()) {
377 os << "DefaultCongestionThreshold: " << parameters.getDefaultCongestionThreshold() << ", ";
378 }
379
Eric Newberry3c9bc042018-06-02 17:58:10 -0700380 if (parameters.hasMtu()) {
381 os << "Mtu: " << parameters.getMtu() << ", ";
382 }
383
Junxiao Shi70911652014-08-12 10:14:24 -0700384 os << ")";
385 return os;
386}
387
388} // namespace nfd
389} // namespace ndn