blob: c0377c50baf928ca3d6f38ea6f75b8287e78f2a8 [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 Shidf505382018-03-04 13:40:44 +000079 if (this->hasNCsEntries()) {
80 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::NCsEntries, m_nCsEntries);
81 }
Junxiao Shi22f85682018-01-22 19:23:22 +000082 if (this->hasCapacity()) {
83 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Capacity, m_capacity);
84 }
Junxiao Shi70911652014-08-12 10:14:24 -070085 if (this->hasCost()) {
86 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
87 }
88 if (this->hasOrigin()) {
89 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Origin, m_origin);
90 }
Eric Newberryd7f5b282017-03-28 19:55:20 -070091 if (this->hasLocalUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +000092 totalLength += prependStringBlock(encoder, tlv::nfd::LocalUri, m_localUri);
Eric Newberryd7f5b282017-03-28 19:55:20 -070093 }
Junxiao Shi70911652014-08-12 10:14:24 -070094 if (this->hasUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +000095 totalLength += prependStringBlock(encoder, tlv::nfd::Uri, m_uri);
Junxiao Shi70911652014-08-12 10:14:24 -070096 }
97 if (this->hasFaceId()) {
98 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
99 }
100 if (this->hasName()) {
101 totalLength += m_name.wireEncode(encoder);
102 }
103
104 totalLength += encoder.prependVarNumber(totalLength);
105 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
106 return totalLength;
107}
108
Davide Pesavento88a0d812017-08-19 21:31:42 -0400109NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ControlParameters);
Junxiao Shi70911652014-08-12 10:14:24 -0700110
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700111Block
Junxiao Shi70911652014-08-12 10:14:24 -0700112ControlParameters::wireEncode() const
113{
114 if (m_wire.hasWire())
115 return m_wire;
116
117 EncodingEstimator estimator;
118 size_t estimatedSize = wireEncode(estimator);
119
120 EncodingBuffer buffer(estimatedSize, 0);
121 wireEncode(buffer);
122
123 m_wire = buffer.block();
124 return m_wire;
125}
126
127void
128ControlParameters::wireDecode(const Block& block)
129{
130 if (block.type() != tlv::nfd::ControlParameters) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700131 BOOST_THROW_EXCEPTION(Error("Expecting TLV-TYPE ControlParameters"));
Junxiao Shi70911652014-08-12 10:14:24 -0700132 }
133 m_wire = block;
134 m_wire.parse();
135 Block::element_const_iterator val;
136
137 val = m_wire.find(tlv::Name);
138 m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
139 if (this->hasName()) {
140 m_name.wireDecode(*val);
141 }
142
143 val = m_wire.find(tlv::nfd::FaceId);
144 m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
145 if (this->hasFaceId()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000146 m_faceId = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700147 }
148
149 val = m_wire.find(tlv::nfd::Uri);
150 m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
151 if (this->hasUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000152 m_uri = readString(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700153 }
154
Eric Newberryd7f5b282017-03-28 19:55:20 -0700155 val = m_wire.find(tlv::nfd::LocalUri);
156 m_hasFields[CONTROL_PARAMETER_LOCAL_URI] = val != m_wire.elements_end();
157 if (this->hasLocalUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000158 m_localUri = readString(*val);
Eric Newberryd7f5b282017-03-28 19:55:20 -0700159 }
160
Junxiao Shi70911652014-08-12 10:14:24 -0700161 val = m_wire.find(tlv::nfd::Origin);
162 m_hasFields[CONTROL_PARAMETER_ORIGIN] = val != m_wire.elements_end();
163 if (this->hasOrigin()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000164 m_origin = readNonNegativeIntegerAs<RouteOrigin>(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700165 }
166
167 val = m_wire.find(tlv::nfd::Cost);
168 m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
169 if (this->hasCost()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000170 m_cost = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700171 }
172
Junxiao Shi22f85682018-01-22 19:23:22 +0000173 val = m_wire.find(tlv::nfd::Capacity);
174 m_hasFields[CONTROL_PARAMETER_CAPACITY] = val != m_wire.elements_end();
175 if (this->hasCapacity()) {
176 m_capacity = readNonNegativeInteger(*val);
177 }
178
Junxiao Shidf505382018-03-04 13:40:44 +0000179 val = m_wire.find(tlv::nfd::NCsEntries);
180 m_hasFields[CONTROL_PARAMETER_N_CS_ENTRIES] = val != m_wire.elements_end();
181 if (this->hasNCsEntries()) {
182 m_nCsEntries = readNonNegativeInteger(*val);
183 }
184
Junxiao Shi70911652014-08-12 10:14:24 -0700185 val = m_wire.find(tlv::nfd::Flags);
186 m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
187 if (this->hasFlags()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000188 m_flags = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700189 }
190
Eric Newberryda916d62016-08-11 23:04:34 -0700191 val = m_wire.find(tlv::nfd::Mask);
192 m_hasFields[CONTROL_PARAMETER_MASK] = val != m_wire.elements_end();
193 if (this->hasMask()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000194 m_mask = readNonNegativeInteger(*val);
Eric Newberryda916d62016-08-11 23:04:34 -0700195 }
196
Junxiao Shi70911652014-08-12 10:14:24 -0700197 val = m_wire.find(tlv::nfd::Strategy);
198 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
199 if (this->hasStrategy()) {
200 val->parse();
201 if (val->elements().empty()) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700202 BOOST_THROW_EXCEPTION(Error("Expecting Strategy/Name"));
Junxiao Shi70911652014-08-12 10:14:24 -0700203 }
204 else {
205 m_strategy.wireDecode(*val->elements_begin());
206 }
207 }
208
209 val = m_wire.find(tlv::nfd::ExpirationPeriod);
210 m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = val != m_wire.elements_end();
211 if (this->hasExpirationPeriod()) {
212 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
213 }
Yukai Tud93c5fc2015-08-25 11:37:16 +0800214
215 val = m_wire.find(tlv::nfd::FacePersistency);
216 m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = val != m_wire.elements_end();
217 if (this->hasFacePersistency()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000218 m_facePersistency = readNonNegativeIntegerAs<FacePersistency>(*val);
Yukai Tud93c5fc2015-08-25 11:37:16 +0800219 }
Eric Newberry07d05c92018-01-22 16:08:01 -0700220
221 val = m_wire.find(tlv::nfd::BaseCongestionMarkingInterval);
222 m_hasFields[CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL] = val != m_wire.elements_end();
223 if (this->hasBaseCongestionMarkingInterval()) {
224 m_baseCongestionMarkingInterval = time::nanoseconds(readNonNegativeInteger(*val));
225 }
226
227 val = m_wire.find(tlv::nfd::DefaultCongestionThreshold);
228 m_hasFields[CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD] = val != m_wire.elements_end();
229 if (this->hasDefaultCongestionThreshold()) {
230 m_defaultCongestionThreshold = readNonNegativeInteger(*val);
231 }
Junxiao Shi70911652014-08-12 10:14:24 -0700232}
233
Eric Newberryda916d62016-08-11 23:04:34 -0700234bool
235ControlParameters::hasFlagBit(size_t bit) const
236{
237 if (bit >= 64) {
238 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
239 }
240
241 if (!hasMask()) {
242 return false;
243 }
244
245 return getMask() & (1 << bit);
246}
247
248bool
249ControlParameters::getFlagBit(size_t bit) const
250{
251 if (bit >= 64) {
252 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
253 }
254
255 if (!hasFlags()) {
256 return false;
257 }
258
259 return getFlags() & (1 << bit);
260}
261
262ControlParameters&
263ControlParameters::setFlagBit(size_t bit, bool value, bool wantMask/* = true*/)
264{
265 if (bit >= 64) {
266 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
267 }
268
269 uint64_t flags = hasFlags() ? getFlags() : 0;
270 if (value) {
271 flags |= (1 << bit);
272 }
273 else {
274 flags &= ~(1 << bit);
275 }
276 setFlags(flags);
277
278 if (wantMask) {
279 uint64_t mask = hasMask() ? getMask() : 0;
280 mask |= (1 << bit);
281 setMask(mask);
282 }
283
284 return *this;
285}
286
287ControlParameters&
288ControlParameters::unsetFlagBit(size_t bit)
289{
290 if (bit >= 64) {
291 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
292 }
293
294 uint64_t mask = hasMask() ? getMask() : 0;
295 mask &= ~(1 << bit);
296 if (mask == 0) {
297 unsetMask();
298 unsetFlags();
299 }
300 else {
301 setMask(mask);
302 }
303
304 return *this;
305}
306
Junxiao Shi70911652014-08-12 10:14:24 -0700307std::ostream&
308operator<<(std::ostream& os, const ControlParameters& parameters)
309{
310 os << "ControlParameters(";
311
312 if (parameters.hasName()) {
313 os << "Name: " << parameters.getName() << ", ";
314 }
315
316 if (parameters.hasFaceId()) {
317 os << "FaceId: " << parameters.getFaceId() << ", ";
318 }
319
320 if (parameters.hasUri()) {
321 os << "Uri: " << parameters.getUri() << ", ";
322 }
323
Eric Newberryd7f5b282017-03-28 19:55:20 -0700324 if (parameters.hasLocalUri()) {
325 os << "LocalUri: " << parameters.getLocalUri() << ", ";
326 }
327
Junxiao Shi70911652014-08-12 10:14:24 -0700328 if (parameters.hasOrigin()) {
329 os << "Origin: " << parameters.getOrigin() << ", ";
330 }
331
332 if (parameters.hasCost()) {
333 os << "Cost: " << parameters.getCost() << ", ";
334 }
335
Junxiao Shi22f85682018-01-22 19:23:22 +0000336 if (parameters.hasCapacity()) {
337 os << "Capacity: " << parameters.getCapacity() << ", ";
338 }
339
Junxiao Shidf505382018-03-04 13:40:44 +0000340 if (parameters.hasNCsEntries()) {
341 os << "NCsEntries: " << parameters.getNCsEntries() << ", ";
342 }
343
Junxiao Shi70911652014-08-12 10:14:24 -0700344 if (parameters.hasFlags()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500345 os << "Flags: " << AsHex{parameters.getFlags()} << ", ";
Eric Newberryda916d62016-08-11 23:04:34 -0700346 }
347
348 if (parameters.hasMask()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500349 os << "Mask: " << AsHex{parameters.getMask()} << ", ";
Junxiao Shi70911652014-08-12 10:14:24 -0700350 }
351
352 if (parameters.hasStrategy()) {
353 os << "Strategy: " << parameters.getStrategy() << ", ";
354 }
355
356 if (parameters.hasExpirationPeriod()) {
357 os << "ExpirationPeriod: " << parameters.getExpirationPeriod() << ", ";
358 }
359
Yanbiao Licbdacb22016-08-02 16:02:35 +0800360 if (parameters.hasFacePersistency()) {
361 os << "FacePersistency: " << parameters.getFacePersistency() << ", ";
362 }
363
Eric Newberry07d05c92018-01-22 16:08:01 -0700364 if (parameters.hasBaseCongestionMarkingInterval()) {
365 os << "BaseCongestionMarkingInterval: " << parameters.getBaseCongestionMarkingInterval() << ", ";
366 }
367
368 if (parameters.hasDefaultCongestionThreshold()) {
369 os << "DefaultCongestionThreshold: " << parameters.getDefaultCongestionThreshold() << ", ";
370 }
371
Junxiao Shi70911652014-08-12 10:14:24 -0700372 os << ")";
373 return os;
374}
375
376} // namespace nfd
377} // namespace ndn