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 
123  ;
124  return tid;
125 }
126 
127 void
129 {
130  NS_LOG_FUNCTION (this);
134  m_rbsTimer.Cancel ();
135 
136  m_txonBuffer.clear ();
137  m_txonBufferSize = 0;
138  m_txedBuffer.clear ();
139  m_txedBufferSize = 0;
140  m_retxBuffer.clear ();
141  m_retxBufferSize = 0;
142  m_rxonBuffer.clear ();
143  m_sdusBuffer.clear ();
144  m_keepS0 = 0;
145  m_controlPduBuffer = 0;
146 
148 }
149 
150 
155 void
157 {
158  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
159 
162  LteRlcSduStatusTag tag;
164  p->AddPacketTag (tag);
165 
166  NS_LOG_LOGIC ("Txon Buffer: New packet added");
167  m_txonBuffer.push_back (TxPdu (p, Simulator::Now ()));
168  m_txonBufferSize += p->GetSize ();
169  NS_LOG_LOGIC ("NumOfBuffers = " << m_txonBuffer.size() );
170  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
171 
174  m_rbsTimer.Cancel ();
176 }
177 
178 
183 void
185 {
186  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << txOpParams.bytes);
187 
188  if (txOpParams.bytes < 4)
189  {
190  // Stingy MAC: In general, we need more bytes.
191  // There are a more restrictive test for each particular case
192  NS_LOG_LOGIC ("TxOpportunity (size = " << txOpParams.bytes << ") too small");
193  NS_ASSERT_MSG (false, "TxOpportunity (size = " << txOpParams.bytes << ") too small.\n"
194  << "Your MAC scheduler is assigned too few resource blocks.");
195  return;
196  }
197 
199  {
200  if (txOpParams.bytes < m_statusPduBufferSize)
201  {
202  // Stingy MAC: We need more bytes for the STATUS PDU
203  NS_LOG_LOGIC ("TxOpportunity (size = " << txOpParams.bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")");
204  NS_ASSERT_MSG (false, "TxOpportunity (size = " << txOpParams.bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")\n"
205  << "Your MAC scheduler is assigned too few resource blocks.");
206  return;
207  }
208 
209  NS_LOG_LOGIC ("Sending STATUS PDU");
210 
211  Ptr<Packet> packet = Create<Packet> ();
212  LteRlcAmHeader rlcAmHeader;
214 
215  NS_LOG_LOGIC ("Check for SNs to NACK from " << m_vrR.GetValue() << " to " << m_vrMs.GetValue());
216  SequenceNumber10 sn;
217  sn.SetModulusBase (m_vrR);
218  std::map<uint16_t, PduBuffer>::iterator pduIt;
219  for (sn = m_vrR; sn < m_vrMs; sn++)
220  {
221  NS_LOG_LOGIC ("SN = " << sn);
222  if (!rlcAmHeader.OneMoreNackWouldFitIn (txOpParams.bytes))
223  {
224  NS_LOG_LOGIC ("Can't fit more NACKs in STATUS PDU");
225  break;
226  }
227  pduIt = m_rxonBuffer.find (sn.GetValue ());
228  if (pduIt == m_rxonBuffer.end () || (!(pduIt->second.m_pduComplete)))
229  {
230  NS_LOG_LOGIC ("adding NACK_SN " << sn.GetValue ());
231  rlcAmHeader.PushNack (sn.GetValue ());
232  }
233  }
234  NS_LOG_LOGIC ("SN at end of NACK loop = " << sn);
235  // 3GPP TS 36.322 section 6.2.2.1.4 ACK SN
236  // find the SN of the next not received RLC Data PDU
237  // which is not reported as missing in the STATUS PDU.
238  pduIt = m_rxonBuffer.find (sn.GetValue ());
239  while ((sn < m_vrMs) && (pduIt != m_rxonBuffer.end ()) && (pduIt->second.m_pduComplete))
240  {
241  NS_LOG_LOGIC ("SN = " << sn << " < " << m_vrMs << " = " << (sn < m_vrMs));
242  sn++;
243  NS_LOG_LOGIC ("SN = " << sn);
244  pduIt = m_rxonBuffer.find (sn.GetValue ());
245  }
246 
247  NS_ASSERT_MSG (sn <= m_vrMs, "first SN not reported as missing = " << sn << ", VR(MS) = " << m_vrMs);
248  rlcAmHeader.SetAckSn (sn);
249 
250 
251  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
252  packet->AddHeader (rlcAmHeader);
253 
254  // Sender timestamp
255  RlcTag rlcTag (Simulator::Now ());
256  packet->AddByteTag (rlcTag, 1, rlcAmHeader.GetSerializedSize ());
257  m_txPdu (m_rnti, m_lcid, packet->GetSize ());
258 
259  // Send RLC PDU to MAC layer
261  params.pdu = packet;
262  params.rnti = m_rnti;
263  params.lcid = m_lcid;
264  params.layer = txOpParams.layer;
265  params.harqProcessId = txOpParams.harqId;
266  params.componentCarrierId = txOpParams.componentCarrierId;
267 
268  m_macSapProvider->TransmitPdu (params);
269 
270  m_statusPduRequested = false;
274  return;
275  }
276  else if ( m_retxBufferSize > 0 )
277  {
278  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
279  NS_LOG_LOGIC ("Sending data from Retransmission Buffer");
280  NS_ASSERT (m_vtA < m_vtS);
281  SequenceNumber10 sn;
282  sn.SetModulusBase (m_vtA);
283  for (sn = m_vtA; sn < m_vtS; sn++)
284  {
285  uint16_t seqNumberValue = sn.GetValue ();
286  NS_LOG_LOGIC ("SN = " << seqNumberValue << " m_pdu " << m_retxBuffer.at (seqNumberValue).m_pdu);
287 
288  if (m_retxBuffer.at (seqNumberValue).m_pdu != 0)
289  {
290  Ptr<Packet> packet = m_retxBuffer.at (seqNumberValue).m_pdu->Copy ();
291 
292  if (( packet->GetSize () <= txOpParams.bytes )
294  {
295  // According to 5.2.1, the data field is left as is, but we rebuild the header
296  LteRlcAmHeader rlcAmHeader;
297  packet->RemoveHeader (rlcAmHeader);
298  NS_LOG_LOGIC ("old AM RLC header: " << rlcAmHeader);
299 
300  // Calculate the Polling Bit (5.2.2.1)
302 
303  NS_LOG_LOGIC ("polling conditions: m_txonBuffer.empty=" << m_txonBuffer.empty ()
304  << " retxBufferSize=" << m_retxBufferSize
305  << " packet->GetSize ()=" << packet->GetSize ());
306  if (((m_txonBuffer.empty ()) && (m_retxBufferSize == packet->GetSize () + rlcAmHeader.GetSerializedSize ()))
307  || (m_vtS >= m_vtMs)
309  {
312  m_pduWithoutPoll = 0;
313  m_byteWithoutPoll = 0;
314 
315  m_pollSn = m_vtS - 1;
316  NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn);
317 
319  {
320  NS_LOG_LOGIC ("Start PollRetransmit timer");
321 
324  }
325  else
326  {
327  NS_LOG_LOGIC ("Restart PollRetransmit timer");
328 
332  }
333  }
334 
335  packet->AddHeader (rlcAmHeader);
336 
337  RlcTag rlcTag;
339 
340  packet->AddByteTag (rlcTag, 1, rlcAmHeader.GetSerializedSize ());
341 
342  NS_LOG_LOGIC ("new AM RLC header: " << rlcAmHeader);
343 
344  m_txPdu (m_rnti, m_lcid, packet->GetSize ());
345 
346  // Send RLC PDU to MAC layer
348  params.pdu = packet;
349  params.rnti = m_rnti;
350  params.lcid = m_lcid;
351  params.layer = txOpParams.layer;
352  params.harqProcessId = txOpParams.harqId;
353  params.componentCarrierId = txOpParams.componentCarrierId;
354 
355  m_macSapProvider->TransmitPdu (params);
356 
357  m_retxBuffer.at (seqNumberValue).m_retxCount++;
358  m_retxBuffer.at (seqNumberValue).m_waitingSince = Simulator::Now ();
359  NS_LOG_INFO ("Incr RETX_COUNT for SN = " << seqNumberValue);
360  if (m_retxBuffer.at (seqNumberValue).m_retxCount >= m_maxRetxThreshold)
361  {
362  NS_LOG_INFO ("Max RETX_COUNT for SN = " << seqNumberValue);
363  }
364 
365  NS_LOG_INFO ("Move SN = " << seqNumberValue << " back to txedBuffer");
366  m_txedBuffer.at (seqNumberValue).m_pdu = m_retxBuffer.at (seqNumberValue).m_pdu->Copy ();
367  m_txedBuffer.at (seqNumberValue).m_retxCount = m_retxBuffer.at (seqNumberValue).m_retxCount;
368  m_txedBuffer.at (seqNumberValue).m_waitingSince = m_retxBuffer.at (seqNumberValue).m_waitingSince;
369  m_txedBufferSize += m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
370 
371  m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
372  m_retxBuffer.at (seqNumberValue).m_pdu = 0;
373  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
374  m_retxBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0);
375 
376  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
377 
378  return;
379  }
380  else
381  {
382  NS_LOG_LOGIC ("TxOpportunity (size = " << txOpParams.bytes << ") too small for retransmission of the packet (size = " << packet->GetSize () << ")");
383  NS_LOG_LOGIC ("Waiting for bigger TxOpportunity");
384  return;
385  }
386  }
387  }
388  NS_ASSERT_MSG (false, "m_retxBufferSize > 0, but no PDU considered for retx found");
389  }
390  else if ( m_txonBufferSize > 0 )
391  {
392  if (txOpParams.bytes < 7)
393  {
394  // Stingy MAC: We need more bytes for new DATA PDUs.
395  NS_LOG_LOGIC ("TxOpportunity (size = " << txOpParams.bytes << ") too small for DATA PDU");
396  NS_ASSERT_MSG (false, "TxOpportunity (size = " << txOpParams.bytes << ") too small for DATA PDU\n"
397  << "Your MAC scheduler is assigned too few resource blocks.");
398  return;
399  }
400 
401  NS_ASSERT (m_vtS <= m_vtMs);
402  if (m_vtS == m_vtMs)
403  {
404  NS_LOG_INFO ("cannot transmit new RLC PDU due to window stalling");
405  return;
406  }
407 
408  NS_LOG_LOGIC ("Sending data from Transmission Buffer");
409  }
410  else
411  {
412  NS_LOG_LOGIC ("No data pending");
413  return;
414  }
415 
416  //
417  //
418  // Build new PDU
419  //
420  //
421 
422  Ptr<Packet> packet = Create<Packet> ();
423  LteRlcAmHeader rlcAmHeader;
424  rlcAmHeader.SetDataPdu ();
425 
426  // Build Data field
427  uint32_t nextSegmentSize = txOpParams.bytes - 4;
428  uint32_t nextSegmentId = 1;
429  uint32_t dataFieldTotalSize = 0;
430  uint32_t dataFieldAddedSize = 0;
431  std::vector < Ptr<Packet> > dataField;
432 
433  // Remove the first packet from the transmission buffer.
434  // If only a segment of the packet is taken, then the remaining is given back later
435  if ( m_txonBuffer.size () == 0 )
436  {
437  NS_LOG_LOGIC ("No data pending");
438  return;
439  }
440 
441  NS_LOG_LOGIC ("SDUs in TxonBuffer = " << m_txonBuffer.size ());
442  NS_LOG_LOGIC ("First SDU buffer = " << m_txonBuffer.begin ()->m_pdu);
443  NS_LOG_LOGIC ("First SDU size = " << m_txonBuffer.begin ()->m_pdu->GetSize ());
444  NS_LOG_LOGIC ("Next segment size = " << nextSegmentSize);
445  NS_LOG_LOGIC ("Remove SDU from TxBuffer");
446  Time firstSegmentTime = m_txonBuffer.begin ()->m_waitingSince;
447  Ptr<Packet> firstSegment = m_txonBuffer.begin ()->m_pdu->Copy ();
448  m_txonBufferSize -= m_txonBuffer.begin ()->m_pdu->GetSize ();
449  NS_LOG_LOGIC ("txBufferSize = " << m_txonBufferSize );
450  m_txonBuffer.erase (m_txonBuffer.begin ());
451 
452  while ( firstSegment && (firstSegment->GetSize () > 0) && (nextSegmentSize > 0) )
453  {
454  NS_LOG_LOGIC ("WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
455  NS_LOG_LOGIC (" firstSegment size = " << firstSegment->GetSize ());
456  NS_LOG_LOGIC (" nextSegmentSize = " << nextSegmentSize);
457  if ( (firstSegment->GetSize () > nextSegmentSize) ||
458  // Segment larger than 2047 octets can only be mapped to the end of the Data field
459  (firstSegment->GetSize () > 2047)
460  )
461  {
462  // Take the minimum size, due to the 2047-bytes 3GPP exception
463  // This exception is due to the length of the LI field (just 11 bits)
464  uint32_t currSegmentSize = std::min (firstSegment->GetSize (), nextSegmentSize);
465 
466  NS_LOG_LOGIC (" IF ( firstSegment > nextSegmentSize ||");
467  NS_LOG_LOGIC (" firstSegment > 2047 )");
468 
469  // Segment txBuffer.FirstBuffer and
470  // Give back the remaining segment to the transmission buffer
471  Ptr<Packet> newSegment = firstSegment->CreateFragment (0, currSegmentSize);
472  NS_LOG_LOGIC (" newSegment size = " << newSegment->GetSize ());
473 
474  // Status tag of the new and remaining segments
475  // Note: This is the only place where a PDU is segmented and
476  // therefore its status can change
477  LteRlcSduStatusTag oldTag, newTag;
478  firstSegment->RemovePacketTag (oldTag);
479  newSegment->RemovePacketTag (newTag);
480  if (oldTag.GetStatus () == LteRlcSduStatusTag::FULL_SDU)
481  {
482  newTag.SetStatus (LteRlcSduStatusTag::FIRST_SEGMENT);
483  oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
484  }
485  else if (oldTag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT)
486  {
487  newTag.SetStatus (LteRlcSduStatusTag::MIDDLE_SEGMENT);
488  //oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
489  }
490 
491  // Give back the remaining segment to the transmission buffer
492  firstSegment->RemoveAtStart (currSegmentSize);
493  NS_LOG_LOGIC (" firstSegment size (after RemoveAtStart) = " << firstSegment->GetSize ());
494  if (firstSegment->GetSize () > 0)
495  {
496  firstSegment->AddPacketTag (oldTag);
497 
498  m_txonBuffer.insert (m_txonBuffer.begin (), TxPdu (firstSegment, firstSegmentTime));
499  m_txonBufferSize += m_txonBuffer.begin ()->m_pdu->GetSize ();
500 
501  NS_LOG_LOGIC (" Txon buffer: Give back the remaining segment");
502  NS_LOG_LOGIC (" Txon buffers = " << m_txonBuffer.size ());
503  NS_LOG_LOGIC (" Front buffer size = " << m_txonBuffer.begin ()->m_pdu->GetSize ());
504  NS_LOG_LOGIC (" txonBufferSize = " << m_txonBufferSize );
505  }
506  else
507  {
508  // Whole segment was taken, so adjust tag
509  if (newTag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
510  {
511  newTag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
512  }
513  else if (newTag.GetStatus () == LteRlcSduStatusTag::MIDDLE_SEGMENT)
514  {
515  newTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
516  }
517  }
518  // Segment is completely taken or
519  // the remaining segment is given back to the transmission buffer
520  firstSegment = 0;
521 
522  // Put status tag once it has been adjusted
523  newSegment->AddPacketTag (newTag);
524 
525  // Add Segment to Data field
526  dataFieldAddedSize = newSegment->GetSize ();
527  dataFieldTotalSize += dataFieldAddedSize;
528  dataField.push_back (newSegment);
529  newSegment = 0;
530 
531  // ExtensionBit (Next_Segment - 1) = 0
532  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
533 
534  // no LengthIndicator for the last one
535 
536  nextSegmentSize -= dataFieldAddedSize;
537  nextSegmentId++;
538 
539  // nextSegmentSize MUST be zero (only if segment is smaller or equal to 2047)
540 
541  // (NO more segments) ? exit
542  // break;
543  }
544  else if ( (nextSegmentSize - firstSegment->GetSize () <= 2) || (m_txonBuffer.size () == 0) )
545  {
546  NS_LOG_LOGIC (" IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
547 
548  // Add txBuffer.FirstBuffer to DataField
549  dataFieldAddedSize = firstSegment->GetSize ();
550  dataFieldTotalSize += dataFieldAddedSize;
551  dataField.push_back (firstSegment);
552  firstSegment = 0;
553 
554  // ExtensionBit (Next_Segment - 1) = 0
555  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
556 
557  // no LengthIndicator for the last one
558 
559  nextSegmentSize -= dataFieldAddedSize;
560  nextSegmentId++;
561 
562  NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
563  if (m_txonBuffer.size () > 0)
564  {
565  NS_LOG_LOGIC (" First SDU buffer = " << m_txonBuffer.begin ()->m_pdu);
566  NS_LOG_LOGIC (" First SDU size = " << m_txonBuffer.begin ()->m_pdu->GetSize ());
567  }
568  NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
569 
570  // nextSegmentSize <= 2 (only if txBuffer is not empty)
571 
572  // (NO more segments) ? exit
573  // break;
574  }
575  else // (firstSegment->GetSize () < m_nextSegmentSize) && (m_txBuffer.size () > 0)
576  {
577  NS_LOG_LOGIC (" IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
578  // Add txBuffer.FirstBuffer to DataField
579  dataFieldAddedSize = firstSegment->GetSize ();
580  dataFieldTotalSize += dataFieldAddedSize;
581  dataField.push_back (firstSegment);
582 
583  // ExtensionBit (Next_Segment - 1) = 1
584  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::E_LI_FIELDS_FOLLOWS);
585 
586  // LengthIndicator (Next_Segment) = txBuffer.FirstBuffer.length()
587  rlcAmHeader.PushLengthIndicator (firstSegment->GetSize ());
588 
589  nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
590  nextSegmentId++;
591 
592  NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
593  if (m_txonBuffer.size () > 0)
594  {
595  NS_LOG_LOGIC (" First SDU buffer = " << m_txonBuffer.begin ()->m_pdu);
596  NS_LOG_LOGIC (" First SDU size = " << m_txonBuffer.begin ()->m_pdu->GetSize ());
597  }
598  NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
599  NS_LOG_LOGIC (" Remove SDU from TxBuffer");
600 
601  // (more segments)
602  firstSegment = m_txonBuffer.begin ()->m_pdu->Copy ();
603  firstSegmentTime = m_txonBuffer.begin ()->m_waitingSince;
604  m_txonBufferSize -= m_txonBuffer.begin ()->m_pdu->GetSize ();
605  m_txonBuffer.erase (m_txonBuffer.begin ());
606  NS_LOG_LOGIC (" txBufferSize = " << m_txonBufferSize );
607  }
608 
609  }
610 
611  //
612  // Build RLC header
613  //
614 
615  rlcAmHeader.SetSequenceNumber ( m_vtS++ );
616  rlcAmHeader.SetResegmentationFlag (LteRlcAmHeader::PDU);
617  rlcAmHeader.SetLastSegmentFlag (LteRlcAmHeader::LAST_PDU_SEGMENT);
618  rlcAmHeader.SetSegmentOffset (0);
619 
620  NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () < m_vtMs, "SN above TX window");
621  NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () >= m_vtA, "SN below TX window");
622 
623  // Calculate FramingInfo flag according the status of the SDUs in the DataField
624  uint8_t framingInfo = 0;
625  std::vector< Ptr<Packet> >::iterator it;
626  it = dataField.begin ();
627 
628  // FIRST SEGMENT
629  LteRlcSduStatusTag tag;
630  NS_ASSERT_MSG ((*it)->PeekPacketTag (tag), "LteRlcSduStatusTag is missing");
631  (*it)->PeekPacketTag (tag);
632  if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
634  )
635  {
636  framingInfo |= LteRlcAmHeader::FIRST_BYTE;
637  }
638  else
639  {
640  framingInfo |= LteRlcAmHeader::NO_FIRST_BYTE;
641  }
642 
643  // Add all SDUs (in DataField) to the Packet
644  while (it < dataField.end ())
645  {
646  NS_LOG_LOGIC ("Adding SDU/segment to packet, length = " << (*it)->GetSize ());
647 
648  NS_ASSERT_MSG ((*it)->PeekPacketTag (tag), "LteRlcSduStatusTag is missing");
649  (*it)->RemovePacketTag (tag);
650  if (packet->GetSize () > 0)
651  {
652  packet->AddAtEnd (*it);
653  }
654  else
655  {
656  packet = (*it);
657  }
658  it++;
659  }
660 
661  // LAST SEGMENT (Note: There could be only one and be the first one)
662  it--;
663  if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
665  {
666  framingInfo |= LteRlcAmHeader::LAST_BYTE;
667  }
668  else
669  {
670  framingInfo |= LteRlcAmHeader::NO_LAST_BYTE;
671  }
672 
673  // Set the FramingInfo flag after the calculation
674  rlcAmHeader.SetFramingInfo (framingInfo);
675 
676 
677  // Calculate the Polling Bit (5.2.2.1)
678  rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
679 
681  NS_LOG_LOGIC ("PDU_WITHOUT_POLL = " << m_pduWithoutPoll);
682  m_byteWithoutPoll += packet->GetSize ();
683  NS_LOG_LOGIC ("BYTE_WITHOUT_POLL = " << m_byteWithoutPoll);
684 
686  ( (m_txonBuffer.empty ()) && (m_retxBufferSize == 0) ) ||
687  (m_vtS >= m_vtMs)
689  )
690  {
692  rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
693  m_pduWithoutPoll = 0;
694  m_byteWithoutPoll = 0;
695 
696  m_pollSn = m_vtS - 1;
697  NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn);
698 
700  {
701  NS_LOG_LOGIC ("Start PollRetransmit timer");
702 
705  }
706  else
707  {
708  NS_LOG_LOGIC ("Restart PollRetransmit timer");
709 
713  }
714  }
715 
716 
717  // Build RLC PDU with DataField and Header
718  NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader);
719 
720  RlcTag rlcTag;
722 
723  packet->AddHeader (rlcAmHeader);
724  packet->AddByteTag (rlcTag, 1, rlcAmHeader.GetSerializedSize ());
725 
726  // Store new PDU into the Transmitted PDU Buffer
727  NS_LOG_LOGIC ("Put transmitted PDU in the txedBuffer");
728  m_txedBufferSize += packet->GetSize ();
729  m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_pdu = packet->Copy ();
730  m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_retxCount = 0;
731  m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_waitingSince = Simulator::Now ();
732 
733  m_txPdu (m_rnti, m_lcid, packet->GetSize ());
734 
735  // Send RLC PDU to MAC layer
737  params.pdu = packet;
738  params.rnti = m_rnti;
739  params.lcid = m_lcid;
740  params.layer = txOpParams.layer;
741  params.harqProcessId = txOpParams.harqId;
742  params.componentCarrierId = txOpParams.componentCarrierId;
743 
744  m_macSapProvider->TransmitPdu (params);
745 }
746 
747 void
749 {
750  NS_LOG_FUNCTION (this);
751 }
752 
753 
754 void
756 {
757  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << rxPduParams.p->GetSize ());
758 
759  // Get RLC header parameters
760  LteRlcAmHeader rlcAmHeader;
761  rxPduParams.p->PeekHeader (rlcAmHeader);
762  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
763 
764  // Receiver timestamp
765  Time delay;
766  RlcTag rlcTag;
767 
768  bool ret = rxPduParams.p->FindFirstMatchingByteTag (rlcTag);
769  NS_ASSERT_MSG(ret, "RlcTag not found in RLC Header. The packet went into a real network?");
770 
771  delay = Simulator::Now () - rlcTag.GetSenderTimestamp ();
772 
773  m_rxPdu (m_rnti, m_lcid, rxPduParams.p->GetSize (), delay.GetNanoSeconds ());
774 
775  if ( rlcAmHeader.IsDataPdu () )
776  {
777 
778  // 5.1.3.1 Transmit operations
779 
780  // 5.1.3.1.1 General
781  //
782  // The transmitting side of an AM RLC entity shall prioritize transmission of RLC control PDUs
783  // over RLC data PDUs. The transmitting side of an AM RLC entity shall prioritize retransmission
784  // of RLC data PDUs over transmission of new AMD PDUs.
785  //
786  // The transmitting side of an AM RLC entity shall maintain a transmitting window according to
787  // state variables VT(A) and VT(MS) as follows:
788  // - a SN falls within the transmitting window if VT(A) <= SN < VT(MS);
789  // - a SN falls outside of the transmitting window otherwise.
790  //
791  // The transmitting side of an AM RLC entity shall not deliver to lower layer any RLC data PDU
792  // whose SN falls outside of the transmitting window.
793  //
794  // When delivering a new AMD PDU to lower layer, the transmitting side of an AM RLC entity shall:
795  // - set the SN of the AMD PDU to VT(S), and then increment VT(S) by one.
796  //
797  // The transmitting side of an AM RLC entity can receive a positive acknowledgement (confirmation
798  // of successful reception by its peer AM RLC entity) for a RLC data PDU by the following:
799  // - STATUS PDU from its peer AM RLC entity.
800  //
801  // When receiving a positive acknowledgement for an AMD PDU with SN = VT(A), the transmitting
802  // side of an AM RLC entity shall:
803  // - set VT(A) equal to the SN of the AMD PDU with the smallest SN, whose SN falls within the
804  // range VT(A) <= SN <= VT(S) and for which a positive acknowledgment has not been received yet.
805  // - if positive acknowledgements have been received for all AMD PDUs associated with
806  // a transmitted RLC SDU:
807  // - send an indication to the upper layers of successful delivery of the RLC SDU.
808 
809 
810  // 5.1.3.2 Receive operations
811  //
812  // 5.1.3.2.1 General
813  //
814  // The receiving side of an AM RLC entity shall maintain a receiving window according to state
815  // variables VR(R) and VR(MR) as follows:
816  // - a SN falls within the receiving window if VR(R) <= SN < VR(MR);
817  // - a SN falls outside of the receiving window otherwise.
818  //
819  // When receiving a RLC data PDU from lower layer, the receiving side of an AM RLC entity shall:
820  // - either discard the received RLC data PDU or place it in the reception buffer (see sub clause 5.1.3.2.2);
821  // - if the received RLC data PDU was placed in the reception buffer:
822  // - 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).
823  //
824  // When t-Reordering expires, the receiving side of an AM RLC entity shall:
825  // - update state variables and start t-Reordering as needed (see sub clause 5.1.3.2.4).
826 
827 
828  SequenceNumber10 seqNumber = rlcAmHeader.GetSequenceNumber ();
829  seqNumber.SetModulusBase (m_vrR);
830 
831  if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::SEGMENT )
832  {
833  NS_LOG_LOGIC ("PDU segment received ( SN = " << seqNumber << " )");
834  }
835  else if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::PDU )
836  {
837  NS_LOG_LOGIC ("PDU received ( SN = " << seqNumber << " )");
838  }
839  else
840  {
841  NS_ASSERT_MSG (false, "Neither a PDU segment nor a PDU received");
842  return ;
843  }
844 
845  // STATUS PDU is requested
846  if ( rlcAmHeader.GetPollingBit () == LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED )
847  {
848  m_statusPduRequested = true;
850 
852  {
854  }
855  }
856 
857  // 5.1.3.2.2 Actions when a RLC data PDU is received from lower layer
858  //
859  // When a RLC data PDU is received from lower layer, where the RLC data PDU contains
860  // byte segment numbers y to z of an AMD PDU with SN = x, the receiving side of an AM RLC entity shall:
861  // - if x falls outside of the receiving window; or
862  // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
863  // - discard the received RLC data PDU;
864  // - else:
865  // - place the received RLC data PDU in the reception buffer;
866  // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
867  // - discard the duplicate byte segments.
868 
869  NS_LOG_LOGIC ("VR(R) = " << m_vrR);
870  NS_LOG_LOGIC ("VR(MR) = " << m_vrMr);
871  NS_LOG_LOGIC ("VR(X) = " << m_vrX);
872  NS_LOG_LOGIC ("VR(MS) = " << m_vrMs);
873  NS_LOG_LOGIC ("VR(H) = " << m_vrH);
874 
875  // - if x falls outside of the receiving window; or
876  // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
877  if ( ! IsInsideReceivingWindow (seqNumber) )
878  {
879  NS_LOG_LOGIC ("PDU discarded");
880  return;
881  }
882  else
883  {
884  // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
885  // - discard the duplicate byte segments.
886  // note: re-segmentation of AMD PDU is currently not supported,
887  // so we just check that the segment was not received before
888  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (seqNumber.GetValue ());
889  if (it != m_rxonBuffer.end () )
890  {
891  NS_ASSERT (it->second.m_byteSegments.size () > 0);
892  NS_ASSERT_MSG (it->second.m_byteSegments.size () == 1, "re-segmentation not supported");
893  NS_LOG_LOGIC ("PDU segment already received, discarded");
894  }
895  else
896  {
897  NS_LOG_LOGIC ("Place PDU in the reception buffer ( SN = " << seqNumber << " )");
898  m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.push_back (rxPduParams.p);
899  m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete = true;
900  }
901 
902 
903  }
904 
905  // 5.1.3.2.3 Actions when a RLC data PDU is placed in the reception buffer
906  // When a RLC data PDU with SN = x is placed in the reception buffer,
907  // the receiving side of an AM RLC entity shall:
908 
909  // - if x >= VR(H)
910  // - update VR(H) to x+ 1;
911 
912  if ( seqNumber >= m_vrH )
913  {
914  m_vrH = seqNumber + 1;
915  NS_LOG_LOGIC ("New VR(H) = " << m_vrH);
916  }
917 
918  // - if all byte segments of the AMD PDU with SN = VR(MS) are received:
919  // - update VR(MS) to the SN of the first AMD PDU with SN > current VR(MS) for
920  // which not all byte segments have been received;
921 
922  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
923  if ( it != m_rxonBuffer.end () &&
924  it->second.m_pduComplete )
925  {
926  int firstVrMs = m_vrMs.GetValue ();
927  while ( it != m_rxonBuffer.end () &&
928  it->second.m_pduComplete )
929  {
930  m_vrMs++;
931  it = m_rxonBuffer.find (m_vrMs.GetValue ());
932  NS_LOG_LOGIC ("Incr VR(MS) = " << m_vrMs);
933 
934  NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in RxonBuffer");
935  }
936  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
937  }
938 
939  // - if x = VR(R):
940  // - if all byte segments of the AMD PDU with SN = VR(R) are received:
941  // - 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;
942  // - update VR(MR) to the updated VR(R) + AM_Window_Size;
943  // - 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;
944 
945  if ( seqNumber == m_vrR )
946  {
947  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (seqNumber.GetValue ());
948  if ( it != m_rxonBuffer.end () &&
949  it->second.m_pduComplete )
950  {
951  it = m_rxonBuffer.find (m_vrR.GetValue ());
952  int firstVrR = m_vrR.GetValue ();
953  while ( it != m_rxonBuffer.end () &&
954  it->second.m_pduComplete )
955  {
956  NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << m_vrR << " )");
957  NS_ASSERT_MSG (it->second.m_byteSegments.size () == 1,
958  "Too many segments. PDU Reassembly process didn't work");
959  ReassembleAndDeliver (it->second.m_byteSegments.front ());
960  m_rxonBuffer.erase (m_vrR.GetValue ());
961 
962  m_vrR++;
967  it = m_rxonBuffer.find (m_vrR.GetValue ());
968 
969  NS_ASSERT_MSG (firstVrR != m_vrR.GetValue (), "Infinite loop in RxonBuffer");
970  }
971  NS_LOG_LOGIC ("New VR(R) = " << m_vrR);
973 
974  NS_LOG_LOGIC ("New VR(MR) = " << m_vrMr);
975  }
976 
977  }
978 
979  // - if t-Reordering is running:
980  // - if VR(X) = VR(R); or
981  // - if VR(X) falls outside of the receiving window and VR(X) is not equal to VR(MR):
982  // - stop and reset t-Reordering;
983 
984  if ( m_reorderingTimer.IsRunning () )
985  {
986  NS_LOG_LOGIC ("Reordering timer is running");
987  if ( (m_vrX == m_vrR) ||
988  ( (! IsInsideReceivingWindow (m_vrX)) && (m_vrX != m_vrMr) )
989  )
990  {
992  NS_LOG_LOGIC ("Stop reordering timer");
994  }
995  }
996 
997  // - if t-Reordering is not running (includes the case t-Reordering is stopped due to actions above):
998  // - if VR (H) > VR(R):
999  // - start t-Reordering;
1000  // - set VR(X) to VR(H).
1001 
1002  if ( ! m_reorderingTimer.IsRunning () )
1003  {
1004  NS_LOG_LOGIC ("Reordering timer is not running");
1005  if ( m_vrH > m_vrR )
1006  {
1007  NS_LOG_LOGIC ("Start reordering timer");
1010  m_vrX = m_vrH;
1011  NS_LOG_LOGIC ("New VR(X) = " << m_vrX);
1012  }
1013  }
1014  }
1015  else if ( rlcAmHeader.IsControlPdu () )
1016  {
1017  NS_LOG_INFO ("Control AM RLC PDU");
1018 
1019  SequenceNumber10 ackSn = rlcAmHeader.GetAckSn ();
1020  SequenceNumber10 sn;
1021 
1022  NS_LOG_INFO ("ackSn = " << ackSn);
1023  NS_LOG_INFO ("VT(A) = " << m_vtA);
1024  NS_LOG_INFO ("VT(S) = " << m_vtS);
1025  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1026  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1027 
1031  ackSn.SetModulusBase (m_vtA);
1032  sn.SetModulusBase (m_vtA);
1033 
1034  bool incrementVtA = true;
1035 
1036  for (sn = m_vtA; sn < ackSn && sn < m_vtS; sn++)
1037  {
1038  NS_LOG_LOGIC ("sn = " << sn);
1039 
1040  uint16_t seqNumberValue = sn.GetValue ();
1041 
1043  && (seqNumberValue == m_pollSn.GetValue ()))
1044  {
1046  }
1047 
1048  if (rlcAmHeader.IsNackPresent (sn))
1049  {
1050  NS_LOG_LOGIC ("sn " << sn << " is NACKed");
1051 
1052  incrementVtA = false;
1053 
1054  if (m_txedBuffer.at (seqNumberValue).m_pdu != 0)
1055  {
1056  NS_LOG_INFO ("Move SN = " << seqNumberValue << " to retxBuffer");
1057  m_retxBuffer.at (seqNumberValue).m_pdu = m_txedBuffer.at (seqNumberValue).m_pdu->Copy ();
1058  m_retxBuffer.at (seqNumberValue).m_retxCount = m_txedBuffer.at (seqNumberValue).m_retxCount;
1059  m_retxBuffer.at (seqNumberValue).m_waitingSince = m_txedBuffer.at (seqNumberValue).m_waitingSince;
1060  m_retxBufferSize += m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
1061 
1062  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
1063  m_txedBuffer.at (seqNumberValue).m_pdu = 0;
1064  m_txedBuffer.at (seqNumberValue).m_retxCount = 0;
1065  m_txedBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0);
1066  }
1067 
1068  NS_ASSERT (m_retxBuffer.at (seqNumberValue).m_pdu != 0);
1069 
1070  }
1071  else
1072  {
1073  NS_LOG_LOGIC ("sn " << sn << " is ACKed");
1074 
1075  if (m_txedBuffer.at (seqNumberValue).m_pdu)
1076  {
1077  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from txedBuffer");
1078  // NS_LOG_INFO ("m_txedBuffer( " << m_vtA << " )->GetSize = " << m_txedBuffer.at (m_vtA.GetValue ())->GetSize ());
1079  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
1080  m_txedBuffer.at (seqNumberValue).m_pdu = 0;
1081  m_txedBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0);
1082  NS_ASSERT (m_retxBuffer.at (seqNumberValue).m_pdu == 0);
1083  }
1084 
1085  if (m_retxBuffer.at (seqNumberValue).m_pdu)
1086  {
1087  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from retxBuffer");
1088  m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
1089  m_retxBuffer.at (seqNumberValue).m_pdu = 0;
1090  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
1091  m_retxBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0);
1092  }
1093 
1094  }
1095 
1096  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1097  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1098 
1099  if (incrementVtA)
1100  {
1101  m_vtA++;
1103  NS_LOG_INFO ("New VT(A) = " << m_vtA);
1107  ackSn.SetModulusBase (m_vtA);
1108  sn.SetModulusBase (m_vtA);
1109  }
1110 
1111  } // loop over SN : VT(A) <= SN < ACK SN
1112 
1113  return;
1114 
1115  }
1116  else
1117  {
1118  NS_LOG_WARN ("Wrong AM RLC PDU type");
1119  return;
1120  }
1121 
1122 }
1123 
1124 
1125 bool
1127 {
1128  NS_LOG_FUNCTION (this << seqNumber);
1129  NS_LOG_LOGIC ("Receiving Window: " <<
1130  m_vrR << " <= " << seqNumber << " <= " << m_vrMr);
1131 
1134  seqNumber.SetModulusBase (m_vrR);
1135 
1136  if ( (m_vrR <= seqNumber) && (seqNumber < m_vrMr ) )
1137  {
1138  NS_LOG_LOGIC (seqNumber << " is INSIDE the receiving window");
1139  return true;
1140  }
1141  else
1142  {
1143  NS_LOG_LOGIC (seqNumber << " is OUTSIDE the receiving window");
1144  return false;
1145  }
1146 }
1147 
1148 
1149 void
1151 {
1152  LteRlcAmHeader rlcAmHeader;
1153  RlcTag rlcTag;
1154  bool ret = packet->FindFirstMatchingByteTag (rlcTag);
1155  NS_ASSERT(ret);
1156  packet->RemoveHeader (rlcAmHeader);
1157  ret = packet->FindFirstMatchingByteTag (rlcTag);
1158  NS_ASSERT(!ret);
1159  uint8_t framingInfo = rlcAmHeader.GetFramingInfo ();
1160  SequenceNumber10 currSeqNumber = rlcAmHeader.GetSequenceNumber ();
1161  bool expectedSnLost;
1162 
1163  if ( currSeqNumber != m_expectedSeqNumber )
1164  {
1165  expectedSnLost = true;
1166  NS_LOG_LOGIC ("There are losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
1167  m_expectedSeqNumber = currSeqNumber + 1;
1168  }
1169  else
1170  {
1171  expectedSnLost = false;
1172  NS_LOG_LOGIC ("No losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
1174  }
1175 
1176  // Build list of SDUs
1177  uint8_t extensionBit;
1178  uint16_t lengthIndicator;
1179  do
1180  {
1181  extensionBit = rlcAmHeader.PopExtensionBit ();
1182  NS_LOG_LOGIC ("E = " << (uint16_t)extensionBit);
1183 
1184  if ( extensionBit == 0 )
1185  {
1186  m_sdusBuffer.push_back (packet);
1187  }
1188  else // extensionBit == 1
1189  {
1190  lengthIndicator = rlcAmHeader.PopLengthIndicator ();
1191  NS_LOG_LOGIC ("LI = " << lengthIndicator);
1192 
1193  // Check if there is enough data in the packet
1194  if ( lengthIndicator >= packet->GetSize () )
1195  {
1196  NS_LOG_LOGIC ("INTERNAL ERROR: Not enough data in the packet (" << packet->GetSize () << "). Needed LI=" << lengthIndicator);
1198  }
1199 
1200  // Split packet in two fragments
1201  Ptr<Packet> data_field = packet->CreateFragment (0, lengthIndicator);
1202  packet->RemoveAtStart (lengthIndicator);
1203 
1204  m_sdusBuffer.push_back (data_field);
1205  }
1206  }
1207  while ( extensionBit == 1 );
1208 
1209  std::list < Ptr<Packet> >::iterator it;
1210 
1211  // Current reassembling state
1212  if (m_reassemblingState == WAITING_S0_FULL) NS_LOG_LOGIC ("Reassembling State = 'WAITING_S0_FULL'");
1213  else if (m_reassemblingState == WAITING_SI_SF) NS_LOG_LOGIC ("Reassembling State = 'WAITING_SI_SF'");
1214  else NS_LOG_LOGIC ("Reassembling State = Unknown state");
1215 
1216 
1217  // Received framing Info
1218  NS_LOG_LOGIC ("Framing Info = " << (uint16_t)framingInfo);
1219  NS_LOG_LOGIC ("m_sdusBuffer = " << m_sdusBuffer.size ());
1220 
1221  // Reassemble the list of SDUs (when there is no losses)
1222  if (!expectedSnLost)
1223  {
1224  switch (m_reassemblingState)
1225  {
1226  case WAITING_S0_FULL:
1227  switch (framingInfo)
1228  {
1231 
1235  for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1236  {
1238  }
1239  m_sdusBuffer.clear ();
1240  break;
1241 
1244 
1248  while ( m_sdusBuffer.size () > 1 )
1249  {
1251  m_sdusBuffer.pop_front ();
1252  }
1253 
1257  m_keepS0 = m_sdusBuffer.front ();
1258  m_sdusBuffer.pop_front ();
1259  break;
1260 
1263  default:
1267  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1268  break;
1269  }
1270  break;
1271 
1272  case WAITING_SI_SF:
1273  switch (framingInfo)
1274  {
1277 
1281  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1282  m_sdusBuffer.pop_front ();
1284 
1288  while ( ! m_sdusBuffer.empty () )
1289  {
1291  m_sdusBuffer.pop_front ();
1292  }
1293  break;
1294 
1297 
1301  if ( m_sdusBuffer.size () == 1 )
1302  {
1303  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1304  m_sdusBuffer.pop_front ();
1305  }
1306  else // m_sdusBuffer.size () > 1
1307  {
1311  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1312  m_sdusBuffer.pop_front ();
1314 
1318  while ( m_sdusBuffer.size () > 1 )
1319  {
1321  m_sdusBuffer.pop_front ();
1322  }
1323 
1327  m_keepS0 = m_sdusBuffer.front ();
1328  m_sdusBuffer.pop_front ();
1329  }
1330  break;
1331 
1334  default:
1338  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1339  break;
1340  }
1341  break;
1342 
1343  default:
1344  NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1345  break;
1346  }
1347  }
1348  else // Reassemble the list of SDUs (when there are losses, i.e. the received SN is not the expected one)
1349  {
1350  switch (m_reassemblingState)
1351  {
1352  case WAITING_S0_FULL:
1353  switch (framingInfo)
1354  {
1357 
1361  for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1362  {
1364  }
1365  m_sdusBuffer.clear ();
1366  break;
1367 
1370 
1374  while ( m_sdusBuffer.size () > 1 )
1375  {
1377  m_sdusBuffer.pop_front ();
1378  }
1379 
1383  m_keepS0 = m_sdusBuffer.front ();
1384  m_sdusBuffer.pop_front ();
1385  break;
1386 
1389 
1393  m_sdusBuffer.pop_front ();
1394 
1398  while ( ! m_sdusBuffer.empty () )
1399  {
1401  m_sdusBuffer.pop_front ();
1402  }
1403  break;
1404 
1406  if ( m_sdusBuffer.size () == 1 )
1407  {
1409  }
1410  else
1411  {
1413  }
1414 
1418  m_sdusBuffer.pop_front ();
1419 
1420  if ( m_sdusBuffer.size () > 0 )
1421  {
1425  while ( m_sdusBuffer.size () > 1 )
1426  {
1428  m_sdusBuffer.pop_front ();
1429  }
1430 
1434  m_keepS0 = m_sdusBuffer.front ();
1435  m_sdusBuffer.pop_front ();
1436  }
1437  break;
1438 
1439  default:
1443  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1444  break;
1445  }
1446  break;
1447 
1448  case WAITING_SI_SF:
1449  switch (framingInfo)
1450  {
1453 
1457  m_keepS0 = 0;
1458 
1462  while ( ! m_sdusBuffer.empty () )
1463  {
1465  m_sdusBuffer.pop_front ();
1466  }
1467  break;
1468 
1471 
1475  m_keepS0 = 0;
1476 
1480  while ( m_sdusBuffer.size () > 1 )
1481  {
1483  m_sdusBuffer.pop_front ();
1484  }
1485 
1489  m_keepS0 = m_sdusBuffer.front ();
1490  m_sdusBuffer.pop_front ();
1491 
1492  break;
1493 
1496 
1500  m_keepS0 = 0;
1501 
1505  m_sdusBuffer.pop_front ();
1506 
1510  while ( ! m_sdusBuffer.empty () )
1511  {
1513  m_sdusBuffer.pop_front ();
1514  }
1515  break;
1516 
1518  if ( m_sdusBuffer.size () == 1 )
1519  {
1521  }
1522  else
1523  {
1525  }
1526 
1530  m_keepS0 = 0;
1531 
1535  m_sdusBuffer.pop_front ();
1536 
1537  if ( m_sdusBuffer.size () > 0 )
1538  {
1542  while ( m_sdusBuffer.size () > 1 )
1543  {
1545  m_sdusBuffer.pop_front ();
1546  }
1547 
1551  m_keepS0 = m_sdusBuffer.front ();
1552  m_sdusBuffer.pop_front ();
1553  }
1554  break;
1555 
1556  default:
1560  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1561  break;
1562  }
1563  break;
1564 
1565  default:
1566  NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1567  break;
1568  }
1569  }
1570 
1571 }
1572 
1573 void
1575 {
1576  NS_LOG_FUNCTION (this);
1577 
1578  Time now = Simulator::Now ();
1579 
1580  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
1581  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1582  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1583  NS_LOG_LOGIC ("VT(A) = " << m_vtA);
1584  NS_LOG_LOGIC ("VT(S) = " << m_vtS);
1585 
1586  // Transmission Queue HOL time
1587  Time txonQueueHolDelay (0);
1588  if ( m_txonBufferSize > 0 )
1589  {
1590  txonQueueHolDelay = now - m_txonBuffer.front ().m_waitingSince;
1591  }
1592 
1593  // Retransmission Queue HOL time
1594  Time retxQueueHolDelay;
1595  if ( m_retxBufferSize > 0 )
1596  {
1597  Time senderTimestamp;
1598  if (m_retxBuffer.at (m_vtA.GetValue ()).m_pdu != 0)
1599  {
1600  senderTimestamp = m_retxBuffer.at (m_vtA.GetValue ()).m_waitingSince;
1601  }
1602  else
1603  {
1604  senderTimestamp = m_txedBuffer.at (m_vtA.GetValue ()).m_waitingSince;
1605  }
1606  retxQueueHolDelay = now - senderTimestamp;
1607  }
1608  else
1609  {
1610  retxQueueHolDelay = Seconds (0);
1611  }
1612 
1614  r.rnti = m_rnti;
1615  r.lcid = m_lcid;
1617  r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
1619  r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
1620 
1622  {
1624  }
1625  else
1626  {
1627  r.statusPduSize = 0;
1628  }
1629 
1630  if ( r.txQueueSize != 0 || r.retxQueueSize != 0 || r.statusPduSize != 0 )
1631  {
1632  NS_LOG_INFO ("Send ReportBufferStatus: " << r.txQueueSize << ", " << r.txQueueHolDelay << ", "
1633  << r.retxQueueSize << ", " << r.retxQueueHolDelay << ", "
1634  << r.statusPduSize);
1636  }
1637  else
1638  {
1639  NS_LOG_INFO ("ReportBufferStatus don't needed");
1640  }
1641 }
1642 
1643 
1644 void
1646 {
1647  NS_LOG_FUNCTION (this);
1648  NS_LOG_LOGIC ("Reordering Timer has expired");
1649 
1650  // 5.1.3.2.4 Actions when t-Reordering expires
1651  // When t-Reordering expires, the receiving side of an AM RLC entity shall:
1652  // - update VR(MS) to the SN of the first AMD PDU with SN >= VR(X) for which not all byte segments
1653  // have been received;
1654  // - if VR(H) > VR(MS):
1655  // - start t-Reordering;
1656  // - set VR(X) to VR(H).
1657 
1658  m_vrMs = m_vrX;
1659  int firstVrMs = m_vrMs.GetValue ();
1660  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
1661  while ( it != m_rxonBuffer.end () &&
1662  it->second.m_pduComplete )
1663  {
1664  m_vrMs++;
1665  it = m_rxonBuffer.find (m_vrMs.GetValue ());
1666 
1667  NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in ExpireReorderingTimer");
1668  }
1669  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
1670 
1671  if ( m_vrH > m_vrMs )
1672  {
1673  NS_LOG_LOGIC ("Start reordering timer");
1676  m_vrX = m_vrH;
1677  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
1678  }
1679 
1680  // Section 5.2.3 Status Reporting:
1681  // - The receiving side of an AM RLC entity shall trigger a
1682  // STATUS report when T_reordering expires.
1683  m_statusPduRequested = true;
1684 }
1685 
1686 void
1688 {
1689  NS_LOG_FUNCTION (this);
1690  NS_LOG_LOGIC ("PollRetransmit Timer has expired");
1691 
1692  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
1693  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1694  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1695  NS_LOG_LOGIC ("statusPduRequested = " << m_statusPduRequested);
1696 
1698 
1699  // see section 5.2.2.3
1700  // note the difference between Rel 8 and Rel 11 specs; we follow Rel 11 here
1701  NS_ASSERT (m_vtS <= m_vtMs);
1702  if ((m_txonBufferSize == 0 && m_retxBufferSize == 0)
1703  || (m_vtS == m_vtMs))
1704  {
1705  NS_LOG_INFO ("txonBuffer and retxBuffer empty. Move PDUs up to = " << m_vtS.GetValue () - 1 << " to retxBuffer");
1706  for (SequenceNumber10 sn = m_vtA; sn < m_vtS; sn++)
1707  {
1708  bool pduAvailable = m_txedBuffer.at (sn.GetValue ()).m_pdu != 0;
1709 
1710  if ( pduAvailable )
1711  {
1712  uint16_t snValue = sn.GetValue ();
1713  NS_LOG_INFO ("Move PDU " << sn << " from txedBuffer to retxBuffer");
1714  m_retxBuffer.at (snValue).m_pdu = m_txedBuffer.at (snValue).m_pdu->Copy ();
1715  m_retxBuffer.at (snValue).m_retxCount = m_txedBuffer.at (snValue).m_retxCount;
1716  m_retxBuffer.at (snValue).m_waitingSince = m_txedBuffer.at (snValue).m_waitingSince;
1717  m_retxBufferSize += m_retxBuffer.at (snValue).m_pdu->GetSize ();
1718 
1719  m_txedBufferSize -= m_txedBuffer.at (snValue).m_pdu->GetSize ();
1720  m_txedBuffer.at (snValue).m_pdu = 0;
1721  m_txedBuffer.at (snValue).m_retxCount = 0;
1722  m_txedBuffer.at (snValue).m_waitingSince = MilliSeconds (0);
1723  }
1724  }
1725  }
1726 
1728 }
1729 
1730 
1731 void
1733 {
1734  NS_LOG_FUNCTION (this);
1735 }
1736 
1737 void
1739 {
1740  NS_LOG_LOGIC ("RBS Timer expires");
1741 
1743  {
1746  }
1747 }
1748 
1749 } // 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:846
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
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
virtual uint32_t GetSerializedSize() const
Definition: lte-rlc-tag.cc:60
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
EventId m_statusProhibitTimer
status prohibit timer
Definition: lte-rlc-am.h:205
#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:191
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:184
EventId m_rbsTimer
RBS timer.
Definition: lte-rlc-am.h:207
#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
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
#define min(a, b)
Definition: 80211b.c:42
uint32_t m_statusPduBufferSize
status PDU buffer size
Definition: lte-rlc-am.h:151
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:84
SequenceNumber10 m_vtS
VT(S)
Definition: lte-rlc-am.h:177
void DoReportBufferStatus()
Report buffer status.
Definition: lte-rlc-am.cc:1574
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:176
#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:204
void SetDataPdu(void)
Set data PDU function.
SequenceNumber10 m_vrMs
VR(MS)
Definition: lte-rlc-am.h:184
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
void SetPollingBit(uint8_t pollingBit)
Set polling bit function.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1070
Time m_pollRetransmitTimerValue
poll retransmit time value
Definition: lte-rlc-am.h:202
SequenceNumber10 m_vrR
VR(R)
Definition: lte-rlc-am.h:181
EventId m_reorderingTimer
reordering timer
Definition: lte-rlc-am.h:203
Time m_rbsTimerValue
RBS timer value.
Definition: lte-rlc-am.h:208
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:280
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:1126
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
EventId m_pollRetransmitTimer
Timers.
Definition: lte-rlc-am.h:201
void SetModulusBase(SequenceNumber10 modulusBase)
Set modulus base.
void ExpireRbsTimer(void)
Expire RBS timer.
Definition: lte-rlc-am.cc:1738
Parameters for LteMacSapProvider::ReportBufferStatus.
Definition: lte-mac-sap.h:67
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
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:146
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:232
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
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1389
std::map< uint16_t, PduBuffer > m_rxonBuffer
Reception buffer.
Definition: lte-rlc-am.h:162
AttributeValue implementation for Time.
Definition: nstime.h:1124
uint16_t m_pollPdu
poll PDU
Definition: lte-rlc-am.h:214
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:227
virtual void DoDispose()
Destructor implementation.
Definition: lte-rlc.cc:122
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:178
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
Definition: lte-rlc.h:166
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:169
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:367
uint16_t m_pollByte
poll byte
Definition: lte-rlc-am.h:215
SequenceNumber10 m_vrH
VR(H)
Definition: lte-rlc-am.h:185
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
bool m_pollRetransmitTimerJustExpired
poll retransmit timer just expired?
Definition: lte-rlc-am.h:218
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:182
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:1125
SequenceNumber10 m_vrX
VR(X)
Definition: lte-rlc-am.h:183
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:190
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:193
uint8_t GetFramingInfo() const
Get framing info.
uint32_t m_txedBufferSize
transmit ed buffer size
Definition: lte-rlc-am.h:148
Time m_statusProhibitTimerValue
status prohibit timer value
Definition: lte-rlc-am.h:206
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
virtual void DoNotifyHarqDeliveryFailure()
Notify HARQ delivery failure
Definition: lte-rlc-am.cc:748
uint16_t m_maxRetxThreshold
Configurable parameters.
Definition: lte-rlc-am.h:213
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:863
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:128
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:264
void ExpireStatusProhibitTimer(void)
method called when the T_status_prohibit timer expires
Definition: lte-rlc-am.cc:1732
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:359
void ExpirePollRetransmitTimer(void)
Expire poll retransmitter.
Definition: lte-rlc-am.cc:1687
SequenceNumber10 m_vtA
State variables.
Definition: lte-rlc-am.h:175
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:870
uint16_t PopLengthIndicator(void)
Pop length indicator function.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
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
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:164
void ReassembleAndDeliver(Ptr< Packet > packet)
Reassemble and deliver.
Definition: lte-rlc-am.cc:1150
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:196
bool m_txOpportunityForRetxAlwaysBigEnough
transmit opportunity for retransmit?
Definition: lte-rlc-am.h:217
virtual void TransmitPdu(TransmitPduParameters params)=0
send an RLC PDU to the MAC for transmission.
ReassemblingState_t m_reassemblingState
reassembling state
Definition: lte-rlc-am.h:226
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:147
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:819
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:150
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:1645
virtual void DoTransmitPdcpPdu(Ptr< Packet > p)
RLC SAP.
Definition: lte-rlc-am.cc:156
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:755
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