blob: 8a0ec3be24d68809d73133022647d9c4f27b11b2 [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> ();
103 interest->SetWire (packet->Copy ());
104
105 Interest wireEncoding (interest);
106 packet->RemoveHeader (wireEncoding);
107
108 interest->SetPayload (packet);
109
110 return interest;
111}
112
113void
114Interest::Serialize (Buffer::Iterator start) const
115{
116 Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Interest, CcnbParser::CCN_DTAG); // <Interest>
117
118 Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG); // <Name>
119 Ccnb::AppendName (start, m_interest->GetName()); // <Component>...</Component>...
120 Ccnb::AppendCloser (start); // </Name>
121
122 // if (m_interest->GetMinSuffixComponents() >= 0)
123 // {
124 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_MinSuffixComponents, CcnbParser::CCN_DTAG);
125 // Ccnb::AppendNumber (start, m_interest->GetMinSuffixComponents ());
126 // Ccnb::AppendCloser (start);
127 // }
128 // if (m_interest->GetMaxSuffixComponents() >= 0)
129 // {
130 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_MaxSuffixComponents, CcnbParser::CCN_DTAG);
131 // Ccnb::AppendNumber (start, m_interest->GetMaxSuffixComponents ());
132 // Ccnb::AppendCloser (start);
133 // }
134 // if (m_interest->IsEnabledExclude() && m_interest->GetExclude().size() > 0)
135 // {
136 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Exclude, CcnbParser::CCN_DTAG); // <Exclude>
137 // Ccnb::AppendName (start, m_interest->GetExclude()); // <Component>...</Component>...
138 // Ccnb::AppendCloser (start); // </Exclude>
139 // }
140 // if (m_interest->IsEnabledChildSelector())
141 // {
142 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_ChildSelector, CcnbParser::CCN_DTAG);
143 // Ccnb::AppendNumber (start, 1);
144 // Ccnb::AppendCloser (start);
145 // }
146 // if (m_interest->IsEnabledAnswerOriginKind())
147 // {
148 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_AnswerOriginKind, CcnbParser::CCN_DTAG);
149 // Ccnb::AppendNumber (start, 1);
150 // Ccnb::AppendCloser (start);
151 // }
152 if (m_interest->GetScope() >= 0)
153 {
154 Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Scope, CcnbParser::CCN_DTAG);
155 Ccnb::AppendNumber (start, m_interest->GetScope ());
156 Ccnb::AppendCloser (start);
157 }
158 if (!m_interest->GetInterestLifetime().IsZero())
159 {
160 Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_InterestLifetime, CcnbParser::CCN_DTAG);
161 Ccnb::AppendTimestampBlob (start, m_interest->GetInterestLifetime ());
162 Ccnb::AppendCloser (start);
163 }
164 if (m_interest->GetNonce()>0)
165 {
166 uint32_t nonce = m_interest->GetNonce();
167 Ccnb::AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Nonce, nonce);
168 }
169
170 if (m_interest->GetNack ()>0)
171 {
172 Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Nack, CcnbParser::CCN_DTAG);
173 Ccnb::AppendNumber (start, m_interest->GetNack ());
174 Ccnb::AppendCloser (start);
175 }
176 Ccnb::AppendCloser (start); // </Interest>
177}
178
179uint32_t
180Interest::GetSerializedSize () const
181{
182 size_t written = 0;
183 written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Interest); // <Interest>
184
185 written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Name); // <Name>
186 written += Ccnb::EstimateName (m_interest->GetName()); // <Component>...</Component>...
187 written += 1; // </Name>
188
189 // if (m_interest->GetMinSuffixComponents() >= 0)
190 // {
191 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_MinSuffixComponents);
192 // written += Ccnb::EstimateNumber (m_interest->GetMinSuffixComponents ());
193 // written += 1;
194 // }
195 // if (m_interest->GetMaxSuffixComponents() >= 0)
196 // {
197 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_MaxSuffixComponents);
198 // written += Ccnb::EstimateNumber (m_interest->GetMaxSuffixComponents ());
199 // written += 1;
200 // }
201 // if (m_interest->IsEnabledExclude() && m_interest->GetExclude().size() > 0)
202 // {
203 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Exclude);
204 // written += Ccnb::EstimateName (m_interest->GetExclude()); // <Component>...</Component>...
205 // written += 1; // </Exclude>
206 // }
207 // if (m_interest->IsEnabledChildSelector())
208 // {
209 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_ChildSelector);
210 // written += Ccnb::EstimateNumber (1);
211 // written += 1;
212 // }
213 // if (m_interest->IsEnabledAnswerOriginKind())
214 // {
215 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_AnswerOriginKind);
216 // written += Ccnb::EstimateNumber (1);
217 // written += 1;
218 // }
219 if (m_interest->GetScope() >= 0)
220 {
221 written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Scope);
222 written += Ccnb::EstimateNumber (m_interest->GetScope ());
223 written += 1;
224 }
225 if (!m_interest->GetInterestLifetime().IsZero())
226 {
227 written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_InterestLifetime);
228 written += Ccnb::EstimateTimestampBlob (m_interest->GetInterestLifetime());
229 written += 1;
230 }
231 if (m_interest->GetNonce()>0)
232 {
233 written += Ccnb::EstimateTaggedBlob (CcnbParser::CCN_DTAG_Nonce, sizeof(uint32_t));
234 }
235 if (m_interest->GetNack ()>0)
236 {
237 written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Nack);
238 written += Ccnb::EstimateNumber (m_interest->GetNack ());
239 written += 1;
240 }
241
242 written += 1; // </Interest>
243
244 return written;
245}
246
247class InterestVisitor : public CcnbParser::VoidDepthFirstVisitor
248{
249public:
250 virtual void visit (CcnbParser::Dtag &n, boost::any param/*should be CcnxInterest* */);
251};
252
253// We don't care about any other fields
254void
255InterestVisitor::visit (CcnbParser::Dtag &n, boost::any param/*should be Interest* */)
256{
257 // uint32_t n.m_dtag;
258 // std::list<Ptr<Block> > n.m_nestedBlocks;
259
260 static CcnbParser::NonNegativeIntegerVisitor nonNegativeIntegerVisitor;
261 static CcnbParser::NameVisitor nameVisitor;
262 static CcnbParser::TimestampVisitor timestampVisitor;
263 static CcnbParser::Uint32tBlobVisitor nonceVisitor;
264
265 ndn::Interest &interest = *(boost::any_cast<ndn::Interest*> (param));
266
267 switch (n.m_dtag)
268 {
269 case CcnbParser::CCN_DTAG_Interest:
270 NS_LOG_DEBUG ("Interest");
271
272 // process nested blocks
273 BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
274 {
275 block->accept (*this, param);
276 }
277 break;
278 case CcnbParser::CCN_DTAG_Name:
279 {
280 NS_LOG_DEBUG ("Name");
281
282 // process name components
283 Ptr<Name> name = Create<Name> ();
284
285 BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
286 {
287 block->accept (nameVisitor, &(*name));
288 }
289 interest.SetName (name);
290 break;
291 }
292 // case CcnbParser::CCN_DTAG_MinSuffixComponents:
293 // NS_LOG_DEBUG ("MinSuffixComponents");
294 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
295 // throw CcnbParser::CcnbDecodingException ();
296 // interest.SetMinSuffixComponents (
297 // boost::any_cast<uint32_t> (
298 // (*n.m_nestedTags.begin())->accept(
299 // nonNegativeIntegerVisitor
300 // )));
301 // break;
302 // case CcnbParser::CCN_DTAG_MaxSuffixComponents:
303 // NS_LOG_DEBUG ("MaxSuffixComponents");
304 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
305 // throw CcnbParser::CcnbDecodingException ();
306 // interest.SetMaxSuffixComponents (
307 // boost::any_cast<uint32_t> (
308 // (*n.m_nestedTags.begin())->accept(
309 // nonNegativeIntegerVisitor
310 // )));
311 // break;
312 // case CcnbParser::CCN_DTAG_Exclude:
313 // {
314 // NS_LOG_DEBUG ("Exclude");
315 // // process exclude components
316 // Ptr<Name> exclude = Create<Name> ();
317
318 // BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
319 // {
320 // block->accept (nameVisitor, &(*exclude));
321 // }
322 // interest.SetExclude (exclude);
323 // break;
324 // }
325 // case CcnbParser::CCN_DTAG_ChildSelector:
326 // NS_LOG_DEBUG ("ChildSelector");
327 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
328 // throw CcnbParser::CcnbDecodingException ();
329
330 // interest.SetChildSelector (
331 // 1 == boost::any_cast<uint32_t> (
332 // (*n.m_nestedTags.begin())->accept(
333 // nonNegativeIntegerVisitor
334 // )));
335 // break;
336 // case CCN_DTAG_AnswerOriginKind:
337 // NS_LOG_DEBUG ("AnswerOriginKind");
338 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
339 // throw CcnbParser::CcnbDecodingException ();
340 // interest.SetAnswerOriginKind (
341 // 1 == boost::any_cast<uint32_t> (
342 // (*n.m_nestedTags.begin())->accept(
343 // nonNegativeIntegerVisitor
344 // )));
345 // break;
346 case CcnbParser::CCN_DTAG_Scope:
347 NS_LOG_DEBUG ("Scope");
348 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
349 throw CcnbParser::CcnbDecodingException ();
350 interest.SetScope (
351 boost::any_cast<uint32_t> (
352 (*n.m_nestedTags.begin())->accept(
353 nonNegativeIntegerVisitor
354 )));
355 break;
356 case CcnbParser::CCN_DTAG_InterestLifetime:
357 NS_LOG_DEBUG ("InterestLifetime");
358 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
359 throw CcnbParser::CcnbDecodingException ();
360
361 interest.SetInterestLifetime (
362 boost::any_cast<Time> (
363 (*n.m_nestedTags.begin())->accept(
364 timestampVisitor
365 )));
366 break;
367 case CcnbParser::CCN_DTAG_Nonce:
368 NS_LOG_DEBUG ("Nonce");
369 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
370 throw CcnbParser::CcnbDecodingException ();
371
372 interest.SetNonce (
373 boost::any_cast<uint32_t> (
374 (*n.m_nestedTags.begin())->accept(
375 nonceVisitor
376 )));
377 break;
378
379
380 case CcnbParser::CCN_DTAG_Nack:
381 NS_LOG_DEBUG ("Nack");
382 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
383 throw CcnbParser::CcnbDecodingException ();
384
385 interest.SetNack (
386 boost::any_cast<uint32_t> (
387 (*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
388 break;
389 }
390}
391
392
393uint32_t
394Interest::Deserialize (Buffer::Iterator start)
395{
396 static InterestVisitor interestVisitor;
397
398 Buffer::Iterator i = start;
399 Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
400 root->accept (interestVisitor, GetPointer (m_interest));
401
402 return i.GetDistanceFrom (start);
403}
404
405void
406Interest::Print (std::ostream &os) const
407{
408 os << "I: " << m_interest->GetName ();
409
410 return;
411 // os << "<Interest>\n <Name>" << GetName () << "</Name>\n";
412 // if (GetNack ()>0)
413 // {
414 // os << " <NACK>";
415 // switch (GetNack ())
416 // {
417 // case NACK_LOOP:
418 // os << "loop";
419 // break;
420 // case NACK_CONGESTION:
421 // os << "congestion";
422 // break;
423 // default:
424 // os << "unknown";
425 // break;
426 // }
427 // os << "</NACK>\n";
428 // }
429 // if (GetMinSuffixComponents () >= 0)
430 // os << " <MinSuffixComponents>" << GetMinSuffixComponents () << "</MinSuffixComponents>\n";
431 // if (GetMaxSuffixComponents () >= 0)
432 // os << " <MaxSuffixComponents>" << m_maxSuffixComponents << "</MaxSuffixComponents>\n";
433 // if (IsEnabledExclude () && GetExclude ().size()>0)
434 // os << " <Exclude>" << GetExclude () << "</Exclude>\n";
435 // if (IsEnabledChildSelector ())
436 // os << " <ChildSelector />\n";
437 // if (IsEnabledAnswerOriginKind ())
438 // os << " <AnswerOriginKind />\n";
439 // if (GetScope () >= 0)
440 // os << " <Scope>" << GetScope () << "</Scope>\n";
441 // if ( !GetInterestLifetime ().IsZero() )
442 // os << " <InterestLifetime>" << GetInterestLifetime () << "</InterestLifetime>\n";
443 // if (GetNonce ()>0)
444 // os << " <Nonce>" << GetNonce () << "</Nonce>\n";
445 // os << "</Interest>";
446}
447
448} // ccnb
449} // wire
450
451NDN_NAMESPACE_END