OLD | NEW |
(Empty) | |
| 1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2011,2012 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 * Nicola Baldo <nbaldo@cttc.es> |
| 20 */ |
| 21 |
| 22 #include "ns3/simulator.h" |
| 23 #include "ns3/log.h" |
| 24 |
| 25 #include "ns3/nist-lte-rlc-tm.h" |
| 26 #include "ns3/nist-lte-rlc-tag.h" |
| 27 |
| 28 namespace ns3 { |
| 29 |
| 30 NS_LOG_COMPONENT_DEFINE ("NistLteRlcTm"); |
| 31 |
| 32 NS_OBJECT_ENSURE_REGISTERED (NistLteRlcTm); |
| 33 |
| 34 NistLteRlcTm::NistLteRlcTm () |
| 35 : m_maxTxBufferSize (0), |
| 36 m_txBufferSize (0) |
| 37 { |
| 38 NS_LOG_FUNCTION (this); |
| 39 } |
| 40 |
| 41 NistLteRlcTm::~NistLteRlcTm () |
| 42 { |
| 43 NS_LOG_FUNCTION (this); |
| 44 } |
| 45 |
| 46 TypeId |
| 47 NistLteRlcTm::GetTypeId (void) |
| 48 { |
| 49 static TypeId tid = TypeId ("ns3::NistLteRlcTm") |
| 50 .SetParent<NistLteRlc> () |
| 51 .AddConstructor<NistLteRlcTm> () |
| 52 .AddAttribute ("MaxTxBufferSize", |
| 53 "Maximum Size of the Transmission Buffer (in Bytes)", |
| 54 UintegerValue (2 * 1024 * 1024), |
| 55 MakeUintegerAccessor (&NistLteRlcTm::m_maxTxBufferSize), |
| 56 MakeUintegerChecker<uint32_t> ()) |
| 57 ; |
| 58 return tid; |
| 59 } |
| 60 |
| 61 void |
| 62 NistLteRlcTm::DoDispose () |
| 63 { |
| 64 NS_LOG_FUNCTION (this); |
| 65 m_rbsTimer.Cancel (); |
| 66 m_txBuffer.clear (); |
| 67 |
| 68 NistLteRlc::DoDispose (); |
| 69 } |
| 70 |
| 71 |
| 72 /** |
| 73 * RLC SAP |
| 74 */ |
| 75 |
| 76 void |
| 77 NistLteRlcTm::DoTransmitPdcpPdu (Ptr<Packet> p) |
| 78 { |
| 79 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ()); |
| 80 |
| 81 if (m_txBufferSize + p->GetSize () <= m_maxTxBufferSize) |
| 82 { |
| 83 /** Store arrival time */ |
| 84 NistRlcTag timeTag (Simulator::Now ()); |
| 85 p->AddPacketTag (timeTag); |
| 86 |
| 87 NS_LOG_LOGIC ("Tx Buffer: New packet added"); |
| 88 m_txBuffer.push_back (p); |
| 89 m_txBufferSize += p->GetSize (); |
| 90 NS_LOG_LOGIC ("NumOfBuffers = " << m_txBuffer.size() ); |
| 91 NS_LOG_LOGIC ("txBufferSize = " << m_txBufferSize); |
| 92 } |
| 93 else |
| 94 { |
| 95 // Discard full RLC SDU |
| 96 NS_LOG_LOGIC ("TxBuffer is full. RLC SDU discarded"); |
| 97 NS_LOG_LOGIC ("MaxTxBufferSize = " << m_maxTxBufferSize); |
| 98 NS_LOG_LOGIC ("txBufferSize = " << m_txBufferSize); |
| 99 NS_LOG_LOGIC ("packet size = " << p->GetSize ()); |
| 100 } |
| 101 |
| 102 /** Report Buffer NistStatus */ |
| 103 DoReportBufferNistStatus (); |
| 104 m_rbsTimer.Cancel (); |
| 105 } |
| 106 |
| 107 |
| 108 /** |
| 109 * MAC SAP |
| 110 */ |
| 111 |
| 112 void |
| 113 NistLteRlcTm::DoNotifyTxOpportunity (uint32_t bytes, uint8_t layer, uint8_t harq
Id) |
| 114 { |
| 115 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << bytes << (uint32_t) l
ayer << (uint32_t) harqId); |
| 116 |
| 117 // 5.1.1.1 Transmit operations· |
| 118 // 5.1.1.1.1 General |
| 119 // When submitting a new TMD PDU to lower layer, the transmitting TM RLC entit
y shall: |
| 120 // - submit a RLC SDU without any modification to lower layer. |
| 121 |
| 122 |
| 123 if ( m_txBuffer.size () == 0 ) |
| 124 { |
| 125 NS_LOG_LOGIC ("No data pending"); |
| 126 return; |
| 127 } |
| 128 |
| 129 Ptr<Packet> packet = (*(m_txBuffer.begin ()))->Copy (); |
| 130 |
| 131 if (bytes < packet->GetSize ()) |
| 132 { |
| 133 NS_LOG_WARN ("TX opportunity too small = " << bytes << " (PDU size: " << p
acket->GetSize () << ")"); |
| 134 return; |
| 135 } |
| 136 |
| 137 m_txBufferSize -= (*(m_txBuffer.begin()))->GetSize (); |
| 138 m_txBuffer.erase (m_txBuffer.begin ()); |
| 139 · |
| 140 // Sender timestamp |
| 141 NistRlcTag rlcTag (Simulator::Now ()); |
| 142 packet->AddByteTag (rlcTag); |
| 143 m_txPdu (m_rnti, m_lcid, packet->GetSize ()); |
| 144 |
| 145 // Send RLC PDU to MAC layer |
| 146 NistLteMacSapProvider::NistTransmitPduParameters params; |
| 147 params.pdu = packet; |
| 148 params.rnti = m_rnti; |
| 149 params.lcid = m_lcid; |
| 150 params.srcL2Id = m_srcL2Id; |
| 151 params.dstL2Id = m_dstL2Id; |
| 152 params.layer = layer; |
| 153 params.harqProcessId = harqId; |
| 154 |
| 155 m_macSapProvider->TransmitPdu (params); |
| 156 |
| 157 if (! m_txBuffer.empty ()) |
| 158 { |
| 159 m_rbsTimer.Cancel (); |
| 160 m_rbsTimer = Simulator::Schedule (MilliSeconds (10), &NistLteRlcTm::Expire
RbsTimer, this); |
| 161 } |
| 162 } |
| 163 |
| 164 void |
| 165 NistLteRlcTm::DoNotifyHarqDeliveryFailure () |
| 166 { |
| 167 NS_LOG_FUNCTION (this); |
| 168 } |
| 169 |
| 170 void |
| 171 NistLteRlcTm::DoReceivePdu (Ptr<Packet> p) |
| 172 { |
| 173 NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ()); |
| 174 |
| 175 // Receiver timestamp |
| 176 NistRlcTag rlcTag; |
| 177 Time delay; |
| 178 if (p->FindFirstMatchingByteTag (rlcTag)) |
| 179 { |
| 180 delay = Simulator::Now() - rlcTag.GetSenderTimestamp (); |
| 181 } |
| 182 m_rxPdu (m_rnti, m_lcid, p->GetSize (), delay.GetNanoSeconds ()); |
| 183 |
| 184 // 5.1.1.2 Receive operations· |
| 185 // 5.1.1.2.1 General |
| 186 // When receiving a new TMD PDU from lower layer, the receiving TM RLC entity
shall: |
| 187 // - deliver the TMD PDU without any modification to upper layer. |
| 188 |
| 189 m_rlcSapUser->ReceivePdcpPdu (p); |
| 190 } |
| 191 |
| 192 |
| 193 void |
| 194 NistLteRlcTm::DoReportBufferNistStatus (void) |
| 195 { |
| 196 Time holDelay (0); |
| 197 uint32_t queueSize = 0; |
| 198 |
| 199 if (! m_txBuffer.empty ()) |
| 200 { |
| 201 NistRlcTag holTimeTag; |
| 202 m_txBuffer.front ()->PeekPacketTag (holTimeTag); |
| 203 holDelay = Simulator::Now () - holTimeTag.GetSenderTimestamp (); |
| 204 |
| 205 queueSize = m_txBufferSize; // just data in tx queue (no header overhead f
or RLC TM) |
| 206 } |
| 207 |
| 208 NistLteMacSapProvider::NistReportBufferNistStatusParameters r; |
| 209 r.rnti = m_rnti; |
| 210 r.lcid = m_lcid; |
| 211 r.srcL2Id = m_srcL2Id; |
| 212 r.dstL2Id = m_dstL2Id; |
| 213 r.txQueueSize = queueSize; |
| 214 r.txQueueHolDelay = holDelay.GetMilliSeconds () ; |
| 215 r.retxQueueSize = 0; |
| 216 r.retxQueueHolDelay = 0; |
| 217 r.statusPduSize = 0; |
| 218 |
| 219 NS_LOG_LOGIC ("Send ReportBufferNistStatus = " << r.txQueueSize << ", " << r.t
xQueueHolDelay ); |
| 220 m_macSapProvider->ReportBufferNistStatus (r); |
| 221 } |
| 222 |
| 223 void |
| 224 NistLteRlcTm::ExpireRbsTimer (void) |
| 225 { |
| 226 NS_LOG_LOGIC ("RBS Timer expires"); |
| 227 |
| 228 if (! m_txBuffer.empty ()) |
| 229 { |
| 230 DoReportBufferNistStatus (); |
| 231 m_rbsTimer = Simulator::Schedule (MilliSeconds (10), &NistLteRlcTm::Expire
RbsTimer, this); |
| 232 } |
| 233 } |
| 234 |
| 235 } // namespace ns3 |
OLD | NEW |