00001
00002
00003 #include "interference-helper.h"
00004 #include "wifi-phy.h"
00005 #include "error-rate-model.h"
00006 #include "ns3/simulator.h"
00007 #include "ns3/log.h"
00008 #include <algorithm>
00009
00010 NS_LOG_COMPONENT_DEFINE ("InterferenceHelper");
00011
00012 namespace ns3 {
00013
00014
00015
00016
00017
00018 InterferenceHelper::Event::Event (uint32_t size, WifiMode payloadMode,
00019 enum WifiPreamble preamble,
00020 Time duration, double rxPower)
00021 : m_size (size),
00022 m_payloadMode (payloadMode),
00023 m_preamble (preamble),
00024 m_startTime (Simulator::Now ()),
00025 m_endTime (m_startTime + duration),
00026 m_rxPowerW (rxPower)
00027 {}
00028 InterferenceHelper::Event::~Event ()
00029 {}
00030
00031 Time
00032 InterferenceHelper::Event::GetDuration (void) const
00033 {
00034 return m_endTime - m_startTime;
00035 }
00036 Time
00037 InterferenceHelper::Event::GetStartTime (void) const
00038 {
00039 return m_startTime;
00040 }
00041 Time
00042 InterferenceHelper::Event::GetEndTime (void) const
00043 {
00044 return m_endTime;
00045 }
00046 bool
00047 InterferenceHelper::Event::Overlaps (Time time) const
00048 {
00049 if (m_startTime <= time &&
00050 m_endTime >= time)
00051 {
00052 return true;
00053 }
00054 else
00055 {
00056 return false;
00057 }
00058 }
00059 double
00060 InterferenceHelper::Event::GetRxPowerW (void) const
00061 {
00062 return m_rxPowerW;
00063 }
00064 uint32_t
00065 InterferenceHelper::Event::GetSize (void) const
00066 {
00067 return m_size;
00068 }
00069 WifiMode
00070 InterferenceHelper::Event::GetPayloadMode (void) const
00071 {
00072 return m_payloadMode;
00073 }
00074 enum WifiPreamble
00075 InterferenceHelper::Event::GetPreambleType (void) const
00076 {
00077 return m_preamble;
00078 }
00079
00080
00081
00082
00083
00084
00085 InterferenceHelper::NiChange::NiChange (Time time, double delta)
00086 : m_time (time), m_delta (delta)
00087 {}
00088 Time
00089 InterferenceHelper::NiChange::GetTime (void) const
00090 {
00091 return m_time;
00092 }
00093 double
00094 InterferenceHelper::NiChange::GetDelta (void) const
00095 {
00096 return m_delta;
00097 }
00098 bool
00099 InterferenceHelper::NiChange::operator < (InterferenceHelper::NiChange const &o) const
00100 {
00101 return (m_time < o.m_time)?true:false;
00102 }
00103
00104
00105
00106
00107
00108 InterferenceHelper::InterferenceHelper ()
00109 : m_useConstantNoiseFloor (false),
00110 m_80211a (false),
00111 m_errorRateModel (0)
00112 {}
00113 InterferenceHelper::~InterferenceHelper ()
00114 {
00115 m_errorRateModel = 0;
00116 }
00117
00118 Ptr<InterferenceHelper::Event>
00119 InterferenceHelper::Add (uint32_t size, WifiMode payloadMode,
00120 enum WifiPreamble preamble,
00121 Time duration, double rxPowerW)
00122 {
00123 Ptr<InterferenceHelper::Event> event;
00124
00125 event = Create<InterferenceHelper::Event>
00126 (size,
00127 payloadMode,
00128 preamble,
00129 duration,
00130 rxPowerW);
00131
00132 AppendEvent (event);
00133 return event;
00134 }
00135
00136 Time
00137 InterferenceHelper::GetMaxPacketDuration (void) const
00138 {
00139 return m_maxPacketDuration;
00140 }
00141
00142 void
00143 InterferenceHelper::SetUseConstantNoiseFloor (bool value)
00144 {
00145 m_useConstantNoiseFloor = value;
00146 }
00147
00148 bool
00149 InterferenceHelper::GetUseConstantNoiseFloor () const
00150 {
00151 return m_useConstantNoiseFloor;
00152 }
00153
00154 void
00155 InterferenceHelper::SetConstantNoiseFloorW (double constantNoiseFloorW)
00156 {
00157 m_constantNoiseFloorW = constantNoiseFloorW;
00158 }
00159 double
00160 InterferenceHelper::GetConstantNoiseFloorW (void) const
00161 {
00162 return m_constantNoiseFloorW;
00163 }
00164
00165 void
00166 InterferenceHelper::SetRxNoiseRatio (double rxNoiseRatio)
00167 {
00168 m_rxNoiseRatio = rxNoiseRatio;
00169 }
00170 double
00171 InterferenceHelper::GetRxNoiseRatio (void) const
00172 {
00173 return m_rxNoiseRatio;
00174 }
00175
00176 void
00177 InterferenceHelper::SetErrorRateModel (Ptr<ErrorRateModel> rate)
00178 {
00179 m_errorRateModel = rate;
00180 }
00181
00182 Ptr<ErrorRateModel>
00183 InterferenceHelper::GetErrorRateModel (void) const
00184 {
00185 return m_errorRateModel;
00186 }
00187
00188 Time
00189 InterferenceHelper::GetEnergyDuration (double energyW)
00190 {
00191 Time now = Simulator::Now ();
00192
00193
00194
00195
00196 Events::const_iterator i = m_events.begin ();
00197 double noiseInterferenceW = 0.0;
00198 NiChanges ni;
00199 while (i != m_events.end ())
00200 {
00201 Ptr<Event> ev = *i;
00202 NS_ASSERT (ev->GetStartTime () <= now);
00203 if (ev->GetEndTime () > now)
00204 {
00205 ni.push_back (NiChange (ev->GetEndTime (), -ev->GetRxPowerW ()));
00206 noiseInterferenceW += ev->GetRxPowerW ();
00207 }
00208 i++;
00209 }
00210 if (noiseInterferenceW < energyW)
00211 {
00212 return MicroSeconds (0);
00213 }
00214
00215
00216
00217 std::sort (ni.begin (), ni.end (), std::less<NiChange> ());
00218
00219
00220 Time end = now;
00221 for (NiChanges::const_iterator i = ni.begin (); i != ni.end (); i++)
00222 {
00223 noiseInterferenceW += i->GetDelta ();
00224 end = i->GetTime ();
00225 if (noiseInterferenceW < energyW)
00226 {
00227 break;
00228 }
00229 }
00230 return end - now;
00231 }
00232
00233 Time
00234 InterferenceHelper::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble) const
00235 {
00236 NS_ASSERT (m_80211a);
00237 uint64_t delay = 0;
00238 delay += m_plcpLongPreambleDelayUs;
00239
00240 delay += 4;
00241 delay += lrint (ceil ((size * 8.0 + 16.0 + 6.0) / payloadMode.GetDataRate () / 4e-6) * 4);
00242 return MicroSeconds (delay);
00243 }
00244
00245 void
00246 InterferenceHelper::Configure80211aParameters (void)
00247 {
00248 NS_LOG_FUNCTION (this);
00249 m_80211a = true;
00250 m_plcpLongPreambleDelayUs = 16;
00251 m_plcpShortPreambleDelayUs = 16;
00252 m_longPlcpHeaderMode = WifiPhy::Get6mba ();
00253 m_shortPlcpHeaderMode = WifiPhy::Get6mba ();
00254 m_plcpHeaderLength = 4 + 1 + 12 + 1 + 6;
00255
00256 m_maxPacketDuration = CalculateTxDuration (4095, WifiPhy::Get6mba (), WIFI_PREAMBLE_LONG);
00257 }
00258
00259 void
00260 InterferenceHelper::AppendEvent (Ptr<InterferenceHelper::Event> event)
00261 {
00262
00263
00264
00265
00266
00267
00268 if (Simulator::Now () > GetMaxPacketDuration ())
00269 {
00270 Time end = Simulator::Now () - GetMaxPacketDuration ();
00271 Events::iterator i = m_events.begin ();
00272 while (i != m_events.end () &&
00273 (*i)->GetEndTime () <= end)
00274 {
00275 i++;
00276 }
00277 m_events.erase (m_events.begin (), i);
00278 }
00279 m_events.push_back (event);
00280 }
00281
00282
00283 double
00284 InterferenceHelper::CalculateSnr (double signal, double noiseInterference, WifiMode mode) const
00285 {
00286 double noiseFloorW = m_constantNoiseFloorW;
00287
00288 if (!m_useConstantNoiseFloor)
00289 {
00290
00291
00292
00293 static const double BOLTZMANN = 1.3803e-23;
00294 double Nt = BOLTZMANN * 290.0 * mode.GetBandwidth ();
00295
00296 noiseFloorW = m_rxNoiseRatio * Nt;
00297 }
00298
00299 double noise = noiseFloorW + noiseInterference;
00300 double snr = signal / noise;
00301 return snr;
00302 }
00303
00304 double
00305 InterferenceHelper::CalculateNoiseInterferenceW (Ptr<InterferenceHelper::Event> event, NiChanges *ni) const
00306 {
00307 Events::const_iterator i = m_events.begin ();
00308 double noiseInterference = 0.0;
00309 while (i != m_events.end ())
00310 {
00311 if (event == (*i))
00312 {
00313 i++;
00314 continue;
00315 }
00316 if (event->Overlaps ((*i)->GetStartTime ()))
00317 {
00318 ni->push_back (NiChange ((*i)->GetStartTime (), (*i)->GetRxPowerW ()));
00319 }
00320 if (event->Overlaps ((*i)->GetEndTime ()))
00321 {
00322 ni->push_back (NiChange ((*i)->GetEndTime (), -(*i)->GetRxPowerW ()));
00323 }
00324 if ((*i)->Overlaps (event->GetStartTime ()))
00325 {
00326 noiseInterference += (*i)->GetRxPowerW ();
00327 }
00328 i++;
00329 }
00330 ni->push_back (NiChange (event->GetStartTime (), noiseInterference));
00331 ni->push_back (NiChange (event->GetEndTime (), 0));
00332
00333
00334 std::sort (ni->begin (), ni->end (), std::less<NiChange> ());
00335
00336 return noiseInterference;
00337 }
00338
00339 double
00340 InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode) const
00341 {
00342 NS_ASSERT_MSG(m_errorRateModel != 0, "InterferenceHelper::CalculateChunkSuccessRate requires an ErrorRateModel");
00343
00344 if (duration == NanoSeconds (0)) {
00345 return 1.0;
00346 }
00347 uint32_t rate = mode.GetPhyRate ();
00348 uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ());
00349 double csr = m_errorRateModel->GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
00350 return csr;
00351 }
00352
00353 double
00354 InterferenceHelper::CalculatePer (Ptr<const InterferenceHelper::Event> event, NiChanges *ni) const
00355 {
00356 double psr = 1.0;
00357 NiChanges::iterator j = ni->begin ();
00358 Time previous = (*j).GetTime ();
00359 uint64_t plcpPreambleDelayUs;
00360 WifiMode payloadMode = event->GetPayloadMode ();
00361 WifiMode headerMode;
00362 switch (event->GetPreambleType ()) {
00363 case WIFI_PREAMBLE_LONG:
00364 plcpPreambleDelayUs = m_plcpLongPreambleDelayUs;
00365 headerMode = m_longPlcpHeaderMode;
00366 break;
00367 case WIFI_PREAMBLE_SHORT:
00368 plcpPreambleDelayUs = m_plcpShortPreambleDelayUs;
00369 headerMode = m_shortPlcpHeaderMode;
00370 break;
00371 default:
00372 NS_ASSERT (false);
00373
00374 plcpPreambleDelayUs = 0;
00375 headerMode = m_shortPlcpHeaderMode;
00376 break;
00377 }
00378 Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (plcpPreambleDelayUs);
00379 Time plcpPayloadStart = plcpHeaderStart +
00380 Seconds ((m_plcpHeaderLength + 0.0) / headerMode.GetDataRate ());
00381 double noiseInterferenceW = (*j).GetDelta ();
00382 double powerW = event->GetRxPowerW ();
00383
00384 j++;
00385 while (ni->end () != j)
00386 {
00387 Time current = (*j).GetTime ();
00388 NS_ASSERT (current >= previous);
00389
00390 if (previous >= plcpPayloadStart)
00391 {
00392 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
00393 noiseInterferenceW,
00394 payloadMode),
00395 current - previous,
00396 payloadMode);
00397 }
00398 else if (previous >= plcpHeaderStart)
00399 {
00400 if (current >= plcpPayloadStart)
00401 {
00402 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
00403 noiseInterferenceW,
00404 headerMode),
00405 plcpPayloadStart - previous,
00406 headerMode);
00407 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
00408 noiseInterferenceW,
00409 payloadMode),
00410 current - plcpPayloadStart,
00411 payloadMode);
00412 }
00413 else
00414 {
00415 NS_ASSERT (current >= plcpHeaderStart);
00416 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
00417 noiseInterferenceW,
00418 headerMode),
00419 current - previous,
00420 headerMode);
00421 }
00422 }
00423 else
00424 {
00425 if (current >= plcpPayloadStart)
00426 {
00427 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
00428 noiseInterferenceW,
00429 headerMode),
00430 plcpPayloadStart - plcpHeaderStart,
00431 headerMode);
00432 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
00433 noiseInterferenceW,
00434 payloadMode),
00435 current - plcpPayloadStart,
00436 payloadMode);
00437 }
00438 else if (current >= plcpHeaderStart)
00439 {
00440 psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
00441 noiseInterferenceW,
00442 headerMode),
00443 current - plcpHeaderStart,
00444 headerMode);
00445 }
00446 }
00447
00448 noiseInterferenceW += (*j).GetDelta ();
00449 previous = (*j).GetTime ();
00450 j++;
00451 }
00452
00453 double per = 1 - psr;
00454 return per;
00455 }
00456
00457
00458 struct InterferenceHelper::SnrPer
00459 InterferenceHelper::CalculateSnrPer (Ptr<InterferenceHelper::Event> event)
00460 {
00461 NiChanges ni;
00462 double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
00463 double snr = CalculateSnr (event->GetRxPowerW (),
00464 noiseInterferenceW,
00465 event->GetPayloadMode ());
00466
00467
00468
00469
00470 double per = CalculatePer (event, &ni);
00471
00472 struct SnrPer snrPer;
00473 snrPer.snr = snr;
00474 snrPer.per = per;
00475 return snrPer;
00476 }
00477
00478 double
00479 InterferenceHelper::CalculateSnr (Ptr<InterferenceHelper::Event> event)
00480 {
00481 NiChanges ni;
00482 double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
00483 double snr = CalculateSnr (event->GetRxPowerW (),
00484 noiseInterferenceW,
00485 event->GetPayloadMode ());
00486
00487 return snr;
00488 }
00489
00490
00491 }