A Discrete-Event Network Simulator
API
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"
23#include "lte-chunk-processor.h"
24
25#include <ns3/simulator.h>
26#include <ns3/log.h>
27
28
29namespace ns3 {
30
31NS_LOG_COMPONENT_DEFINE ("LteInterference");
32
34 : m_receiving (false),
35 m_lastSignalId (0),
36 m_lastSignalIdBeforeReset (0)
37{
38 NS_LOG_FUNCTION (this);
39}
40
42{
43 NS_LOG_FUNCTION (this);
44}
45
46void
48{
49 NS_LOG_FUNCTION (this);
53 m_rxSignal = 0;
54 m_allSignals = 0;
55 m_noise = 0;
57}
58
59
62{
63 static TypeId tid = TypeId ("ns3::LteInterference")
64 .SetParent<Object> ()
65 .SetGroupName("Lte")
66 ;
67 return tid;
68}
69
70
71void
73{
74 NS_LOG_FUNCTION (this << *rxPsd);
75 if (m_receiving == false)
76 {
77 NS_LOG_LOGIC ("first signal");
78 m_rxSignal = rxPsd->Copy ();
80 m_receiving = true;
81 for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
82 {
83 (*it)->Start ();
84 }
85 for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
86 {
87 (*it)->Start ();
88 }
89 for (std::list<Ptr<LteChunkProcessor> >::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
106void
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<LteChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
119 {
120 (*it)->End ();
121 }
122 for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
123 {
124 (*it)->End ();
125 }
126 for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
127 {
128 (*it)->End ();
129 }
130 }
131}
132
133
134void
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
153void
155{
156 NS_LOG_FUNCTION (this << *spd);
158 (*m_allSignals) += (*spd);
159}
160
161void
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
178void
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<LteChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
196 {
197 (*it)->EvaluateChunk (sinr, duration);
198 }
199 for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
200 {
201 (*it)->EvaluateChunk (interf, duration);
202 }
203 for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
204 {
205 (*it)->EvaluateChunk (*m_rxSignal, duration);
206 }
208 }
209}
210
211void
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
230void
232{
233 NS_LOG_FUNCTION (this << p);
234 m_rsPowerChunkProcessorList.push_back (p);
235}
236
237void
239{
240 NS_LOG_FUNCTION (this << p);
241 m_sinrChunkProcessorList.push_back (p);
242}
243
244void
246{
247 NS_LOG_FUNCTION (this << p);
248 m_interfChunkProcessorList.push_back (p);
249}
250
251
252
253
254} // namespace ns3
255
256
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
static TypeId GetTypeId(void)
Get the type ID.
virtual void DoDispose()
Destructor implementation.
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.
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:88
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
Set of values corresponding to a given SpectrumModel.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:281
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Sum(const SpectrumValue &x)
#define list