1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009, 2011 CTTC
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Nicola Baldo <nbaldo@cttc.es>
19  *         Giuseppe Piro  <g.piro@poliba.it>
20  *         Marco Miozzo <marco.miozzo@cttc.es> (add physical error model)
21  */
22 
23 
24 #include <ns3/object-factory.h>
25 #include <ns3/log.h>
26 #include <cmath>
27 #include <ns3/simulator.h>
28 #include <ns3/trace-source-accessor.h>
29 #include <ns3/antenna-model.h>
30 #include "lte-spectrum-phy.h"
31 #include "lte-spectrum-signal-parameters.h"
32 #include "lte-net-device.h"
33 #include "lte-radio-bearer-tag.h"
34 #include "lte-chunk-processor.h"
35 #include "lte-phy-tag.h"
36 #include <ns3/lte-mi-error-model.h>
37 #include <ns3/lte-radio-bearer-tag.h>
38 #include <ns3/boolean.h>
39 #include <ns3/double.h>
40 #include <ns3/config.h>
41 
42 namespace ns3 {
43 
44 NS_LOG_COMPONENT_DEFINE ("LteSpectrumPhy");
45 
46 
47 /// duration of SRS portion of UL subframe
48 /// = 1 symbol for SRS -1ns as margin to avoid overlapping simulator events
49 static const Time UL_SRS_DURATION = NanoSeconds (71429 - 1);
50 
51 /// duration of the control portion of a subframe
52 /// = 0.001 / 14 * 3 (ctrl fixed to 3 symbols) -1ns as margin to avoid overlapping simulator events
53 static const Time DL_CTRL_DURATION = NanoSeconds (214286 - 1);
54 
55 /// Effective coding rate
56 static const double EffectiveCodingRate[29] = {
57   0.08,
58   0.1,
59   0.11,
60   0.15,
61   0.19,
62   0.24,
63   0.3,
64   0.37,
65   0.44,
66   0.51,
67   0.3,
68   0.33,
69   0.37,
70   0.42,
71   0.48,
72   0.54,
73   0.6,
74   0.43,
75   0.45,
76   0.5,
77   0.55,
78   0.6,
79   0.65,
80   0.7,
81   0.75,
82   0.8,
83   0.85,
84   0.89,
85   0.92
86 };
87 
88 
89 
90 
TbId_t()91 TbId_t::TbId_t ()
92 {}
93 
TbId_t(const uint16_t a,const uint8_t b)94 TbId_t::TbId_t (const uint16_t a, const uint8_t b)
95   : m_rnti (a),
96     m_layer (b)
97 {}
98 
99 /**
100  * Equality operator
101  *
102  * \param a lhs
103  * \param b rhs
104  * \returns true if rnti and layer are equal
105  */
106 bool
operator ==(const TbId_t & a,const TbId_t & b)107 operator == (const TbId_t &a, const TbId_t &b)
108 {
109   return ( (a.m_rnti == b.m_rnti) && (a.m_layer == b.m_layer) );
110 }
111 
112 /**
113  * Less than operator
114  *
115  * \param a lhs
116  * \param b rhs
117  * \returns true if rnti less than ro rnti equal and layer less than
118  */
119 bool
operator <(const TbId_t & a,const TbId_t & b)120 operator < (const TbId_t& a, const TbId_t& b)
121 {
122   return ( (a.m_rnti < b.m_rnti) || ( (a.m_rnti == b.m_rnti) && (a.m_layer < b.m_layer) ) );
123 }
124 
125 NS_OBJECT_ENSURE_REGISTERED (LteSpectrumPhy);
126 
LteSpectrumPhy()127 LteSpectrumPhy::LteSpectrumPhy ()
128   : m_state (IDLE),
129     m_cellId (0),
130     m_componentCarrierId (0),
131     m_transmissionMode (0),
132     m_layersNum (1)
133 {
134   NS_LOG_FUNCTION (this);
135   m_random = CreateObject<UniformRandomVariable> ();
136   m_random->SetAttribute ("Min", DoubleValue (0.0));
137   m_random->SetAttribute ("Max", DoubleValue (1.0));
138   m_interferenceData = CreateObject<LteInterference> ();
139   m_interferenceCtrl = CreateObject<LteInterference> ();
140 
141   for (uint8_t i = 0; i < 7; i++)
142     {
143       m_txModeGain.push_back (1.0);
144     }
145 }
146 
147 
~LteSpectrumPhy()148 LteSpectrumPhy::~LteSpectrumPhy ()
149 {
150   NS_LOG_FUNCTION (this);
151   m_expectedTbs.clear ();
152   m_txModeGain.clear ();
153 }
154 
DoDispose()155 void LteSpectrumPhy::DoDispose ()
156 {
157   NS_LOG_FUNCTION (this);
158   m_channel = 0;
159   m_mobility = 0;
160   m_device = 0;
161   m_interferenceData->Dispose ();
162   m_interferenceData = 0;
163   m_interferenceCtrl->Dispose ();
164   m_interferenceCtrl = 0;
165   m_ltePhyRxDataEndErrorCallback = MakeNullCallback< void > ();
166   m_ltePhyRxDataEndOkCallback    = MakeNullCallback< void, Ptr<Packet> >  ();
167   m_ltePhyRxCtrlEndOkCallback = MakeNullCallback< void, std::list<Ptr<LteControlMessage> > > ();
168   m_ltePhyRxCtrlEndErrorCallback = MakeNullCallback< void > ();
169   m_ltePhyDlHarqFeedbackCallback = MakeNullCallback< void, DlInfoListElement_s > ();
170   m_ltePhyUlHarqFeedbackCallback = MakeNullCallback< void, UlInfoListElement_s > ();
171   m_ltePhyRxPssCallback = MakeNullCallback< void, uint16_t, Ptr<SpectrumValue> > ();
172   SpectrumPhy::DoDispose ();
173 }
174 
175 /**
176  * Output stream output operator
177  *
178  * \param os output stream
179  * \param s state
180  * \returns output stream
181  */
operator <<(std::ostream & os,LteSpectrumPhy::State s)182 std::ostream& operator<< (std::ostream& os, LteSpectrumPhy::State s)
183 {
184   switch (s)
185     {
186       case LteSpectrumPhy::IDLE:
187         os << "IDLE";
188         break;
189       case LteSpectrumPhy::RX_DATA:
190         os << "RX_DATA";
191         break;
192       case LteSpectrumPhy::RX_DL_CTRL:
193         os << "RX_DL_CTRL";
194         break;
195       case LteSpectrumPhy::TX_DATA:
196         os << "TX_DATA";
197         break;
198       case LteSpectrumPhy::TX_DL_CTRL:
199         os << "TX_DL_CTRL";
200         break;
201       case LteSpectrumPhy::TX_UL_SRS:
202         os << "TX_UL_SRS";
203         break;
204       default:
205         os << "UNKNOWN";
206         break;
207     }
208   return os;
209 }
210 
211 TypeId
GetTypeId(void)212 LteSpectrumPhy::GetTypeId (void)
213 {
214   static TypeId tid = TypeId ("ns3::LteSpectrumPhy")
215     .SetParent<SpectrumPhy> ()
216     .SetGroupName ("Lte")
217     .AddTraceSource ("TxStart",
218                      "Trace fired when a new transmission is started",
219                      MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyTxStartTrace),
220                      "ns3::PacketBurst::TracedCallback")
221     .AddTraceSource ("TxEnd",
222                      "Trace fired when a previously started transmission is finished",
223                      MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyTxEndTrace),
224                      "ns3::PacketBurst::TracedCallback")
225     .AddTraceSource ("RxStart",
226                      "Trace fired when the start of a signal is detected",
227                      MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyRxStartTrace),
228                      "ns3::PacketBurst::TracedCallback")
229     .AddTraceSource ("RxEndOk",
230                      "Trace fired when a previously started RX terminates successfully",
231                      MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyRxEndOkTrace),
232                      "ns3::Packet::TracedCallback")
233     .AddTraceSource ("RxEndError",
234                      "Trace fired when a previously started RX terminates with an error",
235                      MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyRxEndErrorTrace),
236                      "ns3::Packet::TracedCallback")
237     .AddAttribute ("DataErrorModelEnabled",
238                    "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) [by default is active].",
239                    BooleanValue (true),
240                    MakeBooleanAccessor (&LteSpectrumPhy::m_dataErrorModelEnabled),
241                    MakeBooleanChecker ())
242     .AddAttribute ("CtrlErrorModelEnabled",
243                    "Activate/Deactivate the error model of control (PCFICH-PDCCH decodification) [by default is active].",
244                    BooleanValue (true),
245                    MakeBooleanAccessor (&LteSpectrumPhy::m_ctrlErrorModelEnabled),
246                    MakeBooleanChecker ())
247     .AddTraceSource ("DlPhyReception",
248                      "DL reception PHY layer statistics.",
249                      MakeTraceSourceAccessor (&LteSpectrumPhy::m_dlPhyReception),
250                      "ns3::PhyReceptionStatParameters::TracedCallback")
251     .AddTraceSource ("UlPhyReception",
252                      "DL reception PHY layer statistics.",
253                      MakeTraceSourceAccessor (&LteSpectrumPhy::m_ulPhyReception),
254                      "ns3::PhyReceptionStatParameters::TracedCallback")
255   ;
256   return tid;
257 }
258 
259 
260 
261 Ptr<NetDevice>
GetDevice() const262 LteSpectrumPhy::GetDevice () const
263 {
264   NS_LOG_FUNCTION (this);
265   return m_device;
266 }
267 
268 
269 Ptr<MobilityModel>
GetMobility() const270 LteSpectrumPhy::GetMobility () const
271 {
272   NS_LOG_FUNCTION (this);
273   return m_mobility;
274 }
275 
276 
277 void
SetDevice(Ptr<NetDevice> d)278 LteSpectrumPhy::SetDevice (Ptr<NetDevice> d)
279 {
280   NS_LOG_FUNCTION (this << d);
281   m_device = d;
282 }
283 
284 
285 void
SetMobility(Ptr<MobilityModel> m)286 LteSpectrumPhy::SetMobility (Ptr<MobilityModel> m)
287 {
288   NS_LOG_FUNCTION (this << m);
289   m_mobility = m;
290 }
291 
292 
293 void
SetChannel(Ptr<SpectrumChannel> c)294 LteSpectrumPhy::SetChannel (Ptr<SpectrumChannel> c)
295 {
296   NS_LOG_FUNCTION (this << c);
297   m_channel = c;
298 }
299 
300 Ptr<SpectrumChannel>
GetChannel()301 LteSpectrumPhy::GetChannel ()
302 {
303   return m_channel;
304 }
305 
306 Ptr<const SpectrumModel>
GetRxSpectrumModel() const307 LteSpectrumPhy::GetRxSpectrumModel () const
308 {
309   return m_rxSpectrumModel;
310 }
311 
312 
313 void
SetTxPowerSpectralDensity(Ptr<SpectrumValue> txPsd)314 LteSpectrumPhy::SetTxPowerSpectralDensity (Ptr<SpectrumValue> txPsd)
315 {
316   NS_LOG_FUNCTION (this << txPsd);
317   NS_ASSERT (txPsd);
318   m_txPsd = txPsd;
319 }
320 
321 
322 void
SetNoisePowerSpectralDensity(Ptr<const SpectrumValue> noisePsd)323 LteSpectrumPhy::SetNoisePowerSpectralDensity (Ptr<const SpectrumValue> noisePsd)
324 {
325   NS_LOG_FUNCTION (this << noisePsd);
326   NS_ASSERT (noisePsd);
327   m_rxSpectrumModel = noisePsd->GetSpectrumModel ();
328   m_interferenceData->SetNoisePowerSpectralDensity (noisePsd);
329   m_interferenceCtrl->SetNoisePowerSpectralDensity (noisePsd);
330 }
331 
332 
333 void
Reset()334 LteSpectrumPhy::Reset ()
335 {
336   NS_LOG_FUNCTION (this);
337   m_cellId = 0;
338   m_state = IDLE;
339   m_transmissionMode = 0;
340   m_layersNum = 1;
341   m_endTxEvent.Cancel ();
342   m_endRxDataEvent.Cancel ();
343   m_endRxDlCtrlEvent.Cancel ();
344   m_endRxUlSrsEvent.Cancel ();
345   m_rxControlMessageList.clear ();
346   m_expectedTbs.clear ();
347   m_txControlMessageList.clear ();
348   m_rxPacketBurstList.clear ();
349   m_txPacketBurst = 0;
350   m_rxSpectrumModel = 0;
351 }
352 
353 
354 void
SetLtePhyRxDataEndErrorCallback(LtePhyRxDataEndErrorCallback c)355 LteSpectrumPhy::SetLtePhyRxDataEndErrorCallback (LtePhyRxDataEndErrorCallback c)
356 {
357   NS_LOG_FUNCTION (this);
358   m_ltePhyRxDataEndErrorCallback = c;
359 }
360 
361 
362 void
SetLtePhyRxDataEndOkCallback(LtePhyRxDataEndOkCallback c)363 LteSpectrumPhy::SetLtePhyRxDataEndOkCallback (LtePhyRxDataEndOkCallback c)
364 {
365   NS_LOG_FUNCTION (this);
366   m_ltePhyRxDataEndOkCallback = c;
367 }
368 
369 void
SetLtePhyRxCtrlEndOkCallback(LtePhyRxCtrlEndOkCallback c)370 LteSpectrumPhy::SetLtePhyRxCtrlEndOkCallback (LtePhyRxCtrlEndOkCallback c)
371 {
372   NS_LOG_FUNCTION (this);
373   m_ltePhyRxCtrlEndOkCallback = c;
374 }
375 
376 void
SetLtePhyRxCtrlEndErrorCallback(LtePhyRxCtrlEndErrorCallback c)377 LteSpectrumPhy::SetLtePhyRxCtrlEndErrorCallback (LtePhyRxCtrlEndErrorCallback c)
378 {
379   NS_LOG_FUNCTION (this);
380   m_ltePhyRxCtrlEndErrorCallback = c;
381 }
382 
383 
384 void
SetLtePhyRxPssCallback(LtePhyRxPssCallback c)385 LteSpectrumPhy::SetLtePhyRxPssCallback (LtePhyRxPssCallback c)
386 {
387   NS_LOG_FUNCTION (this);
388   m_ltePhyRxPssCallback = c;
389 }
390 
391 void
SetLtePhyDlHarqFeedbackCallback(LtePhyDlHarqFeedbackCallback c)392 LteSpectrumPhy::SetLtePhyDlHarqFeedbackCallback (LtePhyDlHarqFeedbackCallback c)
393 {
394   NS_LOG_FUNCTION (this);
395   m_ltePhyDlHarqFeedbackCallback = c;
396 }
397 
398 void
SetLtePhyUlHarqFeedbackCallback(LtePhyUlHarqFeedbackCallback c)399 LteSpectrumPhy::SetLtePhyUlHarqFeedbackCallback (LtePhyUlHarqFeedbackCallback c)
400 {
401   NS_LOG_FUNCTION (this);
402   m_ltePhyUlHarqFeedbackCallback = c;
403 }
404 
405 
406 Ptr<AntennaModel>
GetRxAntenna() const407 LteSpectrumPhy::GetRxAntenna () const
408 {
409   return m_antenna;
410 }
411 
412 void
SetAntenna(Ptr<AntennaModel> a)413 LteSpectrumPhy::SetAntenna (Ptr<AntennaModel> a)
414 {
415   NS_LOG_FUNCTION (this << a);
416   m_antenna = a;
417 }
418 
419 void
SetState(State newState)420 LteSpectrumPhy::SetState (State newState)
421 {
422   ChangeState (newState);
423 }
424 
425 
426 void
ChangeState(State newState)427 LteSpectrumPhy::ChangeState (State newState)
428 {
429   NS_LOG_LOGIC (this << " state: " << m_state << " -> " << newState);
430   m_state = newState;
431 }
432 
433 
434 void
SetHarqPhyModule(Ptr<LteHarqPhy> harq)435 LteSpectrumPhy::SetHarqPhyModule (Ptr<LteHarqPhy> harq)
436 {
437   m_harqPhyModule = harq;
438 }
439 
440 
441 
442 
443 bool
StartTxDataFrame(Ptr<PacketBurst> pb,std::list<Ptr<LteControlMessage>> ctrlMsgList,Time duration)444 LteSpectrumPhy::StartTxDataFrame (Ptr<PacketBurst> pb, std::list<Ptr<LteControlMessage> > ctrlMsgList, Time duration)
445 {
446   NS_LOG_FUNCTION (this << pb);
447   NS_LOG_LOGIC (this << " state: " << m_state);
448 
449   m_phyTxStartTrace (pb);
450 
451   switch (m_state)
452     {
453       case RX_DATA:
454       case RX_DL_CTRL:
455       case RX_UL_SRS:
456         NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
457         break;
458 
459       case TX_DATA:
460       case TX_DL_CTRL:
461       case TX_UL_SRS:
462         NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
463         break;
464 
465       case IDLE:
466         {
467           /*
468           m_txPsd must be set by the device, according to
469           (i) the available subchannel for transmission
470           (ii) the power transmission
471           */
472           NS_ASSERT (m_txPsd);
473           m_txPacketBurst = pb;
474 
475           // we need to convey some PHY meta information to the receiver
476           // to be used for simulation purposes (e.g., the CellId). This
477           // is done by setting the ctrlMsgList parameter of
478           // LteSpectrumSignalParametersDataFrame
479           ChangeState (TX_DATA);
480           NS_ASSERT (m_channel);
481           Ptr<LteSpectrumSignalParametersDataFrame> txParams = Create<LteSpectrumSignalParametersDataFrame> ();
482           txParams->duration = duration;
483           txParams->txPhy = GetObject<SpectrumPhy> ();
484           txParams->txAntenna = m_antenna;
485           txParams->psd = m_txPsd;
486           txParams->packetBurst = pb;
487           txParams->ctrlMsgList = ctrlMsgList;
488           txParams->cellId = m_cellId;
489           m_channel->StartTx (txParams);
490           m_endTxEvent = Simulator::Schedule (duration, &LteSpectrumPhy::EndTxData, this);
491         }
492         return false;
493         break;
494 
495       default:
496         NS_FATAL_ERROR ("unknown state");
497         return true;
498         break;
499     }
500 }
501 
502 bool
StartTxDlCtrlFrame(std::list<Ptr<LteControlMessage>> ctrlMsgList,bool pss)503 LteSpectrumPhy::StartTxDlCtrlFrame (std::list<Ptr<LteControlMessage> > ctrlMsgList, bool pss)
504 {
505   NS_LOG_FUNCTION (this << " PSS " << (uint16_t)pss);
506   NS_LOG_LOGIC (this << " state: " << m_state);
507 
508   switch (m_state)
509     {
510       case RX_DATA:
511       case RX_DL_CTRL:
512       case RX_UL_SRS:
513         NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
514         break;
515 
516       case TX_DATA:
517       case TX_DL_CTRL:
518       case TX_UL_SRS:
519         NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
520         break;
521 
522       case IDLE:
523         {
524           /*
525           m_txPsd must be set by the device, according to
526           (i) the available subchannel for transmission
527           (ii) the power transmission
528           */
529           NS_ASSERT (m_txPsd);
530 
531           // we need to convey some PHY meta information to the receiver
532           // to be used for simulation purposes (e.g., the CellId). This
533           // is done by setting the cellId parameter of
534           // LteSpectrumSignalParametersDlCtrlFrame
535           ChangeState (TX_DL_CTRL);
536           NS_ASSERT (m_channel);
537 
538           Ptr<LteSpectrumSignalParametersDlCtrlFrame> txParams = Create<LteSpectrumSignalParametersDlCtrlFrame> ();
539           txParams->duration = DL_CTRL_DURATION;
540           txParams->txPhy = GetObject<SpectrumPhy> ();
541           txParams->txAntenna = m_antenna;
542           txParams->psd = m_txPsd;
543           txParams->cellId = m_cellId;
544           txParams->pss = pss;
545           txParams->ctrlMsgList = ctrlMsgList;
546           m_channel->StartTx (txParams);
547           m_endTxEvent = Simulator::Schedule (DL_CTRL_DURATION, &LteSpectrumPhy::EndTxDlCtrl, this);
548         }
549         return false;
550         break;
551 
552       default:
553         NS_FATAL_ERROR ("unknown state");
554         return true;
555         break;
556     }
557 }
558 
559 
560 bool
StartTxUlSrsFrame()561 LteSpectrumPhy::StartTxUlSrsFrame ()
562 {
563   NS_LOG_FUNCTION (this);
564   NS_LOG_LOGIC (this << " state: " << m_state);
565 
566   switch (m_state)
567     {
568       case RX_DATA:
569       case RX_DL_CTRL:
570       case RX_UL_SRS:
571         NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
572         break;
573 
574       case TX_DL_CTRL:
575       case TX_DATA:
576       case TX_UL_SRS:
577         NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
578         break;
579 
580       case IDLE:
581         {
582           /*
583           m_txPsd must be set by the device, according to
584           (i) the available subchannel for transmission
585           (ii) the power transmission
586           */
587           NS_ASSERT (m_txPsd);
588           NS_LOG_LOGIC (this << " m_txPsd: " << *m_txPsd);
589 
590           // we need to convey some PHY meta information to the receiver
591           // to be used for simulation purposes (e.g., the CellId). This
592           // is done by setting the cellId parameter of
593           // LteSpectrumSignalParametersDlCtrlFrame
594           ChangeState (TX_UL_SRS);
595           NS_ASSERT (m_channel);
596           Ptr<LteSpectrumSignalParametersUlSrsFrame> txParams = Create<LteSpectrumSignalParametersUlSrsFrame> ();
597           txParams->duration = UL_SRS_DURATION;
598           txParams->txPhy = GetObject<SpectrumPhy> ();
599           txParams->txAntenna = m_antenna;
600           txParams->psd = m_txPsd;
601           txParams->cellId = m_cellId;
602           m_channel->StartTx (txParams);
603           m_endTxEvent = Simulator::Schedule (UL_SRS_DURATION, &LteSpectrumPhy::EndTxUlSrs, this);
604         }
605         return false;
606         break;
607 
608       default:
609         NS_FATAL_ERROR ("unknown state");
610         return true;
611         break;
612     }
613 }
614 
615 
616 
617 void
EndTxData()618 LteSpectrumPhy::EndTxData ()
619 {
620   NS_LOG_FUNCTION (this);
621   NS_LOG_LOGIC (this << " state: " << m_state);
622 
623   NS_ASSERT (m_state == TX_DATA);
624   m_phyTxEndTrace (m_txPacketBurst);
625   m_txPacketBurst = 0;
626   ChangeState (IDLE);
627 }
628 
629 void
EndTxDlCtrl()630 LteSpectrumPhy::EndTxDlCtrl ()
631 {
632   NS_LOG_FUNCTION (this);
633   NS_LOG_LOGIC (this << " state: " << m_state);
634 
635   NS_ASSERT (m_state == TX_DL_CTRL);
636   NS_ASSERT (m_txPacketBurst == 0);
637   ChangeState (IDLE);
638 }
639 
640 void
EndTxUlSrs()641 LteSpectrumPhy::EndTxUlSrs ()
642 {
643   NS_LOG_FUNCTION (this);
644   NS_LOG_LOGIC (this << " state: " << m_state);
645 
646   NS_ASSERT (m_state == TX_UL_SRS);
647   NS_ASSERT (m_txPacketBurst == 0);
648   ChangeState (IDLE);
649 }
650 
651 
652 
653 
654 void
StartRx(Ptr<SpectrumSignalParameters> spectrumRxParams)655 LteSpectrumPhy::StartRx (Ptr<SpectrumSignalParameters> spectrumRxParams)
656 {
657   NS_LOG_FUNCTION (this << spectrumRxParams);
658   NS_LOG_LOGIC (this << " state: " << m_state);
659 
660   Ptr <const SpectrumValue> rxPsd = spectrumRxParams->psd;
661   Time duration = spectrumRxParams->duration;
662 
663   // the device might start RX only if the signal is of a type
664   // understood by this device - in this case, an LTE signal.
665   Ptr<LteSpectrumSignalParametersDataFrame> lteDataRxParams = DynamicCast<LteSpectrumSignalParametersDataFrame> (spectrumRxParams);
666   Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams = DynamicCast<LteSpectrumSignalParametersDlCtrlFrame> (spectrumRxParams);
667   Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams = DynamicCast<LteSpectrumSignalParametersUlSrsFrame> (spectrumRxParams);
668   if (lteDataRxParams != 0)
669     {
670       m_interferenceData->AddSignal (rxPsd, duration);
671       StartRxData (lteDataRxParams);
672     }
673   else if (lteDlCtrlRxParams != 0)
674     {
675       m_interferenceCtrl->AddSignal (rxPsd, duration);
676       StartRxDlCtrl (lteDlCtrlRxParams);
677     }
678   else if (lteUlSrsRxParams != 0)
679     {
680       m_interferenceCtrl->AddSignal (rxPsd, duration);
681       StartRxUlSrs (lteUlSrsRxParams);
682     }
683   else
684     {
685       // other type of signal (could be 3G, GSM, whatever) -> interference
686       m_interferenceData->AddSignal (rxPsd, duration);
687       m_interferenceCtrl->AddSignal (rxPsd, duration);
688     }
689 }
690 
691 void
StartRxData(Ptr<LteSpectrumSignalParametersDataFrame> params)692 LteSpectrumPhy::StartRxData (Ptr<LteSpectrumSignalParametersDataFrame> params)
693 {
694   NS_LOG_FUNCTION (this);
695   switch (m_state)
696     {
697       case TX_DATA:
698       case TX_DL_CTRL:
699       case TX_UL_SRS:
700         NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
701         break;
702       case RX_DL_CTRL:
703         NS_FATAL_ERROR ("cannot RX Data while receiving control");
704         break;
705       case IDLE:
706       case RX_DATA:
707         // the behavior is similar when
708         // we're IDLE or RX because we can receive more signals
709         // simultaneously (e.g., at the eNB).
710         {
711           // To check if we're synchronized to this signal, we check
712           // for the CellId which is reported in the
713           //  LteSpectrumSignalParametersDataFrame
714           if (params->cellId  == m_cellId)
715             {
716               NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << params->cellId << ")");
717               if ((m_rxPacketBurstList.empty ())&&(m_rxControlMessageList.empty ()))
718                 {
719                   NS_ASSERT (m_state == IDLE);
720                   // first transmission, i.e., we're IDLE and we
721                   // start RX
722                   m_firstRxStart = Simulator::Now ();
723                   m_firstRxDuration = params->duration;
724                   NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration.As (Time::S));
725                   m_endRxDataEvent = Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxData, this);
726                 }
727               else
728                 {
729                   NS_ASSERT (m_state == RX_DATA);
730                   // sanity check: if there are multiple RX events, they
731                   // should occur at the same time and have the same
732                   // duration, otherwise the interference calculation
733                   // won't be correct
734                   NS_ASSERT ((m_firstRxStart == Simulator::Now ())
735                              && (m_firstRxDuration == params->duration));
736                 }
737 
738               ChangeState (RX_DATA);
739               if (params->packetBurst)
740                 {
741                   m_rxPacketBurstList.push_back (params->packetBurst);
742                   m_interferenceData->StartRx (params->psd);
743 
744                   m_phyRxStartTrace (params->packetBurst);
745                 }
746               NS_LOG_DEBUG (this << " insert msgs " << params->ctrlMsgList.size ());
747               m_rxControlMessageList.insert (m_rxControlMessageList.end (), params->ctrlMsgList.begin (), params->ctrlMsgList.end ());
748 
749               NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
750             }
751           else
752             {
753               NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
754                                  << params->cellId  << ", m_cellId=" << m_cellId << ")");
755             }
756         }
757         break;
758 
759       default:
760         NS_FATAL_ERROR ("unknown state");
761         break;
762     }
763 
764   NS_LOG_LOGIC (this << " state: " << m_state);
765 }
766 
767 
768 
769 void
StartRxDlCtrl(Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams)770 LteSpectrumPhy::StartRxDlCtrl (Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams)
771 {
772   NS_LOG_FUNCTION (this);
773 
774   // To check if we're synchronized to this signal, we check
775   // for the CellId which is reported in the
776   // LteSpectrumSignalParametersDlCtrlFrame
777   uint16_t cellId;
778   NS_ASSERT (lteDlCtrlRxParams != 0);
779   cellId = lteDlCtrlRxParams->cellId;
780 
781   switch (m_state)
782     {
783       case TX_DATA:
784       case TX_DL_CTRL:
785       case TX_UL_SRS:
786       case RX_DATA:
787       case RX_UL_SRS:
788         NS_FATAL_ERROR ("unexpected event in state " << m_state);
789         break;
790 
791       case RX_DL_CTRL:
792       case IDLE:
793 
794         // common code for the two states
795         // check presence of PSS for UE measuerements
796         if (lteDlCtrlRxParams->pss == true)
797           {
798             if (!m_ltePhyRxPssCallback.IsNull ())
799               {
800                 m_ltePhyRxPssCallback (cellId, lteDlCtrlRxParams->psd);
801               }
802           }
803 
804         // differentiated code for the two states
805         switch (m_state)
806           {
807             case RX_DL_CTRL:
808               NS_ASSERT_MSG (m_cellId != cellId, "any other DlCtrl should be from a different cell");
809               NS_LOG_LOGIC (this << " ignoring other DlCtrl (cellId="
810                                  << cellId  << ", m_cellId=" << m_cellId << ")");
811               break;
812 
813             case IDLE:
814               if (cellId  == m_cellId)
815                 {
816                   NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << cellId << ")");
817 
818                   NS_ASSERT (m_rxControlMessageList.empty ());
819                   m_firstRxStart = Simulator::Now ();
820                   m_firstRxDuration = lteDlCtrlRxParams->duration;
821                   NS_LOG_LOGIC (this << " scheduling EndRx with delay " << lteDlCtrlRxParams->duration);
822 
823                   // store the DCIs
824                   m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
825                   m_endRxDlCtrlEvent = Simulator::Schedule (lteDlCtrlRxParams->duration, &LteSpectrumPhy::EndRxDlCtrl, this);
826                   ChangeState (RX_DL_CTRL);
827                   m_interferenceCtrl->StartRx (lteDlCtrlRxParams->psd);
828                 }
829               else
830                 {
831                   NS_LOG_LOGIC (this << " not synchronizing with this signal (cellId="
832                                      << cellId  << ", m_cellId=" << m_cellId << ")");
833                 }
834               break;
835 
836             default:
837               NS_FATAL_ERROR ("unexpected event in state " << m_state);
838               break;
839           }
840         break; // case RX_DL_CTRL or IDLE
841 
842       default:
843         NS_FATAL_ERROR ("unknown state");
844         break;
845     }
846 
847   NS_LOG_LOGIC (this << " state: " << m_state);
848 }
849 
850 
851 
852 
853 void
StartRxUlSrs(Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams)854 LteSpectrumPhy::StartRxUlSrs (Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams)
855 {
856   NS_LOG_FUNCTION (this);
857   switch (m_state)
858     {
859       case TX_DATA:
860       case TX_DL_CTRL:
861       case TX_UL_SRS:
862         NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
863         break;
864 
865       case RX_DATA:
866       case RX_DL_CTRL:
867         NS_FATAL_ERROR ("cannot RX SRS while receiving something else");
868         break;
869 
870       case IDLE:
871       case RX_UL_SRS:
872         // the behavior is similar when
873         // we're IDLE or RX_UL_SRS because we can receive more signals
874         // simultaneously at the eNB
875         {
876           // To check if we're synchronized to this signal, we check
877           // for the CellId which is reported in the
878           // LteSpectrumSignalParametersDlCtrlFrame
879           uint16_t cellId;
880           cellId = lteUlSrsRxParams->cellId;
881           if (cellId  == m_cellId)
882             {
883               NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << cellId << ")");
884               if (m_state == IDLE)
885                 {
886                   // first transmission, i.e., we're IDLE and we
887                   // start RX
888                   NS_ASSERT (m_rxControlMessageList.empty ());
889                   m_firstRxStart = Simulator::Now ();
890                   m_firstRxDuration = lteUlSrsRxParams->duration;
891                   NS_LOG_LOGIC (this << " scheduling EndRx with delay " << lteUlSrsRxParams->duration);
892 
893                   m_endRxUlSrsEvent = Simulator::Schedule (lteUlSrsRxParams->duration, &LteSpectrumPhy::EndRxUlSrs, this);
894                 }
895               else if (m_state == RX_UL_SRS)
896                 {
897                   // sanity check: if there are multiple RX events, they
898                   // should occur at the same time and have the same
899                   // duration, otherwise the interference calculation
900                   // won't be correct
901                   NS_ASSERT ((m_firstRxStart == Simulator::Now ())
902                              && (m_firstRxDuration == lteUlSrsRxParams->duration));
903                 }
904               ChangeState (RX_UL_SRS);
905               m_interferenceCtrl->StartRx (lteUlSrsRxParams->psd);
906             }
907           else
908             {
909               NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
910                                  << cellId  << ", m_cellId=" << m_cellId << ")");
911             }
912         }
913         break;
914 
915       default:
916         NS_FATAL_ERROR ("unknown state");
917         break;
918     }
919 
920   NS_LOG_LOGIC (this << " state: " << m_state);
921 }
922 
923 
924 void
UpdateSinrPerceived(const SpectrumValue & sinr)925 LteSpectrumPhy::UpdateSinrPerceived (const SpectrumValue& sinr)
926 {
927   NS_LOG_FUNCTION (this << sinr);
928   m_sinrPerceived = sinr;
929 }
930 
931 
932 void
AddExpectedTb(uint16_t rnti,uint8_t ndi,uint16_t size,uint8_t mcs,std::vector<int> map,uint8_t layer,uint8_t harqId,uint8_t rv,bool downlink)933 LteSpectrumPhy::AddExpectedTb (uint16_t  rnti, uint8_t ndi, uint16_t size, uint8_t mcs, std::vector<int> map, uint8_t layer, uint8_t harqId,uint8_t rv,  bool downlink)
934 {
935   NS_LOG_FUNCTION (this << " rnti: " << rnti << " NDI " << (uint16_t)ndi << " size " << size << " mcs " << (uint16_t)mcs << " layer " << (uint16_t)layer << " rv " << (uint16_t)rv);
936   TbId_t tbId;
937   tbId.m_rnti = rnti;
938   tbId.m_layer = layer;
939   expectedTbs_t::iterator it;
940   it = m_expectedTbs.find (tbId);
941   if (it != m_expectedTbs.end ())
942     {
943       // migth be a TB of an unreceived packet (due to high progpalosses)
944       m_expectedTbs.erase (it);
945     }
946   // insert new entry
947   tbInfo_t tbInfo = {ndi, size, mcs, map, harqId, rv, 0.0, downlink, false, false};
948   m_expectedTbs.insert (std::pair<TbId_t, tbInfo_t> (tbId,tbInfo));
949 }
950 
951 void
RemoveExpectedTb(uint16_t rnti)952 LteSpectrumPhy::RemoveExpectedTb (uint16_t  rnti)
953 {
954   NS_LOG_FUNCTION (this << rnti);
955   TbId_t tbId;
956   tbId.m_rnti = rnti;
957   //Remove TB of both the layers
958   for (uint8_t i = 0; i < 2; i++)
959     {
960       tbId.m_layer = i;
961       expectedTbs_t::iterator it;
962       it = m_expectedTbs.find (tbId);
963       if (it != m_expectedTbs.end ())
964         {
965           m_expectedTbs.erase (it);
966         }
967     }
968 }
969 
970 
971 
972 
973 void
EndRxData()974 LteSpectrumPhy::EndRxData ()
975 {
976   NS_LOG_FUNCTION (this);
977   NS_LOG_LOGIC (this << " state: " << m_state);
978 
979   NS_ASSERT (m_state == RX_DATA);
980 
981   // this will trigger CQI calculation and Error Model evaluation
982   // as a side effect, the error model should update the error status of all TBs
983   m_interferenceData->EndRx ();
984   NS_LOG_DEBUG (this << " No. of burts " << m_rxPacketBurstList.size ());
985   NS_LOG_DEBUG (this << " Expected TBs " << m_expectedTbs.size ());
986   expectedTbs_t::iterator itTb = m_expectedTbs.begin ();
987 
988   // apply transmission mode gain
989   NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
990   NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
991   m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
992 
993   while (itTb != m_expectedTbs.end ())
994     {
995       if ((m_dataErrorModelEnabled)&&(m_rxPacketBurstList.size () > 0)) // avoid to check for errors when there is no actual data transmitted
996         {
997           // retrieve HARQ info
998           HarqProcessInfoList_t harqInfoList;
999           if ((*itTb).second.ndi == 0)
1000             {
1001               // TB retxed: retrieve HARQ history
1002               uint16_t ulHarqId = 0;
1003               if ((*itTb).second.downlink)
1004                 {
1005                   harqInfoList = m_harqPhyModule->GetHarqProcessInfoDl ((*itTb).second.harqProcessId, (*itTb).first.m_layer);
1006                 }
1007               else
1008                 {
1009                   harqInfoList = m_harqPhyModule->GetHarqProcessInfoUl ((*itTb).first.m_rnti, ulHarqId);
1010                 }
1011             }
1012           TbStats_t tbStats = LteMiErrorModel::GetTbDecodificationStats (m_sinrPerceived, (*itTb).second.rbBitmap, (*itTb).second.size, (*itTb).second.mcs, harqInfoList);
1013           (*itTb).second.mi = tbStats.mi;
1014           (*itTb).second.corrupt = m_random->GetValue () > tbStats.tbler ? false : true;
1015           NS_LOG_DEBUG (this << "RNTI " << (*itTb).first.m_rnti << " size " << (*itTb).second.size << " mcs " << (uint32_t)(*itTb).second.mcs << " bitmap " << (*itTb).second.rbBitmap.size () << " layer " << (uint16_t)(*itTb).first.m_layer << " TBLER " << tbStats.tbler << " corrupted " << (*itTb).second.corrupt);
1016           // fire traces on DL/UL reception PHY stats
1017           PhyReceptionStatParameters params;
1018           params.m_timestamp = Simulator::Now ().GetMilliSeconds ();
1019           params.m_cellId = m_cellId;
1020           params.m_imsi = 0; // it will be set by DlPhyTransmissionCallback in LteHelper
1021           params.m_rnti = (*itTb).first.m_rnti;
1022           params.m_txMode = m_transmissionMode;
1023           params.m_layer =  (*itTb).first.m_layer;
1024           params.m_mcs = (*itTb).second.mcs;
1025           params.m_size = (*itTb).second.size;
1026           params.m_rv = (*itTb).second.rv;
1027           params.m_ndi = (*itTb).second.ndi;
1028           params.m_correctness = (uint8_t) !(*itTb).second.corrupt;
1029           params.m_ccId = m_componentCarrierId;
1030           if ((*itTb).second.downlink)
1031             {
1032               // DL
1033               m_dlPhyReception (params);
1034             }
1035           else
1036             {
1037               // UL
1038               params.m_rv = harqInfoList.size ();
1039               m_ulPhyReception (params);
1040             }
1041         }
1042 
1043       itTb++;
1044     }
1045   std::map <uint16_t, DlInfoListElement_s> harqDlInfoMap;
1046   for (std::list<Ptr<PacketBurst> >::const_iterator i = m_rxPacketBurstList.begin ();
1047        i != m_rxPacketBurstList.end (); ++i)
1048     {
1049       for (std::list<Ptr<Packet> >::const_iterator j = (*i)->Begin (); j != (*i)->End (); ++j)
1050         {
1051           // retrieve TB info of this packet
1052           LteRadioBearerTag tag;
1053           (*j)->PeekPacketTag (tag);
1054           TbId_t tbId;
1055           tbId.m_rnti = tag.GetRnti ();
1056           tbId.m_layer = tag.GetLayer ();
1057           itTb = m_expectedTbs.find (tbId);
1058           NS_LOG_INFO (this << " Packet of " << tbId.m_rnti << " layer " <<  (uint16_t) tag.GetLayer ());
1059           if (itTb != m_expectedTbs.end ())
1060             {
1061               if (!(*itTb).second.corrupt)
1062                 {
1063                   m_phyRxEndOkTrace (*j);
1064 
1065                   if (!m_ltePhyRxDataEndOkCallback.IsNull ())
1066                     {
1067                       m_ltePhyRxDataEndOkCallback (*j);
1068                     }
1069                 }
1070               else
1071                 {
1072                   // TB received with errors
1073                   m_phyRxEndErrorTrace (*j);
1074                 }
1075 
1076               // send HARQ feedback (if not already done for this TB)
1077               if (!(*itTb).second.harqFeedbackSent)
1078                 {
1079                   (*itTb).second.harqFeedbackSent = true;
1080                   if (!(*itTb).second.downlink)
1081                     {
1082                       UlInfoListElement_s harqUlInfo;
1083                       harqUlInfo.m_rnti = tbId.m_rnti;
1084                       harqUlInfo.m_tpc = 0;
1085                       if ((*itTb).second.corrupt)
1086                         {
1087                           harqUlInfo.m_receptionStatus = UlInfoListElement_s::NotOk;
1088                           NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-NACK");
1089                           m_harqPhyModule->UpdateUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
1090                         }
1091                       else
1092                         {
1093                           harqUlInfo.m_receptionStatus = UlInfoListElement_s::Ok;
1094                           NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " send UL-HARQ-ACK");
1095                           m_harqPhyModule->ResetUlHarqProcessStatus (tbId.m_rnti, (*itTb).second.harqProcessId);
1096                         }
1097                       if (!m_ltePhyUlHarqFeedbackCallback.IsNull ())
1098                         {
1099                           m_ltePhyUlHarqFeedbackCallback (harqUlInfo);
1100                         }
1101                     }
1102                   else
1103                     {
1104                       std::map <uint16_t, DlInfoListElement_s>::iterator itHarq = harqDlInfoMap.find (tbId.m_rnti);
1105                       if (itHarq == harqDlInfoMap.end ())
1106                         {
1107                           DlInfoListElement_s harqDlInfo;
1108                           harqDlInfo.m_harqStatus.resize (m_layersNum, DlInfoListElement_s::ACK);
1109                           harqDlInfo.m_rnti = tbId.m_rnti;
1110                           harqDlInfo.m_harqProcessId = (*itTb).second.harqProcessId;
1111                           if ((*itTb).second.corrupt)
1112                             {
1113                               harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
1114                               NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " send DL-HARQ-NACK");
1115                               m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
1116                             }
1117                           else
1118                             {
1119 
1120                               harqDlInfo.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
1121                               NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " size " << (*itTb).second.size << " send DL-HARQ-ACK");
1122                               m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
1123                             }
1124                           harqDlInfoMap.insert (std::pair <uint16_t, DlInfoListElement_s> (tbId.m_rnti, harqDlInfo));
1125                         }
1126                       else
1127                         {
1128                           if ((*itTb).second.corrupt)
1129                             {
1130                               (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::NACK;
1131                               NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " size " << (*itHarq).second.m_harqStatus.size () << " send DL-HARQ-NACK");
1132                               m_harqPhyModule->UpdateDlHarqProcessStatus ((*itTb).second.harqProcessId, tbId.m_layer, (*itTb).second.mi, (*itTb).second.size, (*itTb).second.size / EffectiveCodingRate [(*itTb).second.mcs]);
1133                             }
1134                           else
1135                             {
1136                               NS_ASSERT_MSG (tbId.m_layer < (*itHarq).second.m_harqStatus.size (), " layer " << (uint16_t)tbId.m_layer);
1137                               (*itHarq).second.m_harqStatus.at (tbId.m_layer) = DlInfoListElement_s::ACK;
1138                               NS_LOG_DEBUG (this << " RNTI " << tbId.m_rnti << " harqId " << (uint16_t)(*itTb).second.harqProcessId << " layer " << (uint16_t)tbId.m_layer << " size " << (*itHarq).second.m_harqStatus.size () << " send DL-HARQ-ACK");
1139                               m_harqPhyModule->ResetDlHarqProcessStatus ((*itTb).second.harqProcessId);
1140                             }
1141                         }
1142                     }   // end if ((*itTb).second.downlink) HARQ
1143                 }   // end if (!(*itTb).second.harqFeedbackSent)
1144             }
1145         }
1146     }
1147 
1148   // send DL HARQ feedback to LtePhy
1149   std::map <uint16_t, DlInfoListElement_s>::iterator itHarq;
1150   for (itHarq = harqDlInfoMap.begin (); itHarq != harqDlInfoMap.end (); itHarq++)
1151     {
1152       if (!m_ltePhyDlHarqFeedbackCallback.IsNull ())
1153         {
1154           m_ltePhyDlHarqFeedbackCallback ((*itHarq).second);
1155         }
1156     }
1157   // forward control messages of this frame to LtePhy
1158   if (!m_rxControlMessageList.empty ())
1159     {
1160       if (!m_ltePhyRxCtrlEndOkCallback.IsNull ())
1161         {
1162           m_ltePhyRxCtrlEndOkCallback (m_rxControlMessageList);
1163         }
1164     }
1165   ChangeState (IDLE);
1166   m_rxPacketBurstList.clear ();
1167   m_rxControlMessageList.clear ();
1168   m_expectedTbs.clear ();
1169 }
1170 
1171 
1172 void
EndRxDlCtrl()1173 LteSpectrumPhy::EndRxDlCtrl ()
1174 {
1175   NS_LOG_FUNCTION (this);
1176   NS_LOG_LOGIC (this << " state: " << m_state);
1177 
1178   NS_ASSERT (m_state == RX_DL_CTRL);
1179 
1180   // this will trigger CQI calculation and Error Model evaluation
1181   // as a side effect, the error model should update the error status of all TBs
1182   m_interferenceCtrl->EndRx ();
1183   // apply transmission mode gain
1184   NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
1185   NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
1186   if (m_transmissionMode > 0)
1187     {
1188       // in case of MIMO, ctrl is always txed as TX diversity
1189       m_sinrPerceived *= m_txModeGain.at (1);
1190     }
1191 //   m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
1192   bool error = false;
1193   if (m_ctrlErrorModelEnabled)
1194     {
1195       double  errorRate = LteMiErrorModel::GetPcfichPdcchError (m_sinrPerceived);
1196       error = m_random->GetValue () > errorRate ? false : true;
1197       NS_LOG_DEBUG (this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error " << error);
1198     }
1199 
1200   if (!error)
1201     {
1202       if (!m_ltePhyRxCtrlEndOkCallback.IsNull ())
1203         {
1204           NS_LOG_DEBUG (this << " PCFICH-PDCCH Rxed OK");
1205           m_ltePhyRxCtrlEndOkCallback (m_rxControlMessageList);
1206         }
1207     }
1208   else
1209     {
1210       if (!m_ltePhyRxCtrlEndErrorCallback.IsNull ())
1211         {
1212           NS_LOG_DEBUG (this << " PCFICH-PDCCH Error");
1213           m_ltePhyRxCtrlEndErrorCallback ();
1214         }
1215     }
1216   ChangeState (IDLE);
1217   m_rxControlMessageList.clear ();
1218 }
1219 
1220 void
EndRxUlSrs()1221 LteSpectrumPhy::EndRxUlSrs ()
1222 {
1223   NS_ASSERT (m_state == RX_UL_SRS);
1224   ChangeState (IDLE);
1225   m_interferenceCtrl->EndRx ();
1226   // nothing to do (used only for SRS at this stage)
1227 }
1228 
1229 void
SetCellId(uint16_t cellId)1230 LteSpectrumPhy::SetCellId (uint16_t cellId)
1231 {
1232   m_cellId = cellId;
1233 }
1234 
1235 void
SetComponentCarrierId(uint8_t componentCarrierId)1236 LteSpectrumPhy::SetComponentCarrierId (uint8_t componentCarrierId)
1237 {
1238   m_componentCarrierId = componentCarrierId;
1239 }
1240 
1241 void
AddRsPowerChunkProcessor(Ptr<LteChunkProcessor> p)1242 LteSpectrumPhy::AddRsPowerChunkProcessor (Ptr<LteChunkProcessor> p)
1243 {
1244   m_interferenceCtrl->AddRsPowerChunkProcessor (p);
1245 }
1246 
1247 void
AddDataPowerChunkProcessor(Ptr<LteChunkProcessor> p)1248 LteSpectrumPhy::AddDataPowerChunkProcessor (Ptr<LteChunkProcessor> p)
1249 {
1250   m_interferenceData->AddRsPowerChunkProcessor (p);
1251 }
1252 
1253 void
AddDataSinrChunkProcessor(Ptr<LteChunkProcessor> p)1254 LteSpectrumPhy::AddDataSinrChunkProcessor (Ptr<LteChunkProcessor> p)
1255 {
1256   m_interferenceData->AddSinrChunkProcessor (p);
1257 }
1258 
1259 void
AddInterferenceCtrlChunkProcessor(Ptr<LteChunkProcessor> p)1260 LteSpectrumPhy::AddInterferenceCtrlChunkProcessor (Ptr<LteChunkProcessor> p)
1261 {
1262   m_interferenceCtrl->AddInterferenceChunkProcessor (p);
1263 }
1264 
1265 void
AddInterferenceDataChunkProcessor(Ptr<LteChunkProcessor> p)1266 LteSpectrumPhy::AddInterferenceDataChunkProcessor (Ptr<LteChunkProcessor> p)
1267 {
1268   m_interferenceData->AddInterferenceChunkProcessor (p);
1269 }
1270 
1271 void
AddCtrlSinrChunkProcessor(Ptr<LteChunkProcessor> p)1272 LteSpectrumPhy::AddCtrlSinrChunkProcessor (Ptr<LteChunkProcessor> p)
1273 {
1274   m_interferenceCtrl->AddSinrChunkProcessor (p);
1275 }
1276 
1277 void
SetTransmissionMode(uint8_t txMode)1278 LteSpectrumPhy::SetTransmissionMode (uint8_t txMode)
1279 {
1280   NS_LOG_FUNCTION (this << (uint16_t) txMode);
1281   NS_ASSERT_MSG (txMode < m_txModeGain.size (), "TransmissionMode not available: 1.." << m_txModeGain.size ());
1282   m_transmissionMode = txMode;
1283   m_layersNum = TransmissionModesLayers::TxMode2LayerNum (txMode);
1284 }
1285 
1286 
1287 void
SetTxModeGain(uint8_t txMode,double gain)1288 LteSpectrumPhy::SetTxModeGain (uint8_t txMode, double gain)
1289 {
1290   NS_LOG_FUNCTION (this << " txmode " << (uint16_t)txMode << " gain " << gain);
1291   // convert to linear
1292   gain = std::pow (10.0, (gain / 10.0));
1293   if (m_txModeGain.size () < txMode)
1294     {
1295       m_txModeGain.resize (txMode);
1296     }
1297   std::vector <double> temp;
1298   temp = m_txModeGain;
1299   m_txModeGain.clear ();
1300   for (uint8_t i = 0; i < temp.size (); i++)
1301     {
1302       if (i == txMode - 1)
1303         {
1304           m_txModeGain.push_back (gain);
1305         }
1306       else
1307         {
1308           m_txModeGain.push_back (temp.at (i));
1309         }
1310     }
1311 }
1312 
1313 int64_t
AssignStreams(int64_t stream)1314 LteSpectrumPhy::AssignStreams (int64_t stream)
1315 {
1316   NS_LOG_FUNCTION (this << stream);
1317   m_random->SetStream (stream);
1318   return 1;
1319 }
1320 
1321 
1322 
1323 } // namespace ns3
1324