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