blob: af4fc0f741fce65b55cbe6f59fd688c9fefa8ad8 [file] [log] [blame]
Alexander Afanasyev1043c702013-07-15 16:21:09 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2011 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
19 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
20 */
21
22#include "../ccnb.h"
23
24#include "wire-ccnb.h"
25
26#include "ns3/log.h"
27#include "ns3/unused.h"
28#include "ns3/packet.h"
29
30#include "ccnb-parser/visitors/name-visitor.h"
31#include "ccnb-parser/visitors/non-negative-integer-visitor.h"
32#include "ccnb-parser/visitors/timestamp-visitor.h"
33#include "ccnb-parser/visitors/uint32t-blob-visitor.h"
34
35#include "ccnb-parser/syntax-tree/block.h"
36#include "ccnb-parser/syntax-tree/dtag.h"
37
38#include <boost/foreach.hpp>
39
40NS_LOG_COMPONENT_DEFINE ("ndn.wire.Ccnb.Interest");
41
42NDN_NAMESPACE_BEGIN
43
44namespace wire {
45namespace ccnb {
46
47NS_OBJECT_ENSURE_REGISTERED (Interest);
48
49TypeId
50Interest::GetTypeId (void)
51{
52 static TypeId tid = TypeId ("ns3::ndn::Interest::Ccnb")
53 .SetGroupName ("Ndn")
54 .SetParent<Header> ()
55 .AddConstructor<Interest> ()
56 ;
57 return tid;
58}
59
60TypeId
61Interest::GetInstanceTypeId (void) const
62{
63 return GetTypeId ();
64}
65
66Interest::Interest ()
67 : m_interest (Create<ndn::Interest> ())
68{
69}
70
71Interest::Interest (Ptr<ndn::Interest> interest)
72 : m_interest (interest)
73{
74}
75
76Ptr<ndn::Interest>
77Interest::GetInterest ()
78{
79 return m_interest;
80}
81
82Ptr<Packet>
83Interest::ToWire (Ptr<const ndn::Interest> interest)
84{
85 Ptr<const Packet> p = interest->GetWire ();
86 if (!p)
87 {
88 Ptr<Packet> packet = Create<Packet> (*interest->GetPayload ());
89 Interest wireEncoding (ConstCast<ndn::Interest> (interest));
90 packet->AddHeader (wireEncoding);
91 interest->SetWire (packet);
92
93 p = packet;
94 }
95
96 return p->Copy ();
97}
98
99Ptr<ndn::Interest>
100Interest::FromWire (Ptr<Packet> packet)
101{
102 Ptr<ndn::Interest> interest = Create<ndn::Interest> ();
Alexander Afanasyevdfa69852013-12-05 15:50:44 -0800103 Ptr<Packet> wire = packet->Copy ();
Alexander Afanasyev1043c702013-07-15 16:21:09 -0700104
105 Interest wireEncoding (interest);
106 packet->RemoveHeader (wireEncoding);
107
108 interest->SetPayload (packet);
Alexander Afanasyevdfa69852013-12-05 15:50:44 -0800109 interest->SetWire (wire);
Alexander Afanasyev1043c702013-07-15 16:21:09 -0700110
111 return interest;
112}
113
114void
115Interest::Serialize (Buffer::Iterator start) const
116{
117 Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Interest, CcnbParser::CCN_DTAG); // <Interest>
118
Alexander Afanasyevdfd52492013-09-03 12:48:41 -0700119 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG); // <Name>
Alexander Afanasyeva89bc102013-07-16 10:17:31 -0700120 Ccnb::SerializeName (start, m_interest->GetName()); // <Component>...</Component>...
Alexander Afanasyevdfd52492013-09-03 12:48:41 -0700121 // Ccnb::AppendCloser (start); // </Name>
Alexander Afanasyev1043c702013-07-15 16:21:09 -0700122
123 // if (m_interest->GetMinSuffixComponents() >= 0)
124 // {
125 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_MinSuffixComponents, CcnbParser::CCN_DTAG);
126 // Ccnb::AppendNumber (start, m_interest->GetMinSuffixComponents ());
127 // Ccnb::AppendCloser (start);
128 // }
129 // if (m_interest->GetMaxSuffixComponents() >= 0)
130 // {
131 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_MaxSuffixComponents, CcnbParser::CCN_DTAG);
132 // Ccnb::AppendNumber (start, m_interest->GetMaxSuffixComponents ());
133 // Ccnb::AppendCloser (start);
134 // }
135 // if (m_interest->IsEnabledExclude() && m_interest->GetExclude().size() > 0)
136 // {
137 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Exclude, CcnbParser::CCN_DTAG); // <Exclude>
138 // Ccnb::AppendName (start, m_interest->GetExclude()); // <Component>...</Component>...
139 // Ccnb::AppendCloser (start); // </Exclude>
140 // }
141 // if (m_interest->IsEnabledChildSelector())
142 // {
143 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_ChildSelector, CcnbParser::CCN_DTAG);
144 // Ccnb::AppendNumber (start, 1);
145 // Ccnb::AppendCloser (start);
146 // }
147 // if (m_interest->IsEnabledAnswerOriginKind())
148 // {
149 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_AnswerOriginKind, CcnbParser::CCN_DTAG);
150 // Ccnb::AppendNumber (start, 1);
151 // Ccnb::AppendCloser (start);
152 // }
153 if (m_interest->GetScope() >= 0)
154 {
155 Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Scope, CcnbParser::CCN_DTAG);
156 Ccnb::AppendNumber (start, m_interest->GetScope ());
157 Ccnb::AppendCloser (start);
158 }
159 if (!m_interest->GetInterestLifetime().IsZero())
160 {
161 Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_InterestLifetime, CcnbParser::CCN_DTAG);
162 Ccnb::AppendTimestampBlob (start, m_interest->GetInterestLifetime ());
163 Ccnb::AppendCloser (start);
164 }
165 if (m_interest->GetNonce()>0)
166 {
167 uint32_t nonce = m_interest->GetNonce();
168 Ccnb::AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Nonce, nonce);
169 }
170
171 if (m_interest->GetNack ()>0)
172 {
173 Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Nack, CcnbParser::CCN_DTAG);
174 Ccnb::AppendNumber (start, m_interest->GetNack ());
175 Ccnb::AppendCloser (start);
176 }
177 Ccnb::AppendCloser (start); // </Interest>
178}
179
180uint32_t
181Interest::GetSerializedSize () const
182{
183 size_t written = 0;
184 written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Interest); // <Interest>
185
Alexander Afanasyevdfd52492013-09-03 12:48:41 -0700186 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Name); // <Name>
Alexander Afanasyeva89bc102013-07-16 10:17:31 -0700187 written += Ccnb::SerializedSizeName (m_interest->GetName()); // <Component>...</Component>...
Alexander Afanasyevdfd52492013-09-03 12:48:41 -0700188 // written += 1; // </Name>
Alexander Afanasyev1043c702013-07-15 16:21:09 -0700189
190 // if (m_interest->GetMinSuffixComponents() >= 0)
191 // {
192 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_MinSuffixComponents);
193 // written += Ccnb::EstimateNumber (m_interest->GetMinSuffixComponents ());
194 // written += 1;
195 // }
196 // if (m_interest->GetMaxSuffixComponents() >= 0)
197 // {
198 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_MaxSuffixComponents);
199 // written += Ccnb::EstimateNumber (m_interest->GetMaxSuffixComponents ());
200 // written += 1;
201 // }
202 // if (m_interest->IsEnabledExclude() && m_interest->GetExclude().size() > 0)
203 // {
204 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Exclude);
205 // written += Ccnb::EstimateName (m_interest->GetExclude()); // <Component>...</Component>...
206 // written += 1; // </Exclude>
207 // }
208 // if (m_interest->IsEnabledChildSelector())
209 // {
210 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_ChildSelector);
211 // written += Ccnb::EstimateNumber (1);
212 // written += 1;
213 // }
214 // if (m_interest->IsEnabledAnswerOriginKind())
215 // {
216 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_AnswerOriginKind);
217 // written += Ccnb::EstimateNumber (1);
218 // written += 1;
219 // }
220 if (m_interest->GetScope() >= 0)
221 {
222 written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Scope);
223 written += Ccnb::EstimateNumber (m_interest->GetScope ());
224 written += 1;
225 }
226 if (!m_interest->GetInterestLifetime().IsZero())
227 {
228 written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_InterestLifetime);
229 written += Ccnb::EstimateTimestampBlob (m_interest->GetInterestLifetime());
230 written += 1;
231 }
232 if (m_interest->GetNonce()>0)
233 {
234 written += Ccnb::EstimateTaggedBlob (CcnbParser::CCN_DTAG_Nonce, sizeof(uint32_t));
235 }
236 if (m_interest->GetNack ()>0)
237 {
238 written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Nack);
239 written += Ccnb::EstimateNumber (m_interest->GetNack ());
240 written += 1;
241 }
242
243 written += 1; // </Interest>
244
245 return written;
246}
247
248class InterestVisitor : public CcnbParser::VoidDepthFirstVisitor
249{
250public:
251 virtual void visit (CcnbParser::Dtag &n, boost::any param/*should be CcnxInterest* */);
252};
253
254// We don't care about any other fields
255void
256InterestVisitor::visit (CcnbParser::Dtag &n, boost::any param/*should be Interest* */)
257{
258 // uint32_t n.m_dtag;
259 // std::list<Ptr<Block> > n.m_nestedBlocks;
260
261 static CcnbParser::NonNegativeIntegerVisitor nonNegativeIntegerVisitor;
262 static CcnbParser::NameVisitor nameVisitor;
263 static CcnbParser::TimestampVisitor timestampVisitor;
264 static CcnbParser::Uint32tBlobVisitor nonceVisitor;
265
266 ndn::Interest &interest = *(boost::any_cast<ndn::Interest*> (param));
267
268 switch (n.m_dtag)
269 {
270 case CcnbParser::CCN_DTAG_Interest:
271 NS_LOG_DEBUG ("Interest");
272
273 // process nested blocks
274 BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
275 {
276 block->accept (*this, param);
277 }
278 break;
279 case CcnbParser::CCN_DTAG_Name:
280 {
281 NS_LOG_DEBUG ("Name");
282
283 // process name components
284 Ptr<Name> name = Create<Name> ();
Alexander Afanasyeva89bc102013-07-16 10:17:31 -0700285 n.accept (nameVisitor, GetPointer (name));
Alexander Afanasyev1043c702013-07-15 16:21:09 -0700286 interest.SetName (name);
287 break;
288 }
289 // case CcnbParser::CCN_DTAG_MinSuffixComponents:
290 // NS_LOG_DEBUG ("MinSuffixComponents");
291 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
292 // throw CcnbParser::CcnbDecodingException ();
293 // interest.SetMinSuffixComponents (
294 // boost::any_cast<uint32_t> (
295 // (*n.m_nestedTags.begin())->accept(
296 // nonNegativeIntegerVisitor
297 // )));
298 // break;
299 // case CcnbParser::CCN_DTAG_MaxSuffixComponents:
300 // NS_LOG_DEBUG ("MaxSuffixComponents");
301 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
302 // throw CcnbParser::CcnbDecodingException ();
303 // interest.SetMaxSuffixComponents (
304 // boost::any_cast<uint32_t> (
305 // (*n.m_nestedTags.begin())->accept(
306 // nonNegativeIntegerVisitor
307 // )));
308 // break;
309 // case CcnbParser::CCN_DTAG_Exclude:
310 // {
311 // NS_LOG_DEBUG ("Exclude");
312 // // process exclude components
313 // Ptr<Name> exclude = Create<Name> ();
314
315 // BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
316 // {
317 // block->accept (nameVisitor, &(*exclude));
318 // }
319 // interest.SetExclude (exclude);
320 // break;
321 // }
322 // case CcnbParser::CCN_DTAG_ChildSelector:
323 // NS_LOG_DEBUG ("ChildSelector");
324 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
325 // throw CcnbParser::CcnbDecodingException ();
326
327 // interest.SetChildSelector (
328 // 1 == boost::any_cast<uint32_t> (
329 // (*n.m_nestedTags.begin())->accept(
330 // nonNegativeIntegerVisitor
331 // )));
332 // break;
333 // case CCN_DTAG_AnswerOriginKind:
334 // NS_LOG_DEBUG ("AnswerOriginKind");
335 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
336 // throw CcnbParser::CcnbDecodingException ();
337 // interest.SetAnswerOriginKind (
338 // 1 == boost::any_cast<uint32_t> (
339 // (*n.m_nestedTags.begin())->accept(
340 // nonNegativeIntegerVisitor
341 // )));
342 // break;
343 case CcnbParser::CCN_DTAG_Scope:
344 NS_LOG_DEBUG ("Scope");
345 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
346 throw CcnbParser::CcnbDecodingException ();
347 interest.SetScope (
348 boost::any_cast<uint32_t> (
349 (*n.m_nestedTags.begin())->accept(
350 nonNegativeIntegerVisitor
351 )));
352 break;
353 case CcnbParser::CCN_DTAG_InterestLifetime:
354 NS_LOG_DEBUG ("InterestLifetime");
355 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
356 throw CcnbParser::CcnbDecodingException ();
357
358 interest.SetInterestLifetime (
359 boost::any_cast<Time> (
360 (*n.m_nestedTags.begin())->accept(
361 timestampVisitor
362 )));
363 break;
364 case CcnbParser::CCN_DTAG_Nonce:
365 NS_LOG_DEBUG ("Nonce");
366 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
367 throw CcnbParser::CcnbDecodingException ();
368
369 interest.SetNonce (
370 boost::any_cast<uint32_t> (
371 (*n.m_nestedTags.begin())->accept(
372 nonceVisitor
373 )));
374 break;
375
376
377 case CcnbParser::CCN_DTAG_Nack:
378 NS_LOG_DEBUG ("Nack");
379 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
380 throw CcnbParser::CcnbDecodingException ();
381
382 interest.SetNack (
383 boost::any_cast<uint32_t> (
384 (*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
385 break;
386 }
387}
388
389
390uint32_t
391Interest::Deserialize (Buffer::Iterator start)
392{
393 static InterestVisitor interestVisitor;
394
395 Buffer::Iterator i = start;
396 Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
397 root->accept (interestVisitor, GetPointer (m_interest));
398
399 return i.GetDistanceFrom (start);
400}
401
402void
403Interest::Print (std::ostream &os) const
404{
405 os << "I: " << m_interest->GetName ();
406
407 return;
408 // os << "<Interest>\n <Name>" << GetName () << "</Name>\n";
409 // if (GetNack ()>0)
410 // {
411 // os << " <NACK>";
412 // switch (GetNack ())
413 // {
414 // case NACK_LOOP:
415 // os << "loop";
416 // break;
417 // case NACK_CONGESTION:
418 // os << "congestion";
419 // break;
420 // default:
421 // os << "unknown";
422 // break;
423 // }
424 // os << "</NACK>\n";
425 // }
426 // if (GetMinSuffixComponents () >= 0)
427 // os << " <MinSuffixComponents>" << GetMinSuffixComponents () << "</MinSuffixComponents>\n";
428 // if (GetMaxSuffixComponents () >= 0)
429 // os << " <MaxSuffixComponents>" << m_maxSuffixComponents << "</MaxSuffixComponents>\n";
430 // if (IsEnabledExclude () && GetExclude ().size()>0)
431 // os << " <Exclude>" << GetExclude () << "</Exclude>\n";
432 // if (IsEnabledChildSelector ())
433 // os << " <ChildSelector />\n";
434 // if (IsEnabledAnswerOriginKind ())
435 // os << " <AnswerOriginKind />\n";
436 // if (GetScope () >= 0)
437 // os << " <Scope>" << GetScope () << "</Scope>\n";
438 // if ( !GetInterestLifetime ().IsZero() )
439 // os << " <InterestLifetime>" << GetInterestLifetime () << "</InterestLifetime>\n";
440 // if (GetNonce ()>0)
441 // os << " <Nonce>" << GetNonce () << "</Nonce>\n";
442 // os << "</Interest>";
443}
444
445} // ccnb
446} // wire
447
448NDN_NAMESPACE_END