A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  */
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 
34 
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;
48 
49  // State variables: transmitting side
50  m_windowSize = 512;
51  m_vtA = 0;
53  m_vtS = 0;
54  m_pollSn = 0;
55 
56  // State variables: receiving side
57  m_vrR = 0;
59  m_vrX = 0;
60  m_vrMs = 0;
61  m_vrH = 0;
62 
63  // Counters
64  m_pduWithoutPoll = 0;
66 
67  // Configurable parameters
69  m_pollPdu = 1;
70  m_pollByte = 50;
71 
72  // SDU reassembling process
75 
77 }
78 
80 {
81 }
82 
83 TypeId
85 {
86  static TypeId tid = TypeId ("ns3::LteRlcAm")
87  .SetParent<LteRlc> ()
88  .AddConstructor<LteRlcAm> ()
89  ;
90  return tid;
91 }
92 
93 
98 void
100 {
101  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
102 
104  Time now = Simulator::Now ();
105  RlcTag timeTag (now);
106  p->AddPacketTag (timeTag);
107 
110  LteRlcSduStatusTag tag;
112  p->AddPacketTag (tag);
113 
114  NS_LOG_LOGIC ("Txon Buffer: New packet added");
115  m_txonBuffer.push_back (p);
116  m_txonBufferSize += p->GetSize ();
117  NS_LOG_LOGIC ("NumOfBuffers = " << m_txonBuffer.size() );
118  NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize);
119 
122  // Transmission Queue HOL time
123  RlcTag txonQueueHolTimeTag;
124  m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
125  Time txonQueueHolDelay = now - txonQueueHolTimeTag.GetSenderTimestamp ();
126 
127  // Retransmission Queue HOL time
128  RlcTag retxQueueHolTimeTag;
129  Time retxQueueHolDelay (0);
130  if ( m_retxBufferSize )
131  {
132 //MRE m_retxBuffer.front ().m_pdu->PeekPacketTag (retxQueueHolTimeTag);
133  retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
134  }
135 
137  r.rnti = m_rnti;
138  r.lcid = m_lcid;
140  r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
142  r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
143 
145  {
147  }
148  else
149  {
150  r.statusPduSize = 0;
151  }
152 
153  NS_LOG_INFO ("Send ReportBufferStatus: " << r.txQueueSize << ", " << r.txQueueHolDelay << ", "
154  << r.retxQueueSize << ", " << r.retxQueueHolDelay << ", "
155  << r.statusPduSize);
157 }
158 
159 
164 void
165 LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer)
166 {
167  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes);
168 
169  if (bytes <= 2)
170  {
171  // Stingy MAC: Header fix part is 2 bytes, we need more bytes for the data
172  NS_LOG_LOGIC ("TX opportunity too small = " << bytes);
173  return;
174  }
175 
177  {
178  NS_LOG_LOGIC ("Sending STATUS PDU");
179 
180  Ptr<Packet> packet = Create<Packet> ();
181  LteRlcAmHeader rlcAmHeader;
183  rlcAmHeader.SetAckSn (m_vrR);
184 
185  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
186  packet->AddHeader (rlcAmHeader);
187 
188  // Send RLC PDU to MAC layer
190  params.pdu = packet;
191  params.rnti = m_rnti;
192  params.lcid = m_lcid;
193 
194  m_macSapProvider->TransmitPdu (params);
195  return;
196  }
197  else if ( m_retxBufferSize > 0 )
198  {
199  NS_LOG_LOGIC ("Sending data from Retransmission Buffer");
200 
201  Ptr<Packet> packet = m_retxBuffer.at (m_vtA.GetValue ()).m_pdu->Copy ();
202 
203  if ( packet->GetSize () <= bytes )
204  {
205  LteRlcAmHeader rlcAmHeader;
206  packet->PeekHeader (rlcAmHeader);
207  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
208 
209  // Send RLC PDU to MAC layer
211  params.pdu = packet;
212  params.rnti = m_rnti;
213  params.lcid = m_lcid;
214 
215  m_macSapProvider->TransmitPdu (params);
216  return;
217  }
218  else
219  {
220  NS_LOG_LOGIC ("Tx opportunity too small for retransmission of the packet (" << packet->GetSize () << " bytes)");
221  NS_LOG_LOGIC ("Waiting for bigger tx opportunity");
222  return;
223  }
224  }
225  else if ( m_txonBufferSize > 0 )
226  {
227  NS_LOG_LOGIC ("Sending data from Transmission Buffer");
228  }
229  else
230  {
231  NS_LOG_LOGIC ("No data pending");
232  return;
233  }
234 
235  //
236  //
237  // Build new PDU
238  //
239  //
240 
241  Ptr<Packet> packet = Create<Packet> ();
242  LteRlcAmHeader rlcAmHeader;
243  rlcAmHeader.SetDataPdu ();
244 
245  // Build Data field
246  uint32_t nextSegmentSize = bytes - 4;
247  uint32_t nextSegmentId = 1;
248  uint32_t dataFieldTotalSize = 0;
249  uint32_t dataFieldAddedSize = 0;
250  std::vector < Ptr<Packet> > dataField;
251 
252  // Remove the first packet from the transmission buffer.
253  // If only a segment of the packet is taken, then the remaining is given back later
254  if ( m_txonBuffer.size () == 0 )
255  {
256  NS_LOG_LOGIC ("No data pending");
257  return;
258  }
259 
260  NS_LOG_LOGIC ("SDUs in TxonBuffer = " << m_txonBuffer.size ());
261  NS_LOG_LOGIC ("First SDU buffer = " << *(m_txonBuffer.begin()));
262  NS_LOG_LOGIC ("First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
263  NS_LOG_LOGIC ("Next segment size = " << nextSegmentSize);
264  NS_LOG_LOGIC ("Remove SDU from TxBuffer");
265  Ptr<Packet> firstSegment = (*(m_txonBuffer.begin ()))->Copy ();
266  m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
267  NS_LOG_LOGIC ("txBufferSize = " << m_txonBufferSize );
268  m_txonBuffer.erase (m_txonBuffer.begin ());
269 
270  while ( firstSegment && (firstSegment->GetSize () > 0) && (nextSegmentSize > 0) )
271  {
272  NS_LOG_LOGIC ("WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
273  NS_LOG_LOGIC (" firstSegment size = " << firstSegment->GetSize ());
274  NS_LOG_LOGIC (" nextSegmentSize = " << nextSegmentSize);
275  if ( (firstSegment->GetSize () > nextSegmentSize) ||
276  // Segment larger than 2047 octets can only be mapped to the end of the Data field
277  (firstSegment->GetSize () > 2047)
278  )
279  {
280  // Take the minimum size, due to the 2047-bytes 3GPP exception
281  // This exception is due to the length of the LI field (just 11 bits)
282  uint32_t currSegmentSize = std::min (firstSegment->GetSize (), nextSegmentSize);
283 
284  NS_LOG_LOGIC (" IF ( firstSegment > nextSegmentSize ||");
285  NS_LOG_LOGIC (" firstSegment > 2047 )");
286 
287  // Segment txBuffer.FirstBuffer and
288  // Give back the remaining segment to the transmission buffer
289  Ptr<Packet> newSegment = firstSegment->CreateFragment (0, currSegmentSize);
290  NS_LOG_LOGIC (" newSegment size = " << newSegment->GetSize ());
291 
292  // Status tag of the new and remaining segments
293  // Note: This is the only place where a PDU is segmented and
294  // therefore its status can change
295  LteRlcSduStatusTag oldTag, newTag;
296  firstSegment->RemovePacketTag (oldTag);
297  newSegment->RemovePacketTag (newTag);
298  if (oldTag.GetStatus () == LteRlcSduStatusTag::FULL_SDU)
299  {
300  newTag.SetStatus (LteRlcSduStatusTag::FIRST_SEGMENT);
301  oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
302  }
303  else if (oldTag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT)
304  {
305  newTag.SetStatus (LteRlcSduStatusTag::MIDDLE_SEGMENT);
306  //oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
307  }
308 
309  // Give back the remaining segment to the transmission buffer
310  firstSegment->RemoveAtStart (currSegmentSize);
311  NS_LOG_LOGIC (" firstSegment size (after RemoveAtStart) = " << firstSegment->GetSize ());
312  if (firstSegment->GetSize () > 0)
313  {
314  firstSegment->AddPacketTag (oldTag);
315 
316  m_txonBuffer.insert (m_txonBuffer.begin (), firstSegment);
317  m_txonBufferSize += (*(m_txonBuffer.begin()))->GetSize ();
318 
319  NS_LOG_LOGIC (" Txon buffer: Give back the remaining segment");
320  NS_LOG_LOGIC (" Txon buffers = " << m_txonBuffer.size ());
321  NS_LOG_LOGIC (" Front buffer size = " << (*(m_txonBuffer.begin()))->GetSize ());
322  NS_LOG_LOGIC (" txonBufferSize = " << m_txonBufferSize );
323  }
324  else
325  {
326  // Whole segment was taken, so adjust tag
327  if (newTag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
328  {
329  newTag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
330  }
331  else if (newTag.GetStatus () == LteRlcSduStatusTag::MIDDLE_SEGMENT)
332  {
333  newTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
334  }
335  }
336  // Segment is completely taken or
337  // the remaining segment is given back to the transmission buffer
338  firstSegment = 0;
339 
340  // Put status tag once it has been adjusted
341  newSegment->AddPacketTag (newTag);
342 
343  // Add Segment to Data field
344  dataFieldAddedSize = newSegment->GetSize ();
345  dataFieldTotalSize += dataFieldAddedSize;
346  dataField.push_back (newSegment);
347  newSegment = 0;
348 
349  // ExtensionBit (Next_Segment - 1) = 0
350  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
351 
352  // no LengthIndicator for the last one
353 
354  nextSegmentSize -= dataFieldAddedSize;
355  nextSegmentId++;
356 
357  // nextSegmentSize MUST be zero (only if segment is smaller or equal to 2047)
358 
359  // (NO more segments) → exit
360  // break;
361  }
362  else if ( (nextSegmentSize - firstSegment->GetSize () <= 2) || (m_txonBuffer.size () == 0) )
363  {
364  NS_LOG_LOGIC (" IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
365 
366  // Add txBuffer.FirstBuffer to DataField
367  dataFieldAddedSize = firstSegment->GetSize ();
368  dataFieldTotalSize += dataFieldAddedSize;
369  dataField.push_back (firstSegment);
370  firstSegment = 0;
371 
372  // ExtensionBit (Next_Segment - 1) = 0
373  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
374 
375  // no LengthIndicator for the last one
376 
377  nextSegmentSize -= dataFieldAddedSize;
378  nextSegmentId++;
379 
380  NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
381  if (m_txonBuffer.size () > 0)
382  {
383  NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin()));
384  NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
385  }
386  NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
387 
388  // nextSegmentSize <= 2 (only if txBuffer is not empty)
389 
390  // (NO more segments) → exit
391  // break;
392  }
393  else // (firstSegment->GetSize () < m_nextSegmentSize) && (m_txBuffer.size () > 0)
394  {
395  NS_LOG_LOGIC (" IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
396  // Add txBuffer.FirstBuffer to DataField
397  dataFieldAddedSize = firstSegment->GetSize ();
398  dataFieldTotalSize += dataFieldAddedSize;
399  dataField.push_back (firstSegment);
400 
401  // ExtensionBit (Next_Segment - 1) = 1
402  rlcAmHeader.PushExtensionBit (LteRlcAmHeader::E_LI_FIELDS_FOLLOWS);
403 
404  // LengthIndicator (Next_Segment) = txBuffer.FirstBuffer.length()
405  rlcAmHeader.PushLengthIndicator (firstSegment->GetSize ());
406 
407  nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
408  nextSegmentId++;
409 
410  NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
411  if (m_txonBuffer.size () > 0)
412  {
413  NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin()));
414  NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
415  }
416  NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
417  NS_LOG_LOGIC (" Remove SDU from TxBuffer");
418 
419  // (more segments)
420  firstSegment = (*(m_txonBuffer.begin ()))->Copy ();
421  m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
422  m_txonBuffer.erase (m_txonBuffer.begin ());
423  NS_LOG_LOGIC (" txBufferSize = " << m_txonBufferSize );
424  }
425 
426  }
427 
428  //
429  // Build RLC header
430  //
431 
432  rlcAmHeader.SetSequenceNumber ( m_vtS++ );
433  rlcAmHeader.SetResegmentationFlag (LteRlcAmHeader::PDU);
434  rlcAmHeader.SetLastSegmentFlag (LteRlcAmHeader::LAST_PDU_SEGMENT);
435  rlcAmHeader.SetSegmentOffset (0);
436 
437  // Calculate FramingInfo flag according the status of the SDUs in the DataField
438  uint8_t framingInfo = 0;
439  std::vector< Ptr<Packet> >::iterator it;
440  it = dataField.begin ();
441 
442  // FIRST SEGMENT
443  LteRlcSduStatusTag tag;
444  (*it)->RemovePacketTag (tag);
445  if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
447  )
448  {
449  framingInfo |= LteRlcAmHeader::FIRST_BYTE;
450  }
451  else
452  {
453  framingInfo |= LteRlcAmHeader::NO_FIRST_BYTE;
454  }
455  (*it)->AddPacketTag (tag);
456 
457  // Add all SDUs (in DataField) to the Packet
458  while (it < dataField.end ())
459  {
460  NS_LOG_LOGIC ("Adding SDU/segment to packet, length = " << (*it)->GetSize ());
461 
462  packet->AddAtEnd (*it);
463  it++;
464  }
465 
466  // LAST SEGMENT (Note: There could be only one and be the first one)
467  it--;
468  (*it)->RemovePacketTag (tag);
469  if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
471  {
472  framingInfo |= LteRlcAmHeader::LAST_BYTE;
473  }
474  else
475  {
476  framingInfo |= LteRlcAmHeader::NO_LAST_BYTE;
477  }
478  (*it)->AddPacketTag (tag);
479 
480  // Set the FramingInfo flag after the calculation
481  rlcAmHeader.SetFramingInfo (framingInfo);
482 
483 
484  // Calculate the Polling Bit (5.2.2.1)
485  rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
486 
488  NS_LOG_LOGIC ("PDU_WITHOUT_POLL = " << m_pduWithoutPoll);
489  m_byteWithoutPoll += packet->GetSize ();
490  NS_LOG_LOGIC ("BYTE_WITHOUT_POLL = " << m_byteWithoutPoll);
491 
493  ( (m_txonBuffer.empty ()) && (m_retxBuffer.empty ()) ) ||
494  (m_vtS >= m_vtMs)
495  )
496  {
497  rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
498  m_pduWithoutPoll = 0;
499  m_byteWithoutPoll = 0;
500 
501  m_pollSn = m_vtS - 1;
502  NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn);
503 
505  {
506  NS_LOG_LOGIC ("Start PollRetransmit timer");
507 
510  }
511  else
512  {
513  NS_LOG_LOGIC ("Restart PollRetransmit timer");
514 
518  }
519  }
520 
521 
522  // Build RLC PDU with DataField and Header
523  NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader);
524  packet->AddHeader (rlcAmHeader);
525 
526  // Store new PDU into the Transmitted PDU Buffer
527  NS_LOG_LOGIC ("Put transmitted PDU in the txedBuffer");
528  m_txedBufferSize += packet->GetSize ();
529  m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ) = packet->Copy ();
530 
531  // Sender timestamp
532  RlcTag rlcTag (Simulator::Now ());
533  packet->AddByteTag (rlcTag);
534  m_txPdu (m_rnti, m_lcid, packet->GetSize ());
535 
536  // Send RLC PDU to MAC layer
538  params.pdu = packet;
539  params.rnti = m_rnti;
540  params.lcid = m_lcid;
541  params.layer = layer;
542 
543  m_macSapProvider->TransmitPdu (params);
544 }
545 
546 void
548 {
549  NS_LOG_FUNCTION (this);
550 }
551 
552 void
554 {
555  NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
556 
557  // Receiver timestamp
558  RlcTag rlcTag;
559  Time delay;
560  if (p->FindFirstMatchingByteTag (rlcTag))
561  {
562  delay = Simulator::Now() - rlcTag.GetSenderTimestamp ();
563  }
564  m_rxPdu (m_rnti, m_lcid, p->GetSize (), delay.GetNanoSeconds ());
565 
566  // Get RLC header parameters
567  LteRlcAmHeader rlcAmHeader;
568  p->PeekHeader (rlcAmHeader);
569  NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
570 
571  if ( rlcAmHeader.IsDataPdu () )
572  {
573 
574  // 5.1.3.1 Transmit operations
575 
576  // 5.1.3.1.1 General
577  //
578  // The transmitting side of an AM RLC entity shall prioritize transmission of RLC control PDUs
579  // over RLC data PDUs. The transmitting side of an AM RLC entity shall prioritize retransmission
580  // of RLC data PDUs over transmission of new AMD PDUs.
581  //
582  // The transmitting side of an AM RLC entity shall maintain a transmitting window according to
583  // state variables VT(A) and VT(MS) as follows:
584  // - a SN falls within the transmitting window if VT(A) <= SN < VT(MS);
585  // - a SN falls outside of the transmitting window otherwise.
586  //
587  // The transmitting side of an AM RLC entity shall not deliver to lower layer any RLC data PDU
588  // whose SN falls outside of the transmitting window.
589  //
590  // When delivering a new AMD PDU to lower layer, the transmitting side of an AM RLC entity shall:
591  // - set the SN of the AMD PDU to VT(S), and then increment VT(S) by one.
592  //
593  // The transmitting side of an AM RLC entity can receive a positive acknowledgement (confirmation
594  // of successful reception by its peer AM RLC entity) for a RLC data PDU by the following:
595  // - STATUS PDU from its peer AM RLC entity.
596  //
597  // When receiving a positive acknowledgement for an AMD PDU with SN = VT(A), the transmitting
598  // side of an AM RLC entity shall:
599  // - set VT(A) equal to the SN of the AMD PDU with the smallest SN, whose SN falls within the
600  // range VT(A) <= SN <= VT(S) and for which a positive acknowledgment has not been received yet.
601  // - if positive acknowledgements have been received for all AMD PDUs associated with
602  // a transmitted RLC SDU:
603  // - send an indication to the upper layers of successful delivery of the RLC SDU.
604 
605 
606  // 5.1.3.2 Receive operations
607  //
608  // 5.1.3.2.1 General
609  //
610  // The receiving side of an AM RLC entity shall maintain a receiving window according to state
611  // variables VR(R) and VR(MR) as follows:
612  // - a SN falls within the receiving window if VR(R) <= SN < VR(MR);
613  // - a SN falls outside of the receiving window otherwise.
614  //
615  // When receiving a RLC data PDU from lower layer, the receiving side of an AM RLC entity shall:
616  // - either discard the received RLC data PDU or place it in the reception buffer (see sub clause 5.1.3.2.2);
617  // - if the received RLC data PDU was placed in the reception buffer:
618  // - 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).
619  //
620  // When t-Reordering expires, the receiving side of an AM RLC entity shall:
621  // - update state variables and start t-Reordering as needed (see sub clause 5.1.3.2.4).
622 
623 
624  SequenceNumber10 seqNumber = rlcAmHeader.GetSequenceNumber ();
625 
626  if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::SEGMENT )
627  {
628  NS_LOG_LOGIC ("PDU segment received ( SN = " << seqNumber << " )");
629  }
630  else if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::PDU )
631  {
632  NS_LOG_LOGIC ("PDU received ( SN = " << seqNumber << " )");
633  }
634  else
635  {
636  NS_ASSERT_MSG (false, "Neither a PDU segment nor a PDU received");
637  return ;
638  }
639 
640  // STATUS PDU is requested
641  if ( rlcAmHeader.GetPollingBit () == LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED )
642  {
643  m_statusPduRequested = true;
645 
647  {
648  Time now = Simulator::Now ();
649 
650  // Transmission Queue HOL time
651  RlcTag txonQueueHolTimeTag;
652  Time txonQueueHolDelay (0);
653  if ( ! m_txonBuffer.empty () )
654  {
655  m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
656  txonQueueHolDelay = now - txonQueueHolTimeTag.GetSenderTimestamp ();
657  }
658 
659  // Retransmission Queue HOL time
660  RlcTag retxQueueHolTimeTag;
661  Time retxQueueHolDelay (0);
662  if ( m_retxBufferSize )
663  {
664  m_retxBuffer.front ().m_pdu->PeekPacketTag (retxQueueHolTimeTag);
665  retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
666  }
667 
669  r.rnti = m_rnti;
670  r.lcid = m_lcid;
672  r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
674  r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
675 
677  {
679  }
680  else
681  {
682  r.statusPduSize = 0;
683  }
684 
685  NS_LOG_INFO ("Send ReportBufferStatus: " << r.txQueueSize << ", " << r.txQueueHolDelay << ", "
686  << r.retxQueueSize << ", " << r.retxQueueHolDelay << ", "
687  << r.statusPduSize );
689  }
690  }
691 
692  // 5.1.3.2.2 Actions when a RLC data PDU is received from lower layer
693  //
694  // When a RLC data PDU is received from lower layer, where the RLC data PDU contains
695  // byte segment numbers y to z of an AMD PDU with SN = x, the receiving side of an AM RLC entity shall:
696  // - if x falls outside of the receiving window; or
697  // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
698  // - discard the received RLC data PDU;
699  // - else:
700  // - place the received RLC data PDU in the reception buffer;
701  // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
702  // - discard the duplicate byte segments.
703 
704  NS_LOG_LOGIC ("VR(R) = " << m_vrR);
705  NS_LOG_LOGIC ("VR(MR) = " << m_vrMr);
706  NS_LOG_LOGIC ("VR(X) = " << m_vrX);
707  NS_LOG_LOGIC ("VR(MS) = " << m_vrMs);
708  NS_LOG_LOGIC ("VR(H) = " << m_vrH);
709 
710  // - if x falls outside of the receiving window; or
711  // - if byte segment numbers y to z of the AMD PDU with SN = x have been received before:
712  if ( ! IsInsideReceivingWindow (seqNumber) )
713  {
714  NS_LOG_LOGIC ("PDU discarded");
715  return;
716  }
717  else
718  {
719  NS_LOG_LOGIC ("Place PDU in the reception buffer ( SN = " << seqNumber << " )");
720  m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.push_back (p);
721  m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete = true;
722 
723  // - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
724  // - discard the duplicate byte segments.
725  }
726 
727  // 5.1.3.2.3 Actions when a RLC data PDU is placed in the reception buffer
728  // When a RLC data PDU with SN = x is placed in the reception buffer,
729  // the receiving side of an AM RLC entity shall:
730 
731  // - if x >= VR(H)
732  // - update VR(H) to x+ 1;
733 
734  if ( seqNumber >= m_vrH )
735  {
736  m_vrH = seqNumber + 1;
737  NS_LOG_LOGIC ("New VR(H) = " << m_vrH);
738  }
739 
740  // - if all byte segments of the AMD PDU with SN = VR(MS) are received:
741  // - update VR(MS) to the SN of the first AMD PDU with SN > current VR(MS) for
742  // which not all byte segments have been received;
743 
744  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
745  if ( it != m_rxonBuffer.end () &&
746  m_rxonBuffer[ m_vrMs.GetValue () ].m_pduComplete )
747  {
748  int firstVrMs = m_vrMs.GetValue ();
749  while ( it != m_rxonBuffer.end () &&
750  m_rxonBuffer[ m_vrMs.GetValue () ].m_pduComplete )
751  {
752  m_vrMs++;
753  it = m_rxonBuffer.find (m_vrMs.GetValue ());
754  NS_LOG_LOGIC ("Incr VR(MS) = " << m_vrMs);
755 
756  NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in RxonBuffer");
757  }
758  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
759  }
760 
761  // - if x = VR(R):
762  // - if all byte segments of the AMD PDU with SN = VR(R) are received:
763  // - 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;
764  // - update VR(MR) to the updated VR(R) + AM_Window_Size;
765  // - 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;
766 
767  if ( seqNumber == m_vrR )
768  {
769  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (seqNumber.GetValue ());
770  if ( it != m_rxonBuffer.end () &&
771  m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete )
772  {
773  it = m_rxonBuffer.find (m_vrR.GetValue ());
774  int firstVrR = m_vrR.GetValue ();
775  while ( it != m_rxonBuffer.end () &&
776  m_rxonBuffer[ m_vrR.GetValue () ].m_pduComplete )
777  {
778  NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << m_vrR << " )");
779  NS_ASSERT_MSG (m_rxonBuffer[ m_vrR.GetValue () ].m_byteSegments.size () == 1,
780  "Too many segments. PDU Reassembly process didn't work");
781  ReassembleAndDeliver (m_rxonBuffer[ m_vrR.GetValue () ].m_byteSegments.front ());
782  m_rxonBuffer.erase (m_vrR.GetValue ());
783 
784  m_vrR++;
785  it = m_rxonBuffer.find (m_vrR.GetValue ());
786 
787  NS_ASSERT_MSG (firstVrR != m_vrR.GetValue (), "Infinite loop in RxonBuffer");
788  }
789  NS_LOG_LOGIC ("New VR(R) = " << m_vrR);
791  NS_LOG_LOGIC ("New VR(MR) = " << m_vrMr);
792  }
793 
794 // NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << seqNumber << " )");
795 // NS_ASSERT_MSG (m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.size () == 1,
796 // "Too many segments. PDU Reassembly process didn't work");
797 // ReassembleAndDeliver (m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.front ());
798 // m_rxonBuffer.erase (seqNumber.GetValue ());
799  }
800 
801  // - if t-Reordering is running:
802  // - if VR(X) = VR(R); or
803  // - if VR(X) falls outside of the receiving window and VR(X) is not equal to VR(MR):
804  // - stop and reset t-Reordering;
805 
806  if ( m_reorderingTimer.IsRunning () )
807  {
808  NS_LOG_LOGIC ("Reordering timer is running");
809  if ( (m_vrX == m_vrR) ||
810  ( (! IsInsideReceivingWindow (m_vrX)) && (m_vrX != m_vrMr) )
811  )
812  {
813  // TODO stop and reset the t-Reordering
814  NS_LOG_LOGIC ("Stop reordering timer");
816  }
817  }
818 
819  // - if t-Reordering is not running (includes the case t-Reordering is stopped due to actions above):
820  // - if VR (H) > VR(R):
821  // - start t-Reordering;
822  // - set VR(X) to VR(H).
823 
824  if ( ! m_reorderingTimer.IsRunning () )
825  {
826  NS_LOG_LOGIC ("Reordering timer is not running");
827  if ( m_vrH > m_vrR )
828  {
829  NS_LOG_LOGIC ("Start reordering timer");
832  m_vrX = m_vrH;
833  NS_LOG_LOGIC ("New VR(X) = " << m_vrX);
834  }
835  }
836 
837 
838 
839  // TODO To remove
840 
841  // 5.1.2.2.3 Actions when an UMD PDU is placed in the reception buffer
842  // When an UMD PDU with SN = x is placed in the reception buffer, the receiving UM RLC entity shall:
843 
844  // - if x falls outside of the reordering window:
845  // - update VR(UH) to x + 1;
846  // - reassemble RLC SDUs from any UMD PDUs with SN that falls outside of the reordering window, remove
847  // RLC headers when doing so and deliver the reassembled RLC SDUs to upper layer in ascending order of the
848  // RLC SN if not delivered before;
849  // - if VR(UR) falls outside of the reordering window:
850  // - set VR(UR) to (VR(UH) - UM_Window_Size);
851 
852 // if ( ! IsInsideReorderingWindow (seqNumber))
853 // {
854 // NS_LOG_LOGIC ("SN outside the reordering window");
855 //
856 // m_vrUh = seqNumber + 1;
857 // NS_LOG_LOGIC ("New VR(UH) = " << m_vrUh);
858 //
859 // ReassembleOutsideWindow ();
860 //
861 // if ( ! IsInsideReorderingWindow (m_vrUr) )
862 // {
863 // m_vrUr = m_vrUh - m_windowSize;
864 // NS_LOG_LOGIC ("VR(UR) outside the reordering window");
865 // NS_LOG_LOGIC ("New VR(UR) = " << m_vrUr);
866 // }
867 // }
868 
869  // - if the reception buffer contains an UMD PDU with SN = VR(UR):
870  // - update VR(UR) to the SN of the first UMD PDU with SN > current VR(UR) that has not been received;
871  // - reassemble RLC SDUs from any UMD PDUs with SN < updated VR(UR), remove RLC headers when doing
872  // so and deliver the reassembled RLC SDUs to upper layer in ascending order of the RLC SN if not delivered
873  // before;
874 
875 // if ( m_rxBuffer.count (m_vrUr) > 0 )
876 // {
877 // NS_LOG_LOGIC ("Reception buffer contains SN = " << m_vrUr);
878 //
879 // std::map <uint16_t, Ptr<Packet> >::iterator it;
880 // uint16_t newVrUr;
881 //
882 // it = m_rxBuffer.find (m_vrUr);
883 // newVrUr = (it->first) + 1;
884 // while ( m_rxBuffer.count (newVrUr) > 0 )
885 // {
886 // newVrUr++;
887 // }
888 // m_vrUr = newVrUr;
889 // NS_LOG_LOGIC ("New VR(UR) = " << m_vrUr);
890 //
891 // ReassembleSnLessThan (m_vrUr);
892 // }
893 
894  // - if t-Reordering is running:
895  // - if VR(UX) <= VR(UR); or
896  // - if VR(UX) falls outside of the reordering window and VR(UX) is not equal to VR(UH)::
897  // - stop and reset t-Reordering;
898 // if ( m_reorderingTimer.IsRunning () )
899 // {
900 // NS_LOG_LOGIC ("Reordering timer is running");
901 //
902 // if ( (m_vrUx <= m_vrUr) ||
903 // ((! IsInsideReorderingWindow (m_vrUx)) && (m_vrUx != m_vrUh)) )
904 // {
905 // NS_LOG_LOGIC ("Stop reordering timer");
906 // m_reorderingTimer.Cancel ();
907 // }
908 // }
909 
910  // - if t-Reordering is not running (includes the case when t-Reordering is stopped due to actions above):
911  // - if VR(UH) > VR(UR):
912  // - start t-Reordering;
913  // - set VR(UX) to VR(UH).
914 // if ( ! m_reorderingTimer.IsRunning () )
915 // {
916 // NS_LOG_LOGIC ("Reordering timer is not running");
917 //
918 // if ( m_vrUx > m_vrUr )
919 // {
920 // NS_LOG_LOGIC ("VR(UX) > VR(UR). " << m_vrUx << " > " << m_vrUr);
921 // NS_LOG_LOGIC ("Start reordering timer");
922 // m_reorderingTimer = Simulator::Schedule (Time ("1.0s"),
923 // &LteRlcAm::ExpireReorderingTimer ,this);
924 // m_vrUx = m_vrUh;
925 // NS_LOG_LOGIC ("New VR(UX) = " << m_vrUx);
926 // }
927 // }
928 
929  }
930  else if ( rlcAmHeader.IsControlPdu () )
931  {
932  NS_LOG_INFO ("Control AM RLC PDU");
933 
934  SequenceNumber10 ackSn = rlcAmHeader.GetAckSn ();
935 // SequenceNumber10 seqNumber = m_vtA;
936 
937  NS_LOG_INFO ("ackSn = " << ackSn);
938  NS_LOG_INFO ("VT(A) = " << m_vtA);
939  NS_LOG_INFO ("VT(S) = " << m_vtS);
940  while (m_vtA < ackSn && m_vtA < m_vtS)
941  {
942 // NS_LOG_INFO ("seqNumber = " << seqNumber);
943 // NS_LOG_INFO ("m_txedBuffer( VT(A) ).size = " << m_txedBuffer.size ());
944 
945  uint16_t seqNumberValue = m_vtA.GetValue ();
946  if (m_txedBuffer.at (seqNumberValue))
947  {
948  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from txedBuffer");
949 // NS_LOG_INFO ("m_txedBuffer( " << m_vtA << " )->GetSize = " << m_txedBuffer.at (m_vtA.GetValue ())->GetSize ());
950  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
951  m_txedBuffer.at (seqNumberValue) = 0;
952  }
953 
954  if (m_retxBuffer.at (seqNumberValue).m_pdu)
955  {
956  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from retxBuffer");
957  m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
958  m_retxBuffer.at (seqNumberValue).m_pdu = 0;
959  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
960  }
961 
962  m_vtA++;
963  }
964 
965  NS_LOG_INFO ("New VT(A) = " << m_vtA);
966 
967  SequenceNumber10 seqNumber = m_vtA;
968  uint16_t seqNumberValue;
969  while (seqNumber < m_vtS)
970  {
971  seqNumberValue = seqNumber.GetValue ();
972  if (m_txedBuffer.at (seqNumberValue))
973  {
974  NS_LOG_INFO ("Move SN = " << seqNumberValue << " to retxBuffer");
975  m_retxBuffer.at (seqNumberValue).m_pdu = m_txedBuffer.at (seqNumberValue)->Copy ();
976  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
977  m_retxBufferSize += m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
978 
979  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
980  m_txedBuffer.at (seqNumberValue) = 0;
981  }
982  else if (m_retxBuffer.at (seqNumberValue).m_pdu)
983  {
984  m_retxBuffer.at (seqNumberValue).m_retxCount++;
985  NS_LOG_INFO ("Incr RETX_COUNT for SN = " << seqNumberValue);
986  if (m_retxBuffer.at (seqNumberValue).m_retxCount >= m_maxRetxThreshold)
987  {
988  NS_LOG_INFO ("Max RETX_COUNT for SN = " << seqNumberValue);
989  }
990  }
991 
992  seqNumber++;
993  }
994 
995  return;
996  }
997  else
998  {
999  NS_LOG_WARN ("Wrong AM RLC PDU type");
1000  return;
1001  }
1002 
1003 }
1004 
1005 
1006 void
1008 {
1009  NS_LOG_FUNCTION (this);
1010 
1012  p.rnti = m_rnti;
1013  p.lcid = m_lcid;
1014  p.txQueueSize = 0;
1015  p.txQueueHolDelay = 0;
1016  p.retxQueueSize = 0;
1017  p.retxQueueHolDelay = 0;
1018  p.statusPduSize = 0;
1019 
1021 }
1022 
1023 
1024 bool
1026 {
1027  NS_LOG_FUNCTION (this << seqNumber);
1028  NS_LOG_LOGIC ("Receiving Window: " <<
1029  m_vrR << " <= " << seqNumber << " <= " << m_vrMr);
1030 
1033  seqNumber.SetModulusBase (m_vrR);
1034 
1035  if ( (m_vrR <= seqNumber) && (seqNumber < m_vrMr ) )
1036  {
1037  NS_LOG_LOGIC (seqNumber << " is INSIDE the receiving window");
1038  return true;
1039  }
1040  else
1041  {
1042  NS_LOG_LOGIC (seqNumber << " is OUTSIDE the receiving window");
1043  return false;
1044  }
1045 }
1046 
1047 
1048 void
1050 {
1051  LteRlcAmHeader rlcAmHeader;
1052  packet->RemoveHeader (rlcAmHeader);
1053  uint8_t framingInfo = rlcAmHeader.GetFramingInfo ();
1054  SequenceNumber10 currSeqNumber = rlcAmHeader.GetSequenceNumber ();
1055  bool expectedSnLost;
1056 
1057  if ( currSeqNumber != m_expectedSeqNumber )
1058  {
1059  expectedSnLost = true;
1060  NS_LOG_LOGIC ("There are losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
1061  m_expectedSeqNumber = currSeqNumber + 1;
1062  }
1063  else
1064  {
1065  expectedSnLost = false;
1066  NS_LOG_LOGIC ("No losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
1068  }
1069 
1070  // Build list of SDUs
1071  uint8_t extensionBit;
1072  uint16_t lengthIndicator;
1073  do
1074  {
1075  extensionBit = rlcAmHeader.PopExtensionBit ();
1076  NS_LOG_LOGIC ("E = " << (uint16_t)extensionBit);
1077 
1078  if ( extensionBit == 0 )
1079  {
1080  m_sdusBuffer.push_back (packet);
1081  }
1082  else // extensionBit == 1
1083  {
1084  lengthIndicator = rlcAmHeader.PopLengthIndicator ();
1085  NS_LOG_LOGIC ("LI = " << lengthIndicator);
1086 
1087  // Check if there is enough data in the packet
1088  if ( lengthIndicator >= packet->GetSize () )
1089  {
1090  NS_LOG_LOGIC ("INTERNAL ERROR: Not enough data in the packet (" << packet->GetSize () << "). Needed LI=" << lengthIndicator);
1091  // TODO What to do in this case? Discard packet and continue? Or Assert?
1092  }
1093 
1094  // Split packet in two fragments
1095  Ptr<Packet> data_field = packet->CreateFragment (0, lengthIndicator);
1096  packet->RemoveAtStart (lengthIndicator);
1097 
1098  m_sdusBuffer.push_back (data_field);
1099  }
1100  }
1101  while ( extensionBit == 1 );
1102 
1103  std::list < Ptr<Packet> >::iterator it;
1104 
1105  // Current reassembling state
1106  if (m_reassemblingState == WAITING_S0_FULL) NS_LOG_LOGIC ("Reassembling State = 'WAITING_S0_FULL'");
1107  else if (m_reassemblingState == WAITING_SI_SF) NS_LOG_LOGIC ("Reassembling State = 'WAITING_SI_SF'");
1108  else NS_LOG_LOGIC ("Reassembling State = Unknown state");
1109 
1110  // Received framing Info
1111  NS_LOG_LOGIC ("Framing Info = " << (uint16_t)framingInfo);
1112  NS_LOG_LOGIC ("m_sdusBuffer = " << m_sdusBuffer.size ());
1113 
1114  // Reassemble the list of SDUs (when there is no losses)
1115  if (!expectedSnLost)
1116  {
1117  switch (m_reassemblingState)
1118  {
1119  case WAITING_S0_FULL:
1120  switch (framingInfo)
1121  {
1124 
1128  for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1129  {
1131  }
1132  m_sdusBuffer.clear ();
1133  break;
1134 
1137 
1141  while ( m_sdusBuffer.size () > 1 )
1142  {
1144  m_sdusBuffer.pop_front ();
1145  }
1146 
1150  m_keepS0 = m_sdusBuffer.front ();
1151  m_sdusBuffer.pop_front ();
1152  break;
1153 
1156  default:
1160  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1161  break;
1162  }
1163  break;
1164 
1165  case WAITING_SI_SF:
1166  switch (framingInfo)
1167  {
1170 
1174  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1175  m_sdusBuffer.pop_front ();
1177 
1181  while ( ! m_sdusBuffer.empty () )
1182  {
1184  m_sdusBuffer.pop_front ();
1185  }
1186  break;
1187 
1190 
1194  if ( m_sdusBuffer.size () == 1 )
1195  {
1196  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1197  m_sdusBuffer.pop_front ();
1198  }
1199  else // m_sdusBuffer.size () > 1
1200  {
1204  m_keepS0->AddAtEnd (m_sdusBuffer.front ());
1205  m_sdusBuffer.pop_front ();
1207 
1211  while ( m_sdusBuffer.size () > 1 )
1212  {
1214  m_sdusBuffer.pop_front ();
1215  }
1216 
1220  m_keepS0 = m_sdusBuffer.front ();
1221  m_sdusBuffer.pop_front ();
1222  }
1223  break;
1224 
1227  default:
1231  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1232  break;
1233  }
1234  break;
1235 
1236  default:
1237  NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1238  break;
1239  }
1240  }
1241  else // Reassemble the list of SDUs (when there are losses, i.e. the received SN is not the expected one)
1242  {
1243  switch (m_reassemblingState)
1244  {
1245  case WAITING_S0_FULL:
1246  switch (framingInfo)
1247  {
1250 
1254  for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1255  {
1257  }
1258  m_sdusBuffer.clear ();
1259  break;
1260 
1263 
1267  while ( m_sdusBuffer.size () > 1 )
1268  {
1270  m_sdusBuffer.pop_front ();
1271  }
1272 
1276  m_keepS0 = m_sdusBuffer.front ();
1277  m_sdusBuffer.pop_front ();
1278  break;
1279 
1282 
1286  m_sdusBuffer.pop_front ();
1287 
1291  while ( ! m_sdusBuffer.empty () )
1292  {
1294  m_sdusBuffer.pop_front ();
1295  }
1296  break;
1297 
1299  if ( m_sdusBuffer.size () == 1 )
1300  {
1302  }
1303  else
1304  {
1306  }
1307 
1311  m_sdusBuffer.pop_front ();
1312 
1313  if ( m_sdusBuffer.size () > 0 )
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 
1332  default:
1336  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1337  break;
1338  }
1339  break;
1340 
1341  case WAITING_SI_SF:
1342  switch (framingInfo)
1343  {
1346 
1350  m_keepS0 = 0;
1351 
1355  while ( ! m_sdusBuffer.empty () )
1356  {
1358  m_sdusBuffer.pop_front ();
1359  }
1360  break;
1361 
1364 
1368  m_keepS0 = 0;
1369 
1373  while ( m_sdusBuffer.size () > 1 )
1374  {
1376  m_sdusBuffer.pop_front ();
1377  }
1378 
1382  m_keepS0 = m_sdusBuffer.front ();
1383  m_sdusBuffer.pop_front ();
1384 
1385  break;
1386 
1389 
1393  m_keepS0 = 0;
1394 
1398  m_sdusBuffer.pop_front ();
1399 
1403  while ( ! m_sdusBuffer.empty () )
1404  {
1406  m_sdusBuffer.pop_front ();
1407  }
1408  break;
1409 
1411  if ( m_sdusBuffer.size () == 1 )
1412  {
1414  }
1415  else
1416  {
1418  }
1419 
1423  m_keepS0 = 0;
1424 
1428  m_sdusBuffer.pop_front ();
1429 
1430  if ( m_sdusBuffer.size () > 0 )
1431  {
1435  while ( m_sdusBuffer.size () > 1 )
1436  {
1438  m_sdusBuffer.pop_front ();
1439  }
1440 
1444  m_keepS0 = m_sdusBuffer.front ();
1445  m_sdusBuffer.pop_front ();
1446  }
1447  break;
1448 
1449  default:
1453  NS_LOG_LOGIC ("INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1454  break;
1455  }
1456  break;
1457 
1458  default:
1459  NS_LOG_LOGIC ("INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1460  break;
1461  }
1462  }
1463 
1464 }
1465 
1466 
1467 // TODO To remove
1468 // void
1469 // LteRlcAm::ReassembleOutsideWindow (void)
1470 // {
1471 // NS_LOG_LOGIC ("Reassemble Outside Window");
1472 //
1473 // std::map <uint16_t, Ptr<Packet> >::iterator it;
1474 // it = m_rxBuffer.begin ();
1475 //
1476 // while ( (it != m_rxBuffer.end ()) && ! IsInsideReorderingWindow (it->first) )
1477 // {
1478 // NS_LOG_LOGIC ("SN = " << it->first);
1479 //
1480 // // Reassemble RLC SDUs and deliver the PDCP PDU to upper layer
1481 // ReassembleAndDeliver (it->second);
1482 // m_rxBuffer.erase (it);
1483 // it++;
1484 // }
1485 //
1486 // if (it != m_rxBuffer.end ())
1487 // {
1488 // NS_LOG_LOGIC ("(SN = " << it->first << ") is inside the reordering window");
1489 // }
1490 // }
1491 
1492 
1493 // TODO To remove
1494 // void
1495 // LteRlcAm::ReassembleSnLessThan (uint16_t seqNumber)
1496 // {
1497 // NS_LOG_LOGIC ("Reassemble SN < updated VR(UR)" );
1498 //
1499 // std::map <uint16_t, Ptr<Packet> >::iterator it;
1500 // it = m_rxBuffer.begin ();
1501 //
1502 // while ( (it != m_rxBuffer.end ()) && (it->first < seqNumber) )
1503 // {
1504 // NS_LOG_LOGIC ("SN = " << it->first);
1505 //
1506 // // Reassemble RLC SDUs and deliver the PDCP PDU to upper layer
1507 // ReassembleAndDeliver (it->second);
1508 // m_rxBuffer.erase (it);
1509 // it++;
1510 // }
1511 //
1512 // if (it != m_rxBuffer.end ())
1513 // {
1514 // NS_LOG_LOGIC ("(SN = " << it->first << ") >= " << m_vrUr);
1515 // }
1516 // }
1517 
1518 
1519 void
1521 {
1522  NS_LOG_LOGIC ("Reordering Timer has expired");
1523 
1524  // 5.1.3.2.4 Actions when t-Reordering expires
1525  // When t-Reordering expires, the receiving side of an AM RLC entity shall:
1526  // - update VR(MS) to the SN of the first AMD PDU with SN >= VR(X) for which not all byte segments
1527  // have been received;
1528  // - if VR(H) > VR(MS):
1529  // - start t-Reordering;
1530  // - set VR(X) to VR(H).
1531 
1532  m_vrMs = m_vrX;
1533  int firstVrMs = m_vrMs.GetValue ();
1534  std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.GetValue ());
1535  while ( it != m_rxonBuffer.end () &&
1536  m_rxonBuffer[ m_vrMs.GetValue () ].m_pduComplete )
1537  {
1538  m_vrMs++;
1539  it = m_rxonBuffer.find (m_vrMs.GetValue ());
1540 
1541  NS_ASSERT_MSG (firstVrMs != m_vrMs.GetValue (), "Infinite loop in ExpireReorderingTimer");
1542  }
1543  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
1544 
1545  if ( m_vrH > m_vrMs )
1546  {
1547  NS_LOG_LOGIC ("Start reordering timer");
1550  m_vrX = m_vrH;
1551  NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
1552  }
1553 }
1554 
1555 void
1557 {
1558  NS_LOG_LOGIC ("PollRetransmit Timer has expired");
1559  NS_LOG_LOGIC ("TODO To Check");
1560 }
1561 
1562 
1563 
1564 } // namespace ns3