A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
27namespace ns3
28{
29
30NS_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
45void
47{
48 NS_LOG_FUNCTION(this);
52 m_rxSignal = nullptr;
53 m_allSignals = nullptr;
54 m_noise = nullptr;
56}
57
60{
61 static TypeId tid = TypeId("ns3::LteInterference").SetParent<Object>().SetGroupName("Lte");
62 return tid;
63}
64
65void
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 (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
78 ++it)
79 {
80 (*it)->Start();
81 }
82 for (std::list<Ptr<LteChunkProcessor>>::const_iterator it =
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
108void
110{
111 NS_LOG_FUNCTION(this);
112 if (!m_receiving)
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 =
136 it != m_sinrChunkProcessorList.end();
137 ++it)
138 {
139 (*it)->End();
140 }
141 }
142}
143
144void
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
162void
164{
165 NS_LOG_FUNCTION(this << *spd);
167 (*m_allSignals) += (*spd);
168}
169
170void
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
186void
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 =
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 }
226 }
227}
228
229void
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)
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
248void
250{
251 NS_LOG_FUNCTION(this << p);
252 m_rsPowerChunkProcessorList.push_back(p);
253}
254
255void
257{
258 NS_LOG_FUNCTION(this << p);
259 m_sinrChunkProcessorList.push_back(p);
260}
261
262void
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
#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)