blob: 1e4d9fe5ad19d1ce2bbc57425d6645d695772eb8 [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 Newberry07d05c92018-01-22 16:08:01 -070054 if (this->hasDefaultCongestionThreshold()) {
55 totalLength += prependNonNegativeIntegerBlock(encoder,
56 tlv::nfd::DefaultCongestionThreshold, m_defaultCongestionThreshold);
57 }
58 if (this->hasBaseCongestionMarkingInterval()) {
59 totalLength += prependNonNegativeIntegerBlock(encoder,
60 tlv::nfd::BaseCongestionMarkingInterval, m_baseCongestionMarkingInterval.count());
61 }
Yukai Tud93c5fc2015-08-25 11:37:16 +080062 if (this->hasFacePersistency()) {
63 totalLength += prependNonNegativeIntegerBlock(encoder,
64 tlv::nfd::FacePersistency, m_facePersistency);
65 }
Junxiao Shi70911652014-08-12 10:14:24 -070066 if (this->hasExpirationPeriod()) {
67 totalLength += prependNonNegativeIntegerBlock(encoder,
68 tlv::nfd::ExpirationPeriod, m_expirationPeriod.count());
69 }
70 if (this->hasStrategy()) {
71 totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
72 }
Eric Newberryda916d62016-08-11 23:04:34 -070073 if (this->hasMask()) {
74 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Mask, m_mask);
75 }
Junxiao Shi70911652014-08-12 10:14:24 -070076 if (this->hasFlags()) {
77 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Flags, m_flags);
78 }
Junxiao Shi22f85682018-01-22 19:23:22 +000079 if (this->hasCapacity()) {
80 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Capacity, m_capacity);
81 }
Junxiao Shi70911652014-08-12 10:14:24 -070082 if (this->hasCost()) {
83 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
84 }
85 if (this->hasOrigin()) {
86 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Origin, m_origin);
87 }
Eric Newberryd7f5b282017-03-28 19:55:20 -070088 if (this->hasLocalUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +000089 totalLength += prependStringBlock(encoder, tlv::nfd::LocalUri, m_localUri);
Eric Newberryd7f5b282017-03-28 19:55:20 -070090 }
Junxiao Shi70911652014-08-12 10:14:24 -070091 if (this->hasUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +000092 totalLength += prependStringBlock(encoder, tlv::nfd::Uri, m_uri);
Junxiao Shi70911652014-08-12 10:14:24 -070093 }
94 if (this->hasFaceId()) {
95 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
96 }
97 if (this->hasName()) {
98 totalLength += m_name.wireEncode(encoder);
99 }
100
101 totalLength += encoder.prependVarNumber(totalLength);
102 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
103 return totalLength;
104}
105
Davide Pesavento88a0d812017-08-19 21:31:42 -0400106NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ControlParameters);
Junxiao Shi70911652014-08-12 10:14:24 -0700107
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700108Block
Junxiao Shi70911652014-08-12 10:14:24 -0700109ControlParameters::wireEncode() const
110{
111 if (m_wire.hasWire())
112 return m_wire;
113
114 EncodingEstimator estimator;
115 size_t estimatedSize = wireEncode(estimator);
116
117 EncodingBuffer buffer(estimatedSize, 0);
118 wireEncode(buffer);
119
120 m_wire = buffer.block();
121 return m_wire;
122}
123
124void
125ControlParameters::wireDecode(const Block& block)
126{
127 if (block.type() != tlv::nfd::ControlParameters) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700128 BOOST_THROW_EXCEPTION(Error("Expecting TLV-TYPE ControlParameters"));
Junxiao Shi70911652014-08-12 10:14:24 -0700129 }
130 m_wire = block;
131 m_wire.parse();
132 Block::element_const_iterator val;
133
134 val = m_wire.find(tlv::Name);
135 m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
136 if (this->hasName()) {
137 m_name.wireDecode(*val);
138 }
139
140 val = m_wire.find(tlv::nfd::FaceId);
141 m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
142 if (this->hasFaceId()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000143 m_faceId = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700144 }
145
146 val = m_wire.find(tlv::nfd::Uri);
147 m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
148 if (this->hasUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000149 m_uri = readString(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700150 }
151
Eric Newberryd7f5b282017-03-28 19:55:20 -0700152 val = m_wire.find(tlv::nfd::LocalUri);
153 m_hasFields[CONTROL_PARAMETER_LOCAL_URI] = val != m_wire.elements_end();
154 if (this->hasLocalUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000155 m_localUri = readString(*val);
Eric Newberryd7f5b282017-03-28 19:55:20 -0700156 }
157
Junxiao Shi70911652014-08-12 10:14:24 -0700158 val = m_wire.find(tlv::nfd::Origin);
159 m_hasFields[CONTROL_PARAMETER_ORIGIN] = val != m_wire.elements_end();
160 if (this->hasOrigin()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000161 m_origin = readNonNegativeIntegerAs<RouteOrigin>(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700162 }
163
164 val = m_wire.find(tlv::nfd::Cost);
165 m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
166 if (this->hasCost()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000167 m_cost = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700168 }
169
Junxiao Shi22f85682018-01-22 19:23:22 +0000170 val = m_wire.find(tlv::nfd::Capacity);
171 m_hasFields[CONTROL_PARAMETER_CAPACITY] = val != m_wire.elements_end();
172 if (this->hasCapacity()) {
173 m_capacity = readNonNegativeInteger(*val);
174 }
175
Junxiao Shi70911652014-08-12 10:14:24 -0700176 val = m_wire.find(tlv::nfd::Flags);
177 m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
178 if (this->hasFlags()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000179 m_flags = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700180 }
181
Eric Newberryda916d62016-08-11 23:04:34 -0700182 val = m_wire.find(tlv::nfd::Mask);
183 m_hasFields[CONTROL_PARAMETER_MASK] = val != m_wire.elements_end();
184 if (this->hasMask()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000185 m_mask = readNonNegativeInteger(*val);
Eric Newberryda916d62016-08-11 23:04:34 -0700186 }
187
Junxiao Shi70911652014-08-12 10:14:24 -0700188 val = m_wire.find(tlv::nfd::Strategy);
189 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
190 if (this->hasStrategy()) {
191 val->parse();
192 if (val->elements().empty()) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700193 BOOST_THROW_EXCEPTION(Error("Expecting Strategy/Name"));
Junxiao Shi70911652014-08-12 10:14:24 -0700194 }
195 else {
196 m_strategy.wireDecode(*val->elements_begin());
197 }
198 }
199
200 val = m_wire.find(tlv::nfd::ExpirationPeriod);
201 m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = val != m_wire.elements_end();
202 if (this->hasExpirationPeriod()) {
203 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
204 }
Yukai Tud93c5fc2015-08-25 11:37:16 +0800205
206 val = m_wire.find(tlv::nfd::FacePersistency);
207 m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = val != m_wire.elements_end();
208 if (this->hasFacePersistency()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000209 m_facePersistency = readNonNegativeIntegerAs<FacePersistency>(*val);
Yukai Tud93c5fc2015-08-25 11:37:16 +0800210 }
Eric Newberry07d05c92018-01-22 16:08:01 -0700211
212 val = m_wire.find(tlv::nfd::BaseCongestionMarkingInterval);
213 m_hasFields[CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL] = val != m_wire.elements_end();
214 if (this->hasBaseCongestionMarkingInterval()) {
215 m_baseCongestionMarkingInterval = time::nanoseconds(readNonNegativeInteger(*val));
216 }
217
218 val = m_wire.find(tlv::nfd::DefaultCongestionThreshold);
219 m_hasFields[CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD] = val != m_wire.elements_end();
220 if (this->hasDefaultCongestionThreshold()) {
221 m_defaultCongestionThreshold = readNonNegativeInteger(*val);
222 }
Junxiao Shi70911652014-08-12 10:14:24 -0700223}
224
Eric Newberryda916d62016-08-11 23:04:34 -0700225bool
226ControlParameters::hasFlagBit(size_t bit) const
227{
228 if (bit >= 64) {
229 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
230 }
231
232 if (!hasMask()) {
233 return false;
234 }
235
236 return getMask() & (1 << bit);
237}
238
239bool
240ControlParameters::getFlagBit(size_t bit) const
241{
242 if (bit >= 64) {
243 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
244 }
245
246 if (!hasFlags()) {
247 return false;
248 }
249
250 return getFlags() & (1 << bit);
251}
252
253ControlParameters&
254ControlParameters::setFlagBit(size_t bit, bool value, bool wantMask/* = true*/)
255{
256 if (bit >= 64) {
257 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
258 }
259
260 uint64_t flags = hasFlags() ? getFlags() : 0;
261 if (value) {
262 flags |= (1 << bit);
263 }
264 else {
265 flags &= ~(1 << bit);
266 }
267 setFlags(flags);
268
269 if (wantMask) {
270 uint64_t mask = hasMask() ? getMask() : 0;
271 mask |= (1 << bit);
272 setMask(mask);
273 }
274
275 return *this;
276}
277
278ControlParameters&
279ControlParameters::unsetFlagBit(size_t bit)
280{
281 if (bit >= 64) {
282 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
283 }
284
285 uint64_t mask = hasMask() ? getMask() : 0;
286 mask &= ~(1 << bit);
287 if (mask == 0) {
288 unsetMask();
289 unsetFlags();
290 }
291 else {
292 setMask(mask);
293 }
294
295 return *this;
296}
297
Junxiao Shi70911652014-08-12 10:14:24 -0700298std::ostream&
299operator<<(std::ostream& os, const ControlParameters& parameters)
300{
301 os << "ControlParameters(";
302
303 if (parameters.hasName()) {
304 os << "Name: " << parameters.getName() << ", ";
305 }
306
307 if (parameters.hasFaceId()) {
308 os << "FaceId: " << parameters.getFaceId() << ", ";
309 }
310
311 if (parameters.hasUri()) {
312 os << "Uri: " << parameters.getUri() << ", ";
313 }
314
Eric Newberryd7f5b282017-03-28 19:55:20 -0700315 if (parameters.hasLocalUri()) {
316 os << "LocalUri: " << parameters.getLocalUri() << ", ";
317 }
318
Junxiao Shi70911652014-08-12 10:14:24 -0700319 if (parameters.hasOrigin()) {
320 os << "Origin: " << parameters.getOrigin() << ", ";
321 }
322
323 if (parameters.hasCost()) {
324 os << "Cost: " << parameters.getCost() << ", ";
325 }
326
Junxiao Shi22f85682018-01-22 19:23:22 +0000327 if (parameters.hasCapacity()) {
328 os << "Capacity: " << parameters.getCapacity() << ", ";
329 }
330
Junxiao Shi70911652014-08-12 10:14:24 -0700331 if (parameters.hasFlags()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500332 os << "Flags: " << AsHex{parameters.getFlags()} << ", ";
Eric Newberryda916d62016-08-11 23:04:34 -0700333 }
334
335 if (parameters.hasMask()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500336 os << "Mask: " << AsHex{parameters.getMask()} << ", ";
Junxiao Shi70911652014-08-12 10:14:24 -0700337 }
338
339 if (parameters.hasStrategy()) {
340 os << "Strategy: " << parameters.getStrategy() << ", ";
341 }
342
343 if (parameters.hasExpirationPeriod()) {
344 os << "ExpirationPeriod: " << parameters.getExpirationPeriod() << ", ";
345 }
346
Yanbiao Licbdacb22016-08-02 16:02:35 +0800347 if (parameters.hasFacePersistency()) {
348 os << "FacePersistency: " << parameters.getFacePersistency() << ", ";
349 }
350
Eric Newberry07d05c92018-01-22 16:08:01 -0700351 if (parameters.hasBaseCongestionMarkingInterval()) {
352 os << "BaseCongestionMarkingInterval: " << parameters.getBaseCongestionMarkingInterval() << ", ";
353 }
354
355 if (parameters.hasDefaultCongestionThreshold()) {
356 os << "DefaultCongestionThreshold: " << parameters.getDefaultCongestionThreshold() << ", ";
357 }
358
Junxiao Shi70911652014-08-12 10:14:24 -0700359 os << ")";
360 return os;
361}
362
363} // namespace nfd
364} // namespace ndn