blob: 2c37c4aaa217c4cfa4499b7d074838f1d8a85924 [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:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070029 class Error : public Tlv::Error
30 {
31 public:
32 explicit
33 Error(const std::string& what)
34 : Tlv::Error(what)
35 {
36 }
37 };
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080038
39 PrefixRegOptions()
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070040 : m_faceId(INVALID_FACE_ID)
41 , m_flags(DEFAULT_FLAGS)
42 , m_cost(DEFAULT_COST)
43 , m_expirationPeriod(time::milliseconds::min())
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080044 {
45 }
46
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070047 explicit
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080048 PrefixRegOptions(const Block& block)
49 {
50 wireDecode(block);
51 }
52
53 template<bool T>
54 size_t
55 wireEncode(EncodingImpl<T>& block) const;
Obaid6e7f5f12014-03-11 14:46:10 -050056
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080057 const Block&
58 wireEncode() const;
Obaid6e7f5f12014-03-11 14:46:10 -050059
60 void
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080061 wireDecode(const Block& wire);
Obaid6e7f5f12014-03-11 14:46:10 -050062
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080063 ////////////////////////////////////////////////////////
Obaid6e7f5f12014-03-11 14:46:10 -050064
65 const Name&
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080066 getName() const
67 {
68 return m_name;
69 }
Obaid6e7f5f12014-03-11 14:46:10 -050070
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080071 PrefixRegOptions&
72 setName(const Name& name)
73 {
74 m_name = name;
75 m_wire.reset();
76 return *this;
77 }
78
79 //
Obaid6e7f5f12014-03-11 14:46:10 -050080
Alexander Afanasyev87a7f5f2014-02-26 11:40:13 -080081 uint64_t
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080082 getFaceId() const
83 {
84 return m_faceId;
85 }
86
87 PrefixRegOptions&
Alexander Afanasyev87a7f5f2014-02-26 11:40:13 -080088 setFaceId(uint64_t faceId)
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080089 {
90 m_faceId = faceId;
91 m_wire.reset();
92 return *this;
93 }
94
95 //
Obaid6e7f5f12014-03-11 14:46:10 -050096
97 uint64_t
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080098 getFlags() const
99 {
100 return m_flags;
101 }
102
103 PrefixRegOptions&
104 setFlags(uint64_t flags)
105 {
106 m_flags = flags;
107 m_wire.reset();
108 return *this;
109 }
110
111 //
Obaid6e7f5f12014-03-11 14:46:10 -0500112
113 uint64_t
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800114 getCost() const
115 {
116 return m_cost;
117 }
118
119 PrefixRegOptions&
120 setCost(uint64_t cost)
121 {
122 m_cost = cost;
123 m_wire.reset();
124 return *this;
125 }
126
127 //
Obaid6e7f5f12014-03-11 14:46:10 -0500128
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700129 const time::milliseconds&
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800130 getExpirationPeriod() const
131 {
132 return m_expirationPeriod;
133 }
134
135 PrefixRegOptions&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700136 setExpirationPeriod(const time::milliseconds& expirationPeriod)
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800137 {
138 m_expirationPeriod = expirationPeriod;
139 m_wire.reset();
140 return *this;
141 }
142
143 //
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800144
Obaid6e7f5f12014-03-11 14:46:10 -0500145 const std::string&
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800146 getProtocol() const
147 {
148 return m_protocol;
149 }
150
151 PrefixRegOptions&
152 setProtocol(const std::string& protocol)
153 {
154 m_protocol = protocol;
155 m_wire.reset();
156 return *this;
157 }
Obaid6e7f5f12014-03-11 14:46:10 -0500158
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800159private:
160 Name m_name;
161 uint64_t m_faceId;
162 uint64_t m_flags;
163 uint64_t m_cost;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700164 time::milliseconds m_expirationPeriod;
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800165 std::string m_protocol;
Obaid6e7f5f12014-03-11 14:46:10 -0500166
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800167 mutable Block m_wire;
168};
169
170template<bool T>
171inline size_t
172PrefixRegOptions::wireEncode(EncodingImpl<T>& block) const
173{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700174 size_t totalLength = 0;
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800175
176 // PrefixRegOptions ::= PREFIX-REG-OPTIONS-TYPE TLV-LENGTH
177 // Name
178 // FaceId?
179 // Flags?
Obaid6e7f5f12014-03-11 14:46:10 -0500180 // Cost?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800181 // ExpirationPeriod?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800182 // Protocol?
183
184 // (reverse encoding)
185
186 // Protocol
187 if (!m_protocol.empty())
188 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700189 totalLength += prependByteArrayBlock(block,
190 tlv::nrd::Protocol,
191 reinterpret_cast<const uint8_t*>(m_protocol.c_str()),
192 m_protocol.size());
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800193 }
194
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800195 // ExpirationPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700196 if (m_expirationPeriod > time::milliseconds::zero())
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800197 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700198 totalLength += prependNonNegativeIntegerBlock(block,
199 tlv::nrd::ExpirationPeriod,
200 m_expirationPeriod.count());
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800201 }
202
203 // Cost
204 if (m_cost != DEFAULT_COST)
205 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700206 totalLength += prependNonNegativeIntegerBlock(block, tlv::nrd::Cost, m_cost);
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800207 }
208
209 // Flags
210 if (m_flags != DEFAULT_FLAGS)
211 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700212 totalLength += prependNonNegativeIntegerBlock(block, tlv::nrd::Flags, m_flags);
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800213 }
214
215 // FaceId
216 if (m_faceId != INVALID_FACE_ID)
217 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700218 totalLength += prependNonNegativeIntegerBlock(block, tlv::nrd::FaceId, m_faceId);
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800219 }
220
221 // Name
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700222 totalLength += m_name.wireEncode(block);
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800223
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700224 totalLength += block.prependVarNumber(totalLength);
225 totalLength += block.prependVarNumber(tlv::nrd::PrefixRegOptions);
226 return totalLength;
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800227}
228
229inline const Block&
230PrefixRegOptions::wireEncode() const
231{
232 if (m_wire.hasWire())
233 return m_wire;
234
235 EncodingEstimator estimator;
236 size_t estimatedSize = wireEncode(estimator);
Obaid6e7f5f12014-03-11 14:46:10 -0500237
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800238 EncodingBuffer buffer(estimatedSize, 0);
239 wireEncode(buffer);
240
241 m_wire = buffer.block();
242 return m_wire;
243}
Obaid6e7f5f12014-03-11 14:46:10 -0500244
245inline void
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800246PrefixRegOptions::wireDecode(const Block& wire)
247{
248 // PrefixRegOptions ::= PREFIX-REG-OPTIONS-TYPE TLV-LENGTH
249 // Name
250 // FaceId?
251 // Flags?
Obaid6e7f5f12014-03-11 14:46:10 -0500252 // Cost?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800253 // ExpirationPeriod?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800254 // Protocol?
255
256 m_name.clear();
257 m_faceId = INVALID_FACE_ID;
258 m_flags = DEFAULT_FLAGS;
259 m_cost = DEFAULT_COST;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700260 m_expirationPeriod = time::milliseconds::min();
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800261 m_protocol.clear();
262
263 m_wire = wire;
264
265 if (m_wire.type() != tlv::nrd::PrefixRegOptions)
266 throw Error("Requested decoding of PrefixRegOptions, but Block is of different type");
Obaid6e7f5f12014-03-11 14:46:10 -0500267
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800268 m_wire.parse ();
269
270 // Name
271 Block::element_const_iterator val = m_wire.find(Tlv::Name);
272 if (val != m_wire.elements_end())
273 {
274 m_name.wireDecode(*val);
275 }
276
277 // FaceId
278 val = m_wire.find(tlv::nrd::FaceId);
279 if (val != m_wire.elements_end())
280 {
281 m_faceId = readNonNegativeInteger(*val);
282 }
Obaid6e7f5f12014-03-11 14:46:10 -0500283
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800284 // Flags
285 val = m_wire.find(tlv::nrd::Flags);
286 if (val != m_wire.elements_end())
287 {
288 m_flags = readNonNegativeInteger(*val);
289 }
290
291 // Cost
292 val = m_wire.find(tlv::nrd::Cost);
293 if (val != m_wire.elements_end())
294 {
295 m_cost = readNonNegativeInteger(*val);
296 }
297
298 // ExpirationPeriod
299 val = m_wire.find(tlv::nrd::ExpirationPeriod);
300 if (val != m_wire.elements_end())
301 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700302 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800303 }
304
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800305 // Protocol
306 val = m_wire.find(tlv::nrd::Protocol);
307 if (val != m_wire.elements_end())
308 {
309 m_protocol = std::string(reinterpret_cast<const char*>(val->value()),
310 val->value_size());
311 }
312}
313
Obaid6e7f5f12014-03-11 14:46:10 -0500314inline std::ostream&
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700315operator << (std::ostream& os, const PrefixRegOptions& option)
Obaid6e7f5f12014-03-11 14:46:10 -0500316{
317 os << "PrefixRegOptions(";
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800318
Obaid6e7f5f12014-03-11 14:46:10 -0500319 // Name
320 os << "Prefix: " << option.getName() << ", ";
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800321
Obaid6e7f5f12014-03-11 14:46:10 -0500322 // FaceID
323 os << "FaceID: " << option.getFaceId() << ", ";
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800324
Obaid6e7f5f12014-03-11 14:46:10 -0500325 // Flags
326 os << "Flags: " << option.getFlags() << ", ";
327
328 // Cost
329 os << "Cost: " << option.getCost() << ", ";
330
331 // ExpirationPeriod
332 os << "ExpirationPeriod: " << option.getExpirationPeriod() << ", ";
333
334 // Protocol
335 os << "Protocol: " << option.getProtocol();
336
337 os << ")";
338 return os;
339}
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800340
341} // namespace nrd
342} // namespace ndn
343
344#endif // NDN_MANAGEMENT_NRD_PREFIX_REG_OPTIONS_HPP