blob: 12136e84ae336558c38c682adb3316f2245e4792 [file] [log] [blame]
Alexander Afanasyev0553cd52014-02-18 02:34:45 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2014 Regents of the University of California.
4 *
5 * See COPYING for copyright and distribution information.
6 */
7
8#ifndef NDN_MANAGEMENT_NRD_PREFIX_REG_OPTIONS_HPP
9#define NDN_MANAGEMENT_NRD_PREFIX_REG_OPTIONS_HPP
10
11#include "../encoding/encoding-buffer.hpp"
12#include "../encoding/tlv-nrd.hpp"
13#include "../name.hpp"
14
15namespace ndn {
16namespace nrd {
17
18const uint64_t INVALID_FACE_ID = std::numeric_limits<uint64_t>::max();
19const uint64_t DEFAULT_COST = 0;
20const uint64_t DEFAULT_FLAGS = tlv::nrd::NDN_FORW_CHILD_INHERIT;
21
22/**
23 * @brief Abstraction for prefix registration options for NRD Prefix registration protocol
24 *
25 * @see http://redmine.named-data.net/projects/nrd/wiki/NRD_Prefix_Registration_protocol
26 */
27class PrefixRegOptions {
28public:
29 struct Error : public Tlv::Error { Error(const std::string &what) : Tlv::Error(what) {} };
30
31 PrefixRegOptions()
32 : m_faceId (INVALID_FACE_ID)
33 , m_flags (DEFAULT_FLAGS)
34 , m_cost (DEFAULT_COST)
35 , m_expirationPeriod (-1)
36 {
37 }
38
39 PrefixRegOptions(const Block& block)
40 {
41 wireDecode(block);
42 }
43
44 template<bool T>
45 size_t
46 wireEncode(EncodingImpl<T>& block) const;
47
48 const Block&
49 wireEncode() const;
50
51 void
52 wireDecode(const Block& wire);
53
54 ////////////////////////////////////////////////////////
55
56 const Name&
57 getName() const
58 {
59 return m_name;
60 }
61
62 PrefixRegOptions&
63 setName(const Name& name)
64 {
65 m_name = name;
66 m_wire.reset();
67 return *this;
68 }
69
70 //
71
Alexander Afanasyev87a7f5f2014-02-26 11:40:13 -080072 uint64_t
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080073 getFaceId() const
74 {
75 return m_faceId;
76 }
77
78 PrefixRegOptions&
Alexander Afanasyev87a7f5f2014-02-26 11:40:13 -080079 setFaceId(uint64_t faceId)
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080080 {
81 m_faceId = faceId;
82 m_wire.reset();
83 return *this;
84 }
85
86 //
87
88 uint64_t
89 getFlags() const
90 {
91 return m_flags;
92 }
93
94 PrefixRegOptions&
95 setFlags(uint64_t flags)
96 {
97 m_flags = flags;
98 m_wire.reset();
99 return *this;
100 }
101
102 //
103
104 uint64_t
105 getCost() const
106 {
107 return m_cost;
108 }
109
110 PrefixRegOptions&
111 setCost(uint64_t cost)
112 {
113 m_cost = cost;
114 m_wire.reset();
115 return *this;
116 }
117
118 //
119
120 Milliseconds
121 getExpirationPeriod() const
122 {
123 return m_expirationPeriod;
124 }
125
126 PrefixRegOptions&
127 setExpirationPeriod(Milliseconds expirationPeriod)
128 {
129 m_expirationPeriod = expirationPeriod;
130 m_wire.reset();
131 return *this;
132 }
133
134 //
135
136 const Name&
137 getStrategy() const
138 {
139 return m_strategy;
140 }
141
142 PrefixRegOptions&
143 setStrategy(const Name& strategy)
144 {
145 m_strategy = strategy;
146 m_wire.reset();
147 return *this;
148 }
149
150 //
151
152 const std::string&
153 getProtocol() const
154 {
155 return m_protocol;
156 }
157
158 PrefixRegOptions&
159 setProtocol(const std::string& protocol)
160 {
161 m_protocol = protocol;
162 m_wire.reset();
163 return *this;
164 }
165
166private:
167 Name m_name;
168 uint64_t m_faceId;
169 uint64_t m_flags;
170 uint64_t m_cost;
171 Milliseconds m_expirationPeriod;
172 Name m_strategy;
173 std::string m_protocol;
174
175 mutable Block m_wire;
176};
177
178template<bool T>
179inline size_t
180PrefixRegOptions::wireEncode(EncodingImpl<T>& block) const
181{
182 size_t total_len = 0;
183
184 // PrefixRegOptions ::= PREFIX-REG-OPTIONS-TYPE TLV-LENGTH
185 // Name
186 // FaceId?
187 // Flags?
188 // Cost?
189 // ExpirationPeriod?
190 // StrategyName?
191 // Protocol?
192
193 // (reverse encoding)
194
195 // Protocol
196 if (!m_protocol.empty())
197 {
198 total_len += prependByteArrayBlock(block,
199 tlv::nrd::Protocol,
200 reinterpret_cast<const uint8_t*>(m_protocol.c_str()),
201 m_protocol.size());
202 }
203
204 // StrategyName
205 if (!m_strategy.empty())
206 {
207 total_len += prependNestedBlock(block, tlv::nrd::StrategyName, m_strategy);
208 }
209
210 // ExpirationPeriod
211 if (m_expirationPeriod > 0)
212 {
213 total_len += prependNonNegativeIntegerBlock(block,
214 tlv::nrd::ExpirationPeriod, m_expirationPeriod);
215 }
216
217 // Cost
218 if (m_cost != DEFAULT_COST)
219 {
220 total_len += prependNonNegativeIntegerBlock(block, tlv::nrd::Cost, m_cost);
221 }
222
223 // Flags
224 if (m_flags != DEFAULT_FLAGS)
225 {
226 total_len += prependNonNegativeIntegerBlock(block, tlv::nrd::Flags, m_flags);
227 }
228
229 // FaceId
230 if (m_faceId != INVALID_FACE_ID)
231 {
232 total_len += prependNonNegativeIntegerBlock(block, tlv::nrd::FaceId, m_faceId);
233 }
234
235 // Name
236 total_len += m_name.wireEncode(block);
237
238 total_len += block.prependVarNumber(total_len);
239 total_len += block.prependVarNumber(tlv::nrd::PrefixRegOptions);
240 return total_len;
241}
242
243inline const Block&
244PrefixRegOptions::wireEncode() const
245{
246 if (m_wire.hasWire())
247 return m_wire;
248
249 EncodingEstimator estimator;
250 size_t estimatedSize = wireEncode(estimator);
251
252 EncodingBuffer buffer(estimatedSize, 0);
253 wireEncode(buffer);
254
255 m_wire = buffer.block();
256 return m_wire;
257}
258
259inline void
260PrefixRegOptions::wireDecode(const Block& wire)
261{
262 // PrefixRegOptions ::= PREFIX-REG-OPTIONS-TYPE TLV-LENGTH
263 // Name
264 // FaceId?
265 // Flags?
266 // Cost?
267 // ExpirationPeriod?
268 // StrategyName?
269 // Protocol?
270
271 m_name.clear();
272 m_faceId = INVALID_FACE_ID;
273 m_flags = DEFAULT_FLAGS;
274 m_cost = DEFAULT_COST;
275 m_expirationPeriod = -1;
276 m_strategy.clear();
277 m_protocol.clear();
278
279 m_wire = wire;
280
281 if (m_wire.type() != tlv::nrd::PrefixRegOptions)
282 throw Error("Requested decoding of PrefixRegOptions, but Block is of different type");
283
284 m_wire.parse ();
285
286 // Name
287 Block::element_const_iterator val = m_wire.find(Tlv::Name);
288 if (val != m_wire.elements_end())
289 {
290 m_name.wireDecode(*val);
291 }
292
293 // FaceId
294 val = m_wire.find(tlv::nrd::FaceId);
295 if (val != m_wire.elements_end())
296 {
297 m_faceId = readNonNegativeInteger(*val);
298 }
299
300 // Flags
301 val = m_wire.find(tlv::nrd::Flags);
302 if (val != m_wire.elements_end())
303 {
304 m_flags = readNonNegativeInteger(*val);
305 }
306
307 // Cost
308 val = m_wire.find(tlv::nrd::Cost);
309 if (val != m_wire.elements_end())
310 {
311 m_cost = readNonNegativeInteger(*val);
312 }
313
314 // ExpirationPeriod
315 val = m_wire.find(tlv::nrd::ExpirationPeriod);
316 if (val != m_wire.elements_end())
317 {
318 m_expirationPeriod = readNonNegativeInteger(*val);
319 }
320
321 // StrategyName
322 val = m_wire.find(tlv::nrd::StrategyName);
323 if (val != m_wire.elements_end())
324 {
325 val->parse();
326 if (!val->elements().empty())
327 m_strategy.wireDecode(*val->elements_begin());
328 }
329
330 // Protocol
331 val = m_wire.find(tlv::nrd::Protocol);
332 if (val != m_wire.elements_end())
333 {
334 m_protocol = std::string(reinterpret_cast<const char*>(val->value()),
335 val->value_size());
336 }
337}
338
339// inline std::ostream&
340// operator << (std::ostream &os, const PrefixRegOptions &option)
341// {
342// os << "ForwardingEntry(";
343
344// // Name
345// os << "Prefix: " << option.getName() << ", ";
346
347// // FaceID
348// os << "FaceID: " << option.getFaceId() << ", ";
349
350// // Cost
351// os << "Cost: " << option.getCost() << ", ";
352
353// // Strategy
354// os << "Strategy: " << option.getStrategy() << ", ";
355
356// os << ")";
357// return os;
358// }
359
360} // namespace nrd
361} // namespace ndn
362
363#endif // NDN_MANAGEMENT_NRD_PREFIX_REG_OPTIONS_HPP