OLD | NEW |
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC) | 3 * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC) |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 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 | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 /** Report Buffer Status */ | 177 /** Report Buffer Status */ |
178 DoReportBufferStatus (); | 178 DoReportBufferStatus (); |
179 m_rbsTimer.Cancel (); | 179 m_rbsTimer.Cancel (); |
180 m_rbsTimer = Simulator::Schedule (m_rbsTimerValue, &LteRlcAm::ExpireRbsTimer,
this); | 180 m_rbsTimer = Simulator::Schedule (m_rbsTimerValue, &LteRlcAm::ExpireRbsTimer,
this); |
181 } | 181 } |
182 | 182 |
183 | 183 |
184 /** | 184 /** |
185 * MAC SAP | 185 * MAC SAP |
186 */ | 186 */ |
187 | 187 /*void |
188 void | |
189 LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer, uint8_t harqId) | 188 LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer, uint8_t harqId) |
190 { | 189 { |
191 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes); | 190 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes); |
192 | 191 |
193 if (bytes < 4) | 192 if (bytes < 4) |
194 { | 193 { |
195 // Stingy MAC: In general, we need more bytes. | 194 // Stingy MAC: In general, we need more bytes. |
196 // There are a more restrictive test for each particular case | 195 // There are a more restrictive test for each particular case |
197 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small"); | 196 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small"); |
198 NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small.\n
" | 197 NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small.\n
" |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 // Send RLC PDU to MAC layer | 712 // Send RLC PDU to MAC layer |
714 LteMacSapProvider::TransmitPduParameters params; | 713 LteMacSapProvider::TransmitPduParameters params; |
715 params.pdu = packet; | 714 params.pdu = packet; |
716 params.rnti = m_rnti; | 715 params.rnti = m_rnti; |
717 params.lcid = m_lcid; | 716 params.lcid = m_lcid; |
718 params.layer = layer; | 717 params.layer = layer; |
719 params.harqProcessId = harqId; | 718 params.harqProcessId = harqId; |
720 | 719 |
721 m_macSapProvider->TransmitPdu (params); | 720 m_macSapProvider->TransmitPdu (params); |
722 } | 721 } |
| 722 */·· |
| 723 void |
| 724 LteRlcAm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer, uint8_t harqId,
uint8_t componentCarrierId, uint16_t rnti, uint8_t lcid) |
| 725 { |
| 726 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes); |
| 727 |
| 728 if (bytes < 4) |
| 729 { |
| 730 // Stingy MAC: In general, we need more bytes. |
| 731 // There are a more restrictive test for each particular case |
| 732 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small"); |
| 733 NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small.\n
" |
| 734 << "Your MAC scheduler is assigned too few resource blo
cks."); |
| 735 return; |
| 736 } |
| 737 |
| 738 if ( m_statusPduRequested && ! m_statusProhibitTimer.IsRunning () ) |
| 739 { |
| 740 if (bytes < m_statusPduBufferSize) |
| 741 { |
| 742 // Stingy MAC: We need more bytes for the STATUS PDU |
| 743 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for th
e STATUS PDU (size = " << m_statusPduBufferSize << ")"); |
| 744 NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too smal
l for the STATUS PDU (size = " << m_statusPduBufferSize << ")\n" |
| 745 << "Your MAC scheduler is assigned too few resource
blocks."); |
| 746 return; |
| 747 } |
| 748 |
| 749 NS_LOG_LOGIC ("Sending STATUS PDU"); |
| 750 |
| 751 Ptr<Packet> packet = Create<Packet> (); |
| 752 LteRlcAmHeader rlcAmHeader; |
| 753 rlcAmHeader.SetControlPdu (LteRlcAmHeader::STATUS_PDU); |
| 754 ····· |
| 755 NS_LOG_LOGIC ("Check for SNs to NACK from " << m_vrR.GetValue() << " to "
<< m_vrMs.GetValue()); |
| 756 SequenceNumber10 sn; |
| 757 sn.SetModulusBase (m_vrR); |
| 758 std::map<uint16_t, PduBuffer>::iterator pduIt; |
| 759 for (sn = m_vrR; sn < m_vrMs; sn++)· |
| 760 { |
| 761 NS_LOG_LOGIC ("SN = " << sn);·········· |
| 762 if (!rlcAmHeader.OneMoreNackWouldFitIn (bytes)) |
| 763 { |
| 764 NS_LOG_LOGIC ("Can't fit more NACKs in STATUS PDU"); |
| 765 break; |
| 766 }·········· |
| 767 pduIt = m_rxonBuffer.find (sn.GetValue ()); |
| 768 if (pduIt == m_rxonBuffer.end () || (!(pduIt->second.m_pduComplete))) |
| 769 { |
| 770 NS_LOG_LOGIC ("adding NACK_SN " << sn.GetValue ()); |
| 771 rlcAmHeader.PushNack (sn.GetValue ());·············· |
| 772 }·········· |
| 773 } |
| 774 NS_LOG_LOGIC ("SN at end of NACK loop = " << sn); |
| 775 // 3GPP TS 36.322 section 6.2.2.1.4 ACK SN |
| 776 // find the SN of the next not received RLC Data PDU· |
| 777 // which is not reported as missing in the STATUS PDU.· |
| 778 pduIt = m_rxonBuffer.find (sn.GetValue ()); |
| 779 while ((sn < m_vrMs) && (pduIt != m_rxonBuffer.end ()) && (pduIt->second.m
_pduComplete))············ |
| 780 { |
| 781 NS_LOG_LOGIC ("SN = " << sn << " < " << m_vrMs << " = " << (sn < m_vrM
s)); |
| 782 sn++; |
| 783 NS_LOG_LOGIC ("SN = " << sn); |
| 784 pduIt = m_rxonBuffer.find (sn.GetValue ()); |
| 785 } |
| 786 ······ |
| 787 NS_ASSERT_MSG (sn <= m_vrMs, "first SN not reported as missing = " << sn <
< ", VR(MS) = " << m_vrMs);······ |
| 788 rlcAmHeader.SetAckSn (sn);· |
| 789 |
| 790 |
| 791 NS_LOG_LOGIC ("RLC header: " << rlcAmHeader); |
| 792 packet->AddHeader (rlcAmHeader); |
| 793 |
| 794 // Send RLC PDU to MAC layer |
| 795 LteMacSapProvider::TransmitPduParameters params; |
| 796 params.pdu = packet; |
| 797 params.rnti = m_rnti; |
| 798 params.lcid = m_lcid; |
| 799 params.layer = layer; |
| 800 params.harqProcessId = harqId; |
| 801 params.componentCarrierId = componentCarrierId; |
| 802 |
| 803 m_macSapProvider->TransmitPdu (params); |
| 804 |
| 805 m_statusPduRequested = false; |
| 806 m_statusPduBufferSize = 0; |
| 807 m_statusProhibitTimer = Simulator::Schedule (m_statusProhibitTimerValue, |
| 808 &LteRlcAm::ExpireStatusProhib
itTimer, this); |
| 809 return; |
| 810 } |
| 811 else if ( m_retxBufferSize > 0 ) |
| 812 { |
| 813 NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize);······ |
| 814 NS_LOG_LOGIC ("Sending data from Retransmission Buffer"); |
| 815 NS_ASSERT (m_vtA < m_vtS); |
| 816 SequenceNumber10 sn; |
| 817 sn.SetModulusBase (m_vtA); |
| 818 bool found = false; |
| 819 for (sn = m_vtA; sn < m_vtS; sn++)· |
| 820 { |
| 821 uint16_t seqNumberValue = sn.GetValue (); |
| 822 NS_LOG_LOGIC ("SN = " << seqNumberValue << " m_pdu " << m_retxBuffer.a
t (seqNumberValue).m_pdu); |
| 823 |
| 824 if (m_retxBuffer.at (seqNumberValue).m_pdu != 0) |
| 825 {············ |
| 826 |
| 827 Ptr<Packet> packet = m_retxBuffer.at (seqNumberValue).m_pdu->Copy
(); |
| 828 ·············· |
| 829 if (( packet->GetSize () <= bytes ) |
| 830 || m_txOpportunityForRetxAlwaysBigEnough) |
| 831 { |
| 832 found = true; |
| 833 // According to 5.2.1, the data field is left as is, but we re
build the header |
| 834 LteRlcAmHeader rlcAmHeader; |
| 835 packet->RemoveHeader (rlcAmHeader); |
| 836 NS_LOG_LOGIC ("old AM RLC header: " << rlcAmHeader); |
| 837 |
| 838 // Calculate the Polling Bit (5.2.2.1) |
| 839 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_R
EQUESTED); |
| 840 |
| 841 NS_LOG_LOGIC ("polling conditions: m_txonBuffer.empty=" << m_t
xonBuffer.empty ()· |
| 842 << " retxBufferSize=" << m_retxBufferSize |
| 843 << " packet->GetSize ()=" << packet->GetSize ())
; |
| 844 if (((m_txonBuffer.empty ()) && (m_retxBufferSize == packet->G
etSize () + rlcAmHeader.GetSerializedSize ()))· |
| 845 || (m_vtS >= m_vtMs) |
| 846 || m_pollRetransmitTimerJustExpired) |
| 847 { |
| 848 m_pollRetransmitTimerJustExpired = false; |
| 849 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_I
S_REQUESTED); |
| 850 m_pduWithoutPoll = 0; |
| 851 m_byteWithoutPoll = 0; |
| 852 |
| 853 m_pollSn = m_vtS - 1; |
| 854 NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn); |
| 855 |
| 856 if (! m_pollRetransmitTimer.IsRunning () ) |
| 857 { |
| 858 NS_LOG_LOGIC ("Start PollRetransmit timer"); |
| 859 |
| 860 m_pollRetransmitTimer = Simulator::Schedule (m_pollRet
ransmitTimerValue, |
| 861 &LteRlcAm
::ExpirePollRetransmitTimer, this); |
| 862 } |
| 863 else |
| 864 { |
| 865 NS_LOG_LOGIC ("Restart PollRetransmit timer"); |
| 866 |
| 867 m_pollRetransmitTimer.Cancel (); |
| 868 m_pollRetransmitTimer = Simulator::Schedule (m_pollRet
ransmitTimerValue, |
| 869 &LteRlcAm
::ExpirePollRetransmitTimer, this); |
| 870 } |
| 871 } |
| 872 |
| 873 packet->AddHeader (rlcAmHeader); |
| 874 NS_LOG_LOGIC ("new AM RLC header: " << rlcAmHeader); |
| 875 ·················· |
| 876 // Send RLC PDU to MAC layer |
| 877 LteMacSapProvider::TransmitPduParameters params; |
| 878 params.pdu = packet; |
| 879 params.rnti = m_rnti; |
| 880 params.lcid = m_lcid; |
| 881 params.layer = layer; |
| 882 params.harqProcessId = harqId; |
| 883 params.componentCarrierId = componentCarrierId; |
| 884 ·················· |
| 885 m_macSapProvider->TransmitPdu (params); |
| 886 |
| 887 m_retxBuffer.at (seqNumberValue).m_retxCount++; |
| 888 NS_LOG_INFO ("Incr RETX_COUNT for SN = " << seqNumberValue); |
| 889 if (m_retxBuffer.at (seqNumberValue).m_retxCount >= m_maxRetxT
hreshold) |
| 890 { |
| 891 NS_LOG_INFO ("Max RETX_COUNT for SN = " << seqNumberValue)
; |
| 892 } |
| 893 |
| 894 NS_LOG_INFO ("Move SN = " << seqNumberValue << " back to txedB
uffer"); |
| 895 m_txedBuffer.at (seqNumberValue).m_pdu = m_retxBuffer.at (seqN
umberValue).m_pdu->Copy (); |
| 896 m_txedBuffer.at (seqNumberValue).m_retxCount = m_retxBuffer.at
(seqNumberValue).m_retxCount; |
| 897 m_txedBufferSize += m_txedBuffer.at (seqNumberValue).m_pdu->Ge
tSize (); |
| 898 |
| 899 m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->Ge
tSize (); |
| 900 m_retxBuffer.at (seqNumberValue).m_pdu = 0; |
| 901 m_retxBuffer.at (seqNumberValue).m_retxCount = 0; |
| 902 ·················· |
| 903 NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize); |
| 904 |
| 905 return; |
| 906 } |
| 907 else |
| 908 { |
| 909 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too smal
l for retransmission of the packet (size = " << packet->GetSize () << ")"); |
| 910 NS_LOG_LOGIC ("Waiting for bigger TxOpportunity"); |
| 911 return; |
| 912 } |
| 913 } |
| 914 } |
| 915 NS_ASSERT_MSG (found, "m_retxBufferSize > 0, but no PDU considered for ret
x found"); |
| 916 } |
| 917 else if ( m_txonBufferSize > 0 ) |
| 918 { |
| 919 if (bytes < 7) |
| 920 { |
| 921 // Stingy MAC: We need more bytes for new DATA PDUs. |
| 922 NS_LOG_LOGIC ("TxOpportunity (size = " << bytes << ") too small for DATA
PDU"); |
| 923 NS_ASSERT_MSG (false, "TxOpportunity (size = " << bytes << ") too small
for DATA PDU\n" |
| 924 << "Your MAC scheduler is assigned too few resource b
locks."); |
| 925 return; |
| 926 } |
| 927 |
| 928 NS_ASSERT (m_vtS <= m_vtMs); |
| 929 if (m_vtS == m_vtMs) |
| 930 { |
| 931 NS_LOG_INFO ("cannot transmit new RLC PDU due to window stalling"); |
| 932 return; |
| 933 } |
| 934 |
| 935 NS_LOG_LOGIC ("Sending data from Transmission Buffer"); |
| 936 } |
| 937 else |
| 938 { |
| 939 NS_LOG_LOGIC ("No data pending"); |
| 940 return; |
| 941 } |
| 942 |
| 943 // |
| 944 // |
| 945 // Build new PDU |
| 946 // |
| 947 // |
| 948 |
| 949 Ptr<Packet> packet = Create<Packet> (); |
| 950 LteRlcAmHeader rlcAmHeader; |
| 951 rlcAmHeader.SetDataPdu (); |
| 952 |
| 953 // Build Data field |
| 954 uint32_t nextSegmentSize = bytes - 4; |
| 955 uint32_t nextSegmentId = 1; |
| 956 uint32_t dataFieldTotalSize = 0; |
| 957 uint32_t dataFieldAddedSize = 0; |
| 958 std::vector < Ptr<Packet> > dataField; |
| 959 |
| 960 // Remove the first packet from the transmission buffer. |
| 961 // If only a segment of the packet is taken, then the remaining is given back
later |
| 962 if ( m_txonBuffer.size () == 0 ) |
| 963 { |
| 964 NS_LOG_LOGIC ("No data pending"); |
| 965 return; |
| 966 } |
| 967 |
| 968 NS_LOG_LOGIC ("SDUs in TxonBuffer = " << m_txonBuffer.size ()); |
| 969 NS_LOG_LOGIC ("First SDU buffer = " << *(m_txonBuffer.begin())); |
| 970 NS_LOG_LOGIC ("First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ())
; |
| 971 NS_LOG_LOGIC ("Next segment size = " << nextSegmentSize); |
| 972 NS_LOG_LOGIC ("Remove SDU from TxBuffer"); |
| 973 Ptr<Packet> firstSegment = (*(m_txonBuffer.begin ()))->Copy (); |
| 974 m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize (); |
| 975 NS_LOG_LOGIC ("txBufferSize = " << m_txonBufferSize ); |
| 976 m_txonBuffer.erase (m_txonBuffer.begin ()); |
| 977 |
| 978 while ( firstSegment && (firstSegment->GetSize () > 0) && (nextSegmentSize > 0
) ) |
| 979 { |
| 980 NS_LOG_LOGIC ("WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSe
gmentSize > 0 )"); |
| 981 NS_LOG_LOGIC (" firstSegment size = " << firstSegment->GetSize ()); |
| 982 NS_LOG_LOGIC (" nextSegmentSize = " << nextSegmentSize); |
| 983 if ( (firstSegment->GetSize () > nextSegmentSize) || |
| 984 // Segment larger than 2047 octets can only be mapped to the end of t
he Data field |
| 985 (firstSegment->GetSize () > 2047) |
| 986 ) |
| 987 { |
| 988 // Take the minimum size, due to the 2047-bytes 3GPP exception |
| 989 // This exception is due to the length of the LI field (just 11 bits) |
| 990 uint32_t currSegmentSize = std::min (firstSegment->GetSize (), nextSeg
mentSize); |
| 991 |
| 992 NS_LOG_LOGIC (" IF ( firstSegment > nextSegmentSize ||"); |
| 993 NS_LOG_LOGIC (" firstSegment > 2047 )"); |
| 994 |
| 995 // Segment txBuffer.FirstBuffer and |
| 996 // Give back the remaining segment to the transmission buffer |
| 997 Ptr<Packet> newSegment = firstSegment->CreateFragment (0, currSegmentS
ize); |
| 998 NS_LOG_LOGIC (" newSegment size = " << newSegment->GetSize ()); |
| 999 |
| 1000 // Status tag of the new and remaining segments |
| 1001 // Note: This is the only place where a PDU is segmented and |
| 1002 // therefore its status can change |
| 1003 LteRlcSduStatusTag oldTag, newTag; |
| 1004 firstSegment->RemovePacketTag (oldTag); |
| 1005 newSegment->RemovePacketTag (newTag); |
| 1006 if (oldTag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) |
| 1007 { |
| 1008 newTag.SetStatus (LteRlcSduStatusTag::FIRST_SEGMENT); |
| 1009 oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT); |
| 1010 } |
| 1011 else if (oldTag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT) |
| 1012 { |
| 1013 newTag.SetStatus (LteRlcSduStatusTag::MIDDLE_SEGMENT); |
| 1014 //oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT); |
| 1015 } |
| 1016 |
| 1017 // Give back the remaining segment to the transmission buffer |
| 1018 firstSegment->RemoveAtStart (currSegmentSize); |
| 1019 NS_LOG_LOGIC (" firstSegment size (after RemoveAtStart) = " << firs
tSegment->GetSize ()); |
| 1020 if (firstSegment->GetSize () > 0) |
| 1021 { |
| 1022 firstSegment->AddPacketTag (oldTag); |
| 1023 |
| 1024 m_txonBuffer.insert (m_txonBuffer.begin (), firstSegment); |
| 1025 m_txonBufferSize += (*(m_txonBuffer.begin()))->GetSize (); |
| 1026 |
| 1027 NS_LOG_LOGIC (" Txon buffer: Give back the remaining segment"); |
| 1028 NS_LOG_LOGIC (" Txon buffers = " << m_txonBuffer.size ()); |
| 1029 NS_LOG_LOGIC (" Front buffer size = " << (*(m_txonBuffer.begin(
)))->GetSize ()); |
| 1030 NS_LOG_LOGIC (" txonBufferSize = " << m_txonBufferSize ); |
| 1031 } |
| 1032 else |
| 1033 { |
| 1034 // Whole segment was taken, so adjust tag |
| 1035 if (newTag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT) |
| 1036 { |
| 1037 newTag.SetStatus (LteRlcSduStatusTag::FULL_SDU); |
| 1038 } |
| 1039 else if (newTag.GetStatus () == LteRlcSduStatusTag::MIDDLE_SEGMENT
) |
| 1040 { |
| 1041 newTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT); |
| 1042 } |
| 1043 } |
| 1044 // Segment is completely taken or |
| 1045 // the remaining segment is given back to the transmission buffer |
| 1046 firstSegment = 0; |
| 1047 |
| 1048 // Put status tag once it has been adjusted |
| 1049 newSegment->AddPacketTag (newTag); |
| 1050 |
| 1051 // Add Segment to Data field |
| 1052 dataFieldAddedSize = newSegment->GetSize (); |
| 1053 dataFieldTotalSize += dataFieldAddedSize; |
| 1054 dataField.push_back (newSegment); |
| 1055 newSegment = 0; |
| 1056 |
| 1057 // ExtensionBit (Next_Segment - 1) = 0 |
| 1058 rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS); |
| 1059 |
| 1060 // no LengthIndicator for the last one |
| 1061 |
| 1062 nextSegmentSize -= dataFieldAddedSize; |
| 1063 nextSegmentId++; |
| 1064 |
| 1065 // nextSegmentSize MUST be zero (only if segment is smaller or equal t
o 2047) |
| 1066 |
| 1067 // (NO more segments) ? exit |
| 1068 // break; |
| 1069 } |
| 1070 else if ( (nextSegmentSize - firstSegment->GetSize () <= 2) || (m_txonBuff
er.size () == 0) ) |
| 1071 { |
| 1072 NS_LOG_LOGIC (" IF nextSegmentSize - firstSegment->GetSize () <= 2
|| txonBuffer.size == 0"); |
| 1073 |
| 1074 // Add txBuffer.FirstBuffer to DataField |
| 1075 dataFieldAddedSize = firstSegment->GetSize (); |
| 1076 dataFieldTotalSize += dataFieldAddedSize; |
| 1077 dataField.push_back (firstSegment); |
| 1078 firstSegment = 0; |
| 1079 |
| 1080 // ExtensionBit (Next_Segment - 1) = 0 |
| 1081 rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS); |
| 1082 |
| 1083 // no LengthIndicator for the last one |
| 1084 |
| 1085 nextSegmentSize -= dataFieldAddedSize; |
| 1086 nextSegmentId++; |
| 1087 |
| 1088 NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ()); |
| 1089 if (m_txonBuffer.size () > 0) |
| 1090 { |
| 1091 NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.beg
in())); |
| 1092 NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.be
gin()))->GetSize ()); |
| 1093 } |
| 1094 NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize); |
| 1095 |
| 1096 // nextSegmentSize <= 2 (only if txBuffer is not empty) |
| 1097 |
| 1098 // (NO more segments) ? exit |
| 1099 // break; |
| 1100 } |
| 1101 else // (firstSegment->GetSize () < m_nextSegmentSize) && (m_txBuffer.size
() > 0) |
| 1102 { |
| 1103 NS_LOG_LOGIC (" IF firstSegment < NextSegmentSize && txonBuffer.siz
e > 0"); |
| 1104 // Add txBuffer.FirstBuffer to DataField |
| 1105 dataFieldAddedSize = firstSegment->GetSize (); |
| 1106 dataFieldTotalSize += dataFieldAddedSize; |
| 1107 dataField.push_back (firstSegment); |
| 1108 |
| 1109 // ExtensionBit (Next_Segment - 1) = 1 |
| 1110 rlcAmHeader.PushExtensionBit (LteRlcAmHeader::E_LI_FIELDS_FOLLOWS); |
| 1111 |
| 1112 // LengthIndicator (Next_Segment) = txBuffer.FirstBuffer.length() |
| 1113 rlcAmHeader.PushLengthIndicator (firstSegment->GetSize ()); |
| 1114 |
| 1115 nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedS
ize; |
| 1116 nextSegmentId++; |
| 1117 |
| 1118 NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ()); |
| 1119 if (m_txonBuffer.size () > 0) |
| 1120 { |
| 1121 NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.beg
in())); |
| 1122 NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.be
gin()))->GetSize ()); |
| 1123 } |
| 1124 NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize); |
| 1125 NS_LOG_LOGIC (" Remove SDU from TxBuffer"); |
| 1126 |
| 1127 // (more segments) |
| 1128 firstSegment = (*(m_txonBuffer.begin ()))->Copy (); |
| 1129 m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize (); |
| 1130 m_txonBuffer.erase (m_txonBuffer.begin ()); |
| 1131 NS_LOG_LOGIC (" txBufferSize = " << m_txonBufferSize ); |
| 1132 } |
| 1133 |
| 1134 } |
| 1135 |
| 1136 // |
| 1137 // Build RLC header |
| 1138 // |
| 1139 |
| 1140 rlcAmHeader.SetSequenceNumber ( m_vtS++ ); |
| 1141 rlcAmHeader.SetResegmentationFlag (LteRlcAmHeader::PDU); |
| 1142 rlcAmHeader.SetLastSegmentFlag (LteRlcAmHeader::LAST_PDU_SEGMENT); |
| 1143 rlcAmHeader.SetSegmentOffset (0); |
| 1144 |
| 1145 NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () < m_vtMs, "SN above TX window")
; |
| 1146 NS_ASSERT_MSG(rlcAmHeader.GetSequenceNumber () >= m_vtA, "SN below TX window")
; |
| 1147 |
| 1148 // Calculate FramingInfo flag according the status of the SDUs in the DataFiel
d |
| 1149 uint8_t framingInfo = 0; |
| 1150 std::vector< Ptr<Packet> >::iterator it; |
| 1151 it = dataField.begin (); |
| 1152 |
| 1153 // FIRST SEGMENT |
| 1154 LteRlcSduStatusTag tag; |
| 1155 (*it)->RemovePacketTag (tag); |
| 1156 if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) || |
| 1157 (tag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT) |
| 1158 ) |
| 1159 { |
| 1160 framingInfo |= LteRlcAmHeader::FIRST_BYTE; |
| 1161 } |
| 1162 else |
| 1163 { |
| 1164 framingInfo |= LteRlcAmHeader::NO_FIRST_BYTE; |
| 1165 } |
| 1166 (*it)->AddPacketTag (tag); |
| 1167 |
| 1168 // Add all SDUs (in DataField) to the Packet |
| 1169 while (it < dataField.end ()) |
| 1170 { |
| 1171 NS_LOG_LOGIC ("Adding SDU/segment to packet, length = " << (*it)->GetSize
()); |
| 1172 |
| 1173 packet->AddAtEnd (*it); |
| 1174 it++; |
| 1175 } |
| 1176 |
| 1177 // LAST SEGMENT (Note: There could be only one and be the first one) |
| 1178 it--; |
| 1179 (*it)->RemovePacketTag (tag); |
| 1180 if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) || |
| 1181 (tag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT) ) |
| 1182 { |
| 1183 framingInfo |= LteRlcAmHeader::LAST_BYTE; |
| 1184 } |
| 1185 else |
| 1186 { |
| 1187 framingInfo |= LteRlcAmHeader::NO_LAST_BYTE; |
| 1188 } |
| 1189 (*it)->AddPacketTag (tag); |
| 1190 |
| 1191 // Set the FramingInfo flag after the calculation |
| 1192 rlcAmHeader.SetFramingInfo (framingInfo); |
| 1193 |
| 1194 |
| 1195 // Calculate the Polling Bit (5.2.2.1) |
| 1196 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED); |
| 1197 |
| 1198 m_pduWithoutPoll++; |
| 1199 NS_LOG_LOGIC ("PDU_WITHOUT_POLL = " << m_pduWithoutPoll); |
| 1200 m_byteWithoutPoll += packet->GetSize (); |
| 1201 NS_LOG_LOGIC ("BYTE_WITHOUT_POLL = " << m_byteWithoutPoll); |
| 1202 |
| 1203 if ( (m_pduWithoutPoll >= m_pollPdu) || (m_byteWithoutPoll >= m_pollByte) || |
| 1204 ( (m_txonBuffer.empty ()) && (m_retxBufferSize == 0) ) || |
| 1205 (m_vtS >= m_vtMs) |
| 1206 || m_pollRetransmitTimerJustExpired |
| 1207 ) |
| 1208 { |
| 1209 m_pollRetransmitTimerJustExpired = false; |
| 1210 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED); |
| 1211 m_pduWithoutPoll = 0; |
| 1212 m_byteWithoutPoll = 0; |
| 1213 |
| 1214 m_pollSn = m_vtS - 1; |
| 1215 NS_LOG_LOGIC ("New POLL_SN = " << m_pollSn); |
| 1216 |
| 1217 if (! m_pollRetransmitTimer.IsRunning () ) |
| 1218 { |
| 1219 NS_LOG_LOGIC ("Start PollRetransmit timer"); |
| 1220 |
| 1221 m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValu
e, |
| 1222 &LteRlcAm::ExpirePollRetr
ansmitTimer, this); |
| 1223 } |
| 1224 else |
| 1225 { |
| 1226 NS_LOG_LOGIC ("Restart PollRetransmit timer"); |
| 1227 |
| 1228 m_pollRetransmitTimer.Cancel (); |
| 1229 m_pollRetransmitTimer = Simulator::Schedule (m_pollRetransmitTimerValu
e, |
| 1230 &LteRlcAm::ExpirePollRetr
ansmitTimer, this); |
| 1231 } |
| 1232 } |
| 1233 |
| 1234 |
| 1235 // Build RLC PDU with DataField and Header |
| 1236 NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader); |
| 1237 packet->AddHeader (rlcAmHeader); |
| 1238 |
| 1239 // Store new PDU into the Transmitted PDU Buffer |
| 1240 NS_LOG_LOGIC ("Put transmitted PDU in the txedBuffer"); |
| 1241 m_txedBufferSize += packet->GetSize (); |
| 1242 m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_pdu = packe
t->Copy (); |
| 1243 m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_retxCount =
0; |
| 1244 |
| 1245 // Sender timestamp |
| 1246 RlcTag rlcTag (Simulator::Now ()); |
| 1247 packet->AddByteTag (rlcTag); |
| 1248 m_txPdu (m_rnti, m_lcid, packet->GetSize ()); |
| 1249 |
| 1250 // Send RLC PDU to MAC layer |
| 1251 LteMacSapProvider::TransmitPduParameters params; |
| 1252 params.pdu = packet; |
| 1253 params.rnti = m_rnti; |
| 1254 params.lcid = m_lcid; |
| 1255 params.layer = layer; |
| 1256 params.harqProcessId = harqId; |
| 1257 params.componentCarrierId = componentCarrierId; |
| 1258 |
| 1259 m_macSapProvider->TransmitPdu (params); |
| 1260 } |
723 | 1261 |
724 void | 1262 void |
725 LteRlcAm::DoNotifyHarqDeliveryFailure () | 1263 LteRlcAm::DoNotifyHarqDeliveryFailure () |
726 { | 1264 { |
727 NS_LOG_FUNCTION (this); | 1265 NS_LOG_FUNCTION (this); |
728 } | 1266 } |
729 | 1267 |
730 | 1268 |
731 void | 1269 void |
732 LteRlcAm::DoReceivePdu (Ptr<Packet> p) | 1270 LteRlcAm::DoReceivePdu (Ptr<Packet> p, uint16_t rnti, uint8_t lcid) |
733 { | 1271 { |
734 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ()); | 1272 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ()); |
735 | 1273 |
736 // Receiver timestamp | 1274 // Receiver timestamp |
737 RlcTag rlcTag; | 1275 RlcTag rlcTag; |
738 Time delay; | 1276 Time delay; |
739 if (p->FindFirstMatchingByteTag (rlcTag)) | 1277 if (p->FindFirstMatchingByteTag (rlcTag)) |
740 { | 1278 { |
741 delay = Simulator::Now() - rlcTag.GetSenderTimestamp (); | 1279 delay = Simulator::Now() - rlcTag.GetSenderTimestamp (); |
742 } | 1280 } |
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1705 NS_LOG_LOGIC ("RBS Timer expires"); | 2243 NS_LOG_LOGIC ("RBS Timer expires"); |
1706 | 2244 |
1707 if (m_txonBufferSize + m_txedBufferSize + m_retxBufferSize > 0) | 2245 if (m_txonBufferSize + m_txedBufferSize + m_retxBufferSize > 0) |
1708 { | 2246 { |
1709 DoReportBufferStatus (); | 2247 DoReportBufferStatus (); |
1710 m_rbsTimer = Simulator::Schedule (m_rbsTimerValue, &LteRlcAm::ExpireRbsTim
er, this); | 2248 m_rbsTimer = Simulator::Schedule (m_rbsTimerValue, &LteRlcAm::ExpireRbsTim
er, this); |
1711 } | 2249 } |
1712 } | 2250 } |
1713 | 2251 |
1714 } // namespace ns3 | 2252 } // namespace ns3 |
OLD | NEW |