A Discrete-Event Network Simulator
API
lte-rlc-am.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  * Nicola Baldo <nbaldo@cttc.es>
20  */
21 
22 #include "ns3/simulator.h"
23 #include "ns3/log.h"
24 
25 #include "ns3/lte-rlc-am-header.h"
26 #include "ns3/lte-rlc-am.h"
27 #include "ns3/lte-rlc-sdu-status-tag.h"
28 #include "ns3/lte-rlc-tag.h"
29 
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("LteRlcAm");
34 
36 
37 
39 {
40  NS_LOG_FUNCTION (this);
41 
42  // Buffers
43  m_txonBufferSize = 0;
44  m_retxBuffer.resize (1024);
45  m_retxBufferSize = 0;
46  m_txedBuffer.resize (1024);
47  m_txedBufferSize = 0;
48 
49  m_statusPduRequested = false;
51 
52  // State variables: transmitting side
53  m_windowSize = 512;
54  m_vtA = 0;
56  m_vtS = 0;
57  m_pollSn = 0;
58 
59  // State variables: receiving side
60  m_vrR = 0;
62  m_vrX = 0;
63  m_vrMs = 0;
64  m_vrH = 0;
65 
66  // Counters
67  m_pduWithoutPoll = 0;
69 
70  // Configurable parameters
72  m_pollPdu = 1;
73  m_pollByte = 50;
74 
75  // SDU reassembling process
78 
80 }
81 
83 {
84  NS_LOG_FUNCTION (this);
85 }
86 
87 TypeId
89 {
90  static TypeId tid = TypeId ("ns3::LteRlcAm")
91  .SetParent<LteRlc> ()
92  .SetGroupName("Lte")
93  .AddConstructor<LteRlcAm> ()
94  .AddAttribute ("PollRetransmitTimer",
95  "Value of the t-PollRetransmit timer (See section 7.3 of 3GPP TS 36.322)",
96  TimeValue (MilliSeconds (20)),
98  MakeTimeChecker ())
99  .AddAttribute ("ReorderingTimer",
100  "Value of the t-Reordering timer (See section 7.3 of 3GPP TS 36.322)",
101  TimeValue (MilliSeconds (10)),
103  MakeTimeChecker ())
104  .AddAttribute ("StatusProhibitTimer",
105  "Value of the t-StatusProhibit timer (See section 7.3 of 3GPP TS 36.322)",
106  TimeValue (MilliSeconds (10)),
108  MakeTimeChecker ())
109  .AddAttribute ("ReportBufferStatusTimer",
110  "How much to wait to issue a new Report Buffer Status since the last time "
111  "a new SDU was received",
112  TimeValue (MilliSeconds (20)),
114  MakeTimeChecker ())
115  .AddAttribute ("TxOpportunityForRetxAlwaysBigEnough",
116  "If true, always pretend that the size of a TxOpportunity is big enough "
117  "for retransmission. If false (default and realistic behavior), no retx "
118  "is performed unless the corresponding TxOpportunity is big enough.",
119  BooleanValue (false),
122  .AddAttribute ("MaxTxBufferSize",
123  "Maximum Size of the Transmission Buffer (in Bytes). If zero is configured, the buffer is unlimited.",
124  UintegerValue (10 * 1024),
126  MakeUintegerChecker<uint32_t> ())
127  ;
128  return tid;
129 }
130 
131 void
133 {
134  NS_LOG_FUNCTION (this);
138  m_rbsTimer.Cancel ();
139 
140  m_maxTxBufferSize = 0;
141  m_txonBuffer.clear ();
142  m_txonBufferSize = 0;
143  m_txedBuffer.clear ();
144  m_txedBufferSize = 0;
145  m_retxBuffer.clear ();
146  m_retxBufferSize = 0;
147  m_rxonBuffer.clear ();
148  m_sdusBuffer.clear ();
149  m_keepS0 = 0;
150  m_controlPduBuffer = 0;
151 
153 }
154 
155 
160 void
162 {
163  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
164 
166  {
168  LteRlcSduStatusTag tag;
170  p->AddPacketTag (tag);
171 
172  NS_LOG_LOGIC ("Txon Buffer: New packet added");
173  m_txonBuffer.push_back (TxPdu (p, Simulator::Now ()));
174  m_txonBufferSize += p->GetSize ();
175  NS_LOG_LOGIC ("NumOfBuffers = " << m_txonBuffer.size() );
176  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
177  }
178  else
179  {
180  // Discard full RLC SDU
181  NS_LOG_LOGIC ("TxonBuffer is full. RLC SDU discarded");
182  NS_LOG_LOGIC ("MaxTxBufferSize = " << m_maxTxBufferSize);
183  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
184  NS_LOG_LOGIC ("packet size = " << p->GetSize ());
185  m_txDropTrace (p);
186  }
187 
190  m_rbsTimer.Cancel ();
192 }
193 
194 
199 void
201 {
202  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << txOpParams.bytes);
203 
204  if (txOpParams.bytes < 4)
205  {
206  // Stingy MAC: In general, we need more bytes.
207  // There are a more restrictive test for each particular case
208  NS_LOG_LOGIC ("TxOpportunity (size = " << txOpParams.bytes << ") too small");
209  NS_ASSERT_MSG (false, "TxOpportunity (size = " << txOpParams.bytes << ") too small.\n"
210  << "Your MAC scheduler is assigned too few resource blocks.");
211  return;
212  }
213 
215  {
216  if (txOpParams.bytes < m_statusPduBufferSize)
217  {
218  // Stingy MAC: We need more bytes for the STATUS PDU
219  NS_LOG_LOGIC ("TxOpportunity (size = " << txOpParams.bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")");
220  NS_ASSERT_MSG (false, "TxOpportunity (size = " << txOpParams.bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")\n"
221  << "Your MAC scheduler is assigned too few resource blocks.");
222  return;
223  }
224 
225  NS_LOG_LOGIC ("Sending STATUS PDU");
226 
227  Ptr<Packet> packet = Create<Packet> ();
228  LteRlcAmHeader rlcAmHeader;
230 
231  NS_LOG_LOGIC ("Check for SNs to NACK from " << m_vrR.GetValue() << " to " << m_vrMs.GetValue());
232  SequenceNumber10 sn;
233  sn.SetModulusBase (m_vrR);
234  std::map<uint16_t, PduBuffer>::iterator pduIt;
235  for (sn = m_vrR; sn < m_vrMs; sn++)
236  {
237  NS_LOG_LOGIC ("SN = " << sn);
238  if (!rlcAmHeader.OneMoreNackWouldFitIn (txOpParams.bytes))
239  {
240  NS_LOG_LOGIC ("Can't fit more NACKs in STATUS PDU");
241  break;
242  }
243  pduIt = m_rxonBuffer.find (sn.GetValue ());
244  if (pduIt == m_rxonBuffer.end () || (!(pduIt->second.m_pduComplete)))
245  {
246  NS_LOG_LOGIC ("adding NACK_SN " << sn.GetValue ());
247  rlcAmHeader.PushNack (sn.GetValue ());
248  }
249  }
250  NS_LOG_LOGIC ("SN at end of NACK loop = " << sn);
251  // 3GPP TS 36.322 section 6.2.2.1.4 ACK SN
252  // find the SN of the next not received RLC Data PDU
253  // which is not reported as missing in the STATUS PDU.
254  pduIt = m_rxonBuffer.find (sn.GetValue ());
255  while ((sn < m_vrMs) && (pduIt != m_rxonBuffer.end ()) && (pduIt->second.m_pduComplete))
256  {
257  NS_LOG_LOGIC ("SN = " << sn << " < " << m_vrMs << " = " << (sn < m_vrMs));
258  sn++;
259  NS_LOG_LOGIC ("SN = " << sn);
260  pduIt = m_rxonBuffer.find (sn.GetValue ());
261  }
262 
263  NS_ASSERT_MSG (sn <= m_vrMs, "first SN not reported as missing = " << sn << ", VR(MS) = " << m_vrMs);
264  rlcAmHeader.SetAckSn (sn);
265 
266 
267  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
268  packet->AddHeader (rlcAmHeader);
269 
270  // Sender timestamp
271  RlcTag rlcTag (Simulator::Now ());
272  packet->AddByteTag (rlcTag, 1, rlcAmHeader.GetSerializedSize ());
273  m_txPdu (m_rnti, m_lcid, packet->GetSize ());
274 
275  // Send RLC PDU to MAC layer
277  params.pdu = packet;
278  params.rnti = m_rnti;
279  params.lcid = m_lcid;
280  params.layer = txOpParams.layer;
281  params.harqProcessId = txOpParams.harqId;
282  params.componentCarrierId = txOpParams.componentCarrierId;
283 
284  m_macSapProvider->TransmitPdu (params);
285 
286  m_statusPduRequested = false;
290  return;
291  }
292  else if ( m_retxBufferSize > 0 )
293  {
294  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
295  NS_LOG_LOGIC ("Sending data from Retransmission Buffer");
296  NS_ASSERT (m_vtA < m_vtS);
297  SequenceNumber10 sn;
298  sn.SetModulusBase (m_vtA);
299  for (sn = m_vtA; sn < m_vtS; sn++)
300  {
301  uint16_t seqNumberValue = sn.GetValue ();
302  NS_LOG_LOGIC ("SN = " << seqNumberValue << " m_pdu " << m_retxBuffer.at (seqNumberValue).m_pdu);
303 
304  if (m_retxBuffer.at (seqNumberValue).m_pdu != 0)
305  {
306  Ptr<Packet> packet = m_retxBuffer.at (seqNumberValue).m_pdu->Copy ();
307 
308  if (( packet->GetSize () <= txOpParams.bytes )
310  {
311  // According to 5.2.1, the data field is left as is, but we rebuild the header
312  LteRlcAmHeader rlcAmHeader;
313  packet->RemoveHeader (rlcAmHeader);
314  NS_LOG_LOGIC ("old AM RLC header: " << rlcAmHeader);
315 
316  // Calculate the Polling Bit (5.2.2.1)
318 
319  NS_LOG_LOGIC ("polling conditions: m_txonBuffer.empty=" << m_txonBuffer.empty ()
320  << " retxBufferSize=" << m_retxBufferSize
321  << " packet->GetSize ()=" << packet->GetSize ());
322  if (((m_txonBuffer.empty ()) && (m_retxBufferSize == packet->GetSize () + rlcAmHeader.GetSerializedSize ()))
323  || (m_vtS >= m_vtMs)
325  {
328  m_pduWithoutPoll = 0;
329  m_byteWithoutPoll = 0;
330 
331  m_pollSn = m_vtS - 1;
332  NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn);
333 
335  {
336  NS_LOG_LOGIC ("Start PollRetransmit timer");
337 
340  }
341  else
342  {
343  NS_LOG_LOGIC ("Restart PollRetransmit timer");
344 
348  }
349  }
350 
351  packet->AddHeader (rlcAmHeader);
352 
353  RlcTag rlcTag;
355 
356  packet->AddByteTag (rlcTag, 1, rlcAmHeader.GetSerializedSize ());
357 
358  NS_LOG_LOGIC ("new AM RLC header: " << rlcAmHeader);
359 
360  m_txPdu (m_rnti, m_lcid, packet->GetSize ());
361 
362  // Send RLC PDU to MAC layer
364  params.pdu = packet;
365  params.rnti = m_rnti;
366  params.lcid = m_lcid;
367  params.layer = txOpParams.layer;
368  params.harqProcessId = txOpParams.harqId;
369  params.componentCarrierId = txOpParams.componentCarrierId;
370 
371  m_macSapProvider->TransmitPdu (params);
372 
373  m_retxBuffer.at (seqNumberValue).m_retxCount++;
374  m_retxBuffer.at (seqNumberValue).m_waitingSince = Simulator::Now ();
375  NS_LOG_INFO ("Incr RETX_COUNT for SN = " << seqNumberValue);
376  if (m_retxBuffer.at (seqNumberValue).m_retxCount >= m_maxRetxThreshold)
377  {
378  NS_LOG_INFO ("Max RETX_COUNT for SN = " << seqNumberValue);
379  }
380 
381  NS_LOG_INFO ("Move SN = " << seqNumberValue << " back to txedBuffer");
382  m_txedBuffer.at (seqNumberValue).m_pdu = m_retxBuffer.at (seqNumberValue).m_pdu->Copy ();
383  m_txedBuffer.at (seqNumberValue).m_retxCount = m_retxBuffer.at (seqNumberValue).m_retxCount;
384  m_txedBuffer.at (seqNumberValue).m_waitingSince = m_retxBuffer.at (seqNumberValue).m_waitingSince;
385  m_txedBufferSize += m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
386 
387  m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
388  m_retxBuffer.at (seqNumberValue).m_pdu = 0;
389  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
390  m_retxBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0);
391 
392  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
393 
394  return;
395  }
396  else
397  {
398  NS_LOG_LOGIC ("TxOpportunity (size = " << txOpParams.bytes << ") too small for retransmission of the packet (size = " << packet->GetSize () << ")");
399  NS_LOG_LOGIC ("Waiting for bigger TxOpportunity");
400  return;
401  }
402  }
403  }
404  NS_ASSERT_MSG (false, "m_retxBufferSize > 0, but no PDU considered for retx found");
405  }
406  else if ( m_txonBufferSize > 0 )
407  {
408  if (txOpParams.bytes < 7)
409  {
410  // Stingy MAC: We need more bytes for new DATA PDUs.
411  NS_LOG_LOGIC ("TxOpportunity (size = " << txOpParams.bytes << ") too small for DATA PDU");
412  NS_ASSERT_MSG (false, "TxOpportunity (size = " << txOpParams.bytes << ") too small for DATA PDU\n"
413  << "Your MAC scheduler is assigned too few resource blocks.");
414  return;
415  }
416 
417  NS_ASSERT (m_vtS <= m_vtMs);
418  if (m_vtS == m_vtMs)
419  {
420  NS_LOG_INFO ("cannot transmit new RLC PDU due to window stalling");
421  return;
422  }
423 
424  NS_LOG_LOGIC ("Sending data from Transmission Buffer");
425  }
426  else
427  {
428  NS_LOG_LOGIC ("No data pending");
429  return;
430  }
431 
432  //
433  //
434  // Build new PDU
435  //
436  //
437 
438  Ptr<Packet> packet = Create<Packet> ();
439  LteRlcAmHeader rlcAmHeader;
440  rlcAmHeader.SetDataPdu ();
441 
442  // Build Data field
443  uint32_t nextSegmentSize = txOpParams.bytes - 4;
444  uint32_t nextSegmentId = 1;
445  uint32_t dataFieldTotalSize = 0;
446  uint32_t dataFieldAddedSize = 0;
447  std::vector < Ptr<Packet> > dataField;
448 
449  // Remove the first packet from the transmission buffer.
450  // If only a segment of the packet is taken, then the remaining is given back later
451  if ( m_txonBuffer.size () == 0 )
452  {
453  NS_LOG_LOGIC ("No data pending");
454  return;
455  }
456 
457  NS_LOG_LOGIC ("SDUs in TxonBuffer = " << m_txonBuffer.size ());
458  NS_LOG_LOGIC ("First SDU buffer = " << m_txonBuffer.begin ()->m_pdu);
459  NS_LOG_LOGIC ("First SDU size = " << m_txonBuffer.begin ()->m_pdu->GetSize ());
460  NS_LOG_LOGIC ("Next segment size = " << nextSegmentSize);
461  NS_LOG_LOGIC ("Remove SDU from TxBuffer");
462  Time firstSegmentTime = m_txonBuffer.begin ()->m_waitingSince;
463  Ptr<Packet> firstSegment = m_txonBuffer.begin ()->m_pdu->Copy ();
464  m_txonBufferSize -= m_txonBuffer.begin ()->m_pdu->GetSize ();
465  NS_LOG_LOGIC ("txBufferSize = " << m_txonBufferSize );
466  m_txonBuffer.erase (m_txonBuffer.begin ());
467 
468  while ( firstSegment && (firstSegment->GetSize () > 0) && (nextSegmentSize > 0) )
469  {
470  NS_LOG_LOGIC ("WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
471  NS_LOG_LOGIC (" firstSegment size = " << firstSegment->GetSize ());
472  NS_LOG_LOGIC (" nextSegmentSize = " << nextSegmentSize);
473  if ( (firstSegment->GetSize () > nextSegmentSize) ||
474  // Segment larger than 2047 octets can only be mapped to the end of the Data field
475  (firstSegment->GetSize () > 2047)
476  )
477  {
478  // Take the minimum size, due to the 2047-bytes 3GPP exception
479  // This exception is due to the length of the LI field (just 11 bits)
480  uint32_t currSegmentSize = std::min (firstSegment->GetSize (), nextSegmentSize);
481 
482  NS_LOG_LOGIC (" IF ( firstSegment > nextSegmentSize ||");
483  NS_LOG_LOGIC (" firstSegment > 2047 )");
484 
485  // Segment txBuffer.FirstBuffer and
486  // Give back the remaining segment to the transmission buffer
487  Ptr<Packet> newSegment = firstSegment->CreateFragment (0, currSegmentSize);
488  NS_LOG_LOGIC (" newSegment size = " << newSegment->GetSize ());
489 
490  // Status tag of the new and remaining segments
491  // Note: This is the only place where a PDU is segmented and
492  // therefore its status can change
493  LteRlcSduStatusTag oldTag, newTag;
494  firstSegment->RemovePacketTag (oldTag);
495  newSegment->RemovePacketTag (newTag);
496  if (oldTag.GetStatus () == LteRlcSduStatusTag::FULL_SDU)
497  {
498  newTag.SetStatus (LteRlcSduStatusTag::FIRST_SEGMENT);
499  oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
500  }
501  else if (oldTag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT)
502  {
503  newTag.SetStatus (LteRlcSduStatusTag::MIDDLE_SEGMENT);
504  //oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
505  }
506 
507  // Give back the remaining segment to the transmission buffer
508  firstSegment->RemoveAtStart (currSegmentSize);
509  NS_LOG_LOGIC (" firstSegment size (after RemoveAtStart) = " << firstSegment->GetSize ());
510  if (firstSegment->GetSize () > 0)
511  {
512  firstSegment->AddPacketTag (oldTag);
513 
514  m_txonBuffer.insert (m_txonBuffer.begin (), TxPdu (firstSegment, firstSegmentTime));
515  m_txonBufferSize += m_txonBuffer.begin ()->m_pdu->GetSize ();
516 
517  NS_LOG_LOGIC (" Txon buffer: Give back the remaining segment");
518  NS_LOG_LOGIC (" Txon buffers = " << m_txonBuffer.size ());
519  NS_LOG_LOGIC (" Front buffer size = " << m_txonBuffer.begin ()->m_pdu->GetSize ());
520  NS_LOG_LOGIC (" txonBufferSize = " << m_txonBufferSize );
521  }
522  else
523  {
524  // Whole segment was taken, so adjust tag
525  if (newTag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
526  {
527  newTag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
528  }
529  else if (newTag.GetStatus () == LteRlcSduStatusTag::MIDDLE_SEGMENT)
530  {
531  newTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
532  }
533  }
534  // Segment is completely taken or
535  // the remaining segment is given back to the transmission buffer
536  firstSegment = 0;
537 
538  // Put status tag once it has been adjusted
539  newSegment->AddPacketTag (newTag);
540 
541  // Add Segment to Data field
542  dataFieldAddedSize = newSegment->GetSize ();
543  dataFieldTotalSize += dataFieldAddedSize;
544  dataField.push_back (newSegment);
545  newSegment = 0;
546 
547  // ExtensionBit (Next_Segment - 1) = 0
548  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
549 
550  // no LengthIndicator for the last one
551 
552  nextSegmentSize -= dataFieldAddedSize;
553  nextSegmentId++;
554 
555  // nextSegmentSize MUST be zero (only if segment is smaller or equal to 2047)
556 
557  // (NO more segments) ? exit
558  // break;
559  }
560  else if ( (nextSegmentSize - firstSegment->GetSize () <= 2) || (m_txonBuffer.size () == 0) )
561  {
562  NS_LOG_LOGIC (" IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
563 
564  // Add txBuffer.FirstBuffer to DataField
565  dataFieldAddedSize = firstSegment->GetSize ();
566  dataFieldTotalSize += dataFieldAddedSize;
567  dataField.push_back (firstSegment);
568  firstSegment = 0;
569 
570  // ExtensionBit (Next_Segment - 1) = 0
571  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
572 
573  // no LengthIndicator for the last one
574 
575  nextSegmentSize -= dataFieldAddedSize;
576  nextSegmentId++;
577 
578  NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
579  if (m_txonBuffer.size () > 0)
580  {
581  NS_LOG_LOGIC (" First SDU buffer = " << m_txonBuffer.begin ()->m_pdu);
582  NS_LOG_LOGIC (" First SDU size = " << m_txonBuffer.begin ()->m_pdu->GetSize ());
583  }
584  NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
585 
586  // nextSegmentSize <= 2 (only if txBuffer is not empty)
587 
588  // (NO more segments) ? exit
589  // break;
590  }
591  else // (firstSegment->GetSize () < m_nextSegmentSize) && (m_txBuffer.size () > 0)
592  {
593  NS_LOG_LOGIC (" IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
594  // Add txBuffer.FirstBuffer to DataField
595  dataFieldAddedSize = firstSegment->GetSize ();
596  dataFieldTotalSize += dataFieldAddedSize;
597  dataField.push_back (firstSegment);
598 
599  // ExtensionBit (Next_Segment - 1) = 1
600  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::E_LI_FIELDS_FOLLOWS);
601 
602  // LengthIndicator (Next_Segment) = txBuffer.FirstBuffer.length()
603  rlcAmHeader.PushLengthIndicator (firstSegment->GetSize ());
604 
605  nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
606  nextSegmentId++;
607 
608  NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
609  if (m_txonBuffer.size () > 0)
610  {
611  NS_LOG_LOGIC (" First SDU buffer = " << m_txonBuffer.begin ()->m_pdu);
612  NS_LOG_LOGIC (" First SDU size = " << m_txonBuffer.begin ()->m_pdu->GetSize ());
613  }
614  NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
615  NS_LOG_LOGIC (" Remove SDU from TxBuffer");
616 
617  // (more segments)
618  firstSegment = m_txonBuffer.begin ()->m_pdu->Copy ();
619  firstSegmentTime = m_txonBuffer.begin ()->m_waitingSince;
620  m_txonBufferSize -= m_txonBuffer.begin ()->m_pdu->GetSize ();
621  m_txonBuffer.erase (m_txonBuffer.begin ());
622  NS_LOG_LOGIC (" txBufferSize = " << m_txonBufferSize );
623  }
624 
625  }
626 
627  //
628  // Build RLC header
629  //
630 
631  rlcAmHeader.SetSequenceNumber ( m_vtS++ );
632  rlcAmHeader.SetResegmentationFlag (LteRlcAmHeader::PDU);
633  rlcAmHeader.SetLastSegmentFlag (LteRlcAmHeader::LAST_PDU_SEGMENT);
634  rlcAmHeader.SetSegmentOffset (0);
635 
636  NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () < m_vtMs, "SN above TX window");
637  NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () >= m_vtA, "SN below TX window");
638 
639  // Calculate FramingInfo flag according the status of the SDUs in the DataField
640  uint8_t framingInfo = 0;
641  std::vector< Ptr<Packet> >::iterator it;
642  it = dataField.begin ();
643 
644  // FIRST SEGMENT
645  LteRlcSduStatusTag tag;
646  NS_ASSERT_MSG ((*it)->PeekPacketTag (tag), "LteRlcSduStatusTag is missing");
647  (*it)->PeekPacketTag (tag);
648  if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
650  )
651  {
652  framingInfo |= LteRlcAmHeader::FIRST_BYTE;
653  }
654  else
655  {
656  framingInfo |= LteRlcAmHeader::NO_FIRST_BYTE;
657  }
658 
659  // Add all SDUs (in DataField) to the Packet
660  while (it < dataField.end ())
661  {
662  NS_LOG_LOGIC ("Adding SDU/segment to packet, length = " << (*it)->GetSize ());
663 
664  NS_ASSERT_MSG ((*it)->PeekPacketTag (tag), "LteRlcSduStatusTag is missing");
665  (*it)->RemovePacketTag (tag);
666  if (packet->GetSize () > 0)
667  {
668  packet->AddAtEnd (*it);
669  }
670  else
671  {
672  packet = (*it);
673  }
674  it++;
675  }
676 
677  // LAST SEGMENT (Note: There could be only one and be the first one)
678  it--;
679  if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
681  {
682  framingInfo |= LteRlcAmHeader::LAST_BYTE;
683  }
684  else
685  {
686  framingInfo |= LteRlcAmHeader::NO_LAST_BYTE;
687  }
688 
689  // Set the FramingInfo flag after the calculation
690  rlcAmHeader.SetFramingInfo (framingInfo);
691 
692 
693  // Calculate the Polling Bit (5.2.2.1)
694  rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
695 
697  NS_LOG_LOGIC ("PDU_WITHOUT_POLL = " << m_pduWithoutPoll);
698  m_byteWithoutPoll += packet->GetSize ();
699  NS_LOG_LOGIC ("BYTE_WITHOUT_POLL = " << m_byteWithoutPoll);
700 
702  ( (m_txonBuffer.empty ()) && (m_retxBufferSize == 0) ) ||
703  (m_vtS >= m_vtMs)
705  )
706  {
708  rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
709  m_pduWithoutPoll = 0;
710  m_byteWithoutPoll = 0;
711 
712  m_pollSn = m_vtS - 1;
713  NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn);
714 
716  {
717  NS_LOG_LOGIC ("Start PollRetransmit timer");
718 
721  }
722  else
723  {
724  NS_LOG_LOGIC ("Restart PollRetransmit timer");
725 
729  }
730  }
731 
732 
733  // Build RLC PDU with DataField and Header
734  NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader);
735 
736  RlcTag rlcTag;
738 
739  packet->AddHeader (rlcAmHeader);
740  packet->AddByteTag (rlcTag, 1, rlcAmHeader.GetSerializedSize ());
741 
742  // Store new PDU into the Transmitted PDU Buffer
743  NS_LOG_LOGIC ("Put transmitted PDU in the txedBuffer");
744  m_txedBufferSize += packet->GetSize ();
745  m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_pdu = packet->Copy ();
746  m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_retxCount = 0;
747  m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_waitingSince = Simulator::Now ();
748 
749  m_txPdu (m_rnti, m_lcid, packet->GetSize ());
750 
751  // Send RLC PDU to MAC layer
753  params.pdu = packet;
754  params.rnti = m_rnti;
755  params.lcid = m_lcid;
756  params.layer = txOpParams.layer;
757  params.harqProcessId = txOpParams.harqId;
758  params.componentCarrierId = txOpParams.componentCarrierId;
759 
760  m_macSapProvider->TransmitPdu (params);
761 }
762 
763 void
765 {
766  NS_LOG_FUNCTION (this);
767 }
768 
769 
770 void
772 {
773  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << rxPduParams.p->GetSize ());
774 
775  // Get RLC header parameters
776  LteRlcAmHeader rlcAmHeader;
777  rxPduParams.p->PeekHeader (rlcAmHeader);
778  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
779 
780  // Receiver timestamp
781  Time delay;
782  RlcTag rlcTag;
783 
784  bool ret = rxPduParams.p->FindFirstMatchingByteTag (rlcTag);
785  NS_ASSERT_MSG(ret, "RlcTag not found in RLC Header. The packet went into a real network?");
786 
787  delay = Simulator::Now () - rlcTag.GetSenderTimestamp ();
788 
789  m_rxPdu (m_rnti, m_lcid, rxPduParams.p->GetSize (), delay.GetNanoSeconds ());
790 
791  if ( rlcAmHeader.IsDataPdu () )
792  {
793 
794  // 5.1.3.1 Transmit operations
795 
796  // 5.1.3.1.1 General
797  //
798  // The transmitting side of an AM RLC entity shall prioritize transmission of RLC control PDUs
799  // over RLC data PDUs. The transmitting side of an AM RLC entity shall prioritize retransmission
800  // of RLC data PDUs over transmission of new AMD PDUs.
801  //
802  // The transmitting side of an AM RLC entity shall maintain a transmitting window according to
803  // state variables VT(A) and VT(MS) as follows:
804  // - a SN falls within the transmitting window if VT(A) <= SN < VT(MS);
805  // - a SN falls outside of the transmitting window otherwise.
806  //
807  // The transmitting side of an AM RLC entity shall not deliver to lower layer any RLC data PDU
808  // whose SN falls outside of the transmitting window.
809  //
810  // When delivering a new AMD PDU to lower layer, the transmitting side of an AM RLC entity shall:
811  // - set the SN of the AMD PDU to VT(S), and then increment VT(S) by one.
812  //
813  // The transmitting side of an AM RLC entity can receive a positive acknowledgement (confirmation
814  // of successful reception by its peer AM RLC entity) for a RLC data PDU by the following:
815  // - STATUS PDU from its peer AM RLC entity.
816  //
817  // When receiving a positive acknowledgement for an AMD PDU with SN = VT(A), the transmitting
818  // side of an AM RLC entity shall:
819  // - set VT(A) equal to the SN of the AMD PDU with the smallest SN, whose SN falls within the
820  // range VT(A) <= SN <= VT(S) and for which a positive acknowledgment has not been received yet.
821  // - if positive acknowledgements have been received for all AMD PDUs associated with
822  // a transmitted RLC SDU:
823  // - send an indication to the upper layers of successful delivery of the RLC SDU.
824 
825 
826  // 5.1.3.2 Receive operations
827  //
828  // 5.1.3.2.1 General
829  //
830  // The receiving side of an AM RLC entity shall maintain a receiving window according to state
831  // variables VR(R) and VR(MR) as follows:
832  // - a SN falls within the receiving window if VR(R) <= SN < VR(MR);
833  // - a SN falls outside of the receiving window otherwise.
834  //
835  // When receiving a RLC data PDU from lower layer, the receiving side of an AM RLC entity shall:
836  // - either discard the received RLC data PDU or place it in the reception buffer (see sub clause 5.1.3.2.2);
837  // - if the received RLC data PDU was placed in the reception buffer:
838  // - update state variables, reassemble and deliver RLC SDUs to upper layer and start/stop t-Reordering as needed (see sub clause 5.1.3.2.3).
839  //
840  // When t-Reordering expires, the receiving side of an AM RLC entity shall:
841  // - update state variables and start t-Reordering as needed (see sub clause 5.1.3.2.4).
842 
843 
844  SequenceNumber10 seqNumber = rlcAmHeader.GetSequenceNumber ();
845  seqNumber.SetModulusBase (m_vrR);
846 
847  if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::SEGMENT )
848  {
849  NS_LOG_LOGIC ("PDU segment received ( SN = " << seqNumber << " )");
850  }
851  else if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::PDU )
852  {
853  NS_LOG_LOGIC ("PDU received ( SN = " << seqNumber << " )");
854  }
855  else
856  {
857  NS_ASSERT_MSG (false, "Neither a PDU segment nor a PDU received");
858  return ;
859  }
860 
861  // STATUS PDU is requested
862  if ( rlcAmHeader.GetPollingBit () == LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED )
863  {
864  m_statusPduRequested = true;
866 
868  {
870  }
871  }
872 
873  // 5.1.3.2.2 Actions when a RLC data PDU is received from lower layer
874  //
875  // When a RLC data PDU is received from lower layer, where the RLC data PDU contains
876  // byte segment numbers y to z of an AMD PDU with SN = x, the receiving side of an AM RLC entity shall:
877  // - if x falls outside of the receiving window; or
878  // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
879  // - discard the received RLC data PDU;
880  // - else:
881  // - place the received RLC data PDU in the reception buffer;
882  // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
883  // - discard the duplicate byte segments.
884 
885  NS_LOG_LOGIC ("VR(R) = " << m_vrR);
886  NS_LOG_LOGIC ("VR(MR) = " << m_vrMr);
887  NS_LOG_LOGIC ("VR(X) = " << m_vrX);
888  NS_LOG_LOGIC ("VR(MS) = " << m_vrMs);
889  NS_LOG_LOGIC ("VR(H) = " << m_vrH);
890 
891  // - if x falls outside of the receiving window; or
892  // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
893  if ( ! IsInsideReceivingWindow (seqNumber) )
894  {
895  NS_LOG_LOGIC ("PDU discarded");
896  return;
897  }
898  else
899  {
900  // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
901  // - discard the duplicate byte segments.
902  // note: re-segmentation of AMD PDU is currently not supported,
903  // so we just check that the segment was not received before
904  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (seqNumber.GetValue ());
905  if (it != m_rxonBuffer.end () )
906  {
907  NS_ASSERT (it->second.m_byteSegments.size () > 0);
908  NS_ASSERT_MSG (it->second.m_byteSegments.size () == 1, "re-segmentation not supported");
909  NS_LOG_LOGIC ("PDU segment already received, discarded");
910  }
911  else
912  {
913  NS_LOG_LOGIC ("Place PDU in the reception buffer ( SN = " << seqNumber << " )");
914  m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.push_back (rxPduParams.p);
915  m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete = true;
916  }
917 
918 
919  }
920 
921  // 5.1.3.2.3 Actions when a RLC data PDU is placed in the reception buffer
922  // When a RLC data PDU with SN = x is placed in the reception buffer,
923  // the receiving side of an AM RLC entity shall:
924 
925  // - if x >= VR(H)
926  // - update VR(H) to x+ 1;
927 
928  if ( seqNumber >= m_vrH )
929  {
930  m_vrH = seqNumber + 1;
931  NS_LOG_LOGIC ("New VR(H) = " << m_vrH);
932  }
933 
934  // - if all byte segments of the AMD PDU with SN = VR(MS) are received:
935  // - update VR(MS) to the SN of the first AMD PDU with SN > current VR(MS) for
936  // which not all byte segments have been received;
937 
938  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
939  if ( it != m_rxonBuffer.end () &&
940  it->second.m_pduComplete )
941  {
942  int firstVrMs = m_vrMs.GetValue ();
943  while ( it != m_rxonBuffer.end () &&
944  it->second.m_pduComplete )
945  {
946  m_vrMs++;
947  it = m_rxonBuffer.find (m_vrMs.GetValue ());
948  NS_LOG_LOGIC ("Incr VR(MS) = " << m_vrMs);
949 
950  NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in RxonBuffer");
951  }
952  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
953  }
954 
955  // - if x = VR(R):
956  // - if all byte segments of the AMD PDU with SN = VR(R) are received:
957  // - update VR(R) to the SN of the first AMD PDU with SN > current VR(R) for which not all byte segments have been received;
958  // - update VR(MR) to the updated VR(R) + AM_Window_Size;
959  // - reassemble RLC SDUs from any byte segments of AMD PDUs with SN that falls outside of the receiving window and in-sequence byte segments of the AMD PDU with SN = VR(R), remove RLC headers when doing so and deliver the reassembled RLC SDUs to upper layer in sequence if not delivered before;
960 
961  if ( seqNumber == m_vrR )
962  {
963  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (seqNumber.GetValue ());
964  if ( it != m_rxonBuffer.end () &&
965  it->second.m_pduComplete )
966  {
967  it = m_rxonBuffer.find (m_vrR.GetValue ());
968  int firstVrR = m_vrR.GetValue ();
969  while ( it != m_rxonBuffer.end () &&
970  it->second.m_pduComplete )
971  {
972  NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << m_vrR << " )");
973  NS_ASSERT_MSG (it->second.m_byteSegments.size () == 1,
974  "Too many segments. PDU Reassembly process didn't work");
975  ReassembleAndDeliver (it->second.m_byteSegments.front ());
976  m_rxonBuffer.erase (m_vrR.GetValue ());
977 
978  m_vrR++;
983  it = m_rxonBuffer.find (m_vrR.GetValue ());
984 
985  NS_ASSERT_MSG (firstVrR != m_vrR.GetValue (), "Infinite loop in RxonBuffer");
986  }
987  NS_LOG_LOGIC ("New VR(R) = " << m_vrR);
989 
990  NS_LOG_LOGIC ("New VR(MR) = " << m_vrMr);
991  }
992 
993  }
994 
995  // - if t-Reordering is running:
996  // - if VR(X) = VR(R); or
997  // - if VR(X) falls outside of the receiving window and VR(X) is not equal to VR(MR):
998  // - stop and reset t-Reordering;
999 
1000  if ( m_reorderingTimer.IsRunning () )
1001  {
1002  NS_LOG_LOGIC ("Reordering timer is running");
1003  if ( (m_vrX == m_vrR) ||
1004  ( (! IsInsideReceivingWindow (m_vrX)) && (m_vrX != m_vrMr) )
1005  )
1006  {
1008  NS_LOG_LOGIC ("Stop reordering timer");
1010  }
1011  }
1012 
1013  // - if t-Reordering is not running (includes the case t-Reordering is stopped due to actions above):
1014  // - if VR (H) > VR(R):
1015  // - start t-Reordering;
1016  // - set VR(X) to VR(H).
1017 
1018  if ( ! m_reorderingTimer.IsRunning () )
1019  {
1020  NS_LOG_LOGIC ("Reordering timer is not running");
1021  if ( m_vrH > m_vrR )
1022  {
1023  NS_LOG_LOGIC ("Start reordering timer");
1026  m_vrX = m_vrH;
1027  NS_LOG_LOGIC ("New VR(X) = " << m_vrX);
1028  }
1029  }
1030  }
1031  else if ( rlcAmHeader.IsControlPdu () )
1032  {
1033  NS_LOG_INFO ("Control AM RLC PDU");
1034 
1035  SequenceNumber10 ackSn = rlcAmHeader.GetAckSn ();
1036  SequenceNumber10 sn;
1037 
1038  NS_LOG_INFO ("ackSn = " << ackSn);
1039  NS_LOG_INFO ("VT(A) = " << m_vtA);
1040  NS_LOG_INFO ("VT(S) = " << m_vtS);
1041  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1042  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1043 
1047  ackSn.SetModulusBase (m_vtA);
1048  sn.SetModulusBase (m_vtA);
1049 
1050  bool incrementVtA = true;
1051 
1052  for (sn = m_vtA; sn < ackSn && sn < m_vtS; sn++)
1053  {
1054  NS_LOG_LOGIC ("sn = " << sn);
1055 
1056  uint16_t seqNumberValue = sn.GetValue ();
1057 
1059  && (seqNumberValue == m_pollSn.GetValue ()))
1060  {
1062  }
1063 
1064  if (rlcAmHeader.IsNackPresent (sn))
1065  {
1066  NS_LOG_LOGIC ("sn " << sn << " is NACKed");
1067 
1068  incrementVtA = false;
1069 
1070  if (m_txedBuffer.at (seqNumberValue).m_pdu != 0)
1071  {
1072  NS_LOG_INFO ("Move SN = " << seqNumberValue << " to retxBuffer");
1073  m_retxBuffer.at (seqNumberValue).m_pdu = m_txedBuffer.at (seqNumberValue).m_pdu->Copy ();
1074  m_retxBuffer.at (seqNumberValue).m_retxCount = m_txedBuffer.at (seqNumberValue).m_retxCount;
1075  m_retxBuffer.at (seqNumberValue).m_waitingSince = m_txedBuffer.at (seqNumberValue).m_waitingSince;
1076  m_retxBufferSize += m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
1077 
1078  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
1079  m_txedBuffer.at (seqNumberValue).m_pdu = 0;
1080  m_txedBuffer.at (seqNumberValue).m_retxCount = 0;
1081  m_txedBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0);
1082  }
1083 
1084  NS_ASSERT (m_retxBuffer.at (seqNumberValue).m_pdu != 0);
1085 
1086  }
1087  else
1088  {
1089  NS_LOG_LOGIC ("sn " << sn << " is ACKed");
1090 
1091  if (m_txedBuffer.at (seqNumberValue).m_pdu)
1092  {
1093  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from txedBuffer");
1094  // NS_LOG_INFO ("m_txedBuffer( " << m_vtA << " )->GetSize = " << m_txedBuffer.at (m_vtA.GetValue ())->GetSize ());
1095  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
1096  m_txedBuffer.at (seqNumberValue).m_pdu = 0;
1097  m_txedBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0);
1098  NS_ASSERT (m_retxBuffer.at (seqNumberValue).m_pdu == 0);
1099  }
1100 
1101  if (m_retxBuffer.at (seqNumberValue).m_pdu)
1102  {
1103  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from retxBuffer");
1104  m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
1105  m_retxBuffer.at (seqNumberValue).m_pdu = 0;
1106  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
1107  m_retxBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0);
1108  }
1109 
1110  }
1111 
1112  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1113  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1114 
1115  if (incrementVtA)
1116  {
1117  m_vtA++;
1119  NS_LOG_INFO ("New VT(A) = " << m_vtA);
1123  ackSn.SetModulusBase (m_vtA);
1124  sn.SetModulusBase (m_vtA);
1125  }
1126 
1127  } // loop over SN : VT(A) <= SN < ACK SN
1128 
1129  return;
1130 
1131  }
1132  else
1133  {
1134  NS_LOG_WARN ("Wrong AM RLC PDU type");
1135  return;
1136  }
1137 
1138 }
1139 
1140 
1141 bool
1143 {
1144  NS_LOG_FUNCTION (this << seqNumber);
1145  NS_LOG_LOGIC ("Receiving Window: " <<
1146  m_vrR << " <= " << seqNumber << " <= " << m_vrMr);
1147 
1150  seqNumber.SetModulusBase (m_vrR);
1151 
1152  if ( (m_vrR <= seqNumber) && (seqNumber < m_vrMr ) )
1153  {
1154  NS_LOG_LOGIC (seqNumber << " is INSIDE the receiving window");
1155  return true;
1156  }
1157  else
1158  {
1159  NS_LOG_LOGIC (seqNumber << " is OUTSIDE the receiving window");
1160  return false;
1161  }
1162 }
1163 
1164 
1165 void
1167 {
1168  LteRlcAmHeader rlcAmHeader;
1169  RlcTag rlcTag;
1170  bool ret = packet->FindFirstMatchingByteTag (rlcTag);
1171  NS_ASSERT(ret);
1172  packet->RemoveHeader (rlcAmHeader);
1173  ret = packet->FindFirstMatchingByteTag (rlcTag);
1174  NS_ASSERT(!ret);
1175  uint8_t framingInfo = rlcAmHeader.GetFramingInfo ();
1176  SequenceNumber10 currSeqNumber = rlcAmHeader.GetSequenceNumber ();
1177  bool expectedSnLost;
1178 
1179  if ( currSeqNumber != m_expectedSeqNumber )
1180  {
1181  expectedSnLost = true;
1182  NS_LOG_LOGIC ("There are losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
1183  m_expectedSeqNumber = currSeqNumber + 1;
1184  }
1185  else
1186  {
1187  expectedSnLost = false;
1188  NS_LOG_LOGIC ("No losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
1190  }
1191 
1192  // Build list of SDUs
1193  uint8_t extensionBit;
1194  uint16_t lengthIndicator;
1195  do
1196  {
1197  extensionBit = rlcAmHeader.PopExtensionBit ();
1198  NS_LOG_LOGIC ("E = " << (uint16_t)extensionBit);
1199 
1200  if ( extensionBit == 0 )
1201  {
1202  m_sdusBuffer.push_back (packet);
1203  }
1204  else // extensionBit == 1
1205  {
1206  lengthIndicator = rlcAmHeader.PopLengthIndicator ();
1207  NS_LOG_LOGIC ("LI = " << lengthIndicator);
1208 
1209  // Check if there is enough data in the packet
1210  if ( lengthIndicator >= packet->GetSize () )
1211  {
1212  NS_LOG_LOGIC ("INTERNAL ERROR: Not enough data in the packet (" << packet->GetSize () << "). Needed LI=" << lengthIndicator);
1214  }
1215 
1216  // Split packet in two fragments
1217  Ptr<Packet> data_field = packet->CreateFragment (0, lengthIndicator);
1218  packet->RemoveAtStart (lengthIndicator);
1219 
1220  m_sdusBuffer.push_back (data_field);
1221  }
1222  }
1223  while ( extensionBit == 1 );
1224 
1225  std::list < Ptr<Packet> >::iterator it;
1226 
1227  // Current reassembling state
1228  if (m_reassemblingState == WAITING_S0_FULL) NS_LOG_LOGIC ("Reassembling State = 'WAITING_S0_FULL'");
1229  else if (m_reassemblingState == WAITING_SI_SF) NS_LOG_LOGIC ("Reassembling State = 'WAITING_SI_SF'");
1230  else NS_LOG_LOGIC ("Reassembling State = Unknown state");
1231 
1232 
1233  // Received framing Info
1234  NS_LOG_LOGIC ("Framing Info = " << (uint16_t)framingInfo);
1235  NS_LOG_LOGIC ("m_sdusBuffer = " << m_sdusBuffer.size ());
1236 
1237  // Reassemble the list of SDUs (when there is no losses)
1238  if (!expectedSnLost)
1239  {
1240  switch (m_reassemblingState)
1241  {
1242  case WAITING_S0_FULL:
1243  switch (framingInfo)
1244  {
1247 
1251  for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1252  {
1254  }
1255  m_sdusBuffer.clear ();
1256  break;
1257 
1260 
1264  while ( m_sdusBuffer.size () > 1 )
1265  {
1267  m_sdusBuffer.pop_front ();
1268  }
1269 
1273  m_keepS0 = m_sdusBuffer.front ();
1274  m_sdusBuffer.pop_front ();
1275  break;
1276 
1279  default:
1283  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1284  break;
1285  }
1286  break;
1287 
1288  case WAITING_SI_SF:
1289  switch (framingInfo)
1290  {
1293 
1297  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1298  m_sdusBuffer.pop_front ();
1300 
1304  while ( ! m_sdusBuffer.empty () )
1305  {
1307  m_sdusBuffer.pop_front ();
1308  }
1309  break;
1310 
1313 
1317  if ( m_sdusBuffer.size () == 1 )
1318  {
1319  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1320  m_sdusBuffer.pop_front ();
1321  }
1322  else // m_sdusBuffer.size () > 1
1323  {
1327  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1328  m_sdusBuffer.pop_front ();
1330 
1334  while ( m_sdusBuffer.size () > 1 )
1335  {
1337  m_sdusBuffer.pop_front ();
1338  }
1339 
1343  m_keepS0 = m_sdusBuffer.front ();
1344  m_sdusBuffer.pop_front ();
1345  }
1346  break;
1347 
1350  default:
1354  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1355  break;
1356  }
1357  break;
1358 
1359  default:
1360  NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1361  break;
1362  }
1363  }
1364  else // Reassemble the list of SDUs (when there are losses, i.e. the received SN is not the expected one)
1365  {
1366  switch (m_reassemblingState)
1367  {
1368  case WAITING_S0_FULL:
1369  switch (framingInfo)
1370  {
1373 
1377  for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1378  {
1380  }
1381  m_sdusBuffer.clear ();
1382  break;
1383 
1386 
1390  while ( m_sdusBuffer.size () > 1 )
1391  {
1393  m_sdusBuffer.pop_front ();
1394  }
1395 
1399  m_keepS0 = m_sdusBuffer.front ();
1400  m_sdusBuffer.pop_front ();
1401  break;
1402 
1405 
1409  m_sdusBuffer.pop_front ();
1410 
1414  while ( ! m_sdusBuffer.empty () )
1415  {
1417  m_sdusBuffer.pop_front ();
1418  }
1419  break;
1420 
1422  if ( m_sdusBuffer.size () == 1 )
1423  {
1425  }
1426  else
1427  {
1429  }
1430 
1434  m_sdusBuffer.pop_front ();
1435 
1436  if ( m_sdusBuffer.size () > 0 )
1437  {
1441  while ( m_sdusBuffer.size () > 1 )
1442  {
1444  m_sdusBuffer.pop_front ();
1445  }
1446 
1450  m_keepS0 = m_sdusBuffer.front ();
1451  m_sdusBuffer.pop_front ();
1452  }
1453  break;
1454 
1455  default:
1459  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1460  break;
1461  }
1462  break;
1463 
1464  case WAITING_SI_SF:
1465  switch (framingInfo)
1466  {
1469 
1473  m_keepS0 = 0;
1474 
1478  while ( ! m_sdusBuffer.empty () )
1479  {
1481  m_sdusBuffer.pop_front ();
1482  }
1483  break;
1484 
1487 
1491  m_keepS0 = 0;
1492 
1496  while ( m_sdusBuffer.size () > 1 )
1497  {
1499  m_sdusBuffer.pop_front ();
1500  }
1501 
1505  m_keepS0 = m_sdusBuffer.front ();
1506  m_sdusBuffer.pop_front ();
1507 
1508  break;
1509 
1512 
1516  m_keepS0 = 0;
1517 
1521  m_sdusBuffer.pop_front ();
1522 
1526  while ( ! m_sdusBuffer.empty () )
1527  {
1529  m_sdusBuffer.pop_front ();
1530  }
1531  break;
1532 
1534  if ( m_sdusBuffer.size () == 1 )
1535  {
1537  }
1538  else
1539  {
1541  }
1542 
1546  m_keepS0 = 0;
1547 
1551  m_sdusBuffer.pop_front ();
1552 
1553  if ( m_sdusBuffer.size () > 0 )
1554  {
1558  while ( m_sdusBuffer.size () > 1 )
1559  {
1561  m_sdusBuffer.pop_front ();
1562  }
1563 
1567  m_keepS0 = m_sdusBuffer.front ();
1568  m_sdusBuffer.pop_front ();
1569  }
1570  break;
1571 
1572  default:
1576  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1577  break;
1578  }
1579  break;
1580 
1581  default:
1582  NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1583  break;
1584  }
1585  }
1586 
1587 }
1588 
1589 void
1591 {
1592  NS_LOG_FUNCTION (this);
1593 
1594  Time now = Simulator::Now ();
1595 
1596  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
1597  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1598  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1599  NS_LOG_LOGIC ("VT(A) = " << m_vtA);
1600  NS_LOG_LOGIC ("VT(S) = " << m_vtS);
1601 
1602  // Transmission Queue HOL time
1603  Time txonQueueHolDelay (0);
1604  if ( m_txonBufferSize > 0 )
1605  {
1606  txonQueueHolDelay = now - m_txonBuffer.front ().m_waitingSince;
1607  }
1608 
1609  // Retransmission Queue HOL time
1610  Time retxQueueHolDelay;
1611  if ( m_retxBufferSize > 0 )
1612  {
1613  Time senderTimestamp;
1614  if (m_retxBuffer.at (m_vtA.GetValue ()).m_pdu != 0)
1615  {
1616  senderTimestamp = m_retxBuffer.at (m_vtA.GetValue ()).m_waitingSince;
1617  }
1618  else
1619  {
1620  senderTimestamp = m_txedBuffer.at (m_vtA.GetValue ()).m_waitingSince;
1621  }
1622  retxQueueHolDelay = now - senderTimestamp;
1623  }
1624  else
1625  {
1626  retxQueueHolDelay = Seconds (0);
1627  }
1628 
1630  r.rnti = m_rnti;
1631  r.lcid = m_lcid;
1633  r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
1635  r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
1636 
1638  {
1640  }
1641  else
1642  {
1643  r.statusPduSize = 0;
1644  }
1645 
1646  if ( r.txQueueSize != 0 || r.retxQueueSize != 0 || r.statusPduSize != 0 )
1647  {
1648  NS_LOG_INFO ("Send ReportBufferStatus: " << r.txQueueSize << ", " << r.txQueueHolDelay << ", "
1649  << r.retxQueueSize << ", " << r.retxQueueHolDelay << ", "
1650  << r.statusPduSize);
1652  }
1653  else
1654  {
1655  NS_LOG_INFO ("ReportBufferStatus don't needed");
1656  }
1657 }
1658 
1659 
1660 void
1662 {
1663  NS_LOG_FUNCTION (this);
1664  NS_LOG_LOGIC ("Reordering Timer has expired");
1665 
1666  // 5.1.3.2.4 Actions when t-Reordering expires
1667  // When t-Reordering expires, the receiving side of an AM RLC entity shall:
1668  // - update VR(MS) to the SN of the first AMD PDU with SN >= VR(X) for which not all byte segments
1669  // have been received;
1670  // - if VR(H) > VR(MS):
1671  // - start t-Reordering;
1672  // - set VR(X) to VR(H).
1673 
1674  m_vrMs = m_vrX;
1675  int firstVrMs = m_vrMs.GetValue ();
1676  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
1677  while ( it != m_rxonBuffer.end () &&
1678  it->second.m_pduComplete )
1679  {
1680  m_vrMs++;
1681  it = m_rxonBuffer.find (m_vrMs.GetValue ());
1682 
1683  NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in ExpireReorderingTimer");
1684  }
1685  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
1686 
1687  if ( m_vrH > m_vrMs )
1688  {
1689  NS_LOG_LOGIC ("Start reordering timer");
1692  m_vrX = m_vrH;
1693  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
1694  }
1695 
1696  // Section 5.2.3 Status Reporting:
1697  // - The receiving side of an AM RLC entity shall trigger a
1698  // STATUS report when T_reordering expires.
1699  m_statusPduRequested = true;
1700 }
1701 
1702 void
1704 {
1705  NS_LOG_FUNCTION (this);
1706  NS_LOG_LOGIC ("PollRetransmit Timer has expired");
1707 
1708  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
1709  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1710  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1711  NS_LOG_LOGIC ("statusPduRequested = " << m_statusPduRequested);
1712 
1714 
1715  // see section 5.2.2.3
1716  // note the difference between Rel 8 and Rel 11 specs; we follow Rel 11 here
1717  NS_ASSERT (m_vtS <= m_vtMs);
1718  if ((m_txonBufferSize == 0 && m_retxBufferSize == 0)
1719  || (m_vtS == m_vtMs))
1720  {
1721  NS_LOG_INFO ("txonBuffer and retxBuffer empty. Move PDUs up to = " << m_vtS.GetValue () - 1 << " to retxBuffer");
1722  for (SequenceNumber10 sn = m_vtA; sn < m_vtS; sn++)
1723  {
1724  bool pduAvailable = m_txedBuffer.at (sn.GetValue ()).m_pdu != 0;
1725 
1726  if ( pduAvailable )
1727  {
1728  uint16_t snValue = sn.GetValue ();
1729  NS_LOG_INFO ("Move PDU " << sn << " from txedBuffer to retxBuffer");
1730  m_retxBuffer.at (snValue).m_pdu = m_txedBuffer.at (snValue).m_pdu->Copy ();
1731  m_retxBuffer.at (snValue).m_retxCount = m_txedBuffer.at (snValue).m_retxCount;
1732  m_retxBuffer.at (snValue).m_waitingSince = m_txedBuffer.at (snValue).m_waitingSince;
1733  m_retxBufferSize += m_retxBuffer.at (snValue).m_pdu->GetSize ();
1734 
1735  m_txedBufferSize -= m_txedBuffer.at (snValue).m_pdu->GetSize ();
1736  m_txedBuffer.at (snValue).m_pdu = 0;
1737  m_txedBuffer.at (snValue).m_retxCount = 0;
1738  m_txedBuffer.at (snValue).m_waitingSince = MilliSeconds (0);
1739  }
1740  }
1741  }
1742 
1744 }
1745 
1746 
1747 void
1749 {
1750  NS_LOG_FUNCTION (this);
1751 }
1752 
1753 void
1755 {
1756  NS_LOG_LOGIC ("RBS Timer expires");
1757 
1759  {
1762  }
1763 }
1764 
1765 } // namespace ns3
uint8_t PopExtensionBit(void)
Pop extension bit function.
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:939
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
uint32_t m_maxTxBufferSize
maximum transmission buffer size
Definition: lte-rlc-am.h:146
TracedCallback< uint16_t, uint8_t, uint32_t > m_txPdu
Used to inform of a PDU delivery to the MAC SAP provider.
Definition: lte-rlc.h:174
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
virtual uint32_t GetSerializedSize() const
Definition: lte-rlc-tag.cc:60
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
EventId m_statusProhibitTimer
status prohibit timer
Definition: lte-rlc-am.h:206
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Parameters for LteMacSapUser::NotifyTxOpportunity.
Definition: lte-mac-sap.h:103
uint32_t m_byteWithoutPoll
byte without poll
Definition: lte-rlc-am.h:192
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
virtual void DoNotifyTxOpportunity(LteMacSapUser::TxOpportunityParameters txOpParams)
MAC SAP.
Definition: lte-rlc-am.cc:200
EventId m_rbsTimer
RBS timer.
Definition: lte-rlc-am.h:208
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
#define min(a, b)
Definition: 80211b.c:42
uint32_t m_statusPduBufferSize
status PDU buffer size
Definition: lte-rlc-am.h:152
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:85
SequenceNumber10 m_vtS
VT(S)
Definition: lte-rlc-am.h:178
void DoReportBufferStatus()
Report buffer status.
Definition: lte-rlc-am.cc:1590
Tag to calculate the per-PDU delay from eNb RLC to UE RLC.
Definition: lte-rlc-tag.h:36
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:227
SequenceNumber10 m_vtMs
VT(MS)
Definition: lte-rlc-am.h:177
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
Time m_reorderingTimerValue
reordering timer value
Definition: lte-rlc-am.h:205
void SetDataPdu(void)
Set data PDU function.
SequenceNumber10 m_vrMs
VR(MS)
Definition: lte-rlc-am.h:185
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void SetPollingBit(uint8_t pollingBit)
Set polling bit function.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
Time m_pollRetransmitTimerValue
poll retransmit time value
Definition: lte-rlc-am.h:203
SequenceNumber10 m_vrR
VR(R)
Definition: lte-rlc-am.h:182
EventId m_reorderingTimer
reordering timer
Definition: lte-rlc-am.h:204
Time m_rbsTimerValue
RBS timer value.
Definition: lte-rlc-am.h:209
uint32_t retxQueueSize
the current size of the RLC retransmission queue in bytes
Definition: lte-mac-sap.h:73
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
uint16_t m_rnti
RNTI.
Definition: lte-rlc.h:168
bool IsInsideReceivingWindow(SequenceNumber10 seqNumber)
method called when the T_status_prohibit timer expires
Definition: lte-rlc-am.cc:1142
std::vector< RetxPdu > m_txedBuffer
Buffer for transmitted and retransmitted PDUs that have not been acked but are not considered for ret...
Definition: lte-rlc-am.h:141
virtual uint32_t GetSerializedSize(void) const
uint8_t m_lcid
LCID.
Definition: lte-rlc.h:169
uint16_t rnti
the C-RNTI identifying the UE
Definition: lte-mac-sap.h:69
TracedCallback< Ptr< const Packet > > m_txDropTrace
The trace source fired when the RLC drops a packet before transmission.
Definition: lte-rlc.h:183
EventId m_pollRetransmitTimer
Timers.
Definition: lte-rlc-am.h:202
void SetModulusBase(SequenceNumber10 modulusBase)
Set modulus base.
void ExpireRbsTimer(void)
Expire RBS timer.
Definition: lte-rlc-am.cc:1754
Parameters for LteMacSapProvider::ReportBufferStatus.
Definition: lte-mac-sap.h:67
void SetSenderTimestamp(Time senderTimestamp)
Set the sender timestamp.
Definition: lte-rlc-tag.h:74
uint32_t m_txonBufferSize
transmit on buffer size
Definition: lte-rlc-am.h:147
uint16_t txQueueHolDelay
the Head Of Line delay of the transmission queue
Definition: lte-mac-sap.h:72
SequenceNumber10 GetSequenceNumber() const
Get sequence number.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
SequenceNumber10 m_expectedSeqNumber
Expected Sequence Number.
Definition: lte-rlc-am.h:233
uint8_t GetStatus(void) const
Get status function.
LteRlcSapUser * m_rlcSapUser
RLC SAP user.
Definition: lte-rlc.h:144
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:362
std::map< uint16_t, PduBuffer > m_rxonBuffer
Reception buffer.
Definition: lte-rlc-am.h:163
AttributeValue implementation for Time.
Definition: nstime.h:1353
Hold an unsigned integer type.
Definition: uinteger.h:44
uint16_t m_pollPdu
poll PDU
Definition: lte-rlc-am.h:215
uint8_t componentCarrierId
the component carrier id
Definition: lte-mac-sap.h:132
virtual void ReceivePdcpPdu(Ptr< Packet > p)=0
Called by the RLC entity to notify the PDCP entity of the reception of a new PDCP PDU...
Ptr< Packet > m_keepS0
keep S0
Definition: lte-rlc-am.h:228
virtual void DoDispose()
Destructor implementation.
Definition: lte-rlc.cc:125
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
SequenceNumber10 m_pollSn
POLL_SN.
Definition: lte-rlc-am.h:179
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
Definition: lte-rlc.h:166
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
void SetControlPdu(uint8_t controlPduType)
Set control PDU function.
The packet header for the AM Radio Link Control (RLC) protocol packets.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::list< Ptr< Packet > > m_sdusBuffer
List of SDUs in a packet (PDU)
Definition: lte-rlc-am.h:170
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:392
uint16_t m_pollByte
poll byte
Definition: lte-rlc-am.h:216
SequenceNumber10 m_vrH
VR(H)
Definition: lte-rlc-am.h:186
bool m_pollRetransmitTimerJustExpired
poll retransmit timer just expired?
Definition: lte-rlc-am.h:219
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
SequenceNumber10 m_vrMr
VR(MR)
Definition: lte-rlc-am.h:183
Time GetSenderTimestamp(void) const
Get the instant when the RLC delivers the PDU to the MAC SAP provider.
Definition: lte-rlc-tag.h:65
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1354
SequenceNumber10 m_vrX
VR(X)
Definition: lte-rlc-am.h:184
uint8_t lcid
the logical channel id corresponding to the sending RLC instance
Definition: lte-mac-sap.h:70
uint32_t m_pduWithoutPoll
Counters.
Definition: lte-rlc-am.h:191
uint32_t txQueueSize
the current size of the RLC transmission queue
Definition: lte-mac-sap.h:71
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
uint8_t GetFramingInfo() const
Get framing info.
uint32_t m_txedBufferSize
transmit ed buffer size
Definition: lte-rlc-am.h:149
Time m_statusProhibitTimerValue
status prohibit timer value
Definition: lte-rlc-am.h:207
virtual void DoNotifyHarqDeliveryFailure()
Notify HARQ delivery failure
Definition: lte-rlc-am.cc:764
uint16_t m_maxRetxThreshold
Configurable parameters.
Definition: lte-rlc-am.h:214
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
uint32_t bytes
the number of bytes to transmit
Definition: lte-mac-sap.h:129
uint16_t statusPduSize
the current size of the pending STATUS RLC PDU message in bytes
Definition: lte-mac-sap.h:75
uint8_t layer
the layer of transmission (MIMO)
Definition: lte-mac-sap.h:130
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
This class implements a tag that carries the status of a RLC SDU for the fragmentation process Status...
virtual void DoDispose()
Destructor implementation.
Definition: lte-rlc-am.cc:132
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
void ExpireStatusProhibitTimer(void)
method called when the T_status_prohibit timer expires
Definition: lte-rlc-am.cc:1748
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:384
void ExpirePollRetransmitTimer(void)
Expire poll retransmitter.
Definition: lte-rlc-am.cc:1703
SequenceNumber10 m_vtA
State variables.
Definition: lte-rlc-am.h:176
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
uint16_t PopLengthIndicator(void)
Pop length indicator function.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
std::vector< RetxPdu > m_retxBuffer
Buffer for PDUs considered for retransmission.
Definition: lte-rlc-am.h:144
void SetStatus(uint8_t status)
Set status function.
uint16_t retxQueueHolDelay
the Head Of Line delay of the retransmission queue
Definition: lte-mac-sap.h:74
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
virtual void ReportBufferStatus(ReportBufferStatusParameters params)=0
Report the RLC buffer status to the MAC.
Parameters for LteMacSapUser::ReceivePdu.
Definition: lte-mac-sap.h:156
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
SequenceNumber10 class.
TracedCallback< uint16_t, uint8_t, uint32_t, uint64_t > m_rxPdu
Used to inform of a PDU reception from the MAC SAP user.
Definition: lte-rlc.h:178
LTE RLC Acknowledged Mode (AM), see 3GPP TS 36.322.
Definition: lte-rlc-am.h:36
Ptr< Packet > m_controlPduBuffer
Control PDU buffer (just one PDU)
Definition: lte-rlc-am.h:165
void ReassembleAndDeliver(Ptr< Packet > packet)
Reassemble and deliver.
Definition: lte-rlc-am.cc:1166
Store an incoming (from layer above us) PDU, waiting to transmit it.
Definition: lte-rlc-am.h:113
uint16_t m_windowSize
Constants.
Definition: lte-rlc-am.h:197
bool m_txOpportunityForRetxAlwaysBigEnough
transmit opportunity for retransmit?
Definition: lte-rlc-am.h:218
virtual void TransmitPdu(TransmitPduParameters params)=0
send an RLC PDU to the MAC for transmission.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
ReassemblingState_t m_reassemblingState
reassembling state
Definition: lte-rlc-am.h:227
This abstract base class defines the API to interact with the Radio Link Control (LTE_RLC) in LTE...
Definition: lte-rlc.h:50
a unique identifier for an interface.
Definition: type-id.h:58
uint32_t m_retxBufferSize
retransmit buffer size
Definition: lte-rlc-am.h:148
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:912
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-rlc-am.cc:88
std::vector< TxPdu > m_txonBuffer
Transmission buffer.
Definition: lte-rlc-am.h:131
bool m_statusPduRequested
status PDU requested
Definition: lte-rlc-am.h:151
void ExpireReorderingTimer(void)
This method will schedule a timeout at WaitReplyTimeout interval in the future, unless a timer is alr...
Definition: lte-rlc-am.cc:1661
virtual void DoTransmitPdcpPdu(Ptr< Packet > p)
RLC SAP.
Definition: lte-rlc-am.cc:161
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
virtual ~LteRlcAm()
Definition: lte-rlc-am.cc:82
virtual void DoReceivePdu(LteMacSapUser::ReceivePduParameters rxPduParams)
Receive PDU function.
Definition: lte-rlc-am.cc:771
Ptr< Packet > p
the RLC PDU to be received
Definition: lte-mac-sap.h:175
Parameters for LteMacSapProvider::TransmitPdu.
Definition: lte-mac-sap.h:45