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 (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
101void
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
130void
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
148void
150{
151 NS_LOG_FUNCTION(this << *spd);
153 (*m_allSignals) += (*spd);
154}
155
156void
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
172void
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 }
205 }
206}
207
208void
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
227void
229{
230 NS_LOG_FUNCTION(this << p);
231 m_rsPowerChunkProcessorList.push_back(p);
232}
233
234void
236{
237 NS_LOG_FUNCTION(this << p);
238 m_sinrChunkProcessorList.push_back(p);
239}
240
241void
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:444
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:932
#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)