A Discrete-Event Network Simulator
API
 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 
33  : m_headerLength (0),
34  m_dataControlBit (0xff),
35  m_resegmentationFlag (0xff),
36  m_pollingBit (0xff),
37  m_framingInfo (0xff),
38  m_sequenceNumber (0xfffa),
39  m_segmentOffset (0xffff),
40  m_lastOffset (0xffff),
41  m_controlPduType (0xff),
42  m_ackSn (0xffff),
43  m_nackSn (0xffff)
44 {
45 }
46 
48 {
49  m_headerLength = 0;
50  m_dataControlBit = 0xff;
51  m_resegmentationFlag = 0xff;
52  m_pollingBit = 0xff;
53  m_framingInfo = 0xff;
54  m_sequenceNumber = 0xfffb;
55  m_segmentOffset = 0xffff;
56  m_lastOffset = 0xffff;
57  m_controlPduType = 0xff;
58  m_ackSn = 0xffff;
59  m_nackSn = 0xffff;
60 }
61 
62 void
64 {
65  m_headerLength = 4;
67 }
68 void
69 LteRlcAmHeader::SetControlPdu (uint8_t controlPduType)
70 {
71  m_headerLength = 2;
73  m_controlPduType = controlPduType;
74 }
75 bool
77 {
78  return (m_dataControlBit == DATA_PDU) ? true : false;
79 }
80 bool
82 {
83  return (m_dataControlBit == CONTROL_PDU) ? true : false;
84 }
85 
86 void
87 LteRlcAmHeader::SetFramingInfo (uint8_t framingInfo)
88 {
89  m_framingInfo = framingInfo & 0x03;
90 }
91 
92 void
94 {
95  m_sequenceNumber = sequenceNumber;
96 }
97 
98 uint8_t
100 {
101  return m_framingInfo;
102 }
103 
106 {
107  return m_sequenceNumber;
108 }
109 
110 
111 void
112 LteRlcAmHeader::PushExtensionBit (uint8_t extensionBit)
113 {
114  m_extensionBits.push_back (extensionBit);
115  if (m_extensionBits.size() > 1)
116  {
117  if (m_extensionBits.size() % 2)
118  {
119  m_headerLength += 1;
120  }
121  else
122  {
123  m_headerLength += 2;
124  }
125  }
126 }
127 
128 void
129 LteRlcAmHeader::PushLengthIndicator (uint16_t lengthIndicator)
130 {
131  m_lengthIndicators.push_back (lengthIndicator);
132 }
133 
134 
135 uint8_t
137 {
138  uint8_t extensionBit = m_extensionBits.front ();
139  m_extensionBits.pop_front ();
140 
141  return extensionBit;
142 }
143 
144 uint16_t
146 {
147  uint16_t lengthIndicator = m_lengthIndicators.front ();
148  m_lengthIndicators.pop_front ();
149 
150  return lengthIndicator;
151 }
152 
153 
154 void
156 {
157  m_resegmentationFlag = resegFlag & 0x01;
158 }
159 
160 uint8_t
162 {
163  return m_resegmentationFlag;
164 }
165 
166 
167 void
168 LteRlcAmHeader::SetPollingBit (uint8_t pollingBit)
169 {
170  m_pollingBit = pollingBit & 0x01;
171 }
172 
173 uint8_t
175 {
176  return m_pollingBit;
177 }
178 
179 
180 void
182 {
183  m_lastSegmentFlag = lsf & 0x01;
184 }
185 
186 uint8_t
188 {
189  return m_lastSegmentFlag;
190 }
191 
192 
193 void
194 LteRlcAmHeader::SetSegmentOffset (uint16_t segmentOffset)
195 {
196  m_segmentOffset = segmentOffset & 0x7FFF;
197 }
198 
199 uint16_t
201 {
202  return m_segmentOffset;
203 }
204 
205 uint16_t
207 {
208  return m_lastOffset;
209 }
210 
211 
212 void
214 {
215  m_ackSn = ackSn;
216 }
217 
220 {
221  return m_ackSn;
222 }
223 
224 
225 TypeId
227 {
228  static TypeId tid = TypeId ("ns3::LteRlcAmHeader")
229  .SetParent<Header> ()
230  .AddConstructor<LteRlcAmHeader> ()
231  ;
232  return tid;
233 }
234 
235 TypeId
237 {
238  return GetTypeId ();
239 }
240 
241 void
242 LteRlcAmHeader::Print (std::ostream &os) const
243 {
244  std::list <uint8_t>::const_iterator it1 = m_extensionBits.begin ();
245  std::list <uint16_t>::const_iterator it2 = m_lengthIndicators.begin ();
246 
247  os << "Len=" << m_headerLength;
248  os << " D/C=" << (uint16_t)m_dataControlBit;
249 
250  if ( m_dataControlBit == DATA_PDU )
251  {
252  os << " RF=" << (uint16_t)m_resegmentationFlag;
253  os << " P=" << (uint16_t)m_pollingBit;
254  os << " FI=" << (uint16_t)m_framingInfo;
255  os << " E=" << (uint16_t)(*it1);
256  os << " SN=" << m_sequenceNumber;
257  os << " LSF=" << (uint16_t)(m_lastSegmentFlag);
258  os << " SO=" << m_segmentOffset;
259 
260  it1++;
261  if (it1 != m_extensionBits.end ())
262  {
263  os << " E=";
264  }
265  while ( it1 != m_extensionBits.end () )
266  {
267  os << (uint16_t)(*it1);
268  it1++;
269  }
270 
271  if (it2 != m_lengthIndicators.end ())
272  {
273  os << " LI=";
274  }
275  while ( it2 != m_lengthIndicators.end () )
276  {
277  os << (uint16_t)(*it2) << " ";
278  it2++;
279  }
280  }
281  else // if ( m_dataControlBit == CONTROL_PDU )
282  {
283  os << " ACK_SN=" << m_ackSn;
284  os << " NACK_SN=" << m_nackSn;
285  }
286 }
287 
289 {
290  return m_headerLength;
291 }
292 
294 {
296 
297  std::list <uint8_t>::const_iterator it1 = m_extensionBits.begin ();
298  std::list <uint16_t>::const_iterator it2 = m_lengthIndicators.begin ();
299 
300  if ( m_dataControlBit == DATA_PDU )
301  {
302  i.WriteU8 ( ((DATA_PDU << 7) & 0x80) |
303  ((m_resegmentationFlag << 6) & 0x40) |
304  ((m_pollingBit << 5) & 0x20) |
305  ((m_framingInfo << 3) & 0x18) |
306  (((*it1) << 2) & 0x04) |
307  ((m_sequenceNumber.GetValue () >> 8) & 0x0003) );
308  i.WriteU8 ( m_sequenceNumber.GetValue () & 0x00FF );
309  i.WriteU8 ( ((m_lastSegmentFlag << 7) & 0x80) |
310  ((m_segmentOffset >> 8) & 0x007F) );
311  i.WriteU8 ( m_segmentOffset & 0x00FF );
312  it1++;
313 
314  while ( it1 != m_extensionBits.end () &&
315  it2 != m_lengthIndicators.end () )
316  {
317  uint16_t oddLi, evenLi;
318  uint8_t oddE, evenE;
319 
320  oddE = *it1;
321  oddLi = *it2;
322 
323  it1++;
324  it2++;
325 
326  if ( it1 != m_extensionBits.end () &&
327  it2 != m_lengthIndicators.end () )
328  {
329  evenE = *it1;
330  evenLi = *it2;
331 
332  i.WriteU8 ( ((oddE << 7) & 0x80) | ((oddLi >> 4) & 0x007F) );
333  i.WriteU8 ( ((oddLi << 4) & 0x00F0) | ((evenE << 3) & 0x08) | ((evenLi >> 8) & 0x0007) );
334  i.WriteU8 ( evenLi & 0x00FF );
335 
336  it1++;
337  it2++;
338  }
339  else
340  {
341  i.WriteU8 ( ((oddE << 7) & 0x80) | ((oddLi >> 4) & 0x007F) );
342  i.WriteU8 ( ((oddLi << 4) & 0x00F0) ); // Padding is implicit
343  }
344  }
345  }
346  else // if ( m_dataControlBit == CONTROL_PDU )
347  {
348  i.WriteU8 ( ((CONTROL_PDU << 7) & 0x80) |
349  ((m_controlPduType << 4) & 0x70) |
350  ((m_ackSn.GetValue () >> 6) & 0x0F) );
351  i.WriteU8 ( ((m_ackSn.GetValue () << 2) & 0xFC) );
352  }
353 }
354 
356 {
358  uint8_t byte_1;
359  uint8_t byte_2;
360  uint8_t byte_3;
361  uint8_t byte_4;
362  uint8_t extensionBit;
363 
364  byte_1 = i.ReadU8 ();
365  m_headerLength = 1;
366  m_dataControlBit = (byte_1 & 0x80) >> 7;
367 
368  if ( m_dataControlBit == DATA_PDU )
369  {
370  byte_2 = i.ReadU8 ();
371  byte_3 = i.ReadU8 ();
372  byte_4 = i.ReadU8 ();
373  m_headerLength += 3;
374 
375  m_resegmentationFlag = (byte_1 & 0x40) >> 6;
376  m_pollingBit = (byte_1 & 0x20) >> 5;
377  m_framingInfo = (byte_1 & 0x18) >> 3;
378  m_sequenceNumber = ((byte_1 & 0x03) << 8) | byte_2;
379 
380  m_lastSegmentFlag = (byte_3 & 0x80) >> 7;
381  m_segmentOffset = (byte_3 & 0x7F) | byte_4;
382 
383  extensionBit = (byte_1 & 0x04) >> 2;
384  m_extensionBits.push_back (extensionBit);
385 
386  if (extensionBit == DATA_FIELD_FOLLOWS)
387  {
388  return GetSerializedSize ();
389  }
390 
391  uint16_t oddLi, evenLi;
392  uint8_t oddE, evenE;
393  bool moreLiFields = (extensionBit == E_LI_FIELDS_FOLLOWS);
394 
395  while (moreLiFields)
396  {
397  byte_1 = i.ReadU8 ();
398  byte_2 = i.ReadU8 ();
399 
400  oddE = (byte_1 & 0x80) >> 7;
401  oddLi = ((byte_1 & 0x7F) << 4) | ((byte_2 & 0xF0) >> 4);
402  moreLiFields = (oddE == E_LI_FIELDS_FOLLOWS);
403 
404  m_extensionBits.push_back (oddE);
405  m_lengthIndicators.push_back (oddLi);
406  m_headerLength += 2;
407 
408  if (moreLiFields)
409  {
410  byte_3 = i.ReadU8 ();
411 
412  evenE = (byte_2 & 0x08) >> 3;
413  evenLi = ((byte_2 & 0x07) << 8) | (byte_3 & 0xFF);
414  moreLiFields = (evenE == E_LI_FIELDS_FOLLOWS);
415 
416  m_extensionBits.push_back (evenE);
417  m_lengthIndicators.push_back (evenLi);
418 
419  m_headerLength += 1;
420  }
421  }
422 
424  {
426  }
427  }
428  else // if ( m_dataControlBit == CONTROL_PDU )
429  {
430  byte_2 = i.ReadU8 ();
431 
432  m_controlPduType = (byte_1 & 0x70) >> 4;
433  m_ackSn = ((byte_1 & 0x0F) << 6 ) | ((byte_2 & 0xFC) >> 2);
434 
435  m_headerLength++;
436  }
437 
438  return GetSerializedSize ();
439 }
440 
441 }; // namespace ns3
uint8_t PopExtensionBit(void)
Protocol header serialization and deserialization.
Definition: header.h:42
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
void SetResegmentationFlag(uint8_t resegFlag)
std::list< uint8_t > m_extensionBits
void SetSequenceNumber(SequenceNumber10 sequenceNumber)
virtual void Print(std::ostream &os) const
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
void SetPollingBit(uint8_t pollingBit)
std::list< uint16_t > m_lengthIndicators
iterator in a Buffer instance
Definition: buffer.h:98
uint8_t GetFramingInfo() const
virtual uint32_t GetSerializedSize(void) const
uint8_t GetLastSegmentFlag() const
void SetFramingInfo(uint8_t framingInfo)
void SetSegmentOffset(uint16_t segmentOffset)
bool IsDataPdu(void) const
NS_LOG_COMPONENT_DEFINE("LteRlcAmHeader")
uint8_t GetPollingBit() const
SequenceNumber10 m_sequenceNumber
uint16_t GetLastOffset() const
void PushLengthIndicator(uint16_t lengthIndicator)
void SetControlPdu(uint8_t controlPduType)
SequenceNumber10 m_ackSn
virtual uint32_t Deserialize(Buffer::Iterator start)
uint8_t GetResegmentationFlag() const
static TypeId GetTypeId(void)
virtual void Serialize(Buffer::Iterator start) const
void WriteU8(uint8_t data)
Definition: buffer.h:690
bool IsControlPdu(void) const
uint16_t PopLengthIndicator(void)
uint16_t GetSegmentOffset() const
SequenceNumber10 m_nackSn
uint8_t ReadU8(void)
Definition: buffer.h:819
void SetAckSn(SequenceNumber10 ackSn)
void SetLastSegmentFlag(uint8_t lsf)
void PushExtensionBit(uint8_t extensionBit)
virtual TypeId GetInstanceTypeId(void) const
uint32_t GetSize(void) const
Definition: buffer.cc:1183
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
SequenceNumber10 GetAckSn() const
LteRlcAmHeader()
Constructor.
SequenceNumber10 GetSequenceNumber() const