blob: 836369bc76992828d57e4a7c39750b221ebc5e1e [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;
17typedef ControlParameters FaceManagementOptions;
18typedef ControlParameters FibManagementOptions;
19typedef ControlParameters StrategyChoiceOptions;
20
Junxiao Shi5ec80222014-03-25 20:08:05 -070021enum ControlParameterField {
22 CONTROL_PARAMETER_NAME,
23 CONTROL_PARAMETER_FACE_ID,
24 CONTROL_PARAMETER_URI,
25 CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE,
26 CONTROL_PARAMETER_COST,
27 CONTROL_PARAMETER_STRATEGY,
28 CONTROL_PARAMETER_UBOUND
29};
30
31const std::string CONTROL_PARAMETER_FIELD[CONTROL_PARAMETER_UBOUND] = {
32 "Name",
33 "FaceId",
34 "Uri",
35 "LocalControlFeature",
36 "Cost",
37 "Strategy",
38};
39
Junxiao Shibc19b372014-03-23 16:59:25 -070040enum LocalControlFeature {
41 LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID = 1,
42 LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID = 2
43};
44
45class ControlParameters {
46public:
47 class Error : public Tlv::Error
48 {
49 public:
50 explicit
51 Error(const std::string& what)
52 : Tlv::Error(what)
53 {
54 }
55 };
56
Junxiao Shi5ec80222014-03-25 20:08:05 -070057 ControlParameters()
58 : m_hasFields(CONTROL_PARAMETER_UBOUND)
59 {
60 }
Junxiao Shibc19b372014-03-23 16:59:25 -070061
62 explicit
63 ControlParameters(const Block& block)
Junxiao Shi5ec80222014-03-25 20:08:05 -070064 : m_hasFields(CONTROL_PARAMETER_UBOUND)
Junxiao Shibc19b372014-03-23 16:59:25 -070065 {
66 wireDecode(block);
67 }
68
69 template<bool T>
70 size_t
71 wireEncode(EncodingImpl<T>& encoder) const;
72
73 const Block&
74 wireEncode() const;
75
76 void
77 wireDecode(const Block& wire);
78
79public: // getters & setters
80 bool
81 hasName() const
82 {
Junxiao Shi5ec80222014-03-25 20:08:05 -070083 return m_hasFields[CONTROL_PARAMETER_NAME];
Junxiao Shibc19b372014-03-23 16:59:25 -070084 }
85
86 const Name&
87 getName() const
88 {
Junxiao Shi5ec80222014-03-25 20:08:05 -070089 BOOST_ASSERT(this->hasName());
Junxiao Shibc19b372014-03-23 16:59:25 -070090 return m_name;
91 }
92
93 ControlParameters&
94 setName(const Name& name)
95 {
96 m_wire.reset();
97 m_name = name;
Junxiao Shi5ec80222014-03-25 20:08:05 -070098 m_hasFields[CONTROL_PARAMETER_NAME] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -070099 return *this;
100 }
101
102 ControlParameters&
103 unsetName()
104 {
105 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700106 m_hasFields[CONTROL_PARAMETER_NAME] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700107 return *this;
108 }
109
110 bool
111 hasFaceId() const
112 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700113 return m_hasFields[CONTROL_PARAMETER_FACE_ID];
Junxiao Shibc19b372014-03-23 16:59:25 -0700114 }
115
116 uint64_t
117 getFaceId() const
118 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700119 BOOST_ASSERT(this->hasFaceId());
Junxiao Shibc19b372014-03-23 16:59:25 -0700120 return m_faceId;
121 }
122
123 ControlParameters&
124 setFaceId(uint64_t faceId)
125 {
126 m_wire.reset();
127 m_faceId = faceId;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700128 m_hasFields[CONTROL_PARAMETER_FACE_ID] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700129 return *this;
130 }
131
132 ControlParameters&
133 unsetFaceId()
134 {
135 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700136 m_hasFields[CONTROL_PARAMETER_FACE_ID] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700137 return *this;
138 }
139
140 bool
141 hasUri() const
142 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700143 return m_hasFields[CONTROL_PARAMETER_URI];
Junxiao Shibc19b372014-03-23 16:59:25 -0700144 }
145
146 const std::string&
147 getUri() const
148 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700149 BOOST_ASSERT(this->hasUri());
Junxiao Shibc19b372014-03-23 16:59:25 -0700150 return m_uri;
151 }
152
153 ControlParameters&
154 setUri(const std::string& uri)
155 {
156 m_wire.reset();
157 m_uri = uri;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700158 m_hasFields[CONTROL_PARAMETER_URI] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700159 return *this;
160 }
161
162 ControlParameters&
163 unsetUri()
164 {
165 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700166 m_hasFields[CONTROL_PARAMETER_URI] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700167 return *this;
168 }
169
170 bool
171 hasLocalControlFeature() const
172 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700173 return m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE];
Junxiao Shibc19b372014-03-23 16:59:25 -0700174 }
175
176 LocalControlFeature
177 getLocalControlFeature() const
178 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700179 BOOST_ASSERT(this->hasLocalControlFeature());
Junxiao Shibc19b372014-03-23 16:59:25 -0700180 return m_localControlFeature;
181 }
182
183 ControlParameters&
184 setLocalControlFeature(LocalControlFeature localControlFeature)
185 {
186 m_wire.reset();
187 m_localControlFeature = localControlFeature;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700188 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700189 return *this;
190 }
191
192 ControlParameters&
193 unsetLocalControlFeature()
194 {
195 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700196 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700197 return *this;
198 }
199
200 bool
201 hasCost() const
202 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700203 return m_hasFields[CONTROL_PARAMETER_COST];
Junxiao Shibc19b372014-03-23 16:59:25 -0700204 }
205
206 uint64_t
207 getCost() const
208 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700209 BOOST_ASSERT(this->hasCost());
Junxiao Shibc19b372014-03-23 16:59:25 -0700210 return m_cost;
211 }
212
213 ControlParameters&
214 setCost(uint64_t cost)
215 {
216 m_wire.reset();
217 m_cost = cost;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700218 m_hasFields[CONTROL_PARAMETER_COST] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700219 return *this;
220 }
221
222 ControlParameters&
223 unsetCost()
224 {
225 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700226 m_hasFields[CONTROL_PARAMETER_COST] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700227 return *this;
228 }
229
230 bool
231 hasStrategy() const
232 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700233 return m_hasFields[CONTROL_PARAMETER_STRATEGY];
Junxiao Shibc19b372014-03-23 16:59:25 -0700234 }
235
236 const Name&
237 getStrategy() const
238 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700239 BOOST_ASSERT(this->hasStrategy());
Junxiao Shibc19b372014-03-23 16:59:25 -0700240 return m_strategy;
241 }
242
243 ControlParameters&
244 setStrategy(const Name& strategy)
245 {
246 m_wire.reset();
247 m_strategy = strategy;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700248 m_hasFields[CONTROL_PARAMETER_STRATEGY] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700249 return *this;
250 }
251
252 ControlParameters&
253 unsetStrategy()
254 {
255 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700256 m_hasFields[CONTROL_PARAMETER_STRATEGY] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700257 return *this;
258 }
259
Junxiao Shi5ec80222014-03-25 20:08:05 -0700260 const std::vector<bool>&
261 getPresentFields() const
262 {
263 return m_hasFields;
264 }
265
Junxiao Shibc19b372014-03-23 16:59:25 -0700266private: // fields
Junxiao Shi5ec80222014-03-25 20:08:05 -0700267 std::vector<bool> m_hasFields;
268
Junxiao Shibc19b372014-03-23 16:59:25 -0700269 Name m_name;
270 uint64_t m_faceId;
271 std::string m_uri;
272 LocalControlFeature m_localControlFeature;
273 uint64_t m_cost;
274 Name m_strategy;
275
Junxiao Shibc19b372014-03-23 16:59:25 -0700276private:
277 mutable Block m_wire;
278};
279
280
Junxiao Shibc19b372014-03-23 16:59:25 -0700281template<bool T>
282inline size_t
283ControlParameters::wireEncode(EncodingImpl<T>& encoder) const
284{
285 size_t totalLength = 0;
286
Junxiao Shi5ec80222014-03-25 20:08:05 -0700287 if (this->hasStrategy()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700288 totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
289 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700290 if (this->hasCost()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700291 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
292 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700293 if (this->hasLocalControlFeature()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700294 totalLength += prependNonNegativeIntegerBlock(encoder,
295 tlv::nfd::LocalControlFeature, m_localControlFeature);
296 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700297 if (this->hasUri()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700298 size_t valLength = encoder.prependByteArray(
299 reinterpret_cast<const uint8_t*>(m_uri.c_str()), m_uri.size());
300 totalLength += valLength;
301 totalLength += encoder.prependVarNumber(valLength);
302 totalLength += encoder.prependVarNumber(tlv::nfd::Uri);
303 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700304 if (this->hasFaceId()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700305 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
306 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700307 if (this->hasName()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700308 totalLength += m_name.wireEncode(encoder);
309 }
310
311 totalLength += encoder.prependVarNumber(totalLength);
312 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
313 return totalLength;
314}
315
316inline const Block&
317ControlParameters::wireEncode() const
318{
319 if (m_wire.hasWire())
320 return m_wire;
321
322 EncodingEstimator estimator;
323 size_t estimatedSize = wireEncode(estimator);
324
325 EncodingBuffer buffer(estimatedSize, 0);
326 wireEncode(buffer);
327
328 m_wire = buffer.block();
329 return m_wire;
330}
331
332inline void
333ControlParameters::wireDecode(const Block& block)
334{
335 if (block.type() != tlv::nfd::ControlParameters) {
336 throw Error("expecting TLV-TYPE ControlParameters");
337 }
338 m_wire = block;
339 m_wire.parse();
340 Block::element_const_iterator val;
341
342 val = m_wire.find(Tlv::Name);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700343 m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
344 if (this->hasName()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700345 m_name.wireDecode(*val);
346 }
347
348 val = m_wire.find(tlv::nfd::FaceId);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700349 m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
350 if (this->hasFaceId()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700351 m_faceId = static_cast<uint64_t>(readNonNegativeInteger(*val));
352 }
353
354 val = m_wire.find(tlv::nfd::Uri);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700355 m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
356 if (this->hasUri()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700357 m_uri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
358 }
359
360 val = m_wire.find(tlv::nfd::LocalControlFeature);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700361 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = val != m_wire.elements_end();
362 if (this->hasLocalControlFeature()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700363 m_localControlFeature = static_cast<LocalControlFeature>(readNonNegativeInteger(*val));
364 }
365
366 val = m_wire.find(tlv::nfd::Cost);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700367 m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
368 if (this->hasCost()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700369 m_cost = static_cast<uint64_t>(readNonNegativeInteger(*val));
370 }
371
372 val = m_wire.find(tlv::nfd::Strategy);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700373 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
374 if (this->hasStrategy()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700375 val->parse();
376 if (val->elements().empty()) {
377 throw Error("expecting Strategy/Name");
378 }
379 else {
380 m_strategy.wireDecode(*val->elements_begin());
381 }
382 }
383}
384
385inline std::ostream&
386operator<<(std::ostream& os, const ControlParameters& parameters)
387{
388 os << "ControlParameters(";
389
390 if (parameters.hasName()) {
391 os << "Name: " << parameters.getName() << ", ";
392 }
393
394 if (parameters.hasFaceId()) {
395 os << "FaceId: " << parameters.getFaceId() << ", ";
396 }
397
398 if (parameters.hasUri()) {
399 os << "Uri: " << parameters.getUri() << ", ";
400 }
401
402 if (parameters.hasLocalControlFeature()) {
403 os << "LocalControlFeature: " << parameters.getLocalControlFeature() << ", ";
404 }
405
406 if (parameters.hasCost()) {
407 os << "Cost: " << parameters.getCost() << ", ";
408 }
409
410 if (parameters.hasStrategy()) {
411 os << "Strategy: " << parameters.getStrategy() << ", ";
412 }
413
414 os << ")";
415 return os;
416}
417
418
419} // namespace nfd
420} // namespace ndn
421
422#endif // NDN_MANAGEMENT_NFD_CONTROL_PARAMETERS_HPP