blob: 0eff8aedcd85db9a3828bedad12c8026bcb750e9 [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
Junxiao Shi5ec80222014-03-25 20:08:05 -070016enum ControlParameterField {
17 CONTROL_PARAMETER_NAME,
18 CONTROL_PARAMETER_FACE_ID,
19 CONTROL_PARAMETER_URI,
20 CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE,
21 CONTROL_PARAMETER_COST,
22 CONTROL_PARAMETER_STRATEGY,
23 CONTROL_PARAMETER_UBOUND
24};
25
26const std::string CONTROL_PARAMETER_FIELD[CONTROL_PARAMETER_UBOUND] = {
27 "Name",
28 "FaceId",
29 "Uri",
30 "LocalControlFeature",
31 "Cost",
32 "Strategy",
33};
34
Junxiao Shibc19b372014-03-23 16:59:25 -070035enum LocalControlFeature {
36 LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID = 1,
37 LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID = 2
38};
39
Junxiao Shi7b6b79d2014-03-26 20:59:35 -070040/** \brief represents parameters in a ControlCommand request or response
41 * \sa http://redmine.named-data.net/projects/nfd/wiki/ControlCommand
42 */
43class ControlParameters
44{
Junxiao Shibc19b372014-03-23 16:59:25 -070045public:
46 class Error : public Tlv::Error
47 {
48 public:
49 explicit
50 Error(const std::string& what)
51 : Tlv::Error(what)
52 {
53 }
54 };
55
Junxiao Shi5ec80222014-03-25 20:08:05 -070056 ControlParameters()
57 : m_hasFields(CONTROL_PARAMETER_UBOUND)
58 {
59 }
Junxiao Shibc19b372014-03-23 16:59:25 -070060
61 explicit
62 ControlParameters(const Block& block)
Junxiao Shi5ec80222014-03-25 20:08:05 -070063 : m_hasFields(CONTROL_PARAMETER_UBOUND)
Junxiao Shibc19b372014-03-23 16:59:25 -070064 {
65 wireDecode(block);
66 }
67
68 template<bool T>
69 size_t
70 wireEncode(EncodingImpl<T>& encoder) const;
71
72 const Block&
73 wireEncode() const;
74
75 void
76 wireDecode(const Block& wire);
77
78public: // getters & setters
79 bool
80 hasName() const
81 {
Junxiao Shi5ec80222014-03-25 20:08:05 -070082 return m_hasFields[CONTROL_PARAMETER_NAME];
Junxiao Shibc19b372014-03-23 16:59:25 -070083 }
84
85 const Name&
86 getName() const
87 {
Junxiao Shi5ec80222014-03-25 20:08:05 -070088 BOOST_ASSERT(this->hasName());
Junxiao Shibc19b372014-03-23 16:59:25 -070089 return m_name;
90 }
91
92 ControlParameters&
93 setName(const Name& name)
94 {
95 m_wire.reset();
96 m_name = name;
Junxiao Shi5ec80222014-03-25 20:08:05 -070097 m_hasFields[CONTROL_PARAMETER_NAME] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -070098 return *this;
99 }
100
101 ControlParameters&
102 unsetName()
103 {
104 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700105 m_hasFields[CONTROL_PARAMETER_NAME] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700106 return *this;
107 }
108
109 bool
110 hasFaceId() const
111 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700112 return m_hasFields[CONTROL_PARAMETER_FACE_ID];
Junxiao Shibc19b372014-03-23 16:59:25 -0700113 }
114
115 uint64_t
116 getFaceId() const
117 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700118 BOOST_ASSERT(this->hasFaceId());
Junxiao Shibc19b372014-03-23 16:59:25 -0700119 return m_faceId;
120 }
121
122 ControlParameters&
123 setFaceId(uint64_t faceId)
124 {
125 m_wire.reset();
126 m_faceId = faceId;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700127 m_hasFields[CONTROL_PARAMETER_FACE_ID] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700128 return *this;
129 }
130
131 ControlParameters&
132 unsetFaceId()
133 {
134 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700135 m_hasFields[CONTROL_PARAMETER_FACE_ID] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700136 return *this;
137 }
138
139 bool
140 hasUri() const
141 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700142 return m_hasFields[CONTROL_PARAMETER_URI];
Junxiao Shibc19b372014-03-23 16:59:25 -0700143 }
144
145 const std::string&
146 getUri() const
147 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700148 BOOST_ASSERT(this->hasUri());
Junxiao Shibc19b372014-03-23 16:59:25 -0700149 return m_uri;
150 }
151
152 ControlParameters&
153 setUri(const std::string& uri)
154 {
155 m_wire.reset();
156 m_uri = uri;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700157 m_hasFields[CONTROL_PARAMETER_URI] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700158 return *this;
159 }
160
161 ControlParameters&
162 unsetUri()
163 {
164 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700165 m_hasFields[CONTROL_PARAMETER_URI] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700166 return *this;
167 }
168
169 bool
170 hasLocalControlFeature() const
171 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700172 return m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE];
Junxiao Shibc19b372014-03-23 16:59:25 -0700173 }
174
175 LocalControlFeature
176 getLocalControlFeature() const
177 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700178 BOOST_ASSERT(this->hasLocalControlFeature());
Junxiao Shibc19b372014-03-23 16:59:25 -0700179 return m_localControlFeature;
180 }
181
182 ControlParameters&
183 setLocalControlFeature(LocalControlFeature localControlFeature)
184 {
185 m_wire.reset();
186 m_localControlFeature = localControlFeature;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700187 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700188 return *this;
189 }
190
191 ControlParameters&
192 unsetLocalControlFeature()
193 {
194 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700195 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700196 return *this;
197 }
198
199 bool
200 hasCost() const
201 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700202 return m_hasFields[CONTROL_PARAMETER_COST];
Junxiao Shibc19b372014-03-23 16:59:25 -0700203 }
204
205 uint64_t
206 getCost() const
207 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700208 BOOST_ASSERT(this->hasCost());
Junxiao Shibc19b372014-03-23 16:59:25 -0700209 return m_cost;
210 }
211
212 ControlParameters&
213 setCost(uint64_t cost)
214 {
215 m_wire.reset();
216 m_cost = cost;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700217 m_hasFields[CONTROL_PARAMETER_COST] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700218 return *this;
219 }
220
221 ControlParameters&
222 unsetCost()
223 {
224 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700225 m_hasFields[CONTROL_PARAMETER_COST] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700226 return *this;
227 }
228
229 bool
230 hasStrategy() const
231 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700232 return m_hasFields[CONTROL_PARAMETER_STRATEGY];
Junxiao Shibc19b372014-03-23 16:59:25 -0700233 }
234
235 const Name&
236 getStrategy() const
237 {
Junxiao Shi5ec80222014-03-25 20:08:05 -0700238 BOOST_ASSERT(this->hasStrategy());
Junxiao Shibc19b372014-03-23 16:59:25 -0700239 return m_strategy;
240 }
241
242 ControlParameters&
243 setStrategy(const Name& strategy)
244 {
245 m_wire.reset();
246 m_strategy = strategy;
Junxiao Shi5ec80222014-03-25 20:08:05 -0700247 m_hasFields[CONTROL_PARAMETER_STRATEGY] = true;
Junxiao Shibc19b372014-03-23 16:59:25 -0700248 return *this;
249 }
250
251 ControlParameters&
252 unsetStrategy()
253 {
254 m_wire.reset();
Junxiao Shi5ec80222014-03-25 20:08:05 -0700255 m_hasFields[CONTROL_PARAMETER_STRATEGY] = false;
Junxiao Shibc19b372014-03-23 16:59:25 -0700256 return *this;
257 }
258
Junxiao Shi5ec80222014-03-25 20:08:05 -0700259 const std::vector<bool>&
260 getPresentFields() const
261 {
262 return m_hasFields;
263 }
264
Junxiao Shibc19b372014-03-23 16:59:25 -0700265private: // fields
Junxiao Shi5ec80222014-03-25 20:08:05 -0700266 std::vector<bool> m_hasFields;
267
Junxiao Shibc19b372014-03-23 16:59:25 -0700268 Name m_name;
269 uint64_t m_faceId;
270 std::string m_uri;
271 LocalControlFeature m_localControlFeature;
272 uint64_t m_cost;
273 Name m_strategy;
274
Junxiao Shibc19b372014-03-23 16:59:25 -0700275private:
276 mutable Block m_wire;
277};
278
279
Junxiao Shibc19b372014-03-23 16:59:25 -0700280template<bool T>
281inline size_t
282ControlParameters::wireEncode(EncodingImpl<T>& encoder) const
283{
284 size_t totalLength = 0;
285
Junxiao Shi5ec80222014-03-25 20:08:05 -0700286 if (this->hasStrategy()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700287 totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
288 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700289 if (this->hasCost()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700290 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
291 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700292 if (this->hasLocalControlFeature()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700293 totalLength += prependNonNegativeIntegerBlock(encoder,
294 tlv::nfd::LocalControlFeature, m_localControlFeature);
295 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700296 if (this->hasUri()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700297 size_t valLength = encoder.prependByteArray(
298 reinterpret_cast<const uint8_t*>(m_uri.c_str()), m_uri.size());
299 totalLength += valLength;
300 totalLength += encoder.prependVarNumber(valLength);
301 totalLength += encoder.prependVarNumber(tlv::nfd::Uri);
302 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700303 if (this->hasFaceId()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700304 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
305 }
Junxiao Shi5ec80222014-03-25 20:08:05 -0700306 if (this->hasName()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700307 totalLength += m_name.wireEncode(encoder);
308 }
309
310 totalLength += encoder.prependVarNumber(totalLength);
311 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
312 return totalLength;
313}
314
315inline const Block&
316ControlParameters::wireEncode() const
317{
318 if (m_wire.hasWire())
319 return m_wire;
320
321 EncodingEstimator estimator;
322 size_t estimatedSize = wireEncode(estimator);
323
324 EncodingBuffer buffer(estimatedSize, 0);
325 wireEncode(buffer);
326
327 m_wire = buffer.block();
328 return m_wire;
329}
330
331inline void
332ControlParameters::wireDecode(const Block& block)
333{
334 if (block.type() != tlv::nfd::ControlParameters) {
335 throw Error("expecting TLV-TYPE ControlParameters");
336 }
337 m_wire = block;
338 m_wire.parse();
339 Block::element_const_iterator val;
340
341 val = m_wire.find(Tlv::Name);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700342 m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
343 if (this->hasName()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700344 m_name.wireDecode(*val);
345 }
346
347 val = m_wire.find(tlv::nfd::FaceId);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700348 m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
349 if (this->hasFaceId()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700350 m_faceId = static_cast<uint64_t>(readNonNegativeInteger(*val));
351 }
352
353 val = m_wire.find(tlv::nfd::Uri);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700354 m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
355 if (this->hasUri()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700356 m_uri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
357 }
358
359 val = m_wire.find(tlv::nfd::LocalControlFeature);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700360 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = val != m_wire.elements_end();
361 if (this->hasLocalControlFeature()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700362 m_localControlFeature = static_cast<LocalControlFeature>(readNonNegativeInteger(*val));
363 }
364
365 val = m_wire.find(tlv::nfd::Cost);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700366 m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
367 if (this->hasCost()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700368 m_cost = static_cast<uint64_t>(readNonNegativeInteger(*val));
369 }
370
371 val = m_wire.find(tlv::nfd::Strategy);
Junxiao Shi5ec80222014-03-25 20:08:05 -0700372 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
373 if (this->hasStrategy()) {
Junxiao Shibc19b372014-03-23 16:59:25 -0700374 val->parse();
375 if (val->elements().empty()) {
376 throw Error("expecting Strategy/Name");
377 }
378 else {
379 m_strategy.wireDecode(*val->elements_begin());
380 }
381 }
382}
383
384inline std::ostream&
385operator<<(std::ostream& os, const ControlParameters& parameters)
386{
387 os << "ControlParameters(";
388
389 if (parameters.hasName()) {
390 os << "Name: " << parameters.getName() << ", ";
391 }
392
393 if (parameters.hasFaceId()) {
394 os << "FaceId: " << parameters.getFaceId() << ", ";
395 }
396
397 if (parameters.hasUri()) {
398 os << "Uri: " << parameters.getUri() << ", ";
399 }
400
401 if (parameters.hasLocalControlFeature()) {
402 os << "LocalControlFeature: " << parameters.getLocalControlFeature() << ", ";
403 }
404
405 if (parameters.hasCost()) {
406 os << "Cost: " << parameters.getCost() << ", ";
407 }
408
409 if (parameters.hasStrategy()) {
410 os << "Strategy: " << parameters.getStrategy() << ", ";
411 }
412
413 os << ")";
414 return os;
415}
416
417
418} // namespace nfd
419} // namespace ndn
420
421#endif // NDN_MANAGEMENT_NFD_CONTROL_PARAMETERS_HPP