A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
lte-spectrum-phy.cc
Go to the documentation of this file.
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"
32 #include "lte-net-device.h"
33 #include "lte-radio-bearer-tag.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 
41 NS_LOG_COMPONENT_DEFINE ("LteSpectrumPhy");
42 
43 namespace ns3 {
44 
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 
56 
57 
59 {
60 }
61 
62 TbId_t::TbId_t (const uint16_t a, const uint8_t b)
63 : m_rnti (a),
64  m_layer (b)
65 {
66 }
67 
68 bool
69 operator == (const TbId_t &a, const TbId_t &b)
70 {
71  return ( (a.m_rnti == b.m_rnti) && (a.m_layer == b.m_layer) );
72 }
73 
74 bool
75 operator < (const TbId_t& a, const TbId_t& b)
76 {
77  return ( (a.m_rnti < b.m_rnti) || ( (a.m_rnti == b.m_rnti) && (a.m_layer < b.m_layer) ) );
78 }
79 
80 NS_OBJECT_ENSURE_REGISTERED (LteSpectrumPhy);
81 
83  : m_state (IDLE),
84  m_transmissionMode (0)
85 {
86  NS_LOG_FUNCTION (this);
87  m_random = CreateObject<UniformRandomVariable> ();
88  m_random->SetAttribute ("Min", DoubleValue (0.0));
89  m_random->SetAttribute ("Max", DoubleValue (1.0));
90  m_interferenceData = CreateObject<LteInterference> ();
91  m_interferenceCtrl = CreateObject<LteInterference> ();
92 
93  for (uint8_t i = 0; i < 7; i++)
94  {
95  m_txModeGain.push_back (1.0);
96  }
97 }
98 
99 
101 {
102  NS_LOG_FUNCTION (this);
103  m_expectedTbs.clear ();
104  m_txModeGain.clear ();
105 }
106 
108 {
109  NS_LOG_FUNCTION (this);
110  m_channel = 0;
111  m_mobility = 0;
112  m_device = 0;
114  m_interferenceData = 0;
116  m_interferenceCtrl = 0;
117  m_ltePhyTxEndCallback = MakeNullCallback< void, Ptr<const Packet> > ();
118  m_ltePhyRxDataEndErrorCallback = MakeNullCallback< void > ();
119  m_ltePhyRxDataEndOkCallback = MakeNullCallback< void, Ptr<Packet> > ();
120  m_ltePhyRxCtrlEndOkCallback = MakeNullCallback< void, std::list<Ptr<LteControlMessage> > > ();
121  m_ltePhyRxCtrlEndErrorCallback = MakeNullCallback< void > ();
123 }
124 
125 std::ostream& operator<< (std::ostream& os, LteSpectrumPhy::State s)
126 {
127  switch (s)
128  {
130  os << "IDLE";
131  break;
133  os << "RX_DATA";
134  break;
136  os << "RX_CTRL";
137  break;
138  case LteSpectrumPhy::TX:
139  os << "TX";
140  break;
141  default:
142  os << "UNKNOWN";
143  break;
144  }
145  return os;
146 }
147 
148 TypeId
150 {
151  static TypeId tid = TypeId ("ns3::LteSpectrumPhy")
153  .AddTraceSource ("TxStart",
154  "Trace fired when a new transmission is started",
156  .AddTraceSource ("TxEnd",
157  "Trace fired when a previosuly started transmission is finished",
159  .AddTraceSource ("RxStart",
160  "Trace fired when the start of a signal is detected",
162  .AddTraceSource ("RxEndOk",
163  "Trace fired when a previosuly started RX terminates successfully",
165  .AddTraceSource ("RxEndError",
166  "Trace fired when a previosuly started RX terminates with an error",
168  .AddAttribute ("DataErrorModelEnabled",
169  "Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) [by default is active].",
170  BooleanValue (true),
171  MakeBooleanAccessor (&LteSpectrumPhy::m_dataErrorModelEnabled),
172  MakeBooleanChecker ())
173  .AddAttribute ("CtrlErrorModelEnabled",
174  "Activate/Deactivate the error model of control (PCFICH-PDCCH decodification) [by default is active].",
175  BooleanValue (true),
176  MakeBooleanAccessor (&LteSpectrumPhy::m_ctrlErrorModelEnabled),
177  MakeBooleanChecker ())
178  ;
179  return tid;
180 }
181 
182 
183 
186 {
187  NS_LOG_FUNCTION (this);
188  return m_device;
189 }
190 
191 
194 {
195  NS_LOG_FUNCTION (this);
196  return m_mobility;
197 }
198 
199 
200 void
202 {
203  NS_LOG_FUNCTION (this << d);
204  m_device = d;
205 }
206 
207 
208 void
210 {
211  NS_LOG_FUNCTION (this << m);
212  m_mobility = m;
213 }
214 
215 
216 void
218 {
219  NS_LOG_FUNCTION (this << c);
220  m_channel = c;
221 }
222 
225 {
226  return m_rxSpectrumModel;
227 }
228 
229 
230 void
232 {
233  NS_LOG_FUNCTION (this << txPsd);
234  NS_ASSERT (txPsd);
235  m_txPsd = txPsd;
236 }
237 
238 
239 void
241 {
242  NS_LOG_FUNCTION (this << noisePsd);
243  NS_ASSERT (noisePsd);
244  m_rxSpectrumModel = noisePsd->GetSpectrumModel ();
247 }
248 
249 
250 
251 void
253 {
254  NS_LOG_FUNCTION (this);
256 }
257 
258 
259 void
261 {
262  NS_LOG_FUNCTION (this);
264 }
265 
266 
267 void
269 {
270  NS_LOG_FUNCTION (this);
272 }
273 
274 void
276 {
277  NS_LOG_FUNCTION (this);
279 }
280 
281 void
283 {
284  NS_LOG_FUNCTION (this);
286 }
287 
288 
291 {
292  return m_antenna;
293 }
294 
295 void
297 {
298  NS_LOG_FUNCTION (this << a);
299  m_antenna = a;
300 }
301 
302 void
304 {
305  ChangeState (newState);
306 }
307 
308 
309 void
311 {
312  NS_LOG_LOGIC (this << " state: " << m_state << " -> " << newState);
313  m_state = newState;
314 }
315 
316 
317 
318 bool
320 {
321  NS_LOG_FUNCTION (this << pb);
322  NS_LOG_LOGIC (this << " state: " << m_state);
323 
324  m_phyTxStartTrace (pb);
325 
326  switch (m_state)
327  {
328  case RX_DATA:
329  case RX_CTRL:
330  NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
331  break;
332 
333  case TX:
334  NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
335  break;
336 
337  case IDLE:
338  {
339  /*
340  m_txPsd must be setted by the device, according to
341  (i) the available subchannel for transmission
342  (ii) the power transmission
343  */
344  NS_ASSERT (m_txPsd);
345  m_txPacketBurst = pb;
346 
347  // we need to convey some PHY meta information to the receiver
348  // to be used for simulation purposes (e.g., the CellId). This
349  // is done by setting the ctrlMsgList parameter of
350  // LteSpectrumSignalParametersDataFrame
351  ChangeState (TX);
353  Ptr<LteSpectrumSignalParametersDataFrame> txParams = Create<LteSpectrumSignalParametersDataFrame> ();
354  txParams->duration = duration;
355  txParams->txPhy = GetObject<SpectrumPhy> ();
356  txParams->txAntenna = m_antenna;
357  txParams->psd = m_txPsd;
358  txParams->packetBurst = pb;
359  txParams->ctrlMsgList = ctrlMsgList;
360  txParams->cellId = m_cellId;
361  m_channel->StartTx (txParams);
362  Simulator::Schedule (duration, &LteSpectrumPhy::EndTx, this);
363  }
364  return false;
365  break;
366 
367  default:
368  NS_FATAL_ERROR ("unknown state");
369  return true;
370  break;
371  }
372 }
373 
374 bool
376 {
377  NS_LOG_FUNCTION (this << time);
378  NS_LOG_LOGIC (this << " state: " << m_state);
379 
380 // m_phyTxStartTrace (pb);
381 
382  switch (m_state)
383  {
384  case RX_DATA:
385  case RX_CTRL:
386  NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
387  break;
388 
389  case TX:
390  NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
391  break;
392 
393  case IDLE:
394  {
395  /*
396  m_txPsd must be setted by the device, according to
397  (i) the available subchannel for transmission
398  (ii) the power transmission
399  */
400  NS_ASSERT (m_txPsd);
401 
402  // we need to convey some PHY meta information to the receiver
403  // to be used for simulation purposes (e.g., the CellId). This
404  // is done by setting the cellId parameter of
405  // LteSpectrumSignalParametersDlCtrlFrame
406  ChangeState (TX);
408 
409  Ptr<LteSpectrumSignalParametersDlCtrlFrame> txParams = Create<LteSpectrumSignalParametersDlCtrlFrame> ();
410  txParams->duration = DL_CTRL_DURATION;
411  txParams->txPhy = GetObject<SpectrumPhy> ();
412  txParams->txAntenna = m_antenna;
413  txParams->psd = m_txPsd;
414  txParams->cellId = m_cellId;
415  txParams->ctrlMsgList = ctrlMsgList;
416  m_channel->StartTx (txParams);
418  }
419  return false;
420  break;
421 
422  default:
423  NS_FATAL_ERROR ("unknown state");
424  return true;
425  break;
426  }
427 }
428 
429 
430 bool
432 {
433  NS_LOG_FUNCTION (this << time);
434  NS_LOG_LOGIC (this << " state: " << m_state);
435 
436  // m_phyTxStartTrace (pb);
437 
438  switch (m_state)
439  {
440  case RX_DATA:
441  case RX_CTRL:
442  NS_FATAL_ERROR ("cannot TX while RX: according to FDD channel acces, the physical layer for transmission cannot be used for reception");
443  break;
444 
445  case TX:
446  NS_FATAL_ERROR ("cannot TX while already TX: the MAC should avoid this");
447  break;
448 
449  case IDLE:
450  {
451  /*
452  m_txPsd must be setted by the device, according to
453  (i) the available subchannel for transmission
454  (ii) the power transmission
455  */
456  NS_ASSERT (m_txPsd);
457 
458  // we need to convey some PHY meta information to the receiver
459  // to be used for simulation purposes (e.g., the CellId). This
460  // is done by setting the cellId parameter of
461  // LteSpectrumSignalParametersDlCtrlFrame
462  ChangeState (TX);
464  Ptr<LteSpectrumSignalParametersUlSrsFrame> txParams = Create<LteSpectrumSignalParametersUlSrsFrame> ();
465  txParams->duration = UL_SRS_DURATION;
466  txParams->txPhy = GetObject<SpectrumPhy> ();
467  txParams->txAntenna = m_antenna;
468  txParams->psd = m_txPsd;
469  txParams->cellId = m_cellId;
470  m_channel->StartTx (txParams);
472  }
473  return false;
474  break;
475 
476  default:
477  NS_FATAL_ERROR ("unknown state");
478  return true;
479  break;
480  }
481 }
482 
483 
484 
485 void
487 {
488  NS_LOG_FUNCTION (this);
489  NS_LOG_LOGIC (this << " state: " << m_state);
490 
491  NS_ASSERT (m_state == TX);
492 
494 
496  {
497  for (std::list<Ptr<Packet> >::const_iterator iter = m_txPacketBurst->Begin (); iter
498  != m_txPacketBurst->End (); ++iter)
499  {
500  Ptr<Packet> packet = (*iter)->Copy ();
501  m_ltePhyTxEndCallback (packet);
502  }
503  }
504 
505  m_txPacketBurst = 0;
506  ChangeState (IDLE);
507 }
508 
509 
510 void
512 {
513  NS_LOG_FUNCTION (this << spectrumRxParams);
514  NS_LOG_LOGIC (this << " state: " << m_state);
515 
516  Ptr <const SpectrumValue> rxPsd = spectrumRxParams->psd;
517  Time duration = spectrumRxParams->duration;
518 
519  // the device might start RX only if the signal is of a type
520  // understood by this device - in this case, an LTE signal.
521  Ptr<LteSpectrumSignalParametersDataFrame> lteDataRxParams = DynamicCast<LteSpectrumSignalParametersDataFrame> (spectrumRxParams);
522  if (lteDataRxParams != 0)
523  {
524  m_interferenceData->AddSignal (rxPsd, duration);
525  StartRxData (lteDataRxParams);
526  }
527  else
528  {
529  Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams = DynamicCast<LteSpectrumSignalParametersDlCtrlFrame> (spectrumRxParams);
530  Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams = DynamicCast<LteSpectrumSignalParametersUlSrsFrame> (spectrumRxParams);
531  if ((lteDlCtrlRxParams!=0)||(lteUlSrsRxParams!=0))
532  {
533  m_interferenceCtrl->AddSignal (rxPsd, duration);
534  StartRxCtrl (spectrumRxParams);
535  }
536  else
537  {
538  // other type of signal (could be 3G, GSM, whatever) -> interference
539  m_interferenceData->AddSignal (rxPsd, duration);
540  m_interferenceCtrl->AddSignal (rxPsd, duration);
541  }
542  }
543 
544 }
545 
546 void
548 {
549  NS_LOG_FUNCTION (this);
550  switch (m_state)
551  {
552  case TX:
553  NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
554  break;
555  case RX_CTRL:
556  NS_FATAL_ERROR ("cannot RX Data while receiving control");
557  break;
558  case IDLE:
559  case RX_DATA:
560  // the behavior is similar when
561  // we're IDLE or RX because we can receive more signals
562  // simultaneously (e.g., at the eNB).
563  {
564  // To check if we're synchronized to this signal, we check
565  // for the CellId which is reported in the
566  // LteSpectrumSignalParametersDataFrame
567  if (params->cellId == m_cellId)
568  {
569  NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << params->cellId << ")");
570  if ((m_rxPacketBurstList.empty ())&&(m_rxControlMessageList.empty ()))
571  {
572  NS_ASSERT (m_state == IDLE);
573  // first transmission, i.e., we're IDLE and we
574  // start RX
576  m_firstRxDuration = params->duration;
577  NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration.GetSeconds () << "s");
578  Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxData, this);
579  }
580  else
581  {
583  // sanity check: if there are multiple RX events, they
584  // should occur at the same time and have the same
585  // duration, otherwise the interference calculation
586  // won't be correct
588  && (m_firstRxDuration == params->duration));
589  }
590 
592  if (params->packetBurst)
593  {
594  m_rxPacketBurstList.push_back (params->packetBurst);
595  m_interferenceData->StartRx (params->psd);
596 
597  m_phyRxStartTrace (params->packetBurst);
598  }
599  NS_LOG_DEBUG (this << " insert msgs " << params->ctrlMsgList.size ());
600  m_rxControlMessageList.insert (m_rxControlMessageList.end (), params->ctrlMsgList.begin (), params->ctrlMsgList.end ());
601 
602  NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
603  }
604  else
605  {
606  NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
607  << params->cellId << ", m_cellId=" << m_cellId << ")");
608  }
609  }
610  break;
611 
612  default:
613  NS_FATAL_ERROR ("unknown state");
614  break;
615  }
616 
617  NS_LOG_LOGIC (this << " state: " << m_state);
618 }
619 
620 
621 
622 void
624 {
625  NS_LOG_FUNCTION (this);
626  switch (m_state)
627  {
628  case TX:
629  NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception");
630  break;
631  case RX_DATA:
632  NS_FATAL_ERROR ("cannot RX data while receing control");
633  break;
634  case IDLE:
635  case RX_CTRL:
636  // the behavior is similar when
637  // we're IDLE or RX because we can receive more signals
638  // simultaneously (e.g., at the eNB).
639  {
640  // To check if we're synchronized to this signal, we check
641  // for the CellId which is reported in the
642  // LteSpectrumSignalParametersDlCtrlFrame
643  uint16_t cellId;
644  bool dl;
645  Ptr<LteSpectrumSignalParametersDlCtrlFrame> lteDlCtrlRxParams = DynamicCast<LteSpectrumSignalParametersDlCtrlFrame> (params);
646  if (lteDlCtrlRxParams!=0)
647  {
648  cellId = lteDlCtrlRxParams->cellId;
649  dl = true;
650  }
651  else
652  {
653  Ptr<LteSpectrumSignalParametersUlSrsFrame> lteUlSrsRxParams = DynamicCast<LteSpectrumSignalParametersUlSrsFrame> (params);
654  cellId = lteUlSrsRxParams->cellId;
655  dl = false;
656  }
657  if (cellId == m_cellId)
658  {
659  NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << cellId << ")");
660  if (m_state == IDLE)
661  {
662  // first transmission, i.e., we're IDLE and we
663  // start RX
666  m_firstRxDuration = params->duration;
667  NS_LOG_LOGIC (this << " scheduling EndRx with delay " << params->duration);
668  if (dl==true)
669  {
670  // store the DCIs
671  m_rxControlMessageList = lteDlCtrlRxParams->ctrlMsgList;
672  Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxDlCtrl, this);
673  }
674  else
675  {
676  Simulator::Schedule (params->duration, &LteSpectrumPhy::EndRxUlSrs, this);
677  }
678  }
679  else if (m_state == RX_CTRL)
680  {
681  // sanity check: if there are multiple RX events, they
682  // should occur at the same time and have the same
683  // duration, otherwise the interference calculation
684  // won't be correct
686  && (m_firstRxDuration == params->duration));
687  }
688 
690  m_interferenceCtrl->StartRx (params->psd);
691 
692 // NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ());
693  }
694  else
695  {
696  NS_LOG_LOGIC (this << " not in sync with this signal (cellId="
697  << cellId << ", m_cellId=" << m_cellId << ")");
698  }
699  }
700  break;
701 
702  default:
703  NS_FATAL_ERROR ("unknown state");
704  break;
705  }
706 
707  NS_LOG_LOGIC (this << " state: " << m_state);
708 }
709 
710 
711 void
713 {
714  NS_LOG_FUNCTION (this << sinr);
715  m_sinrPerceived = sinr;
716 }
717 
718 
719 void
720 LteSpectrumPhy::AddExpectedTb (uint16_t rnti, uint16_t size, uint8_t mcs, std::vector<int> map, uint8_t layer)
721 {
722  NS_LOG_LOGIC (this << " rnti: " << rnti << " size " << size << " mcs " << (uint16_t)mcs << " layer " << (uint8_t)layer);
723  TbId_t tbId;
724  tbId.m_rnti = rnti;
725  tbId.m_layer = layer;
726  expectedTbs_t::iterator it;
727  it = m_expectedTbs.find (tbId);
728  if (it != m_expectedTbs.end ())
729  {
730  // migth be a TB of an unreceived packet (due to high progpalosses)
731  m_expectedTbs.erase (it);
732  }
733  // insert new entry
734  tbInfo_t tbInfo = {size, mcs, map, false};
735  m_expectedTbs.insert (std::pair<TbId_t, tbInfo_t> (tbId,tbInfo ));
736 }
737 
738 
739 void
741 {
742  NS_LOG_FUNCTION (this);
743  NS_LOG_LOGIC (this << " state: " << m_state);
744 
746 
747  // this will trigger CQI calculation and Error Model evaluation
748  // as a side effect, the error model should update the error status of all TBs
750  NS_LOG_DEBUG (this << " No. of burts " << m_rxPacketBurstList.size ());
751  NS_LOG_DEBUG (this << " Expected TBs " << m_expectedTbs.size ());
752  expectedTbs_t::iterator itTb = m_expectedTbs.begin ();
753 
754  // apply transmission mode gain
755  NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
758 
759  while (itTb!=m_expectedTbs.end ())
760  {
761  if ((m_dataErrorModelEnabled)&&(m_rxPacketBurstList.size ()>0)) // avoid to check for errors when there is no actual data transmitted
762  {
763  double errorRate = LteMiErrorModel::GetTbError (m_sinrPerceived, (*itTb).second.rbBitmap, (*itTb).second.size, (*itTb).second.mcs);
764  (*itTb).second.corrupt = m_random->GetValue () > errorRate ? false : true;
765  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 << " ErrorRate " << errorRate << " corrupted " << (*itTb).second.corrupt);
766  }
767 
768 // for (uint16_t i = 0; i < (*itTb).second.rbBitmap.size (); i++)
769 // {
770 // NS_LOG_DEBUG (this << " RB " << (*itTb).second.rbBitmap.at (i) << " SINR " << m_sinrPerceived[(*itTb).second.rbBitmap.at (i)]);
771 // }
772  itTb++;
773  }
774  for (std::list<Ptr<PacketBurst> >::const_iterator i = m_rxPacketBurstList.begin ();
775  i != m_rxPacketBurstList.end (); ++i)
776  {
777  for (std::list<Ptr<Packet> >::const_iterator j = (*i)->Begin (); j != (*i)->End (); ++j)
778  {
779  // retrieve TB info of this packet
780  LteRadioBearerTag tag;
781  (*j)->PeekPacketTag (tag);
782  TbId_t tbId;
783  tbId.m_rnti = tag.GetRnti ();
784  tbId.m_layer = tag.GetLayer ();
785  itTb = m_expectedTbs.find (tbId);
786  NS_LOG_INFO (this << " Packet of " << tbId.m_rnti << " layer " << (uint8_t) tbId.m_layer);
787  if (itTb!=m_expectedTbs.end ())
788  {
789  if (!(*itTb).second.corrupt)
790  {
791  m_phyRxEndOkTrace (*j);
792 
794  {
796  }
797  }
798  else
799  {
800  // TB received with errors
802  }
803  }
804  }
805  }
806 
807  if (!m_rxControlMessageList.empty ())
808  {
810  {
812  }
813  }
814  ChangeState (IDLE);
815  m_rxPacketBurstList.clear ();
816  m_rxControlMessageList.clear ();
817  m_expectedTbs.clear ();
818 }
819 
820 
821 void
823 {
824  NS_LOG_FUNCTION (this);
825  NS_LOG_LOGIC (this << " state: " << m_state);
826 
828 
829  // this will trigger CQI calculation and Error Model evaluation
830  // as a side effect, the error model should update the error status of all TBs
832  // apply transmission mode gain
833  NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
835  if (m_transmissionMode>0)
836  {
837  // in case of MIMO, ctrl is always txed as TX diversity
838  m_sinrPerceived *= m_txModeGain.at (1);
839  }
840 // m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
841  bool error = false;
843  {
846  error = m_random->GetValue () > errorRate ? false : true;
847  NS_LOG_DEBUG (this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error " << error);
848  }
849 
850  if (!error)
851  {
853  {
855  }
856  }
857  else
858  {
860  {
862  }
863  }
864  ChangeState (IDLE);
865  m_rxControlMessageList.clear ();
866 }
867 
868 void
870 {
872  ChangeState (IDLE);
874  // nothing to do (used only for SRS at this stage)
875 }
876 
877 void
878 LteSpectrumPhy::SetCellId (uint16_t cellId)
879 {
880  m_cellId = cellId;
881 }
882 
883 
884 void
886 {
888 }
889 
890 void
892 {
894 }
895 
896 void
898 {
899  NS_LOG_FUNCTION (this << (uint16_t) txMode);
900  NS_ASSERT_MSG (txMode < m_txModeGain.size (), "TransmissionMode not available: 1.." << m_txModeGain.size ());
901  m_transmissionMode = txMode;
902 }
903 
904 
905 void
906 LteSpectrumPhy::SetTxModeGain (uint8_t txMode, double gain)
907 {
908  NS_LOG_FUNCTION (this << " txmode " << (uint16_t)txMode << " gain " << gain);
909  // convert to linear
910  gain = std::pow (10.0, (gain / 10.0));
911  if (m_txModeGain.size () < txMode)
912  {
913  m_txModeGain.resize (txMode);
914  }
915  std::vector <double> temp;
916  temp = m_txModeGain;
917  m_txModeGain.clear ();
918  for (uint8_t i = 0; i < temp.size (); i++)
919  {
920  if (i==txMode-1)
921  {
922  m_txModeGain.push_back (gain);
923  }
924  else
925  {
926  m_txModeGain.push_back (temp.at (i));
927  }
928  }
929 }
930 
931 int64_t
933 {
934  NS_LOG_FUNCTION (this << stream);
935  m_random->SetStream (stream);
936  return 1;
937 }
938 
939 
940 
941 } // namespace ns3