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: Nicola Baldo <nbaldo@cttc.es>
19  */
20 
21 
22 #include "ns3/log.h"
23 #include "ns3/simulator.h"
24 
25 #include "ns3/lte-rlc.h"
26 #include "ns3/lte-rlc-tag.h"
27 // #include "lte-mac-sap.h"
28 #include "ns3/lte-rlc-sap.h"
29 // #include "ff-mac-sched-sap.h"
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("LteRlc");
34 
35 /// LteRlcSpecificLteMacSapUser class
36 class LteRlcSpecificLteMacSapUser : public LteMacSapUser
37 {
38 public:
39   /**
40    * Constructor
41    *
42    * \param rlc the RLC
43    */
44   LteRlcSpecificLteMacSapUser (LteRlc* rlc);
45 
46   // Interface implemented from LteMacSapUser
47   virtual void NotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters params);
48   virtual void NotifyHarqDeliveryFailure ();
49   virtual void ReceivePdu (LteMacSapUser::ReceivePduParameters params);
50 
51 private:
52   LteRlcSpecificLteMacSapUser ();
53   LteRlc* m_rlc; ///< the RLC
54 };
55 
LteRlcSpecificLteMacSapUser(LteRlc * rlc)56 LteRlcSpecificLteMacSapUser::LteRlcSpecificLteMacSapUser (LteRlc* rlc)
57   : m_rlc (rlc)
58 {}
59 
LteRlcSpecificLteMacSapUser()60 LteRlcSpecificLteMacSapUser::LteRlcSpecificLteMacSapUser ()
61 {}
62 
63 void
NotifyTxOpportunity(TxOpportunityParameters params)64 LteRlcSpecificLteMacSapUser::NotifyTxOpportunity (TxOpportunityParameters params)
65 {
66   m_rlc->DoNotifyTxOpportunity (params);
67 }
68 
69 void
NotifyHarqDeliveryFailure()70 LteRlcSpecificLteMacSapUser::NotifyHarqDeliveryFailure ()
71 {
72   m_rlc->DoNotifyHarqDeliveryFailure ();
73 }
74 
75 void
ReceivePdu(LteMacSapUser::ReceivePduParameters params)76 LteRlcSpecificLteMacSapUser::ReceivePdu (LteMacSapUser::ReceivePduParameters params)
77 {
78   m_rlc->DoReceivePdu (params);
79 }
80 
81 
82 ///////////////////////////////////////
83 
84 NS_OBJECT_ENSURE_REGISTERED (LteRlc);
85 
LteRlc()86 LteRlc::LteRlc ()
87   : m_rlcSapUser (0),
88     m_macSapProvider (0),
89     m_rnti (0),
90     m_lcid (0)
91 {
92   NS_LOG_FUNCTION (this);
93   m_rlcSapProvider = new LteRlcSpecificLteRlcSapProvider<LteRlc> (this);
94   m_macSapUser = new LteRlcSpecificLteMacSapUser (this);
95 }
96 
~LteRlc()97 LteRlc::~LteRlc ()
98 {
99   NS_LOG_FUNCTION (this);
100 }
101 
GetTypeId(void)102 TypeId LteRlc::GetTypeId (void)
103 {
104   static TypeId tid = TypeId ("ns3::LteRlc")
105     .SetParent<Object> ()
106     .SetGroupName ("Lte")
107     .AddTraceSource ("TxPDU",
108                      "PDU transmission notified to the MAC.",
109                      MakeTraceSourceAccessor (&LteRlc::m_txPdu),
110                      "ns3::LteRlc::NotifyTxTracedCallback")
111     .AddTraceSource ("RxPDU",
112                      "PDU received.",
113                      MakeTraceSourceAccessor (&LteRlc::m_rxPdu),
114                      "ns3::LteRlc::ReceiveTracedCallback")
115     .AddTraceSource ("TxDrop",
116                      "Trace source indicating a packet "
117                      "has been dropped before transmission",
118                      MakeTraceSourceAccessor (&LteRlc::m_txDropTrace),
119                      "ns3::Packet::TracedCallback")
120   ;
121   return tid;
122 }
123 
124 void
DoDispose()125 LteRlc::DoDispose ()
126 {
127   NS_LOG_FUNCTION (this);
128   delete (m_rlcSapProvider);
129   delete (m_macSapUser);
130 }
131 
132 void
SetRnti(uint16_t rnti)133 LteRlc::SetRnti (uint16_t rnti)
134 {
135   NS_LOG_FUNCTION (this << (uint32_t) rnti);
136   m_rnti = rnti;
137 }
138 
139 void
SetLcId(uint8_t lcId)140 LteRlc::SetLcId (uint8_t lcId)
141 {
142   NS_LOG_FUNCTION (this << (uint32_t) lcId);
143   m_lcid = lcId;
144 }
145 
146 void
SetLteRlcSapUser(LteRlcSapUser * s)147 LteRlc::SetLteRlcSapUser (LteRlcSapUser * s)
148 {
149   NS_LOG_FUNCTION (this << s);
150   m_rlcSapUser = s;
151 }
152 
153 LteRlcSapProvider*
GetLteRlcSapProvider()154 LteRlc::GetLteRlcSapProvider ()
155 {
156   NS_LOG_FUNCTION (this);
157   return m_rlcSapProvider;
158 }
159 
160 void
SetLteMacSapProvider(LteMacSapProvider * s)161 LteRlc::SetLteMacSapProvider (LteMacSapProvider * s)
162 {
163   NS_LOG_FUNCTION (this << s);
164   m_macSapProvider = s;
165 }
166 
167 LteMacSapUser*
GetLteMacSapUser()168 LteRlc::GetLteMacSapUser ()
169 {
170   NS_LOG_FUNCTION (this);
171   return m_macSapUser;
172 }
173 
174 
175 
176 ////////////////////////////////////////
177 
178 NS_OBJECT_ENSURE_REGISTERED (LteRlcSm);
179 
LteRlcSm()180 LteRlcSm::LteRlcSm ()
181 {
182   NS_LOG_FUNCTION (this);
183 }
184 
~LteRlcSm()185 LteRlcSm::~LteRlcSm ()
186 {
187   NS_LOG_FUNCTION (this);
188 }
189 
190 TypeId
GetTypeId(void)191 LteRlcSm::GetTypeId (void)
192 {
193   static TypeId tid = TypeId ("ns3::LteRlcSm")
194     .SetParent<LteRlc> ()
195     .SetGroupName ("Lte")
196     .AddConstructor<LteRlcSm> ()
197   ;
198   return tid;
199 }
200 
201 void
DoInitialize()202 LteRlcSm::DoInitialize ()
203 {
204   NS_LOG_FUNCTION (this);
205   ReportBufferStatus ();
206 }
207 
208 void
DoDispose()209 LteRlcSm::DoDispose ()
210 {
211   NS_LOG_FUNCTION (this);
212   LteRlc::DoDispose ();
213 }
214 
215 void
DoTransmitPdcpPdu(Ptr<Packet> p)216 LteRlcSm::DoTransmitPdcpPdu (Ptr<Packet> p)
217 {
218   NS_LOG_FUNCTION (this << p);
219 }
220 
221 void
DoReceivePdu(LteMacSapUser::ReceivePduParameters rxPduParams)222 LteRlcSm::DoReceivePdu (LteMacSapUser::ReceivePduParameters rxPduParams)
223 {
224   NS_LOG_FUNCTION (this << rxPduParams.p);
225   // RLC Performance evaluation
226   RlcTag rlcTag;
227   Time delay;
228   bool ret = rxPduParams.p->FindFirstMatchingByteTag (rlcTag);
229   NS_ASSERT_MSG (ret, "RlcTag is missing");
230   delay = Simulator::Now () - rlcTag.GetSenderTimestamp ();
231   NS_LOG_LOGIC (" RNTI=" << m_rnti
232                          << " LCID=" << (uint32_t) m_lcid
233                          << " size=" << rxPduParams.p->GetSize ()
234                          << " delay=" << delay.As (Time::NS));
235   m_rxPdu (m_rnti, m_lcid, rxPduParams.p->GetSize (), delay.GetNanoSeconds () );
236 }
237 
238 void
DoNotifyTxOpportunity(LteMacSapUser::TxOpportunityParameters txOpParams)239 LteRlcSm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpParams)
240 {
241   NS_LOG_FUNCTION (this << txOpParams.bytes);
242   LteMacSapProvider::TransmitPduParameters params;
243   RlcTag tag (Simulator::Now ());
244 
245   params.pdu = Create<Packet> (txOpParams.bytes);
246   NS_ABORT_MSG_UNLESS (txOpParams.bytes > 0, "Bytes must be > 0");
247   /**
248    * For RLC SM, the packets are not passed to the upper layers, therefore,
249    * in the absence of an header we can safely byte tag the entire packet.
250    */
251   params.pdu->AddByteTag (tag, 1, params.pdu->GetSize ());
252 
253   params.rnti = m_rnti;
254   params.lcid = m_lcid;
255   params.layer = txOpParams.layer;
256   params.harqProcessId = txOpParams.harqId;
257   params.componentCarrierId = txOpParams.componentCarrierId;
258 
259   // RLC Performance evaluation
260   NS_LOG_LOGIC (" RNTI=" << m_rnti
261                          << " LCID=" << (uint32_t) m_lcid
262                          << " size=" << txOpParams.bytes);
263   m_txPdu (m_rnti, m_lcid, txOpParams.bytes);
264 
265   m_macSapProvider->TransmitPdu (params);
266   ReportBufferStatus ();
267 }
268 
269 void
DoNotifyHarqDeliveryFailure()270 LteRlcSm::DoNotifyHarqDeliveryFailure ()
271 {
272   NS_LOG_FUNCTION (this);
273 }
274 
275 void
ReportBufferStatus()276 LteRlcSm::ReportBufferStatus ()
277 {
278   NS_LOG_FUNCTION (this);
279   LteMacSapProvider::ReportBufferStatusParameters p;
280   p.rnti = m_rnti;
281   p.lcid = m_lcid;
282   p.txQueueSize = 80000;
283   p.txQueueHolDelay = 10;
284   p.retxQueueSize = 0;
285   p.retxQueueHolDelay = 0;
286   p.statusPduSize = 0;
287   m_macSapProvider->ReportBufferStatus (p);
288 }
289 
290 
291 
292 
293 //////////////////////////////////////////
294 
295 // LteRlcTm::~LteRlcTm ()
296 // {
297 // }
298 
299 //////////////////////////////////////////
300 
301 // LteRlcUm::~LteRlcUm ()
302 // {
303 // }
304 
305 //////////////////////////////////////////
306 
307 // LteRlcAm::~LteRlcAm ()
308 // {
309 // }
310 
311 
312 } // namespace ns3
313