blob: c80d04b79bc23a2bd21d8dc18536f2f0cc808194 [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 Afanasyevaa0e7da2014-03-17 14:37:33 -070029 struct Error : public Tlv::Error { Error(const std::string& what) : Tlv::Error(what) {} };
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080030
31 PrefixRegOptions()
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -070032 : m_faceId(INVALID_FACE_ID)
33 , m_flags(DEFAULT_FLAGS)
34 , m_cost(DEFAULT_COST)
35 , m_expirationPeriod(time::milliseconds::min())
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080036 {
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;
Obaid6e7f5f12014-03-11 14:46:10 -050047
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080048 const Block&
49 wireEncode() const;
Obaid6e7f5f12014-03-11 14:46:10 -050050
51 void
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080052 wireDecode(const Block& wire);
Obaid6e7f5f12014-03-11 14:46:10 -050053
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080054 ////////////////////////////////////////////////////////
Obaid6e7f5f12014-03-11 14:46:10 -050055
56 const Name&
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080057 getName() const
58 {
59 return m_name;
60 }
Obaid6e7f5f12014-03-11 14:46:10 -050061
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080062 PrefixRegOptions&
63 setName(const Name& name)
64 {
65 m_name = name;
66 m_wire.reset();
67 return *this;
68 }
69
70 //
Obaid6e7f5f12014-03-11 14:46:10 -050071
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 //
Obaid6e7f5f12014-03-11 14:46:10 -050087
88 uint64_t
Alexander Afanasyev0553cd52014-02-18 02:34:45 -080089 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 //
Obaid6e7f5f12014-03-11 14:46:10 -0500103
104 uint64_t
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800105 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 //
Obaid6e7f5f12014-03-11 14:46:10 -0500119
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700120 const time::milliseconds&
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800121 getExpirationPeriod() const
122 {
123 return m_expirationPeriod;
124 }
125
126 PrefixRegOptions&
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700127 setExpirationPeriod(const time::milliseconds& expirationPeriod)
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800128 {
129 m_expirationPeriod = expirationPeriod;
130 m_wire.reset();
131 return *this;
132 }
133
134 //
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800135
Obaid6e7f5f12014-03-11 14:46:10 -0500136 const std::string&
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800137 getProtocol() const
138 {
139 return m_protocol;
140 }
141
142 PrefixRegOptions&
143 setProtocol(const std::string& protocol)
144 {
145 m_protocol = protocol;
146 m_wire.reset();
147 return *this;
148 }
Obaid6e7f5f12014-03-11 14:46:10 -0500149
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800150private:
151 Name m_name;
152 uint64_t m_faceId;
153 uint64_t m_flags;
154 uint64_t m_cost;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700155 time::milliseconds m_expirationPeriod;
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800156 std::string m_protocol;
Obaid6e7f5f12014-03-11 14:46:10 -0500157
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800158 mutable Block m_wire;
159};
160
161template<bool T>
162inline size_t
163PrefixRegOptions::wireEncode(EncodingImpl<T>& block) const
164{
165 size_t total_len = 0;
166
167 // PrefixRegOptions ::= PREFIX-REG-OPTIONS-TYPE TLV-LENGTH
168 // Name
169 // FaceId?
170 // Flags?
Obaid6e7f5f12014-03-11 14:46:10 -0500171 // Cost?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800172 // ExpirationPeriod?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800173 // Protocol?
174
175 // (reverse encoding)
176
177 // Protocol
178 if (!m_protocol.empty())
179 {
180 total_len += prependByteArrayBlock(block,
181 tlv::nrd::Protocol,
182 reinterpret_cast<const uint8_t*>(m_protocol.c_str()),
183 m_protocol.size());
184 }
185
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800186 // ExpirationPeriod
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700187 if (m_expirationPeriod > time::milliseconds::zero())
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800188 {
189 total_len += prependNonNegativeIntegerBlock(block,
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700190 tlv::nrd::ExpirationPeriod,
191 m_expirationPeriod.count());
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800192 }
193
194 // Cost
195 if (m_cost != DEFAULT_COST)
196 {
197 total_len += prependNonNegativeIntegerBlock(block, tlv::nrd::Cost, m_cost);
198 }
199
200 // Flags
201 if (m_flags != DEFAULT_FLAGS)
202 {
203 total_len += prependNonNegativeIntegerBlock(block, tlv::nrd::Flags, m_flags);
204 }
205
206 // FaceId
207 if (m_faceId != INVALID_FACE_ID)
208 {
209 total_len += prependNonNegativeIntegerBlock(block, tlv::nrd::FaceId, m_faceId);
210 }
211
212 // Name
213 total_len += m_name.wireEncode(block);
214
215 total_len += block.prependVarNumber(total_len);
216 total_len += block.prependVarNumber(tlv::nrd::PrefixRegOptions);
217 return total_len;
218}
219
220inline const Block&
221PrefixRegOptions::wireEncode() const
222{
223 if (m_wire.hasWire())
224 return m_wire;
225
226 EncodingEstimator estimator;
227 size_t estimatedSize = wireEncode(estimator);
Obaid6e7f5f12014-03-11 14:46:10 -0500228
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800229 EncodingBuffer buffer(estimatedSize, 0);
230 wireEncode(buffer);
231
232 m_wire = buffer.block();
233 return m_wire;
234}
Obaid6e7f5f12014-03-11 14:46:10 -0500235
236inline void
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800237PrefixRegOptions::wireDecode(const Block& wire)
238{
239 // PrefixRegOptions ::= PREFIX-REG-OPTIONS-TYPE TLV-LENGTH
240 // Name
241 // FaceId?
242 // Flags?
Obaid6e7f5f12014-03-11 14:46:10 -0500243 // Cost?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800244 // ExpirationPeriod?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800245 // Protocol?
246
247 m_name.clear();
248 m_faceId = INVALID_FACE_ID;
249 m_flags = DEFAULT_FLAGS;
250 m_cost = DEFAULT_COST;
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700251 m_expirationPeriod = time::milliseconds::min();
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800252 m_protocol.clear();
253
254 m_wire = wire;
255
256 if (m_wire.type() != tlv::nrd::PrefixRegOptions)
257 throw Error("Requested decoding of PrefixRegOptions, but Block is of different type");
Obaid6e7f5f12014-03-11 14:46:10 -0500258
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800259 m_wire.parse ();
260
261 // Name
262 Block::element_const_iterator val = m_wire.find(Tlv::Name);
263 if (val != m_wire.elements_end())
264 {
265 m_name.wireDecode(*val);
266 }
267
268 // FaceId
269 val = m_wire.find(tlv::nrd::FaceId);
270 if (val != m_wire.elements_end())
271 {
272 m_faceId = readNonNegativeInteger(*val);
273 }
Obaid6e7f5f12014-03-11 14:46:10 -0500274
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800275 // Flags
276 val = m_wire.find(tlv::nrd::Flags);
277 if (val != m_wire.elements_end())
278 {
279 m_flags = readNonNegativeInteger(*val);
280 }
281
282 // Cost
283 val = m_wire.find(tlv::nrd::Cost);
284 if (val != m_wire.elements_end())
285 {
286 m_cost = readNonNegativeInteger(*val);
287 }
288
289 // ExpirationPeriod
290 val = m_wire.find(tlv::nrd::ExpirationPeriod);
291 if (val != m_wire.elements_end())
292 {
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700293 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800294 }
295
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800296 // Protocol
297 val = m_wire.find(tlv::nrd::Protocol);
298 if (val != m_wire.elements_end())
299 {
300 m_protocol = std::string(reinterpret_cast<const char*>(val->value()),
301 val->value_size());
302 }
303}
304
Obaid6e7f5f12014-03-11 14:46:10 -0500305inline std::ostream&
306operator << (std::ostream &os, const PrefixRegOptions &option)
307{
308 os << "PrefixRegOptions(";
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800309
Obaid6e7f5f12014-03-11 14:46:10 -0500310 // Name
311 os << "Prefix: " << option.getName() << ", ";
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800312
Obaid6e7f5f12014-03-11 14:46:10 -0500313 // FaceID
314 os << "FaceID: " << option.getFaceId() << ", ";
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800315
Obaid6e7f5f12014-03-11 14:46:10 -0500316 // Flags
317 os << "Flags: " << option.getFlags() << ", ";
318
319 // Cost
320 os << "Cost: " << option.getCost() << ", ";
321
322 // ExpirationPeriod
323 os << "ExpirationPeriod: " << option.getExpirationPeriod() << ", ";
324
325 // Protocol
326 os << "Protocol: " << option.getProtocol();
327
328 os << ")";
329 return os;
330}
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800331
332} // namespace nrd
333} // namespace ndn
334
335#endif // NDN_MANAGEMENT_NRD_PREFIX_REG_OPTIONS_HPP