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