1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
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: Giuseppe Piro <g.piro@poliba.it>
19 * Marco Miozzo <mmiozzo@cttc.es>
20 */
21
22 #include <ns3/object-factory.h>
23 #include <ns3/log.h>
24 #include <cfloat>
25 #include <cmath>
26 #include <ns3/simulator.h>
27 #include <ns3/attribute-accessor-helper.h>
28 #include <ns3/double.h>
29
30
31 #include "lte-enb-phy.h"
32 #include "lte-ue-phy.h"
33 #include "lte-net-device.h"
34 #include "lte-spectrum-value-helper.h"
35 #include "lte-control-messages.h"
36 #include "lte-enb-net-device.h"
37 #include "lte-ue-rrc.h"
38 #include "lte-enb-mac.h"
39 #include <ns3/lte-common.h>
40 #include <ns3/lte-vendor-specific-parameters.h>
41
42 // WILD HACK for the inizialization of direct eNB-UE ctrl messaging
43 #include <ns3/node-list.h>
44 #include <ns3/node.h>
45 #include <ns3/lte-ue-net-device.h>
46 #include <ns3/pointer.h>
47
48 namespace ns3 {
49
50 NS_LOG_COMPONENT_DEFINE ("LteEnbPhy");
51
52 NS_OBJECT_ENSURE_REGISTERED (LteEnbPhy);
53
54 /**
55 * Duration of the data portion of a DL subframe.
56 * Equals to "TTI length * (11/14) - margin".
57 * Data portion is fixed to 11 symbols out of the available 14 symbols.
58 * 1 nanosecond margin is added to avoid overlapping simulator events.
59 */
60 static const Time DL_DATA_DURATION = NanoSeconds (785714 - 1);
61
62 /**
63 * Delay from the start of a DL subframe to transmission of the data portion.
64 * Equals to "TTI length * (3/14)".
65 * Control portion is fixed to 3 symbols out of the available 14 symbols.
66 */
67 static const Time DL_CTRL_DELAY_FROM_SUBFRAME_START = NanoSeconds (214286);
68
69 ////////////////////////////////////////
70 // member SAP forwarders
71 ////////////////////////////////////////
72
73 /// \todo SetBandwidth() and SetCellId() can be removed.
74 class EnbMemberLteEnbPhySapProvider : public LteEnbPhySapProvider
75 {
76 public:
77 /**
78 * Constructor
79 *
80 * \param phy the ENB Phy
81 */
82 EnbMemberLteEnbPhySapProvider (LteEnbPhy* phy);
83
84 // inherited from LteEnbPhySapProvider
85 virtual void SendMacPdu (Ptr<Packet> p);
86 virtual void SendLteControlMessage (Ptr<LteControlMessage> msg);
87 virtual uint8_t GetMacChTtiDelay ();
88 /**
89 * Set bandwidth function
90 *
91 * \param ulBandwidth the UL bandwidth
92 * \param dlBandwidth the DL bandwidth
93 */
94 virtual void SetBandwidth (uint16_t ulBandwidth, uint16_t dlBandwidth);
95 /**
96 * Set Cell ID function
97 *
98 * \param cellId the cell ID
99 */
100 virtual void SetCellId (uint16_t cellId);
101
102 private:
103 LteEnbPhy* m_phy; ///< the ENB Phy
104 };
105
EnbMemberLteEnbPhySapProvider(LteEnbPhy * phy)106 EnbMemberLteEnbPhySapProvider::EnbMemberLteEnbPhySapProvider (LteEnbPhy* phy) : m_phy (phy)
107 {}
108
109 void
SendMacPdu(Ptr<Packet> p)110 EnbMemberLteEnbPhySapProvider::SendMacPdu (Ptr<Packet> p)
111 {
112 m_phy->DoSendMacPdu (p);
113 }
114
115 void
SetBandwidth(uint16_t ulBandwidth,uint16_t dlBandwidth)116 EnbMemberLteEnbPhySapProvider::SetBandwidth (uint16_t ulBandwidth, uint16_t dlBandwidth)
117 {
118 m_phy->DoSetBandwidth (ulBandwidth, dlBandwidth);
119 }
120
121 void
SetCellId(uint16_t cellId)122 EnbMemberLteEnbPhySapProvider::SetCellId (uint16_t cellId)
123 {
124 m_phy->DoSetCellId (cellId);
125 }
126
127 void
SendLteControlMessage(Ptr<LteControlMessage> msg)128 EnbMemberLteEnbPhySapProvider::SendLteControlMessage (Ptr<LteControlMessage> msg)
129 {
130 m_phy->DoSendLteControlMessage (msg);
131 }
132
133 uint8_t
GetMacChTtiDelay()134 EnbMemberLteEnbPhySapProvider::GetMacChTtiDelay ()
135 {
136 return (m_phy->DoGetMacChTtiDelay ());
137 }
138
139
140 ////////////////////////////////////////
141 // generic LteEnbPhy methods
142 ////////////////////////////////////////
143
144
145
LteEnbPhy()146 LteEnbPhy::LteEnbPhy ()
147 {
148 NS_LOG_FUNCTION (this);
149 NS_FATAL_ERROR ("This constructor should not be called");
150 }
151
LteEnbPhy(Ptr<LteSpectrumPhy> dlPhy,Ptr<LteSpectrumPhy> ulPhy)152 LteEnbPhy::LteEnbPhy (Ptr<LteSpectrumPhy> dlPhy, Ptr<LteSpectrumPhy> ulPhy)
153 : LtePhy (dlPhy, ulPhy),
154 m_enbPhySapUser (0),
155 m_enbCphySapUser (0),
156 m_nrFrames (0),
157 m_nrSubFrames (0),
158 m_srsPeriodicity (0),
159 m_srsStartTime (Seconds (0)),
160 m_currentSrsOffset (0),
161 m_interferenceSampleCounter (0)
162 {
163 m_enbPhySapProvider = new EnbMemberLteEnbPhySapProvider (this);
164 m_enbCphySapProvider = new MemberLteEnbCphySapProvider<LteEnbPhy> (this);
165 m_harqPhyModule = Create <LteHarqPhy> ();
166 m_downlinkSpectrumPhy->SetHarqPhyModule (m_harqPhyModule);
167 m_uplinkSpectrumPhy->SetHarqPhyModule (m_harqPhyModule);
168 }
169
170 TypeId
GetTypeId(void)171 LteEnbPhy::GetTypeId (void)
172 {
173 static TypeId tid = TypeId ("ns3::LteEnbPhy")
174 .SetParent<LtePhy> ()
175 .SetGroupName ("Lte")
176 .AddConstructor<LteEnbPhy> ()
177 .AddAttribute ("TxPower",
178 "Transmission power in dBm",
179 DoubleValue (30.0),
180 MakeDoubleAccessor (&LteEnbPhy::SetTxPower,
181 &LteEnbPhy::GetTxPower),
182 MakeDoubleChecker<double> ())
183 .AddAttribute ("NoiseFigure",
184 "Loss (dB) in the Signal-to-Noise-Ratio due to "
185 "non-idealities in the receiver. According to Wikipedia "
186 "(http://en.wikipedia.org/wiki/Noise_figure), this is "
187 "\"the difference in decibels (dB) between"
188 " the noise output of the actual receiver to "
189 "the noise output of an ideal receiver with "
190 "the same overall gain and bandwidth when the receivers "
191 "are connected to sources at the standard noise "
192 "temperature T0.\" In this model, we consider T0 = 290K.",
193 DoubleValue (5.0),
194 MakeDoubleAccessor (&LteEnbPhy::SetNoiseFigure,
195 &LteEnbPhy::GetNoiseFigure),
196 MakeDoubleChecker<double> ())
197 .AddAttribute ("MacToChannelDelay",
198 "The delay in TTI units that occurs between "
199 "a scheduling decision in the MAC and the actual "
200 "start of the transmission by the PHY. This is "
201 "intended to be used to model the latency of real PHY "
202 "and MAC implementations.",
203 UintegerValue (2),
204 MakeUintegerAccessor (&LteEnbPhy::SetMacChDelay,
205 &LteEnbPhy::GetMacChDelay),
206 MakeUintegerChecker<uint8_t> ())
207 .AddTraceSource ("ReportUeSinr",
208 "Report UEs' averaged linear SINR",
209 MakeTraceSourceAccessor (&LteEnbPhy::m_reportUeSinr),
210 "ns3::LteEnbPhy::ReportUeSinrTracedCallback")
211 .AddAttribute ("UeSinrSamplePeriod",
212 "The sampling period for reporting UEs' SINR stats.",
213 UintegerValue (1), /// \todo In what unit is this?
214 MakeUintegerAccessor (&LteEnbPhy::m_srsSamplePeriod),
215 MakeUintegerChecker<uint16_t> ())
216 .AddTraceSource ("ReportInterference",
217 "Report linear interference power per PHY RB",
218 MakeTraceSourceAccessor (&LteEnbPhy::m_reportInterferenceTrace),
219 "ns3::LteEnbPhy::ReportInterferenceTracedCallback")
220 .AddAttribute ("InterferenceSamplePeriod",
221 "The sampling period for reporting interference stats",
222 UintegerValue (1), /// \todo In what unit is this?
223 MakeUintegerAccessor (&LteEnbPhy::m_interferenceSamplePeriod),
224 MakeUintegerChecker<uint16_t> ())
225 .AddTraceSource ("DlPhyTransmission",
226 "DL transmission PHY layer statistics.",
227 MakeTraceSourceAccessor (&LteEnbPhy::m_dlPhyTransmission),
228 "ns3::PhyTransmissionStatParameters::TracedCallback")
229 .AddAttribute ("DlSpectrumPhy",
230 "The downlink LteSpectrumPhy associated to this LtePhy",
231 TypeId::ATTR_GET,
232 PointerValue (),
233 MakePointerAccessor (&LteEnbPhy::GetDlSpectrumPhy),
234 MakePointerChecker <LteSpectrumPhy> ())
235 .AddAttribute ("UlSpectrumPhy",
236 "The uplink LteSpectrumPhy associated to this LtePhy",
237 TypeId::ATTR_GET,
238 PointerValue (),
239 MakePointerAccessor (&LteEnbPhy::GetUlSpectrumPhy),
240 MakePointerChecker <LteSpectrumPhy> ())
241 ;
242 return tid;
243 }
244
245
~LteEnbPhy()246 LteEnbPhy::~LteEnbPhy ()
247 {}
248
249 void
DoDispose()250 LteEnbPhy::DoDispose ()
251 {
252 NS_LOG_FUNCTION (this);
253 m_ueAttached.clear ();
254 m_srsUeOffset.clear ();
255 delete m_enbPhySapProvider;
256 delete m_enbCphySapProvider;
257 LtePhy::DoDispose ();
258 }
259
260 void
DoInitialize()261 LteEnbPhy::DoInitialize ()
262 {
263 NS_LOG_FUNCTION (this);
264
265 NS_ABORT_MSG_IF (m_netDevice == nullptr, "LteEnbDevice is not available in LteEnbPhy");
266 Ptr<Node> node = m_netDevice->GetNode ();
267 NS_ABORT_MSG_IF (node == nullptr, "Node is not available in the LteNetDevice of LteEnbPhy");
268 uint32_t nodeId = node->GetId ();
269
270 //ScheduleWithContext() is needed here to set context for logs,
271 //because Initialize() is called outside of Node::AddDevice().
272
273 Simulator::ScheduleWithContext (nodeId, Seconds (0), &LteEnbPhy::StartFrame, this);
274
275 Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_ulEarfcn, m_ulBandwidth, m_noiseFigure);
276 m_uplinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
277 LtePhy::DoInitialize ();
278 }
279
280
281 void
SetLteEnbPhySapUser(LteEnbPhySapUser * s)282 LteEnbPhy::SetLteEnbPhySapUser (LteEnbPhySapUser* s)
283 {
284 m_enbPhySapUser = s;
285 }
286
287 LteEnbPhySapProvider*
GetLteEnbPhySapProvider()288 LteEnbPhy::GetLteEnbPhySapProvider ()
289 {
290 return (m_enbPhySapProvider);
291 }
292
293 void
SetLteEnbCphySapUser(LteEnbCphySapUser * s)294 LteEnbPhy::SetLteEnbCphySapUser (LteEnbCphySapUser* s)
295 {
296 NS_LOG_FUNCTION (this);
297 m_enbCphySapUser = s;
298 }
299
300 LteEnbCphySapProvider*
GetLteEnbCphySapProvider()301 LteEnbPhy::GetLteEnbCphySapProvider ()
302 {
303 NS_LOG_FUNCTION (this);
304 return (m_enbCphySapProvider);
305 }
306
307 void
SetTxPower(double pow)308 LteEnbPhy::SetTxPower (double pow)
309 {
310 NS_LOG_FUNCTION (this << pow);
311 m_txPower = pow;
312 }
313
314 double
GetTxPower() const315 LteEnbPhy::GetTxPower () const
316 {
317 NS_LOG_FUNCTION (this);
318 return m_txPower;
319 }
320
321 int8_t
DoGetReferenceSignalPower() const322 LteEnbPhy::DoGetReferenceSignalPower () const
323 {
324 NS_LOG_FUNCTION (this);
325 return m_txPower;
326 }
327
328 void
SetNoiseFigure(double nf)329 LteEnbPhy::SetNoiseFigure (double nf)
330 {
331 NS_LOG_FUNCTION (this << nf);
332 m_noiseFigure = nf;
333 }
334
335 double
GetNoiseFigure() const336 LteEnbPhy::GetNoiseFigure () const
337 {
338 NS_LOG_FUNCTION (this);
339 return m_noiseFigure;
340 }
341
342 void
SetMacChDelay(uint8_t delay)343 LteEnbPhy::SetMacChDelay (uint8_t delay)
344 {
345 NS_LOG_FUNCTION (this);
346 m_macChTtiDelay = delay;
347 for (int i = 0; i < m_macChTtiDelay; i++)
348 {
349 Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
350 m_packetBurstQueue.push_back (pb);
351 std::list<Ptr<LteControlMessage> > l;
352 m_controlMessagesQueue.push_back (l);
353 std::list<UlDciLteControlMessage> l1;
354 m_ulDciQueue.push_back (l1);
355 }
356 for (int i = 0; i < UL_PUSCH_TTIS_DELAY; i++)
357 {
358 std::list<UlDciLteControlMessage> l1;
359 m_ulDciQueue.push_back (l1);
360 }
361 }
362
363 uint8_t
GetMacChDelay(void) const364 LteEnbPhy::GetMacChDelay (void) const
365 {
366 return (m_macChTtiDelay);
367 }
368
369 Ptr<LteSpectrumPhy>
GetDlSpectrumPhy() const370 LteEnbPhy::GetDlSpectrumPhy () const
371 {
372 return m_downlinkSpectrumPhy;
373 }
374
375 Ptr<LteSpectrumPhy>
GetUlSpectrumPhy() const376 LteEnbPhy::GetUlSpectrumPhy () const
377 {
378 return m_uplinkSpectrumPhy;
379 }
380
381 bool
AddUePhy(uint16_t rnti)382 LteEnbPhy::AddUePhy (uint16_t rnti)
383 {
384 NS_LOG_FUNCTION (this << rnti);
385 std::set <uint16_t>::iterator it;
386 it = m_ueAttached.find (rnti);
387 if (it == m_ueAttached.end ())
388 {
389 m_ueAttached.insert (rnti);
390 return (true);
391 }
392 else
393 {
394 NS_LOG_ERROR ("UE already attached");
395 return (false);
396 }
397 }
398
399 bool
DeleteUePhy(uint16_t rnti)400 LteEnbPhy::DeleteUePhy (uint16_t rnti)
401 {
402 NS_LOG_FUNCTION (this << rnti);
403 std::set <uint16_t>::iterator it;
404 it = m_ueAttached.find (rnti);
405 if (it == m_ueAttached.end ())
406 {
407 NS_LOG_ERROR ("UE not attached");
408 return (false);
409 }
410 else
411 {
412 m_ueAttached.erase (it);
413 return (true);
414 }
415 }
416
417
418
419 void
DoSendMacPdu(Ptr<Packet> p)420 LteEnbPhy::DoSendMacPdu (Ptr<Packet> p)
421 {
422 NS_LOG_FUNCTION (this);
423 SetMacPdu (p);
424 }
425
426 uint8_t
DoGetMacChTtiDelay()427 LteEnbPhy::DoGetMacChTtiDelay ()
428 {
429 return (m_macChTtiDelay);
430 }
431
432
433 void
PhyPduReceived(Ptr<Packet> p)434 LteEnbPhy::PhyPduReceived (Ptr<Packet> p)
435 {
436 NS_LOG_FUNCTION (this);
437 m_enbPhySapUser->ReceivePhyPdu (p);
438 }
439
440 void
SetDownlinkSubChannels(std::vector<int> mask)441 LteEnbPhy::SetDownlinkSubChannels (std::vector<int> mask)
442 {
443 NS_LOG_FUNCTION (this);
444 m_listOfDownlinkSubchannel = mask;
445 Ptr<SpectrumValue> txPsd = CreateTxPowerSpectralDensity ();
446 m_downlinkSpectrumPhy->SetTxPowerSpectralDensity (txPsd);
447 }
448
449 void
SetDownlinkSubChannelsWithPowerAllocation(std::vector<int> mask)450 LteEnbPhy::SetDownlinkSubChannelsWithPowerAllocation (std::vector<int> mask)
451 {
452 NS_LOG_FUNCTION (this);
453 m_listOfDownlinkSubchannel = mask;
454 Ptr<SpectrumValue> txPsd = CreateTxPowerSpectralDensityWithPowerAllocation ();
455 m_downlinkSpectrumPhy->SetTxPowerSpectralDensity (txPsd);
456 }
457
458 std::vector<int>
GetDownlinkSubChannels(void)459 LteEnbPhy::GetDownlinkSubChannels (void)
460 {
461 NS_LOG_FUNCTION (this);
462 return m_listOfDownlinkSubchannel;
463 }
464
465 void
GeneratePowerAllocationMap(uint16_t rnti,int rbId)466 LteEnbPhy::GeneratePowerAllocationMap (uint16_t rnti, int rbId)
467 {
468 NS_LOG_FUNCTION (this);
469 double rbgTxPower = m_txPower;
470
471 std::map<uint16_t, double>::iterator it = m_paMap.find (rnti);
472 if (it != m_paMap.end ())
473 {
474 rbgTxPower = m_txPower + it->second;
475 }
476
477 m_dlPowerAllocationMap.insert (std::pair<int, double> (rbId, rbgTxPower));
478 }
479
480 Ptr<SpectrumValue>
CreateTxPowerSpectralDensity()481 LteEnbPhy::CreateTxPowerSpectralDensity ()
482 {
483 NS_LOG_FUNCTION (this);
484
485 Ptr<SpectrumValue> psd = LteSpectrumValueHelper::CreateTxPowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_txPower, GetDownlinkSubChannels ());
486
487 return psd;
488 }
489
490 Ptr<SpectrumValue>
CreateTxPowerSpectralDensityWithPowerAllocation()491 LteEnbPhy::CreateTxPowerSpectralDensityWithPowerAllocation ()
492 {
493 NS_LOG_FUNCTION (this);
494
495 Ptr<SpectrumValue> psd = LteSpectrumValueHelper::CreateTxPowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_txPower, m_dlPowerAllocationMap, GetDownlinkSubChannels ());
496
497 return psd;
498 }
499
500
501 void
CalcChannelQualityForUe(std::vector<double> sinr,Ptr<LteSpectrumPhy> ue)502 LteEnbPhy::CalcChannelQualityForUe (std::vector <double> sinr, Ptr<LteSpectrumPhy> ue)
503 {
504 NS_LOG_FUNCTION (this);
505 }
506
507
508 void
DoSendLteControlMessage(Ptr<LteControlMessage> msg)509 LteEnbPhy::DoSendLteControlMessage (Ptr<LteControlMessage> msg)
510 {
511 NS_LOG_FUNCTION (this << msg);
512 // queues the message (wait for MAC-PHY delay)
513 SetControlMessages (msg);
514 }
515
516
517
518 void
ReceiveLteControlMessage(Ptr<LteControlMessage> msg)519 LteEnbPhy::ReceiveLteControlMessage (Ptr<LteControlMessage> msg)
520 {
521 NS_FATAL_ERROR ("Obsolete function");
522 NS_LOG_FUNCTION (this << msg);
523 m_enbPhySapUser->ReceiveLteControlMessage (msg);
524 }
525
526 void
ReceiveLteControlMessageList(std::list<Ptr<LteControlMessage>> msgList)527 LteEnbPhy::ReceiveLteControlMessageList (std::list<Ptr<LteControlMessage> > msgList)
528 {
529 NS_LOG_FUNCTION (this);
530 std::list<Ptr<LteControlMessage> >::iterator it;
531 for (it = msgList.begin (); it != msgList.end (); it++)
532 {
533 switch ((*it)->GetMessageType ())
534 {
535 case LteControlMessage::RACH_PREAMBLE:
536 {
537 Ptr<RachPreambleLteControlMessage> rachPreamble = DynamicCast<RachPreambleLteControlMessage> (*it);
538 m_enbPhySapUser->ReceiveRachPreamble (rachPreamble->GetRapId ());
539 }
540 break;
541 case LteControlMessage::DL_CQI:
542 {
543 Ptr<DlCqiLteControlMessage> dlcqiMsg = DynamicCast<DlCqiLteControlMessage> (*it);
544 CqiListElement_s dlcqi = dlcqiMsg->GetDlCqi ();
545 // check whether the UE is connected
546 if (m_ueAttached.find (dlcqi.m_rnti) != m_ueAttached.end ())
547 {
548 m_enbPhySapUser->ReceiveLteControlMessage (*it);
549 }
550 }
551 break;
552 case LteControlMessage::BSR:
553 {
554 Ptr<BsrLteControlMessage> bsrMsg = DynamicCast<BsrLteControlMessage> (*it);
555 MacCeListElement_s bsr = bsrMsg->GetBsr ();
556 // check whether the UE is connected
557 if (m_ueAttached.find (bsr.m_rnti) != m_ueAttached.end ())
558 {
559 m_enbPhySapUser->ReceiveLteControlMessage (*it);
560 }
561 }
562 break;
563 case LteControlMessage::DL_HARQ:
564 {
565 Ptr<DlHarqFeedbackLteControlMessage> dlharqMsg = DynamicCast<DlHarqFeedbackLteControlMessage> (*it);
566 DlInfoListElement_s dlharq = dlharqMsg->GetDlHarqFeedback ();
567 // check whether the UE is connected
568 if (m_ueAttached.find (dlharq.m_rnti) != m_ueAttached.end ())
569 {
570 m_enbPhySapUser->ReceiveLteControlMessage (*it);
571 }
572 }
573 break;
574 default:
575 NS_FATAL_ERROR ("Unexpected LteControlMessage type");
576 break;
577 }
578 }
579 }
580
581
582
583 void
StartFrame(void)584 LteEnbPhy::StartFrame (void)
585 {
586 NS_LOG_FUNCTION (this);
587
588 ++m_nrFrames;
589 NS_LOG_INFO ("-----frame " << m_nrFrames << "-----");
590 m_nrSubFrames = 0;
591
592 // send MIB at beginning of every frame
593 m_mib.systemFrameNumber = m_nrSubFrames;
594 Ptr<MibLteControlMessage> mibMsg = Create<MibLteControlMessage> ();
595 mibMsg->SetMib (m_mib);
596 m_controlMessagesQueue.at (0).push_back (mibMsg);
597
598 StartSubFrame ();
599 }
600
601
602 void
StartSubFrame(void)603 LteEnbPhy::StartSubFrame (void)
604 {
605 NS_LOG_FUNCTION (this);
606
607 ++m_nrSubFrames;
608
609 /*
610 * Send SIB1 at 6th subframe of every odd-numbered radio frame. This is
611 * equivalent with Section 5.2.1.2 of 3GPP TS 36.331, where it is specified
612 * "repetitions are scheduled in subframe #5 of all other radio frames for
613 * which SFN mod 2 = 0," except that 3GPP counts frames and subframes starting
614 * from 0, while ns-3 counts starting from 1.
615 */
616 if ((m_nrSubFrames == 6) && ((m_nrFrames % 2) == 1))
617 {
618 Ptr<Sib1LteControlMessage> msg = Create<Sib1LteControlMessage> ();
619 msg->SetSib1 (m_sib1);
620 m_controlMessagesQueue.at (0).push_back (msg);
621 }
622
623 if (m_srsPeriodicity > 0)
624 {
625 // might be 0 in case the eNB has no UEs attached
626 NS_ASSERT_MSG (m_nrFrames > 1, "the SRS index check code assumes that frameNo starts at 1");
627 NS_ASSERT_MSG (m_nrSubFrames > 0 && m_nrSubFrames <= 10, "the SRS index check code assumes that subframeNo starts at 1");
628 m_currentSrsOffset = (((m_nrFrames - 1) * 10 + (m_nrSubFrames - 1)) % m_srsPeriodicity);
629 }
630 NS_LOG_INFO ("-----sub frame " << m_nrSubFrames << "-----");
631 m_harqPhyModule->SubframeIndication (m_nrFrames, m_nrSubFrames);
632
633 // update info on TB to be received
634 std::list<UlDciLteControlMessage> uldcilist = DequeueUlDci ();
635 std::list<UlDciLteControlMessage>::iterator dciIt = uldcilist.begin ();
636 NS_LOG_DEBUG (this << " eNB Expected TBs " << uldcilist.size ());
637 for (dciIt = uldcilist.begin (); dciIt != uldcilist.end (); dciIt++)
638 {
639 std::set <uint16_t>::iterator it2;
640 it2 = m_ueAttached.find ((*dciIt).GetDci ().m_rnti);
641
642 if (it2 == m_ueAttached.end ())
643 {
644 NS_LOG_ERROR ("UE not attached");
645 }
646 else
647 {
648 // send info of TB to LteSpectrumPhy
649 // translate to allocation map
650 std::vector <int> rbMap;
651 for (int i = (*dciIt).GetDci ().m_rbStart; i < (*dciIt).GetDci ().m_rbStart + (*dciIt).GetDci ().m_rbLen; i++)
652 {
653 rbMap.push_back (i);
654 }
655 m_uplinkSpectrumPhy->AddExpectedTb ((*dciIt).GetDci ().m_rnti, (*dciIt).GetDci ().m_ndi, (*dciIt).GetDci ().m_tbSize, (*dciIt).GetDci ().m_mcs, rbMap, 0 /* always SISO*/, 0 /* no HARQ proc id in UL*/, 0 /*evaluated by LteSpectrumPhy*/, false /* UL*/);
656 if ((*dciIt).GetDci ().m_ndi == 1)
657 {
658 NS_LOG_DEBUG (this << " RNTI " << (*dciIt).GetDci ().m_rnti << " NEW TB");
659 }
660 else
661 {
662 NS_LOG_DEBUG (this << " RNTI " << (*dciIt).GetDci ().m_rnti << " HARQ RETX");
663 }
664 }
665 }
666
667 // process the current burst of control messages
668 std::list<Ptr<LteControlMessage> > ctrlMsg = GetControlMessages ();
669 m_dlDataRbMap.clear ();
670 m_dlPowerAllocationMap.clear ();
671 if (ctrlMsg.size () > 0)
672 {
673 std::list<Ptr<LteControlMessage> >::iterator it;
674 it = ctrlMsg.begin ();
675 while (it != ctrlMsg.end ())
676 {
677 Ptr<LteControlMessage> msg = (*it);
678 if (msg->GetMessageType () == LteControlMessage::DL_DCI)
679 {
680 Ptr<DlDciLteControlMessage> dci = DynamicCast<DlDciLteControlMessage> (msg);
681 // get the tx power spectral density according to DL-DCI(s)
682 // translate the DCI to Spectrum framework
683 uint32_t mask = 0x1;
684 for (int i = 0; i < 32; i++)
685 {
686 if (((dci->GetDci ().m_rbBitmap & mask) >> i) == 1)
687 {
688 for (int k = 0; k < GetRbgSize (); k++)
689 {
690 m_dlDataRbMap.push_back ((i * GetRbgSize ()) + k);
691 //NS_LOG_DEBUG(this << " [enb]DL-DCI allocated PRB " << (i*GetRbgSize()) + k);
692 GeneratePowerAllocationMap (dci->GetDci ().m_rnti, (i * GetRbgSize ()) + k );
693 }
694 }
695 mask = (mask << 1);
696 }
697 // fire trace of DL Tx PHY stats
698 for (uint8_t i = 0; i < dci->GetDci ().m_mcs.size (); i++)
699 {
700 PhyTransmissionStatParameters params;
701 params.m_cellId = m_cellId;
702 params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
703 params.m_timestamp = Simulator::Now ().GetMilliSeconds ();
704 params.m_rnti = dci->GetDci ().m_rnti;
705 params.m_txMode = 0; // TBD
706 params.m_layer = i;
707 params.m_mcs = dci->GetDci ().m_mcs.at (i);
708 params.m_size = dci->GetDci ().m_tbsSize.at (i);
709 params.m_rv = dci->GetDci ().m_rv.at (i);
710 params.m_ndi = dci->GetDci ().m_ndi.at (i);
711 params.m_ccId = m_componentCarrierId;
712 m_dlPhyTransmission (params);
713 }
714
715 }
716 else if (msg->GetMessageType () == LteControlMessage::UL_DCI)
717 {
718 Ptr<UlDciLteControlMessage> dci = DynamicCast<UlDciLteControlMessage> (msg);
719 QueueUlDci (*dci);
720 }
721 else if (msg->GetMessageType () == LteControlMessage::RAR)
722 {
723 Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage> (msg);
724 for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin (); it != rarMsg->RarListEnd (); ++it)
725 {
726 if (it->rarPayload.m_grant.m_ulDelay == true)
727 {
728 NS_FATAL_ERROR (" RAR delay is not yet implemented");
729 }
730 UlGrant_s ulGrant = it->rarPayload.m_grant;
731 // translate the UL grant in a standard UL-DCI and queue it
732 UlDciListElement_s dci;
733 dci.m_rnti = ulGrant.m_rnti;
734 dci.m_rbStart = ulGrant.m_rbStart;
735 dci.m_rbLen = ulGrant.m_rbLen;
736 dci.m_tbSize = ulGrant.m_tbSize;
737 dci.m_mcs = ulGrant.m_mcs;
738 dci.m_hopping = ulGrant.m_hopping;
739 dci.m_tpc = ulGrant.m_tpc;
740 dci.m_cqiRequest = ulGrant.m_cqiRequest;
741 dci.m_ndi = 1;
742 UlDciLteControlMessage msg;
743 msg.SetDci (dci);
744 QueueUlDci (msg);
745 }
746 }
747 it++;
748
749 }
750 }
751
752 SendControlChannels (ctrlMsg);
753
754 // send data frame
755 Ptr<PacketBurst> pb = GetPacketBurst ();
756 if (pb)
757 {
758 Simulator::Schedule (DL_CTRL_DELAY_FROM_SUBFRAME_START, // ctrl frame fixed to 3 symbols
759 &LteEnbPhy::SendDataChannels,
760 this,pb);
761 }
762
763 // trigger the MAC
764 m_enbPhySapUser->SubframeIndication (m_nrFrames, m_nrSubFrames);
765
766 Simulator::Schedule (Seconds (GetTti ()),
767 &LteEnbPhy::EndSubFrame,
768 this);
769
770 }
771
772 void
SendControlChannels(std::list<Ptr<LteControlMessage>> ctrlMsgList)773 LteEnbPhy::SendControlChannels (std::list<Ptr<LteControlMessage> > ctrlMsgList)
774 {
775 NS_LOG_FUNCTION (this << " eNB " << m_cellId << " start tx ctrl frame");
776 // set the current tx power spectral density (full bandwidth)
777 std::vector <int> dlRb;
778 for (uint8_t i = 0; i < m_dlBandwidth; i++)
779 {
780 dlRb.push_back (i);
781 }
782 SetDownlinkSubChannels (dlRb);
783 NS_LOG_LOGIC (this << " eNB start TX CTRL");
784 bool pss = false;
785 if ((m_nrSubFrames == 1) || (m_nrSubFrames == 6))
786 {
787 pss = true;
788 }
789 m_downlinkSpectrumPhy->StartTxDlCtrlFrame (ctrlMsgList, pss);
790
791 }
792
793 void
SendDataChannels(Ptr<PacketBurst> pb)794 LteEnbPhy::SendDataChannels (Ptr<PacketBurst> pb)
795 {
796 // set the current tx power spectral density
797 SetDownlinkSubChannelsWithPowerAllocation (m_dlDataRbMap);
798 // send the current burts of packets
799 NS_LOG_LOGIC (this << " eNB start TX DATA");
800 std::list<Ptr<LteControlMessage> > ctrlMsgList;
801 ctrlMsgList.clear ();
802 m_downlinkSpectrumPhy->StartTxDataFrame (pb, ctrlMsgList, DL_DATA_DURATION);
803 }
804
805
806 void
EndSubFrame(void)807 LteEnbPhy::EndSubFrame (void)
808 {
809 NS_LOG_FUNCTION (this << Simulator::Now ().As (Time::S));
810 if (m_nrSubFrames == 10)
811 {
812 Simulator::ScheduleNow (&LteEnbPhy::EndFrame, this);
813 }
814 else
815 {
816 Simulator::ScheduleNow (&LteEnbPhy::StartSubFrame, this);
817 }
818 }
819
820
821 void
EndFrame(void)822 LteEnbPhy::EndFrame (void)
823 {
824 NS_LOG_FUNCTION (this << Simulator::Now ().As (Time::S));
825 Simulator::ScheduleNow (&LteEnbPhy::StartFrame, this);
826 }
827
828
829 void
GenerateCtrlCqiReport(const SpectrumValue & sinr)830 LteEnbPhy::GenerateCtrlCqiReport (const SpectrumValue& sinr)
831 {
832 NS_LOG_FUNCTION (this << sinr << Simulator::Now () << m_srsStartTime);
833 // avoid processing SRSs sent with an old SRS configuration index
834 if (Simulator::Now () > m_srsStartTime)
835 {
836 FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi = CreateSrsCqiReport (sinr);
837 m_enbPhySapUser->UlCqiReport (ulcqi);
838 }
839 }
840
841 void
GenerateDataCqiReport(const SpectrumValue & sinr)842 LteEnbPhy::GenerateDataCqiReport (const SpectrumValue& sinr)
843 {
844 NS_LOG_FUNCTION (this << sinr);
845 FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi = CreatePuschCqiReport (sinr);
846 m_enbPhySapUser->UlCqiReport (ulcqi);
847 }
848
849 void
ReportInterference(const SpectrumValue & interf)850 LteEnbPhy::ReportInterference (const SpectrumValue& interf)
851 {
852 NS_LOG_FUNCTION (this << interf);
853 Ptr<SpectrumValue> interfCopy = Create<SpectrumValue> (interf);
854 m_interferenceSampleCounter++;
855 if (m_interferenceSampleCounter == m_interferenceSamplePeriod)
856 {
857 m_reportInterferenceTrace (m_cellId, interfCopy);
858 m_interferenceSampleCounter = 0;
859 }
860 }
861
862 void
ReportRsReceivedPower(const SpectrumValue & power)863 LteEnbPhy::ReportRsReceivedPower (const SpectrumValue& power)
864 {
865 // not used by eNB
866 }
867
868
869
870 FfMacSchedSapProvider::SchedUlCqiInfoReqParameters
CreatePuschCqiReport(const SpectrumValue & sinr)871 LteEnbPhy::CreatePuschCqiReport (const SpectrumValue& sinr)
872 {
873 NS_LOG_FUNCTION (this << sinr);
874 Values::const_iterator it;
875 FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi;
876 ulcqi.m_ulCqi.m_type = UlCqi_s::PUSCH;
877 int i = 0;
878 for (it = sinr.ConstValuesBegin (); it != sinr.ConstValuesEnd (); it++)
879 {
880 double sinrdb = 10 * std::log10 ((*it));
881 // NS_LOG_DEBUG ("ULCQI RB " << i << " value " << sinrdb);
882 // convert from double to fixed point notation Sxxxxxxxxxxx.xxx
883 int16_t sinrFp = LteFfConverter::double2fpS11dot3 (sinrdb);
884 ulcqi.m_ulCqi.m_sinr.push_back (sinrFp);
885 i++;
886 }
887 return (ulcqi);
888
889 }
890
891
892 void
DoSetBandwidth(uint16_t ulBandwidth,uint16_t dlBandwidth)893 LteEnbPhy::DoSetBandwidth (uint16_t ulBandwidth, uint16_t dlBandwidth)
894 {
895 NS_LOG_FUNCTION (this << (uint32_t) ulBandwidth << (uint32_t) dlBandwidth);
896 m_ulBandwidth = ulBandwidth;
897 m_dlBandwidth = dlBandwidth;
898
899 static const int Type0AllocationRbg[4] = {
900 10, // RGB size 1
901 26, // RGB size 2
902 63, // RGB size 3
903 110 // RGB size 4
904 }; // see table 7.1.6.1-1 of 36.213
905 for (int i = 0; i < 4; i++)
906 {
907 if (dlBandwidth < Type0AllocationRbg[i])
908 {
909 m_rbgSize = i + 1;
910 break;
911 }
912 }
913 }
914
915 void
DoSetEarfcn(uint32_t ulEarfcn,uint32_t dlEarfcn)916 LteEnbPhy::DoSetEarfcn (uint32_t ulEarfcn, uint32_t dlEarfcn)
917 {
918 NS_LOG_FUNCTION (this << ulEarfcn << dlEarfcn);
919 m_ulEarfcn = ulEarfcn;
920 m_dlEarfcn = dlEarfcn;
921 }
922
923
924 void
DoAddUe(uint16_t rnti)925 LteEnbPhy::DoAddUe (uint16_t rnti)
926 {
927 NS_LOG_FUNCTION (this << rnti);
928
929 bool success = AddUePhy (rnti);
930 NS_ASSERT_MSG (success, "AddUePhy() failed");
931
932 // add default P_A value
933 DoSetPa (rnti, 0);
934 }
935
936 void
DoRemoveUe(uint16_t rnti)937 LteEnbPhy::DoRemoveUe (uint16_t rnti)
938 {
939 NS_LOG_FUNCTION (this << rnti);
940
941 bool success = DeleteUePhy (rnti);
942 NS_ASSERT_MSG (success, "DeleteUePhy() failed");
943
944 // remove also P_A value
945 std::map<uint16_t, double>::iterator it = m_paMap.find (rnti);
946 if (it != m_paMap.end ())
947 {
948 m_paMap.erase (it);
949 }
950
951 //additional data to be removed
952 m_uplinkSpectrumPhy->RemoveExpectedTb (rnti);
953 //remove srs info to avoid trace errors
954 std::map<uint16_t, uint16_t>::iterator sit = m_srsSampleCounterMap.find (rnti);
955 if (sit != m_srsSampleCounterMap.end ())
956 {
957 m_srsSampleCounterMap.erase (rnti);
958 }
959 //remove DL_DCI message otherwise errors occur for m_dlPhyTransmission trace
960 //remove also any UL_DCI message for the UE to be removed
961
962 for (auto & ctrlMessageList : m_controlMessagesQueue)
963 {
964 std::list<Ptr<LteControlMessage> >::iterator ctrlMsgListIt = ctrlMessageList.begin ();
965 while (ctrlMsgListIt != ctrlMessageList.end ())
966 {
967 Ptr<LteControlMessage> msg = (*ctrlMsgListIt);
968 if (msg->GetMessageType () == LteControlMessage::DL_DCI)
969 {
970 auto dci = DynamicCast<DlDciLteControlMessage> (msg);
971 if (dci->GetDci ().m_rnti == rnti)
972 {
973 NS_LOG_INFO ("DL_DCI to be sent from cell id : "
974 << m_cellId << " to RNTI : " << rnti << " is deleted");
975 ctrlMsgListIt = ctrlMessageList.erase (ctrlMsgListIt);
976 }
977 else
978 {
979 ++ctrlMsgListIt;
980 }
981 }
982 else if (msg->GetMessageType () == LteControlMessage::UL_DCI)
983 {
984 auto dci = DynamicCast<UlDciLteControlMessage> (msg);
985 if (dci->GetDci ().m_rnti == rnti)
986 {
987 NS_LOG_INFO ("UL_DCI to be sent from cell id : "
988 << m_cellId << " to RNTI : " << rnti << " is deleted");
989 ctrlMsgListIt = ctrlMessageList.erase (ctrlMsgListIt);
990 }
991 else
992 {
993 ++ctrlMsgListIt;
994 }
995 }
996 else
997 {
998 ++ctrlMsgListIt;
999 }
1000 }
1001 }
1002
1003 }
1004
1005 void
DoSetPa(uint16_t rnti,double pa)1006 LteEnbPhy::DoSetPa (uint16_t rnti, double pa)
1007 {
1008 NS_LOG_FUNCTION (this << rnti);
1009
1010 std::map<uint16_t, double>::iterator it = m_paMap.find (rnti);
1011
1012 if (it == m_paMap.end ())
1013 {
1014 m_paMap.insert (std::pair<uint16_t, double> (rnti, pa));
1015 }
1016 else
1017 {
1018 it->second = pa;
1019 }
1020
1021 }
1022
1023 FfMacSchedSapProvider::SchedUlCqiInfoReqParameters
CreateSrsCqiReport(const SpectrumValue & sinr)1024 LteEnbPhy::CreateSrsCqiReport (const SpectrumValue& sinr)
1025 {
1026 NS_LOG_FUNCTION (this << sinr);
1027 Values::const_iterator it;
1028 FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi;
1029 ulcqi.m_ulCqi.m_type = UlCqi_s::SRS;
1030 int i = 0;
1031 double srsSum = 0.0;
1032 for (it = sinr.ConstValuesBegin (); it != sinr.ConstValuesEnd (); it++)
1033 {
1034 double sinrdb = 10 * log10 ((*it));
1035 // NS_LOG_DEBUG ("ULCQI RB " << i << " value " << sinrdb);
1036 // convert from double to fixed point notation Sxxxxxxxxxxx.xxx
1037 int16_t sinrFp = LteFfConverter::double2fpS11dot3 (sinrdb);
1038 srsSum += (*it);
1039 ulcqi.m_ulCqi.m_sinr.push_back (sinrFp);
1040 i++;
1041 }
1042 // Insert the user generated the srs as a vendor specific parameter
1043 NS_LOG_DEBUG (this << " ENB RX UL-CQI of " << m_srsUeOffset.at (m_currentSrsOffset));
1044 VendorSpecificListElement_s vsp;
1045 vsp.m_type = SRS_CQI_RNTI_VSP;
1046 vsp.m_length = sizeof(SrsCqiRntiVsp);
1047 Ptr<SrsCqiRntiVsp> rnti = Create <SrsCqiRntiVsp> (m_srsUeOffset.at (m_currentSrsOffset));
1048 vsp.m_value = rnti;
1049 ulcqi.m_vendorSpecificList.push_back (vsp);
1050 // call SRS tracing method
1051 CreateSrsReport (m_srsUeOffset.at (m_currentSrsOffset),
1052 (i > 0) ? (srsSum / i) : DBL_MAX);
1053 return (ulcqi);
1054
1055 }
1056
1057
1058 void
CreateSrsReport(uint16_t rnti,double srs)1059 LteEnbPhy::CreateSrsReport (uint16_t rnti, double srs)
1060 {
1061 NS_LOG_FUNCTION (this << rnti << srs);
1062 std::map <uint16_t,uint16_t>::iterator it = m_srsSampleCounterMap.find (rnti);
1063 if (it == m_srsSampleCounterMap.end ())
1064 {
1065 // create new entry
1066 m_srsSampleCounterMap.insert (std::pair <uint16_t,uint16_t> (rnti, 0));
1067 it = m_srsSampleCounterMap.find (rnti);
1068 }
1069 (*it).second++;
1070 if ((*it).second == m_srsSamplePeriod)
1071 {
1072 m_reportUeSinr (m_cellId, rnti, srs, (uint16_t) m_componentCarrierId);
1073 (*it).second = 0;
1074 }
1075 }
1076
1077 void
DoSetTransmissionMode(uint16_t rnti,uint8_t txMode)1078 LteEnbPhy::DoSetTransmissionMode (uint16_t rnti, uint8_t txMode)
1079 {
1080 NS_LOG_FUNCTION (this << rnti << (uint16_t)txMode);
1081 // UL supports only SISO MODE
1082 }
1083
1084 void
QueueUlDci(UlDciLteControlMessage m)1085 LteEnbPhy::QueueUlDci (UlDciLteControlMessage m)
1086 {
1087 NS_LOG_FUNCTION (this);
1088 m_ulDciQueue.at (UL_PUSCH_TTIS_DELAY - 1).push_back (m);
1089 }
1090
1091 std::list<UlDciLteControlMessage>
DequeueUlDci(void)1092 LteEnbPhy::DequeueUlDci (void)
1093 {
1094 NS_LOG_FUNCTION (this);
1095 if (m_ulDciQueue.at (0).size () > 0)
1096 {
1097 std::list<UlDciLteControlMessage> ret = m_ulDciQueue.at (0);
1098 m_ulDciQueue.erase (m_ulDciQueue.begin ());
1099 std::list<UlDciLteControlMessage> l;
1100 m_ulDciQueue.push_back (l);
1101 return (ret);
1102 }
1103 else
1104 {
1105 m_ulDciQueue.erase (m_ulDciQueue.begin ());
1106 std::list<UlDciLteControlMessage> l;
1107 m_ulDciQueue.push_back (l);
1108 std::list<UlDciLteControlMessage> emptylist;
1109 return (emptylist);
1110 }
1111 }
1112
1113 void
DoSetSrsConfigurationIndex(uint16_t rnti,uint16_t srcCi)1114 LteEnbPhy::DoSetSrsConfigurationIndex (uint16_t rnti, uint16_t srcCi)
1115 {
1116 NS_LOG_FUNCTION (this);
1117 uint16_t p = GetSrsPeriodicity (srcCi);
1118 if (p != m_srsPeriodicity)
1119 {
1120 // resize the array of offset -> re-initialize variables
1121 m_srsUeOffset.clear ();
1122 m_srsUeOffset.resize (p, 0);
1123 m_srsPeriodicity = p;
1124 // inhibit SRS until RRC Connection Reconfiguration propagates
1125 // to UEs, otherwise we might be wrong in determining the UE who
1126 // actually sent the SRS (if the UE was using a stale SRS config)
1127 // if we use a static SRS configuration index, we can have a 0ms guard time
1128 m_srsStartTime = Simulator::Now () + MilliSeconds (m_macChTtiDelay) + MilliSeconds (0);
1129 }
1130
1131 NS_LOG_DEBUG (this << " ENB SRS P " << m_srsPeriodicity << " RNTI " << rnti << " offset " << GetSrsSubframeOffset (srcCi) << " CI " << srcCi);
1132 std::map <uint16_t,uint16_t>::iterator it = m_srsCounter.find (rnti);
1133 if (it != m_srsCounter.end ())
1134 {
1135 (*it).second = GetSrsSubframeOffset (srcCi) + 1;
1136 }
1137 else
1138 {
1139 m_srsCounter.insert (std::pair<uint16_t, uint16_t> (rnti, GetSrsSubframeOffset (srcCi) + 1));
1140 }
1141 m_srsUeOffset.at (GetSrsSubframeOffset (srcCi)) = rnti;
1142
1143 }
1144
1145
1146 void
DoSetMasterInformationBlock(LteRrcSap::MasterInformationBlock mib)1147 LteEnbPhy::DoSetMasterInformationBlock (LteRrcSap::MasterInformationBlock mib)
1148 {
1149 NS_LOG_FUNCTION (this);
1150 m_mib = mib;
1151 }
1152
1153
1154 void
DoSetSystemInformationBlockType1(LteRrcSap::SystemInformationBlockType1 sib1)1155 LteEnbPhy::DoSetSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1)
1156 {
1157 NS_LOG_FUNCTION (this);
1158 m_sib1 = sib1;
1159 }
1160
1161
1162 void
SetHarqPhyModule(Ptr<LteHarqPhy> harq)1163 LteEnbPhy::SetHarqPhyModule (Ptr<LteHarqPhy> harq)
1164 {
1165 m_harqPhyModule = harq;
1166 }
1167
1168
1169 void
ReportUlHarqFeedback(UlInfoListElement_s mes)1170 LteEnbPhy::ReportUlHarqFeedback (UlInfoListElement_s mes)
1171 {
1172 NS_LOG_FUNCTION (this);
1173 // forward to scheduler
1174 m_enbPhySapUser->UlInfoListElementHarqFeeback (mes);
1175 }
1176
1177 }
1178