A Discrete-Event Network Simulator
API
lte-rlc-header.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Manuel Requena <manuel.requena@cttc.es>
18  */
19 
20 #include "lte-rlc-header.h"
21 
22 #include "ns3/log.h"
23 
24 namespace ns3
25 {
26 
27 NS_LOG_COMPONENT_DEFINE("LteRlcHeader");
28 
29 NS_OBJECT_ENSURE_REGISTERED(LteRlcHeader);
30 
32  : m_headerLength(0),
33  m_framingInfo(0xff),
34  m_sequenceNumber(0xfffa)
35 {
36 }
37 
39 {
40  m_headerLength = 0;
41  m_framingInfo = 0xff;
42  m_sequenceNumber = 0xfffb;
43 }
44 
45 void
46 LteRlcHeader::SetFramingInfo(uint8_t framingInfo)
47 {
48  m_framingInfo = framingInfo & 0x03;
49 }
50 
51 void
53 {
54  m_sequenceNumber = sequenceNumber;
55 }
56 
57 uint8_t
59 {
60  return m_framingInfo;
61 }
62 
65 {
66  return m_sequenceNumber;
67 }
68 
69 void
70 LteRlcHeader::PushExtensionBit(uint8_t extensionBit)
71 {
72  m_extensionBits.push_back(extensionBit);
73  if (m_extensionBits.size() == 1)
74  {
75  m_headerLength = 2; // Only fixed part
76  }
77  else if (m_extensionBits.size() % 2)
78  {
79  m_headerLength += 1;
80  }
81  else
82  {
83  m_headerLength += 2;
84  }
85 }
86 
87 void
88 LteRlcHeader::PushLengthIndicator(uint16_t lengthIndicator)
89 {
90  m_lengthIndicators.push_back(lengthIndicator);
91 }
92 
93 uint8_t
95 {
96  uint8_t extensionBit = m_extensionBits.front();
97  m_extensionBits.pop_front();
98 
99  return extensionBit;
100 }
101 
102 uint16_t
104 {
105  uint16_t lengthIndicator = m_lengthIndicators.front();
106  m_lengthIndicators.pop_front();
107 
108  return lengthIndicator;
109 }
110 
111 TypeId
113 {
114  static TypeId tid = TypeId("ns3::LteRlcHeader")
115  .SetParent<Header>()
116  .SetGroupName("Lte")
117  .AddConstructor<LteRlcHeader>();
118  return tid;
119 }
120 
121 TypeId
123 {
124  return GetTypeId();
125 }
126 
127 void
128 LteRlcHeader::Print(std::ostream& os) const
129 {
130  auto it1 = m_extensionBits.begin();
131  auto it2 = m_lengthIndicators.begin();
132 
133  os << "Len=" << m_headerLength;
134  os << " FI=" << (uint16_t)m_framingInfo;
135  os << " E=" << (uint16_t)(*it1);
136  os << " SN=" << m_sequenceNumber;
137 
138  it1++;
139  if (it1 != m_extensionBits.end())
140  {
141  os << " E=";
142  }
143  while (it1 != m_extensionBits.end())
144  {
145  os << (uint16_t)(*it1);
146  it1++;
147  }
148 
149  if (it2 != m_lengthIndicators.end())
150  {
151  os << " LI=";
152  }
153  while (it2 != m_lengthIndicators.end())
154  {
155  os << (uint16_t)(*it2) << " ";
156  it2++;
157  }
158 }
159 
160 uint32_t
162 {
163  return m_headerLength;
164 }
165 
166 void
168 {
170 
171  auto it1 = m_extensionBits.begin();
172  auto it2 = m_lengthIndicators.begin();
173 
174  i.WriteU8(((m_framingInfo << 3) & 0x18) | (((*it1) << 2) & 0x04) |
175  ((m_sequenceNumber.GetValue() >> 8) & 0x0003));
176  i.WriteU8(m_sequenceNumber.GetValue() & 0x00FF);
177  it1++;
178 
179  while (it1 != m_extensionBits.end() && it2 != m_lengthIndicators.end())
180  {
181  uint16_t oddLi;
182  uint16_t evenLi;
183  uint8_t oddE;
184  uint8_t evenE;
185 
186  oddE = *it1;
187  oddLi = *it2;
188 
189  it1++;
190  it2++;
191 
192  if (it1 != m_extensionBits.end() && it2 != m_lengthIndicators.end())
193  {
194  evenE = *it1;
195  evenLi = *it2;
196 
197  i.WriteU8(((oddE << 7) & 0x80) | ((oddLi >> 4) & 0x007F));
198  i.WriteU8(((oddLi << 4) & 0x00F0) | ((evenE << 3) & 0x08) | ((evenLi >> 8) & 0x0007));
199  i.WriteU8(evenLi & 0x00FF);
200 
201  it1++;
202  it2++;
203  }
204  else
205  {
206  i.WriteU8(((oddE << 7) & 0x80) | ((oddLi >> 4) & 0x007F));
207  i.WriteU8((oddLi << 4) & 0x00F0); // Padding is implicit
208  }
209  }
210 }
211 
212 uint32_t
214 {
216  uint8_t byte_1;
217  uint8_t byte_2;
218  uint8_t byte_3;
219  uint8_t extensionBit;
220 
221  byte_1 = i.ReadU8();
222  byte_2 = i.ReadU8();
223  m_headerLength = 2;
224  m_framingInfo = (byte_1 & 0x18) >> 3;
225  m_sequenceNumber = ((byte_1 & 0x03) << 8) | byte_2;
226 
227  extensionBit = (byte_1 & 0x04) >> 2;
228  m_extensionBits.push_back(extensionBit);
229 
230  if (extensionBit == DATA_FIELD_FOLLOWS)
231  {
232  return GetSerializedSize();
233  }
234 
235  uint16_t oddLi;
236  uint16_t evenLi;
237  uint8_t oddE;
238  uint8_t evenE;
239  bool moreLiFields = (extensionBit == E_LI_FIELDS_FOLLOWS);
240 
241  while (moreLiFields)
242  {
243  byte_1 = i.ReadU8();
244  byte_2 = i.ReadU8();
245 
246  oddE = (byte_1 & 0x80) >> 7;
247  oddLi = ((byte_1 & 0x7F) << 4) | ((byte_2 & 0xF0) >> 4);
248  moreLiFields = (oddE == E_LI_FIELDS_FOLLOWS);
249 
250  m_extensionBits.push_back(oddE);
251  m_lengthIndicators.push_back(oddLi);
252  m_headerLength += 2;
253 
254  if (moreLiFields)
255  {
256  byte_3 = i.ReadU8();
257 
258  evenE = (byte_2 & 0x08) >> 3;
259  evenLi = ((byte_2 & 0x07) << 8) | (byte_3 & 0xFF);
260  moreLiFields = (evenE == E_LI_FIELDS_FOLLOWS);
261 
262  m_extensionBits.push_back(evenE);
263  m_lengthIndicators.push_back(evenLi);
264 
265  m_headerLength += 1;
266  }
267  }
268 
269  return GetSerializedSize();
270 }
271 
272 }; // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
void WriteU8(uint8_t data)
Definition: buffer.h:881
Protocol header serialization and deserialization.
Definition: header.h:44
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
The packet header for the Radio Link Control (RLC) protocol packets.
void Serialize(Buffer::Iterator start) const override
uint8_t m_framingInfo
2 bits
std::list< uint8_t > m_extensionBits
Includes extensionBit of the fixed part.
uint32_t GetSerializedSize() const override
void PushExtensionBit(uint8_t extensionBit)
Push extension bit.
SequenceNumber10 m_sequenceNumber
sequence number
void Print(std::ostream &os) const override
SequenceNumber10 GetSequenceNumber() const
Get sequence number.
uint16_t m_headerLength
header length
void SetSequenceNumber(SequenceNumber10 sequenceNumber)
Set sequence number.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void SetFramingInfo(uint8_t framingInfo)
Set framing info.
std::list< uint16_t > m_lengthIndicators
length indicators
uint8_t PopExtensionBit()
Pop extension bit.
~LteRlcHeader() override
LteRlcHeader()
Constructor.
uint16_t PopLengthIndicator()
Pop length indicator.
static TypeId GetTypeId()
Get the type ID.
uint8_t GetFramingInfo() const
Get framing info.
void PushLengthIndicator(uint16_t lengthIndicator)
Push length indicator.
SequenceNumber10 class.
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.