|
|
| 88 |
* short period of time. |
88 |
* short period of time. |
| 89 |
****************************************************************/ |
89 |
****************************************************************/ |
| 90 |
|
90 |
|
| 91 |
InterferenceHelper::NiChange::NiChange (Time time, double delta, Ptr<InterferenceHelper::Event> event) |
91 |
InterferenceHelper::NiChange::NiChange (double power, Ptr<InterferenceHelper::Event> event) |
| 92 |
: m_time (time), |
92 |
: m_power (power), |
| 93 |
m_delta (delta), |
|
|
| 94 |
m_event (event) |
93 |
m_event (event) |
| 95 |
{ |
94 |
{ |
| 96 |
} |
95 |
} |
| 97 |
|
96 |
|
| 98 |
Time |
97 |
double |
| 99 |
InterferenceHelper::NiChange::GetTime (void) const |
98 |
InterferenceHelper::NiChange::GetPower (void) const |
| 100 |
{ |
99 |
{ |
| 101 |
return m_time; |
100 |
return m_power; |
| 102 |
} |
101 |
} |
| 103 |
|
102 |
|
| 104 |
double |
103 |
void |
| 105 |
InterferenceHelper::NiChange::GetDelta (void) const |
104 |
InterferenceHelper::NiChange::AddPower (double power) |
| 106 |
{ |
105 |
{ |
| 107 |
return m_delta; |
106 |
m_power += power; |
| 108 |
} |
107 |
} |
| 109 |
|
108 |
|
| 110 |
Ptr<InterferenceHelper::Event> |
109 |
Ptr<InterferenceHelper::Event> |
|
|
| 113 |
return m_event; |
112 |
return m_event; |
| 114 |
} |
113 |
} |
| 115 |
|
114 |
|
| 116 |
bool |
|
|
| 117 |
InterferenceHelper::NiChange::operator < (const InterferenceHelper::NiChange& o) const |
| 118 |
{ |
| 119 |
return (m_time < o.m_time); |
| 120 |
} |
| 121 |
|
| 122 |
|
115 |
|
| 123 |
/**************************************************************** |
116 |
/**************************************************************** |
| 124 |
* The actual InterferenceHelper |
117 |
* The actual InterferenceHelper |
|
|
| 130 |
m_firstPower (0), |
123 |
m_firstPower (0), |
| 131 |
m_rxing (false) |
124 |
m_rxing (false) |
| 132 |
{ |
125 |
{ |
|
|
126 |
// Always have a zero power noise event in the list |
| 127 |
AddNiChangeEvent (Time (0), NiChange (0.0, 0)); |
| 133 |
} |
128 |
} |
| 134 |
|
129 |
|
| 135 |
InterferenceHelper::~InterferenceHelper () |
130 |
InterferenceHelper::~InterferenceHelper () |
|
|
| 141 |
Ptr<InterferenceHelper::Event> |
136 |
Ptr<InterferenceHelper::Event> |
| 142 |
InterferenceHelper::Add (Ptr<const Packet> packet, WifiTxVector txVector, Time duration, double rxPowerW) |
137 |
InterferenceHelper::Add (Ptr<const Packet> packet, WifiTxVector txVector, Time duration, double rxPowerW) |
| 143 |
{ |
138 |
{ |
| 144 |
Ptr<InterferenceHelper::Event> event; |
139 |
Ptr<InterferenceHelper::Event> event = Create<InterferenceHelper::Event> (packet, txVector, duration, rxPowerW); |
| 145 |
event = Create<InterferenceHelper::Event> (packet, txVector, duration, rxPowerW); |
|
|
| 146 |
AppendEvent (event); |
140 |
AppendEvent (event); |
| 147 |
return event; |
141 |
return event; |
| 148 |
} |
142 |
} |
|
|
| 191 |
InterferenceHelper::GetEnergyDuration (double energyW) const |
185 |
InterferenceHelper::GetEnergyDuration (double energyW) const |
| 192 |
{ |
186 |
{ |
| 193 |
Time now = Simulator::Now (); |
187 |
Time now = Simulator::Now (); |
| 194 |
double noiseInterferenceW = 0; |
188 |
auto i = GetPreviousPosition (now); |
| 195 |
Time end = now; |
189 |
Time end = i->first; |
| 196 |
noiseInterferenceW = m_firstPower; |
190 |
for ( ; i != m_niChanges.end (); ++i) |
| 197 |
for (NiChanges::const_iterator i = m_niChanges.begin (); i != m_niChanges.end (); i++) |
|
|
| 198 |
{ |
191 |
{ |
| 199 |
noiseInterferenceW += i->GetDelta (); |
192 |
double noiseInterferenceW = i->second.GetPower (); |
| 200 |
end = i->GetTime (); |
193 |
end = i->first; |
| 201 |
if (end < now) |
|
|
| 202 |
{ |
| 203 |
continue; |
| 204 |
} |
| 205 |
if (noiseInterferenceW < energyW) |
194 |
if (noiseInterferenceW < energyW) |
| 206 |
{ |
195 |
{ |
| 207 |
break; |
196 |
break; |
|
|
| 213 |
void |
202 |
void |
| 214 |
InterferenceHelper::AppendEvent (Ptr<InterferenceHelper::Event> event) |
203 |
InterferenceHelper::AppendEvent (Ptr<InterferenceHelper::Event> event) |
| 215 |
{ |
204 |
{ |
| 216 |
Time now = Simulator::Now (); |
205 |
NS_LOG_FUNCTION (this); |
|
|
206 |
double previousPowerStart = 0; |
| 207 |
double previousPowerEnd = 0; |
| 208 |
previousPowerStart = GetPreviousPosition (event->GetStartTime ())->second.GetPower (); |
| 209 |
previousPowerEnd = GetPreviousPosition (event->GetEndTime ())->second.GetPower (); |
| 210 |
|
| 217 |
if (!m_rxing) |
211 |
if (!m_rxing) |
| 218 |
{ |
212 |
{ |
| 219 |
NiChanges::const_iterator nowIterator = GetPosition (now); |
213 |
m_firstPower = previousPowerStart; |
| 220 |
for (NiChanges::const_iterator i = m_niChanges.begin (); i != nowIterator; i++) |
214 |
// Always leave the first zero power noise event in the list |
| 221 |
{ |
215 |
m_niChanges.erase (++(m_niChanges.begin ()), |
| 222 |
m_firstPower += i->GetDelta (); |
216 |
GetNextPosition (event->GetStartTime ())); |
| 223 |
} |
|
|
| 224 |
m_niChanges.erase (m_niChanges.begin (), nowIterator); |
| 225 |
} |
217 |
} |
| 226 |
AddNiChangeEvent (NiChange (event->GetStartTime (), event->GetRxPowerW (), event)); |
218 |
auto first = AddNiChangeEvent (event->GetStartTime (), NiChange (previousPowerStart, event)); |
| 227 |
AddNiChangeEvent (NiChange (event->GetEndTime (), -event->GetRxPowerW (), event)); |
219 |
auto last = AddNiChangeEvent (event->GetEndTime (), NiChange (previousPowerEnd, event)); |
|
|
220 |
for (auto i = first; i != last; ++i) |
| 221 |
{ |
| 222 |
i->second.AddPower (event->GetRxPowerW ()); |
| 223 |
} |
| 228 |
} |
224 |
} |
| 229 |
|
225 |
|
| 230 |
double |
226 |
double |
|
|
| 246 |
InterferenceHelper::CalculateNoiseInterferenceW (Ptr<InterferenceHelper::Event> event, NiChanges *ni) const |
242 |
InterferenceHelper::CalculateNoiseInterferenceW (Ptr<InterferenceHelper::Event> event, NiChanges *ni) const |
| 247 |
{ |
243 |
{ |
| 248 |
double noiseInterference = m_firstPower; |
244 |
double noiseInterference = m_firstPower; |
| 249 |
NiChanges::const_iterator eventIterator = m_niChanges.begin (); |
245 |
auto it = m_niChanges.find (event->GetStartTime ()); |
| 250 |
while (eventIterator != m_niChanges.end ()) |
246 |
for (; it != m_niChanges.end () && it->second.GetEvent () != event; ++it) |
| 251 |
{ |
247 |
{ |
| 252 |
// Iterate the NI change list from the beginning to the end |
248 |
noiseInterference = it->second.GetPower (); |
| 253 |
// until find the position of the event in the NI change list |
|
|
| 254 |
// The reason of using the event that causes the NI change to identify |
| 255 |
// different NI changes is because in some special cases |
| 256 |
// different NI changes happen at the same time with the same delta |
| 257 |
// value. Therefore, it may be impossible to identify a NI change that belongs |
| 258 |
// to which event based on just the NI time and NI delta value |
| 259 |
if (eventIterator->GetEvent () != event) |
| 260 |
{ |
| 261 |
// The NI changes which happen before the event should be considered |
| 262 |
// as the interference. This considers the case that the receiving event |
| 263 |
// arrives while another receiving event is going on. The SINR of |
| 264 |
// the newly arrived event is calculated for checking the possibility of frame capture |
| 265 |
noiseInterference += eventIterator->GetDelta (); |
| 266 |
} |
| 267 |
else |
| 268 |
{ |
| 269 |
break; |
| 270 |
} |
| 271 |
++eventIterator; |
| 272 |
} |
249 |
} |
| 273 |
|
250 |
ni->emplace (event->GetStartTime (), NiChange (0, event)); |
| 274 |
for (NiChanges::const_iterator i = eventIterator + 1; i != m_niChanges.end (); ++i) |
251 |
while (++it != m_niChanges.end () && it->second.GetEvent () != event) |
| 275 |
{ |
252 |
{ |
| 276 |
if (event->GetEndTime () == i->GetTime () && event == i->GetEvent ()) |
253 |
ni->insert (*it); |
| 277 |
{ |
|
|
| 278 |
break; |
| 279 |
} |
| 280 |
ni->push_back (*i); |
| 281 |
} |
254 |
} |
| 282 |
ni->insert (ni->begin (), NiChange (event->GetStartTime (), noiseInterference, event)); |
255 |
ni->emplace(event->GetEndTime (), NiChange (0, event)); |
| 283 |
ni->push_back (NiChange (event->GetEndTime (), 0, event)); |
256 |
NS_ABORT_MSG_IF (noiseInterference < 0, "noiseInterference < 0: " << |
|
|
257 |
noiseInterference); |
| 284 |
return noiseInterference; |
258 |
return noiseInterference; |
| 285 |
} |
259 |
} |
| 286 |
|
260 |
|
|
|
| 312 |
NS_LOG_FUNCTION (this); |
286 |
NS_LOG_FUNCTION (this); |
| 313 |
const WifiTxVector txVector = event->GetTxVector (); |
287 |
const WifiTxVector txVector = event->GetTxVector (); |
| 314 |
double psr = 1.0; /* Packet Success Rate */ |
288 |
double psr = 1.0; /* Packet Success Rate */ |
| 315 |
NiChanges::const_iterator j = ni->begin (); |
289 |
auto j = ni->begin (); |
| 316 |
Time previous = (*j).GetTime (); |
290 |
Time previous = j->first; |
| 317 |
WifiMode payloadMode = event->GetPayloadMode (); |
291 |
WifiMode payloadMode = event->GetPayloadMode (); |
| 318 |
WifiPreamble preamble = txVector.GetPreambleType (); |
292 |
WifiPreamble preamble = txVector.GetPreambleType (); |
| 319 |
Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (txVector); //packet start time + preamble |
293 |
Time plcpHeaderStart = j->first + WifiPhy::GetPlcpPreambleDuration (txVector); //packet start time + preamble |
| 320 |
Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (txVector); //packet start time + preamble + L-SIG |
294 |
Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (txVector); //packet start time + preamble + L-SIG |
| 321 |
Time plcpTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble) + WifiPhy::GetPlcpSigA1Duration (preamble) + WifiPhy::GetPlcpSigA2Duration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A |
295 |
Time plcpTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble) + WifiPhy::GetPlcpSigA1Duration (preamble) + WifiPhy::GetPlcpSigA2Duration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A |
| 322 |
Time plcpPayloadStart = plcpTrainingSymbolsStart + WifiPhy::GetPlcpTrainingSymbolDuration (txVector) + WifiPhy::GetPlcpSigBDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B |
296 |
Time plcpPayloadStart = plcpTrainingSymbolsStart + WifiPhy::GetPlcpTrainingSymbolDuration (txVector) + WifiPhy::GetPlcpSigBDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B |
| 323 |
double noiseInterferenceW = (*j).GetDelta (); |
297 |
double noiseInterferenceW = m_firstPower; |
| 324 |
double powerW = event->GetRxPowerW (); |
298 |
double powerW = event->GetRxPowerW (); |
| 325 |
j++; |
299 |
while (++j != ni->end ()) |
| 326 |
while (ni->end () != j) |
|
|
| 327 |
{ |
300 |
{ |
| 328 |
Time current = (*j).GetTime (); |
301 |
Time current = j->first; |
| 329 |
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current); |
302 |
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current); |
| 330 |
NS_ASSERT (current >= previous); |
303 |
NS_ASSERT (current >= previous); |
| 331 |
//Case 1: Both previous and current point to the payload |
304 |
//Case 1: Both previous and current point to the payload |
|
|
| 348 |
payloadMode, txVector); |
321 |
payloadMode, txVector); |
| 349 |
NS_LOG_DEBUG ("previous is before payload and current is in the payload: mode=" << payloadMode << ", psr=" << psr); |
322 |
NS_LOG_DEBUG ("previous is before payload and current is in the payload: mode=" << payloadMode << ", psr=" << psr); |
| 350 |
} |
323 |
} |
| 351 |
noiseInterferenceW += (*j).GetDelta (); |
324 |
noiseInterferenceW = j->second.GetPower () - powerW; |
| 352 |
previous = (*j).GetTime (); |
325 |
previous = j->first; |
| 353 |
j++; |
|
|
| 354 |
} |
326 |
} |
| 355 |
double per = 1 - psr; |
327 |
double per = 1 - psr; |
| 356 |
return per; |
328 |
return per; |
|
|
| 362 |
NS_LOG_FUNCTION (this); |
334 |
NS_LOG_FUNCTION (this); |
| 363 |
const WifiTxVector txVector = event->GetTxVector (); |
335 |
const WifiTxVector txVector = event->GetTxVector (); |
| 364 |
double psr = 1.0; /* Packet Success Rate */ |
336 |
double psr = 1.0; /* Packet Success Rate */ |
| 365 |
NiChanges::const_iterator j = ni->begin (); |
337 |
auto j = ni->begin (); |
| 366 |
Time previous = (*j).GetTime (); |
338 |
Time previous = j->first; |
| 367 |
WifiPreamble preamble = txVector.GetPreambleType (); |
339 |
WifiPreamble preamble = txVector.GetPreambleType (); |
| 368 |
WifiMode mcsHeaderMode; |
340 |
WifiMode mcsHeaderMode; |
| 369 |
if (preamble == WIFI_PREAMBLE_HT_MF || preamble == WIFI_PREAMBLE_HT_GF) |
341 |
if (preamble == WIFI_PREAMBLE_HT_MF || preamble == WIFI_PREAMBLE_HT_GF) |
|
|
| 382 |
mcsHeaderMode = WifiPhy::GetHePlcpHeaderMode (); |
354 |
mcsHeaderMode = WifiPhy::GetHePlcpHeaderMode (); |
| 383 |
} |
355 |
} |
| 384 |
WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (txVector); |
356 |
WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (txVector); |
| 385 |
Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (txVector); //packet start time + preamble |
357 |
Time plcpHeaderStart = j->first + WifiPhy::GetPlcpPreambleDuration (txVector); //packet start time + preamble |
| 386 |
Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (txVector); //packet start time + preamble + L-SIG |
358 |
Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (txVector); //packet start time + preamble + L-SIG |
| 387 |
Time plcpTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble) + WifiPhy::GetPlcpSigA1Duration (preamble) + WifiPhy::GetPlcpSigA2Duration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A |
359 |
Time plcpTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble) + WifiPhy::GetPlcpSigA1Duration (preamble) + WifiPhy::GetPlcpSigA2Duration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A |
| 388 |
Time plcpPayloadStart = plcpTrainingSymbolsStart + WifiPhy::GetPlcpTrainingSymbolDuration (txVector) + WifiPhy::GetPlcpSigBDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B |
360 |
Time plcpPayloadStart = plcpTrainingSymbolsStart + WifiPhy::GetPlcpTrainingSymbolDuration (txVector) + WifiPhy::GetPlcpSigBDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B |
| 389 |
double noiseInterferenceW = (*j).GetDelta (); |
361 |
double noiseInterferenceW = m_firstPower; |
| 390 |
double powerW = event->GetRxPowerW (); |
362 |
double powerW = event->GetRxPowerW (); |
| 391 |
j++; |
363 |
while (++j != ni->end ()) |
| 392 |
while (ni->end () != j) |
|
|
| 393 |
{ |
364 |
{ |
| 394 |
Time current = (*j).GetTime (); |
365 |
Time current = j->first; |
| 395 |
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current); |
366 |
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current); |
| 396 |
NS_ASSERT (current >= previous); |
367 |
NS_ASSERT (current >= previous); |
| 397 |
//Case 1: previous and current after playload start: nothing to do |
368 |
//Case 1: previous and current after playload start: nothing to do |
|
|
| 764 |
} |
735 |
} |
| 765 |
} |
736 |
} |
| 766 |
|
737 |
|
| 767 |
noiseInterferenceW += (*j).GetDelta (); |
738 |
noiseInterferenceW = j->second.GetPower () - powerW; |
| 768 |
previous = (*j).GetTime (); |
739 |
previous = j->first; |
| 769 |
j++; |
|
|
| 770 |
} |
740 |
} |
| 771 |
|
741 |
|
| 772 |
double per = 1 - psr; |
742 |
double per = 1 - psr; |
|
|
| 774 |
} |
744 |
} |
| 775 |
|
745 |
|
| 776 |
struct InterferenceHelper::SnrPer |
746 |
struct InterferenceHelper::SnrPer |
| 777 |
InterferenceHelper::CalculatePlcpPayloadSnrPer (Ptr<InterferenceHelper::Event> event) |
747 |
InterferenceHelper::CalculatePlcpPayloadSnrPer (Ptr<InterferenceHelper::Event> event) const |
| 778 |
{ |
748 |
{ |
| 779 |
NiChanges ni; |
749 |
NiChanges ni; |
| 780 |
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni); |
750 |
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni); |
|
|
| 794 |
} |
764 |
} |
| 795 |
|
765 |
|
| 796 |
struct InterferenceHelper::SnrPer |
766 |
struct InterferenceHelper::SnrPer |
| 797 |
InterferenceHelper::CalculatePlcpHeaderSnrPer (Ptr<InterferenceHelper::Event> event) |
767 |
InterferenceHelper::CalculatePlcpHeaderSnrPer (Ptr<InterferenceHelper::Event> event) const |
| 798 |
{ |
768 |
{ |
| 799 |
NiChanges ni; |
769 |
NiChanges ni; |
| 800 |
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni); |
770 |
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni); |
|
|
| 817 |
InterferenceHelper::EraseEvents (void) |
787 |
InterferenceHelper::EraseEvents (void) |
| 818 |
{ |
788 |
{ |
| 819 |
m_niChanges.clear (); |
789 |
m_niChanges.clear (); |
|
|
790 |
// Always have a zero power noise event in the list |
| 791 |
AddNiChangeEvent (Time (0), NiChange (0.0, 0)); |
| 820 |
m_rxing = false; |
792 |
m_rxing = false; |
| 821 |
m_firstPower = 0; |
793 |
m_firstPower = 0; |
| 822 |
} |
794 |
} |
| 823 |
|
795 |
|
| 824 |
InterferenceHelper::NiChanges::const_iterator |
796 |
InterferenceHelper::NiChanges::const_iterator |
| 825 |
InterferenceHelper::GetPosition (Time moment) |
797 |
InterferenceHelper::GetNextPosition (Time moment) const |
| 826 |
{ |
798 |
{ |
| 827 |
return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0, NULL)); |
799 |
return m_niChanges.upper_bound (moment); |
| 828 |
} |
800 |
} |
| 829 |
|
801 |
|
| 830 |
void |
802 |
InterferenceHelper::NiChanges::const_iterator |
| 831 |
InterferenceHelper::AddNiChangeEvent (NiChange change) |
803 |
InterferenceHelper::GetPreviousPosition (Time moment) const |
| 832 |
{ |
804 |
{ |
| 833 |
m_niChanges.insert (GetPosition (change.GetTime ()), change); |
805 |
auto it = GetNextPosition (moment); |
|
|
806 |
// This is safe since there is always an NiChange at time 0, |
| 807 |
// before moment. |
| 808 |
--it; |
| 809 |
return it; |
| 810 |
} |
| 811 |
|
| 812 |
InterferenceHelper::NiChanges::iterator |
| 813 |
InterferenceHelper::AddNiChangeEvent (Time moment, NiChange change) |
| 814 |
{ |
| 815 |
return m_niChanges.insert (GetNextPosition (moment), std::make_pair (moment, change)); |
| 834 |
} |
816 |
} |
| 835 |
|
817 |
|
| 836 |
void |
818 |
void |
|
|
| 845 |
{ |
827 |
{ |
| 846 |
NS_LOG_FUNCTION (this); |
828 |
NS_LOG_FUNCTION (this); |
| 847 |
m_rxing = false; |
829 |
m_rxing = false; |
|
|
830 |
//Update m_firstPower for frame capture |
| 831 |
auto it = m_niChanges.find (Simulator::Now ()); |
| 832 |
it--; |
| 833 |
m_firstPower = it->second.GetPower (); |
| 848 |
} |
834 |
} |
| 849 |
|
835 |
|
| 850 |
} //namespace ns3 |
836 |
} //namespace ns3 |