A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lte-interference.cc
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-sinr-chunk-processor.h"
24 
25 #include <ns3/simulator.h>
26 #include <ns3/log.h>
27 
28 
29 NS_LOG_COMPONENT_DEFINE ("LteInterference");
30 
31 namespace ns3 {
32 
33 
34 LteInterference::LteInterference ()
35  : m_receiving (false),
36  m_lastSignalId (0),
37  m_lastSignalIdBeforeReset (0)
38 {
39  NS_LOG_FUNCTION (this);
40 }
41 
42 LteInterference::~LteInterference ()
43 {
44  NS_LOG_FUNCTION (this);
45 }
46 
47 void
49 {
50  NS_LOG_FUNCTION (this);
52  m_sinrChunkProcessorList.clear ();
54  m_rxSignal = 0;
55  m_allSignals = 0;
56  m_noise = 0;
58 }
59 
60 
61 TypeId
62 LteInterference::GetTypeId (void)
63 {
64  static TypeId tid = TypeId ("ns3::LteInterference")
65  .SetParent<Object> ()
66  ;
67  return tid;
68 }
69 
70 
71 void
73 {
74  NS_LOG_FUNCTION (this << *rxPsd);
75  if (m_receiving == false)
76  {
77  NS_LOG_LOGIC ("first signal");
78  m_rxSignal = rxPsd->Copy ();
79  m_lastChangeTime = Now ();
80  m_receiving = true;
81  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
82  {
83  (*it)->Start ();
84  }
85  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
86  {
87  (*it)->Start ();
88  }
89  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.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 
106 void
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  {
116  ConditionallyEvaluateChunk ();
117  m_receiving = false;
118  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
119  {
120  (*it)->End ();
121  }
122  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
123  {
124  (*it)->End ();
125  }
126  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
127  {
128  (*it)->End ();
129  }
130  }
131 }
132 
133 
134 void
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 
153 void
154 LteInterference::DoAddSignal (Ptr<const SpectrumValue> spd)
155 {
156  NS_LOG_FUNCTION (this << *spd);
157  ConditionallyEvaluateChunk ();
158  (*m_allSignals) += (*spd);
159 }
160 
161 void
162 LteInterference::DoSubtractSignal (Ptr<const SpectrumValue> spd, uint32_t signalId)
163 {
164  NS_LOG_FUNCTION (this << *spd);
165  ConditionallyEvaluateChunk ();
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 
178 void
179 LteInterference::ConditionallyEvaluateChunk ()
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<LteSinrChunkProcessor> >::const_iterator it = m_sinrChunkProcessorList.begin (); it != m_sinrChunkProcessorList.end (); ++it)
196  {
197  (*it)->EvaluateSinrChunk (sinr, duration);
198  }
199  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_rsPowerChunkProcessorList.begin (); it != m_rsPowerChunkProcessorList.end (); ++it)
200  {
201  (*it)->EvaluateSinrChunk (*m_rxSignal, duration);
202  }
203  for (std::list<Ptr<LteSinrChunkProcessor> >::const_iterator it = m_interfChunkProcessorList.begin (); it != m_interfChunkProcessorList.end (); ++it)
204  {
205  NS_LOG_DEBUG (this << "ConditionallyEvaluateChunk INTERF ");
206  (*it)->EvaluateSinrChunk (interf, duration);
207  }
208  m_lastChangeTime = Now ();
209  }
210  else
211  {
212  NS_LOG_DEBUG (this << " NO EV");
213  }
214 }
215 
216 void
218 {
219  NS_LOG_FUNCTION (this << *noisePsd);
220  ConditionallyEvaluateChunk ();
221  m_noise = noisePsd;
222  // reset m_allSignals (will reset if already set previously)
223  // this is needed since this method can potentially change the SpectrumModel
224  m_allSignals = Create<SpectrumValue> (noisePsd->GetSpectrumModel ());
225  if (m_receiving == true)
226  {
227  // abort rx
228  m_receiving = false;
229  }
230  // record the last SignalId so that we can ignore all signals that
231  // were scheduled for subtraction before m_allSignal
232  m_lastSignalIdBeforeReset = m_lastSignalId;
233 }
234 
235 void
237 {
238  NS_LOG_FUNCTION (this << p);
239  m_rsPowerChunkProcessorList.push_back (p);
240 }
241 
242 void
244 {
245  NS_LOG_FUNCTION (this << p);
246  m_sinrChunkProcessorList.push_back (p);
247 }
248 
249 void
251 {
252  NS_LOG_FUNCTION (this << p);
253  m_interfChunkProcessorList.push_back (p);
254 }
255 
256 
257 
258 
259 } // namespace ns3
260 
261 
keep track of time unit.
Definition: nstime.h:149
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
std::list< Ptr< LteSinrChunkProcessor > > m_interfChunkProcessorList
void AddInterferenceChunkProcessor(Ptr< LteSinrChunkProcessor > p)
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void DoDispose()
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_INFO(msg)
Definition: log.h:264
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
void AddSinrChunkProcessor(Ptr< LteSinrChunkProcessor > p)
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
void SetNoisePowerSpectralDensity(Ptr< const SpectrumValue > noisePsd)
void StartRx(Ptr< const SpectrumValue > rxPsd)
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:286
void AddRsPowerChunkProcessor(Ptr< LteSinrChunkProcessor > p)
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void AddSignal(Ptr< const SpectrumValue > spd, const Time duration)
double Sum(const SpectrumValue &x)
Ptr< SpectrumValue > m_rxSignal
std::list< Ptr< LteSinrChunkProcessor > > m_rsPowerChunkProcessorList
std::list< Ptr< LteSinrChunkProcessor > > m_sinrChunkProcessorList
a base class which provides memory management and object aggregation
Definition: object.h:63
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
Ptr< SpectrumValue > m_allSignals