src/lte/model/lte-rlc-am.cc
changeset 11302 b81502a7dae8
parent 11301 25168b480c1c
child 11303 4d5d717de23e
--- a/src/lte/model/lte-rlc-am.cc	Tue Oct 22 13:32:39 2013 +0200
+++ b/src/lte/model/lte-rlc-am.cc	Wed Oct 23 15:21:13 2013 +0200
@@ -33,12 +33,6 @@
 
 NS_OBJECT_ENSURE_REGISTERED (LteRlcAm);
 
-// Brett
-// Used to keep track of when the RLC AM sliding window wraps back around. This
-// is required for knowning when a small ACK SN also ACKs a larger SN from the
-// before the window wrapped around.
-bool m_windowWrap = false;
-
 LteRlcAm::LteRlcAm ()
 {
   NS_LOG_FUNCTION (this);
@@ -199,44 +193,43 @@
       NS_LOG_LOGIC ("Sending STATUS PDU");
 
       Ptr<Packet> packet = Create<Packet> ();
-      NS_LOG_LOGIC ( "Brett -- About to make AM header for STATUS PDU" );
       LteRlcAmHeader rlcAmHeader;
       rlcAmHeader.SetControlPdu (LteRlcAmHeader::STATUS_PDU);
-//      rlcAmHeader.SetAckSn (m_vrR); // Brett, need to change this
-      rlcAmHeader.SetAckSn (m_vrH); // Brett, is this right?
-
-      //=======================================================================
-      // Brett
-      // Check the reception buffer and find which Sequence Numbers are missing
-      // based on what is being ACKed. All SNs missing from the reception
-      // buffer that come before the SN number that is being ACKed are going to
-      // be NACKed packets.
-       
-      NS_LOG_LOGIC ("Brett - Receiver Side - Check for SNs to NACK");
-      NS_LOG_LOGIC ("Brett - Receiver Side - Check SNs from " << m_vrR.GetValue() << " to " << m_vrH.GetValue());
-      for ( int i = m_vrR.GetValue(); i < m_vrH.GetValue(); i++ ) {
-        // NS_LOG_LOGIC ("Brett - Receiver Side - Checking SN " << i );
-        // Need a different check but similar idea
-      /* struct PduBuffer
+     
+      NS_LOG_LOGIC ("Check for SNs to NACK from " << m_vrR.GetValue() << " to " << m_vrH.GetValue());
+      SequenceNumber10 sn;
+      sn.SetModulusBase (m_vrR);
+      std::map<uint16_t, PduBuffer>::iterator pduIt;
+      for (sn = m_vrR; sn < m_vrH; sn++) 
         {
-          SequenceNumber10  m_seqNumber;
-          std::list < Ptr<Packet> >  m_byteSegments;
-
-          bool      m_pduComplete;
-          uint16_t  m_totalSize;
-          uint16_t  m_currSize;
-        };*/
+          if (!rlcAmHeader.OneMoreNackWouldFitIn (bytes))
+            {
+              NS_LOG_LOGIC ("Can't fit more NACKs in STATUS PDU");
+              break;
+            }          
+          pduIt = m_rxonBuffer.find (sn.GetValue ());
+          if (pduIt == m_rxonBuffer.end () || (!(pduIt->second.m_pduComplete)))
+            {
+              NS_LOG_LOGIC ("adding NACK_SN " << sn.GetValue ());
+              rlcAmHeader.PushNack (sn.GetValue ());              
+            }          
+        }
 
-        int test =  m_rxonBuffer[ i ].m_pduComplete;
-        //NS_LOG_LOGIC("Brett - Is PDU complete: " <<  m_rxonBuffer[ i ].m_pduComplete);
-        if ( test == 0 ) {
-//          NS_LOG_LOGIC("Brett - NACK " << i );
-//          rlcAmHeader.EnqueueNAckSn( SequenceNumber10( i ) );
-          rlcAmHeader.PushNack( SequenceNumber10( i ).GetValue() );
+      // 3GPP TS 36.322 section 6.2.2.1.4 ACK SN
+      // find the  SN of the next not received RLC Data PDU 
+      // which is not reported as missing in the STATUS PDU. 
+      do
+        {
+          sn++;
+          pduIt = m_rxonBuffer.find (sn.GetValue ());
         }
-      }
-      //=======================================================================
+      while (pduIt != m_rxonBuffer.end () && (pduIt->second.m_pduComplete) && (sn < m_vrH));      
 
+      if (sn != m_vrMs)
+        {
+          NS_LOG_WARN ("SN=" << sn << ", VR(MS)=" << m_vrMs);
+        }      
+      rlcAmHeader.SetAckSn (m_vrR); 
 
 
       NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
@@ -261,8 +254,9 @@
       NS_LOG_LOGIC ("Sending data from Retransmission Buffer");
 
       Ptr<Packet> packet = m_retxBuffer.at (m_vtA.GetValue ()).m_pdu->Copy ();
-
-      if ( packet->GetSize () <= bytes )
+      
+      if (( packet->GetSize () <= bytes )
+          || m_txOpportunityForRetxAlwaysBigEnough)
         {
           LteRlcAmHeader rlcAmHeader;
           packet->PeekHeader (rlcAmHeader);
@@ -299,7 +293,7 @@
 
       NS_LOG_LOGIC ("Sending data from Transmission Buffer");
     }
- /* else if ( m_txedBufferSize > 0 )
+  /* else if ( m_txedBufferSize > 0 )
     {
       NS_LOG_LOGIC ("Sending data from Transmitted Buffer");
 
@@ -308,10 +302,10 @@
 
       uint16_t vta = m_vtA.GetValue ();
       Ptr<Packet> packet = m_txedBuffer.at (vta)->Copy ();
-
-      if ( packet->GetSize () <= bytes )
+      
+      if (( packet->GetSize () <= bytes )
+          || m_txOpportunityForRetxAlwaysBigEnough)
         {
-         // Brett - Move to retransmission buffer
           NS_LOG_INFO ("Move SN = " << vta << " to retxBuffer");
           m_retxBuffer.at (vta).m_pdu = m_txedBuffer.at (vta)->Copy ();
           m_retxBuffer.at (vta).m_retxCount = 1;
@@ -341,8 +335,8 @@
           NS_LOG_LOGIC ("Waiting for bigger TxOpportunity");
           return;
         }
-    }
-*/  else
+    } */
+  else
     {
       NS_LOG_LOGIC ("No data pending");
       return;
@@ -1010,137 +1004,93 @@
       NS_LOG_INFO ("Control AM RLC PDU");
 
       SequenceNumber10 ackSn = rlcAmHeader.GetAckSn ();
-//       SequenceNumber10 seqNumber = m_vtA;
+      SequenceNumber10 sn;
 
       NS_LOG_INFO ("ackSn     = " << ackSn);
       NS_LOG_INFO ("VT(A)     = " << m_vtA);
       NS_LOG_INFO ("VT(S)     = " << m_vtS);
 
+      m_vtA.SetModulusBase (m_vtA);
+      m_vtS.SetModulusBase (m_vtA);
+      ackSn.SetModulusBase (m_vtA);
+      sn.SetModulusBase (m_vtA);
 
+      bool incrementVtA = true; 
+
+      for (sn = m_vtA; sn < ackSn && sn < m_vtS; sn++)
+        {
+          NS_LOG_LOGIC ("sn = " << sn);
 
-      // Check for the first NACK
-      uint16_t nackSN = rlcAmHeader.PopNack ();
-      // Flag to indicate if any NACKs exist in the header. This is used to
-      // determine when VT(A) should stop incrementing as it is the lower
-      // bound of the transmission window and should equal the highest ACKed
-      // SN in sequence (no NACKs previous).
-      bool foundNack = false;
-      // Used to iterate over the transmission window to apply the ACKs and
-      // NACKs from the control PDU.
-      uint16_t loopCount = m_vtA.GetValue ();
+          uint16_t seqNumberValue = sn.GetValue ();
 
-      // Brett - Check to see if the transmission window needs to wrap around.
-      // This window needs to wrap if the current VT(A) (last ACKed PDU) plus
-      // the window size is larger than 1023 and the SN just received is for
-      // a PDU that somwhere in the range of 0 to the top of the window. If
-      // this is the case then set the window wrap flag.
-      if ((m_vtA.GetValue() + m_windowSize > 1023) 
-          && 0 <= ackSn.GetValue() && ackSn.GetValue() < m_vtA.GetValue() + m_windowSize - 1023)
-        {
-          m_windowWrap = true;
-        } 
+          if (m_pollRetransmitTimer.IsRunning () 
+              && (seqNumberValue == m_pollSn.GetValue ()))
+            {
+              m_pollRetransmitTimer.Cancel ();
+            }
+
+          if (rlcAmHeader.IsNackPresent (sn))
+            {
+              NS_LOG_LOGIC ("sn " << sn << " is NACKed");
 
-      // Brett - There is a problem with the transmitting window wrapping back
-      // to the beginning. An ACK is for the next sequence number expected, but
-      // the largest sequence number that can be sent is 1023. We cannot send
-      // 1024 or anything higher than this to ACK an SN of 1023. To resolve I
-      // am adding the OR condition to this while loop. In the situation that
-      // the check above finds that it is time for the window to wrap then the
-      // window wrap flag allows this loop to execute. The loop will ACK all
-      // SNs from VT(A) to SN 1023 before resetting the window wrap flag to
-      // false and resetting the last ACKed SN to 0.
-      NS_LOG_INFO("Brett - Check - Look at transmit window from " << loopCount << " to " << m_vtS.GetValue ());
-      while (( loopCount < ackSn.GetValue() && loopCount < m_vtS.GetValue ())
-              || m_windowWrap)
-       {
-           NS_LOG_INFO("Brett - Current NACK is " << nackSN);
-//           NS_LOG_INFO ("seqNumber = " << seqNumber);
-//           NS_LOG_INFO ("m_txedBuffer( VT(A) ).size = " << m_txedBuffer.size ());
+              incrementVtA = false;
 
-          //uint16_t seqNumberValue = m_vtA.GetValue ();
-          uint16_t seqNumberValue = loopCount;
-          if ( nackSN != seqNumberValue )
-          {
+              if (m_txedBuffer.at (seqNumberValue))
+                {
+                  NS_LOG_INFO ("Move SN = " << seqNumberValue << " to retxBuffer");
+                  m_retxBuffer.at (seqNumberValue).m_pdu = m_txedBuffer.at (seqNumberValue)->Copy ();
+                  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
+                  m_retxBufferSize += m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
 
-            if (m_txedBuffer.at (seqNumberValue))
-              {
-                NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from txedBuffer");
-//                 NS_LOG_INFO ("m_txedBuffer( " << m_vtA << " )->GetSize = " << m_txedBuffer.at (m_vtA.GetValue ())->GetSize ());
-                m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
-                m_txedBuffer.at (seqNumberValue) = 0;
-              }
-
-            if (m_retxBuffer.at (seqNumberValue).m_pdu)
-              {
-                NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from retxBuffer");
-                m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
-                m_retxBuffer.at (seqNumberValue).m_pdu = 0;
-                m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
-              }
-
-            if ( !foundNack )
-              {
-                m_vtA++;
-                NS_LOG_INFO ("Brett -- Updated VT(A) = " << m_vtA);
-                m_vtA.SetModulusBase (m_vtA);
-                m_vtS.SetModulusBase (m_vtA);
-                ackSn.SetModulusBase (m_vtA);
-              }
+                  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
+                  m_txedBuffer.at (seqNumberValue) = 0;
+                }
+              else if (m_retxBuffer.at (seqNumberValue).m_pdu)
+                {
+                  m_retxBuffer.at (seqNumberValue).m_retxCount++;
+                  NS_LOG_INFO ("Incr RETX_COUNT for SN = " << seqNumberValue);
+                  if (m_retxBuffer.at (seqNumberValue).m_retxCount >= m_maxRetxThreshold)
+                    {
+                      NS_LOG_INFO ("Max RETX_COUNT for SN = " << seqNumberValue);
+                    }
+                }
+              
             }
           else
             {
-              foundNack = true;
-              if (m_txedBuffer.at (nackSN))
-               {
-                 NS_LOG_INFO ("NACKed SN = " << seqNumberValue << " from txedBuffer");
-                 // Brett - Move to Retransmission Buffer
-                  NS_LOG_INFO ("Move SN = " << nackSN << " to retxBuffer");
-                  m_retxBuffer.at (nackSN).m_pdu = m_txedBuffer.at (nackSN)->Copy ();
-                  m_retxBuffer.at (nackSN).m_retxCount = 0;
-                  m_retxBufferSize += m_retxBuffer.at (nackSN).m_pdu->GetSize ();
+              NS_LOG_LOGIC ("sn " << sn << " is ACKed");
 
-                  m_txedBufferSize -= m_txedBuffer.at (nackSN)->GetSize ();
-                  m_txedBuffer.at (nackSN) = 0;
-               }
-              else if (m_retxBuffer.at (nackSN).m_pdu)
-               {
-                 NS_LOG_INFO ("NACKed SN = " << seqNumberValue << " from retxBuffer");
-                 m_retxBuffer.at (nackSN).m_retxCount++;
-                 NS_LOG_INFO ("Incr RETX_COUNT for SN = " << nackSN);
-                 if (m_retxBuffer.at (nackSN).m_retxCount >= m_maxRetxThreshold)
-                   {
-                     NS_LOG_INFO ("Max RETX_COUNT for SN = " << nackSN);
-                   }
-               }
+              if (m_txedBuffer.at (seqNumberValue))
+                {
+                  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from txedBuffer");
+                  //               NS_LOG_INFO ("m_txedBuffer( " << m_vtA << " )->GetSize = " << m_txedBuffer.at (m_vtA.GetValue ())->GetSize ());
+                  m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
+                  m_txedBuffer.at (seqNumberValue) = 0;
+                }
+
+              if (m_retxBuffer.at (seqNumberValue).m_pdu)
+                {
+                  NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from retxBuffer");
+                  m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
+                  m_retxBuffer.at (seqNumberValue).m_pdu = 0;
+                  m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
+                }
 
             }
-            // Check to see if it is time to find the next NACK
-            if ( seqNumberValue == nackSN )
-              {
-                nackSN = rlcAmHeader.PopNack ();
-              }
-
 
-            // If m_vtA has an SN of 1023 and the window wrap flag is true then
-            // it is time to reset m_vtA to 0 an reset the window wrap flag.
-            if ( m_vtA.GetValue() == 1023 && m_windowWrap )
-              {
-                loopCount = 0;
-                m_vtA = 0;
-                m_windowWrap = false;
-             
-                // Wrap around with the transmission window.
-                //nackSN = rlcAmHeader.PopNack ();
-                //NS_LOG_INFO( "Brett - Tx window wrap, new NACK is " << nackSN );
-              }
-            else
-              {
-                loopCount++;               
-              }
-        }
+          if (incrementVtA)
+            {
+              NS_LOG_INFO ("New VT(A) = " << m_vtA);
+              m_vtA.SetModulusBase (m_vtA);
+              m_vtS.SetModulusBase (m_vtA);
+              ackSn.SetModulusBase (m_vtA);
+              sn.SetModulusBase (m_vtA);
+            }
+          
+        } // loop over SN : VT(A) <= SN < ACK SN
+      
+      return;
 
-      NS_LOG_INFO ("New VT(A) = " << m_vtA);
-      return;
     }
   else
     {
@@ -1669,17 +1619,16 @@
     }
 
   // Retransmission Queue HOL time
-  Time retxQueueHolDelay (0);
+  Time retxQueueHolDelay;
   RlcTag retxQueueHolTimeTag;
   if ( m_retxBufferSize > 0 )
     {
       m_retxBuffer.at (m_vtA.GetValue ()).m_pdu->PeekPacketTag (retxQueueHolTimeTag);
       retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
     }
-  else if ( m_txedBufferSize > 0 )
-    {
-      m_txedBuffer.at (m_vtA.GetValue ())->PeekPacketTag (retxQueueHolTimeTag);
-      retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
+  else 
+    {      
+      retxQueueHolDelay = Seconds (0);
     }
 
   LteMacSapProvider::ReportBufferStatusParameters r;