blob: 747d264e8eca190d160548b3992a0ad1b53e32f3 [file] [log] [blame]
Alexander Afanasyevb989b122013-07-10 17:15:46 -07001/** -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Alexander Afanasyev
5 *
6 * BSD license, See the doc/LICENSE file for more information
7 *
8 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
9 */
10
11#include "ndnsim.h"
12
13NDN_NAMESPACE_BEGIN
14
15namespace wire {
16namespace ndnSIM {
17
18
19class Name
20{
21public:
22 Name ()
23 : m_name (Create<ndn::Name> ())
24 {
25 }
26
27 Name (Ptr<ndn::Name> name)
28 : m_name (name)
29 {
30 }
31
32 Ptr<Name>
33 GetName ()
34 {
35 return m_name;
36 }
37
38 size_t
39 GetSerializedSize () const
40 {
41 size_t nameSerializedSize = 2;
42
43 for (std::list<std::string>::const_iterator i = m_name->begin ();
44 i != m_name->end ();
45 i++)
46 {
47 nameSerializedSize += 2 + i->size ();
48 }
49 NS_ASSERT_MSG (nameSerializedSize < 30000, "Name is too long (> 30kbytes)");
50
51 return nameSerializedSize;
52 }
53
54 uint32_t
55 Serialize (Buffer::Iterator start) const
56 {
57 Buffer::Iterator i = start;
58
59 i.WriteU16 (static_cast<uint16_t> (m_name->GetSerializedSize ()-2));
60
61 for (std::list<std::string>::const_iterator item = m_name->begin ();
62 item != m_name->end ();
63 item++)
64 {
65 i.WriteU16 (static_cast<uint16_t> (item->size ()));
66 i.Write (reinterpret_cast<const uint8_t*> (item->c_str ()), item->size ());
67 }
68
69 return i.GetDistanceFrom (start);
70 }
71
72 uint32_t
73 Deserialize (Buffer::Iterator start)
74 {
75 Buffer::Iterator i = start;
76
77 uint16_t nameLength = i.ReadU16 ();
78 while (nameLength > 0)
79 {
80 uint16_t length = i.ReadU16 ();
81 nameLength = nameLength - 2 - length;
82
83 uint8_t tmp[length];
84 i.Read (tmp, length);
85
86 m_name->Add (string (reinterpret_cast<const char*> (tmp), length));
87 }
88
89 return i.GetDistanceFrom (start);
90 }
91
92private:
93 Ptr<ndn::Name> m_name;
94};
95
96///////////////////////////////////////////////////////////////////////////////////////////////////
97///////////////////////////////////////////////////////////////////////////////////////////////////
98///////////////////////////////////////////////////////////////////////////////////////////////////
99
100Interest::Interest ()
101 : m_interest (Create<ndn::Interest> ())
102{
103}
104
105Interest::Interest (Ptr<ndn::Interest> interest)
106 : m_interest (interest)
107{
108}
109
110Ptr<ndn::Interest>
111Interest::GetInterest ()
112{
113 return m_interest;
114}
115
116
117TypeId
118Interest::GetTypeId (void)
119{
120 static TypeId tid = TypeId ("ns3::ndn::Interest::ndnSIM")
121 .SetGroupName ("Ndn")
122 .AddParent<Header> ()
123 .AddConstructor<Interest> ()
124 ;
125 return tid;
126}
127
128TypeId
129Interest::GetInstanceTypeId (void) const
130{
131 return GetTypeId ();
132}
133
134Ptr<Packet>
135Interest::ToWire (Ptr<const ndn::Interest> interest)
136{
137 Ptr<const Packet> p = interest->GetWire ();
138 if (!p)
139 {
140 p = Create<Packet> (*interest->GetPayload ());
141 Interest wireEncoding (interest);
142 p->AddHeader (wireEncoding);
143 interest->SetWire (p);
144 }
145
146 return p->Copy ();
147}
148
149Ptr<ndn::Interest>
150Interest::FromWire (Ptr<Packet> packet)
151{
152 Ptr<ndn::Interest> interest = Create<ndn::Interest> ();
153 // interest->SetWire (packet->Copy ()); /* not sure if this is needed */
154
155 Interest wireEncoding (interest);
156 packet->RemoveHeader (wireEncoding);
157
158 interest->SetPayload (packet);
159
160 return interest;
161}
162
163uint32_t
164Interest::GetSerializedSize (void) const
165{
166 size_t size =
167 1/*version*/ + 1 /*type*/ + 2/*length*/ +
168 (4/*nonce*/ + 1/*scope*/ + 1/*nack type*/ + 2/*timestamp*/ +
169 (Name (ConstCast<ns3::Name> (m_interest->GetNamePtr ())).GetSerializedSize ()) +
170 (2 + 0)/* selectors */ +
171 (2 + 0)/* options */);
172
173 NS_LOG_INFO ("Serialize size = " << size);
174 return size;
175}
176
177void
178Interest::Serialize (Buffer::Iterator start) const
179{
180 start.WriteU8 (0x80); // version
181 start.WriteU8 (0x00); // packet type
182
183 start.WriteU16 (GetSerializedSize () - 4);
184
185 start.WriteU32 (m_nonce);
186 start.WriteU8 (m_scope);
187 start.WriteU8 (m_nackType);
188
189 NS_ASSERT_MSG (0 <= m_interest->GetInterestLifetime.ToInteger (Time::S) && m_interest->GetInterestLifetime.ToInteger (Time::S) < 65535,
190 "Incorrect InterestLifetime (should not be smaller than 0 and larger than 65535");
191
192 // rounding timestamp value to seconds
193 start.WriteU16 (static_cast<uint16_t> (m_interest->GetInterestLifetime.ToInteger (Time::S)));
194
195 uint32_t offset = Name (ConstCast<ns3::Name> (m_interest->GetNamePtr ())).Serialize (start);
196 start.Next (offset);
197
198 start.WriteU16 (0); // no selectors
199 start.WriteU16 (0); // no options
200}
201
202uint32_t
203Interest::Deserialize (Buffer::Iterator start)
204{
205 Buffer::Iterator i = start;
206
207 if (i.ReadU8 () != 0x80)
208 throw new InterestException ();
209
210 if (i.ReadU8 () != 0x00)
211 throw new InterestException ();
212
213 i.ReadU16 (); // length, don't need it right now
214
215 m_interest->SetNonce (i.ReadU32 ());
216 m_interest->SetScope (i.ReadU8 ());
217 m_interest->SetNackType (i.ReadU8 ());
218
219 m_interest->SetInterestLifetime (Seconds (i.ReadU16 ()));
220
221 Name name;
222 uint32_t offset = name.Deserialize (i);
223 m_interest->SetName (name->GetName ());
224 i.Next (offset);
225
226 i.ReadU16 ();
227 i.ReadU16 ();
228
229 NS_ASSERT (GetSerializedSize () == (i.GetDistanceFrom (start)));
230
231 return i.GetDistanceFrom (start);
232}
233
234///////////////////////////////////////////////////////////////////////////////////////////////////
235///////////////////////////////////////////////////////////////////////////////////////////////////
236///////////////////////////////////////////////////////////////////////////////////////////////////
237
238
239TypeId
240Data::GetTypeId (void)
241{
242 static TypeId tid = TypeId ("ns3::ndn::Data::ndnSIM")
243 .SetGroupName ("Ndn")
244 .SetParent<Header> ()
245 .AddConstructor<Data> ()
246 ;
247 return tid;
248}
249
250TypeId
251Data::GetInstanceTypeId (void) const
252{
253 return GetTypeId ();
254}
255
256
257Data::Data ()
258 : m_data (Create<ndn::ContentObject> ())
259{
260}
261
262Data::Data (Ptr<ndn::ContentObject> data)
263 : m_data (data)
264{
265}
266
267Ptr<ndn::ContentObject>
268GetData ()
269{
270 return m_data;
271}
272
273Ptr<Packet>
274Data::ToWire (Ptr<const ndn::ContentObject> data)
275{
276 Ptr<const Packet> p = data->GetWire ();
277 if (!p)
278 {
279 p = Create<Packet> (*data->GetPayload ());
280 Data wireEncoding (data);
281 p->AddHeader (wireEncoding);
282 data->SetWire (p);
283 }
284
285 return p->Copy ();
286}
287
288Ptr<ndn::ContentObject>
289Data::FromWire (Ptr<Packet> packet)
290{
291 Ptr<ndn::ContentObject> data = Create<ndn::ContentObject> ();
292 // data->SetWire (packet->Copy ()); /* not sure if this is needed */
293
294 Data wireEncoding (data);
295 packet->RemoveHeader (wireEncoding);
296
297 data->SetPayload (packet);
298
299 return data;
300}
301
302uint32_t
303Data::GetSerializedSize () const
304{
305 uint32_t size = 1 + 1 + 2 +
306 ((2 + 2) + (Name (ConstCast<ns3::Name> (m_data->GetNamePtr ())).GetSerializedSize ()) + (2 + 2 + 4 + 2 + 2 + (2 + 0)));
307 if (m_data->GetSignature () != 0)
308 size += 4;
309
310 NS_LOG_INFO ("Serialize size = " << size);
311 return size;
312}
313
314void
315Data::Serialize (Buffer::Iterator start) const
316{
317 start.WriteU8 (0x80); // version
318 start.WriteU8 (0x01); // packet type
319 start.WriteU16 (GetSerializedSize () - 4); // length
320
321 if (m_data->GetSignature () != 0)
322 {
323 start.WriteU16 (6); // signature length
324 start.WriteU16 (0xFF00); // "fake" simulator signature
325 start.WriteU32 (m_data->GetSignature ());
326 }
327 else
328 {
329 start.WriteU16 (2); // signature length
330 start.WriteU16 (0); // empty signature
331 }
332
333 // name
334 uint32_t offset = Name (ConstCast<ns3::Name> (m_data->GetNamePtr ())).Serialize (start);
335 start.Next (offset);
336
337 // content
338 // for now assume that contentdata length is zero
339 start.WriteU16 (2 + 4 + 2 + 2 + (2 + 0));
340 start.WriteU16 (4 + 2 + 2 + (2 + 0));
341 start.WriteU32 (static_cast<uint32_t> (m_data->GetTimestamp.ToInteger (Time::S)));
342 start.WriteU16 (static_cast<uint16_t> (m_data->GetFreshness.ToInteger (Time::S)));
343 start.WriteU16 (0); // reserved
344 start.WriteU16 (0); // Length (ContentInfoOptions)
345
346 // that's it folks
347}
348
349uint32_t
350Data::Deserialize (Buffer::Iterator start)
351{
352 Buffer::Iterator i = start;
353
354 if (i.ReadU8 () != 0x80)
355 throw new ContentObjectException ();
356
357 if (i.ReadU8 () != 0x01)
358 throw new ContentObjectException ();
359
360 i.ReadU16 (); // length
361
362 uint32_t signatureLength = i.ReadU16 ();
363 if (signatureLength == 6)
364 {
365 if (i.ReadU16 () != 0xFF00) // signature type
366 throw new ContentObjectException ();
367 m_data.SetSignature (i.ReadU32 ());
368 }
369 else if (signatureLength == 2)
370 {
371 if (i.ReadU16 () != 0) // signature type
372 throw new ContentObjectException ();
373 m_data.SetSignature (0);
374 }
375 else
376 throw new ContentObjectException ();
377
378 Name name;
379 uint32_t offset = name.Deserialize (i);
380 m_data->SetName (name->GetName ());
381 i.Next (offset);
382
383 if (i.ReadU16 () != (2 + 4 + 2 + 2 + (2 + 0))) // content length
384 throw new ContentObjectException ();
385
386 if (i.ReadU16 () != (4 + 2 + 2 + (2 + 0))) // Length (content Info)
387 throw new ContentObjectException ();
388
389 m_data->SetTimestamp (Seconds (i.ReadU32 ()));
390 m_data->SetFreshness (Seconds (i.ReadU16 ()));
391
392 if (i.ReadU16 () != 0) // Reserved
393 throw new ContentObjectException ();
394 if (i.ReadU16 () != 0) // Length (ContentInfoOptions)
395 throw new ContentObjectException ();
396
397 NS_ASSERT_MSG (i.GetDistanceFrom (start) == GetSerializedSize (),
398 "Something wrong with ContentObject::Deserialize");
399
400 return i.GetDistanceFrom (start);
401}
402
403}
404}
405
406NDN_NAMESPACE_END