A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lte-rlc-am.cc
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Manuel Requena <manuel.requena@cttc.es>
19  */
20 
21 #include "ns3/simulator.h"
22 #include "ns3/log.h"
23 
24 #include "ns3/lte-rlc-am-header.h"
25 #include "ns3/lte-rlc-am.h"
26 #include "ns3/lte-rlc-sdu-status-tag.h"
27 #include "ns3/lte-rlc-tag.h"
28 
29 NS_LOG_COMPONENT_DEFINE ("LteRlcAm");
30 
31 namespace ns3 {
32 
33 NS_OBJECT_ENSURE_REGISTERED (LteRlcAm);
34 
35 LteRlcAm::LteRlcAm ()
36 {
37  NS_LOG_FUNCTION (this);
38 
39  // Buffers
40  m_txonBufferSize = 0;
41  m_retxBuffer.resize (1024);
42  m_retxBufferSize = 0;
43  m_txedBuffer.resize (1024);
44  m_txedBufferSize = 0;
45 
46  m_statusPduRequested = false;
47  m_statusPduBufferSize = 0;
48 
49  // State variables: transmitting side
50  m_windowSize = 512;
51  m_vtA = 0;
52  m_vtMs = m_vtA + m_windowSize;
53  m_vtS = 0;
54  m_pollSn = 0;
55 
56  // State variables: receiving side
57  m_vrR = 0;
58  m_vrMr = m_vrR + m_windowSize;
59  m_vrX = 0;
60  m_vrMs = 0;
61  m_vrH = 0;
62 
63  // Counters
64  m_pduWithoutPoll = 0;
65  m_byteWithoutPoll = 0;
66 
67  // Configurable parameters
69  m_pollPdu = 1;
70  m_pollByte = 50;
71 
72  // SDU reassembling process
73  m_reassemblingState = WAITING_S0_FULL;
75 
76  // Timers
77  m_pollRetransmitTimerValue = MilliSeconds (100);
78 }
79 
80 LteRlcAm::~LteRlcAm ()
81 {
82  NS_LOG_FUNCTION (this);
83 }
84 
85 TypeId
86 LteRlcAm::GetTypeId (void)
87 {
88  static TypeId tid = TypeId ("ns3::LteRlcAm")
89  .SetParent<LteRlc> ()
90  .AddConstructor<LteRlcAm> ()
91  .AddAttribute ("PollRetransmitTimer",
92  "Value of the t-PollRetransmit (See section 7.3 of 3GPP TS 36.322)",
93  TimeValue (MilliSeconds (100)),
94  MakeTimeAccessor (&LteRlcAm::m_pollRetransmitTimerValue),
95  MakeTimeChecker ())
96  ;
97  return tid;
98 }
99 
100 void
102 {
103  NS_LOG_FUNCTION (this);
105  m_reorderingTimer.Cancel ();
106  m_statusProhibitTimer.Cancel ();
107 
108  m_txonBuffer.clear ();
109  m_txonBufferSize = 0;
110  m_txedBuffer.clear ();
111  m_txedBufferSize = 0;
112  m_retxBuffer.clear ();
113  m_retxBufferSize = 0;
114  m_rxonBuffer.clear ();
115  m_sdusBuffer.clear ();
116  m_keepS0 = 0;
117  m_controlPduBuffer = 0;
118 
120 }
121 
122 
127 void
129 {
130  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
131 
133  Time now = Simulator::Now ();
134  RlcTag timeTag (now);
135  p->AddPacketTag (timeTag);
136 
139  LteRlcSduStatusTag tag;
140  tag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
141  p->AddPacketTag (tag);
142 
143  NS_LOG_LOGIC ("Txon Buffer: New packet added");
144  m_txonBuffer.push_back (p);
145  m_txonBufferSize += p->GetSize ();
146  NS_LOG_LOGIC ("NumOfBuffers = " << m_txonBuffer.size() );
147  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
148 
150  DoReportBufferStatus ();
151 }
152 
153 
158 void
159 LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer, uint8_t harqId)
160 {
161  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes);
162 
163  if (bytes < 4)
164  {
165  // Stingy MAC: In general, we need more bytes.
166  // There are a more restrictive test for each particular case
167  NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small");
168  NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small.\n"
169  << "Your MAC scheduler is assigned too few resource blocks.");
170  return;
171  }
172 
173  if ( m_statusPduRequested && ! m_statusProhibitTimer.IsRunning () )
174  {
175  if (bytes < m_statusPduBufferSize)
176  {
177  // Stingy MAC: We need more bytes for the STATUS PDU
178  NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")");
179  NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")\n"
180  << "Your MAC scheduler is assigned too few resource blocks.");
181  return;
182  }
183 
184  NS_LOG_LOGIC ("Sending STATUS PDU");
185 
186  Ptr<Packet> packet = Create<Packet> ();
187  LteRlcAmHeader rlcAmHeader;
188  rlcAmHeader.SetControlPdu (LteRlcAmHeader::STATUS_PDU);
189  rlcAmHeader.SetAckSn (m_vrR);
190 
191  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
192  packet->AddHeader (rlcAmHeader);
193 
194  // Send RLC PDU to MAC layer
196  params.pdu = packet;
197  params.rnti = m_rnti;
198  params.lcid = m_lcid;
199  params.layer = layer;
200  params.harqProcessId = harqId;
201 
202  m_macSapProvider->TransmitPdu (params);
203 
204  m_statusPduRequested = false;
205  m_statusPduBufferSize = 0;
206  return;
207  }
208  else if ( m_retxBufferSize > 0 )
209  {
210  NS_LOG_LOGIC ("Sending data from Retransmission Buffer");
211 
212  Ptr<Packet> packet = m_retxBuffer.at (m_vtA.GetValue ()).m_pdu->Copy ();
213 
214  if ( packet->GetSize () <= bytes )
215  {
216  LteRlcAmHeader rlcAmHeader;
217  packet->PeekHeader (rlcAmHeader);
218  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
219 
220  // Send RLC PDU to MAC layer
222  params.pdu = packet;
223  params.rnti = m_rnti;
224  params.lcid = m_lcid;
225  params.layer = layer;
226  params.harqProcessId = harqId;
227 
228  m_macSapProvider->TransmitPdu (params);
229  return;
230  }
231  else
232  {
233  NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for retransmission of the packet (size = " << packet->GetSize () << ")");
234  NS_LOG_LOGIC ("Waiting for bigger TxOpportunity");
235  return;
236  }
237  }
238  else if ( m_txonBufferSize > 0 )
239  {
240  if (bytes < 7)
241  {
242  // Stingy MAC: We need more bytes for new DATA PDUs.
243  NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for DATA PDU");
244  NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small for DATA PDU\n"
245  << "Your MAC scheduler is assigned too few resource blocks.");
246  return;
247  }
248 
249  NS_LOG_LOGIC ("Sending data from Transmission Buffer");
250  }
251  else if ( m_txedBufferSize > 0 )
252  {
253  NS_LOG_LOGIC ("Sending data from Transmitted Buffer");
254 
255  NS_LOG_INFO ("VT(A) = " << m_vtA);
256  NS_LOG_INFO ("VT(S) = " << m_vtS);
257 
258  uint16_t vta = m_vtA.GetValue ();
259  Ptr<Packet> packet = m_txedBuffer.at (vta)->Copy ();
260 
261  if ( packet->GetSize () <= bytes )
262  {
263  NS_LOG_INFO ("Move SN = " << vta << " to retxBuffer");
264  m_retxBuffer.at (vta).m_pdu = m_txedBuffer.at (vta)->Copy ();
265  m_retxBuffer.at (vta).m_retxCount = 1;
266  m_retxBufferSize += m_retxBuffer.at (vta).m_pdu->GetSize ();
267 
268  m_txedBufferSize -= m_txedBuffer.at (vta)->GetSize ();
269  m_txedBuffer.at (vta) = 0;
270 
271  LteRlcAmHeader rlcAmHeader;
272  packet->PeekHeader (rlcAmHeader);
273  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
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 = layer;
281  params.harqProcessId = harqId;
282 
283  m_macSapProvider->TransmitPdu (params);
284  return;
285  }
286  else
287  {
288  NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for retransmission of the packet (size = " << packet->GetSize () << ")");
289  NS_LOG_LOGIC ("Waiting for bigger TxOpportunity");
290  return;
291  }
292  }
293  else
294  {
295  NS_LOG_LOGIC ("No data pending");
296  return;
297  }
298 
299  //
300  //
301  // Build new PDU
302  //
303  //
304 
305  Ptr<Packet> packet = Create<Packet> ();
306  LteRlcAmHeader rlcAmHeader;
307  rlcAmHeader.SetDataPdu ();
308 
309  // Build Data field
310  uint32_t nextSegmentSize = bytes - 4;
311  uint32_t nextSegmentId = 1;
312  uint32_t dataFieldTotalSize = 0;
313  uint32_t dataFieldAddedSize = 0;
314  std::vector < Ptr<Packet> > dataField;
315 
316  // Remove the first packet from the transmission buffer.
317  // If only a segment of the packet is taken, then the remaining is given back later
318  if ( m_txonBuffer.size () == 0 )
319  {
320  NS_LOG_LOGIC ("No data pending");
321  return;
322  }
323 
324  NS_LOG_LOGIC ("SDUs in TxonBuffer = " << m_txonBuffer.size ());
325  NS_LOG_LOGIC ("First SDU buffer = " << *(m_txonBuffer.begin()));
326  NS_LOG_LOGIC ("First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
327  NS_LOG_LOGIC ("Next segment size = " << nextSegmentSize);
328  NS_LOG_LOGIC ("Remove SDU from TxBuffer");
329  Ptr<Packet> firstSegment = (*(m_txonBuffer.begin ()))->Copy ();
330  m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
331  NS_LOG_LOGIC ("txBufferSize = " << m_txonBufferSize );
332  m_txonBuffer.erase (m_txonBuffer.begin ());
333 
334  while ( firstSegment && (firstSegment->GetSize () > 0) && (nextSegmentSize > 0) )
335  {
336  NS_LOG_LOGIC ("WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
337  NS_LOG_LOGIC (" firstSegment size = " << firstSegment->GetSize ());
338  NS_LOG_LOGIC (" nextSegmentSize = " << nextSegmentSize);
339  if ( (firstSegment->GetSize () > nextSegmentSize) ||
340  // Segment larger than 2047 octets can only be mapped to the end of the Data field
341  (firstSegment->GetSize () > 2047)
342  )
343  {
344  // Take the minimum size, due to the 2047-bytes 3GPP exception
345  // This exception is due to the length of the LI field (just 11 bits)
346  uint32_t currSegmentSize = std::min (firstSegment->GetSize (), nextSegmentSize);
347 
348  NS_LOG_LOGIC (" IF ( firstSegment > nextSegmentSize ||");
349  NS_LOG_LOGIC (" firstSegment > 2047 )");
350 
351  // Segment txBuffer.FirstBuffer and
352  // Give back the remaining segment to the transmission buffer
353  Ptr<Packet> newSegment = firstSegment->CreateFragment (0, currSegmentSize);
354  NS_LOG_LOGIC (" newSegment size = " << newSegment->GetSize ());
355 
356  // Status tag of the new and remaining segments
357  // Note: This is the only place where a PDU is segmented and
358  // therefore its status can change
359  LteRlcSduStatusTag oldTag, newTag;
360  firstSegment->RemovePacketTag (oldTag);
361  newSegment->RemovePacketTag (newTag);
362  if (oldTag.GetStatus () == LteRlcSduStatusTag::FULL_SDU)
363  {
364  newTag.SetStatus (LteRlcSduStatusTag::FIRST_SEGMENT);
365  oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
366  }
367  else if (oldTag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT)
368  {
369  newTag.SetStatus (LteRlcSduStatusTag::MIDDLE_SEGMENT);
370  //oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
371  }
372 
373  // Give back the remaining segment to the transmission buffer
374  firstSegment->RemoveAtStart (currSegmentSize);
375  NS_LOG_LOGIC (" firstSegment size (after RemoveAtStart) = " << firstSegment->GetSize ());
376  if (firstSegment->GetSize () > 0)
377  {
378  firstSegment->AddPacketTag (oldTag);
379 
380  m_txonBuffer.insert (m_txonBuffer.begin (), firstSegment);
381  m_txonBufferSize += (*(m_txonBuffer.begin()))->GetSize ();
382 
383  NS_LOG_LOGIC (" Txon buffer: Give back the remaining segment");
384  NS_LOG_LOGIC (" Txon buffers = " << m_txonBuffer.size ());
385  NS_LOG_LOGIC (" Front buffer size = " << (*(m_txonBuffer.begin()))->GetSize ());
386  NS_LOG_LOGIC (" txonBufferSize = " << m_txonBufferSize );
387  }
388  else
389  {
390  // Whole segment was taken, so adjust tag
391  if (newTag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
392  {
393  newTag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
394  }
395  else if (newTag.GetStatus () == LteRlcSduStatusTag::MIDDLE_SEGMENT)
396  {
397  newTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
398  }
399  }
400  // Segment is completely taken or
401  // the remaining segment is given back to the transmission buffer
402  firstSegment = 0;
403 
404  // Put status tag once it has been adjusted
405  newSegment->AddPacketTag (newTag);
406 
407  // Add Segment to Data field
408  dataFieldAddedSize = newSegment->GetSize ();
409  dataFieldTotalSize += dataFieldAddedSize;
410  dataField.push_back (newSegment);
411  newSegment = 0;
412 
413  // ExtensionBit (Next_Segment - 1) = 0
414  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
415 
416  // no LengthIndicator for the last one
417 
418  nextSegmentSize -= dataFieldAddedSize;
419  nextSegmentId++;
420 
421  // nextSegmentSize MUST be zero (only if segment is smaller or equal to 2047)
422 
423  // (NO more segments) → exit
424  // break;
425  }
426  else if ( (nextSegmentSize - firstSegment->GetSize () <= 2) || (m_txonBuffer.size () == 0) )
427  {
428  NS_LOG_LOGIC (" IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
429 
430  // Add txBuffer.FirstBuffer to DataField
431  dataFieldAddedSize = firstSegment->GetSize ();
432  dataFieldTotalSize += dataFieldAddedSize;
433  dataField.push_back (firstSegment);
434  firstSegment = 0;
435 
436  // ExtensionBit (Next_Segment - 1) = 0
437  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
438 
439  // no LengthIndicator for the last one
440 
441  nextSegmentSize -= dataFieldAddedSize;
442  nextSegmentId++;
443 
444  NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
445  if (m_txonBuffer.size () > 0)
446  {
447  NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin()));
448  NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
449  }
450  NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
451 
452  // nextSegmentSize <= 2 (only if txBuffer is not empty)
453 
454  // (NO more segments) → exit
455  // break;
456  }
457  else // (firstSegment->GetSize () < m_nextSegmentSize) && (m_txBuffer.size () > 0)
458  {
459  NS_LOG_LOGIC (" IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
460  // Add txBuffer.FirstBuffer to DataField
461  dataFieldAddedSize = firstSegment->GetSize ();
462  dataFieldTotalSize += dataFieldAddedSize;
463  dataField.push_back (firstSegment);
464 
465  // ExtensionBit (Next_Segment - 1) = 1
466  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::E_LI_FIELDS_FOLLOWS);
467 
468  // LengthIndicator (Next_Segment) = txBuffer.FirstBuffer.length()
469  rlcAmHeader.PushLengthIndicator (firstSegment->GetSize ());
470 
471  nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
472  nextSegmentId++;
473 
474  NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
475  if (m_txonBuffer.size () > 0)
476  {
477  NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin()));
478  NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
479  }
480  NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
481  NS_LOG_LOGIC (" Remove SDU from TxBuffer");
482 
483  // (more segments)
484  firstSegment = (*(m_txonBuffer.begin ()))->Copy ();
485  m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
486  m_txonBuffer.erase (m_txonBuffer.begin ());
487  NS_LOG_LOGIC (" txBufferSize = " << m_txonBufferSize );
488  }
489 
490  }
491 
492  //
493  // Build RLC header
494  //
495 
496  rlcAmHeader.SetSequenceNumber ( m_vtS++ );
497  rlcAmHeader.SetResegmentationFlag (LteRlcAmHeader::PDU);
498  rlcAmHeader.SetLastSegmentFlag (LteRlcAmHeader::LAST_PDU_SEGMENT);
499  rlcAmHeader.SetSegmentOffset (0);
500 
501  // Calculate FramingInfo flag according the status of the SDUs in the DataField
502  uint8_t framingInfo = 0;
503  std::vector< Ptr<Packet> >::iterator it;
504  it = dataField.begin ();
505 
506  // FIRST SEGMENT
507  LteRlcSduStatusTag tag;
508  (*it)->RemovePacketTag (tag);
509  if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
510  (tag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
511  )
512  {
513  framingInfo |= LteRlcAmHeader::FIRST_BYTE;
514  }
515  else
516  {
517  framingInfo |= LteRlcAmHeader::NO_FIRST_BYTE;
518  }
519  (*it)->AddPacketTag (tag);
520 
521  // Add all SDUs (in DataField) to the Packet
522  while (it < dataField.end ())
523  {
524  NS_LOG_LOGIC ("Adding SDU/segment to packet, length = " << (*it)->GetSize ());
525 
526  packet->AddAtEnd (*it);
527  it++;
528  }
529 
530  // LAST SEGMENT (Note: There could be only one and be the first one)
531  it--;
532  (*it)->RemovePacketTag (tag);
533  if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
534  (tag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT) )
535  {
536  framingInfo |= LteRlcAmHeader::LAST_BYTE;
537  }
538  else
539  {
540  framingInfo |= LteRlcAmHeader::NO_LAST_BYTE;
541  }
542  (*it)->AddPacketTag (tag);
543 
544  // Set the FramingInfo flag after the calculation
545  rlcAmHeader.SetFramingInfo (framingInfo);
546 
547 
548  // Calculate the Polling Bit (5.2.2.1)
549  rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
550 
552  NS_LOG_LOGIC ("PDU_WITHOUT_POLL = " << m_pduWithoutPoll);
553  m_byteWithoutPoll += packet->GetSize ();
554  NS_LOG_LOGIC ("BYTE_WITHOUT_POLL = " << m_byteWithoutPoll);
555 
556  if ( (m_pduWithoutPoll >= m_pollPdu) || (m_byteWithoutPoll >= m_pollByte) ||
557  ( (m_txonBuffer.empty ()) && (m_retxBuffer.empty ()) ) ||
558  (m_vtS >= m_vtMs)
559  )
560  {
561  rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
562  m_pduWithoutPoll = 0;
563  m_byteWithoutPoll = 0;
564 
565  m_pollSn = m_vtS - 1;
566  NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn);
567 
569  {
570  NS_LOG_LOGIC ("Start PollRetransmit timer");
571 
572  m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
573  &LteRlcAm::ExpirePollRetransmitTimer, this);
574  }
575  else
576  {
577  NS_LOG_LOGIC ("Restart PollRetransmit timer");
578 
580  m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
581  &LteRlcAm::ExpirePollRetransmitTimer, this);
582  }
583  }
584 
585 
586  // Build RLC PDU with DataField and Header
587  NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader);
588  packet->AddHeader (rlcAmHeader);
589 
590  // Store new PDU into the Transmitted PDU Buffer
591  NS_LOG_LOGIC ("Put transmitted PDU in the txedBuffer");
592  m_txedBufferSize += packet->GetSize ();
593  m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ) = packet->Copy ();
594 
595  // Sender timestamp
596  RlcTag rlcTag (Simulator::Now ());
597  packet->AddByteTag (rlcTag);
598  m_txPdu (m_rnti, m_lcid, packet->GetSize ());
599 
600  // Send RLC PDU to MAC layer
602  params.pdu = packet;
603  params.rnti = m_rnti;
604  params.lcid = m_lcid;
605  params.layer = layer;
606  params.harqProcessId = harqId;
607 
608  m_macSapProvider->TransmitPdu (params);
609 }
610 
611 void
612 LteRlcAm::DoNotifyHarqDeliveryFailure ()
613 {
614  NS_LOG_FUNCTION (this);
615 }
616 
617 void
618 LteRlcAm::DoReceivePdu (Ptr<Packet> p)
619 {
620  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
621 
622  // Receiver timestamp
623  RlcTag rlcTag;
624  Time delay;
625  if (p->FindFirstMatchingByteTag (rlcTag))
626  {
627  delay = Simulator::Now() - rlcTag.GetSenderTimestamp ();
628  }
629  m_rxPdu (m_rnti, m_lcid, p->GetSize (), delay.GetNanoSeconds ());
630 
631  // Get RLC header parameters
632  LteRlcAmHeader rlcAmHeader;
633  p->PeekHeader (rlcAmHeader);
634  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
635 
636  if ( rlcAmHeader.IsDataPdu () )
637  {
638 
639  // 5.1.3.1 Transmit operations
640 
641  // 5.1.3.1.1 General
642  //
643  // The transmitting side of an AM RLC entity shall prioritize transmission of RLC control PDUs
644  // over RLC data PDUs. The transmitting side of an AM RLC entity shall prioritize retransmission
645  // of RLC data PDUs over transmission of new AMD PDUs.
646  //
647  // The transmitting side of an AM RLC entity shall maintain a transmitting window according to
648  // state variables VT(A) and VT(MS) as follows:
649  // - a SN falls within the transmitting window if VT(A) <= SN < VT(MS);
650  // - a SN falls outside of the transmitting window otherwise.
651  //
652  // The transmitting side of an AM RLC entity shall not deliver to lower layer any RLC data PDU
653  // whose SN falls outside of the transmitting window.
654  //
655  // When delivering a new AMD PDU to lower layer, the transmitting side of an AM RLC entity shall:
656  // - set the SN of the AMD PDU to VT(S), and then increment VT(S) by one.
657  //
658  // The transmitting side of an AM RLC entity can receive a positive acknowledgement (confirmation
659  // of successful reception by its peer AM RLC entity) for a RLC data PDU by the following:
660  // - STATUS PDU from its peer AM RLC entity.
661  //
662  // When receiving a positive acknowledgement for an AMD PDU with SN = VT(A), the transmitting
663  // side of an AM RLC entity shall:
664  // - set VT(A) equal to the SN of the AMD PDU with the smallest SN, whose SN falls within the
665  // range VT(A) <= SN <= VT(S) and for which a positive acknowledgment has not been received yet.
666  // - if positive acknowledgements have been received for all AMD PDUs associated with
667  // a transmitted RLC SDU:
668  // - send an indication to the upper layers of successful delivery of the RLC SDU.
669 
670 
671  // 5.1.3.2 Receive operations
672  //
673  // 5.1.3.2.1 General
674  //
675  // The receiving side of an AM RLC entity shall maintain a receiving window according to state
676  // variables VR(R) and VR(MR) as follows:
677  // - a SN falls within the receiving window if VR(R) <= SN < VR(MR);
678  // - a SN falls outside of the receiving window otherwise.
679  //
680  // When receiving a RLC data PDU from lower layer, the receiving side of an AM RLC entity shall:
681  // - either discard the received RLC data PDU or place it in the reception buffer (see sub clause 5.1.3.2.2);
682  // - if the received RLC data PDU was placed in the reception buffer:
683  // - 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).
684  //
685  // When t-Reordering expires, the receiving side of an AM RLC entity shall:
686  // - update state variables and start t-Reordering as needed (see sub clause 5.1.3.2.4).
687 
688 
689  SequenceNumber10 seqNumber = rlcAmHeader.GetSequenceNumber ();
690 
691  if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::SEGMENT )
692  {
693  NS_LOG_LOGIC ("PDU segment received ( SN = " << seqNumber << " )");
694  }
695  else if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::PDU )
696  {
697  NS_LOG_LOGIC ("PDU received ( SN = " << seqNumber << " )");
698  }
699  else
700  {
701  NS_ASSERT_MSG (false, "Neither a PDU segment nor a PDU received");
702  return ;
703  }
704 
705  // STATUS PDU is requested
706  if ( rlcAmHeader.GetPollingBit () == LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED )
707  {
708  m_statusPduRequested = true;
709  m_statusPduBufferSize = 4;
710 
711  if (! m_statusProhibitTimer.IsRunning ())
712  {
713  DoReportBufferStatus ();
714  }
715  }
716 
717  // 5.1.3.2.2 Actions when a RLC data PDU is received from lower layer
718  //
719  // When a RLC data PDU is received from lower layer, where the RLC data PDU contains
720  // byte segment numbers y to z of an AMD PDU with SN = x, the receiving side of an AM RLC entity shall:
721  // - if x falls outside of the receiving window; or
722  // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
723  // - discard the received RLC data PDU;
724  // - else:
725  // - place the received RLC data PDU in the reception buffer;
726  // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
727  // - discard the duplicate byte segments.
728 
729  NS_LOG_LOGIC ("VR(R) = " << m_vrR);
730  NS_LOG_LOGIC ("VR(MR) = " << m_vrMr);
731  NS_LOG_LOGIC ("VR(X) = " << m_vrX);
732  NS_LOG_LOGIC ("VR(MS) = " << m_vrMs);
733  NS_LOG_LOGIC ("VR(H) = " << m_vrH);
734 
735  // - if x falls outside of the receiving window; or
736  // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
737  if ( ! IsInsideReceivingWindow (seqNumber) )
738  {
739  NS_LOG_LOGIC ("PDU discarded");
740  return;
741  }
742  else
743  {
744  NS_LOG_LOGIC ("Place PDU in the reception buffer ( SN = " << seqNumber << " )");
745  m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.push_back (p);
746  m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete = true;
747 
748  // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
749  // - discard the duplicate byte segments.
750  }
751 
752  // 5.1.3.2.3 Actions when a RLC data PDU is placed in the reception buffer
753  // When a RLC data PDU with SN = x is placed in the reception buffer,
754  // the receiving side of an AM RLC entity shall:
755 
756  // - if x >= VR(H)
757  // - update VR(H) to x+ 1;
758 
759  if ( seqNumber >= m_vrH )
760  {
761  m_vrH = seqNumber + 1;
762  NS_LOG_LOGIC ("New VR(H) = " << m_vrH);
763  }
764 
765  // - if all byte segments of the AMD PDU with SN = VR(MS) are received:
766  // - update VR(MS) to the SN of the first AMD PDU with SN > current VR(MS) for
767  // which not all byte segments have been received;
768 
769  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
770  if ( it != m_rxonBuffer.end () &&
771  m_rxonBuffer[ m_vrMs.GetValue () ].m_pduComplete )
772  {
773  int firstVrMs = m_vrMs.GetValue ();
774  while ( it != m_rxonBuffer.end () &&
775  m_rxonBuffer[ m_vrMs.GetValue () ].m_pduComplete )
776  {
777  m_vrMs++;
778  it = m_rxonBuffer.find (m_vrMs.GetValue ());
779  NS_LOG_LOGIC ("Incr VR(MS) = " << m_vrMs);
780 
781  NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in RxonBuffer");
782  }
783  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
784  }
785 
786  // - if x = VR(R):
787  // - if all byte segments of the AMD PDU with SN = VR(R) are received:
788  // - 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;
789  // - update VR(MR) to the updated VR(R) + AM_Window_Size;
790  // - 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;
791 
792  if ( seqNumber == m_vrR )
793  {
794  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (seqNumber.GetValue ());
795  if ( it != m_rxonBuffer.end () &&
796  m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete )
797  {
798  it = m_rxonBuffer.find (m_vrR.GetValue ());
799  int firstVrR = m_vrR.GetValue ();
800  while ( it != m_rxonBuffer.end () &&
801  m_rxonBuffer[ m_vrR.GetValue () ].m_pduComplete )
802  {
803  NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << m_vrR << " )");
804  NS_ASSERT_MSG (m_rxonBuffer[ m_vrR.GetValue () ].m_byteSegments.size () == 1,
805  "Too many segments. PDU Reassembly process didn't work");
806  ReassembleAndDeliver (m_rxonBuffer[ m_vrR.GetValue () ].m_byteSegments.front ());
807  m_rxonBuffer.erase (m_vrR.GetValue ());
808 
809  m_vrR++;
810  it = m_rxonBuffer.find (m_vrR.GetValue ());
811 
812  NS_ASSERT_MSG (firstVrR != m_vrR.GetValue (), "Infinite loop in RxonBuffer");
813  }
814  NS_LOG_LOGIC ("New VR(R) = " << m_vrR);
815  m_vrMr = m_vrR + m_windowSize;
816  NS_LOG_LOGIC ("New VR(MR) = " << m_vrMr);
817  }
818 
819 // NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << seqNumber << " )");
820 // NS_ASSERT_MSG (m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.size () == 1,
821 // "Too many segments. PDU Reassembly process didn't work");
822 // ReassembleAndDeliver (m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.front ());
823 // m_rxonBuffer.erase (seqNumber.GetValue ());
824  }
825 
826  // - if t-Reordering is running:
827  // - if VR(X) = VR(R); or
828  // - if VR(X) falls outside of the receiving window and VR(X) is not equal to VR(MR):
829  // - stop and reset t-Reordering;
830 
831  if ( m_reorderingTimer.IsRunning () )
832  {
833  NS_LOG_LOGIC ("Reordering timer is running");
834  if ( (m_vrX == m_vrR) ||
835  ( (! IsInsideReceivingWindow (m_vrX)) && (m_vrX != m_vrMr) )
836  )
837  {
838  // TODO stop and reset the t-Reordering
839  NS_LOG_LOGIC ("Stop reordering timer");
840  m_reorderingTimer.Cancel ();
841  }
842  }
843 
844  // - if t-Reordering is not running (includes the case t-Reordering is stopped due to actions above):
845  // - if VR (H) > VR(R):
846  // - start t-Reordering;
847  // - set VR(X) to VR(H).
848 
849  if ( ! m_reorderingTimer.IsRunning () )
850  {
851  NS_LOG_LOGIC ("Reordering timer is not running");
852  if ( m_vrH > m_vrR )
853  {
854  NS_LOG_LOGIC ("Start reordering timer");
855  m_reorderingTimer = Simulator::Schedule (Time ("0.1s"),
857  m_vrX = m_vrH;
858  NS_LOG_LOGIC ("New VR(X) = " << m_vrX);
859  }
860  }
861 
862 
863 
864  // TODO To remove
865 
866  // 5.1.2.2.3 Actions when an UMD PDU is placed in the reception buffer
867  // When an UMD PDU with SN = x is placed in the reception buffer, the receiving UM RLC entity shall:
868 
869  // - if x falls outside of the reordering window:
870  // - update VR(UH) to x + 1;
871  // - reassemble RLC SDUs from any UMD PDUs with SN that falls outside of the reordering window, remove
872  // RLC headers when doing so and deliver the reassembled RLC SDUs to upper layer in ascending order of the
873  // RLC SN if not delivered before;
874  // - if VR(UR) falls outside of the reordering window:
875  // - set VR(UR) to (VR(UH) - UM_Window_Size);
876 
877 // if ( ! IsInsideReorderingWindow (seqNumber))
878 // {
879 // NS_LOG_LOGIC ("SN outside the reordering window");
880 //
881 // m_vrUh = seqNumber + 1;
882 // NS_LOG_LOGIC ("New VR(UH) = " << m_vrUh);
883 //
884 // ReassembleOutsideWindow ();
885 //
886 // if ( ! IsInsideReorderingWindow (m_vrUr) )
887 // {
888 // m_vrUr = m_vrUh - m_windowSize;
889 // NS_LOG_LOGIC ("VR(UR) outside the reordering window");
890 // NS_LOG_LOGIC ("New VR(UR) = " << m_vrUr);
891 // }
892 // }
893 
894  // - if the reception buffer contains an UMD PDU with SN = VR(UR):
895  // - update VR(UR) to the SN of the first UMD PDU with SN > current VR(UR) that has not been received;
896  // - reassemble RLC SDUs from any UMD PDUs with SN < updated VR(UR), remove RLC headers when doing
897  // so and deliver the reassembled RLC SDUs to upper layer in ascending order of the RLC SN if not delivered
898  // before;
899 
900 // if ( m_rxBuffer.count (m_vrUr) > 0 )
901 // {
902 // NS_LOG_LOGIC ("Reception buffer contains SN = " << m_vrUr);
903 //
904 // std::map <uint16_t, Ptr<Packet> >::iterator it;
905 // uint16_t newVrUr;
906 //
907 // it = m_rxBuffer.find (m_vrUr);
908 // newVrUr = (it->first) + 1;
909 // while ( m_rxBuffer.count (newVrUr) > 0 )
910 // {
911 // newVrUr++;
912 // }
913 // m_vrUr = newVrUr;
914 // NS_LOG_LOGIC ("New VR(UR) = " << m_vrUr);
915 //
916 // ReassembleSnLessThan (m_vrUr);
917 // }
918 
919  // - if t-Reordering is running:
920  // - if VR(UX) <= VR(UR); or
921  // - if VR(UX) falls outside of the reordering window and VR(UX) is not equal to VR(UH)::
922  // - stop and reset t-Reordering;
923 // if ( m_reorderingTimer.IsRunning () )
924 // {
925 // NS_LOG_LOGIC ("Reordering timer is running");
926 //
927 // if ( (m_vrUx <= m_vrUr) ||
928 // ((! IsInsideReorderingWindow (m_vrUx)) && (m_vrUx != m_vrUh)) )
929 // {
930 // NS_LOG_LOGIC ("Stop reordering timer");
931 // m_reorderingTimer.Cancel ();
932 // }
933 // }
934 
935  // - if t-Reordering is not running (includes the case when t-Reordering is stopped due to actions above):
936  // - if VR(UH) > VR(UR):
937  // - start t-Reordering;
938  // - set VR(UX) to VR(UH).
939 // if ( ! m_reorderingTimer.IsRunning () )
940 // {
941 // NS_LOG_LOGIC ("Reordering timer is not running");
942 //
943 // if ( m_vrUx > m_vrUr )
944 // {
945 // NS_LOG_LOGIC ("VR(UX) > VR(UR). " << m_vrUx << " > " << m_vrUr);
946 // NS_LOG_LOGIC ("Start reordering timer");
947 // m_reorderingTimer = Simulator::Schedule (Time ("1.0s"),
948 // &LteRlcAm::ExpireReorderingTimer ,this);
949 // m_vrUx = m_vrUh;
950 // NS_LOG_LOGIC ("New VR(UX) = " << m_vrUx);
951 // }
952 // }
953 
954  }
955  else if ( rlcAmHeader.IsControlPdu () )
956  {
957  NS_LOG_INFO ("Control AM RLC PDU");
958 
959  SequenceNumber10 ackSn = rlcAmHeader.GetAckSn ();
960 // SequenceNumber10 seqNumber = m_vtA;
961 
962  NS_LOG_INFO ("ackSn = " << ackSn);
963  NS_LOG_INFO ("VT(A) = " << m_vtA);
964  NS_LOG_INFO ("VT(S) = " << m_vtS);
965  while (m_vtA < ackSn && m_vtA < m_vtS)
966  {
967 // NS_LOG_INFO ("seqNumber = " << seqNumber);
968 // NS_LOG_INFO ("m_txedBuffer( VT(A) ).size = " << m_txedBuffer.size ());
969 
970  uint16_t seqNumberValue = m_vtA.GetValue ();
971  if (m_txedBuffer.at (seqNumberValue))
972  {
973  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from txedBuffer");
974 // NS_LOG_INFO ("m_txedBuffer( " << m_vtA << " )->GetSize = " << m_txedBuffer.at (m_vtA.GetValue ())->GetSize ());
975  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
976  m_txedBuffer.at (seqNumberValue) = 0;
977  }
978 
979  if (m_retxBuffer.at (seqNumberValue).m_pdu)
980  {
981  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from retxBuffer");
982  m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
983  m_retxBuffer.at (seqNumberValue).m_pdu = 0;
984  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
985  }
986 
987  m_vtA++;
988  }
989 
990  NS_LOG_INFO ("New VT(A) = " << m_vtA);
991 
992  SequenceNumber10 seqNumber = m_vtA;
993  uint16_t seqNumberValue;
994  while (seqNumber < m_vtS)
995  {
996  seqNumberValue = seqNumber.GetValue ();
997  if (m_txedBuffer.at (seqNumberValue))
998  {
999  NS_LOG_INFO ("Move SN = " << seqNumberValue << " to retxBuffer");
1000  m_retxBuffer.at (seqNumberValue).m_pdu = m_txedBuffer.at (seqNumberValue)->Copy ();
1001  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
1002  m_retxBufferSize += m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
1003 
1004  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
1005  m_txedBuffer.at (seqNumberValue) = 0;
1006  }
1007  else if (m_retxBuffer.at (seqNumberValue).m_pdu)
1008  {
1009  m_retxBuffer.at (seqNumberValue).m_retxCount++;
1010  NS_LOG_INFO ("Incr RETX_COUNT for SN = " << seqNumberValue);
1011  if (m_retxBuffer.at (seqNumberValue).m_retxCount >= m_maxRetxThreshold)
1012  {
1013  NS_LOG_INFO ("Max RETX_COUNT for SN = " << seqNumberValue);
1014  }
1015  }
1016 
1017  seqNumber++;
1018  }
1019 
1020  return;
1021  }
1022  else
1023  {
1024  NS_LOG_WARN ("Wrong AM RLC PDU type");
1025  return;
1026  }
1027 
1028 }
1029 
1030 
1031 bool
1032 LteRlcAm::IsInsideReceivingWindow (SequenceNumber10 seqNumber)
1033 {
1034  NS_LOG_FUNCTION (this << seqNumber);
1035  NS_LOG_LOGIC ("Receiving Window: " <<
1036  m_vrR << " <= " << seqNumber << " <= " << m_vrMr);
1037 
1038  m_vrR.SetModulusBase (m_vrR);
1039  m_vrMr.SetModulusBase (m_vrR);
1040  seqNumber.SetModulusBase (m_vrR);
1041 
1042  if ( (m_vrR <= seqNumber) && (seqNumber < m_vrMr ) )
1043  {
1044  NS_LOG_LOGIC (seqNumber << " is INSIDE the receiving window");
1045  return true;
1046  }
1047  else
1048  {
1049  NS_LOG_LOGIC (seqNumber << " is OUTSIDE the receiving window");
1050  return false;
1051  }
1052 }
1053 
1054 
1055 void
1057 {
1058  LteRlcAmHeader rlcAmHeader;
1059  packet->RemoveHeader (rlcAmHeader);
1060  uint8_t framingInfo = rlcAmHeader.GetFramingInfo ();
1061  SequenceNumber10 currSeqNumber = rlcAmHeader.GetSequenceNumber ();
1062  bool expectedSnLost;
1063 
1064  if ( currSeqNumber != m_expectedSeqNumber )
1065  {
1066  expectedSnLost = true;
1067  NS_LOG_LOGIC ("There are losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
1068  m_expectedSeqNumber = currSeqNumber + 1;
1069  }
1070  else
1071  {
1072  expectedSnLost = false;
1073  NS_LOG_LOGIC ("No losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
1075  }
1076 
1077  // Build list of SDUs
1078  uint8_t extensionBit;
1079  uint16_t lengthIndicator;
1080  do
1081  {
1082  extensionBit = rlcAmHeader.PopExtensionBit ();
1083  NS_LOG_LOGIC ("E = " << (uint16_t)extensionBit);
1084 
1085  if ( extensionBit == 0 )
1086  {
1087  m_sdusBuffer.push_back (packet);
1088  }
1089  else // extensionBit == 1
1090  {
1091  lengthIndicator = rlcAmHeader.PopLengthIndicator ();
1092  NS_LOG_LOGIC ("LI = " << lengthIndicator);
1093 
1094  // Check if there is enough data in the packet
1095  if ( lengthIndicator >= packet->GetSize () )
1096  {
1097  NS_LOG_LOGIC ("INTERNAL ERROR: Not enough data in the packet (" << packet->GetSize () << "). Needed LI=" << lengthIndicator);
1098  // TODO What to do in this case? Discard packet and continue? Or Assert?
1099  }
1100 
1101  // Split packet in two fragments
1102  Ptr<Packet> data_field = packet->CreateFragment (0, lengthIndicator);
1103  packet->RemoveAtStart (lengthIndicator);
1104 
1105  m_sdusBuffer.push_back (data_field);
1106  }
1107  }
1108  while ( extensionBit == 1 );
1109 
1110  std::list < Ptr<Packet> >::iterator it;
1111 
1112  // Current reassembling state
1113  if (m_reassemblingState == WAITING_S0_FULL) NS_LOG_LOGIC ("Reassembling State = 'WAITING_S0_FULL'");
1114  else if (m_reassemblingState == WAITING_SI_SF) NS_LOG_LOGIC ("Reassembling State = 'WAITING_SI_SF'");
1115  else NS_LOG_LOGIC ("Reassembling State = Unknown state");
1116 
1117  // Received framing Info
1118  NS_LOG_LOGIC ("Framing Info = " << (uint16_t)framingInfo);
1119  NS_LOG_LOGIC ("m_sdusBuffer = " << m_sdusBuffer.size ());
1120 
1121  // Reassemble the list of SDUs (when there is no losses)
1122  if (!expectedSnLost)
1123  {
1124  switch (m_reassemblingState)
1125  {
1126  case WAITING_S0_FULL:
1127  switch (framingInfo)
1128  {
1129  case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1130  m_reassemblingState = WAITING_S0_FULL;
1131 
1135  for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1136  {
1137  m_rlcSapUser->ReceivePdcpPdu (*it);
1138  }
1139  m_sdusBuffer.clear ();
1140  break;
1141 
1142  case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1143  m_reassemblingState = WAITING_SI_SF;
1144 
1148  while ( m_sdusBuffer.size () > 1 )
1149  {
1150  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1151  m_sdusBuffer.pop_front ();
1152  }
1153 
1157  m_keepS0 = m_sdusBuffer.front ();
1158  m_sdusBuffer.pop_front ();
1159  break;
1160 
1161  case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1162  case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1163  default:
1167  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1168  break;
1169  }
1170  break;
1171 
1172  case WAITING_SI_SF:
1173  switch (framingInfo)
1174  {
1175  case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1176  m_reassemblingState = WAITING_S0_FULL;
1177 
1181  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1182  m_sdusBuffer.pop_front ();
1183  m_rlcSapUser->ReceivePdcpPdu (m_keepS0);
1184 
1188  while ( ! m_sdusBuffer.empty () )
1189  {
1190  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1191  m_sdusBuffer.pop_front ();
1192  }
1193  break;
1194 
1195  case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1196  m_reassemblingState = WAITING_SI_SF;
1197 
1201  if ( m_sdusBuffer.size () == 1 )
1202  {
1203  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1204  m_sdusBuffer.pop_front ();
1205  }
1206  else // m_sdusBuffer.size () > 1
1207  {
1211  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1212  m_sdusBuffer.pop_front ();
1213  m_rlcSapUser->ReceivePdcpPdu (m_keepS0);
1214 
1218  while ( m_sdusBuffer.size () > 1 )
1219  {
1220  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1221  m_sdusBuffer.pop_front ();
1222  }
1223 
1227  m_keepS0 = m_sdusBuffer.front ();
1228  m_sdusBuffer.pop_front ();
1229  }
1230  break;
1231 
1232  case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1233  case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1234  default:
1238  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1239  break;
1240  }
1241  break;
1242 
1243  default:
1244  NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1245  break;
1246  }
1247  }
1248  else // Reassemble the list of SDUs (when there are losses, i.e. the received SN is not the expected one)
1249  {
1250  switch (m_reassemblingState)
1251  {
1252  case WAITING_S0_FULL:
1253  switch (framingInfo)
1254  {
1255  case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1256  m_reassemblingState = WAITING_S0_FULL;
1257 
1261  for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1262  {
1263  m_rlcSapUser->ReceivePdcpPdu (*it);
1264  }
1265  m_sdusBuffer.clear ();
1266  break;
1267 
1268  case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1269  m_reassemblingState = WAITING_SI_SF;
1270 
1274  while ( m_sdusBuffer.size () > 1 )
1275  {
1276  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1277  m_sdusBuffer.pop_front ();
1278  }
1279 
1283  m_keepS0 = m_sdusBuffer.front ();
1284  m_sdusBuffer.pop_front ();
1285  break;
1286 
1287  case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1288  m_reassemblingState = WAITING_S0_FULL;
1289 
1293  m_sdusBuffer.pop_front ();
1294 
1298  while ( ! m_sdusBuffer.empty () )
1299  {
1300  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1301  m_sdusBuffer.pop_front ();
1302  }
1303  break;
1304 
1305  case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1306  if ( m_sdusBuffer.size () == 1 )
1307  {
1308  m_reassemblingState = WAITING_S0_FULL;
1309  }
1310  else
1311  {
1312  m_reassemblingState = WAITING_SI_SF;
1313  }
1314 
1318  m_sdusBuffer.pop_front ();
1319 
1320  if ( m_sdusBuffer.size () > 0 )
1321  {
1325  while ( m_sdusBuffer.size () > 1 )
1326  {
1327  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1328  m_sdusBuffer.pop_front ();
1329  }
1330 
1334  m_keepS0 = m_sdusBuffer.front ();
1335  m_sdusBuffer.pop_front ();
1336  }
1337  break;
1338 
1339  default:
1343  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1344  break;
1345  }
1346  break;
1347 
1348  case WAITING_SI_SF:
1349  switch (framingInfo)
1350  {
1351  case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1352  m_reassemblingState = WAITING_S0_FULL;
1353 
1357  m_keepS0 = 0;
1358 
1362  while ( ! m_sdusBuffer.empty () )
1363  {
1364  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1365  m_sdusBuffer.pop_front ();
1366  }
1367  break;
1368 
1369  case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1370  m_reassemblingState = WAITING_SI_SF;
1371 
1375  m_keepS0 = 0;
1376 
1380  while ( m_sdusBuffer.size () > 1 )
1381  {
1382  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1383  m_sdusBuffer.pop_front ();
1384  }
1385 
1389  m_keepS0 = m_sdusBuffer.front ();
1390  m_sdusBuffer.pop_front ();
1391 
1392  break;
1393 
1394  case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1395  m_reassemblingState = WAITING_S0_FULL;
1396 
1400  m_keepS0 = 0;
1401 
1405  m_sdusBuffer.pop_front ();
1406 
1410  while ( ! m_sdusBuffer.empty () )
1411  {
1412  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1413  m_sdusBuffer.pop_front ();
1414  }
1415  break;
1416 
1417  case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1418  if ( m_sdusBuffer.size () == 1 )
1419  {
1420  m_reassemblingState = WAITING_S0_FULL;
1421  }
1422  else
1423  {
1424  m_reassemblingState = WAITING_SI_SF;
1425  }
1426 
1430  m_keepS0 = 0;
1431 
1435  m_sdusBuffer.pop_front ();
1436 
1437  if ( m_sdusBuffer.size () > 0 )
1438  {
1442  while ( m_sdusBuffer.size () > 1 )
1443  {
1444  m_rlcSapUser->ReceivePdcpPdu (m_sdusBuffer.front ());
1445  m_sdusBuffer.pop_front ();
1446  }
1447 
1451  m_keepS0 = m_sdusBuffer.front ();
1452  m_sdusBuffer.pop_front ();
1453  }
1454  break;
1455 
1456  default:
1460  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1461  break;
1462  }
1463  break;
1464 
1465  default:
1466  NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1467  break;
1468  }
1469  }
1470 
1471 }
1472 
1473 
1474 // TODO To remove
1475 // void
1476 // LteRlcAm::ReassembleOutsideWindow (void)
1477 // {
1478 // NS_LOG_LOGIC ("Reassemble Outside Window");
1479 //
1480 // std::map <uint16_t, Ptr<Packet> >::iterator it;
1481 // it = m_rxBuffer.begin ();
1482 //
1483 // while ( (it != m_rxBuffer.end ()) && ! IsInsideReorderingWindow (it->first) )
1484 // {
1485 // NS_LOG_LOGIC ("SN = " << it->first);
1486 //
1487 // // Reassemble RLC SDUs and deliver the PDCP PDU to upper layer
1488 // ReassembleAndDeliver (it->second);
1489 // m_rxBuffer.erase (it);
1490 // it++;
1491 // }
1492 //
1493 // if (it != m_rxBuffer.end ())
1494 // {
1495 // NS_LOG_LOGIC ("(SN = " << it->first << ") is inside the reordering window");
1496 // }
1497 // }
1498 
1499 
1500 // TODO To remove
1501 // void
1502 // LteRlcAm::ReassembleSnLessThan (uint16_t seqNumber)
1503 // {
1504 // NS_LOG_LOGIC ("Reassemble SN < updated VR(UR)" );
1505 //
1506 // std::map <uint16_t, Ptr<Packet> >::iterator it;
1507 // it = m_rxBuffer.begin ();
1508 //
1509 // while ( (it != m_rxBuffer.end ()) && (it->first < seqNumber) )
1510 // {
1511 // NS_LOG_LOGIC ("SN = " << it->first);
1512 //
1513 // // Reassemble RLC SDUs and deliver the PDCP PDU to upper layer
1514 // ReassembleAndDeliver (it->second);
1515 // m_rxBuffer.erase (it);
1516 // it++;
1517 // }
1518 //
1519 // if (it != m_rxBuffer.end ())
1520 // {
1521 // NS_LOG_LOGIC ("(SN = " << it->first << ") >= " << m_vrUr);
1522 // }
1523 // }
1524 
1525 
1526 void
1527 LteRlcAm::DoReportBufferStatus (void)
1528 {
1529  NS_LOG_FUNCTION (this);
1530 
1531  Time now = Simulator::Now ();
1532 
1533  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
1534  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1535  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1536  NS_LOG_LOGIC ("VT(A) = " << m_vtA);
1537  NS_LOG_LOGIC ("VT(S) = " << m_vtS);
1538 
1539  // Transmission Queue HOL time
1540  Time txonQueueHolDelay (0);
1541  if ( m_txonBufferSize > 0 )
1542  {
1543  RlcTag txonQueueHolTimeTag;
1544  m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
1545  txonQueueHolDelay = now - txonQueueHolTimeTag.GetSenderTimestamp ();
1546  }
1547 
1548  // Retransmission Queue HOL time
1549  Time retxQueueHolDelay (0);
1550  RlcTag retxQueueHolTimeTag;
1551  if ( m_retxBufferSize > 0 )
1552  {
1553  m_retxBuffer.at (m_vtA.GetValue ()).m_pdu->PeekPacketTag (retxQueueHolTimeTag);
1554  retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
1555  }
1556  else if ( m_txedBufferSize > 0 )
1557  {
1558  m_txedBuffer.at (m_vtA.GetValue ())->PeekPacketTag (retxQueueHolTimeTag);
1559  retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
1560  }
1561 
1562  LteMacSapProvider::ReportBufferStatusParameters r;
1563  r.rnti = m_rnti;
1564  r.lcid = m_lcid;
1565  r.txQueueSize = m_txonBufferSize;
1566  r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
1567  r.retxQueueSize = m_retxBufferSize + m_txedBufferSize;
1568  r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
1569 
1570  if ( m_statusPduRequested && ! m_statusProhibitTimer.IsRunning () )
1571  {
1572  r.statusPduSize = m_statusPduBufferSize;
1573  }
1574  else
1575  {
1576  r.statusPduSize = 0;
1577  }
1578 
1579  if ( r.txQueueSize != 0 || r.retxQueueSize != 0 || r.statusPduSize != 0 )
1580  {
1581  NS_LOG_INFO ("Send ReportBufferStatus: " << r.txQueueSize << ", " << r.txQueueHolDelay << ", "
1582  << r.retxQueueSize << ", " << r.retxQueueHolDelay << ", "
1583  << r.statusPduSize);
1584  m_macSapProvider->ReportBufferStatus (r);
1585  }
1586  else
1587  {
1588  NS_LOG_INFO ("ReportBufferStatus don't needed");
1589  }
1590 }
1591 
1592 
1593 void
1595 {
1596  NS_LOG_FUNCTION (this);
1597  NS_LOG_LOGIC ("Reordering Timer has expired");
1598 
1599  // 5.1.3.2.4 Actions when t-Reordering expires
1600  // When t-Reordering expires, the receiving side of an AM RLC entity shall:
1601  // - update VR(MS) to the SN of the first AMD PDU with SN >= VR(X) for which not all byte segments
1602  // have been received;
1603  // - if VR(H) > VR(MS):
1604  // - start t-Reordering;
1605  // - set VR(X) to VR(H).
1606 
1607  m_vrMs = m_vrX;
1608  int firstVrMs = m_vrMs.GetValue ();
1609  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
1610  while ( it != m_rxonBuffer.end () &&
1611  m_rxonBuffer[ m_vrMs.GetValue () ].m_pduComplete )
1612  {
1613  m_vrMs++;
1614  it = m_rxonBuffer.find (m_vrMs.GetValue ());
1615 
1616  NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in ExpireReorderingTimer");
1617  }
1618  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
1619 
1620  if ( m_vrH > m_vrMs )
1621  {
1622  NS_LOG_LOGIC ("Start reordering timer");
1623  m_reorderingTimer = Simulator::Schedule (Time ("0.1s"),
1625  m_vrX = m_vrH;
1626  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
1627  }
1628 }
1629 
1630 void
1631 LteRlcAm::ExpirePollRetransmitTimer (void)
1632 {
1633  NS_LOG_FUNCTION (this);
1634  NS_LOG_LOGIC ("PollRetransmit Timer has expired");
1635 
1636  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
1637  NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
1638  NS_LOG_LOGIC ("txedBufferSize = " << m_txedBufferSize);
1639  NS_LOG_LOGIC ("statusPduRequested = " << m_statusPduRequested);
1640 
1641  DoReportBufferStatus ();
1642 }
1643 
1644 
1645 
1646 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:285
TracedCallback< uint16_t, uint8_t, uint32_t > m_txPdu
Definition: lte-rlc.h:128
keep track of time unit.
Definition: nstime.h:149
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
virtual void DoNotifyTxOpportunity(uint32_t bytes, uint8_t layer, uint8_t harqId)
Definition: lte-rlc-am.cc:159
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:868
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
uint32_t GetSize(void) const
Definition: packet.h:620
#define NS_LOG_INFO(msg)
Definition: log.h:264
bool IsRunning(void) const
Definition: event-id.cc:59
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
EventId m_pollRetransmitTimer
Definition: lte-rlc-am.h:142
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Definition: packet.cc:243
void AddAtEnd(Ptr< const Packet > packet)
Definition: packet.cc:334
SequenceNumber10 m_expectedSeqNumber
Definition: lte-rlc-am.h:166
void RemoveAtStart(uint32_t size)
Definition: packet.cc:370
virtual void ReceivePdcpPdu(Ptr< Packet > p)=0
virtual void DoDispose()
Definition: lte-rlc.cc:117
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
uint32_t PeekHeader(Header &header) const
Definition: packet.cc:294
The packet header for the AM Radio Link Control (RLC) protocol packets.
Time GetSenderTimestamp(void) const
Definition: lte-rlc-tag.h:59
uint32_t m_pduWithoutPoll
Definition: lte-rlc-am.h:131
static Time Now(void)
Definition: simulator.cc:179
uint16_t m_maxRetxThreshold
Definition: lte-rlc-am.h:150
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
This class implements a tag that carries the status of a RLC SDU for the fragmentation process Status...
virtual void DoDispose()
Definition: lte-rlc-am.cc:101
#define NS_LOG_WARN(msg)
Definition: log.h:246
SequenceNumber10 m_vtA
Definition: lte-rlc-am.h:116
bool RemovePacketTag(Tag &tag)
Definition: packet.cc:874
void Cancel(void)
Definition: event-id.cc:47
virtual void ReportBufferStatus(ReportBufferStatusParameters params)=0
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
Definition: nstime.h:601
TracedCallback< uint16_t, uint8_t, uint32_t, uint64_t > m_rxPdu
Definition: lte-rlc.h:132
void ReassembleAndDeliver(Ptr< Packet > packet)
Definition: lte-rlc-am.cc:1056
uint16_t m_windowSize
Definition: lte-rlc-am.h:137
virtual void TransmitPdu(TransmitPduParameters params)=0
void ExpireReorderingTimer(void)
Definition: lte-rlc-am.cc:1594
virtual void DoTransmitPdcpPdu(Ptr< Packet > p)
Definition: lte-rlc-am.cc:128
void AddHeader(const Header &header)
Definition: packet.cc:270
void AddByteTag(const Tag &tag) const
Definition: packet.cc:833