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)
70  {
71  NS_LOG_LOGIC("first signal");
72  m_rxSignal = rxPsd->Copy();
74  m_receiving = true;
75  for (auto it = m_rsPowerChunkProcessorList.begin(); it != m_rsPowerChunkProcessorList.end();
76  ++it)
77  {
78  (*it)->Start();
79  }
80  for (auto it = m_interfChunkProcessorList.begin(); it != m_interfChunkProcessorList.end();
81  ++it)
82  {
83  (*it)->Start();
84  }
85  for (auto it = m_sinrChunkProcessorList.begin(); it != m_sinrChunkProcessorList.end(); ++it)
86  {
87  (*it)->Start();
88  }
89  }
90  else
91  {
92  NS_LOG_LOGIC("additional signal" << *m_rxSignal);
93  // receiving multiple simultaneous signals, make sure they are synchronized
95  // make sure they use orthogonal resource blocks
96  NS_ASSERT(Sum((*rxPsd) * (*m_rxSignal)) == 0.0);
97  (*m_rxSignal) += (*rxPsd);
98  }
99 }
100 
101 void
103 {
104  NS_LOG_FUNCTION(this);
105  if (!m_receiving)
106  {
107  NS_LOG_INFO("EndRx was already evaluated or RX was aborted");
108  }
109  else
110  {
112  m_receiving = false;
113  for (auto it = m_rsPowerChunkProcessorList.begin(); it != m_rsPowerChunkProcessorList.end();
114  ++it)
115  {
116  (*it)->End();
117  }
118  for (auto it = m_interfChunkProcessorList.begin(); it != m_interfChunkProcessorList.end();
119  ++it)
120  {
121  (*it)->End();
122  }
123  for (auto it = m_sinrChunkProcessorList.begin(); it != m_sinrChunkProcessorList.end(); ++it)
124  {
125  (*it)->End();
126  }
127  }
128 }
129 
130 void
132 {
133  NS_LOG_FUNCTION(this << *spd << duration);
134  DoAddSignal(spd);
135  uint32_t signalId = ++m_lastSignalId;
136  if (signalId == m_lastSignalIdBeforeReset)
137  {
138  // This happens when m_lastSignalId eventually wraps around. Given that so
139  // many signals have elapsed since the last reset, we hope that by now there is
140  // no stale pending signal (i.e., a signal that was scheduled
141  // for subtraction before the reset). So we just move the
142  // boundary further.
143  m_lastSignalIdBeforeReset += 0x10000000;
144  }
145  Simulator::Schedule(duration, &LteInterference::DoSubtractSignal, this, spd, signalId);
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION(this << *spd);
153  (*m_allSignals) += (*spd);
154 }
155 
156 void
158 {
159  NS_LOG_FUNCTION(this << *spd);
161  int32_t deltaSignalId = signalId - m_lastSignalIdBeforeReset;
162  if (deltaSignalId > 0)
163  {
164  (*m_allSignals) -= (*spd);
165  }
166  else
167  {
168  NS_LOG_INFO("ignoring signal scheduled for subtraction before last reset");
169  }
170 }
171 
172 void
174 {
175  NS_LOG_FUNCTION(this);
176  if (m_receiving)
177  {
178  NS_LOG_DEBUG(this << " Receiving");
179  }
180  NS_LOG_DEBUG(this << " now " << Now() << " last " << m_lastChangeTime);
181  if (m_receiving && (Now() > m_lastChangeTime))
182  {
183  NS_LOG_LOGIC(this << " signal = " << *m_rxSignal << " allSignals = " << *m_allSignals
184  << " noise = " << *m_noise);
185 
186  SpectrumValue interf = (*m_allSignals) - (*m_rxSignal) + (*m_noise);
187 
188  SpectrumValue sinr = (*m_rxSignal) / interf;
189  Time duration = Now() - m_lastChangeTime;
190  for (auto it = m_sinrChunkProcessorList.begin(); it != m_sinrChunkProcessorList.end(); ++it)
191  {
192  (*it)->EvaluateChunk(sinr, duration);
193  }
194  for (auto it = m_interfChunkProcessorList.begin(); it != m_interfChunkProcessorList.end();
195  ++it)
196  {
197  (*it)->EvaluateChunk(interf, duration);
198  }
199  for (auto it = m_rsPowerChunkProcessorList.begin(); it != m_rsPowerChunkProcessorList.end();
200  ++it)
201  {
202  (*it)->EvaluateChunk(*m_rxSignal, duration);
203  }
204  m_lastChangeTime = Now();
205  }
206 }
207 
208 void
210 {
211  NS_LOG_FUNCTION(this << *noisePsd);
213  m_noise = noisePsd;
214  // reset m_allSignals (will reset if already set previously)
215  // this is needed since this method can potentially change the SpectrumModel
216  m_allSignals = Create<SpectrumValue>(noisePsd->GetSpectrumModel());
217  if (m_receiving)
218  {
219  // abort rx
220  m_receiving = false;
221  }
222  // record the last SignalId so that we can ignore all signals that
223  // were scheduled for subtraction before m_allSignal
225 }
226 
227 void
229 {
230  NS_LOG_FUNCTION(this << p);
231  m_rsPowerChunkProcessorList.push_back(p);
232 }
233 
234 void
236 {
237  NS_LOG_FUNCTION(this << p);
238  m_sinrChunkProcessorList.push_back(p);
239 }
240 
241 void
243 {
244  NS_LOG_FUNCTION(this << p);
245  m_interfChunkProcessorList.push_back(p);
246 }
247 
248 } // 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:352
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#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:305
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Sum(const SpectrumValue &x)