blob: f1711f8c1c132aa0f9034d7437290ff31b3a0914 [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
Alexander Afanasyevdfd52492013-09-03 12:48:41 -0700118 // Ccnb::AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG); // <Name>
Alexander Afanasyeva89bc102013-07-16 10:17:31 -0700119 Ccnb::SerializeName (start, m_interest->GetName()); // <Component>...</Component>...
Alexander Afanasyevdfd52492013-09-03 12:48:41 -0700120 // Ccnb::AppendCloser (start); // </Name>
Alexander Afanasyev1043c702013-07-15 16:21:09 -0700121
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
Alexander Afanasyevdfd52492013-09-03 12:48:41 -0700185 // written += Ccnb::EstimateBlockHeader (CcnbParser::CCN_DTAG_Name); // <Name>
Alexander Afanasyeva89bc102013-07-16 10:17:31 -0700186 written += Ccnb::SerializedSizeName (m_interest->GetName()); // <Component>...</Component>...
Alexander Afanasyevdfd52492013-09-03 12:48:41 -0700187 // written += 1; // </Name>
Alexander Afanasyev1043c702013-07-15 16:21:09 -0700188
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> ();
Alexander Afanasyeva89bc102013-07-16 10:17:31 -0700284 n.accept (nameVisitor, GetPointer (name));
Alexander Afanasyev1043c702013-07-15 16:21:09 -0700285 interest.SetName (name);
286 break;
287 }
288 // case CcnbParser::CCN_DTAG_MinSuffixComponents:
289 // NS_LOG_DEBUG ("MinSuffixComponents");
290 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
291 // throw CcnbParser::CcnbDecodingException ();
292 // interest.SetMinSuffixComponents (
293 // boost::any_cast<uint32_t> (
294 // (*n.m_nestedTags.begin())->accept(
295 // nonNegativeIntegerVisitor
296 // )));
297 // break;
298 // case CcnbParser::CCN_DTAG_MaxSuffixComponents:
299 // NS_LOG_DEBUG ("MaxSuffixComponents");
300 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
301 // throw CcnbParser::CcnbDecodingException ();
302 // interest.SetMaxSuffixComponents (
303 // boost::any_cast<uint32_t> (
304 // (*n.m_nestedTags.begin())->accept(
305 // nonNegativeIntegerVisitor
306 // )));
307 // break;
308 // case CcnbParser::CCN_DTAG_Exclude:
309 // {
310 // NS_LOG_DEBUG ("Exclude");
311 // // process exclude components
312 // Ptr<Name> exclude = Create<Name> ();
313
314 // BOOST_FOREACH (Ptr<CcnbParser::Block> block, n.m_nestedTags)
315 // {
316 // block->accept (nameVisitor, &(*exclude));
317 // }
318 // interest.SetExclude (exclude);
319 // break;
320 // }
321 // case CcnbParser::CCN_DTAG_ChildSelector:
322 // NS_LOG_DEBUG ("ChildSelector");
323 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
324 // throw CcnbParser::CcnbDecodingException ();
325
326 // interest.SetChildSelector (
327 // 1 == boost::any_cast<uint32_t> (
328 // (*n.m_nestedTags.begin())->accept(
329 // nonNegativeIntegerVisitor
330 // )));
331 // break;
332 // case CCN_DTAG_AnswerOriginKind:
333 // NS_LOG_DEBUG ("AnswerOriginKind");
334 // if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
335 // throw CcnbParser::CcnbDecodingException ();
336 // interest.SetAnswerOriginKind (
337 // 1 == boost::any_cast<uint32_t> (
338 // (*n.m_nestedTags.begin())->accept(
339 // nonNegativeIntegerVisitor
340 // )));
341 // break;
342 case CcnbParser::CCN_DTAG_Scope:
343 NS_LOG_DEBUG ("Scope");
344 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
345 throw CcnbParser::CcnbDecodingException ();
346 interest.SetScope (
347 boost::any_cast<uint32_t> (
348 (*n.m_nestedTags.begin())->accept(
349 nonNegativeIntegerVisitor
350 )));
351 break;
352 case CcnbParser::CCN_DTAG_InterestLifetime:
353 NS_LOG_DEBUG ("InterestLifetime");
354 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
355 throw CcnbParser::CcnbDecodingException ();
356
357 interest.SetInterestLifetime (
358 boost::any_cast<Time> (
359 (*n.m_nestedTags.begin())->accept(
360 timestampVisitor
361 )));
362 break;
363 case CcnbParser::CCN_DTAG_Nonce:
364 NS_LOG_DEBUG ("Nonce");
365 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
366 throw CcnbParser::CcnbDecodingException ();
367
368 interest.SetNonce (
369 boost::any_cast<uint32_t> (
370 (*n.m_nestedTags.begin())->accept(
371 nonceVisitor
372 )));
373 break;
374
375
376 case CcnbParser::CCN_DTAG_Nack:
377 NS_LOG_DEBUG ("Nack");
378 if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
379 throw CcnbParser::CcnbDecodingException ();
380
381 interest.SetNack (
382 boost::any_cast<uint32_t> (
383 (*n.m_nestedTags.begin())->accept(nonNegativeIntegerVisitor)));
384 break;
385 }
386}
387
388
389uint32_t
390Interest::Deserialize (Buffer::Iterator start)
391{
392 static InterestVisitor interestVisitor;
393
394 Buffer::Iterator i = start;
395 Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
396 root->accept (interestVisitor, GetPointer (m_interest));
397
398 return i.GetDistanceFrom (start);
399}
400
401void
402Interest::Print (std::ostream &os) const
403{
404 os << "I: " << m_interest->GetName ();
405
406 return;
407 // os << "<Interest>\n <Name>" << GetName () << "</Name>\n";
408 // if (GetNack ()>0)
409 // {
410 // os << " <NACK>";
411 // switch (GetNack ())
412 // {
413 // case NACK_LOOP:
414 // os << "loop";
415 // break;
416 // case NACK_CONGESTION:
417 // os << "congestion";
418 // break;
419 // default:
420 // os << "unknown";
421 // break;
422 // }
423 // os << "</NACK>\n";
424 // }
425 // if (GetMinSuffixComponents () >= 0)
426 // os << " <MinSuffixComponents>" << GetMinSuffixComponents () << "</MinSuffixComponents>\n";
427 // if (GetMaxSuffixComponents () >= 0)
428 // os << " <MaxSuffixComponents>" << m_maxSuffixComponents << "</MaxSuffixComponents>\n";
429 // if (IsEnabledExclude () && GetExclude ().size()>0)
430 // os << " <Exclude>" << GetExclude () << "</Exclude>\n";
431 // if (IsEnabledChildSelector ())
432 // os << " <ChildSelector />\n";
433 // if (IsEnabledAnswerOriginKind ())
434 // os << " <AnswerOriginKind />\n";
435 // if (GetScope () >= 0)
436 // os << " <Scope>" << GetScope () << "</Scope>\n";
437 // if ( !GetInterestLifetime ().IsZero() )
438 // os << " <InterestLifetime>" << GetInterestLifetime () << "</InterestLifetime>\n";
439 // if (GetNonce ()>0)
440 // os << " <Nonce>" << GetNonce () << "</Nonce>\n";
441 // os << "</Interest>";
442}
443
444} // ccnb
445} // wire
446
447NDN_NAMESPACE_END