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: Marco Miozzo <marco.miozzo@cttc.es>
19  *         Nicola Baldo  <nbaldo@cttc.es>
20  * Modified by:
21  *          Danilo Abrignani <danilo.abrignani@unibo.it> (Carrier Aggregation - GSoC 2015)
22  *          Biljana Bojovic <biljana.bojovic@cttc.es> (Carrier Aggregation)
23  */
24 
25 
26 #include <ns3/log.h>
27 #include <ns3/pointer.h>
28 #include <ns3/packet.h>
29 #include <ns3/simulator.h>
30 
31 #include "lte-amc.h"
32 #include "lte-control-messages.h"
33 #include "lte-enb-net-device.h"
34 #include "lte-ue-net-device.h"
35 
36 #include <ns3/lte-enb-mac.h>
37 #include <ns3/lte-radio-bearer-tag.h>
38 #include <ns3/lte-ue-phy.h>
39 
40 #include "ns3/lte-mac-sap.h"
41 #include "ns3/lte-enb-cmac-sap.h"
42 #include <ns3/lte-common.h>
43 
44 
45 namespace ns3 {
46 
47 NS_LOG_COMPONENT_DEFINE ("LteEnbMac");
48 
49 NS_OBJECT_ENSURE_REGISTERED (LteEnbMac);
50 
51 
52 
53 // //////////////////////////////////////
54 // member SAP forwarders
55 // //////////////////////////////////////
56 
57 
58 /// EnbMacMemberLteEnbCmacSapProvider class
59 class EnbMacMemberLteEnbCmacSapProvider : public LteEnbCmacSapProvider
60 {
61 public:
62   /**
63    * Constructor
64    *
65    * \param mac the MAC
66    */
67   EnbMacMemberLteEnbCmacSapProvider (LteEnbMac* mac);
68 
69   // inherited from LteEnbCmacSapProvider
70   virtual void ConfigureMac (uint16_t ulBandwidth, uint16_t dlBandwidth);
71   virtual void AddUe (uint16_t rnti);
72   virtual void RemoveUe (uint16_t rnti);
73   virtual void AddLc (LcInfo lcinfo, LteMacSapUser* msu);
74   virtual void ReconfigureLc (LcInfo lcinfo);
75   virtual void ReleaseLc (uint16_t rnti, uint8_t lcid);
76   virtual void UeUpdateConfigurationReq (UeConfig params);
77   virtual RachConfig GetRachConfig ();
78   virtual AllocateNcRaPreambleReturnValue AllocateNcRaPreamble (uint16_t rnti);
79 
80 
81 private:
82   LteEnbMac* m_mac; ///< the MAC
83 };
84 
85 
EnbMacMemberLteEnbCmacSapProvider(LteEnbMac * mac)86 EnbMacMemberLteEnbCmacSapProvider::EnbMacMemberLteEnbCmacSapProvider (LteEnbMac* mac)
87   : m_mac (mac)
88 {
89 }
90 
91 void
ConfigureMac(uint16_t ulBandwidth,uint16_t dlBandwidth)92 EnbMacMemberLteEnbCmacSapProvider::ConfigureMac (uint16_t ulBandwidth, uint16_t dlBandwidth)
93 {
94   m_mac->DoConfigureMac (ulBandwidth, dlBandwidth);
95 }
96 
97 void
AddUe(uint16_t rnti)98 EnbMacMemberLteEnbCmacSapProvider::AddUe (uint16_t rnti)
99 {
100   m_mac->DoAddUe (rnti);
101 }
102 
103 void
RemoveUe(uint16_t rnti)104 EnbMacMemberLteEnbCmacSapProvider::RemoveUe (uint16_t rnti)
105 {
106   m_mac->DoRemoveUe (rnti);
107 }
108 
109 void
AddLc(LcInfo lcinfo,LteMacSapUser * msu)110 EnbMacMemberLteEnbCmacSapProvider::AddLc (LcInfo lcinfo, LteMacSapUser* msu)
111 {
112   m_mac->DoAddLc (lcinfo, msu);
113 }
114 
115 void
ReconfigureLc(LcInfo lcinfo)116 EnbMacMemberLteEnbCmacSapProvider::ReconfigureLc (LcInfo lcinfo)
117 {
118   m_mac->DoReconfigureLc (lcinfo);
119 }
120 
121 void
ReleaseLc(uint16_t rnti,uint8_t lcid)122 EnbMacMemberLteEnbCmacSapProvider::ReleaseLc (uint16_t rnti, uint8_t lcid)
123 {
124   m_mac->DoReleaseLc (rnti, lcid);
125 }
126 
127 void
UeUpdateConfigurationReq(UeConfig params)128 EnbMacMemberLteEnbCmacSapProvider::UeUpdateConfigurationReq (UeConfig params)
129 {
130   m_mac->DoUeUpdateConfigurationReq (params);
131 }
132 
133 LteEnbCmacSapProvider::RachConfig
GetRachConfig()134 EnbMacMemberLteEnbCmacSapProvider::GetRachConfig ()
135 {
136   return m_mac->DoGetRachConfig ();
137 }
138 
139 LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue
AllocateNcRaPreamble(uint16_t rnti)140 EnbMacMemberLteEnbCmacSapProvider::AllocateNcRaPreamble (uint16_t rnti)
141 {
142   return m_mac->DoAllocateNcRaPreamble (rnti);
143 }
144 
145 
146 /// EnbMacMemberFfMacSchedSapUser class
147 class EnbMacMemberFfMacSchedSapUser : public FfMacSchedSapUser
148 {
149 public:
150   /**
151    * Constructor
152    *
153    * \param mac the MAC
154    */
155   EnbMacMemberFfMacSchedSapUser (LteEnbMac* mac);
156 
157 
158   virtual void SchedDlConfigInd (const struct SchedDlConfigIndParameters& params);
159   virtual void SchedUlConfigInd (const struct SchedUlConfigIndParameters& params);
160 private:
161   LteEnbMac* m_mac; ///< the MAC
162 };
163 
164 
EnbMacMemberFfMacSchedSapUser(LteEnbMac * mac)165 EnbMacMemberFfMacSchedSapUser::EnbMacMemberFfMacSchedSapUser (LteEnbMac* mac)
166   : m_mac (mac)
167 {
168 }
169 
170 
171 void
SchedDlConfigInd(const struct SchedDlConfigIndParameters & params)172 EnbMacMemberFfMacSchedSapUser::SchedDlConfigInd (const struct SchedDlConfigIndParameters& params)
173 {
174   m_mac->DoSchedDlConfigInd (params);
175 }
176 
177 
178 
179 void
SchedUlConfigInd(const struct SchedUlConfigIndParameters & params)180 EnbMacMemberFfMacSchedSapUser::SchedUlConfigInd (const struct SchedUlConfigIndParameters& params)
181 {
182   m_mac->DoSchedUlConfigInd (params);
183 }
184 
185 
186 /// EnbMacMemberFfMacCschedSapUser class
187 class EnbMacMemberFfMacCschedSapUser : public FfMacCschedSapUser
188 {
189 public:
190   /**
191    * Constructor
192    *
193    * \param mac the MAC
194    */
195   EnbMacMemberFfMacCschedSapUser (LteEnbMac* mac);
196 
197   virtual void CschedCellConfigCnf (const struct CschedCellConfigCnfParameters& params);
198   virtual void CschedUeConfigCnf (const struct CschedUeConfigCnfParameters& params);
199   virtual void CschedLcConfigCnf (const struct CschedLcConfigCnfParameters& params);
200   virtual void CschedLcReleaseCnf (const struct CschedLcReleaseCnfParameters& params);
201   virtual void CschedUeReleaseCnf (const struct CschedUeReleaseCnfParameters& params);
202   virtual void CschedUeConfigUpdateInd (const struct CschedUeConfigUpdateIndParameters& params);
203   virtual void CschedCellConfigUpdateInd (const struct CschedCellConfigUpdateIndParameters& params);
204 
205 private:
206   LteEnbMac* m_mac; ///< the MAC
207 };
208 
209 
EnbMacMemberFfMacCschedSapUser(LteEnbMac * mac)210 EnbMacMemberFfMacCschedSapUser::EnbMacMemberFfMacCschedSapUser (LteEnbMac* mac)
211   : m_mac (mac)
212 {
213 }
214 
215 void
CschedCellConfigCnf(const struct CschedCellConfigCnfParameters & params)216 EnbMacMemberFfMacCschedSapUser::CschedCellConfigCnf (const struct CschedCellConfigCnfParameters& params)
217 {
218   m_mac->DoCschedCellConfigCnf (params);
219 }
220 
221 void
CschedUeConfigCnf(const struct CschedUeConfigCnfParameters & params)222 EnbMacMemberFfMacCschedSapUser::CschedUeConfigCnf (const struct CschedUeConfigCnfParameters& params)
223 {
224   m_mac->DoCschedUeConfigCnf (params);
225 }
226 
227 void
CschedLcConfigCnf(const struct CschedLcConfigCnfParameters & params)228 EnbMacMemberFfMacCschedSapUser::CschedLcConfigCnf (const struct CschedLcConfigCnfParameters& params)
229 {
230   m_mac->DoCschedLcConfigCnf (params);
231 }
232 
233 void
CschedLcReleaseCnf(const struct CschedLcReleaseCnfParameters & params)234 EnbMacMemberFfMacCschedSapUser::CschedLcReleaseCnf (const struct CschedLcReleaseCnfParameters& params)
235 {
236   m_mac->DoCschedLcReleaseCnf (params);
237 }
238 
239 void
CschedUeReleaseCnf(const struct CschedUeReleaseCnfParameters & params)240 EnbMacMemberFfMacCschedSapUser::CschedUeReleaseCnf (const struct CschedUeReleaseCnfParameters& params)
241 {
242   m_mac->DoCschedUeReleaseCnf (params);
243 }
244 
245 void
CschedUeConfigUpdateInd(const struct CschedUeConfigUpdateIndParameters & params)246 EnbMacMemberFfMacCschedSapUser::CschedUeConfigUpdateInd (const struct CschedUeConfigUpdateIndParameters& params)
247 {
248   m_mac->DoCschedUeConfigUpdateInd (params);
249 }
250 
251 void
CschedCellConfigUpdateInd(const struct CschedCellConfigUpdateIndParameters & params)252 EnbMacMemberFfMacCschedSapUser::CschedCellConfigUpdateInd (const struct CschedCellConfigUpdateIndParameters& params)
253 {
254   m_mac->DoCschedCellConfigUpdateInd (params);
255 }
256 
257 
258 
259 /// ---------- PHY-SAP
260 class EnbMacMemberLteEnbPhySapUser : public LteEnbPhySapUser
261 {
262 public:
263   /**
264    * Constructor
265    *
266    * \param mac the MAC
267    */
268   EnbMacMemberLteEnbPhySapUser (LteEnbMac* mac);
269 
270   // inherited from LteEnbPhySapUser
271   virtual void ReceivePhyPdu (Ptr<Packet> p);
272   virtual void SubframeIndication (uint32_t frameNo, uint32_t subframeNo);
273   virtual void ReceiveLteControlMessage (Ptr<LteControlMessage> msg);
274   virtual void ReceiveRachPreamble (uint32_t prachId);
275   virtual void UlCqiReport (FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi);
276   virtual void UlInfoListElementHarqFeeback (UlInfoListElement_s params);
277   virtual void DlInfoListElementHarqFeeback (DlInfoListElement_s params);
278 
279 private:
280   LteEnbMac* m_mac; ///< the MAC
281 };
282 
EnbMacMemberLteEnbPhySapUser(LteEnbMac * mac)283 EnbMacMemberLteEnbPhySapUser::EnbMacMemberLteEnbPhySapUser (LteEnbMac* mac) : m_mac (mac)
284 {
285 }
286 
287 
288 void
ReceivePhyPdu(Ptr<Packet> p)289 EnbMacMemberLteEnbPhySapUser::ReceivePhyPdu (Ptr<Packet> p)
290 {
291   m_mac->DoReceivePhyPdu (p);
292 }
293 
294 void
SubframeIndication(uint32_t frameNo,uint32_t subframeNo)295 EnbMacMemberLteEnbPhySapUser::SubframeIndication (uint32_t frameNo, uint32_t subframeNo)
296 {
297   m_mac->DoSubframeIndication (frameNo, subframeNo);
298 }
299 
300 void
ReceiveLteControlMessage(Ptr<LteControlMessage> msg)301 EnbMacMemberLteEnbPhySapUser::ReceiveLteControlMessage (Ptr<LteControlMessage> msg)
302 {
303   m_mac->DoReceiveLteControlMessage (msg);
304 }
305 
306 void
ReceiveRachPreamble(uint32_t prachId)307 EnbMacMemberLteEnbPhySapUser::ReceiveRachPreamble (uint32_t prachId)
308 {
309   m_mac->DoReceiveRachPreamble (prachId);
310 }
311 
312 void
UlCqiReport(FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi)313 EnbMacMemberLteEnbPhySapUser::UlCqiReport (FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi)
314 {
315   m_mac->DoUlCqiReport (ulcqi);
316 }
317 
318 void
UlInfoListElementHarqFeeback(UlInfoListElement_s params)319 EnbMacMemberLteEnbPhySapUser::UlInfoListElementHarqFeeback (UlInfoListElement_s params)
320 {
321   m_mac->DoUlInfoListElementHarqFeeback (params);
322 }
323 
324 void
DlInfoListElementHarqFeeback(DlInfoListElement_s params)325 EnbMacMemberLteEnbPhySapUser::DlInfoListElementHarqFeeback (DlInfoListElement_s params)
326 {
327   m_mac->DoDlInfoListElementHarqFeeback (params);
328 }
329 
330 
331 // //////////////////////////////////////
332 // generic LteEnbMac methods
333 // //////////////////////////////////////
334 
335 
336 TypeId
GetTypeId(void)337 LteEnbMac::GetTypeId (void)
338 {
339   static TypeId tid = TypeId ("ns3::LteEnbMac")
340     .SetParent<Object> ()
341     .SetGroupName("Lte")
342     .AddConstructor<LteEnbMac> ()
343     .AddAttribute ("NumberOfRaPreambles",
344                    "how many random access preambles are available for the contention based RACH process",
345                    UintegerValue (52),
346                    MakeUintegerAccessor (&LteEnbMac::m_numberOfRaPreambles),
347                    MakeUintegerChecker<uint8_t> (4, 64))
348     .AddAttribute ("PreambleTransMax",
349                    "Maximum number of random access preamble transmissions",
350                    UintegerValue (50),
351                    MakeUintegerAccessor (&LteEnbMac::m_preambleTransMax),
352                    MakeUintegerChecker<uint8_t> (3, 200))
353     .AddAttribute ("RaResponseWindowSize",
354                    "length of the window (in TTIs) for the reception of the random access response (RAR); the resulting RAR timeout is this value + 3 ms",
355                    UintegerValue (3),
356                    MakeUintegerAccessor (&LteEnbMac::m_raResponseWindowSize),
357                    MakeUintegerChecker<uint8_t> (2, 10))
358     .AddAttribute ("ConnEstFailCount",
359                    "how many time T300 timer can expire on the same cell",
360                    UintegerValue (1),
361                    MakeUintegerAccessor (&LteEnbMac::m_connEstFailCount),
362                    MakeUintegerChecker<uint8_t> (1, 4))
363     .AddTraceSource ("DlScheduling",
364                      "Information regarding DL scheduling.",
365                      MakeTraceSourceAccessor (&LteEnbMac::m_dlScheduling),
366                      "ns3::LteEnbMac::DlSchedulingTracedCallback")
367     .AddTraceSource ("UlScheduling",
368                      "Information regarding UL scheduling.",
369                      MakeTraceSourceAccessor (&LteEnbMac::m_ulScheduling),
370                      "ns3::LteEnbMac::UlSchedulingTracedCallback")
371     .AddAttribute ("ComponentCarrierId",
372                    "ComponentCarrier Id, needed to reply on the appropriate sap.",
373                    UintegerValue (0),
374                    MakeUintegerAccessor (&LteEnbMac::m_componentCarrierId),
375                    MakeUintegerChecker<uint8_t> (0,4))
376   ;
377 
378   return tid;
379 }
380 
381 
LteEnbMac()382 LteEnbMac::LteEnbMac ():
383 m_ccmMacSapUser (0)
384 {
385   NS_LOG_FUNCTION (this);
386   m_macSapProvider = new EnbMacMemberLteMacSapProvider<LteEnbMac> (this);
387   m_cmacSapProvider = new EnbMacMemberLteEnbCmacSapProvider (this);
388   m_schedSapUser = new EnbMacMemberFfMacSchedSapUser (this);
389   m_cschedSapUser = new EnbMacMemberFfMacCschedSapUser (this);
390   m_enbPhySapUser = new EnbMacMemberLteEnbPhySapUser (this);
391   m_ccmMacSapProvider = new MemberLteCcmMacSapProvider<LteEnbMac> (this);
392 }
393 
394 
~LteEnbMac()395 LteEnbMac::~LteEnbMac ()
396 {
397   NS_LOG_FUNCTION (this);
398 }
399 
400 void
DoDispose()401 LteEnbMac::DoDispose ()
402 {
403   NS_LOG_FUNCTION (this);
404   m_dlCqiReceived.clear ();
405   m_ulCqiReceived.clear ();
406   m_ulCeReceived.clear ();
407   m_dlInfoListReceived.clear ();
408   m_ulInfoListReceived.clear ();
409   m_miDlHarqProcessesPackets.clear ();
410   delete m_macSapProvider;
411   delete m_cmacSapProvider;
412   delete m_schedSapUser;
413   delete m_cschedSapUser;
414   delete m_enbPhySapUser;
415   delete m_ccmMacSapProvider;
416 }
417 
418 void
SetComponentCarrierId(uint8_t index)419 LteEnbMac::SetComponentCarrierId (uint8_t index)
420 {
421   m_componentCarrierId = index;
422 }
423 
424 void
SetFfMacSchedSapProvider(FfMacSchedSapProvider * s)425 LteEnbMac::SetFfMacSchedSapProvider (FfMacSchedSapProvider* s)
426 {
427   m_schedSapProvider = s;
428 }
429 
430 FfMacSchedSapUser*
GetFfMacSchedSapUser(void)431 LteEnbMac::GetFfMacSchedSapUser (void)
432 {
433   return m_schedSapUser;
434 }
435 
436 void
SetFfMacCschedSapProvider(FfMacCschedSapProvider * s)437 LteEnbMac::SetFfMacCschedSapProvider (FfMacCschedSapProvider* s)
438 {
439   m_cschedSapProvider = s;
440 }
441 
442 FfMacCschedSapUser*
GetFfMacCschedSapUser(void)443 LteEnbMac::GetFfMacCschedSapUser (void)
444 {
445   return m_cschedSapUser;
446 }
447 
448 
449 
450 void
SetLteMacSapUser(LteMacSapUser * s)451 LteEnbMac::SetLteMacSapUser (LteMacSapUser* s)
452 {
453   m_macSapUser = s;
454 }
455 
456 LteMacSapProvider*
GetLteMacSapProvider(void)457 LteEnbMac::GetLteMacSapProvider (void)
458 {
459   return m_macSapProvider;
460 }
461 
462 void
SetLteEnbCmacSapUser(LteEnbCmacSapUser * s)463 LteEnbMac::SetLteEnbCmacSapUser (LteEnbCmacSapUser* s)
464 {
465   m_cmacSapUser = s;
466 }
467 
468 LteEnbCmacSapProvider*
GetLteEnbCmacSapProvider(void)469 LteEnbMac::GetLteEnbCmacSapProvider (void)
470 {
471   return m_cmacSapProvider;
472 }
473 
474 void
SetLteEnbPhySapProvider(LteEnbPhySapProvider * s)475 LteEnbMac::SetLteEnbPhySapProvider (LteEnbPhySapProvider* s)
476 {
477   m_enbPhySapProvider = s;
478 }
479 
480 
481 LteEnbPhySapUser*
GetLteEnbPhySapUser()482 LteEnbMac::GetLteEnbPhySapUser ()
483 {
484   return m_enbPhySapUser;
485 }
486 
487 void
SetLteCcmMacSapUser(LteCcmMacSapUser * s)488 LteEnbMac::SetLteCcmMacSapUser (LteCcmMacSapUser* s)
489 {
490   m_ccmMacSapUser = s;
491 }
492 
493 
494 LteCcmMacSapProvider*
GetLteCcmMacSapProvider()495 LteEnbMac::GetLteCcmMacSapProvider ()
496 {
497   return m_ccmMacSapProvider;
498 }
499 
500 void
DoSubframeIndication(uint32_t frameNo,uint32_t subframeNo)501 LteEnbMac::DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo)
502 {
503   NS_LOG_FUNCTION (this << " EnbMac - frame " << frameNo << " subframe " << subframeNo);
504 
505   // Store current frame / subframe number
506   m_frameNo = frameNo;
507   m_subframeNo = subframeNo;
508 
509 
510   // --- DOWNLINK ---
511   // Send Dl-CQI info to the scheduler
512   if (m_dlCqiReceived.size () > 0)
513     {
514       FfMacSchedSapProvider::SchedDlCqiInfoReqParameters dlcqiInfoReq;
515       dlcqiInfoReq.m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & subframeNo);
516       dlcqiInfoReq.m_cqiList.insert (dlcqiInfoReq.m_cqiList.begin (), m_dlCqiReceived.begin (), m_dlCqiReceived.end ());
517       m_dlCqiReceived.erase (m_dlCqiReceived.begin (), m_dlCqiReceived.end ());
518       m_schedSapProvider->SchedDlCqiInfoReq (dlcqiInfoReq);
519     }
520 
521   if (!m_receivedRachPreambleCount.empty ())
522     {
523       // process received RACH preambles and notify the scheduler
524       FfMacSchedSapProvider::SchedDlRachInfoReqParameters rachInfoReqParams;
525       NS_ASSERT (subframeNo > 0 && subframeNo <= 10); // subframe in 1..10
526       for (std::map<uint8_t, uint32_t>::const_iterator it = m_receivedRachPreambleCount.begin ();
527            it != m_receivedRachPreambleCount.end ();
528            ++it)
529         {
530           NS_LOG_INFO (this << " preambleId " << (uint32_t) it->first << ": " << it->second << " received");
531           NS_ASSERT (it->second != 0);
532           if (it->second > 1)
533             {
534               NS_LOG_INFO ("preambleId " << (uint32_t) it->first << ": collision");
535               // in case of collision we assume that no preamble is
536               // successfully received, hence no RAR is sent
537             }
538           else
539             {
540               uint16_t rnti;
541               std::map<uint8_t, NcRaPreambleInfo>::iterator jt = m_allocatedNcRaPreambleMap.find (it->first);
542               if (jt != m_allocatedNcRaPreambleMap.end ())
543                 {
544                   rnti = jt->second.rnti;
545                   NS_LOG_INFO ("preambleId previously allocated for NC based RA, RNTI =" << (uint32_t) rnti << ", sending RAR");
546 
547                 }
548               else
549                 {
550                   rnti = m_cmacSapUser->AllocateTemporaryCellRnti ();
551                   NS_LOG_INFO ("preambleId " << (uint32_t) it->first << ": allocated T-C-RNTI " << (uint32_t) rnti << ", sending RAR");
552                 }
553 
554               RachListElement_s rachLe;
555               rachLe.m_rnti = rnti;
556               rachLe.m_estimatedSize = 144; // to be confirmed
557               rachInfoReqParams.m_rachList.push_back (rachLe);
558               m_rapIdRntiMap.insert (std::pair <uint16_t, uint32_t> (rnti, it->first));
559             }
560         }
561       m_schedSapProvider->SchedDlRachInfoReq (rachInfoReqParams);
562       m_receivedRachPreambleCount.clear ();
563     }
564   // Get downlink transmission opportunities
565   uint32_t dlSchedFrameNo = m_frameNo;
566   uint32_t dlSchedSubframeNo = m_subframeNo;
567   //   NS_LOG_DEBUG (this << " sfn " << frameNo << " sbfn " << subframeNo);
568   if (dlSchedSubframeNo + m_macChTtiDelay > 10)
569     {
570       dlSchedFrameNo++;
571       dlSchedSubframeNo = (dlSchedSubframeNo + m_macChTtiDelay) % 10;
572     }
573   else
574     {
575       dlSchedSubframeNo = dlSchedSubframeNo + m_macChTtiDelay;
576     }
577   FfMacSchedSapProvider::SchedDlTriggerReqParameters dlparams;
578   dlparams.m_sfnSf = ((0x3FF & dlSchedFrameNo) << 4) | (0xF & dlSchedSubframeNo);
579 
580   // Forward DL HARQ feebacks collected during last TTI
581   if (m_dlInfoListReceived.size () > 0)
582     {
583       dlparams.m_dlInfoList = m_dlInfoListReceived;
584       // empty local buffer
585       m_dlInfoListReceived.clear ();
586     }
587 
588   m_schedSapProvider->SchedDlTriggerReq (dlparams);
589 
590 
591   // --- UPLINK ---
592   // Send UL-CQI info to the scheduler
593   for (uint16_t i = 0; i < m_ulCqiReceived.size (); i++)
594     {
595       if (subframeNo > 1)
596         {
597           m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & (subframeNo - 1));
598         }
599       else
600         {
601           m_ulCqiReceived.at (i).m_sfnSf = ((0x3FF & (frameNo - 1)) << 4) | (0xF & 10);
602         }
603       m_schedSapProvider->SchedUlCqiInfoReq (m_ulCqiReceived.at (i));
604     }
605     m_ulCqiReceived.clear ();
606 
607   // Send BSR reports to the scheduler
608   if (m_ulCeReceived.size () > 0)
609     {
610       FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters ulMacReq;
611       ulMacReq.m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & subframeNo);
612       ulMacReq.m_macCeList.insert (ulMacReq.m_macCeList.begin (), m_ulCeReceived.begin (), m_ulCeReceived.end ());
613       m_ulCeReceived.erase (m_ulCeReceived.begin (), m_ulCeReceived.end ());
614       m_schedSapProvider->SchedUlMacCtrlInfoReq (ulMacReq);
615     }
616 
617 
618   // Get uplink transmission opportunities
619   uint32_t ulSchedFrameNo = m_frameNo;
620   uint32_t ulSchedSubframeNo = m_subframeNo;
621   //   NS_LOG_DEBUG (this << " sfn " << frameNo << " sbfn " << subframeNo);
622   if (ulSchedSubframeNo + (m_macChTtiDelay + UL_PUSCH_TTIS_DELAY) > 10)
623     {
624       ulSchedFrameNo++;
625       ulSchedSubframeNo = (ulSchedSubframeNo + (m_macChTtiDelay + UL_PUSCH_TTIS_DELAY)) % 10;
626     }
627   else
628     {
629       ulSchedSubframeNo = ulSchedSubframeNo + (m_macChTtiDelay + UL_PUSCH_TTIS_DELAY);
630     }
631   FfMacSchedSapProvider::SchedUlTriggerReqParameters ulparams;
632   ulparams.m_sfnSf = ((0x3FF & ulSchedFrameNo) << 4) | (0xF & ulSchedSubframeNo);
633 
634   // Forward DL HARQ feebacks collected during last TTI
635   if (m_ulInfoListReceived.size () > 0)
636     {
637      ulparams.m_ulInfoList = m_ulInfoListReceived;
638       // empty local buffer
639       m_ulInfoListReceived.clear ();
640     }
641 
642   m_schedSapProvider->SchedUlTriggerReq (ulparams);
643 
644 }
645 
646 
647 void
DoReceiveLteControlMessage(Ptr<LteControlMessage> msg)648 LteEnbMac::DoReceiveLteControlMessage  (Ptr<LteControlMessage> msg)
649 {
650   NS_LOG_FUNCTION (this << msg);
651   if (msg->GetMessageType () == LteControlMessage::DL_CQI)
652     {
653       Ptr<DlCqiLteControlMessage> dlcqi = DynamicCast<DlCqiLteControlMessage> (msg);
654       ReceiveDlCqiLteControlMessage (dlcqi);
655     }
656   else if (msg->GetMessageType () == LteControlMessage::BSR)
657     {
658       Ptr<BsrLteControlMessage> bsr = DynamicCast<BsrLteControlMessage> (msg);
659       ReceiveBsrMessage (bsr->GetBsr ());
660     }
661   else if (msg->GetMessageType () == LteControlMessage::DL_HARQ)
662     {
663       Ptr<DlHarqFeedbackLteControlMessage> dlharq = DynamicCast<DlHarqFeedbackLteControlMessage> (msg);
664       DoDlInfoListElementHarqFeeback (dlharq->GetDlHarqFeedback ());
665     }
666   else
667     {
668       NS_LOG_LOGIC (this << " LteControlMessage type " << msg->GetMessageType () << " not recognized");
669     }
670 }
671 
672 void
DoReceiveRachPreamble(uint8_t rapId)673 LteEnbMac::DoReceiveRachPreamble  (uint8_t rapId)
674 {
675   NS_LOG_FUNCTION (this << (uint32_t) rapId);
676   // just record that the preamble has been received; it will be processed later
677   ++m_receivedRachPreambleCount[rapId]; // will create entry if not exists
678 }
679 
680 void
DoUlCqiReport(FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi)681 LteEnbMac::DoUlCqiReport (FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi)
682 {
683   if (ulcqi.m_ulCqi.m_type == UlCqi_s::PUSCH)
684     {
685       NS_LOG_DEBUG (this << " eNB rxed an PUSCH UL-CQI");
686     }
687   else if (ulcqi.m_ulCqi.m_type == UlCqi_s::SRS)
688     {
689       NS_LOG_DEBUG (this << " eNB rxed an SRS UL-CQI");
690     }
691   m_ulCqiReceived.push_back (ulcqi);
692 }
693 
694 
695 void
ReceiveDlCqiLteControlMessage(Ptr<DlCqiLteControlMessage> msg)696 LteEnbMac::ReceiveDlCqiLteControlMessage  (Ptr<DlCqiLteControlMessage> msg)
697 {
698   NS_LOG_FUNCTION (this << msg);
699 
700   CqiListElement_s dlcqi = msg->GetDlCqi ();
701   NS_LOG_LOGIC (this << "Enb Received DL-CQI rnti" << dlcqi.m_rnti);
702   NS_ASSERT (dlcqi.m_rnti != 0);
703   m_dlCqiReceived.push_back (dlcqi);
704 
705 }
706 
707 
708 void
ReceiveBsrMessage(MacCeListElement_s bsr)709 LteEnbMac::ReceiveBsrMessage  (MacCeListElement_s bsr)
710 {
711   NS_LOG_FUNCTION (this);
712   m_ccmMacSapUser->UlReceiveMacCe (bsr, m_componentCarrierId);
713 }
714 
715 void
DoReportMacCeToScheduler(MacCeListElement_s bsr)716 LteEnbMac::DoReportMacCeToScheduler (MacCeListElement_s bsr)
717 {
718   NS_LOG_FUNCTION (this);
719   NS_LOG_DEBUG (this << " bsr Size " << (uint16_t) m_ulCeReceived.size ());
720   //send to LteCcmMacSapUser
721   m_ulCeReceived.push_back (bsr); // this to called when LteUlCcmSapProvider::ReportMacCeToScheduler is called
722   NS_LOG_DEBUG (this << " bsr Size after push_back " << (uint16_t) m_ulCeReceived.size ());
723 }
724 
725 
726 void
DoReceivePhyPdu(Ptr<Packet> p)727 LteEnbMac::DoReceivePhyPdu (Ptr<Packet> p)
728 {
729   NS_LOG_FUNCTION (this);
730   LteRadioBearerTag tag;
731   p->RemovePacketTag (tag);
732 
733   // store info of the packet received
734 
735 //   std::map <uint16_t,UlInfoListElement_s>::iterator it;
736 //   u_int rnti = tag.GetRnti ();
737 //  u_int lcid = tag.GetLcid ();
738 //   it = m_ulInfoListElements.find (tag.GetRnti ());
739 //   if (it == m_ulInfoListElements.end ())
740 //     {
741 //       // new RNTI
742 //       UlInfoListElement_s ulinfonew;
743 //       ulinfonew.m_rnti = tag.GetRnti ();
744 //       // always allocate full size of ulReception vector, initializing all elements to 0
745 //       ulinfonew.m_ulReception.assign (MAX_LC_LIST+1, 0);
746 //       // set the element for the current LCID
747 //       ulinfonew.m_ulReception.at (tag.GetLcid ()) = p->GetSize ();
748 //       ulinfonew.m_receptionStatus = UlInfoListElement_s::Ok;
749 //       ulinfonew.m_tpc = 0; // Tx power control not implemented at this stage
750 //       m_ulInfoListElements.insert (std::pair<uint16_t, UlInfoListElement_s > (tag.GetRnti (), ulinfonew));
751 //
752 //     }
753 //   else
754 //     {
755 //       // existing RNTI: we just set the value for the current
756 //       // LCID. Note that the corresponding element had already been
757 //       // allocated previously.
758 //       NS_ASSERT_MSG ((*it).second.m_ulReception.at (tag.GetLcid ()) == 0, "would overwrite previously written ulReception element");
759 //       (*it).second.m_ulReception.at (tag.GetLcid ()) = p->GetSize ();
760 //       (*it).second.m_receptionStatus = UlInfoListElement_s::Ok;
761 //     }
762 
763 
764 
765   // forward the packet to the correspondent RLC
766   uint16_t rnti = tag.GetRnti ();
767   uint8_t lcid = tag.GetLcid ();
768   std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator rntiIt = m_rlcAttached.find (rnti);
769   NS_ASSERT_MSG (rntiIt != m_rlcAttached.end (), "could not find RNTI" << rnti);
770   std::map<uint8_t, LteMacSapUser*>::iterator lcidIt = rntiIt->second.find (lcid);
771   //NS_ASSERT_MSG (lcidIt != rntiIt->second.end (), "could not find LCID" << lcid);
772 
773   LteMacSapUser::ReceivePduParameters rxPduParams;
774   rxPduParams.p = p;
775   rxPduParams.rnti = rnti;
776   rxPduParams.lcid = lcid;
777 
778   //Receive PDU only if LCID is found
779   if (lcidIt != rntiIt->second.end ())
780     {
781       (*lcidIt).second->ReceivePdu (rxPduParams);
782     }
783 }
784 
785 
786 
787 // ////////////////////////////////////////////
788 // CMAC SAP
789 // ////////////////////////////////////////////
790 
791 void
DoConfigureMac(uint16_t ulBandwidth,uint16_t dlBandwidth)792 LteEnbMac::DoConfigureMac (uint16_t ulBandwidth, uint16_t dlBandwidth)
793 {
794   NS_LOG_FUNCTION (this << " ulBandwidth=" << ulBandwidth << " dlBandwidth=" << dlBandwidth);
795   FfMacCschedSapProvider::CschedCellConfigReqParameters params;
796   // Configure the subset of parameters used by FfMacScheduler
797   params.m_ulBandwidth = ulBandwidth;
798   params.m_dlBandwidth = dlBandwidth;
799   m_macChTtiDelay = m_enbPhySapProvider->GetMacChTtiDelay ();
800   // ...more parameters can be configured
801   m_cschedSapProvider->CschedCellConfigReq (params);
802 }
803 
804 
805 void
DoAddUe(uint16_t rnti)806 LteEnbMac::DoAddUe (uint16_t rnti)
807 {
808   NS_LOG_FUNCTION (this << " rnti=" << rnti);
809   std::map<uint8_t, LteMacSapUser*> empty;
810   std::pair <std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator, bool>
811     ret = m_rlcAttached.insert (std::pair <uint16_t,  std::map<uint8_t, LteMacSapUser*> >
812                                 (rnti, empty));
813   NS_ASSERT_MSG (ret.second, "element already present, RNTI already existed");
814 
815   FfMacCschedSapProvider::CschedUeConfigReqParameters params;
816   params.m_rnti = rnti;
817   params.m_transmissionMode = 0; // set to default value (SISO) for avoiding random initialization (valgrind error)
818 
819   m_cschedSapProvider->CschedUeConfigReq (params);
820 
821   // Create DL transmission HARQ buffers
822   std::vector < Ptr<PacketBurst> > dlHarqLayer0pkt;
823   dlHarqLayer0pkt.resize (8);
824   for (uint8_t i = 0; i < 8; i++)
825     {
826       Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
827       dlHarqLayer0pkt.at (i) = pb;
828     }
829   std::vector < Ptr<PacketBurst> > dlHarqLayer1pkt;
830   dlHarqLayer1pkt.resize (8);
831   for (uint8_t i = 0; i < 8; i++)
832     {
833       Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
834       dlHarqLayer1pkt.at (i) = pb;
835     }
836   DlHarqProcessesBuffer_t buf;
837   buf.push_back (dlHarqLayer0pkt);
838   buf.push_back (dlHarqLayer1pkt);
839   m_miDlHarqProcessesPackets.insert (std::pair <uint16_t, DlHarqProcessesBuffer_t> (rnti, buf));
840 }
841 
842 void
DoRemoveUe(uint16_t rnti)843 LteEnbMac::DoRemoveUe (uint16_t rnti)
844 {
845   NS_LOG_FUNCTION (this << " rnti=" << rnti);
846   FfMacCschedSapProvider::CschedUeReleaseReqParameters params;
847   params.m_rnti = rnti;
848   m_cschedSapProvider->CschedUeReleaseReq (params);
849   m_rlcAttached.erase (rnti);
850   m_miDlHarqProcessesPackets.erase (rnti);
851 
852   NS_LOG_DEBUG ("start checking for unprocessed preamble for rnti: " << rnti);
853   //remove unprocessed preamble received for RACH during handover
854   std::map<uint8_t, NcRaPreambleInfo>::iterator jt = m_allocatedNcRaPreambleMap.begin ();
855   while (jt != m_allocatedNcRaPreambleMap.end ())
856     {
857       if (jt->second.rnti == rnti)
858         {
859           std::map<uint8_t, uint32_t>::const_iterator it = m_receivedRachPreambleCount.find (jt->first);
860           if (it != m_receivedRachPreambleCount.end ())
861             {
862               m_receivedRachPreambleCount.erase (it->first);
863             }
864           jt = m_allocatedNcRaPreambleMap.erase (jt);
865         }
866       else
867         {
868           ++jt;
869         }
870     }
871 
872   std::vector<MacCeListElement_s>::iterator itCeRxd = m_ulCeReceived.begin ();
873   while (itCeRxd != m_ulCeReceived.end ())
874     {
875       if (itCeRxd->m_rnti == rnti)
876         {
877           itCeRxd = m_ulCeReceived.erase (itCeRxd);
878         }
879       else
880         {
881           itCeRxd++;
882         }
883     }
884 }
885 
886 void
DoAddLc(LteEnbCmacSapProvider::LcInfo lcinfo,LteMacSapUser * msu)887 LteEnbMac::DoAddLc (LteEnbCmacSapProvider::LcInfo lcinfo, LteMacSapUser* msu)
888 {
889   NS_LOG_FUNCTION (this << lcinfo.rnti << (uint16_t) lcinfo.lcId);
890 
891   std::map <LteFlowId_t, LteMacSapUser* >::iterator it;
892 
893   LteFlowId_t flow (lcinfo.rnti, lcinfo.lcId);
894 
895   std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator rntiIt = m_rlcAttached.find (lcinfo.rnti);
896   NS_ASSERT_MSG (rntiIt != m_rlcAttached.end (), "RNTI not found");
897   std::map<uint8_t, LteMacSapUser*>::iterator lcidIt = rntiIt->second.find (lcinfo.lcId);
898   if (lcidIt == rntiIt->second.end ())
899     {
900       rntiIt->second.insert (std::pair<uint8_t, LteMacSapUser*> (lcinfo.lcId, msu));
901     }
902   else
903     {
904       NS_LOG_ERROR ("LC already exists");
905     }
906 
907   // CCCH (LCID 0) is pre-configured
908   // see FF LTE MAC Scheduler
909   // Interface Specification v1.11,
910   // 4.3.4 logicalChannelConfigListElement
911   if (lcinfo.lcId != 0)
912     {
913       struct FfMacCschedSapProvider::CschedLcConfigReqParameters params;
914       params.m_rnti = lcinfo.rnti;
915       params.m_reconfigureFlag = false;
916 
917       struct LogicalChannelConfigListElement_s lccle;
918       lccle.m_logicalChannelIdentity = lcinfo.lcId;
919       lccle.m_logicalChannelGroup = lcinfo.lcGroup;
920       lccle.m_direction = LogicalChannelConfigListElement_s::DIR_BOTH;
921       lccle.m_qosBearerType = lcinfo.isGbr ? LogicalChannelConfigListElement_s::QBT_GBR : LogicalChannelConfigListElement_s::QBT_NON_GBR;
922       lccle.m_qci = lcinfo.qci;
923       lccle.m_eRabMaximulBitrateUl = lcinfo.mbrUl;
924       lccle.m_eRabMaximulBitrateDl = lcinfo.mbrDl;
925       lccle.m_eRabGuaranteedBitrateUl = lcinfo.gbrUl;
926       lccle.m_eRabGuaranteedBitrateDl = lcinfo.gbrDl;
927       params.m_logicalChannelConfigList.push_back (lccle);
928 
929       m_cschedSapProvider->CschedLcConfigReq (params);
930     }
931 }
932 
933 void
DoReconfigureLc(LteEnbCmacSapProvider::LcInfo lcinfo)934 LteEnbMac::DoReconfigureLc (LteEnbCmacSapProvider::LcInfo lcinfo)
935 {
936   NS_FATAL_ERROR ("not implemented");
937 }
938 
939 void
DoReleaseLc(uint16_t rnti,uint8_t lcid)940 LteEnbMac::DoReleaseLc (uint16_t rnti, uint8_t lcid)
941 {
942   NS_LOG_FUNCTION (this);
943 
944   //Find user based on rnti and then erase lcid stored against the same
945   std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator rntiIt = m_rlcAttached.find (rnti);
946   rntiIt->second.erase (lcid);
947 
948   struct FfMacCschedSapProvider::CschedLcReleaseReqParameters params;
949   params.m_rnti = rnti;
950   params.m_logicalChannelIdentity.push_back (lcid);
951   m_cschedSapProvider->CschedLcReleaseReq (params);
952 }
953 
954 void
DoUeUpdateConfigurationReq(LteEnbCmacSapProvider::UeConfig params)955 LteEnbMac::DoUeUpdateConfigurationReq (LteEnbCmacSapProvider::UeConfig params)
956 {
957   NS_LOG_FUNCTION (this);
958 
959   // propagates to scheduler
960   FfMacCschedSapProvider::CschedUeConfigReqParameters req;
961   req.m_rnti = params.m_rnti;
962   req.m_transmissionMode = params.m_transmissionMode;
963   req.m_reconfigureFlag = true;
964   m_cschedSapProvider->CschedUeConfigReq (req);
965 }
966 
967 LteEnbCmacSapProvider::RachConfig
DoGetRachConfig()968 LteEnbMac::DoGetRachConfig ()
969 {
970   struct LteEnbCmacSapProvider::RachConfig rc;
971   rc.numberOfRaPreambles = m_numberOfRaPreambles;
972   rc.preambleTransMax = m_preambleTransMax;
973   rc.raResponseWindowSize = m_raResponseWindowSize;
974   rc.connEstFailCount = m_connEstFailCount;
975   return rc;
976 }
977 
978 LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue
DoAllocateNcRaPreamble(uint16_t rnti)979 LteEnbMac::DoAllocateNcRaPreamble (uint16_t rnti)
980 {
981   bool found = false;
982   uint8_t preambleId;
983   for (preambleId = m_numberOfRaPreambles; preambleId < 64; ++preambleId)
984     {
985       std::map<uint8_t, NcRaPreambleInfo>::iterator it = m_allocatedNcRaPreambleMap.find (preambleId);
986       /**
987        * Allocate preamble only if its free. The non-contention preamble
988        * assigned to UE during handover or PDCCH order is valid only until the
989        * time duration of the “expiryTime” of the preamble is reached. This
990        * timer value is only maintained at the eNodeB and the UE has no way of
991        * knowing if this timer has expired. If the UE tries to send the preamble
992        * again after the expiryTime and the preamble is re-assigned to another
993        * UE, it results in errors. This has been solved by re-assigning the
994        * preamble to another UE only if it is not being used (An UE can be using
995        * the preamble even after the expiryTime duration).
996        */
997       if ((it != m_allocatedNcRaPreambleMap.end ()) && (it->second.expiryTime < Simulator::Now ()))
998         {
999           if (!m_cmacSapUser->IsRandomAccessCompleted (it->second.rnti))
1000             {
1001               //random access of the UE is not completed,
1002               //check other preambles
1003               continue;
1004             }
1005         }
1006       if ((it ==  m_allocatedNcRaPreambleMap.end ())
1007           || (it->second.expiryTime < Simulator::Now ()))
1008         {
1009           found = true;
1010           NcRaPreambleInfo preambleInfo;
1011           uint32_t expiryIntervalMs = (uint32_t) m_preambleTransMax * ((uint32_t) m_raResponseWindowSize + 5);
1012 
1013           preambleInfo.expiryTime = Simulator::Now () + MilliSeconds (expiryIntervalMs);
1014           preambleInfo.rnti = rnti;
1015           NS_LOG_INFO ("allocated preamble for NC based RA: preamble " << preambleId << ", RNTI " << preambleInfo.rnti << ", exiryTime " << preambleInfo.expiryTime);
1016           m_allocatedNcRaPreambleMap[preambleId] = preambleInfo; // create if not exist, update otherwise
1017           break;
1018         }
1019     }
1020   LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue ret;
1021   if (found)
1022     {
1023       ret.valid = true;
1024       ret.raPreambleId = preambleId;
1025       ret.raPrachMaskIndex = 0;
1026     }
1027   else
1028     {
1029       ret.valid = false;
1030       ret.raPreambleId = 0;
1031       ret.raPrachMaskIndex = 0;
1032     }
1033   return ret;
1034 }
1035 
1036 
1037 
1038 // ////////////////////////////////////////////
1039 // MAC SAP
1040 // ////////////////////////////////////////////
1041 
1042 
1043 void
DoTransmitPdu(LteMacSapProvider::TransmitPduParameters params)1044 LteEnbMac::DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params)
1045 {
1046   NS_LOG_FUNCTION (this);
1047   LteRadioBearerTag tag (params.rnti, params.lcid, params.layer);
1048   params.pdu->AddPacketTag (tag);
1049   params.componentCarrierId = m_componentCarrierId;
1050   // Store pkt in HARQ buffer
1051   std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it =  m_miDlHarqProcessesPackets.find (params.rnti);
1052   NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
1053   NS_LOG_DEBUG (this << " LAYER " << (uint16_t)tag.GetLayer () << " HARQ ID " << (uint16_t)params.harqProcessId);
1054 
1055   //(*it).second.at (params.layer).at (params.harqProcessId) = params.pdu;//->Copy ();
1056   (*it).second.at (params.layer).at (params.harqProcessId)->AddPacket (params.pdu);
1057   m_enbPhySapProvider->SendMacPdu (params.pdu);
1058 }
1059 
1060 void
DoReportBufferStatus(LteMacSapProvider::ReportBufferStatusParameters params)1061 LteEnbMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params)
1062 {
1063   NS_LOG_FUNCTION (this);
1064   FfMacSchedSapProvider::SchedDlRlcBufferReqParameters req;
1065   req.m_rnti = params.rnti;
1066   req.m_logicalChannelIdentity = params.lcid;
1067   req.m_rlcTransmissionQueueSize = params.txQueueSize;
1068   req.m_rlcTransmissionQueueHolDelay = params.txQueueHolDelay;
1069   req.m_rlcRetransmissionQueueSize = params.retxQueueSize;
1070   req.m_rlcRetransmissionHolDelay = params.retxQueueHolDelay;
1071   req.m_rlcStatusPduSize = params.statusPduSize;
1072   m_schedSapProvider->SchedDlRlcBufferReq (req);
1073 }
1074 
1075 
1076 
1077 // ////////////////////////////////////////////
1078 // SCHED SAP
1079 // ////////////////////////////////////////////
1080 
1081 
1082 
1083 void
DoSchedDlConfigInd(FfMacSchedSapUser::SchedDlConfigIndParameters ind)1084 LteEnbMac::DoSchedDlConfigInd (FfMacSchedSapUser::SchedDlConfigIndParameters ind)
1085 {
1086   NS_LOG_FUNCTION (this);
1087   // Create DL PHY PDU
1088   Ptr<PacketBurst> pb = CreateObject<PacketBurst> ();
1089   std::map <LteFlowId_t, LteMacSapUser* >::iterator it;
1090   LteMacSapUser::TxOpportunityParameters txOpParams;
1091 
1092   for (unsigned int i = 0; i < ind.m_buildDataList.size (); i++)
1093     {
1094       for (uint16_t layer = 0; layer < ind.m_buildDataList.at (i).m_dci.m_ndi.size (); layer++)
1095         {
1096           if (ind.m_buildDataList.at (i).m_dci.m_ndi.at (layer) == 1)
1097             {
1098               // new data -> force emptying correspondent harq pkt buffer
1099               std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (ind.m_buildDataList.at (i).m_rnti);
1100               NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
1101               for (uint16_t lcId = 0; lcId < (*it).second.size (); lcId++)
1102                 {
1103                   Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
1104                   (*it).second.at (lcId).at (ind.m_buildDataList.at (i).m_dci.m_harqProcess) = pb;
1105                 }
1106             }
1107         }
1108       for (unsigned int j = 0; j < ind.m_buildDataList.at (i).m_rlcPduList.size (); j++)
1109         {
1110           for (uint16_t k = 0; k < ind.m_buildDataList.at (i).m_rlcPduList.at (j).size (); k++)
1111             {
1112               if (ind.m_buildDataList.at (i).m_dci.m_ndi.at (k) == 1)
1113                 {
1114                   // New Data -> retrieve it from RLC
1115                   uint16_t rnti = ind.m_buildDataList.at (i).m_rnti;
1116                   uint8_t lcid = ind.m_buildDataList.at (i).m_rlcPduList.at (j).at (k).m_logicalChannelIdentity;
1117                   std::map <uint16_t, std::map<uint8_t, LteMacSapUser*> >::iterator rntiIt = m_rlcAttached.find (rnti);
1118                   NS_ASSERT_MSG (rntiIt != m_rlcAttached.end (), "could not find RNTI" << rnti);
1119                   std::map<uint8_t, LteMacSapUser*>::iterator lcidIt = rntiIt->second.find (lcid);
1120                   NS_ASSERT_MSG (lcidIt != rntiIt->second.end (), "could not find LCID" << (uint32_t)lcid<<" carrier id:"<<(uint16_t)m_componentCarrierId);
1121                   NS_LOG_DEBUG (this << " rnti= " << rnti << " lcid= " << (uint32_t) lcid << " layer= " << k);
1122                   txOpParams.bytes = ind.m_buildDataList.at (i).m_rlcPduList.at (j).at (k).m_size;
1123                   txOpParams.layer = k;
1124                   txOpParams.harqId = ind.m_buildDataList.at (i).m_dci.m_harqProcess;
1125                   txOpParams.componentCarrierId = m_componentCarrierId;
1126                   txOpParams.rnti = rnti;
1127                   txOpParams.lcid = lcid;
1128                   (*lcidIt).second->NotifyTxOpportunity (txOpParams);
1129                 }
1130               else
1131                 {
1132                   if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (k) > 0)
1133                     {
1134                       // HARQ retransmission -> retrieve TB from HARQ buffer
1135                       std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it = m_miDlHarqProcessesPackets.find (ind.m_buildDataList.at (i).m_rnti);
1136                       NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
1137                       Ptr<PacketBurst> pb = (*it).second.at (k).at ( ind.m_buildDataList.at (i).m_dci.m_harqProcess);
1138                       for (std::list<Ptr<Packet> >::const_iterator j = pb->Begin (); j != pb->End (); ++j)
1139                         {
1140                           Ptr<Packet> pkt = (*j)->Copy ();
1141                           m_enbPhySapProvider->SendMacPdu (pkt);
1142                         }
1143                     }
1144                 }
1145             }
1146         }
1147       // send the relative DCI
1148       Ptr<DlDciLteControlMessage> msg = Create<DlDciLteControlMessage> ();
1149       msg->SetDci (ind.m_buildDataList.at (i).m_dci);
1150       m_enbPhySapProvider->SendLteControlMessage (msg);
1151     }
1152 
1153   // Fire the trace with the DL information
1154   for (  uint32_t i  = 0; i < ind.m_buildDataList.size (); i++ )
1155     {
1156       // Only one TB used
1157       if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.size () == 1)
1158         {
1159           DlSchedulingCallbackInfo dlSchedulingCallbackInfo;
1160           dlSchedulingCallbackInfo.frameNo = m_frameNo;
1161           dlSchedulingCallbackInfo.subframeNo = m_subframeNo;
1162           dlSchedulingCallbackInfo.rnti = ind.m_buildDataList.at (i).m_dci.m_rnti;
1163           dlSchedulingCallbackInfo.mcsTb1=ind.m_buildDataList.at (i).m_dci.m_mcs.at (0);
1164           dlSchedulingCallbackInfo.sizeTb1 = ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (0);
1165           dlSchedulingCallbackInfo.mcsTb2 = 0;
1166           dlSchedulingCallbackInfo.sizeTb2 = 0;
1167           dlSchedulingCallbackInfo.componentCarrierId = m_componentCarrierId;
1168           m_dlScheduling(dlSchedulingCallbackInfo);
1169         }
1170       // Two TBs used
1171       else if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.size () == 2)
1172         {
1173           DlSchedulingCallbackInfo dlSchedulingCallbackInfo;
1174           dlSchedulingCallbackInfo.frameNo = m_frameNo;
1175           dlSchedulingCallbackInfo.subframeNo = m_subframeNo;
1176           dlSchedulingCallbackInfo.rnti = ind.m_buildDataList.at (i).m_dci.m_rnti;
1177           dlSchedulingCallbackInfo.mcsTb1=ind.m_buildDataList.at (i).m_dci.m_mcs.at (0);
1178           dlSchedulingCallbackInfo.sizeTb1 = ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (0);
1179           dlSchedulingCallbackInfo.mcsTb2 = ind.m_buildDataList.at (i).m_dci.m_mcs.at (1);
1180           dlSchedulingCallbackInfo.sizeTb2 = ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (1);
1181           dlSchedulingCallbackInfo.componentCarrierId = m_componentCarrierId;
1182           m_dlScheduling(dlSchedulingCallbackInfo);
1183         }
1184       else
1185         {
1186           NS_FATAL_ERROR ("Found element with more than two transport blocks");
1187         }
1188     }
1189 
1190   // Random Access procedure: send RARs
1191   Ptr<RarLteControlMessage> rarMsg = Create<RarLteControlMessage> ();
1192   // see TS 36.321 5.1.4;  preambles were sent two frames ago
1193   // (plus 3GPP counts subframes from 0, not 1)
1194   uint16_t raRnti;
1195   if (m_subframeNo < 3)
1196     {
1197       raRnti = m_subframeNo + 7; // equivalent to +10-3
1198     }
1199   else
1200     {
1201       raRnti = m_subframeNo - 3;
1202     }
1203   rarMsg->SetRaRnti (raRnti);
1204   for (unsigned int i = 0; i < ind.m_buildRarList.size (); i++)
1205     {
1206       std::map <uint16_t, uint32_t>::iterator itRapId = m_rapIdRntiMap.find (ind.m_buildRarList.at (i).m_rnti);
1207       if (itRapId == m_rapIdRntiMap.end ())
1208         {
1209           NS_FATAL_ERROR ("Unable to find rapId of RNTI " << ind.m_buildRarList.at (i).m_rnti);
1210         }
1211       RarLteControlMessage::Rar rar;
1212       rar.rapId = itRapId->second;
1213       rar.rarPayload = ind.m_buildRarList.at (i);
1214       rarMsg->AddRar (rar);
1215       NS_LOG_INFO (this << " Send RAR message to RNTI " << ind.m_buildRarList.at (i).m_rnti << " rapId " << itRapId->second);
1216     }
1217   if (ind.m_buildRarList.size () > 0)
1218     {
1219       m_enbPhySapProvider->SendLteControlMessage (rarMsg);
1220     }
1221   m_rapIdRntiMap.clear ();
1222 }
1223 
1224 
1225 void
DoSchedUlConfigInd(FfMacSchedSapUser::SchedUlConfigIndParameters ind)1226 LteEnbMac::DoSchedUlConfigInd (FfMacSchedSapUser::SchedUlConfigIndParameters ind)
1227 {
1228   NS_LOG_FUNCTION (this);
1229 
1230   for (unsigned int i = 0; i < ind.m_dciList.size (); i++)
1231     {
1232       // send the correspondent ul dci
1233       Ptr<UlDciLteControlMessage> msg = Create<UlDciLteControlMessage> ();
1234       msg->SetDci (ind.m_dciList.at (i));
1235       m_enbPhySapProvider->SendLteControlMessage (msg);
1236     }
1237 
1238   // Fire the trace with the UL information
1239   for (  uint32_t i  = 0; i < ind.m_dciList.size (); i++ )
1240     {
1241       m_ulScheduling (m_frameNo, m_subframeNo, ind.m_dciList.at (i).m_rnti,
1242                       ind.m_dciList.at (i).m_mcs, ind.m_dciList.at (i).m_tbSize, m_componentCarrierId);
1243     }
1244 
1245 
1246 
1247 }
1248 
1249 
1250 
1251 
1252 // ////////////////////////////////////////////
1253 // CSCHED SAP
1254 // ////////////////////////////////////////////
1255 
1256 
1257 void
DoCschedCellConfigCnf(FfMacCschedSapUser::CschedCellConfigCnfParameters params)1258 LteEnbMac::DoCschedCellConfigCnf (FfMacCschedSapUser::CschedCellConfigCnfParameters params)
1259 {
1260   NS_LOG_FUNCTION (this);
1261 }
1262 
1263 void
DoCschedUeConfigCnf(FfMacCschedSapUser::CschedUeConfigCnfParameters params)1264 LteEnbMac::DoCschedUeConfigCnf (FfMacCschedSapUser::CschedUeConfigCnfParameters params)
1265 {
1266   NS_LOG_FUNCTION (this);
1267 }
1268 
1269 void
DoCschedLcConfigCnf(FfMacCschedSapUser::CschedLcConfigCnfParameters params)1270 LteEnbMac::DoCschedLcConfigCnf (FfMacCschedSapUser::CschedLcConfigCnfParameters params)
1271 {
1272   NS_LOG_FUNCTION (this);
1273   // Call the CSCHED primitive
1274   // m_cschedSap->LcConfigCompleted();
1275 }
1276 
1277 void
DoCschedLcReleaseCnf(FfMacCschedSapUser::CschedLcReleaseCnfParameters params)1278 LteEnbMac::DoCschedLcReleaseCnf (FfMacCschedSapUser::CschedLcReleaseCnfParameters params)
1279 {
1280   NS_LOG_FUNCTION (this);
1281 }
1282 
1283 void
DoCschedUeReleaseCnf(FfMacCschedSapUser::CschedUeReleaseCnfParameters params)1284 LteEnbMac::DoCschedUeReleaseCnf (FfMacCschedSapUser::CschedUeReleaseCnfParameters params)
1285 {
1286   NS_LOG_FUNCTION (this);
1287 }
1288 
1289 void
DoCschedUeConfigUpdateInd(FfMacCschedSapUser::CschedUeConfigUpdateIndParameters params)1290 LteEnbMac::DoCschedUeConfigUpdateInd (FfMacCschedSapUser::CschedUeConfigUpdateIndParameters params)
1291 {
1292   NS_LOG_FUNCTION (this);
1293   // propagates to RRC
1294   LteEnbCmacSapUser::UeConfig ueConfigUpdate;
1295   ueConfigUpdate.m_rnti = params.m_rnti;
1296   ueConfigUpdate.m_transmissionMode = params.m_transmissionMode;
1297   m_cmacSapUser->RrcConfigurationUpdateInd (ueConfigUpdate);
1298 }
1299 
1300 void
DoCschedCellConfigUpdateInd(FfMacCschedSapUser::CschedCellConfigUpdateIndParameters params)1301 LteEnbMac::DoCschedCellConfigUpdateInd (FfMacCschedSapUser::CschedCellConfigUpdateIndParameters params)
1302 {
1303   NS_LOG_FUNCTION (this);
1304 }
1305 
1306 void
DoUlInfoListElementHarqFeeback(UlInfoListElement_s params)1307 LteEnbMac::DoUlInfoListElementHarqFeeback (UlInfoListElement_s params)
1308 {
1309   NS_LOG_FUNCTION (this);
1310   m_ulInfoListReceived.push_back (params);
1311 }
1312 
1313 void
DoDlInfoListElementHarqFeeback(DlInfoListElement_s params)1314 LteEnbMac::DoDlInfoListElementHarqFeeback (DlInfoListElement_s params)
1315 {
1316   NS_LOG_FUNCTION (this);
1317   // Update HARQ buffer
1318   std::map <uint16_t, DlHarqProcessesBuffer_t>::iterator it =  m_miDlHarqProcessesPackets.find (params.m_rnti);
1319   NS_ASSERT (it != m_miDlHarqProcessesPackets.end ());
1320   for (uint8_t layer = 0; layer < params.m_harqStatus.size (); layer++)
1321     {
1322       if (params.m_harqStatus.at (layer) == DlInfoListElement_s::ACK)
1323         {
1324           // discard buffer
1325           Ptr<PacketBurst> emptyBuf = CreateObject <PacketBurst> ();
1326           (*it).second.at (layer).at (params.m_harqProcessId) = emptyBuf;
1327           NS_LOG_DEBUG (this << " HARQ-ACK UE " << params.m_rnti << " harqId " << (uint16_t)params.m_harqProcessId << " layer " << (uint16_t)layer);
1328         }
1329       else if (params.m_harqStatus.at (layer) == DlInfoListElement_s::NACK)
1330         {
1331           NS_LOG_DEBUG (this << " HARQ-NACK UE " << params.m_rnti << " harqId " << (uint16_t)params.m_harqProcessId << " layer " << (uint16_t)layer);
1332         }
1333       else
1334         {
1335           NS_FATAL_ERROR (" HARQ functionality not implemented");
1336         }
1337     }
1338   m_dlInfoListReceived.push_back (params);
1339 }
1340 
1341 
1342 } // namespace ns3
1343