blob: 842c427ff011082aa17696dd24600934a8dc9e71 [file] [log] [blame]
Jeff Thompson25b4e612013-10-10 16:03:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Jeff Thompson47eecfc2013-07-07 22:56:46 -07002/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07003 * Copyright (C) 2013 Regents of the University of California.
Jeff Thompson47eecfc2013-07-07 22:56:46 -07004 * See COPYING for copyright and distribution information.
Jeff Thompsonb7f95562013-07-03 18:36:42 -07005 */
6
7#ifndef NDN_INTEREST_HPP
Jeff Thompson2d27e2f2013-08-09 12:55:00 -07008#define NDN_INTEREST_HPP
Jeff Thompsonb7f95562013-07-03 18:36:42 -07009
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080010#include "common.hpp"
Jeff Thompson53412192013-08-06 13:35:50 -070011#include "name.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080012#include "selectors.hpp"
Jeff Thompsonb7f95562013-07-03 18:36:42 -070013
14namespace ndn {
Alexander Afanasyevc348f832014-02-17 16:35:17 -080015
16const Milliseconds DEFAULT_INTEREST_LIFETIME = 4000;
17
Jeff Thompson8238d002013-07-10 11:56:49 -070018/**
Jeff Thompson8238d002013-07-10 11:56:49 -070019 * An Interest holds a Name and other fields for an interest.
20 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -080021class Interest : public enable_shared_from_this<Interest>
22{
Jeff Thompsonb7f95562013-07-03 18:36:42 -070023public:
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080024 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080025 * @brief Create a new Interest with an empty name and "none" for all values.
26 */
27 Interest()
28 : m_nonce(0)
29 , m_scope(-1)
30 , m_interestLifetime(-1.0)
31 {
32 }
33
34 /**
35 * @brief Create a new Interest with the given name and "none" for other values.
36 *
37 * @param name The name for the interest.
38 */
39 Interest(const Name& name)
40 : m_name(name)
41 , m_nonce(0)
42 , m_scope(-1)
43 , m_interestLifetime(-1.0)
44 {
45 }
46
47 /**
48 * Create a new Interest with the given name and interest lifetime and "none" for other values.
49 * @param name The name for the interest.
50 * @param interestLifetimeMilliseconds The interest lifetime in milliseconds, or -1 for none.
51 */
52 Interest(const Name& name, Milliseconds interestLifetime)
53 : m_name(name)
54 , m_nonce(0)
55 , m_scope(-1)
56 , m_interestLifetime(interestLifetime)
57 {
58 }
59
60 Interest(const Name& name,
61 const Selectors& selectors,
62 int scope,
63 Milliseconds interestLifetime,
64 uint32_t nonce = 0)
65 : m_name(name)
66 , m_selectors(selectors)
67 , m_nonce(nonce)
68 , m_scope(scope)
69 , m_interestLifetime(interestLifetime)
70 {
71 }
72
73 /**
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080074 * Create a new Interest for the given name and values.
75 * @param name
76 * @param minSuffixComponents
77 * @param maxSuffixComponents
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080078 * @param exclude
79 * @param childSelector
Alexander Afanasyev84681982014-01-03 13:26:09 -080080 * @param mustBeFresh
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080081 * @param scope
Alexander Afanasyev84681982014-01-03 13:26:09 -080082 * @param interestLifetime
Jeff Thompson1b4a7b12013-11-15 12:00:02 -080083 * @param nonce
84 */
Alexander Afanasyev84681982014-01-03 13:26:09 -080085 Interest(const Name& name,
86 int minSuffixComponents, int maxSuffixComponents,
87 const Exclude& exclude,
88 int childSelector,
89 bool mustBeFresh,
90 int scope,
91 Milliseconds interestLifetime,
92 uint32_t nonce = 0)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080093 : m_name(name)
94 , m_selectors(minSuffixComponents, maxSuffixComponents, exclude, childSelector, mustBeFresh)
95 , m_nonce(nonce)
96 , m_scope(scope)
97 , m_interestLifetime(interestLifetime)
Jeff Thompson3f76e9e2013-08-21 13:14:58 -070098 {
99 }
100
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800101 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800102 * @brief Fast encoding or block size estimation
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800103 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800104 template<bool T>
105 inline size_t
106 wireEncode(EncodingImpl<T> &block) const;
Jeff Thompsonf59a87a2013-07-31 16:55:41 -0700107
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800108 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800109 * @brief Encode to a wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800110 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800111 inline const Block&
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800112 wireEncode() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800113
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800114 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800115 * @brief Decode from the wire format
Jeff Thompson1b4a7b12013-11-15 12:00:02 -0800116 */
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800117 inline void
Alexander Afanasyev1eb961a2014-01-03 13:51:49 -0800118 wireDecode(const Block &wire);
Jeff Thompsond9e278c2013-07-08 15:20:13 -0700119
120 /**
Jeff Thompson13e280b2013-12-03 13:12:23 -0800121 * Encode the name according to the "NDN URI Scheme". If there are interest selectors, append "?" and
122 * added the selectors as a query string. For example "/test/name?ndn.ChildSelector=1".
123 * @return The URI string.
124 */
Alexander Afanasyev84681982014-01-03 13:26:09 -0800125 inline std::string
Jeff Thompson13e280b2013-12-03 13:12:23 -0800126 toUri() const;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700127
Alexander Afanasyev84681982014-01-03 13:26:09 -0800128 inline bool
129 hasSelectors() const;
130
131 inline bool
132 hasGuiders() const;
133
134 /**
135 * @brief Check if Interest name matches the given name (using ndn_Name_match) and the given name also conforms to the
136 * interest selectors.
137 * @param self A pointer to the ndn_Interest struct.
138 * @param name A pointer to the name to check.
139 * @return 1 if the name and interest selectors match, 0 otherwise.
140 */
141 bool
142 matchesName(const Name &name) const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800143
144 ///////////////////////////////////////////////////////////////////////////////
145 ///////////////////////////////////////////////////////////////////////////////
146 ///////////////////////////////////////////////////////////////////////////////
147 // Gettest/setters
Jeff Thompsoneb316a82013-07-09 15:11:17 -0700148
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800149 const Name&
150 getName() const
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700151 {
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800152 return m_name;
153 }
154
155 Interest&
156 setName(const Name& name)
157 {
158 m_name = name;
159 m_wire.reset();
160 return *this;
Jeff Thompsonc0486c12013-07-16 14:36:16 -0700161 }
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700162
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800163 //
Alexander Afanasyev84681982014-01-03 13:26:09 -0800164
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800165 const Selectors&
166 getSelectors() const
167 {
168 return m_selectors;
169 }
170
171 Interest&
172 setSelectors(const Selectors& selectors)
173 {
174 m_selectors = selectors;
175 m_wire.reset();
176 return *this;
177 }
178
179 //
180
181 int
182 getScope() const
183 {
184 return m_scope;
185 }
186
187 Interest&
188 setScope(int scope)
189 {
190 m_scope = scope;
191 m_wire.reset();
192 return *this;
193 }
194
195 //
196
197 Milliseconds
198 getInterestLifetime() const
199 {
200 return m_interestLifetime;
201 }
202
203 Interest&
204 setInterestLifetime(Milliseconds interestLifetime)
205 {
206 m_interestLifetime = interestLifetime;
207 m_wire.reset();
208 return *this;
209 }
210
211 //
212
213 /**
214 * @brief Get Interest's nonce
215 *
216 * If nonce was not set before this call, it will be automatically assigned to a random value
217 *
218 * Const reference needed for C decoding
219 */
220 const uint32_t&
221 getNonce() const;
222
223 Interest&
224 setNonce(uint32_t nonce)
225 {
226 m_nonce = nonce;
227 m_wire.reset();
228 return *this;
229 }
230
231 //
232
233 uint64_t
234 getIncomingFaceId() const
235 {
236 return m_incomingFaceId;
237 }
238
239 Interest&
240 setIncomingFaceId(uint64_t incomingFaceId)
241 {
242 m_incomingFaceId = incomingFaceId;
243 return *this;
244 }
245
246 //
247
248 ///////////////////////////////////////////////////////////////////////////////
249 ///////////////////////////////////////////////////////////////////////////////
250 ///////////////////////////////////////////////////////////////////////////////
251 // Wrappers for Selectors
252 //
253
254 int
255 getMinSuffixComponents() const
256 {
257 return m_selectors.getMinSuffixComponents();
258 }
259
260 Interest&
261 setMinSuffixComponents(int minSuffixComponents)
262 {
263 m_selectors.setMinSuffixComponents(minSuffixComponents);
264 m_wire.reset();
265 return *this;
266 }
267
268 //
269
270 int
271 getMaxSuffixComponents() const
272 {
273 return m_selectors.getMaxSuffixComponents();
274 }
275
276 Interest&
277 setMaxSuffixComponents(int maxSuffixComponents)
278 {
279 m_selectors.setMaxSuffixComponents(maxSuffixComponents);
280 m_wire.reset();
281 return *this;
282 }
283
284 //
285
286 const Exclude&
287 getExclude() const
288 {
289 return m_selectors.getExclude();
290 }
291
292 Interest&
293 setExclude(const Exclude& exclude)
294 {
295 m_selectors.setExclude(exclude);
296 m_wire.reset();
297 return *this;
298 }
299
300 //
301
302 int
303 getChildSelector() const
304 {
305 return m_selectors.getChildSelector();
306 }
307
308 Interest&
309 setChildSelector(int childSelector)
310 {
311 m_selectors.setChildSelector(childSelector);
312 m_wire.reset();
313 return *this;
314 }
315
316 //
317
318 int
319 getMustBeFresh() const
320 {
321 return m_selectors.getMustBeFresh();
322 }
323
324 Interest&
325 setMustBeFresh(bool mustBeFresh)
326 {
327 m_selectors.setMustBeFresh(mustBeFresh);
328 m_wire.reset();
329 return *this;
330 }
331
332 //
333
334private:
335 Name m_name;
336 Selectors m_selectors;
337 mutable uint32_t m_nonce;
338 int m_scope;
339 Milliseconds m_interestLifetime;
340
341 mutable Block m_wire;
Yingdi Yua4e57672014-02-06 11:16:17 -0800342
343 uint64_t m_incomingFaceId;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700344};
Alexander Afanasyev84681982014-01-03 13:26:09 -0800345
346std::ostream &
347operator << (std::ostream &os, const Interest &interest);
348
349inline std::string
350Interest::toUri() const
351{
352 std::ostringstream os;
353 os << *this;
354 return os.str();
355}
356
357inline bool
358Interest::hasSelectors() const
359{
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800360 return !m_selectors.empty();
Alexander Afanasyev84681982014-01-03 13:26:09 -0800361}
362
363inline bool
364Interest::hasGuiders() const
365{
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800366 return m_scope >= 0 ||
367 m_interestLifetime >= 0 ||
368 m_nonce > 0;
Alexander Afanasyev84681982014-01-03 13:26:09 -0800369}
370
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800371template<bool T>
372inline size_t
373Interest::wireEncode(EncodingImpl<T> &block) const
374{
375 size_t total_len = 0;
376
377 // Interest ::= INTEREST-TYPE TLV-LENGTH
378 // Name
379 // Selectors?
380 // Nonce
381 // Scope?
382 // InterestLifetime?
383
384 // (reverse encoding)
385
386 // InterestLifetime
387 if (getInterestLifetime() >= 0 && getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
388 {
389 total_len += prependNonNegativeIntegerBlock(block, Tlv::InterestLifetime, getInterestLifetime());
390 }
391
392 // Scope
393 if (getScope() >= 0)
394 {
395 total_len += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
396 }
397
398 // Nonce
399 total_len += prependNonNegativeIntegerBlock(block, Tlv::Nonce, getNonce());
400
401 // Selectors
402 if (!getSelectors().empty())
403 {
404 total_len += getSelectors().wireEncode(block);
405 }
406
407 // Name
408 total_len += getName().wireEncode(block);
409
410 total_len += block.prependVarNumber (total_len);
411 total_len += block.prependVarNumber (Tlv::Interest);
412 return total_len;
Jeff Thompsonb7f95562013-07-03 18:36:42 -0700413}
414
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800415inline const Block &
416Interest::wireEncode() const
417{
418 if (m_wire.hasWire())
419 return m_wire;
420
421 EncodingEstimator estimator;
422 size_t estimatedSize = wireEncode(estimator);
423
424 EncodingBuffer buffer(estimatedSize, 0);
425 wireEncode(buffer);
426
427 m_wire = buffer.block();
428 return m_wire;
429}
430
431inline void
432Interest::wireDecode(const Block &wire)
433{
434 m_wire = wire;
435 m_wire.parse();
436
437 // Interest ::= INTEREST-TYPE TLV-LENGTH
438 // Name
439 // Selectors?
440 // Nonce
441 // Scope?
442 // InterestLifetime?
443
444 if (m_wire.type() != Tlv::Interest)
445 throw Tlv::Error("Unexpected TLV number when decoding Interest");
446
447 // Name
448 m_name.wireDecode(m_wire.get(Tlv::Name));
449
450 // Selectors
451 Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
452 if (val != m_wire.elements_end())
453 {
454 m_selectors.wireDecode(*val);
455 }
456 else
457 m_selectors = Selectors();
458
459 // Nonce
460 val = m_wire.find(Tlv::Nonce);
461 if (val != m_wire.elements_end())
462 {
463 m_nonce = readNonNegativeInteger(*val);
464 }
465 else
466 m_nonce = 0;
467
468 // Scope
469 val = m_wire.find(Tlv::Scope);
470 if (val != m_wire.elements_end())
471 {
472 m_scope = readNonNegativeInteger(*val);
473 }
474 else
475 m_scope = -1;
476
477 // InterestLifetime
478 val = m_wire.find(Tlv::InterestLifetime);
479 if (val != m_wire.elements_end())
480 {
481 m_interestLifetime = readNonNegativeInteger(*val);
482 }
483 else
484 {
485 m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
486 }
487}
488
489
490} // namespace ndn
491
492#endif // NDN_INTEREST_HPP