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