|
mathieu@150
|
1 |
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
mathieu@9
|
2 |
/*
|
|
mathieu@9
|
3 |
* Copyright (c) 2005,2006 INRIA
|
|
mathieu@9
|
4 |
*
|
|
mathieu@9
|
5 |
* This program is free software; you can redistribute it and/or modify
|
|
mathieu@9
|
6 |
* it under the terms of the GNU General Public License version 2 as
|
|
mathieu@9
|
7 |
* published by the Free Software Foundation;
|
|
mathieu@9
|
8 |
*
|
|
mathieu@9
|
9 |
* This program is distributed in the hope that it will be useful,
|
|
mathieu@9
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
mathieu@9
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
mathieu@9
|
12 |
* GNU General Public License for more details.
|
|
mathieu@9
|
13 |
*
|
|
mathieu@9
|
14 |
* You should have received a copy of the GNU General Public License
|
|
mathieu@9
|
15 |
* along with this program; if not, write to the Free Software
|
|
mathieu@9
|
16 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
mathieu@9
|
17 |
*
|
|
mathieu@9
|
18 |
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
|
mathieu@9
|
19 |
*/
|
|
mathieu@9
|
20 |
#include "packet.h"
|
|
mathieu@286
|
21 |
#include "ns3/assert.h"
|
|
mathieu@3158
|
22 |
#include "ns3/log.h"
|
|
boyko@5334
|
23 |
#include "ns3/test.h"
|
|
boyko@5334
|
24 |
#include <string>
|
|
boyko@5334
|
25 |
#include <stdarg.h>
|
|
mathieu@3158
|
26 |
|
|
mathieu@3158
|
27 |
NS_LOG_COMPONENT_DEFINE ("Packet");
|
|
mathieu@9
|
28 |
|
|
mathieu@16
|
29 |
namespace ns3 {
|
|
mathieu@9
|
30 |
|
|
mathieu@463
|
31 |
uint32_t Packet::m_globalUid = 0;
|
|
mathieu@91
|
32 |
|
|
mathieu@3035
|
33 |
TypeId
|
|
mathieu@4502
|
34 |
ByteTagIterator::Item::GetTypeId (void) const
|
|
mathieu@3035
|
35 |
{
|
|
mathieu@3035
|
36 |
return m_tid;
|
|
mathieu@3035
|
37 |
}
|
|
mathieu@3035
|
38 |
uint32_t
|
|
mathieu@4502
|
39 |
ByteTagIterator::Item::GetStart (void) const
|
|
mathieu@3035
|
40 |
{
|
|
mathieu@3035
|
41 |
return m_start;
|
|
mathieu@3035
|
42 |
}
|
|
mathieu@3035
|
43 |
uint32_t
|
|
mathieu@4502
|
44 |
ByteTagIterator::Item::GetEnd (void) const
|
|
mathieu@3035
|
45 |
{
|
|
mathieu@3035
|
46 |
return m_end;
|
|
mathieu@3035
|
47 |
}
|
|
mathieu@3035
|
48 |
void
|
|
mathieu@4502
|
49 |
ByteTagIterator::Item::GetTag (Tag &tag) const
|
|
mathieu@3035
|
50 |
{
|
|
mathieu@3035
|
51 |
if (tag.GetInstanceTypeId () != GetTypeId ())
|
|
mathieu@3035
|
52 |
{
|
|
mathieu@3035
|
53 |
NS_FATAL_ERROR ("The tag you provided is not of the right type.");
|
|
mathieu@3035
|
54 |
}
|
|
mathieu@3035
|
55 |
tag.Deserialize (m_buffer);
|
|
mathieu@3035
|
56 |
}
|
|
mathieu@4502
|
57 |
ByteTagIterator::Item::Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
|
|
mathieu@3035
|
58 |
: m_tid (tid),
|
|
mathieu@3035
|
59 |
m_start (start),
|
|
mathieu@3035
|
60 |
m_end (end),
|
|
mathieu@3035
|
61 |
m_buffer (buffer)
|
|
mathieu@3035
|
62 |
{}
|
|
mathieu@3035
|
63 |
bool
|
|
mathieu@4502
|
64 |
ByteTagIterator::HasNext (void) const
|
|
mathieu@3035
|
65 |
{
|
|
mathieu@3035
|
66 |
return m_current.HasNext ();
|
|
mathieu@3035
|
67 |
}
|
|
mathieu@4502
|
68 |
ByteTagIterator::Item
|
|
mathieu@4502
|
69 |
ByteTagIterator::Next (void)
|
|
mathieu@3035
|
70 |
{
|
|
mathieu@4502
|
71 |
ByteTagList::Iterator::Item i = m_current.Next ();
|
|
mathieu@4502
|
72 |
return ByteTagIterator::Item (i.tid,
|
|
mathieu@4502
|
73 |
i.start-m_current.GetOffsetStart (),
|
|
mathieu@4502
|
74 |
i.end-m_current.GetOffsetStart (),
|
|
mathieu@4502
|
75 |
i.buf);
|
|
mathieu@3035
|
76 |
}
|
|
mathieu@4502
|
77 |
ByteTagIterator::ByteTagIterator (ByteTagList::Iterator i)
|
|
mathieu@3035
|
78 |
: m_current (i)
|
|
mathieu@3035
|
79 |
{}
|
|
mathieu@3035
|
80 |
|
|
mathieu@3035
|
81 |
|
|
mathieu@4502
|
82 |
PacketTagIterator::PacketTagIterator (const struct PacketTagList::TagData *head)
|
|
mathieu@4502
|
83 |
: m_current (head)
|
|
mathieu@4502
|
84 |
{}
|
|
mathieu@4502
|
85 |
bool
|
|
mathieu@4502
|
86 |
PacketTagIterator::HasNext (void) const
|
|
mathieu@4502
|
87 |
{
|
|
mathieu@4502
|
88 |
return m_current != 0;
|
|
mathieu@4502
|
89 |
}
|
|
mathieu@4502
|
90 |
PacketTagIterator::Item
|
|
mathieu@4502
|
91 |
PacketTagIterator::Next (void)
|
|
mathieu@4502
|
92 |
{
|
|
mathieu@4502
|
93 |
NS_ASSERT (HasNext ());
|
|
mathieu@4502
|
94 |
const struct PacketTagList::TagData *prev = m_current;
|
|
mathieu@4502
|
95 |
m_current = m_current->next;
|
|
mathieu@4502
|
96 |
return PacketTagIterator::Item (prev);
|
|
mathieu@4502
|
97 |
}
|
|
mathieu@4502
|
98 |
|
|
mathieu@4502
|
99 |
PacketTagIterator::Item::Item (const struct PacketTagList::TagData *data)
|
|
mathieu@4502
|
100 |
: m_data (data)
|
|
mathieu@4502
|
101 |
{}
|
|
mathieu@4502
|
102 |
TypeId
|
|
mathieu@4502
|
103 |
PacketTagIterator::Item::GetTypeId (void) const
|
|
mathieu@4502
|
104 |
{
|
|
mathieu@4502
|
105 |
return m_data->tid;
|
|
mathieu@4502
|
106 |
}
|
|
mathieu@4502
|
107 |
void
|
|
mathieu@4502
|
108 |
PacketTagIterator::Item::GetTag (Tag &tag) const
|
|
mathieu@4502
|
109 |
{
|
|
mathieu@4502
|
110 |
NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
|
|
mathieu@4502
|
111 |
tag.Deserialize (TagBuffer ((uint8_t*)m_data->data, (uint8_t*)m_data->data+PACKET_TAG_MAX_SIZE));
|
|
mathieu@4502
|
112 |
}
|
|
mathieu@4502
|
113 |
|
|
mathieu@4502
|
114 |
|
|
mathieu@1865
|
115 |
Ptr<Packet>
|
|
mathieu@1865
|
116 |
Packet::Copy (void) const
|
|
mathieu@1865
|
117 |
{
|
|
mathieu@1865
|
118 |
// we need to invoke the copy constructor directly
|
|
mathieu@1865
|
119 |
// rather than calling Create because the copy constructor
|
|
mathieu@1865
|
120 |
// is private.
|
|
mathieu@1865
|
121 |
return Ptr<Packet> (new Packet (*this), false);
|
|
mathieu@1865
|
122 |
}
|
|
mathieu@1865
|
123 |
|
|
mathieu@9
|
124 |
Packet::Packet ()
|
|
mathieu@150
|
125 |
: m_buffer (),
|
|
mathieu@4502
|
126 |
m_byteTagList (),
|
|
mathieu@4502
|
127 |
m_packetTagList (),
|
|
mathieu@1865
|
128 |
m_metadata (m_globalUid, 0),
|
|
mathieu@5505
|
129 |
m_nixVector (0)
|
|
mathieu@91
|
130 |
{
|
|
mathieu@463
|
131 |
m_globalUid++;
|
|
mathieu@91
|
132 |
}
|
|
mathieu@9
|
133 |
|
|
mathieu@1865
|
134 |
Packet::Packet (const Packet &o)
|
|
mathieu@1865
|
135 |
: m_buffer (o.m_buffer),
|
|
mathieu@4502
|
136 |
m_byteTagList (o.m_byteTagList),
|
|
mathieu@4502
|
137 |
m_packetTagList (o.m_packetTagList),
|
|
mathieu@5505
|
138 |
m_metadata (o.m_metadata)
|
|
jpelkey@5224
|
139 |
{
|
|
jpelkey@5224
|
140 |
o.m_nixVector ? m_nixVector = o.m_nixVector->Copy ()
|
|
jpelkey@5224
|
141 |
: m_nixVector = 0;
|
|
jpelkey@5224
|
142 |
}
|
|
mathieu@1865
|
143 |
|
|
mathieu@1865
|
144 |
Packet &
|
|
mathieu@1865
|
145 |
Packet::operator = (const Packet &o)
|
|
mathieu@1865
|
146 |
{
|
|
mathieu@1865
|
147 |
if (this == &o)
|
|
mathieu@1865
|
148 |
{
|
|
mathieu@1865
|
149 |
return *this;
|
|
mathieu@1865
|
150 |
}
|
|
mathieu@1865
|
151 |
m_buffer = o.m_buffer;
|
|
mathieu@4502
|
152 |
m_byteTagList = o.m_byteTagList;
|
|
mathieu@4502
|
153 |
m_packetTagList = o.m_packetTagList;
|
|
mathieu@1865
|
154 |
m_metadata = o.m_metadata;
|
|
jpelkey@5224
|
155 |
o.m_nixVector ? m_nixVector = o.m_nixVector->Copy ()
|
|
jpelkey@5224
|
156 |
: m_nixVector = 0;
|
|
mathieu@1865
|
157 |
return *this;
|
|
mathieu@1865
|
158 |
}
|
|
mathieu@1865
|
159 |
|
|
mathieu@9
|
160 |
Packet::Packet (uint32_t size)
|
|
mathieu@150
|
161 |
: m_buffer (size),
|
|
mathieu@4502
|
162 |
m_byteTagList (),
|
|
mathieu@4502
|
163 |
m_packetTagList (),
|
|
mathieu@1865
|
164 |
m_metadata (m_globalUid, size),
|
|
mathieu@5505
|
165 |
m_nixVector (0)
|
|
mathieu@91
|
166 |
{
|
|
mathieu@463
|
167 |
m_globalUid++;
|
|
mathieu@91
|
168 |
}
|
|
mathieu@239
|
169 |
Packet::Packet (uint8_t const*buffer, uint32_t size)
|
|
mathieu@239
|
170 |
: m_buffer (),
|
|
mathieu@4502
|
171 |
m_byteTagList (),
|
|
mathieu@4502
|
172 |
m_packetTagList (),
|
|
mathieu@1865
|
173 |
m_metadata (m_globalUid, size),
|
|
mathieu@5505
|
174 |
m_nixVector (0)
|
|
mathieu@239
|
175 |
{
|
|
mathieu@463
|
176 |
m_globalUid++;
|
|
mathieu@239
|
177 |
m_buffer.AddAtStart (size);
|
|
mathieu@239
|
178 |
Buffer::Iterator i = m_buffer.Begin ();
|
|
mathieu@239
|
179 |
i.Write (buffer, size);
|
|
mathieu@239
|
180 |
}
|
|
mathieu@239
|
181 |
|
|
mathieu@4502
|
182 |
Packet::Packet (const Buffer &buffer, const ByteTagList &byteTagList,
|
|
mathieu@4502
|
183 |
const PacketTagList &packetTagList, const PacketMetadata &metadata)
|
|
mathieu@150
|
184 |
: m_buffer (buffer),
|
|
mathieu@4502
|
185 |
m_byteTagList (byteTagList),
|
|
mathieu@4502
|
186 |
m_packetTagList (packetTagList),
|
|
mathieu@1865
|
187 |
m_metadata (metadata),
|
|
mathieu@5505
|
188 |
m_nixVector (0)
|
|
mathieu@9
|
189 |
{}
|
|
mathieu@9
|
190 |
|
|
mathieu@1865
|
191 |
Ptr<Packet>
|
|
mathieu@122
|
192 |
Packet::CreateFragment (uint32_t start, uint32_t length) const
|
|
mathieu@9
|
193 |
{
|
|
mathieu@3158
|
194 |
NS_LOG_FUNCTION (this << start << length);
|
|
mathieu@463
|
195 |
Buffer buffer = m_buffer.CreateFragment (start, length);
|
|
mathieu@819
|
196 |
NS_ASSERT (m_buffer.GetSize () >= start + length);
|
|
mathieu@819
|
197 |
uint32_t end = m_buffer.GetSize () - (start + length);
|
|
mathieu@888
|
198 |
PacketMetadata metadata = m_metadata.CreateFragment (start, end);
|
|
mathieu@1865
|
199 |
// again, call the constructor directly rather than
|
|
mathieu@1865
|
200 |
// through Create because it is private.
|
|
mathieu@4502
|
201 |
return Ptr<Packet> (new Packet (buffer, m_byteTagList, m_packetTagList, metadata), false);
|
|
mathieu@9
|
202 |
}
|
|
mathieu@9
|
203 |
|
|
jpelkey@5224
|
204 |
void
|
|
jpelkey@5224
|
205 |
Packet::SetNixVector (Ptr<NixVector> nixVector)
|
|
jpelkey@5224
|
206 |
{
|
|
jpelkey@5224
|
207 |
m_nixVector = nixVector;
|
|
jpelkey@5224
|
208 |
}
|
|
jpelkey@5224
|
209 |
|
|
jpelkey@5224
|
210 |
Ptr<NixVector>
|
|
jpelkey@5224
|
211 |
Packet::GetNixVector (void) const
|
|
jpelkey@5224
|
212 |
{
|
|
jpelkey@5224
|
213 |
return m_nixVector;
|
|
jpelkey@5224
|
214 |
}
|
|
jpelkey@5224
|
215 |
|
|
mathieu@9
|
216 |
uint32_t
|
|
mathieu@122
|
217 |
Packet::GetSize (void) const
|
|
mathieu@9
|
218 |
{
|
|
mathieu@150
|
219 |
return m_buffer.GetSize ();
|
|
mathieu@9
|
220 |
}
|
|
mathieu@9
|
221 |
|
|
mathieu@2663
|
222 |
void
|
|
mathieu@2663
|
223 |
Packet::AddHeader (const Header &header)
|
|
mathieu@2663
|
224 |
{
|
|
mathieu@2663
|
225 |
uint32_t size = header.GetSerializedSize ();
|
|
mathieu@4484
|
226 |
NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << size);
|
|
mathieu@3035
|
227 |
uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
|
|
mathieu@3035
|
228 |
bool resized = m_buffer.AddAtStart (size);
|
|
mathieu@3035
|
229 |
if (resized)
|
|
mathieu@3035
|
230 |
{
|
|
mathieu@4502
|
231 |
m_byteTagList.AddAtStart (m_buffer.GetCurrentStartOffset () + size - orgStart,
|
|
mathieu@4502
|
232 |
m_buffer.GetCurrentStartOffset () + size);
|
|
mathieu@3035
|
233 |
}
|
|
mathieu@2663
|
234 |
header.Serialize (m_buffer.Begin ());
|
|
mathieu@2663
|
235 |
m_metadata.AddHeader (header, size);
|
|
mathieu@2663
|
236 |
}
|
|
mathieu@2663
|
237 |
uint32_t
|
|
mathieu@2663
|
238 |
Packet::RemoveHeader (Header &header)
|
|
mathieu@2663
|
239 |
{
|
|
mathieu@2663
|
240 |
uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
|
|
mathieu@4484
|
241 |
NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
|
|
mathieu@2663
|
242 |
m_buffer.RemoveAtStart (deserialized);
|
|
mathieu@2663
|
243 |
m_metadata.RemoveHeader (header, deserialized);
|
|
mathieu@2663
|
244 |
return deserialized;
|
|
mathieu@2663
|
245 |
}
|
|
mathieu@3364
|
246 |
uint32_t
|
|
mathieu@3738
|
247 |
Packet::PeekHeader (Header &header) const
|
|
mathieu@3364
|
248 |
{
|
|
mathieu@3364
|
249 |
uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
|
|
mathieu@4484
|
250 |
NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
|
|
mathieu@3364
|
251 |
return deserialized;
|
|
mathieu@3364
|
252 |
}
|
|
mathieu@2663
|
253 |
void
|
|
mathieu@2663
|
254 |
Packet::AddTrailer (const Trailer &trailer)
|
|
mathieu@2663
|
255 |
{
|
|
mathieu@2663
|
256 |
uint32_t size = trailer.GetSerializedSize ();
|
|
mathieu@4484
|
257 |
NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << size);
|
|
mathieu@3237
|
258 |
uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
|
|
mathieu@3035
|
259 |
bool resized = m_buffer.AddAtEnd (size);
|
|
mathieu@3035
|
260 |
if (resized)
|
|
mathieu@3035
|
261 |
{
|
|
mathieu@4502
|
262 |
m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - orgStart,
|
|
mathieu@4502
|
263 |
m_buffer.GetCurrentEndOffset () - size);
|
|
mathieu@3035
|
264 |
}
|
|
mathieu@2663
|
265 |
Buffer::Iterator end = m_buffer.End ();
|
|
mathieu@2663
|
266 |
trailer.Serialize (end);
|
|
mathieu@2663
|
267 |
m_metadata.AddTrailer (trailer, size);
|
|
mathieu@2663
|
268 |
}
|
|
mathieu@2663
|
269 |
uint32_t
|
|
mathieu@2663
|
270 |
Packet::RemoveTrailer (Trailer &trailer)
|
|
mathieu@2663
|
271 |
{
|
|
mathieu@2663
|
272 |
uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
|
|
mathieu@4484
|
273 |
NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
|
|
mathieu@2663
|
274 |
m_buffer.RemoveAtEnd (deserialized);
|
|
mathieu@2663
|
275 |
m_metadata.RemoveTrailer (trailer, deserialized);
|
|
mathieu@2663
|
276 |
return deserialized;
|
|
mathieu@2663
|
277 |
}
|
|
mathieu@3364
|
278 |
uint32_t
|
|
mathieu@3364
|
279 |
Packet::PeekTrailer (Trailer &trailer)
|
|
mathieu@3364
|
280 |
{
|
|
mathieu@3364
|
281 |
uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
|
|
mathieu@4484
|
282 |
NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
|
|
mathieu@3364
|
283 |
return deserialized;
|
|
mathieu@3364
|
284 |
}
|
|
mathieu@2663
|
285 |
|
|
mathieu@9
|
286 |
void
|
|
mathieu@1865
|
287 |
Packet::AddAtEnd (Ptr<const Packet> packet)
|
|
mathieu@9
|
288 |
{
|
|
mathieu@4484
|
289 |
NS_LOG_FUNCTION (this << packet << packet->GetSize ());
|
|
mathieu@3035
|
290 |
uint32_t aStart = m_buffer.GetCurrentStartOffset ();
|
|
mathieu@3035
|
291 |
uint32_t bEnd = packet->m_buffer.GetCurrentEndOffset ();
|
|
mathieu@2992
|
292 |
m_buffer.AddAtEnd (packet->m_buffer);
|
|
mathieu@3035
|
293 |
uint32_t appendPrependOffset = m_buffer.GetCurrentEndOffset () - packet->m_buffer.GetSize ();
|
|
mathieu@4502
|
294 |
m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - aStart,
|
|
mathieu@4502
|
295 |
appendPrependOffset);
|
|
mathieu@4502
|
296 |
ByteTagList copy = packet->m_byteTagList;
|
|
mathieu@3035
|
297 |
copy.AddAtStart (m_buffer.GetCurrentEndOffset () - bEnd,
|
|
mathieu@3035
|
298 |
appendPrependOffset);
|
|
mathieu@4502
|
299 |
m_byteTagList.Add (copy);
|
|
mathieu@1865
|
300 |
m_metadata.AddAtEnd (packet->m_metadata);
|
|
mathieu@9
|
301 |
}
|
|
mathieu@463
|
302 |
void
|
|
mathieu@463
|
303 |
Packet::AddPaddingAtEnd (uint32_t size)
|
|
mathieu@9
|
304 |
{
|
|
mathieu@3158
|
305 |
NS_LOG_FUNCTION (this << size);
|
|
mathieu@3035
|
306 |
uint32_t orgEnd = m_buffer.GetCurrentEndOffset ();
|
|
mathieu@3035
|
307 |
bool resized = m_buffer.AddAtEnd (size);
|
|
mathieu@3035
|
308 |
if (resized)
|
|
mathieu@3035
|
309 |
{
|
|
mathieu@4502
|
310 |
m_byteTagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - orgEnd,
|
|
mathieu@4502
|
311 |
m_buffer.GetCurrentEndOffset () - size);
|
|
mathieu@3035
|
312 |
}
|
|
mathieu@888
|
313 |
m_metadata.AddPaddingAtEnd (size);
|
|
mathieu@9
|
314 |
}
|
|
mathieu@9
|
315 |
void
|
|
mathieu@122
|
316 |
Packet::RemoveAtEnd (uint32_t size)
|
|
mathieu@9
|
317 |
{
|
|
mathieu@3158
|
318 |
NS_LOG_FUNCTION (this << size);
|
|
mathieu@150
|
319 |
m_buffer.RemoveAtEnd (size);
|
|
mathieu@888
|
320 |
m_metadata.RemoveAtEnd (size);
|
|
mathieu@9
|
321 |
}
|
|
mathieu@9
|
322 |
void
|
|
mathieu@122
|
323 |
Packet::RemoveAtStart (uint32_t size)
|
|
mathieu@9
|
324 |
{
|
|
mathieu@3158
|
325 |
NS_LOG_FUNCTION (this << size);
|
|
mathieu@150
|
326 |
m_buffer.RemoveAtStart (size);
|
|
mathieu@888
|
327 |
m_metadata.RemoveAtStart (size);
|
|
mathieu@9
|
328 |
}
|
|
mathieu@9
|
329 |
|
|
mathieu@9
|
330 |
void
|
|
mathieu@4502
|
331 |
Packet::RemoveAllByteTags (void)
|
|
mathieu@9
|
332 |
{
|
|
mathieu@3158
|
333 |
NS_LOG_FUNCTION (this);
|
|
mathieu@4502
|
334 |
m_byteTagList.RemoveAll ();
|
|
mathieu@9
|
335 |
}
|
|
mathieu@9
|
336 |
|
|
mathieu@90
|
337 |
uint8_t const *
|
|
mathieu@122
|
338 |
Packet::PeekData (void) const
|
|
mathieu@90
|
339 |
{
|
|
mathieu@4483
|
340 |
NS_LOG_FUNCTION (this);
|
|
boyko@4486
|
341 |
uint32_t oldStart = m_buffer.GetCurrentStartOffset ();
|
|
boyko@4486
|
342 |
uint8_t const * data = m_buffer.PeekData ();
|
|
boyko@4486
|
343 |
uint32_t newStart = m_buffer.GetCurrentStartOffset ();
|
|
mathieu@4502
|
344 |
|
|
boyko@4486
|
345 |
// Update tag offsets if buffer offsets were changed
|
|
mathieu@4502
|
346 |
const_cast<ByteTagList &>(m_byteTagList).AddAtStart (newStart - oldStart, newStart);
|
|
boyko@4486
|
347 |
return data;
|
|
mathieu@90
|
348 |
}
|
|
mathieu@90
|
349 |
|
|
mathieu@91
|
350 |
uint32_t
|
|
mathieu@3764
|
351 |
Packet::CopyData (uint8_t *buffer, uint32_t size) const
|
|
mathieu@3764
|
352 |
{
|
|
mathieu@3764
|
353 |
Buffer::Iterator i = m_buffer.Begin ();
|
|
mathieu@3764
|
354 |
uint32_t cur = 0;
|
|
mathieu@3764
|
355 |
while (!i.IsEnd () && cur < size)
|
|
mathieu@3764
|
356 |
{
|
|
mathieu@3764
|
357 |
buffer[cur] = i.ReadU8 ();
|
|
mathieu@3764
|
358 |
cur++;
|
|
mathieu@3764
|
359 |
}
|
|
mathieu@3764
|
360 |
return cur;
|
|
mathieu@3764
|
361 |
}
|
|
mathieu@3764
|
362 |
|
|
mathieu@4518
|
363 |
void
|
|
mathieu@4518
|
364 |
Packet::CopyData(std::ostream *os, uint32_t size) const
|
|
mathieu@4518
|
365 |
{
|
|
mathieu@4518
|
366 |
return m_buffer.CopyData (os, size);
|
|
mathieu@4518
|
367 |
}
|
|
mathieu@4518
|
368 |
|
|
mathieu@3764
|
369 |
uint32_t
|
|
mathieu@122
|
370 |
Packet::GetUid (void) const
|
|
mathieu@91
|
371 |
{
|
|
mathieu@888
|
372 |
return m_metadata.GetUid ();
|
|
mathieu@91
|
373 |
}
|
|
mathieu@91
|
374 |
|
|
mathieu@463
|
375 |
void
|
|
mathieu@4502
|
376 |
Packet::PrintByteTags (std::ostream &os) const
|
|
mathieu@1241
|
377 |
{
|
|
mathieu@4502
|
378 |
ByteTagIterator i = GetByteTagIterator ();
|
|
mathieu@3208
|
379 |
while (i.HasNext ())
|
|
mathieu@3208
|
380 |
{
|
|
mathieu@4502
|
381 |
ByteTagIterator::Item item = i.Next ();
|
|
mathieu@3208
|
382 |
os << item.GetTypeId ().GetName () << " [" << item.GetStart () << "-" << item.GetEnd () << "]";
|
|
mathieu@3208
|
383 |
Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
|
|
mathieu@3208
|
384 |
if (constructor.IsNull ())
|
|
mathieu@3208
|
385 |
{
|
|
mathieu@3208
|
386 |
if (i.HasNext ())
|
|
mathieu@3208
|
387 |
{
|
|
mathieu@3208
|
388 |
os << " ";
|
|
mathieu@3208
|
389 |
}
|
|
mathieu@3208
|
390 |
continue;
|
|
mathieu@3208
|
391 |
}
|
|
mathieu@3208
|
392 |
Tag *tag = dynamic_cast<Tag *> (constructor ());
|
|
mathieu@3208
|
393 |
NS_ASSERT (tag != 0);
|
|
mathieu@3208
|
394 |
os << " ";
|
|
mathieu@3230
|
395 |
item.GetTag (*tag);
|
|
mathieu@3208
|
396 |
tag->Print (os);
|
|
mathieu@3208
|
397 |
if (i.HasNext ())
|
|
mathieu@3208
|
398 |
{
|
|
mathieu@3208
|
399 |
os << " ";
|
|
mathieu@3208
|
400 |
}
|
|
mathieu@3208
|
401 |
delete tag;
|
|
mathieu@3208
|
402 |
}
|
|
mathieu@1241
|
403 |
}
|
|
mathieu@1241
|
404 |
|
|
mathieu@1241
|
405 |
void
|
|
mathieu@463
|
406 |
Packet::Print (std::ostream &os) const
|
|
mathieu@789
|
407 |
{
|
|
mathieu@2660
|
408 |
PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
|
|
mathieu@2660
|
409 |
while (i.HasNext ())
|
|
mathieu@2660
|
410 |
{
|
|
mathieu@2660
|
411 |
PacketMetadata::Item item = i.Next ();
|
|
mathieu@2660
|
412 |
if (item.isFragment)
|
|
mathieu@2660
|
413 |
{
|
|
mathieu@2660
|
414 |
switch (item.type) {
|
|
mathieu@2660
|
415 |
case PacketMetadata::Item::PAYLOAD:
|
|
mathieu@2660
|
416 |
os << "Payload";
|
|
mathieu@2660
|
417 |
break;
|
|
mathieu@2660
|
418 |
case PacketMetadata::Item::HEADER:
|
|
mathieu@2660
|
419 |
case PacketMetadata::Item::TRAILER:
|
|
mathieu@2660
|
420 |
os << item.tid.GetName ();
|
|
mathieu@2660
|
421 |
break;
|
|
mathieu@2660
|
422 |
}
|
|
mathieu@2660
|
423 |
os << " Fragment [" << item.currentTrimedFromStart<<":"
|
|
mathieu@2660
|
424 |
<< (item.currentTrimedFromStart + item.currentSize) << "]";
|
|
mathieu@2660
|
425 |
}
|
|
mathieu@2660
|
426 |
else
|
|
mathieu@2660
|
427 |
{
|
|
mathieu@2660
|
428 |
switch (item.type) {
|
|
mathieu@2660
|
429 |
case PacketMetadata::Item::PAYLOAD:
|
|
mathieu@2660
|
430 |
os << "Payload (size=" << item.currentSize << ")";
|
|
mathieu@2660
|
431 |
break;
|
|
mathieu@2660
|
432 |
case PacketMetadata::Item::HEADER:
|
|
mathieu@2660
|
433 |
case PacketMetadata::Item::TRAILER:
|
|
mathieu@2660
|
434 |
os << item.tid.GetName () << " (";
|
|
mathieu@2660
|
435 |
{
|
|
mathieu@2660
|
436 |
NS_ASSERT (item.tid.HasConstructor ());
|
|
mathieu@2660
|
437 |
Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
|
|
mathieu@2660
|
438 |
NS_ASSERT (!constructor.IsNull ());
|
|
mathieu@2660
|
439 |
ObjectBase *instance = constructor ();
|
|
mathieu@2660
|
440 |
NS_ASSERT (instance != 0);
|
|
mathieu@2660
|
441 |
Chunk *chunk = dynamic_cast<Chunk *> (instance);
|
|
mathieu@2660
|
442 |
NS_ASSERT (chunk != 0);
|
|
mathieu@2660
|
443 |
chunk->Deserialize (item.current);
|
|
mathieu@2660
|
444 |
chunk->Print (os);
|
|
mathieu@2790
|
445 |
delete chunk;
|
|
mathieu@2660
|
446 |
}
|
|
mathieu@2660
|
447 |
os << ")";
|
|
mathieu@2660
|
448 |
break;
|
|
mathieu@2660
|
449 |
}
|
|
mathieu@2660
|
450 |
}
|
|
mathieu@2660
|
451 |
if (i.HasNext ())
|
|
mathieu@2660
|
452 |
{
|
|
mathieu@2660
|
453 |
os << " ";
|
|
mathieu@2660
|
454 |
}
|
|
mathieu@2660
|
455 |
}
|
|
mathieu@2660
|
456 |
#if 0
|
|
mathieu@2660
|
457 |
// The code below will work only if headers and trailers
|
|
mathieu@2660
|
458 |
// define the right attributes which is not the case for
|
|
mathieu@2660
|
459 |
// now. So, as a temporary measure, we use the
|
|
mathieu@2660
|
460 |
// headers' and trailers' Print method as shown above.
|
|
mathieu@2647
|
461 |
PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
|
|
mathieu@2647
|
462 |
while (i.HasNext ())
|
|
mathieu@2647
|
463 |
{
|
|
mathieu@2647
|
464 |
PacketMetadata::Item item = i.Next ();
|
|
mathieu@2647
|
465 |
if (item.isFragment)
|
|
mathieu@2647
|
466 |
{
|
|
mathieu@2647
|
467 |
switch (item.type) {
|
|
mathieu@2647
|
468 |
case PacketMetadata::Item::PAYLOAD:
|
|
mathieu@2647
|
469 |
os << "Payload";
|
|
mathieu@2647
|
470 |
break;
|
|
mathieu@2647
|
471 |
case PacketMetadata::Item::HEADER:
|
|
mathieu@2647
|
472 |
case PacketMetadata::Item::TRAILER:
|
|
mathieu@2647
|
473 |
os << item.tid.GetName ();
|
|
mathieu@2647
|
474 |
break;
|
|
mathieu@2647
|
475 |
}
|
|
mathieu@2647
|
476 |
os << " Fragment [" << item.currentTrimedFromStart<<":"
|
|
mathieu@2647
|
477 |
<< (item.currentTrimedFromStart + item.currentSize) << "]";
|
|
mathieu@2647
|
478 |
}
|
|
mathieu@2647
|
479 |
else
|
|
mathieu@2647
|
480 |
{
|
|
mathieu@2647
|
481 |
switch (item.type) {
|
|
mathieu@2647
|
482 |
case PacketMetadata::Item::PAYLOAD:
|
|
mathieu@2647
|
483 |
os << "Payload (size=" << item.currentSize << ")";
|
|
mathieu@2647
|
484 |
break;
|
|
mathieu@2647
|
485 |
case PacketMetadata::Item::HEADER:
|
|
mathieu@2647
|
486 |
case PacketMetadata::Item::TRAILER:
|
|
mathieu@2647
|
487 |
os << item.tid.GetName () << "(";
|
|
mathieu@2647
|
488 |
{
|
|
mathieu@2647
|
489 |
NS_ASSERT (item.tid.HasConstructor ());
|
|
mathieu@2647
|
490 |
Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
|
|
mathieu@2647
|
491 |
NS_ASSERT (constructor.IsNull ());
|
|
mathieu@2647
|
492 |
ObjectBase *instance = constructor ();
|
|
mathieu@2647
|
493 |
NS_ASSERT (instance != 0);
|
|
mathieu@2647
|
494 |
Chunk *chunk = dynamic_cast<Chunk *> (instance);
|
|
mathieu@2647
|
495 |
NS_ASSERT (chunk != 0);
|
|
mathieu@2647
|
496 |
chunk->Deserialize (item.current);
|
|
mathieu@2693
|
497 |
for (uint32_t j = 0; j < item.tid.GetAttributeN (); j++)
|
|
mathieu@2647
|
498 |
{
|
|
mathieu@2647
|
499 |
std::string attrName = item.tid.GetAttributeName (j);
|
|
mathieu@2647
|
500 |
std::string value;
|
|
mathieu@2647
|
501 |
bool ok = chunk->GetAttribute (attrName, value);
|
|
mathieu@2647
|
502 |
NS_ASSERT (ok);
|
|
mathieu@2647
|
503 |
os << attrName << "=" << value;
|
|
mathieu@2693
|
504 |
if ((j + 1) < item.tid.GetAttributeN ())
|
|
mathieu@2647
|
505 |
{
|
|
mathieu@2647
|
506 |
os << ",";
|
|
mathieu@2647
|
507 |
}
|
|
mathieu@2647
|
508 |
}
|
|
mathieu@2647
|
509 |
}
|
|
mathieu@2647
|
510 |
os << ")";
|
|
mathieu@2647
|
511 |
break;
|
|
mathieu@2647
|
512 |
}
|
|
mathieu@2647
|
513 |
}
|
|
mathieu@2647
|
514 |
if (i.HasNext ())
|
|
mathieu@2647
|
515 |
{
|
|
mathieu@2647
|
516 |
os << " ";
|
|
mathieu@2647
|
517 |
}
|
|
mathieu@2647
|
518 |
}
|
|
mathieu@2660
|
519 |
#endif
|
|
mathieu@789
|
520 |
}
|
|
mathieu@463
|
521 |
|
|
mathieu@2639
|
522 |
PacketMetadata::ItemIterator
|
|
mathieu@2639
|
523 |
Packet::BeginItem (void) const
|
|
mathieu@806
|
524 |
{
|
|
mathieu@2639
|
525 |
return m_metadata.BeginItem (m_buffer);
|
|
mathieu@806
|
526 |
}
|
|
mathieu@806
|
527 |
|
|
mathieu@875
|
528 |
void
|
|
mathieu@3553
|
529 |
Packet::EnablePrinting (void)
|
|
mathieu@3553
|
530 |
{
|
|
mathieu@3553
|
531 |
NS_LOG_FUNCTION_NOARGS ();
|
|
mathieu@883
|
532 |
PacketMetadata::Enable ();
|
|
mathieu@875
|
533 |
}
|
|
mathieu@463
|
534 |
|
|
mathieu@3553
|
535 |
void
|
|
mathieu@3553
|
536 |
Packet::EnableChecking (void)
|
|
mathieu@3553
|
537 |
{
|
|
mathieu@3553
|
538 |
NS_LOG_FUNCTION_NOARGS ();
|
|
mathieu@3553
|
539 |
PacketMetadata::EnableChecking ();
|
|
mathieu@3553
|
540 |
}
|
|
mathieu@3553
|
541 |
|
|
mathieu@1138
|
542 |
Buffer
|
|
mathieu@1142
|
543 |
Packet::Serialize (void) const
|
|
mathieu@1138
|
544 |
{
|
|
mathieu@3158
|
545 |
NS_LOG_FUNCTION (this);
|
|
mathieu@1144
|
546 |
Buffer buffer;
|
|
mathieu@1144
|
547 |
uint32_t reserve;
|
|
mathieu@1144
|
548 |
|
|
mathieu@1144
|
549 |
// write metadata
|
|
mathieu@1144
|
550 |
reserve = m_metadata.GetSerializedSize ();
|
|
mathieu@1144
|
551 |
buffer.AddAtStart (reserve);
|
|
mathieu@1144
|
552 |
m_metadata.Serialize (buffer.Begin (), reserve);
|
|
mathieu@1144
|
553 |
|
|
mathieu@1144
|
554 |
// write tags
|
|
mathieu@3039
|
555 |
//XXX
|
|
mathieu@3039
|
556 |
//reserve = m_tags.GetSerializedSize ();
|
|
mathieu@3039
|
557 |
//buffer.AddAtStart (reserve);
|
|
mathieu@3039
|
558 |
//m_tags.Serialize (buffer.Begin (), reserve);
|
|
mathieu@1144
|
559 |
|
|
mathieu@1144
|
560 |
// aggregate byte buffer, metadata, and tags
|
|
mathieu@1144
|
561 |
Buffer tmp = m_buffer.CreateFullCopy ();
|
|
mathieu@3039
|
562 |
tmp.AddAtEnd (buffer);
|
|
mathieu@1144
|
563 |
|
|
mathieu@1150
|
564 |
// write byte buffer size.
|
|
mathieu@3039
|
565 |
tmp.AddAtStart (4);
|
|
mathieu@3039
|
566 |
tmp.Begin ().WriteU32 (m_buffer.GetSize ());
|
|
mathieu@1144
|
567 |
|
|
mathieu@3039
|
568 |
return tmp;
|
|
mathieu@1138
|
569 |
}
|
|
mathieu@1138
|
570 |
void
|
|
mathieu@1138
|
571 |
Packet::Deserialize (Buffer buffer)
|
|
mathieu@1138
|
572 |
{
|
|
mathieu@3158
|
573 |
NS_LOG_FUNCTION (this);
|
|
mathieu@1138
|
574 |
Buffer buf = buffer;
|
|
mathieu@1144
|
575 |
// read size
|
|
mathieu@1138
|
576 |
uint32_t packetSize = buf.Begin ().ReadU32 ();
|
|
mathieu@1138
|
577 |
buf.RemoveAtStart (4);
|
|
mathieu@1144
|
578 |
|
|
mathieu@1144
|
579 |
// read buffer.
|
|
mathieu@1150
|
580 |
buf.RemoveAtEnd (buf.GetSize () - packetSize);
|
|
mathieu@1138
|
581 |
m_buffer = buf;
|
|
mathieu@3039
|
582 |
buffer.RemoveAtStart (4 + packetSize);
|
|
mathieu@3039
|
583 |
|
|
mathieu@1144
|
584 |
|
|
mathieu@1144
|
585 |
// read tags
|
|
mathieu@3039
|
586 |
//XXX
|
|
mathieu@3039
|
587 |
//uint32_t tagsDeserialized = m_tags.Deserialize (buffer.Begin ());
|
|
mathieu@3039
|
588 |
//buffer.RemoveAtStart (tagsDeserialized);
|
|
mathieu@1144
|
589 |
|
|
mathieu@1144
|
590 |
// read metadata
|
|
mathieu@1144
|
591 |
uint32_t metadataDeserialized =
|
|
mathieu@1144
|
592 |
m_metadata.Deserialize (buffer.Begin ());
|
|
mathieu@1144
|
593 |
buffer.RemoveAtStart (metadataDeserialized);
|
|
mathieu@1138
|
594 |
}
|
|
mathieu@1138
|
595 |
|
|
mathieu@3035
|
596 |
void
|
|
mathieu@4502
|
597 |
Packet::AddByteTag (const Tag &tag) const
|
|
mathieu@3035
|
598 |
{
|
|
mathieu@4484
|
599 |
NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
|
|
mathieu@4502
|
600 |
ByteTagList *list = const_cast<ByteTagList *> (&m_byteTagList);
|
|
mathieu@3040
|
601 |
TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
|
|
mathieu@4502
|
602 |
m_buffer.GetCurrentStartOffset (),
|
|
mathieu@4502
|
603 |
m_buffer.GetCurrentEndOffset ());
|
|
mathieu@3035
|
604 |
tag.Serialize (buffer);
|
|
mathieu@3035
|
605 |
}
|
|
mathieu@4502
|
606 |
ByteTagIterator
|
|
mathieu@4502
|
607 |
Packet::GetByteTagIterator (void) const
|
|
mathieu@3035
|
608 |
{
|
|
mathieu@4502
|
609 |
return ByteTagIterator (m_byteTagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ()));
|
|
mathieu@3035
|
610 |
}
|
|
mathieu@3035
|
611 |
|
|
mathieu@3035
|
612 |
bool
|
|
mathieu@4502
|
613 |
Packet::FindFirstMatchingByteTag (Tag &tag) const
|
|
mathieu@3035
|
614 |
{
|
|
mathieu@3035
|
615 |
TypeId tid = tag.GetInstanceTypeId ();
|
|
mathieu@4502
|
616 |
ByteTagIterator i = GetByteTagIterator ();
|
|
mathieu@3035
|
617 |
while (i.HasNext ())
|
|
mathieu@3035
|
618 |
{
|
|
mathieu@4502
|
619 |
ByteTagIterator::Item item = i.Next ();
|
|
mathieu@3035
|
620 |
if (tid == item.GetTypeId ())
|
|
mathieu@3035
|
621 |
{
|
|
mathieu@3035
|
622 |
item.GetTag (tag);
|
|
mathieu@3035
|
623 |
return true;
|
|
mathieu@3035
|
624 |
}
|
|
mathieu@3035
|
625 |
}
|
|
mathieu@3035
|
626 |
return false;
|
|
mathieu@3035
|
627 |
}
|
|
mathieu@3035
|
628 |
|
|
mathieu@4502
|
629 |
void
|
|
mathieu@4502
|
630 |
Packet::AddPacketTag (const Tag &tag) const
|
|
mathieu@4502
|
631 |
{
|
|
mathieu@4502
|
632 |
NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
|
|
mathieu@4502
|
633 |
m_packetTagList.Add (tag);
|
|
mathieu@4502
|
634 |
}
|
|
mathieu@4502
|
635 |
bool
|
|
mathieu@4502
|
636 |
Packet::RemovePacketTag (Tag &tag)
|
|
mathieu@4502
|
637 |
{
|
|
mathieu@4502
|
638 |
NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
|
|
mathieu@4502
|
639 |
bool found = m_packetTagList.Remove (tag);
|
|
mathieu@4502
|
640 |
return found;
|
|
mathieu@4502
|
641 |
}
|
|
mathieu@4502
|
642 |
bool
|
|
mathieu@4502
|
643 |
Packet::PeekPacketTag (Tag &tag) const
|
|
mathieu@4502
|
644 |
{
|
|
mathieu@4502
|
645 |
bool found = m_packetTagList.Peek (tag);
|
|
mathieu@4502
|
646 |
return found;
|
|
mathieu@4502
|
647 |
}
|
|
mathieu@4502
|
648 |
void
|
|
mathieu@4502
|
649 |
Packet::RemoveAllPacketTags (void)
|
|
mathieu@4502
|
650 |
{
|
|
mathieu@4502
|
651 |
NS_LOG_FUNCTION (this);
|
|
mathieu@4502
|
652 |
m_packetTagList.RemoveAll ();
|
|
mathieu@4502
|
653 |
}
|
|
mathieu@4502
|
654 |
|
|
mathieu@4502
|
655 |
void
|
|
mathieu@4502
|
656 |
Packet::PrintPacketTags (std::ostream &os) const
|
|
mathieu@4502
|
657 |
{
|
|
mathieu@4502
|
658 |
PacketTagIterator i = GetPacketTagIterator ();
|
|
mathieu@4502
|
659 |
while (i.HasNext ())
|
|
mathieu@4502
|
660 |
{
|
|
mathieu@4502
|
661 |
PacketTagIterator::Item item = i.Next ();
|
|
mathieu@4502
|
662 |
NS_ASSERT (item.GetTypeId ().HasConstructor ());
|
|
mathieu@4502
|
663 |
Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
|
|
mathieu@4502
|
664 |
NS_ASSERT (!constructor.IsNull ());
|
|
mathieu@4502
|
665 |
ObjectBase *instance = constructor ();
|
|
mathieu@4502
|
666 |
Tag *tag = dynamic_cast<Tag *> (instance);
|
|
mathieu@4502
|
667 |
NS_ASSERT (tag != 0);
|
|
mathieu@4502
|
668 |
item.GetTag (*tag);
|
|
mathieu@4502
|
669 |
tag->Print (os);
|
|
mathieu@4502
|
670 |
delete tag;
|
|
mathieu@4502
|
671 |
if (i.HasNext ())
|
|
mathieu@4502
|
672 |
{
|
|
mathieu@4502
|
673 |
os << " ";
|
|
mathieu@4502
|
674 |
}
|
|
mathieu@4502
|
675 |
}
|
|
mathieu@4502
|
676 |
}
|
|
mathieu@4502
|
677 |
|
|
mathieu@4502
|
678 |
PacketTagIterator
|
|
mathieu@4502
|
679 |
Packet::GetPacketTagIterator (void) const
|
|
mathieu@4502
|
680 |
{
|
|
mathieu@4502
|
681 |
return PacketTagIterator (m_packetTagList.Head ());
|
|
mathieu@4502
|
682 |
}
|
|
mathieu@4502
|
683 |
|
|
mathieu@1360
|
684 |
std::ostream& operator<< (std::ostream& os, const Packet &packet)
|
|
mathieu@1360
|
685 |
{
|
|
mathieu@1360
|
686 |
packet.Print (os);
|
|
mathieu@1360
|
687 |
return os;
|
|
mathieu@1360
|
688 |
}
|
|
mathieu@1360
|
689 |
|
|
boyko@5334
|
690 |
//-----------------------------------------------------------------------------
|
|
boyko@5334
|
691 |
// Unit tests
|
|
boyko@5334
|
692 |
//-----------------------------------------------------------------------------
|
|
mathieu@3035
|
693 |
namespace {
|
|
mathieu@3035
|
694 |
|
|
mathieu@3040
|
695 |
class ATestTagBase : public Tag
|
|
mathieu@3035
|
696 |
{
|
|
mathieu@3035
|
697 |
public:
|
|
mathieu@3035
|
698 |
ATestTagBase () : m_error (false) {}
|
|
mathieu@3035
|
699 |
bool m_error;
|
|
mathieu@3035
|
700 |
};
|
|
mathieu@3035
|
701 |
|
|
mathieu@3035
|
702 |
template <int N>
|
|
mathieu@3035
|
703 |
class ATestTag : public ATestTagBase
|
|
mathieu@3035
|
704 |
{
|
|
mathieu@3035
|
705 |
public:
|
|
mathieu@3035
|
706 |
static TypeId GetTypeId (void) {
|
|
mathieu@3035
|
707 |
std::ostringstream oss;
|
|
mathieu@3035
|
708 |
oss << "anon::ATestTag<" << N << ">";
|
|
mathieu@3035
|
709 |
static TypeId tid = TypeId (oss.str ().c_str ())
|
|
mathieu@3040
|
710 |
.SetParent<Tag> ()
|
|
mathieu@3035
|
711 |
.AddConstructor<ATestTag<N> > ()
|
|
mathieu@3035
|
712 |
.HideFromDocumentation ()
|
|
mathieu@3035
|
713 |
;
|
|
mathieu@3035
|
714 |
return tid;
|
|
mathieu@3035
|
715 |
}
|
|
mathieu@3035
|
716 |
virtual TypeId GetInstanceTypeId (void) const {
|
|
mathieu@3035
|
717 |
return GetTypeId ();
|
|
mathieu@3035
|
718 |
}
|
|
mathieu@3035
|
719 |
virtual uint32_t GetSerializedSize (void) const {
|
|
mathieu@3035
|
720 |
return N;
|
|
mathieu@3035
|
721 |
}
|
|
mathieu@3040
|
722 |
virtual void Serialize (TagBuffer buf) const {
|
|
mathieu@3035
|
723 |
for (uint32_t i = 0; i < N; ++i)
|
|
mathieu@3035
|
724 |
{
|
|
mathieu@3035
|
725 |
buf.WriteU8 (N);
|
|
mathieu@3035
|
726 |
}
|
|
mathieu@3035
|
727 |
}
|
|
mathieu@3040
|
728 |
virtual void Deserialize (TagBuffer buf) {
|
|
mathieu@3035
|
729 |
for (uint32_t i = 0; i < N; ++i)
|
|
mathieu@3035
|
730 |
{
|
|
mathieu@3035
|
731 |
uint8_t v = buf.ReadU8 ();
|
|
mathieu@3035
|
732 |
if (v != N)
|
|
mathieu@3035
|
733 |
{
|
|
mathieu@3035
|
734 |
m_error = true;
|
|
mathieu@3035
|
735 |
}
|
|
mathieu@3035
|
736 |
}
|
|
mathieu@3035
|
737 |
}
|
|
mathieu@3208
|
738 |
virtual void Print (std::ostream &os) const {
|
|
mathieu@3208
|
739 |
os << N;
|
|
mathieu@3208
|
740 |
}
|
|
mathieu@3035
|
741 |
ATestTag ()
|
|
mathieu@3035
|
742 |
: ATestTagBase () {}
|
|
mathieu@3035
|
743 |
};
|
|
mathieu@3035
|
744 |
|
|
mathieu@3048
|
745 |
class ATestHeaderBase : public Header
|
|
mathieu@3048
|
746 |
{
|
|
mathieu@3048
|
747 |
public:
|
|
mathieu@3048
|
748 |
ATestHeaderBase () : Header (), m_error (false) {}
|
|
mathieu@3048
|
749 |
bool m_error;
|
|
mathieu@3048
|
750 |
};
|
|
mathieu@3048
|
751 |
|
|
mathieu@3048
|
752 |
template <int N>
|
|
mathieu@3048
|
753 |
class ATestHeader : public ATestHeaderBase
|
|
mathieu@3048
|
754 |
{
|
|
mathieu@3048
|
755 |
public:
|
|
mathieu@3048
|
756 |
static TypeId GetTypeId (void) {
|
|
mathieu@3048
|
757 |
std::ostringstream oss;
|
|
mathieu@3048
|
758 |
oss << "anon::ATestHeader<" << N << ">";
|
|
mathieu@3048
|
759 |
static TypeId tid = TypeId (oss.str ().c_str ())
|
|
mathieu@3048
|
760 |
.SetParent<Header> ()
|
|
mathieu@3048
|
761 |
.AddConstructor<ATestHeader<N> > ()
|
|
mathieu@3048
|
762 |
.HideFromDocumentation ()
|
|
mathieu@3048
|
763 |
;
|
|
mathieu@3048
|
764 |
return tid;
|
|
mathieu@3048
|
765 |
}
|
|
mathieu@3048
|
766 |
virtual TypeId GetInstanceTypeId (void) const {
|
|
mathieu@3048
|
767 |
return GetTypeId ();
|
|
mathieu@3048
|
768 |
}
|
|
mathieu@3048
|
769 |
virtual uint32_t GetSerializedSize (void) const {
|
|
mathieu@3048
|
770 |
return N;
|
|
mathieu@3048
|
771 |
}
|
|
mathieu@3048
|
772 |
virtual void Serialize (Buffer::Iterator iter) const {
|
|
mathieu@3048
|
773 |
for (uint32_t i = 0; i < N; ++i)
|
|
mathieu@3048
|
774 |
{
|
|
mathieu@3048
|
775 |
iter.WriteU8 (N);
|
|
mathieu@3048
|
776 |
}
|
|
mathieu@3048
|
777 |
}
|
|
mathieu@3048
|
778 |
virtual uint32_t Deserialize (Buffer::Iterator iter) {
|
|
mathieu@3048
|
779 |
for (uint32_t i = 0; i < N; ++i)
|
|
mathieu@3048
|
780 |
{
|
|
mathieu@3048
|
781 |
uint8_t v = iter.ReadU8 ();
|
|
mathieu@3048
|
782 |
if (v != N)
|
|
mathieu@3048
|
783 |
{
|
|
mathieu@3048
|
784 |
m_error = true;
|
|
mathieu@3048
|
785 |
}
|
|
mathieu@3048
|
786 |
}
|
|
mathieu@3048
|
787 |
return N;
|
|
mathieu@3048
|
788 |
}
|
|
mathieu@3048
|
789 |
virtual void Print (std::ostream &os) const {
|
|
mathieu@3048
|
790 |
}
|
|
mathieu@3048
|
791 |
ATestHeader ()
|
|
mathieu@3048
|
792 |
: ATestHeaderBase () {}
|
|
mathieu@3048
|
793 |
|
|
mathieu@3048
|
794 |
};
|
|
mathieu@3048
|
795 |
|
|
mathieu@3237
|
796 |
class ATestTrailerBase : public Trailer
|
|
mathieu@3237
|
797 |
{
|
|
mathieu@3237
|
798 |
public:
|
|
mathieu@3237
|
799 |
ATestTrailerBase () : Trailer (), m_error (false) {}
|
|
mathieu@3237
|
800 |
bool m_error;
|
|
mathieu@3237
|
801 |
};
|
|
mathieu@3237
|
802 |
|
|
mathieu@3237
|
803 |
template <int N>
|
|
mathieu@3237
|
804 |
class ATestTrailer : public ATestTrailerBase
|
|
mathieu@3237
|
805 |
{
|
|
mathieu@3237
|
806 |
public:
|
|
mathieu@3237
|
807 |
static TypeId GetTypeId (void) {
|
|
mathieu@3237
|
808 |
std::ostringstream oss;
|
|
mathieu@3237
|
809 |
oss << "anon::ATestTrailer<" << N << ">";
|
|
mathieu@3237
|
810 |
static TypeId tid = TypeId (oss.str ().c_str ())
|
|
mathieu@3237
|
811 |
.SetParent<Header> ()
|
|
mathieu@3237
|
812 |
.AddConstructor<ATestTrailer<N> > ()
|
|
mathieu@3237
|
813 |
.HideFromDocumentation ()
|
|
mathieu@3237
|
814 |
;
|
|
mathieu@3237
|
815 |
return tid;
|
|
mathieu@3237
|
816 |
}
|
|
mathieu@3237
|
817 |
virtual TypeId GetInstanceTypeId (void) const {
|
|
mathieu@3237
|
818 |
return GetTypeId ();
|
|
mathieu@3237
|
819 |
}
|
|
mathieu@3237
|
820 |
virtual uint32_t GetSerializedSize (void) const {
|
|
mathieu@3237
|
821 |
return N;
|
|
mathieu@3237
|
822 |
}
|
|
mathieu@3237
|
823 |
virtual void Serialize (Buffer::Iterator iter) const {
|
|
mathieu@3237
|
824 |
iter.Prev (N);
|
|
mathieu@3237
|
825 |
for (uint32_t i = 0; i < N; ++i)
|
|
mathieu@3237
|
826 |
{
|
|
mathieu@3237
|
827 |
iter.WriteU8 (N);
|
|
mathieu@3237
|
828 |
}
|
|
mathieu@3237
|
829 |
}
|
|
mathieu@3237
|
830 |
virtual uint32_t Deserialize (Buffer::Iterator iter) {
|
|
mathieu@3237
|
831 |
iter.Prev (N);
|
|
mathieu@3237
|
832 |
for (uint32_t i = 0; i < N; ++i)
|
|
mathieu@3237
|
833 |
{
|
|
mathieu@3237
|
834 |
uint8_t v = iter.ReadU8 ();
|
|
mathieu@3237
|
835 |
if (v != N)
|
|
mathieu@3237
|
836 |
{
|
|
mathieu@3237
|
837 |
m_error = true;
|
|
mathieu@3237
|
838 |
}
|
|
mathieu@3237
|
839 |
}
|
|
mathieu@3237
|
840 |
return N;
|
|
mathieu@3237
|
841 |
}
|
|
mathieu@3237
|
842 |
virtual void Print (std::ostream &os) const {
|
|
mathieu@3237
|
843 |
}
|
|
mathieu@3237
|
844 |
ATestTrailer ()
|
|
mathieu@3237
|
845 |
: ATestTrailerBase () {}
|
|
mathieu@3237
|
846 |
|
|
mathieu@3237
|
847 |
};
|
|
mathieu@3237
|
848 |
|
|
mathieu@3237
|
849 |
|
|
mathieu@3035
|
850 |
struct Expected
|
|
mathieu@3035
|
851 |
{
|
|
mathieu@3035
|
852 |
Expected (uint32_t n_, uint32_t start_, uint32_t end_)
|
|
mathieu@3035
|
853 |
: n (n_), start (start_), end (end_) {}
|
|
mathieu@3035
|
854 |
|
|
mathieu@3035
|
855 |
uint32_t n;
|
|
mathieu@3035
|
856 |
uint32_t start;
|
|
mathieu@3035
|
857 |
uint32_t end;
|
|
mathieu@3035
|
858 |
};
|
|
mathieu@3035
|
859 |
|
|
mathieu@3035
|
860 |
}
|
|
mathieu@3035
|
861 |
|
|
mathieu@3237
|
862 |
// tag name, start, end
|
|
mathieu@3035
|
863 |
#define E(a,b,c) a,b,c
|
|
mathieu@3035
|
864 |
|
|
mathieu@3035
|
865 |
#define CHECK(p, n, ...) \
|
|
boyko@5334
|
866 |
DoCheck (p, __FILE__, __LINE__, n, __VA_ARGS__)
|
|
gjc@772
|
867 |
|
|
boyko@5334
|
868 |
class PacketTest: public TestCase
|
|
mathieu@3035
|
869 |
{
|
|
gjc@772
|
870 |
public:
|
|
mathieu@3035
|
871 |
PacketTest ();
|
|
boyko@5334
|
872 |
virtual bool DoRun (void);
|
|
mathieu@3035
|
873 |
private:
|
|
boyko@5334
|
874 |
void DoCheck (Ptr<const Packet> p, const char *file, int line, uint32_t n, ...);
|
|
boyko@5334
|
875 |
};
|
|
gjc@772
|
876 |
|
|
gjc@772
|
877 |
|
|
gjc@772
|
878 |
PacketTest::PacketTest ()
|
|
boyko@5334
|
879 |
: TestCase ("Packet") {}
|
|
gjc@772
|
880 |
|
|
boyko@5334
|
881 |
void
|
|
mathieu@3035
|
882 |
PacketTest::DoCheck (Ptr<const Packet> p, const char *file, int line, uint32_t n, ...)
|
|
mathieu@3035
|
883 |
{
|
|
mathieu@3035
|
884 |
std::vector<struct Expected> expected;
|
|
mathieu@3035
|
885 |
va_list ap;
|
|
mathieu@3035
|
886 |
va_start (ap, n);
|
|
mathieu@3035
|
887 |
for (uint32_t k = 0; k < n; ++k)
|
|
mathieu@3035
|
888 |
{
|
|
mathieu@3035
|
889 |
uint32_t N = va_arg (ap, uint32_t);
|
|
mathieu@3035
|
890 |
uint32_t start = va_arg (ap, uint32_t);
|
|
mathieu@3035
|
891 |
uint32_t end = va_arg (ap, uint32_t);
|
|
mathieu@3035
|
892 |
expected.push_back (Expected (N, start, end));
|
|
mathieu@3035
|
893 |
}
|
|
mathieu@3035
|
894 |
va_end (ap);
|
|
mathieu@3035
|
895 |
|
|
mathieu@4502
|
896 |
ByteTagIterator i = p->GetByteTagIterator ();
|
|
mathieu@3035
|
897 |
uint32_t j = 0;
|
|
mathieu@3035
|
898 |
while (i.HasNext () && j < expected.size ())
|
|
mathieu@3035
|
899 |
{
|
|
mathieu@4502
|
900 |
ByteTagIterator::Item item = i.Next ();
|
|
mathieu@3035
|
901 |
struct Expected e = expected[j];
|
|
mathieu@3035
|
902 |
std::ostringstream oss;
|
|
mathieu@3035
|
903 |
oss << "anon::ATestTag<" << e.n << ">";
|
|
boyko@5334
|
904 |
NS_TEST_EXPECT_MSG_EQ_INTERNAL (item.GetTypeId ().GetName (), oss.str (), "trivial", file, line);
|
|
boyko@5334
|
905 |
NS_TEST_EXPECT_MSG_EQ_INTERNAL (item.GetStart (), e.start, "trivial", file, line);
|
|
boyko@5334
|
906 |
NS_TEST_EXPECT_MSG_EQ_INTERNAL (item.GetEnd (), e.end, "trivial", file, line);
|
|
mathieu@3035
|
907 |
ATestTagBase *tag = dynamic_cast<ATestTagBase *> (item.GetTypeId ().GetConstructor () ());
|
|
boyko@5334
|
908 |
NS_TEST_EXPECT_MSG_NE (tag, 0, "trivial");
|
|
mathieu@3035
|
909 |
item.GetTag (*tag);
|
|
boyko@5334
|
910 |
NS_TEST_EXPECT_MSG_EQ (tag->m_error, false, "trivial");
|
|
mathieu@3035
|
911 |
delete tag;
|
|
mathieu@3035
|
912 |
j++;
|
|
mathieu@3035
|
913 |
}
|
|
boyko@5334
|
914 |
NS_TEST_EXPECT_MSG_EQ (i.HasNext (), false, "Nothing left");
|
|
boyko@5334
|
915 |
NS_TEST_EXPECT_MSG_EQ (j, expected.size (), "Size match");
|
|
mathieu@3035
|
916 |
}
|
|
gjc@772
|
917 |
|
|
gjc@772
|
918 |
bool
|
|
boyko@5334
|
919 |
PacketTest::DoRun (void)
|
|
gjc@772
|
920 |
{
|
|
mathieu@1865
|
921 |
Ptr<Packet> pkt1 = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello"), 5);
|
|
mathieu@1865
|
922 |
Ptr<Packet> pkt2 = Create<Packet> (reinterpret_cast<const uint8_t*> (" world"), 6);
|
|
mathieu@1865
|
923 |
Ptr<Packet> packet = Create<Packet> ();
|
|
mathieu@1865
|
924 |
packet->AddAtEnd (pkt1);
|
|
mathieu@1865
|
925 |
packet->AddAtEnd (pkt2);
|
|
gjc@772
|
926 |
|
|
boyko@5334
|
927 |
NS_TEST_EXPECT_MSG_EQ (packet->GetSize (), 11, "trivial");
|
|
gjc@772
|
928 |
|
|
mathieu@1865
|
929 |
std::string msg = std::string (reinterpret_cast<const char *>(packet->PeekData ()),
|
|
mathieu@1865
|
930 |
packet->GetSize ());
|
|
boyko@5334
|
931 |
NS_TEST_EXPECT_MSG_EQ (msg, "hello world", "trivial");
|
|
gjc@772
|
932 |
|
|
mathieu@3035
|
933 |
|
|
mathieu@3035
|
934 |
Ptr<const Packet> p = Create<Packet> (1000);
|
|
mathieu@3035
|
935 |
|
|
mathieu@4502
|
936 |
p->AddByteTag (ATestTag<1> ());
|
|
mathieu@3035
|
937 |
CHECK (p, 1, E (1, 0, 1000));
|
|
mathieu@3035
|
938 |
Ptr<const Packet> copy = p->Copy ();
|
|
mathieu@3035
|
939 |
CHECK (copy, 1, E (1, 0, 1000));
|
|
mathieu@3035
|
940 |
|
|
mathieu@4502
|
941 |
p->AddByteTag (ATestTag<2> ());
|
|
mathieu@3035
|
942 |
CHECK (p, 2, E (1, 0, 1000), E(2, 0, 1000));
|
|
mathieu@3035
|
943 |
CHECK (copy, 1, E (1, 0, 1000));
|
|
mathieu@3035
|
944 |
|
|
mathieu@3046
|
945 |
{
|
|
mathieu@3046
|
946 |
Packet c0 = *copy;
|
|
mathieu@3046
|
947 |
Packet c1 = *copy;
|
|
mathieu@3046
|
948 |
c0 = c1;
|
|
mathieu@3046
|
949 |
CHECK (&c0, 1, E (1, 0, 1000));
|
|
mathieu@3046
|
950 |
CHECK (&c1, 1, E (1, 0, 1000));
|
|
mathieu@3046
|
951 |
CHECK (copy, 1, E (1, 0, 1000));
|
|
mathieu@4502
|
952 |
c0.AddByteTag (ATestTag<10> ());
|
|
mathieu@3046
|
953 |
CHECK (&c0, 2, E (1, 0, 1000), E (10, 0, 1000));
|
|
mathieu@3046
|
954 |
CHECK (&c1, 1, E (1, 0, 1000));
|
|
mathieu@3046
|
955 |
CHECK (copy, 1, E (1, 0, 1000));
|
|
mathieu@3046
|
956 |
}
|
|
mathieu@3046
|
957 |
|
|
mathieu@3035
|
958 |
Ptr<Packet> frag0 = p->CreateFragment (0, 10);
|
|
mathieu@3035
|
959 |
Ptr<Packet> frag1 = p->CreateFragment (10, 90);
|
|
mathieu@3035
|
960 |
Ptr<const Packet> frag2 = p->CreateFragment (100, 900);
|
|
mathieu@4502
|
961 |
frag0->AddByteTag (ATestTag<3> ());
|
|
mathieu@3035
|
962 |
CHECK (frag0, 3, E (1, 0, 10), E(2, 0, 10), E (3, 0, 10));
|
|
mathieu@4502
|
963 |
frag1->AddByteTag (ATestTag<4> ());
|
|
mathieu@3035
|
964 |
CHECK (frag1, 3, E (1, 0, 90), E(2, 0, 90), E (4, 0, 90));
|
|
mathieu@4502
|
965 |
frag2->AddByteTag (ATestTag<5> ());
|
|
mathieu@3035
|
966 |
CHECK (frag2, 3, E (1, 0, 900), E(2, 0, 900), E (5, 0, 900));
|
|
mathieu@3035
|
967 |
|
|
mathieu@3035
|
968 |
frag1->AddAtEnd (frag2);
|
|
mathieu@3035
|
969 |
CHECK (frag1, 6, E (1, 0, 90), E(2, 0, 90), E (4, 0, 90), E (1, 90, 990), E(2, 90, 990), E (5, 90, 990));
|
|
mathieu@3035
|
970 |
|
|
mathieu@3035
|
971 |
CHECK (frag0, 3, E (1, 0, 10), E(2, 0, 10), E (3, 0, 10));
|
|
mathieu@3035
|
972 |
frag0->AddAtEnd (frag1);
|
|
mathieu@3035
|
973 |
CHECK (frag0, 9,
|
|
mathieu@3035
|
974 |
E (1, 0, 10), E(2, 0, 10), E (3, 0, 10),
|
|
mathieu@3035
|
975 |
E (1, 10, 100), E(2, 10, 100), E (4, 10, 100),
|
|
mathieu@3035
|
976 |
E (1, 100, 1000), E(2, 100, 1000), E (5, 100, 1000));
|
|
mathieu@3035
|
977 |
|
|
mathieu@3048
|
978 |
|
|
mathieu@3048
|
979 |
// force caching a buffer of the right size.
|
|
mathieu@3048
|
980 |
frag0 = Create<Packet> (1000);
|
|
mathieu@3048
|
981 |
frag0->AddHeader (ATestHeader<10> ());
|
|
mathieu@3048
|
982 |
frag0 = 0;
|
|
mathieu@3048
|
983 |
|
|
mathieu@3048
|
984 |
p = Create<Packet> (1000);
|
|
mathieu@4502
|
985 |
p->AddByteTag (ATestTag<20> ());
|
|
mathieu@3048
|
986 |
CHECK (p, 1, E (20, 0, 1000));
|
|
mathieu@3048
|
987 |
frag0 = p->CreateFragment (10, 90);
|
|
mathieu@3048
|
988 |
CHECK (p, 1, E (20, 0, 1000));
|
|
mathieu@3048
|
989 |
CHECK (frag0, 1, E (20, 0, 90));
|
|
mathieu@3048
|
990 |
p = 0;
|
|
mathieu@3048
|
991 |
frag0->AddHeader (ATestHeader<10> ());
|
|
mathieu@3048
|
992 |
CHECK (frag0, 1, E (20, 10, 100));
|
|
mathieu@3048
|
993 |
|
|
mathieu@3237
|
994 |
{
|
|
mathieu@3237
|
995 |
Ptr<Packet> tmp = Create<Packet> (100);
|
|
mathieu@4502
|
996 |
tmp->AddByteTag (ATestTag<20> ());
|
|
mathieu@3237
|
997 |
CHECK (tmp, 1, E (20, 0, 100));
|
|
mathieu@3237
|
998 |
tmp->AddHeader (ATestHeader<10> ());
|
|
mathieu@3237
|
999 |
CHECK (tmp, 1, E (20, 10, 110));
|
|
mathieu@3237
|
1000 |
ATestHeader<10> h;
|
|
mathieu@3237
|
1001 |
tmp->RemoveHeader (h);
|
|
mathieu@3237
|
1002 |
CHECK (tmp, 1, E (20, 0, 100));
|
|
mathieu@3237
|
1003 |
tmp->AddHeader (ATestHeader<10> ());
|
|
mathieu@3237
|
1004 |
CHECK (tmp, 1, E (20, 10, 110));
|
|
mathieu@3237
|
1005 |
|
|
mathieu@3237
|
1006 |
tmp = Create<Packet> (100);
|
|
mathieu@4502
|
1007 |
tmp->AddByteTag (ATestTag<20> ());
|
|
mathieu@3237
|
1008 |
CHECK (tmp, 1, E (20, 0, 100));
|
|
mathieu@3237
|
1009 |
tmp->AddTrailer (ATestTrailer<10> ());
|
|
mathieu@3237
|
1010 |
CHECK (tmp, 1, E (20, 0, 100));
|
|
mathieu@3237
|
1011 |
ATestTrailer<10> t;
|
|
mathieu@3237
|
1012 |
tmp->RemoveTrailer (t);
|
|
mathieu@3237
|
1013 |
CHECK (tmp, 1, E (20, 0, 100));
|
|
mathieu@3237
|
1014 |
tmp->AddTrailer (ATestTrailer<10> ());
|
|
mathieu@3237
|
1015 |
CHECK (tmp, 1, E (20, 0, 100));
|
|
mathieu@3237
|
1016 |
|
|
mathieu@3237
|
1017 |
}
|
|
mathieu@3298
|
1018 |
|
|
mathieu@3298
|
1019 |
{
|
|
mathieu@3298
|
1020 |
Ptr<Packet> tmp = Create<Packet> (0);
|
|
mathieu@3298
|
1021 |
tmp->AddHeader (ATestHeader<156> ());
|
|
mathieu@4502
|
1022 |
tmp->AddByteTag (ATestTag<20> ());
|
|
mathieu@3298
|
1023 |
CHECK (tmp, 1, E (20, 0, 156));
|
|
mathieu@3298
|
1024 |
tmp->RemoveAtStart (120);
|
|
mathieu@3298
|
1025 |
CHECK (tmp, 1, E (20, 0, 36));
|
|
mathieu@3298
|
1026 |
Ptr<Packet> a = Create<Packet> (0);
|
|
mathieu@3298
|
1027 |
a->AddAtEnd (tmp);
|
|
mathieu@3298
|
1028 |
CHECK (a, 1, E (20, 0, 36));
|
|
mathieu@3300
|
1029 |
}
|
|
mathieu@3300
|
1030 |
|
|
mathieu@3300
|
1031 |
{
|
|
mathieu@3300
|
1032 |
Ptr<Packet> tmp = Create<Packet> (0);
|
|
mathieu@4502
|
1033 |
tmp->AddByteTag (ATestTag<20> ());
|
|
mathieu@3300
|
1034 |
CHECK (tmp, 0, E (20, 0, 0));
|
|
mathieu@3300
|
1035 |
}
|
|
mathieu@3301
|
1036 |
{
|
|
mathieu@3301
|
1037 |
Ptr<Packet> tmp = Create<Packet> (1000);
|
|
mathieu@4502
|
1038 |
tmp->AddByteTag (ATestTag<20> ());
|
|
mathieu@3301
|
1039 |
CHECK (tmp, 1, E (20, 0, 1000));
|
|
mathieu@3301
|
1040 |
tmp->RemoveAtStart (1000);
|
|
mathieu@3301
|
1041 |
CHECK (tmp, 0, E (0,0,0));
|
|
mathieu@3301
|
1042 |
Ptr<Packet> a = Create<Packet> (10);
|
|
mathieu@4502
|
1043 |
a->AddByteTag (ATestTag<10> ());
|
|
mathieu@3301
|
1044 |
CHECK (a, 1, E (10, 0, 10));
|
|
mathieu@3301
|
1045 |
tmp->AddAtEnd (a);
|
|
mathieu@3301
|
1046 |
CHECK (tmp, 1, E (10, 0, 10));
|
|
mathieu@3301
|
1047 |
}
|
|
mathieu@4502
|
1048 |
|
|
mathieu@4502
|
1049 |
{
|
|
mathieu@4502
|
1050 |
Packet p;
|
|
mathieu@4502
|
1051 |
ATestTag<10> a;
|
|
mathieu@4502
|
1052 |
p.AddPacketTag (a);
|
|
boyko@5334
|
1053 |
NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (a), true, "trivial");
|
|
mathieu@4502
|
1054 |
ATestTag<11> b;
|
|
mathieu@4502
|
1055 |
p.AddPacketTag (b);
|
|
boyko@5334
|
1056 |
NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (b), true, "trivial");
|
|
boyko@5334
|
1057 |
NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (a), true, "trivial");
|
|
mathieu@4502
|
1058 |
Packet copy = p;
|
|
boyko@5334
|
1059 |
NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (b), true, "trivial");
|
|
boyko@5334
|
1060 |
NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (a), true, "trivial");
|
|
mathieu@4502
|
1061 |
ATestTag<12> c;
|
|
boyko@5334
|
1062 |
NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (c), false, "trivial");
|
|
mathieu@4502
|
1063 |
copy.AddPacketTag (c);
|
|
boyko@5334
|
1064 |
NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (c), true, "trivial");
|
|
boyko@5334
|
1065 |
NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (b), true, "trivial");
|
|
boyko@5334
|
1066 |
NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (a), true, "trivial");
|
|
boyko@5334
|
1067 |
NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (c), false, "trivial");
|
|
mathieu@4502
|
1068 |
copy.RemovePacketTag (b);
|
|
boyko@5334
|
1069 |
NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (b), false, "trivial");
|
|
boyko@5334
|
1070 |
NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (b), true, "trivial");
|
|
mathieu@4502
|
1071 |
p.RemovePacketTag (a);
|
|
boyko@5334
|
1072 |
NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (a), false, "trivial");
|
|
boyko@5334
|
1073 |
NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (a), true, "trivial");
|
|
boyko@5334
|
1074 |
NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (c), false, "trivial");
|
|
boyko@5334
|
1075 |
NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (c), true, "trivial");
|
|
mathieu@4502
|
1076 |
p.RemoveAllPacketTags ();
|
|
boyko@5334
|
1077 |
NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (b), false, "trivial");
|
|
mathieu@4502
|
1078 |
}
|
|
mathieu@4502
|
1079 |
|
|
boyko@4486
|
1080 |
{
|
|
boyko@4486
|
1081 |
// bug 572
|
|
boyko@4486
|
1082 |
Ptr<Packet> tmp = Create<Packet> (1000);
|
|
mathieu@4502
|
1083 |
tmp->AddByteTag (ATestTag<20> ());
|
|
boyko@4486
|
1084 |
CHECK (tmp, 1, E (20, 0, 1000));
|
|
boyko@4486
|
1085 |
tmp->AddHeader (ATestHeader<2> ());
|
|
boyko@4486
|
1086 |
CHECK (tmp, 1, E (20, 2, 1002));
|
|
boyko@4486
|
1087 |
tmp->RemoveAtStart (1);
|
|
boyko@4486
|
1088 |
CHECK (tmp, 1, E (20, 1, 1001));
|
|
boyko@4486
|
1089 |
tmp->PeekData ();
|
|
boyko@4486
|
1090 |
CHECK (tmp, 1, E (20, 1, 1001));
|
|
boyko@4486
|
1091 |
}
|
|
mathieu@3048
|
1092 |
|
|
boyko@5334
|
1093 |
return GetErrorStatus ();
|
|
boyko@5334
|
1094 |
}
|
|
boyko@5334
|
1095 |
//-----------------------------------------------------------------------------
|
|
boyko@5334
|
1096 |
class PacketTestSuite : public TestSuite
|
|
boyko@5334
|
1097 |
{
|
|
boyko@5334
|
1098 |
public:
|
|
boyko@5334
|
1099 |
PacketTestSuite ();
|
|
boyko@5334
|
1100 |
};
|
|
boyko@5334
|
1101 |
|
|
boyko@5334
|
1102 |
PacketTestSuite::PacketTestSuite ()
|
|
boyko@5334
|
1103 |
: TestSuite ("packet", UNIT)
|
|
boyko@5334
|
1104 |
{
|
|
boyko@5334
|
1105 |
AddTestCase (new PacketTest);
|
|
gjc@772
|
1106 |
}
|
|
gjc@772
|
1107 |
|
|
boyko@5334
|
1108 |
PacketTestSuite g_packetTestSuite;
|
|
boyko@5334
|
1109 |
|
|
boyko@5334
|
1110 |
|
|
mathieu@4502
|
1111 |
} // namespace ns3
|