blob: c92a23f7703cfae280d2532fbc6dfced980eccf1 [file] [log] [blame]
Junxiao Shibc19b372014-03-23 16:59:25 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NDN_MANAGEMENT_NFD_CONTROL_PARAMETERS_HPP
8#define NDN_MANAGEMENT_NFD_CONTROL_PARAMETERS_HPP
9
10#include "../name.hpp"
11#include "../encoding/tlv-nfd.hpp"
12
13namespace ndn {
14namespace nfd {
15
16class ControlParameters;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070017/** \deprecated use ControlParameters instead
18 */
Junxiao Shibc19b372014-03-23 16:59:25 -070019typedef ControlParameters FaceManagementOptions;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070020/** \deprecated use ControlParameters instead
21 */
Junxiao Shibc19b372014-03-23 16:59:25 -070022typedef ControlParameters FibManagementOptions;
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070023/** \deprecated use ControlParameters instead
24 */
Junxiao Shibc19b372014-03-23 16:59:25 -070025typedef ControlParameters StrategyChoiceOptions;
26
Junxiao Shi5ec80222014-03-25 20:08:05 -070027enum ControlParameterField {
28 CONTROL_PARAMETER_NAME,
29 CONTROL_PARAMETER_FACE_ID,
30 CONTROL_PARAMETER_URI,
31 CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE,
32 CONTROL_PARAMETER_COST,
33 CONTROL_PARAMETER_STRATEGY,
34 CONTROL_PARAMETER_UBOUND
35};
36
37const std::string CONTROL_PARAMETER_FIELD[CONTROL_PARAMETER_UBOUND] = {
38 "Name",
39 "FaceId",
40 "Uri",
41 "LocalControlFeature",
42 "Cost",
43 "Strategy",
44};
45
Junxiao Shibc19b372014-03-23 16:59:25 -070046enum LocalControlFeature {
47 LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID = 1,
48 LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID = 2
49};
50
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070051/** \brief represents parameters in a ControlCommand request or response
52 * \sa http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
53 */
54class ControlParameters
55{
Junxiao Shibc19b372014-03-23 16:59:25 -070056public:
57 class Error : public Tlv::Error
58 {
59 public:
60 explicit
61 Error(const std::string& what)
62 : Tlv::Error(what)
63 {
64 }
65 };
66
Junxiao Shi5ec80222014-03-25 20:08:05 -070067 ControlParameters()
68 : m_hasFields(CONTROL_PARAMETER_UBOUND)
69 {
70 }
Junxiao Shibc19b372014-03-23 16:59:25 -070071
72 explicit
73 ControlParameters(const Block& block)
Junxiao Shi5ec80222014-03-25 20:08:05 -070074 : m_hasFields(CONTROL_PARAMETER_UBOUND)
Junxiao Shibc19b372014-03-23 16:59:25 -070075 {
76 wireDecode(block);
77 }
78
79 template<bool T>
80 size_t
81 wireEncode(EncodingImpl<T>& encoder) const;
82
83 const Block&
84 wireEncode() const;
85
86 void
87 wireDecode(const Block& wire);
88
89public: // getters & setters
90 bool
91 hasName() const
92 {
Junxiao Shi5ec80222014-03-25 20:08:05 -070093 return m_hasFields[CONTROL_PARAMETER_NAME];
Junxiao Shibc19b372014-03-23 16:59:25 -070094 }
95
96 const Name&
97 getName() const
98 {
Junxiao Shi5ec80222014-03-25 20:08:05 -070099 BOOST_ASSERT(this->hasName());
Junxiao Shibc19b372014-03-23 16:59:25 -0700100 return m_name;
101 }
102
103 ControlParameters&
104 setName(const Name& name)
105 {
106 m_wire.reset();
107 m_name = name;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700108 m_hasFields[CONTROL_PARAMETER_NAME] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700109 return *this;
110 }
111
112 ControlParameters&
113 unsetName()
114 {
115 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700116 m_hasFields[CONTROL_PARAMETER_NAME] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700117 return *this;
118 }
119
120 bool
121 hasFaceId() const
122 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700123 return m_hasFields[CONTROL_PARAMETER_FACE_ID];
Junxiao Shibc19b372014-03-23 16:59:25 -0700124 }
125
126 uint64_t
127 getFaceId() const
128 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700129 BOOST_ASSERT(this->hasFaceId());
Junxiao Shibc19b372014-03-23 16:59:25 -0700130 return m_faceId;
131 }
132
133 ControlParameters&
134 setFaceId(uint64_t faceId)
135 {
136 m_wire.reset();
137 m_faceId = faceId;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700138 m_hasFields[CONTROL_PARAMETER_FACE_ID] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700139 return *this;
140 }
141
142 ControlParameters&
143 unsetFaceId()
144 {
145 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700146 m_hasFields[CONTROL_PARAMETER_FACE_ID] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700147 return *this;
148 }
149
150 bool
151 hasUri() const
152 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700153 return m_hasFields[CONTROL_PARAMETER_URI];
Junxiao Shibc19b372014-03-23 16:59:25 -0700154 }
155
156 const std::string&
157 getUri() const
158 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700159 BOOST_ASSERT(this->hasUri());
Junxiao Shibc19b372014-03-23 16:59:25 -0700160 return m_uri;
161 }
162
163 ControlParameters&
164 setUri(const std::string& uri)
165 {
166 m_wire.reset();
167 m_uri = uri;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700168 m_hasFields[CONTROL_PARAMETER_URI] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700169 return *this;
170 }
171
172 ControlParameters&
173 unsetUri()
174 {
175 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700176 m_hasFields[CONTROL_PARAMETER_URI] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700177 return *this;
178 }
179
180 bool
181 hasLocalControlFeature() const
182 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700183 return m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE];
Junxiao Shibc19b372014-03-23 16:59:25 -0700184 }
185
186 LocalControlFeature
187 getLocalControlFeature() const
188 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700189 BOOST_ASSERT(this->hasLocalControlFeature());
Junxiao Shibc19b372014-03-23 16:59:25 -0700190 return m_localControlFeature;
191 }
192
193 ControlParameters&
194 setLocalControlFeature(LocalControlFeature localControlFeature)
195 {
196 m_wire.reset();
197 m_localControlFeature = localControlFeature;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700198 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700199 return *this;
200 }
201
202 ControlParameters&
203 unsetLocalControlFeature()
204 {
205 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700206 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700207 return *this;
208 }
209
210 bool
211 hasCost() const
212 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700213 return m_hasFields[CONTROL_PARAMETER_COST];
Junxiao Shibc19b372014-03-23 16:59:25 -0700214 }
215
216 uint64_t
217 getCost() const
218 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700219 BOOST_ASSERT(this->hasCost());
Junxiao Shibc19b372014-03-23 16:59:25 -0700220 return m_cost;
221 }
222
223 ControlParameters&
224 setCost(uint64_t cost)
225 {
226 m_wire.reset();
227 m_cost = cost;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700228 m_hasFields[CONTROL_PARAMETER_COST] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700229 return *this;
230 }
231
232 ControlParameters&
233 unsetCost()
234 {
235 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700236 m_hasFields[CONTROL_PARAMETER_COST] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700237 return *this;
238 }
239
240 bool
241 hasStrategy() const
242 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700243 return m_hasFields[CONTROL_PARAMETER_STRATEGY];
Junxiao Shibc19b372014-03-23 16:59:25 -0700244 }
245
246 const Name&
247 getStrategy() const
248 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700249 BOOST_ASSERT(this->hasStrategy());
Junxiao Shibc19b372014-03-23 16:59:25 -0700250 return m_strategy;
251 }
252
253 ControlParameters&
254 setStrategy(const Name& strategy)
255 {
256 m_wire.reset();
257 m_strategy = strategy;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700258 m_hasFields[CONTROL_PARAMETER_STRATEGY] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700259 return *this;
260 }
261
262 ControlParameters&
263 unsetStrategy()
264 {
265 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700266 m_hasFields[CONTROL_PARAMETER_STRATEGY] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700267 return *this;
268 }
269
Junxiao Shi5ec80222014-03-25 20:08:05 -0700270 const std::vector<bool>&
271 getPresentFields() const
272 {
273 return m_hasFields;
274 }
275
Junxiao Shibc19b372014-03-23 16:59:25 -0700276private: // fields
Junxiao Shi5ec80222014-03-25 20:08:05 -0700277 std::vector<bool> m_hasFields;
278
Junxiao Shibc19b372014-03-23 16:59:25 -0700279 Name m_name;
280 uint64_t m_faceId;
281 std::string m_uri;
282 LocalControlFeature m_localControlFeature;
283 uint64_t m_cost;
284 Name m_strategy;
285
Junxiao Shibc19b372014-03-23 16:59:25 -0700286private:
287 mutable Block m_wire;
288};
289
290
Junxiao Shibc19b372014-03-23 16:59:25 -0700291template<bool T>
292inline size_t
293ControlParameters::wireEncode(EncodingImpl<T>& encoder) const
294{
295 size_t totalLength = 0;
296
Junxiao Shi5ec80222014-03-25 20:08:05 -0700297 if (this->hasStrategy()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700298 totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
299 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700300 if (this->hasCost()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700301 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
302 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700303 if (this->hasLocalControlFeature()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700304 totalLength += prependNonNegativeIntegerBlock(encoder,
305 tlv::nfd::LocalControlFeature, m_localControlFeature);
306 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700307 if (this->hasUri()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700308 size_t valLength = encoder.prependByteArray(
309 reinterpret_cast<const uint8_t*>(m_uri.c_str()), m_uri.size());
310 totalLength += valLength;
311 totalLength += encoder.prependVarNumber(valLength);
312 totalLength += encoder.prependVarNumber(tlv::nfd::Uri);
313 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700314 if (this->hasFaceId()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700315 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
316 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700317 if (this->hasName()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700318 totalLength += m_name.wireEncode(encoder);
319 }
320
321 totalLength += encoder.prependVarNumber(totalLength);
322 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
323 return totalLength;
324}
325
326inline const Block&
327ControlParameters::wireEncode() const
328{
329 if (m_wire.hasWire())
330 return m_wire;
331
332 EncodingEstimator estimator;
333 size_t estimatedSize = wireEncode(estimator);
334
335 EncodingBuffer buffer(estimatedSize, 0);
336 wireEncode(buffer);
337
338 m_wire = buffer.block();
339 return m_wire;
340}
341
342inline void
343ControlParameters::wireDecode(const Block& block)
344{
345 if (block.type() != tlv::nfd::ControlParameters) {
346 throw Error("expecting TLV-TYPE ControlParameters");
347 }
348 m_wire = block;
349 m_wire.parse();
350 Block::element_const_iterator val;
351
352 val = m_wire.find(Tlv::Name);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700353 m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
354 if (this->hasName()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700355 m_name.wireDecode(*val);
356 }
357
358 val = m_wire.find(tlv::nfd::FaceId);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700359 m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
360 if (this->hasFaceId()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700361 m_faceId = static_cast<uint64_t>(readNonNegativeInteger(*val));
362 }
363
364 val = m_wire.find(tlv::nfd::Uri);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700365 m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
366 if (this->hasUri()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700367 m_uri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
368 }
369
370 val = m_wire.find(tlv::nfd::LocalControlFeature);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700371 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = val != m_wire.elements_end();
372 if (this->hasLocalControlFeature()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700373 m_localControlFeature = static_cast<LocalControlFeature>(readNonNegativeInteger(*val));
374 }
375
376 val = m_wire.find(tlv::nfd::Cost);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700377 m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
378 if (this->hasCost()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700379 m_cost = static_cast<uint64_t>(readNonNegativeInteger(*val));
380 }
381
382 val = m_wire.find(tlv::nfd::Strategy);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700383 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
384 if (this->hasStrategy()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700385 val->parse();
386 if (val->elements().empty()) {
387 throw Error("expecting Strategy/Name");
388 }
389 else {
390 m_strategy.wireDecode(*val->elements_begin());
391 }
392 }
393}
394
395inline std::ostream&
396operator<<(std::ostream& os, const ControlParameters& parameters)
397{
398 os << "ControlParameters(";
399
400 if (parameters.hasName()) {
401 os << "Name: " << parameters.getName() << ", ";
402 }
403
404 if (parameters.hasFaceId()) {
405 os << "FaceId: " << parameters.getFaceId() << ", ";
406 }
407
408 if (parameters.hasUri()) {
409 os << "Uri: " << parameters.getUri() << ", ";
410 }
411
412 if (parameters.hasLocalControlFeature()) {
413 os << "LocalControlFeature: " << parameters.getLocalControlFeature() << ", ";
414 }
415
416 if (parameters.hasCost()) {
417 os << "Cost: " << parameters.getCost() << ", ";
418 }
419
420 if (parameters.hasStrategy()) {
421 os << "Strategy: " << parameters.getStrategy() << ", ";
422 }
423
424 os << ")";
425 return os;
426}
427
428
429} // namespace nfd
430} // namespace ndn
431
432#endif // NDN_MANAGEMENT_NFD_CONTROL_PARAMETERS_HPP