Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(723)

Unified Diff: src/lte/model/lte-rlc-am.cc

Issue 262000043: GSoC 2015 - FinalTerm Milestone - Carrier Aggregation
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/lte/model/lte-rlc-am.h ('k') | src/lte/model/lte-rlc-tm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/lte/model/lte-rlc-am.cc
===================================================================
--- a/src/lte/model/lte-rlc-am.cc
+++ b/src/lte/model/lte-rlc-am.cc
@@ -184,8 +184,7 @@
/**
* MAC SAP
*/
-
-void
+/*void
LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer, uint8_t harqId)
{
NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes);
@@ -720,6 +719,545 @@
m_macSapProvider->TransmitPdu (params);
}
+*/
+void
+LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer, uint8_t harqId, uint8_t componentCarrierId, uint16_t rnti, uint8_t lcid)
+{
+ NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes);
+
+ if (bytes < 4)
+ {
+ // Stingy MAC: In general, we need more bytes.
+ // There are a more restrictive test for each particular case
+ NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small");
+ NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small.\n"
+ << "Your MAC scheduler is assigned too few resource blocks.");
+ return;
+ }
+
+ if ( m_statusPduRequested && ! m_statusProhibitTimer.IsRunning () )
+ {
+ if (bytes < m_statusPduBufferSize)
+ {
+ // Stingy MAC: We need more bytes for the STATUS PDU
+ NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")");
+ NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small for the STATUS PDU (size = " << m_statusPduBufferSize << ")\n"
+ << "Your MAC scheduler is assigned too few resource blocks.");
+ return;
+ }
+
+ NS_LOG_LOGIC ("Sending STATUS PDU");
+
+ Ptr<Packet> packet = Create<Packet> ();
+ LteRlcAmHeader rlcAmHeader;
+ rlcAmHeader.SetControlPdu (LteRlcAmHeader::STATUS_PDU);
+
+ NS_LOG_LOGIC ("Check for SNs to NACK from " << m_vrR.GetValue() << " to " << m_vrMs.GetValue());
+ SequenceNumber10 sn;
+ sn.SetModulusBase (m_vrR);
+ std::map<uint16_t, PduBuffer>::iterator pduIt;
+ for (sn = m_vrR; sn < m_vrMs; sn++)
+ {
+ NS_LOG_LOGIC ("SN = " << sn);
+ 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 ());
+ }
+ }
+ NS_LOG_LOGIC ("SN at end of NACK loop = " << sn);
+ // 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.
+ pduIt = m_rxonBuffer.find (sn.GetValue ());
+ while ((sn < m_vrMs) && (pduIt != m_rxonBuffer.end ()) && (pduIt->second.m_pduComplete))
+ {
+ NS_LOG_LOGIC ("SN = " << sn << " < " << m_vrMs << " = " << (sn < m_vrMs));
+ sn++;
+ NS_LOG_LOGIC ("SN = " << sn);
+ pduIt = m_rxonBuffer.find (sn.GetValue ());
+ }
+
+ NS_ASSERT_MSG (sn <= m_vrMs, "first SN not reported as missing = " << sn << ", VR(MS) = " << m_vrMs);
+ rlcAmHeader.SetAckSn (sn);
+
+
+ NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
+ packet->AddHeader (rlcAmHeader);
+
+ // Send RLC PDU to MAC layer
+ LteMacSapProvider::TransmitPduParameters params;
+ params.pdu = packet;
+ params.rnti = m_rnti;
+ params.lcid = m_lcid;
+ params.layer = layer;
+ params.harqProcessId = harqId;
+ params.componentCarrierId = componentCarrierId;
+
+ m_macSapProvider->TransmitPdu (params);
+
+ m_statusPduRequested = false;
+ m_statusPduBufferSize = 0;
+ m_statusProhibitTimer = Simulator::Schedule (m_statusProhibitTimerValue,
+ &LteRlcAm::ExpireStatusProhibitTimer, this);
+ return;
+ }
+ else if ( m_retxBufferSize > 0 )
+ {
+ NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
+ NS_LOG_LOGIC ("Sending data from Retransmission Buffer");
+ NS_ASSERT (m_vtA < m_vtS);
+ SequenceNumber10 sn;
+ sn.SetModulusBase (m_vtA);
+ bool found = false;
+ for (sn = m_vtA; sn < m_vtS; sn++)
+ {
+ uint16_t seqNumberValue = sn.GetValue ();
+ NS_LOG_LOGIC ("SN = " << seqNumberValue << " m_pdu " << m_retxBuffer.at (seqNumberValue).m_pdu);
+
+ if (m_retxBuffer.at (seqNumberValue).m_pdu != 0)
+ {
+
+ Ptr<Packet> packet = m_retxBuffer.at (seqNumberValue).m_pdu->Copy ();
+
+ if (( packet->GetSize () <= bytes )
+ || m_txOpportunityForRetxAlwaysBigEnough)
+ {
+ found = true;
+ // According to 5.2.1, the data field is left as is, but we rebuild the header
+ LteRlcAmHeader rlcAmHeader;
+ packet->RemoveHeader (rlcAmHeader);
+ NS_LOG_LOGIC ("old AM RLC header: " << rlcAmHeader);
+
+ // Calculate the Polling Bit (5.2.2.1)
+ rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
+
+ NS_LOG_LOGIC ("polling conditions: m_txonBuffer.empty=" << m_txonBuffer.empty ()
+ << " retxBufferSize=" << m_retxBufferSize
+ << " packet->GetSize ()=" << packet->GetSize ());
+ if (((m_txonBuffer.empty ()) && (m_retxBufferSize == packet->GetSize () + rlcAmHeader.GetSerializedSize ()))
+ || (m_vtS >= m_vtMs)
+ || m_pollRetransmitTimerJustExpired)
+ {
+ m_pollRetransmitTimerJustExpired = false;
+ rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
+ m_pduWithoutPoll = 0;
+ m_byteWithoutPoll = 0;
+
+ m_pollSn = m_vtS - 1;
+ NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn);
+
+ if (! m_pollRetransmitTimer.IsRunning () )
+ {
+ NS_LOG_LOGIC ("Start PollRetransmit timer");
+
+ m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
+ &LteRlcAm::ExpirePollRetransmitTimer, this);
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Restart PollRetransmit timer");
+
+ m_pollRetransmitTimer.Cancel ();
+ m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
+ &LteRlcAm::ExpirePollRetransmitTimer, this);
+ }
+ }
+
+ packet->AddHeader (rlcAmHeader);
+ NS_LOG_LOGIC ("new AM RLC header: " << rlcAmHeader);
+
+ // Send RLC PDU to MAC layer
+ LteMacSapProvider::TransmitPduParameters params;
+ params.pdu = packet;
+ params.rnti = m_rnti;
+ params.lcid = m_lcid;
+ params.layer = layer;
+ params.harqProcessId = harqId;
+ params.componentCarrierId = componentCarrierId;
+
+ m_macSapProvider->TransmitPdu (params);
+
+ 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);
+ }
+
+ NS_LOG_INFO ("Move SN = " << seqNumberValue << " back to txedBuffer");
+ m_txedBuffer.at (seqNumberValue).m_pdu = m_retxBuffer.at (seqNumberValue).m_pdu->Copy ();
+ m_txedBuffer.at (seqNumberValue).m_retxCount = m_retxBuffer.at (seqNumberValue).m_retxCount;
+ m_txedBufferSize += m_txedBuffer.at (seqNumberValue).m_pdu->GetSize ();
+
+ m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
+ m_retxBuffer.at (seqNumberValue).m_pdu = 0;
+ m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
+
+ NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);
+
+ return;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for retransmission of the packet (size = " << packet->GetSize () << ")");
+ NS_LOG_LOGIC ("Waiting for bigger TxOpportunity");
+ return;
+ }
+ }
+ }
+ NS_ASSERT_MSG (found, "m_retxBufferSize > 0, but no PDU considered for retx found");
+ }
+ else if ( m_txonBufferSize > 0 )
+ {
+ if (bytes < 7)
+ {
+ // Stingy MAC: We need more bytes for new DATA PDUs.
+ NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for DATA PDU");
+ NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small for DATA PDU\n"
+ << "Your MAC scheduler is assigned too few resource blocks.");
+ return;
+ }
+
+ NS_ASSERT (m_vtS <= m_vtMs);
+ if (m_vtS == m_vtMs)
+ {
+ NS_LOG_INFO ("cannot transmit new RLC PDU due to window stalling");
+ return;
+ }
+
+ NS_LOG_LOGIC ("Sending data from Transmission Buffer");
+ }
+ else
+ {
+ NS_LOG_LOGIC ("No data pending");
+ return;
+ }
+
+ //
+ //
+ // Build new PDU
+ //
+ //
+
+ Ptr<Packet> packet = Create<Packet> ();
+ LteRlcAmHeader rlcAmHeader;
+ rlcAmHeader.SetDataPdu ();
+
+ // Build Data field
+ uint32_t nextSegmentSize = bytes - 4;
+ uint32_t nextSegmentId = 1;
+ uint32_t dataFieldTotalSize = 0;
+ uint32_t dataFieldAddedSize = 0;
+ std::vector < Ptr<Packet> > dataField;
+
+ // Remove the first packet from the transmission buffer.
+ // If only a segment of the packet is taken, then the remaining is given back later
+ if ( m_txonBuffer.size () == 0 )
+ {
+ NS_LOG_LOGIC ("No data pending");
+ return;
+ }
+
+ NS_LOG_LOGIC ("SDUs in TxonBuffer = " << m_txonBuffer.size ());
+ NS_LOG_LOGIC ("First SDU buffer = " << *(m_txonBuffer.begin()));
+ NS_LOG_LOGIC ("First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
+ NS_LOG_LOGIC ("Next segment size = " << nextSegmentSize);
+ NS_LOG_LOGIC ("Remove SDU from TxBuffer");
+ Ptr<Packet> firstSegment = (*(m_txonBuffer.begin ()))->Copy ();
+ m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
+ NS_LOG_LOGIC ("txBufferSize = " << m_txonBufferSize );
+ m_txonBuffer.erase (m_txonBuffer.begin ());
+
+ while ( firstSegment && (firstSegment->GetSize () > 0) && (nextSegmentSize > 0) )
+ {
+ NS_LOG_LOGIC ("WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
+ NS_LOG_LOGIC (" firstSegment size = " << firstSegment->GetSize ());
+ NS_LOG_LOGIC (" nextSegmentSize = " << nextSegmentSize);
+ if ( (firstSegment->GetSize () > nextSegmentSize) ||
+ // Segment larger than 2047 octets can only be mapped to the end of the Data field
+ (firstSegment->GetSize () > 2047)
+ )
+ {
+ // Take the minimum size, due to the 2047-bytes 3GPP exception
+ // This exception is due to the length of the LI field (just 11 bits)
+ uint32_t currSegmentSize = std::min (firstSegment->GetSize (), nextSegmentSize);
+
+ NS_LOG_LOGIC (" IF ( firstSegment > nextSegmentSize ||");
+ NS_LOG_LOGIC (" firstSegment > 2047 )");
+
+ // Segment txBuffer.FirstBuffer and
+ // Give back the remaining segment to the transmission buffer
+ Ptr<Packet> newSegment = firstSegment->CreateFragment (0, currSegmentSize);
+ NS_LOG_LOGIC (" newSegment size = " << newSegment->GetSize ());
+
+ // Status tag of the new and remaining segments
+ // Note: This is the only place where a PDU is segmented and
+ // therefore its status can change
+ LteRlcSduStatusTag oldTag, newTag;
+ firstSegment->RemovePacketTag (oldTag);
+ newSegment->RemovePacketTag (newTag);
+ if (oldTag.GetStatus () == LteRlcSduStatusTag::FULL_SDU)
+ {
+ newTag.SetStatus (LteRlcSduStatusTag::FIRST_SEGMENT);
+ oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
+ }
+ else if (oldTag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT)
+ {
+ newTag.SetStatus (LteRlcSduStatusTag::MIDDLE_SEGMENT);
+ //oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
+ }
+
+ // Give back the remaining segment to the transmission buffer
+ firstSegment->RemoveAtStart (currSegmentSize);
+ NS_LOG_LOGIC (" firstSegment size (after RemoveAtStart) = " << firstSegment->GetSize ());
+ if (firstSegment->GetSize () > 0)
+ {
+ firstSegment->AddPacketTag (oldTag);
+
+ m_txonBuffer.insert (m_txonBuffer.begin (), firstSegment);
+ m_txonBufferSize += (*(m_txonBuffer.begin()))->GetSize ();
+
+ NS_LOG_LOGIC (" Txon buffer: Give back the remaining segment");
+ NS_LOG_LOGIC (" Txon buffers = " << m_txonBuffer.size ());
+ NS_LOG_LOGIC (" Front buffer size = " << (*(m_txonBuffer.begin()))->GetSize ());
+ NS_LOG_LOGIC (" txonBufferSize = " << m_txonBufferSize );
+ }
+ else
+ {
+ // Whole segment was taken, so adjust tag
+ if (newTag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
+ {
+ newTag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
+ }
+ else if (newTag.GetStatus () == LteRlcSduStatusTag::MIDDLE_SEGMENT)
+ {
+ newTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
+ }
+ }
+ // Segment is completely taken or
+ // the remaining segment is given back to the transmission buffer
+ firstSegment = 0;
+
+ // Put status tag once it has been adjusted
+ newSegment->AddPacketTag (newTag);
+
+ // Add Segment to Data field
+ dataFieldAddedSize = newSegment->GetSize ();
+ dataFieldTotalSize += dataFieldAddedSize;
+ dataField.push_back (newSegment);
+ newSegment = 0;
+
+ // ExtensionBit (Next_Segment - 1) = 0
+ rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
+
+ // no LengthIndicator for the last one
+
+ nextSegmentSize -= dataFieldAddedSize;
+ nextSegmentId++;
+
+ // nextSegmentSize MUST be zero (only if segment is smaller or equal to 2047)
+
+ // (NO more segments) ? exit
+ // break;
+ }
+ else if ( (nextSegmentSize - firstSegment->GetSize () <= 2) || (m_txonBuffer.size () == 0) )
+ {
+ NS_LOG_LOGIC (" IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
+
+ // Add txBuffer.FirstBuffer to DataField
+ dataFieldAddedSize = firstSegment->GetSize ();
+ dataFieldTotalSize += dataFieldAddedSize;
+ dataField.push_back (firstSegment);
+ firstSegment = 0;
+
+ // ExtensionBit (Next_Segment - 1) = 0
+ rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
+
+ // no LengthIndicator for the last one
+
+ nextSegmentSize -= dataFieldAddedSize;
+ nextSegmentId++;
+
+ NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
+ if (m_txonBuffer.size () > 0)
+ {
+ NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin()));
+ NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
+ }
+ NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
+
+ // nextSegmentSize <= 2 (only if txBuffer is not empty)
+
+ // (NO more segments) ? exit
+ // break;
+ }
+ else // (firstSegment->GetSize () < m_nextSegmentSize) && (m_txBuffer.size () > 0)
+ {
+ NS_LOG_LOGIC (" IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
+ // Add txBuffer.FirstBuffer to DataField
+ dataFieldAddedSize = firstSegment->GetSize ();
+ dataFieldTotalSize += dataFieldAddedSize;
+ dataField.push_back (firstSegment);
+
+ // ExtensionBit (Next_Segment - 1) = 1
+ rlcAmHeader.PushExtensionBit (LteRlcAmHeader::E_LI_FIELDS_FOLLOWS);
+
+ // LengthIndicator (Next_Segment) = txBuffer.FirstBuffer.length()
+ rlcAmHeader.PushLengthIndicator (firstSegment->GetSize ());
+
+ nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
+ nextSegmentId++;
+
+ NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
+ if (m_txonBuffer.size () > 0)
+ {
+ NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin()));
+ NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
+ }
+ NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
+ NS_LOG_LOGIC (" Remove SDU from TxBuffer");
+
+ // (more segments)
+ firstSegment = (*(m_txonBuffer.begin ()))->Copy ();
+ m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
+ m_txonBuffer.erase (m_txonBuffer.begin ());
+ NS_LOG_LOGIC (" txBufferSize = " << m_txonBufferSize );
+ }
+
+ }
+
+ //
+ // Build RLC header
+ //
+
+ rlcAmHeader.SetSequenceNumber ( m_vtS++ );
+ rlcAmHeader.SetResegmentationFlag (LteRlcAmHeader::PDU);
+ rlcAmHeader.SetLastSegmentFlag (LteRlcAmHeader::LAST_PDU_SEGMENT);
+ rlcAmHeader.SetSegmentOffset (0);
+
+ NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () < m_vtMs, "SN above TX window");
+ NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () >= m_vtA, "SN below TX window");
+
+ // Calculate FramingInfo flag according the status of the SDUs in the DataField
+ uint8_t framingInfo = 0;
+ std::vector< Ptr<Packet> >::iterator it;
+ it = dataField.begin ();
+
+ // FIRST SEGMENT
+ LteRlcSduStatusTag tag;
+ (*it)->RemovePacketTag (tag);
+ if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
+ (tag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
+ )
+ {
+ framingInfo |= LteRlcAmHeader::FIRST_BYTE;
+ }
+ else
+ {
+ framingInfo |= LteRlcAmHeader::NO_FIRST_BYTE;
+ }
+ (*it)->AddPacketTag (tag);
+
+ // Add all SDUs (in DataField) to the Packet
+ while (it < dataField.end ())
+ {
+ NS_LOG_LOGIC ("Adding SDU/segment to packet, length = " << (*it)->GetSize ());
+
+ packet->AddAtEnd (*it);
+ it++;
+ }
+
+ // LAST SEGMENT (Note: There could be only one and be the first one)
+ it--;
+ (*it)->RemovePacketTag (tag);
+ if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
+ (tag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT) )
+ {
+ framingInfo |= LteRlcAmHeader::LAST_BYTE;
+ }
+ else
+ {
+ framingInfo |= LteRlcAmHeader::NO_LAST_BYTE;
+ }
+ (*it)->AddPacketTag (tag);
+
+ // Set the FramingInfo flag after the calculation
+ rlcAmHeader.SetFramingInfo (framingInfo);
+
+
+ // Calculate the Polling Bit (5.2.2.1)
+ rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
+
+ m_pduWithoutPoll++;
+ NS_LOG_LOGIC ("PDU_WITHOUT_POLL = " << m_pduWithoutPoll);
+ m_byteWithoutPoll += packet->GetSize ();
+ NS_LOG_LOGIC ("BYTE_WITHOUT_POLL = " << m_byteWithoutPoll);
+
+ if ( (m_pduWithoutPoll >= m_pollPdu) || (m_byteWithoutPoll >= m_pollByte) ||
+ ( (m_txonBuffer.empty ()) && (m_retxBufferSize == 0) ) ||
+ (m_vtS >= m_vtMs)
+ || m_pollRetransmitTimerJustExpired
+ )
+ {
+ m_pollRetransmitTimerJustExpired = false;
+ rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
+ m_pduWithoutPoll = 0;
+ m_byteWithoutPoll = 0;
+
+ m_pollSn = m_vtS - 1;
+ NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn);
+
+ if (! m_pollRetransmitTimer.IsRunning () )
+ {
+ NS_LOG_LOGIC ("Start PollRetransmit timer");
+
+ m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
+ &LteRlcAm::ExpirePollRetransmitTimer, this);
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Restart PollRetransmit timer");
+
+ m_pollRetransmitTimer.Cancel ();
+ m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValue,
+ &LteRlcAm::ExpirePollRetransmitTimer, this);
+ }
+ }
+
+
+ // Build RLC PDU with DataField and Header
+ NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader);
+ packet->AddHeader (rlcAmHeader);
+
+ // Store new PDU into the Transmitted PDU Buffer
+ NS_LOG_LOGIC ("Put transmitted PDU in the txedBuffer");
+ m_txedBufferSize += packet->GetSize ();
+ m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_pdu = packet->Copy ();
+ m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_retxCount = 0;
+
+ // Sender timestamp
+ RlcTag rlcTag (Simulator::Now ());
+ packet->AddByteTag (rlcTag);
+ m_txPdu (m_rnti, m_lcid, packet->GetSize ());
+
+ // Send RLC PDU to MAC layer
+ LteMacSapProvider::TransmitPduParameters params;
+ params.pdu = packet;
+ params.rnti = m_rnti;
+ params.lcid = m_lcid;
+ params.layer = layer;
+ params.harqProcessId = harqId;
+ params.componentCarrierId = componentCarrierId;
+
+ m_macSapProvider->TransmitPdu (params);
+}
void
LteRlcAm::DoNotifyHarqDeliveryFailure ()
@@ -729,7 +1267,7 @@
void
-LteRlcAm::DoReceivePdu (Ptr<Packet> p)
+LteRlcAm::DoReceivePdu (Ptr<Packet> p, uint16_t rnti, uint8_t lcid)
{
NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
« no previous file with comments | « src/lte/model/lte-rlc-am.h ('k') | src/lte/model/lte-rlc-tm.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b