blob: 412194b1df5f721b718db99bd4957af1ea487f3c [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;
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 Afanasyev0553cd52014-02-18 02:34:45 -0800120 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 //
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;
155 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
187 if (m_expirationPeriod > 0)
188 {
189 total_len += prependNonNegativeIntegerBlock(block,
190 tlv::nrd::ExpirationPeriod, m_expirationPeriod);
191 }
192
193 // Cost
194 if (m_cost != DEFAULT_COST)
195 {
196 total_len += prependNonNegativeIntegerBlock(block, tlv::nrd::Cost, m_cost);
197 }
198
199 // Flags
200 if (m_flags != DEFAULT_FLAGS)
201 {
202 total_len += prependNonNegativeIntegerBlock(block, tlv::nrd::Flags, m_flags);
203 }
204
205 // FaceId
206 if (m_faceId != INVALID_FACE_ID)
207 {
208 total_len += prependNonNegativeIntegerBlock(block, tlv::nrd::FaceId, m_faceId);
209 }
210
211 // Name
212 total_len += m_name.wireEncode(block);
213
214 total_len += block.prependVarNumber(total_len);
215 total_len += block.prependVarNumber(tlv::nrd::PrefixRegOptions);
216 return total_len;
217}
218
219inline const Block&
220PrefixRegOptions::wireEncode() const
221{
222 if (m_wire.hasWire())
223 return m_wire;
224
225 EncodingEstimator estimator;
226 size_t estimatedSize = wireEncode(estimator);
Obaid6e7f5f12014-03-11 14:46:10 -0500227
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800228 EncodingBuffer buffer(estimatedSize, 0);
229 wireEncode(buffer);
230
231 m_wire = buffer.block();
232 return m_wire;
233}
Obaid6e7f5f12014-03-11 14:46:10 -0500234
235inline void
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800236PrefixRegOptions::wireDecode(const Block& wire)
237{
238 // PrefixRegOptions ::= PREFIX-REG-OPTIONS-TYPE TLV-LENGTH
239 // Name
240 // FaceId?
241 // Flags?
Obaid6e7f5f12014-03-11 14:46:10 -0500242 // Cost?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800243 // ExpirationPeriod?
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800244 // Protocol?
245
246 m_name.clear();
247 m_faceId = INVALID_FACE_ID;
248 m_flags = DEFAULT_FLAGS;
249 m_cost = DEFAULT_COST;
250 m_expirationPeriod = -1;
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800251 m_protocol.clear();
252
253 m_wire = wire;
254
255 if (m_wire.type() != tlv::nrd::PrefixRegOptions)
256 throw Error("Requested decoding of PrefixRegOptions, but Block is of different type");
Obaid6e7f5f12014-03-11 14:46:10 -0500257
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800258 m_wire.parse ();
259
260 // Name
261 Block::element_const_iterator val = m_wire.find(Tlv::Name);
262 if (val != m_wire.elements_end())
263 {
264 m_name.wireDecode(*val);
265 }
266
267 // FaceId
268 val = m_wire.find(tlv::nrd::FaceId);
269 if (val != m_wire.elements_end())
270 {
271 m_faceId = readNonNegativeInteger(*val);
272 }
Obaid6e7f5f12014-03-11 14:46:10 -0500273
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800274 // Flags
275 val = m_wire.find(tlv::nrd::Flags);
276 if (val != m_wire.elements_end())
277 {
278 m_flags = readNonNegativeInteger(*val);
279 }
280
281 // Cost
282 val = m_wire.find(tlv::nrd::Cost);
283 if (val != m_wire.elements_end())
284 {
285 m_cost = readNonNegativeInteger(*val);
286 }
287
288 // ExpirationPeriod
289 val = m_wire.find(tlv::nrd::ExpirationPeriod);
290 if (val != m_wire.elements_end())
291 {
292 m_expirationPeriod = readNonNegativeInteger(*val);
293 }
294
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800295 // Protocol
296 val = m_wire.find(tlv::nrd::Protocol);
297 if (val != m_wire.elements_end())
298 {
299 m_protocol = std::string(reinterpret_cast<const char*>(val->value()),
300 val->value_size());
301 }
302}
303
Obaid6e7f5f12014-03-11 14:46:10 -0500304inline std::ostream&
305operator << (std::ostream &os, const PrefixRegOptions &option)
306{
307 os << "PrefixRegOptions(";
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800308
Obaid6e7f5f12014-03-11 14:46:10 -0500309 // Name
310 os << "Prefix: " << option.getName() << ", ";
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800311
Obaid6e7f5f12014-03-11 14:46:10 -0500312 // FaceID
313 os << "FaceID: " << option.getFaceId() << ", ";
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800314
Obaid6e7f5f12014-03-11 14:46:10 -0500315 // Flags
316 os << "Flags: " << option.getFlags() << ", ";
317
318 // Cost
319 os << "Cost: " << option.getCost() << ", ";
320
321 // ExpirationPeriod
322 os << "ExpirationPeriod: " << option.getExpirationPeriod() << ", ";
323
324 // Protocol
325 os << "Protocol: " << option.getProtocol();
326
327 os << ")";
328 return os;
329}
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800330
331} // namespace nrd
332} // namespace ndn
333
334#endif // NDN_MANAGEMENT_NRD_PREFIX_REG_OPTIONS_HPP