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 
29 namespace ns3 {
30 
31 NS_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 
46 void
48 {
49  NS_LOG_FUNCTION (this);
51  m_sinrChunkProcessorList.clear ();
53  m_rxSignal = 0;
54  m_allSignals = 0;
55  m_noise = 0;
57 }
58 
59 
60 TypeId
62 {
63  static TypeId tid = TypeId ("ns3::LteInterference")
64  .SetParent<Object> ()
65  ;
66  return tid;
67 }
68 
69 
70 void
72 {
73  NS_LOG_FUNCTION (this << *rxPsd);
74  if (m_receiving == false)
75  {
76  NS_LOG_LOGIC ("first signal");
77  m_rxSignal = rxPsd->Copy ();
78  m_lastChangeTime = Now ();
79  m_receiving = true;
80  for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
81  {
82  (*it)->Start ();
83  }
84  for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
85  {
86  (*it)->Start ();
87  }
88  for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
89  {
90  (*it)->Start ();
91  }
92  }
93  else
94  {
95  NS_LOG_LOGIC ("additional signal" << *m_rxSignal);
96  // receiving multiple simultaneous signals, make sure they are synchronized
98  // make sure they use orthogonal resource blocks
99  NS_ASSERT (Sum ((*rxPsd) * (*m_rxSignal)) == 0.0);
100  (*m_rxSignal) += (*rxPsd);
101  }
102 }
103 
104 
105 void
107 {
108  NS_LOG_FUNCTION (this);
109  if (m_receiving != true)
110  {
111  NS_LOG_INFO ("EndRx was already evaluated or RX was aborted");
112  }
113  else
114  {
116  m_receiving = false;
117  for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
118  {
119  (*it)->End ();
120  }
121  for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
122  {
123  (*it)->End ();
124  }
125  for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
126  {
127  (*it)->End ();
128  }
129  }
130 }
131 
132 
133 void
135 {
136  NS_LOG_FUNCTION (this << *spd << duration);
137  DoAddSignal (spd);
138  uint32_t signalId = ++m_lastSignalId;
139  if (signalId == m_lastSignalIdBeforeReset)
140  {
141  // This happens when m_lastSignalId eventually wraps around. Given that so
142  // many signals have elapsed since the last reset, we hope that by now there is
143  // no stale pending signal (i.e., a signal that was scheduled
144  // for subtraction before the reset). So we just move the
145  // boundary further.
146  m_lastSignalIdBeforeReset += 0x10000000;
147  }
148  Simulator::Schedule (duration, &LteInterference::DoSubtractSignal, this, spd, signalId);
149 }
150 
151 
152 void
154 {
155  NS_LOG_FUNCTION (this << *spd);
157  (*m_allSignals) += (*spd);
158 }
159 
160 void
162 {
163  NS_LOG_FUNCTION (this << *spd);
165  int32_t deltaSignalId = signalId - m_lastSignalIdBeforeReset;
166  if (deltaSignalId > 0)
167  {
168  (*m_allSignals) -= (*spd);
169  }
170  else
171  {
172  NS_LOG_INFO ("ignoring signal scheduled for subtraction before last reset");
173  }
174 }
175 
176 
177 void
179 {
180  NS_LOG_FUNCTION (this);
181  if (m_receiving)
182  {
183  NS_LOG_DEBUG (this << " Receiving");
184  }
185  NS_LOG_DEBUG (this << " now " << Now () << " last " << m_lastChangeTime);
186  if (m_receiving && (Now () > m_lastChangeTime))
187  {
188  NS_LOG_LOGIC (this << " signal = " << *m_rxSignal << " allSignals = " << *m_allSignals << " noise = " << *m_noise);
189 
190  SpectrumValue interf = (*m_allSignals) - (*m_rxSignal) + (*m_noise);
191 
192  SpectrumValue sinr = (*m_rxSignal) / interf;
193  Time duration = Now () - m_lastChangeTime;
194  for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
195  {
196  (*it)->EvaluateChunk (sinr, duration);
197  }
198  for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
199  {
200  (*it)->EvaluateChunk (interf, duration);
201  }
202  for (std::list<Ptr<LteChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
203  {
204  (*it)->EvaluateChunk (*m_rxSignal, duration);
205  }
206  m_lastChangeTime = Now ();
207  }
208 }
209 
210 void
212 {
213  NS_LOG_FUNCTION (this << *noisePsd);
215  m_noise = noisePsd;
216  // reset m_allSignals (will reset if already set previously)
217  // this is needed since this method can potentially change the SpectrumModel
218  m_allSignals = Create<SpectrumValue> (noisePsd->GetSpectrumModel ());
219  if (m_receiving == true)
220  {
221  // abort rx
222  m_receiving = false;
223  }
224  // record the last SignalId so that we can ignore all signals that
225  // were scheduled for subtraction before m_allSignal
227 }
228 
229 void
231 {
232  NS_LOG_FUNCTION (this << p);
233  m_rsPowerChunkProcessorList.push_back (p);
234 }
235 
236 void
238 {
239  NS_LOG_FUNCTION (this << p);
240  m_sinrChunkProcessorList.push_back (p);
241 }
242 
243 void
245 {
246  NS_LOG_FUNCTION (this << p);
247  m_interfChunkProcessorList.push_back (p);
248 }
249 
250 
251 
252 
253 } // namespace ns3
254 
255 
Time m_lastChangeTime
the time of the last change in m_TotalPower
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Ptr< const SpectrumValue > m_noise
virtual void DoDispose()
Destructor implementation.
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:338
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:819
void AddSinrChunkProcessor(Ptr< LteChunkProcessor > p)
Add a LteChunkProcessor that will use the time-vs-frequency SINR calculated by this LteInterference i...
std::list< Ptr< LteChunkProcessor > > m_sinrChunkProcessorList
all the processor instances that need to be notified whenever a new SINR chunk is calculated ...
void AddRsPowerChunkProcessor(Ptr< LteChunkProcessor > p)
Add a LteChunkProcessor that will use the time-vs-frequency power calculated by this LteInterference ...
void DoSubtractSignal(Ptr< const SpectrumValue > spd, uint32_t signalId)
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
static TypeId GetTypeId(void)
#define list
std::list< Ptr< LteChunkProcessor > > m_rsPowerChunkProcessorList
all the processor instances that need to be notified whenever a new interference chunk is calculated ...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void AddInterferenceChunkProcessor(Ptr< LteChunkProcessor > p)
Add a LteChunkProcessor that will use the time-vs-frequency interference calculated by this LteInterf...
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
void DoAddSignal(Ptr< const SpectrumValue > spd)
std::list< Ptr< LteChunkProcessor > > m_interfChunkProcessorList
all the processor instances that need to be notified whenever a new interference chunk is calculated ...
void EndRx()
notify that the RX attempt has ended.
uint32_t m_lastSignalIdBeforeReset
void StartRx(Ptr< const SpectrumValue > rxPsd)
notify that the PHY is starting a RX attempt
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
void AddSignal(Ptr< const SpectrumValue > spd, const Time duration)
notify that a new signal is being perceived in the medium.
double Sum(const SpectrumValue &x)
Ptr< SpectrumValue > m_rxSignal
stores the power spectral density of the signal whose RX is being attempted
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:330
A base class which provides memory management and object aggregation.
Definition: object.h:87
Set of values corresponding to a given SpectrumModel.
a unique identifier for an interface.
Definition: type-id.h:51
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
Ptr< SpectrumValue > m_allSignals
stores the spectral power density of the sum of incoming signals; does not include noise...