A Discrete-Event Network Simulator
API
lte-interference.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 CTTC
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Nicola Baldo <nbaldo@cttc.es>
18  */
19 
20 #include "lte-interference.h"
21 
22 #include "lte-chunk-processor.h"
23 
24 #include <ns3/log.h>
25 #include <ns3/simulator.h>
26 
27 namespace ns3
28 {
29 
30 NS_LOG_COMPONENT_DEFINE("LteInterference");
31 
33  : m_receiving(false),
34  m_lastSignalId(0),
35  m_lastSignalIdBeforeReset(0)
36 {
37  NS_LOG_FUNCTION(this);
38 }
39 
41 {
42  NS_LOG_FUNCTION(this);
43 }
44 
45 void
47 {
48  NS_LOG_FUNCTION(this);
52  m_rxSignal = nullptr;
53  m_allSignals = nullptr;
54  m_noise = nullptr;
56 }
57 
58 TypeId
60 {
61  static TypeId tid = TypeId("ns3::LteInterference").SetParent<Object>().SetGroupName("Lte");
62  return tid;
63 }
64 
65 void
67 {
68  NS_LOG_FUNCTION(this << *rxPsd);
69  if (m_receiving == false)
70  {
71  NS_LOG_LOGIC("first signal");
72  m_rxSignal = rxPsd->Copy();
74  m_receiving = true;
75  for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
77  it != m_rsPowerChunkProcessorList.end();
78  ++it)
79  {
80  (*it)->Start();
81  }
82  for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
84  it != m_interfChunkProcessorList.end();
85  ++it)
86  {
87  (*it)->Start();
88  }
89  for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
91  it != m_sinrChunkProcessorList.end();
92  ++it)
93  {
94  (*it)->Start();
95  }
96  }
97  else
98  {
99  NS_LOG_LOGIC("additional signal" << *m_rxSignal);
100  // receiving multiple simultaneous signals, make sure they are synchronized
102  // make sure they use orthogonal resource blocks
103  NS_ASSERT(Sum((*rxPsd) * (*m_rxSignal)) == 0.0);
104  (*m_rxSignal) += (*rxPsd);
105  }
106 }
107 
108 void
110 {
111  NS_LOG_FUNCTION(this);
112  if (m_receiving != true)
113  {
114  NS_LOG_INFO("EndRx was already evaluated or RX was aborted");
115  }
116  else
117  {
119  m_receiving = false;
120  for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
122  it != m_rsPowerChunkProcessorList.end();
123  ++it)
124  {
125  (*it)->End();
126  }
127  for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
129  it != m_interfChunkProcessorList.end();
130  ++it)
131  {
132  (*it)->End();
133  }
134  for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
135  m_sinrChunkProcessorList.begin();
136  it != m_sinrChunkProcessorList.end();
137  ++it)
138  {
139  (*it)->End();
140  }
141  }
142 }
143 
144 void
146 {
147  NS_LOG_FUNCTION(this << *spd << duration);
148  DoAddSignal(spd);
149  uint32_t signalId = ++m_lastSignalId;
150  if (signalId == m_lastSignalIdBeforeReset)
151  {
152  // This happens when m_lastSignalId eventually wraps around. Given that so
153  // many signals have elapsed since the last reset, we hope that by now there is
154  // no stale pending signal (i.e., a signal that was scheduled
155  // for subtraction before the reset). So we just move the
156  // boundary further.
157  m_lastSignalIdBeforeReset += 0x10000000;
158  }
159  Simulator::Schedule(duration, &LteInterference::DoSubtractSignal, this, spd, signalId);
160 }
161 
162 void
164 {
165  NS_LOG_FUNCTION(this << *spd);
167  (*m_allSignals) += (*spd);
168 }
169 
170 void
172 {
173  NS_LOG_FUNCTION(this << *spd);
175  int32_t deltaSignalId = signalId - m_lastSignalIdBeforeReset;
176  if (deltaSignalId > 0)
177  {
178  (*m_allSignals) -= (*spd);
179  }
180  else
181  {
182  NS_LOG_INFO("ignoring signal scheduled for subtraction before last reset");
183  }
184 }
185 
186 void
188 {
189  NS_LOG_FUNCTION(this);
190  if (m_receiving)
191  {
192  NS_LOG_DEBUG(this << " Receiving");
193  }
194  NS_LOG_DEBUG(this << " now " << Now() << " last " << m_lastChangeTime);
195  if (m_receiving && (Now() > m_lastChangeTime))
196  {
197  NS_LOG_LOGIC(this << " signal = " << *m_rxSignal << " allSignals = " << *m_allSignals
198  << " noise = " << *m_noise);
199 
200  SpectrumValue interf = (*m_allSignals) - (*m_rxSignal) + (*m_noise);
201 
202  SpectrumValue sinr = (*m_rxSignal) / interf;
203  Time duration = Now() - m_lastChangeTime;
204  for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
205  m_sinrChunkProcessorList.begin();
206  it != m_sinrChunkProcessorList.end();
207  ++it)
208  {
209  (*it)->EvaluateChunk(sinr, duration);
210  }
211  for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
213  it != m_interfChunkProcessorList.end();
214  ++it)
215  {
216  (*it)->EvaluateChunk(interf, duration);
217  }
218  for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
220  it != m_rsPowerChunkProcessorList.end();
221  ++it)
222  {
223  (*it)->EvaluateChunk(*m_rxSignal, duration);
224  }
225  m_lastChangeTime = Now();
226  }
227 }
228 
229 void
231 {
232  NS_LOG_FUNCTION(this << *noisePsd);
234  m_noise = noisePsd;
235  // reset m_allSignals (will reset if already set previously)
236  // this is needed since this method can potentially change the SpectrumModel
237  m_allSignals = Create<SpectrumValue>(noisePsd->GetSpectrumModel());
238  if (m_receiving == true)
239  {
240  // abort rx
241  m_receiving = false;
242  }
243  // record the last SignalId so that we can ignore all signals that
244  // were scheduled for subtraction before m_allSignal
246 }
247 
248 void
250 {
251  NS_LOG_FUNCTION(this << p);
252  m_rsPowerChunkProcessorList.push_back(p);
253 }
254 
255 void
257 {
258  NS_LOG_FUNCTION(this << p);
259  m_sinrChunkProcessorList.push_back(p);
260 }
261 
262 void
264 {
265  NS_LOG_FUNCTION(this << p);
266  m_interfChunkProcessorList.push_back(p);
267 }
268 
269 } // namespace ns3
static TypeId GetTypeId()
Get the type ID.
virtual void DoSubtractSignal(Ptr< const SpectrumValue > spd, uint32_t signalId)
Subtract signal.
Ptr< SpectrumValue > m_rxSignal
stores the power spectral density of the signal whose RX is being attempted
bool m_receiving
are we receiving?
virtual void AddSinrChunkProcessor(Ptr< LteChunkProcessor > p)
Add a LteChunkProcessor that will use the time-vs-frequency SINR calculated by this LteInterference i...
virtual void ConditionallyEvaluateChunk()
Conditionally evaluate chunk.
virtual void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
Ptr< SpectrumValue > m_allSignals
stores the spectral power density of the sum of incoming signals; does not include noise,...
virtual void EndRx()
notify that the RX attempt has ended.
uint32_t m_lastSignalIdBeforeReset
the last signal ID before reset
std::list< Ptr< LteChunkProcessor > > m_rsPowerChunkProcessorList
all the processor instances that need to be notified whenever a new interference chunk is calculated
virtual void AddSignal(Ptr< const SpectrumValue > spd, const Time duration)
notify that a new signal is being perceived in the medium.
virtual void AddInterferenceChunkProcessor(Ptr< LteChunkProcessor > p)
Add a LteChunkProcessor that will use the time-vs-frequency interference calculated by this LteInterf...
Ptr< const SpectrumValue > m_noise
the noise value
virtual void AddRsPowerChunkProcessor(Ptr< LteChunkProcessor > p)
Add a LteChunkProcessor that will use the time-vs-frequency power calculated by this LteInterference ...
Time m_lastChangeTime
the time of the last change in m_TotalPower
std::list< Ptr< LteChunkProcessor > > m_interfChunkProcessorList
all the processor instances that need to be notified whenever a new interference chunk is calculated
virtual void StartRx(Ptr< const SpectrumValue > rxPsd)
Notify that the PHY is starting a RX attempt.
void DoDispose() override
Destructor implementation.
uint32_t m_lastSignalId
the last signal ID
std::list< Ptr< LteChunkProcessor > > m_sinrChunkProcessorList
all the processor instances that need to be notified whenever a new SINR chunk is calculated
virtual void DoAddSignal(Ptr< const SpectrumValue > spd)
Add signal function.
A base class which provides memory management and object aggregation.
Definition: object.h:89
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
Set of values corresponding to a given SpectrumModel.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Sum(const SpectrumValue &x)
#define list