A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lte-rlc-am-header.cc
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 
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
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 
288 {
289  return m_headerLength;
290 }
291 
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 
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
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
virtual void Print(std::ostream &os) const
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
iterator in a Buffer instance
Definition: buffer.h:98
virtual uint32_t GetSerializedSize(void) const
virtual uint32_t Deserialize(Buffer::Iterator start)
virtual void Serialize(Buffer::Iterator start) const
void WriteU8(uint8_t data)
Definition: buffer.h:690
uint8_t ReadU8(void)
Definition: buffer.h:819
virtual TypeId GetInstanceTypeId(void) const
uint32_t GetSize(void) const
Definition: buffer.cc:1183
LteRlcAmHeader()
Constructor.