A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
lte-interference.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 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  */
20 
21 
22 #include "lte-interference.h"
24 
25 #include <ns3/simulator.h>
26 #include <ns3/log.h>
27 
28 
29 NS_LOG_COMPONENT_DEFINE ("LteInterference");
30 
31 namespace ns3 {
32 
33 
35  : m_receiving (false),
36  m_lastSignalId (0),
37  m_lastSignalIdBeforeReset (0)
38 {
39  NS_LOG_FUNCTION (this);
40 }
41 
43 {
44  NS_LOG_FUNCTION (this);
45 }
46 
47 void
49 {
50  NS_LOG_FUNCTION (this);
52  m_sinrChunkProcessorList.clear ();
54  m_rxSignal = 0;
55  m_allSignals = 0;
56  m_noise = 0;
58 }
59 
60 
61 TypeId
63 {
64  static TypeId tid = TypeId ("ns3::LteInterference")
65  .SetParent<Object> ()
66  ;
67  return tid;
68 }
69 
70 
71 void
73 {
74  NS_LOG_FUNCTION (this << *rxPsd);
75  if (m_receiving == false)
76  {
77  NS_LOG_LOGIC ("first signal");
78  m_rxSignal = rxPsd->Copy ();
79  m_lastChangeTime = Now ();
80  m_receiving = true;
81  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
82  {
83  (*it)->Start ();
84  }
85  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
86  {
87  (*it)->Start ();
88  }
89  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
90  {
91  (*it)->Start ();
92  }
93  }
94  else
95  {
96  NS_LOG_LOGIC ("additional signal" << *m_rxSignal);
97  // receiving multiple simultaneous signals, make sure they are synchronized
99  // make sure they use orthogonal resource blocks
100  NS_ASSERT (Sum ((*rxPsd) * (*m_rxSignal)) == 0.0);
101  (*m_rxSignal) += (*rxPsd);
102  }
103 }
104 
105 
106 void
108 {
109  NS_LOG_FUNCTION (this);
110  if (m_receiving != true)
111  {
112  NS_LOG_INFO ("EndRx was already evaluated or RX was aborted");
113  }
114  else
115  {
117  m_receiving = false;
118  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
119  {
120  (*it)->End ();
121  }
122  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
123  {
124  (*it)->End ();
125  }
126  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
127  {
128  (*it)->End ();
129  }
130  }
131 }
132 
133 
134 void
136 {
137  NS_LOG_FUNCTION (this << *spd << duration);
138  DoAddSignal (spd);
139  uint32_t signalId = ++m_lastSignalId;
140  if (signalId == m_lastSignalIdBeforeReset)
141  {
142  // This happens when m_lastSignalId eventually wraps around. Given that so
143  // many signals have elapsed since the last reset, we hope that by now there is
144  // no stale pending signal (i.e., a signal that was scheduled
145  // for subtraction before the reset). So we just move the
146  // boundary further.
147  m_lastSignalIdBeforeReset += 0x10000000;
148  }
149  Simulator::Schedule (duration, &LteInterference::DoSubtractSignal, this, spd, signalId);
150 }
151 
152 
153 void
155 {
156  NS_LOG_FUNCTION (this << *spd);
158  (*m_allSignals) += (*spd);
159 }
160 
161 void
163 {
164  NS_LOG_FUNCTION (this << *spd);
166  int32_t deltaSignalId = signalId - m_lastSignalIdBeforeReset;
167  if (deltaSignalId > 0)
168  {
169  (*m_allSignals) -= (*spd);
170  }
171  else
172  {
173  NS_LOG_INFO ("ignoring signal scheduled for subtraction before last reset");
174  }
175 }
176 
177 
178 void
180 {
181  NS_LOG_FUNCTION (this);
182  if (m_receiving)
183  {
184  NS_LOG_DEBUG (this << " Receiving");
185  }
186  NS_LOG_DEBUG (this << " now " << Now () << " last " << m_lastChangeTime);
187  if (m_receiving && (Now () > m_lastChangeTime))
188  {
189  NS_LOG_LOGIC (this << " signal = " << *m_rxSignal << " allSignals = " << *m_allSignals << " noise = " << *m_noise);
190 
191  SpectrumValue interf = (*m_allSignals) - (*m_rxSignal) + (*m_noise);
192 
193  SpectrumValue sinr = (*m_rxSignal) / interf;
194  Time duration = Now () - m_lastChangeTime;
195  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
196  {
197  (*it)->EvaluateSinrChunk (sinr, duration);
198  }
199  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
200  {
201  (*it)->EvaluateSinrChunk (interf, duration);
202  }
203  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
204  {
205  (*it)->EvaluateSinrChunk (*m_rxSignal, duration);
206  }
207  m_lastChangeTime = Now ();
208  }
209 }
210 
211 void
213 {
214  NS_LOG_FUNCTION (this << *noisePsd);
216  m_noise = noisePsd;
217  // reset m_allSignals (will reset if already set previously)
218  // this is needed since this method can potentially change the SpectrumModel
219  m_allSignals = Create<SpectrumValue> (noisePsd->GetSpectrumModel ());
220  if (m_receiving == true)
221  {
222  // abort rx
223  m_receiving = false;
224  }
225  // record the last SignalId so that we can ignore all signals that
226  // were scheduled for subtraction before m_allSignal
228 }
229 
230 void
232 {
233  NS_LOG_FUNCTION (this << p);
234  m_rsPowerChunkProcessorList.push_back (p);
235 }
236 
237 void
239 {
240  NS_LOG_FUNCTION (this << p);
241  m_sinrChunkProcessorList.push_back (p);
242 }
243 
244 void
246 {
247  NS_LOG_FUNCTION (this << p);
248  m_interfChunkProcessorList.push_back (p);
249 }
250 
251 
252 
253 
254 } // namespace ns3
255 
256 
Time m_lastChangeTime
the time of the last change in m_TotalPower
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
std::list< Ptr< LteSinrChunkProcessor > > m_interfChunkProcessorList
all the processor instances that need to be notified whenever a new interference chunk is calculated ...
void AddInterferenceChunkProcessor(Ptr< LteSinrChunkProcessor > p)
Add a LteSinrChunkProcessor that will use the time-vs-frequency interference calculated by this LteIn...
#define NS_ASSERT(condition)
Definition: assert.h:64
Ptr< const SpectrumValue > m_noise
virtual void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
#define NS_LOG_INFO(msg)
Definition: log.h:298
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:824
NS_LOG_COMPONENT_DEFINE("LteInterference")
void AddSinrChunkProcessor(Ptr< LteSinrChunkProcessor > p)
Add a LteSinrChunkProcessor that will use the time-vs-frequency SINR calculated by this LteInterferen...
void DoSubtractSignal(Ptr< const SpectrumValue > spd, uint32_t signalId)
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
static TypeId GetTypeId(void)
#define list
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
void DoAddSignal(Ptr< const SpectrumValue > spd)
void EndRx()
notify that the RX attempt has ended.
uint32_t m_lastSignalIdBeforeReset
void StartRx(Ptr< const SpectrumValue > rxPsd)
notify that the PHY is starting a RX attempt
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
void AddRsPowerChunkProcessor(Ptr< LteSinrChunkProcessor > p)
Add a LteSinrChunkProcessor that will use the time-vs-frequency power calculated by this LteInterfere...
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
void AddSignal(Ptr< const SpectrumValue > spd, const Time duration)
notify that a new signal is being perceived in the medium.
double Sum(const SpectrumValue &x)
Ptr< SpectrumValue > m_rxSignal
stores the power spectral density of the signal whose RX is being attempted
std::list< Ptr< LteSinrChunkProcessor > > m_rsPowerChunkProcessorList
all the processor instances that need to be notified whenever a new interference chunk is calculated ...
std::list< Ptr< LteSinrChunkProcessor > > m_sinrChunkProcessorList
all the processor instances that need to be notified whenever a new SINR chunk is calculated ...
a base class which provides memory management and object aggregation
Definition: object.h:63
Set of values corresponding to a given SpectrumModel.
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
Ptr< SpectrumValue > m_allSignals
stores the spectral power density of the sum of incoming signals; does not include noise...