A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
lte-enb-phy.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Giuseppe Piro <g.piro@poliba.it>
19  * Marco Miozzo <mmiozzo@cttc.es>
20  */
21 
22 #include <ns3/object-factory.h>
23 #include <ns3/log.h>
24 #include <math.h>
25 #include <ns3/simulator.h>
26 #include <ns3/attribute-accessor-helper.h>
27 #include <ns3/double.h>
28 
29 
30 #include "lte-enb-phy.h"
31 #include "lte-net-device.h"
33 #include "ideal-control-messages.h"
34 #include "lte-enb-net-device.h"
35 #include "lte-enb-mac.h"
36 #include <ns3/lte-common.h>
37 
38 
39 NS_LOG_COMPONENT_DEFINE ("LteEnbPhy");
40 
41 namespace ns3 {
42 
43 
45 // member SAP forwarders
47 
48 
50 {
51 public:
53 
54  // inherited from LteEnbPhySapProvider
55  virtual void SendMacPdu (Ptr<Packet> p);
56  virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
57  virtual void SetCellId (uint16_t cellId);
59  virtual uint8_t GetMacChTtiDelay ();
60  virtual void SetTransmissionMode (uint16_t rnti, uint8_t txMode);
61 
62 
63 private:
65 };
66 
68 {
69 
70 }
71 
72 
73 void
75 {
76  m_phy->DoSendMacPdu (p);
77 }
78 
79 void
80 EnbMemberLteEnbPhySapProvider::SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth)
81 {
82  m_phy->DoSetBandwidth (ulBandwidth, dlBandwidth);
83 }
84 
85 void
87 {
88  m_phy->DoSetCellId (cellId);
89 }
90 
91 void
93 {
95 }
96 
97 uint8_t
99 {
100  return (m_phy->DoGetMacChTtiDelay ());
101 }
102 
103 void
105 {
106  m_phy->DoSetTransmissionMode (rnti, txMode);
107 }
108 
109 
111 // generic LteEnbPhy methods
113 
114 
115 
117 
118 
120 {
121  NS_LOG_FUNCTION (this);
122  NS_FATAL_ERROR ("This constructor should not be called");
123 }
124 
126  : LtePhy (dlPhy, ulPhy),
127  m_nrFrames (0),
128  m_nrSubFrames (0)
129 {
132 }
133 
134 TypeId
136 {
137  static TypeId tid = TypeId ("ns3::LteEnbPhy")
138  .SetParent<LtePhy> ()
139  .AddConstructor<LteEnbPhy> ()
140  .AddAttribute ("TxPower",
141  "Transmission power in dBm",
142  DoubleValue (30.0),
143  MakeDoubleAccessor (&LteEnbPhy::SetTxPower,
145  MakeDoubleChecker<double> ())
146  .AddAttribute ("NoiseFigure",
147  "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
148  " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
149  "\"the difference in decibels (dB) between"
150  " the noise output of the actual receiver to the noise output of an "
151  " ideal receiver with the same overall gain and bandwidth when the receivers "
152  " are connected to sources at the standard noise temperature T0.\" "
153  "In this model, we consider T0 = 290K.",
154  DoubleValue (5.0),
155  MakeDoubleAccessor (&LteEnbPhy::SetNoiseFigure,
157  MakeDoubleChecker<double> ())
158  .AddAttribute ("MacToChannelDelay",
159  "The delay in TTI units that occurs between a scheduling decision in the MAC and the actual start of the transmission by the PHY. This is intended to be used to model the latency of real PHY and MAC implementations.",
160  UintegerValue (2),
161  MakeUintegerAccessor (&LteEnbPhy::SetMacChDelay,
163  MakeUintegerChecker<uint8_t> ())
164  ;
165  return tid;
166 }
167 
168 
170 {
171 }
172 
173 void
175 {
176  NS_LOG_FUNCTION (this);
177  m_ueAttached.clear ();
178  delete m_enbPhySapProvider;
180 }
181 
182 void
184 {
185  NS_LOG_FUNCTION (this);
188  LtePhy::DoStart ();
189 }
190 
191 
192 void
194 {
195  m_enbPhySapUser = s;
196 }
197 
200 {
201  return (m_enbPhySapProvider);
202 }
203 
204 void
206 {
207  NS_LOG_FUNCTION (this << pow);
208  m_txPower = pow;
209 }
210 
211 double
213 {
214  NS_LOG_FUNCTION (this);
215  return m_txPower;
216 }
217 
218 void
220 {
221  NS_LOG_FUNCTION (this << nf);
222  m_noiseFigure = nf;
223 }
224 
225 double
227 {
228  NS_LOG_FUNCTION (this);
229  return m_noiseFigure;
230 }
231 
232 void
234 {
235  m_macChTtiDelay = delay;
236  for (int i = 0; i < m_macChTtiDelay; i++)
237  {
238  Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
239  m_packetBurstQueue.push_back (pb);
240  std::list<Ptr<IdealControlMessage> > l;
241  m_controlMessagesQueue.push_back (l);
242  std::list<UlDciIdealControlMessage> l1;
243  m_ulDciQueue.push_back (l1);
244  }
245  for (int i = 0; i < UL_PUSCH_TTIS_DELAY; i++)
246  {
247  std::list<UlDciIdealControlMessage> l1;
248  m_ulDciQueue.push_back (l1);
249  }
250 }
251 
252 uint8_t
254 {
255  return (m_macChTtiDelay);
256 }
257 
258 bool
259 LteEnbPhy::AddUePhy (uint16_t rnti, Ptr<LteUePhy> phy)
260 {
261  std::map <uint16_t, Ptr<LteUePhy> >::iterator it;
262  it = m_ueAttached.find (rnti);
263  if (it == m_ueAttached.end ())
264  {
265  m_ueAttached.insert (std::pair<uint16_t, Ptr<LteUePhy> > (rnti, phy));
266  return (true);
267  }
268  else
269  {
270  NS_LOG_ERROR ("UE already attached");
271  return (false);
272  }
273 }
274 
275 bool
276 LteEnbPhy::DeleteUePhy (uint16_t rnti)
277 {
278  std::map <uint16_t, Ptr<LteUePhy> >::iterator it;
279  it = m_ueAttached.find (rnti);
280  if (it == m_ueAttached.end ())
281  {
282  NS_LOG_ERROR ("UE not attached");
283  return (false);
284  }
285  else
286  {
287  m_ueAttached.erase (it);
288  return (true);
289  }
290 }
291 
292 
293 
294 void
296 {
297  NS_LOG_FUNCTION (this);
298  SetMacPdu (p);
299 }
300 
301 uint8_t
303 {
304  return (m_macChTtiDelay);
305 }
306 
307 
308 void
310 {
311  NS_LOG_FUNCTION (this);
313 }
314 
315 void
317 {
318  NS_LOG_FUNCTION (this);
321 }
322 
323 
326 {
327  NS_LOG_FUNCTION (this);
328 
330 
331  return psd;
332 }
333 
334 
335 void
337 {
338  NS_LOG_FUNCTION (this);
339 }
340 
341 
342 void
344 {
345  NS_LOG_FUNCTION (this << msg);
346  // queues the message (wait for MAC-PHY delay)
347  SetControlMessages (msg);
348 }
349 
350 
351 
352 void
354 {
355  NS_LOG_FUNCTION (this << msg);
357 }
358 
359 
360 
361 void
363 {
364  NS_LOG_FUNCTION (this);
365 
366  ++m_nrFrames;
367  NS_LOG_INFO ("-----frame " << m_nrFrames << "-----");
368  m_nrSubFrames = 0;
369  StartSubFrame ();
370 }
371 
372 
373 void
375 {
376  NS_LOG_FUNCTION (this);
377 
378  ++m_nrSubFrames;
379  NS_LOG_INFO ("-----sub frame " << m_nrSubFrames << "-----");
380 
381  // update info on TB to be received
382  std::list<UlDciIdealControlMessage> uldcilist = DequeueUlDci ();
383  std::list<UlDciIdealControlMessage>::iterator dciIt = uldcilist.begin ();
384  for (dciIt = uldcilist.begin (); dciIt!=uldcilist.end (); dciIt++)
385  {
386  std::map <uint16_t, Ptr<LteUePhy> >::iterator it2;
387  it2 = m_ueAttached.find ((*dciIt).GetDci ().m_rnti);
388 
389  if (it2 == m_ueAttached.end ())
390  {
391  NS_LOG_ERROR ("UE not attached");
392  }
393  else
394  {
395  // send info of TB to LteSpectrumPhy
396  // translate to allocation map
397  std::vector <int> rbMap;
398  for (int i = (*dciIt).GetDci ().m_rbStart; i < (*dciIt).GetDci ().m_rbStart + (*dciIt).GetDci ().m_rbLen; i++)
399  {
400  rbMap.push_back (i);
401  }
402  m_uplinkSpectrumPhy->AddExpectedTb ((*dciIt).GetDci ().m_rnti, (*dciIt).GetDci ().m_tbSize, (*dciIt).GetDci ().m_mcs, rbMap, 0 /* always SISO*/);
403  }
404  }
405 
406  // send the current burst of control messages
407  std::list<Ptr<IdealControlMessage> > ctrlMsg = GetControlMessages ();
408  std::vector <int> dlRb;
409  if (ctrlMsg.size () > 0)
410  {
411  std::list<Ptr<IdealControlMessage> >::iterator it;
412  it = ctrlMsg.begin ();
413  while (it != ctrlMsg.end ())
414  {
415  Ptr<IdealControlMessage> msg = (*it);
417  {
418  std::map <uint16_t, Ptr<LteUePhy> >::iterator it2;
419  Ptr<DlDciIdealControlMessage> dci = DynamicCast<DlDciIdealControlMessage> (msg);
420  it2 = m_ueAttached.find (dci->GetDci ().m_rnti);
421 
422  if (it2 == m_ueAttached.end ())
423  {
424  NS_LOG_ERROR ("UE not attached");
425  }
426  else
427  {
428  // get the tx power spectral density according to DL-DCI(s)
429  // translate the DCI to Spectrum framework
430  uint32_t mask = 0x1;
431  for (int i = 0; i < 32; i++)
432  {
433  if (((dci->GetDci ().m_rbBitmap & mask) >> i) == 1)
434  {
435  for (int k = 0; k < GetRbgSize (); k++)
436  {
437  dlRb.push_back ((i * GetRbgSize ()) + k);
438  //NS_LOG_DEBUG(this << " [enb]DL-DCI allocated PRB " << (i*GetRbgSize()) + k);
439  }
440  }
441  mask = (mask << 1);
442  }
443  (*it2).second->ReceiveIdealControlMessage (msg);
444  }
445  }
446  else if (msg->GetMessageType () == IdealControlMessage::UL_DCI)
447  {
448  std::map <uint16_t, Ptr<LteUePhy> >::iterator it2;
449  Ptr<UlDciIdealControlMessage> dci = DynamicCast<UlDciIdealControlMessage> (msg);
450 // QueueUlDci (*dci);
451  it2 = m_ueAttached.find (dci->GetDci ().m_rnti);
452 
453  if (it2 == m_ueAttached.end ())
454  {
455  NS_LOG_ERROR ("UE not attached");
456  }
457  else
458  {
459  (*it2).second->ReceiveIdealControlMessage (msg);
460  QueueUlDci (*dci);
461  }
462  }
463  ctrlMsg.pop_front ();
464  it = ctrlMsg.begin ();
465  }
466  }
467  // set the current tx power spectral density
468  SetDownlinkSubChannels (dlRb);
469  // send the current burts of packets
471  if (pb)
472  {
473  NS_LOG_LOGIC (this << " eNB start TX");
475  }
476 
477  // trigger the MAC
479 
480 
481  // trigger the UE(s)
482  std::map <uint16_t, Ptr<LteUePhy> >::iterator it;
483  for (it = m_ueAttached.begin (); it != m_ueAttached.end (); it++)
484  {
485  (*it).second->SubframeIndication (m_nrFrames, m_nrSubFrames);
486  }
487 
490  this);
491 
492 }
493 
494 
495 void
497 {
498  NS_LOG_FUNCTION (this << Simulator::Now ().GetSeconds ());
499  if (m_nrSubFrames == 10)
500  {
502  }
503  else
504  {
506  }
507 }
508 
509 
510 void
512 {
513  NS_LOG_FUNCTION (this << Simulator::Now ().GetSeconds ());
515 }
516 
517 
518 void
520 {
521  NS_LOG_FUNCTION (this << sinr);
523 }
524 
525 
526 UlCqi_s
528 {
529  NS_LOG_FUNCTION (this << sinr);
530  Values::const_iterator it;
531  UlCqi_s ulcqi;
532  ulcqi.m_type = UlCqi_s::PUSCH;
533  int i = 0;
534  for (it = sinr.ConstValuesBegin (); it != sinr.ConstValuesEnd (); it++)
535  {
536  double sinrdb = 10 * log10 ((*it));
537 // NS_LOG_DEBUG ("ULCQI RB " << i << " value " << sinrdb);
538  // convert from double to fixed point notation Sxxxxxxxxxxx.xxx
539  int16_t sinrFp = LteFfConverter::double2fpS11dot3 (sinrdb);
540  ulcqi.m_sinr.push_back (sinrFp);
541  i++;
542  }
543  return (ulcqi);
544 
545 }
546 
547 void
548 LteEnbPhy::DoSetTransmissionMode (uint16_t rnti, uint8_t txMode)
549 {
550  NS_LOG_FUNCTION (this << rnti << (uint16_t)txMode);
551  // UL supports only SISO MODE
552 }
553 
554 void
556 {
557  NS_LOG_FUNCTION (this);
558  m_ulDciQueue.at (UL_PUSCH_TTIS_DELAY - 1).push_back (m);
559 }
560 
561 std::list<UlDciIdealControlMessage>
563 {
564  NS_LOG_FUNCTION (this);
565  if (m_ulDciQueue.at (0).size ()>0)
566  {
567  std::list<UlDciIdealControlMessage> ret = m_ulDciQueue.at (0);
568  m_ulDciQueue.erase (m_ulDciQueue.begin ());
569  std::list<UlDciIdealControlMessage> l;
570  m_ulDciQueue.push_back (l);
571  return (ret);
572  }
573  else
574  {
575  m_ulDciQueue.erase (m_ulDciQueue.begin ());
576  std::list<UlDciIdealControlMessage> l;
577  m_ulDciQueue.push_back (l);
578  std::list<UlDciIdealControlMessage> emptylist;
579  return (emptylist);
580  }
581 }
582 
583 
584 };