A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
lte-rlc-am-header.cc
Go to the documentation of this file.
1
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
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: Manuel Requena <manuel.requena@cttc.es>
19
*/
20
21
#include "ns3/log.h"
22
23
#include "ns3/lte-rlc-am-header.h"
24
25
NS_LOG_COMPONENT_DEFINE
(
"LteRlcAmHeader"
);
26
27
namespace
ns3 {
28
29
NS_OBJECT_ENSURE_REGISTERED
(LteRlcAmHeader);
30
31
LteRlcAmHeader::LteRlcAmHeader
()
32
: m_headerLength (0),
33
m_dataControlBit (0xff),
34
m_resegmentationFlag (0xff),
35
m_pollingBit (0xff),
36
m_framingInfo (0xff),
37
m_sequenceNumber (0xfffa),
38
m_segmentOffset (0xffff),
39
m_lastOffset (0xffff),
40
m_controlPduType (0xff),
41
m_ackSn (0xffff),
42
m_nackSn (0xffff)
43
{
44
}
45
46
LteRlcAmHeader::~LteRlcAmHeader
()
47
{
48
m_headerLength
= 0;
49
m_dataControlBit
= 0xff;
50
m_resegmentationFlag
= 0xff;
51
m_pollingBit
= 0xff;
52
m_framingInfo
= 0xff;
53
m_sequenceNumber
= 0xfffb;
54
m_segmentOffset
= 0xffff;
55
m_lastOffset
= 0xffff;
56
m_controlPduType
= 0xff;
57
m_ackSn
= 0xffff;
58
m_nackSn
= 0xffff;
59
}
60
61
void
62
LteRlcAmHeader::SetDataPdu
(
void
)
63
{
64
m_headerLength
= 4;
65
m_dataControlBit
=
DATA_PDU
;
66
}
67
void
68
LteRlcAmHeader::SetControlPdu
(uint8_t controlPduType)
69
{
70
m_headerLength
= 2;
71
m_dataControlBit
=
CONTROL_PDU
;
72
m_controlPduType
= controlPduType;
73
}
74
bool
75
LteRlcAmHeader::IsDataPdu
(
void
)
const
76
{
77
return
(
m_dataControlBit
==
DATA_PDU
) ?
true
:
false
;
78
}
79
bool
80
LteRlcAmHeader::IsControlPdu
(
void
)
const
81
{
82
return
(
m_dataControlBit
==
CONTROL_PDU
) ?
true
:
false
;
83
}
84
85
void
86
LteRlcAmHeader::SetFramingInfo
(uint8_t framingInfo)
87
{
88
m_framingInfo
= framingInfo & 0x03;
89
}
90
91
void
92
LteRlcAmHeader::SetSequenceNumber
(
SequenceNumber10
sequenceNumber)
93
{
94
m_sequenceNumber
= sequenceNumber;
95
}
96
97
uint8_t
98
LteRlcAmHeader::GetFramingInfo
()
const
99
{
100
return
m_framingInfo
;
101
}
102
103
SequenceNumber10
104
LteRlcAmHeader::GetSequenceNumber
()
const
105
{
106
return
m_sequenceNumber
;
107
}
108
109
110
void
111
LteRlcAmHeader::PushExtensionBit
(uint8_t extensionBit)
112
{
113
m_extensionBits
.push_back (extensionBit);
114
if
(
m_extensionBits
.size() > 1)
115
{
116
if
(
m_extensionBits
.size() % 2)
117
{
118
m_headerLength
+= 1;
119
}
120
else
121
{
122
m_headerLength
+= 2;
123
}
124
}
125
}
126
127
void
128
LteRlcAmHeader::PushLengthIndicator
(uint16_t lengthIndicator)
129
{
130
m_lengthIndicators
.push_back (lengthIndicator);
131
}
132
133
134
uint8_t
135
LteRlcAmHeader::PopExtensionBit
(
void
)
136
{
137
uint8_t extensionBit =
m_extensionBits
.front ();
138
m_extensionBits
.pop_front ();
139
140
return
extensionBit;
141
}
142
143
uint16_t
144
LteRlcAmHeader::PopLengthIndicator
(
void
)
145
{
146
uint16_t lengthIndicator =
m_lengthIndicators
.front ();
147
m_lengthIndicators
.pop_front ();
148
149
return
lengthIndicator;
150
}
151
152
153
void
154
LteRlcAmHeader::SetResegmentationFlag
(uint8_t resegFlag)
155
{
156
m_resegmentationFlag
= resegFlag & 0x01;
157
}
158
159
uint8_t
160
LteRlcAmHeader::GetResegmentationFlag
()
const
161
{
162
return
m_resegmentationFlag
;
163
}
164
165
166
void
167
LteRlcAmHeader::SetPollingBit
(uint8_t pollingBit)
168
{
169
m_pollingBit
= pollingBit & 0x01;
170
}
171
172
uint8_t
173
LteRlcAmHeader::GetPollingBit
(
void
)
const
174
{
175
return
m_pollingBit
;
176
}
177
178
179
void
180
LteRlcAmHeader::SetLastSegmentFlag
(uint8_t lsf)
181
{
182
m_lastSegmentFlag
= lsf & 0x01;
183
}
184
185
uint8_t
186
LteRlcAmHeader::GetLastSegmentFlag
(
void
)
const
187
{
188
return
m_lastSegmentFlag
;
189
}
190
191
192
void
193
LteRlcAmHeader::SetSegmentOffset
(uint16_t segmentOffset)
194
{
195
m_segmentOffset
= segmentOffset & 0x7FFF;
196
}
197
198
uint16_t
199
LteRlcAmHeader::GetSegmentOffset
(
void
)
const
200
{
201
return
m_segmentOffset
;
202
}
203
204
uint16_t
205
LteRlcAmHeader::GetLastOffset
(
void
)
const
206
{
207
return
m_lastOffset
;
208
}
209
210
211
void
212
LteRlcAmHeader::SetAckSn
(
SequenceNumber10
ackSn)
213
{
214
m_ackSn
= ackSn;
215
}
216
217
SequenceNumber10
218
LteRlcAmHeader::GetAckSn
(
void
)
const
219
{
220
return
m_ackSn
;
221
}
222
223
224
TypeId
225
LteRlcAmHeader::GetTypeId
(
void
)
226
{
227
static
TypeId
tid =
TypeId
(
"ns3::LteRlcAmHeader"
)
228
.
SetParent
<
Header
> ()
229
.AddConstructor<LteRlcAmHeader> ()
230
;
231
return
tid;
232
}
233
234
TypeId
235
LteRlcAmHeader::GetInstanceTypeId
(
void
)
const
236
{
237
return
GetTypeId
();
238
}
239
240
void
241
LteRlcAmHeader::Print
(std::ostream &os)
const
242
{
243
std::list <uint8_t>::const_iterator it1 =
m_extensionBits
.begin ();
244
std::list <uint16_t>::const_iterator it2 =
m_lengthIndicators
.begin ();
245
246
os <<
"Len="
<<
m_headerLength
;
247
os <<
" D/C="
<< (uint16_t)
m_dataControlBit
;
248
249
if
(
m_dataControlBit
==
DATA_PDU
)
250
{
251
os <<
" RF="
<< (uint16_t)
m_resegmentationFlag
;
252
os <<
" P="
<< (uint16_t)
m_pollingBit
;
253
os <<
" FI="
<< (uint16_t)
m_framingInfo
;
254
os <<
" E="
<< (uint16_t)(*it1);
255
os <<
" SN="
<<
m_sequenceNumber
;
256
os <<
" LSF="
<< (uint16_t)(
m_lastSegmentFlag
);
257
os <<
" SO="
<<
m_segmentOffset
;
258
259
it1++;
260
if
(it1 !=
m_extensionBits
.end ())
261
{
262
os <<
" E="
;
263
}
264
while
( it1 !=
m_extensionBits
.end () )
265
{
266
os << (uint16_t)(*it1);
267
it1++;
268
}
269
270
if
(it2 !=
m_lengthIndicators
.end ())
271
{
272
os <<
" LI="
;
273
}
274
while
( it2 !=
m_lengthIndicators
.end () )
275
{
276
os << (uint16_t)(*it2) <<
" "
;
277
it2++;
278
}
279
}
280
else
// if ( m_dataControlBit == CONTROL_PDU )
281
{
282
os <<
" ACK_SN="
<<
m_ackSn
;
283
os <<
" NACK_SN="
<<
m_nackSn
;
284
}
285
}
286
287
uint32_t
LteRlcAmHeader::GetSerializedSize
(
void
)
const
288
{
289
return
m_headerLength
;
290
}
291
292
void
LteRlcAmHeader::Serialize
(
Buffer::Iterator
start
)
const
293
{
294
Buffer::Iterator
i =
start
;
295
296
std::list <uint8_t>::const_iterator it1 =
m_extensionBits
.begin ();
297
std::list <uint16_t>::const_iterator it2 =
m_lengthIndicators
.begin ();
298
299
if
(
m_dataControlBit
==
DATA_PDU
)
300
{
301
i.
WriteU8
( ((
DATA_PDU
<< 7) & 0x80) |
302
((
m_resegmentationFlag
<< 6) & 0x40) |
303
((
m_pollingBit
<< 5) & 0x20) |
304
((
m_framingInfo
<< 3) & 0x18) |
305
(((*it1) << 2) & 0x04) |
306
((
m_sequenceNumber
.
GetValue
() >> 8) & 0x0003) );
307
i.
WriteU8
(
m_sequenceNumber
.
GetValue
() & 0x00FF );
308
i.
WriteU8
( ((
m_lastSegmentFlag
<< 7) & 0x80) |
309
((
m_segmentOffset
>> 8) & 0x007F) );
310
i.
WriteU8
(
m_segmentOffset
& 0x00FF );
311
it1++;
312
313
while
( it1 !=
m_extensionBits
.end () &&
314
it2 !=
m_lengthIndicators
.end () )
315
{
316
uint16_t oddLi, evenLi;
317
uint8_t oddE, evenE;
318
319
oddE = *it1;
320
oddLi = *it2;
321
322
it1++;
323
it2++;
324
325
if
( it1 !=
m_extensionBits
.end () &&
326
it2 !=
m_lengthIndicators
.end () )
327
{
328
evenE = *it1;
329
evenLi = *it2;
330
331
i.
WriteU8
( ((oddE << 7) & 0x80) | ((oddLi >> 4) & 0x007F) );
332
i.
WriteU8
( ((oddLi << 4) & 0x00F0) | ((evenE << 3) & 0x08) | ((evenLi >> 8) & 0x0007) );
333
i.
WriteU8
( evenLi & 0x00FF );
334
335
it1++;
336
it2++;
337
}
338
else
339
{
340
i.
WriteU8
( ((oddE << 7) & 0x80) | ((oddLi >> 4) & 0x007F) );
341
i.
WriteU8
( ((oddLi << 4) & 0x00F0) );
// Padding is implicit
342
}
343
}
344
}
345
else
// if ( m_dataControlBit == CONTROL_PDU )
346
{
347
i.
WriteU8
( ((
CONTROL_PDU
<< 7) & 0x80) |
348
((
m_controlPduType
<< 4) & 0x70) |
349
((
m_ackSn
.
GetValue
() >> 6) & 0x0F) );
350
i.
WriteU8
( ((
m_ackSn
.
GetValue
() << 2) & 0xFC) );
351
}
352
}
353
354
uint32_t
LteRlcAmHeader::Deserialize
(
Buffer::Iterator
start
)
355
{
356
Buffer::Iterator
i =
start
;
357
uint8_t byte_1;
358
uint8_t byte_2;
359
uint8_t byte_3;
360
uint8_t byte_4;
361
uint8_t extensionBit;
362
363
byte_1 = i.
ReadU8
();
364
m_headerLength
= 1;
365
m_dataControlBit
= (byte_1 & 0x80) >> 7;
366
367
if
(
m_dataControlBit
==
DATA_PDU
)
368
{
369
byte_2 = i.
ReadU8
();
370
byte_3 = i.
ReadU8
();
371
byte_4 = i.
ReadU8
();
372
m_headerLength
+= 3;
373
374
m_resegmentationFlag
= (byte_1 & 0x40) >> 6;
375
m_pollingBit
= (byte_1 & 0x20) >> 5;
376
m_framingInfo
= (byte_1 & 0x18) >> 3;
377
m_sequenceNumber
= ((byte_1 & 0x03) << 8) | byte_2;
378
379
m_lastSegmentFlag
= (byte_3 & 0x80) >> 7;
380
m_segmentOffset
= (byte_3 & 0x7F) | byte_4;
381
382
extensionBit = (byte_1 & 0x04) >> 2;
383
m_extensionBits
.push_back (extensionBit);
384
385
if
(extensionBit ==
DATA_FIELD_FOLLOWS
)
386
{
387
return
GetSerializedSize
();
388
}
389
390
uint16_t oddLi, evenLi;
391
uint8_t oddE, evenE;
392
bool
moreLiFields = (extensionBit ==
E_LI_FIELDS_FOLLOWS
);
393
394
while
(moreLiFields)
395
{
396
byte_1 = i.
ReadU8
();
397
byte_2 = i.
ReadU8
();
398
399
oddE = (byte_1 & 0x80) >> 7;
400
oddLi = ((byte_1 & 0x7F) << 4) | ((byte_2 & 0xF0) >> 4);
401
moreLiFields = (oddE ==
E_LI_FIELDS_FOLLOWS
);
402
403
m_extensionBits
.push_back (oddE);
404
m_lengthIndicators
.push_back (oddLi);
405
m_headerLength
+= 2;
406
407
if
(moreLiFields)
408
{
409
byte_3 = i.
ReadU8
();
410
411
evenE = (byte_2 & 0x08) >> 3;
412
evenLi = ((byte_2 & 0x07) << 8) | (byte_3 & 0xFF);
413
moreLiFields = (evenE ==
E_LI_FIELDS_FOLLOWS
);
414
415
m_extensionBits
.push_back (evenE);
416
m_lengthIndicators
.push_back (evenLi);
417
418
m_headerLength
+= 1;
419
}
420
}
421
422
if
(
m_resegmentationFlag
==
SEGMENT
)
423
{
424
m_lastOffset
=
m_segmentOffset
+ start.
GetSize
() -
m_headerLength
;
425
}
426
}
427
else
// if ( m_dataControlBit == CONTROL_PDU )
428
{
429
byte_2 = i.
ReadU8
();
430
431
m_controlPduType
= (byte_1 & 0x70) >> 4;
432
m_ackSn
= ((byte_1 & 0x0F) << 6 ) | ((byte_2 & 0xFC) >> 2);
433
434
m_headerLength
++;
435
}
436
437
return
GetSerializedSize
();
438
}
439
440
};
// namespace ns3
src
lte
model
lte-rlc-am-header.cc
Generated on Tue Oct 9 2012 16:45:40 for ns-3 by
1.8.1.2