blob: 4958749f586de7a139bb59c8d4d4d90bf5eb3f03 [file] [log] [blame]
Junxiao Shi70911652014-08-12 10:14:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesaventoe78eeca2017-02-23 23:22:32 -05003 * Copyright (c) 2013-2017 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/tlv-nfd.hpp"
24#include "encoding/block-helpers.hpp"
25#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
Yukai Tud93c5fc2015-08-25 11:37:16 +080054 if (this->hasFacePersistency()) {
55 totalLength += prependNonNegativeIntegerBlock(encoder,
56 tlv::nfd::FacePersistency, m_facePersistency);
57 }
Junxiao Shi70911652014-08-12 10:14:24 -070058 if (this->hasExpirationPeriod()) {
59 totalLength += prependNonNegativeIntegerBlock(encoder,
60 tlv::nfd::ExpirationPeriod, m_expirationPeriod.count());
61 }
62 if (this->hasStrategy()) {
63 totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
64 }
Eric Newberryda916d62016-08-11 23:04:34 -070065 if (this->hasMask()) {
66 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Mask, m_mask);
67 }
Junxiao Shi70911652014-08-12 10:14:24 -070068 if (this->hasFlags()) {
69 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Flags, m_flags);
70 }
71 if (this->hasCost()) {
72 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
73 }
74 if (this->hasOrigin()) {
75 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Origin, m_origin);
76 }
77 if (this->hasLocalControlFeature()) {
78 totalLength += prependNonNegativeIntegerBlock(encoder,
79 tlv::nfd::LocalControlFeature, m_localControlFeature);
80 }
81 if (this->hasUri()) {
82 size_t valLength = encoder.prependByteArray(
83 reinterpret_cast<const uint8_t*>(m_uri.c_str()), m_uri.size());
84 totalLength += valLength;
85 totalLength += encoder.prependVarNumber(valLength);
86 totalLength += encoder.prependVarNumber(tlv::nfd::Uri);
87 }
88 if (this->hasFaceId()) {
89 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
90 }
91 if (this->hasName()) {
92 totalLength += m_name.wireEncode(encoder);
93 }
94
95 totalLength += encoder.prependVarNumber(totalLength);
96 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
97 return totalLength;
98}
99
100template size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -0800101ControlParameters::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>&) const;
Junxiao Shi70911652014-08-12 10:14:24 -0700102
103template size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -0800104ControlParameters::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>&) const;
Junxiao Shi70911652014-08-12 10:14:24 -0700105
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700106Block
Junxiao Shi70911652014-08-12 10:14:24 -0700107ControlParameters::wireEncode() const
108{
109 if (m_wire.hasWire())
110 return m_wire;
111
112 EncodingEstimator estimator;
113 size_t estimatedSize = wireEncode(estimator);
114
115 EncodingBuffer buffer(estimatedSize, 0);
116 wireEncode(buffer);
117
118 m_wire = buffer.block();
119 return m_wire;
120}
121
122void
123ControlParameters::wireDecode(const Block& block)
124{
125 if (block.type() != tlv::nfd::ControlParameters) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700126 BOOST_THROW_EXCEPTION(Error("Expecting TLV-TYPE ControlParameters"));
Junxiao Shi70911652014-08-12 10:14:24 -0700127 }
128 m_wire = block;
129 m_wire.parse();
130 Block::element_const_iterator val;
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 = static_cast<uint64_t>(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.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
148 }
149
150 val = m_wire.find(tlv::nfd::LocalControlFeature);
151 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = val != m_wire.elements_end();
152 if (this->hasLocalControlFeature()) {
153 m_localControlFeature = static_cast<LocalControlFeature>(readNonNegativeInteger(*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 = static_cast<uint64_t>(readNonNegativeInteger(*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 = static_cast<uint64_t>(readNonNegativeInteger(*val));
166 }
167
168 val = m_wire.find(tlv::nfd::Flags);
169 m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
170 if (this->hasFlags()) {
171 m_flags = static_cast<uint64_t>(readNonNegativeInteger(*val));
172 }
173
Eric Newberryda916d62016-08-11 23:04:34 -0700174 val = m_wire.find(tlv::nfd::Mask);
175 m_hasFields[CONTROL_PARAMETER_MASK] = val != m_wire.elements_end();
176 if (this->hasMask()) {
177 m_mask = static_cast<uint64_t>(readNonNegativeInteger(*val));
178 }
179
Junxiao Shi70911652014-08-12 10:14:24 -0700180 val = m_wire.find(tlv::nfd::Strategy);
181 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
182 if (this->hasStrategy()) {
183 val->parse();
184 if (val->elements().empty()) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700185 BOOST_THROW_EXCEPTION(Error("Expecting Strategy/Name"));
Junxiao Shi70911652014-08-12 10:14:24 -0700186 }
187 else {
188 m_strategy.wireDecode(*val->elements_begin());
189 }
190 }
191
192 val = m_wire.find(tlv::nfd::ExpirationPeriod);
193 m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = val != m_wire.elements_end();
194 if (this->hasExpirationPeriod()) {
195 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
196 }
Yukai Tud93c5fc2015-08-25 11:37:16 +0800197
198 val = m_wire.find(tlv::nfd::FacePersistency);
199 m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = val != m_wire.elements_end();
200 if (this->hasFacePersistency()) {
201 m_facePersistency = static_cast<FacePersistency>(readNonNegativeInteger(*val));
202 }
Junxiao Shi70911652014-08-12 10:14:24 -0700203}
204
Eric Newberryda916d62016-08-11 23:04:34 -0700205bool
206ControlParameters::hasFlagBit(size_t bit) const
207{
208 if (bit >= 64) {
209 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
210 }
211
212 if (!hasMask()) {
213 return false;
214 }
215
216 return getMask() & (1 << bit);
217}
218
219bool
220ControlParameters::getFlagBit(size_t bit) const
221{
222 if (bit >= 64) {
223 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
224 }
225
226 if (!hasFlags()) {
227 return false;
228 }
229
230 return getFlags() & (1 << bit);
231}
232
233ControlParameters&
234ControlParameters::setFlagBit(size_t bit, bool value, bool wantMask/* = true*/)
235{
236 if (bit >= 64) {
237 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
238 }
239
240 uint64_t flags = hasFlags() ? getFlags() : 0;
241 if (value) {
242 flags |= (1 << bit);
243 }
244 else {
245 flags &= ~(1 << bit);
246 }
247 setFlags(flags);
248
249 if (wantMask) {
250 uint64_t mask = hasMask() ? getMask() : 0;
251 mask |= (1 << bit);
252 setMask(mask);
253 }
254
255 return *this;
256}
257
258ControlParameters&
259ControlParameters::unsetFlagBit(size_t bit)
260{
261 if (bit >= 64) {
262 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
263 }
264
265 uint64_t mask = hasMask() ? getMask() : 0;
266 mask &= ~(1 << bit);
267 if (mask == 0) {
268 unsetMask();
269 unsetFlags();
270 }
271 else {
272 setMask(mask);
273 }
274
275 return *this;
276}
277
Junxiao Shi70911652014-08-12 10:14:24 -0700278std::ostream&
279operator<<(std::ostream& os, const ControlParameters& parameters)
280{
281 os << "ControlParameters(";
282
283 if (parameters.hasName()) {
284 os << "Name: " << parameters.getName() << ", ";
285 }
286
287 if (parameters.hasFaceId()) {
288 os << "FaceId: " << parameters.getFaceId() << ", ";
289 }
290
291 if (parameters.hasUri()) {
292 os << "Uri: " << parameters.getUri() << ", ";
293 }
294
295 if (parameters.hasLocalControlFeature()) {
296 os << "LocalControlFeature: " << parameters.getLocalControlFeature() << ", ";
297 }
298
299 if (parameters.hasOrigin()) {
300 os << "Origin: " << parameters.getOrigin() << ", ";
301 }
302
303 if (parameters.hasCost()) {
304 os << "Cost: " << parameters.getCost() << ", ";
305 }
306
307 if (parameters.hasFlags()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500308 os << "Flags: " << AsHex{parameters.getFlags()} << ", ";
Eric Newberryda916d62016-08-11 23:04:34 -0700309 }
310
311 if (parameters.hasMask()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500312 os << "Mask: " << AsHex{parameters.getMask()} << ", ";
Junxiao Shi70911652014-08-12 10:14:24 -0700313 }
314
315 if (parameters.hasStrategy()) {
316 os << "Strategy: " << parameters.getStrategy() << ", ";
317 }
318
319 if (parameters.hasExpirationPeriod()) {
320 os << "ExpirationPeriod: " << parameters.getExpirationPeriod() << ", ";
321 }
322
Yanbiao Licbdacb22016-08-02 16:02:35 +0800323 if (parameters.hasFacePersistency()) {
324 os << "FacePersistency: " << parameters.getFacePersistency() << ", ";
325 }
326
Junxiao Shi70911652014-08-12 10:14:24 -0700327 os << ")";
328 return os;
329}
330
331} // namespace nfd
332} // namespace ndn