|
|
| 38 |
WifiMode m_lastMode; //!< Mode most recently used to the remote station |
38 |
WifiMode m_lastMode; //!< Mode most recently used to the remote station |
| 39 |
}; |
39 |
}; |
| 40 |
|
40 |
|
|
|
41 |
// To avoid using the cache before a valid value has been cached |
| 42 |
static const double CACHE_INITIAL_VALUE = -100; |
| 43 |
|
| 41 |
NS_OBJECT_ENSURE_REGISTERED (IdealWifiManager); |
44 |
NS_OBJECT_ENSURE_REGISTERED (IdealWifiManager); |
| 42 |
|
45 |
|
| 43 |
NS_LOG_COMPONENT_DEFINE ("IdealWifiManager"); |
46 |
NS_LOG_COMPONENT_DEFINE ("IdealWifiManager"); |
|
|
| 148 |
{ |
151 |
{ |
| 149 |
guardInterval = GetPhy ()->GetGuardInterval ().GetNanoSeconds (); |
152 |
guardInterval = GetPhy ()->GetGuardInterval ().GetNanoSeconds (); |
| 150 |
} |
153 |
} |
| 151 |
uint8_t maxNss = GetPhy ()->GetMaxSupportedTxSpatialStreams (); |
154 |
for (uint8_t i = 1; i <= GetPhy ()->GetMaxSupportedTxSpatialStreams (); i++) |
| 152 |
for (uint8_t i = 1; i <= maxNss; i++) |
|
|
| 153 |
{ |
155 |
{ |
| 154 |
NS_LOG_DEBUG ("Initialize, adding mode = " << mode.GetUniqueName () << |
156 |
NS_LOG_DEBUG ("Initialize, adding mode = " << mode.GetUniqueName () << |
| 155 |
" channel width " << (uint16_t) j << |
157 |
" channel width " << (uint16_t) j << |
|
|
| 204 |
NS_LOG_FUNCTION (this); |
206 |
NS_LOG_FUNCTION (this); |
| 205 |
IdealWifiRemoteStation *station = new IdealWifiRemoteStation (); |
207 |
IdealWifiRemoteStation *station = new IdealWifiRemoteStation (); |
| 206 |
station->m_lastSnrObserved = 0.0; |
208 |
station->m_lastSnrObserved = 0.0; |
| 207 |
station->m_lastSnrCached = 0.0; |
209 |
station->m_lastSnrCached = CACHE_INITIAL_VALUE; |
| 208 |
station->m_lastMode = GetDefaultMode (); |
210 |
station->m_lastMode = GetDefaultMode (); |
| 209 |
station->m_nss = 1; |
211 |
station->m_nss = 1; |
| 210 |
return station; |
212 |
return station; |
|
|
| 280 |
NS_LOG_FUNCTION (this << st); |
282 |
NS_LOG_FUNCTION (this << st); |
| 281 |
IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st; |
283 |
IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st; |
| 282 |
//We search within the Supported rate set the mode with the |
284 |
//We search within the Supported rate set the mode with the |
| 283 |
//highest snr threshold possible which is smaller than m_lastSnr |
285 |
//highest data rate for which the snr threshold is smaller than m_lastSnr |
| 284 |
//to ensure correct packet delivery. |
286 |
//to ensure correct packet delivery. |
| 285 |
double maxThreshold = 0.0; |
|
|
| 286 |
WifiMode maxMode = GetDefaultMode (); |
287 |
WifiMode maxMode = GetDefaultMode (); |
| 287 |
WifiTxVector txVector; |
288 |
WifiTxVector txVector; |
| 288 |
WifiMode mode; |
289 |
WifiMode mode; |
|
|
290 |
uint64_t bestRate = 0; |
| 289 |
uint8_t selectedNss = 1; |
291 |
uint8_t selectedNss = 1; |
| 290 |
uint16_t guardInterval; |
292 |
uint16_t guardInterval; |
| 291 |
uint8_t channelWidth = std::min (GetChannelWidth (station), GetPhy ()->GetChannelWidth ()); |
293 |
uint8_t channelWidth = std::min (GetChannelWidth (station), GetPhy ()->GetChannelWidth ()); |
| 292 |
txVector.SetChannelWidth (channelWidth); |
294 |
txVector.SetChannelWidth (channelWidth); |
| 293 |
if (station->m_lastSnrObserved == station->m_lastSnrCached) |
295 |
if (station->m_lastSnrCached != CACHE_INITIAL_VALUE && station->m_lastSnrObserved == station->m_lastSnrCached) |
| 294 |
{ |
296 |
{ |
| 295 |
// SNR has not changed, so skip the search and use the last |
297 |
// SNR has not changed, so skip the search and use the last |
| 296 |
// mode selected |
298 |
// mode selected |
|
|
| 298 |
selectedNss = station->m_nss; |
300 |
selectedNss = station->m_nss; |
| 299 |
NS_LOG_DEBUG ("Using cached mode = " << maxMode.GetUniqueName () << |
301 |
NS_LOG_DEBUG ("Using cached mode = " << maxMode.GetUniqueName () << |
| 300 |
" last snr observed " << station->m_lastSnrObserved << |
302 |
" last snr observed " << station->m_lastSnrObserved << |
| 301 |
" cached " << station->m_lastSnrCached); |
303 |
" cached " << station->m_lastSnrCached << |
|
|
304 |
" nss " << (uint16_t) selectedNss); |
| 302 |
} |
305 |
} |
| 303 |
else |
306 |
else |
| 304 |
{ |
307 |
{ |
|
|
| 326 |
// Derive NSS from the MCS index. There is a different mode for each possible NSS value. |
329 |
// Derive NSS from the MCS index. There is a different mode for each possible NSS value. |
| 327 |
uint8_t nss = (mode.GetMcsValue () / 8) + 1; |
330 |
uint8_t nss = (mode.GetMcsValue () / 8) + 1; |
| 328 |
txVector.SetNss (nss); |
331 |
txVector.SetNss (nss); |
| 329 |
if (WifiPhy::IsValidTxVector (txVector) == false) |
332 |
if (WifiPhy::IsValidTxVector (txVector) == false || |
|
|
333 |
nss > GetNumberOfSupportedStreams (st)) |
| 330 |
{ |
334 |
{ |
| 331 |
NS_LOG_DEBUG ("Skipping mode " << mode.GetUniqueName () << |
335 |
NS_LOG_DEBUG ("Skipping mode " << mode.GetUniqueName () << |
| 332 |
" nss " << (uint16_t) nss << " width " << |
336 |
" nss " << (uint16_t) nss << " width " << |
|
|
| 334 |
continue; |
338 |
continue; |
| 335 |
} |
339 |
} |
| 336 |
double threshold = GetSnrThreshold (txVector); |
340 |
double threshold = GetSnrThreshold (txVector); |
| 337 |
NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () << |
341 |
uint64_t dataRate = mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), nss); |
| 338 |
" threshold " << threshold << " maxThreshold " << |
342 |
NS_LOG_DEBUG ("Testing mode " << mode.GetUniqueName () << |
| 339 |
maxThreshold << " last snr observed " << |
343 |
" data rate " << dataRate << |
|
|
344 |
" threshold " << threshold << " last snr observed " << |
| 340 |
station->m_lastSnrObserved << " cached " << |
345 |
station->m_lastSnrObserved << " cached " << |
| 341 |
station->m_lastSnrCached); |
346 |
station->m_lastSnrCached); |
| 342 |
if (threshold > maxThreshold && threshold < station->m_lastSnrObserved) |
347 |
if (dataRate > bestRate && threshold < station->m_lastSnrObserved) |
| 343 |
{ |
348 |
{ |
| 344 |
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () << |
349 |
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () << |
|
|
350 |
" data rate " << dataRate << |
| 345 |
" threshold " << threshold << |
351 |
" threshold " << threshold << |
| 346 |
" last snr observed " << |
352 |
" last snr observed " << |
| 347 |
station->m_lastSnrObserved); |
353 |
station->m_lastSnrObserved); |
| 348 |
maxThreshold = threshold; |
354 |
bestRate = dataRate; |
| 349 |
maxMode = mode; |
355 |
maxMode = mode; |
| 350 |
selectedNss = nss; |
356 |
selectedNss = nss; |
| 351 |
} |
357 |
} |
|
|
| 364 |
{ |
370 |
{ |
| 365 |
continue; |
371 |
continue; |
| 366 |
} |
372 |
} |
| 367 |
uint8_t maxNss = GetPhy ()->GetMaxSupportedTxSpatialStreams (); |
373 |
for (uint8_t nss = 1; nss <= GetNumberOfSupportedStreams (station); nss++) |
| 368 |
for (uint8_t nss = 1; nss <= maxNss; nss++) |
|
|
| 369 |
{ |
374 |
{ |
| 370 |
// If the peer does not support more streams, stop searching. |
|
|
| 371 |
if (GetNumberOfSupportedStreams (station) < nss) |
| 372 |
{ |
| 373 |
break; |
| 374 |
} |
| 375 |
txVector.SetNss (nss); |
375 |
txVector.SetNss (nss); |
| 376 |
if (WifiPhy::IsValidTxVector (txVector) == false) |
376 |
if (WifiPhy::IsValidTxVector (txVector) == false) |
| 377 |
{ |
377 |
{ |
|
|
| 381 |
continue; |
381 |
continue; |
| 382 |
} |
382 |
} |
| 383 |
double threshold = GetSnrThreshold (txVector); |
383 |
double threshold = GetSnrThreshold (txVector); |
|
|
384 |
uint64_t dataRate = mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), nss); |
| 384 |
NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () << |
385 |
NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () << |
| 385 |
" threshold " << threshold << " maxThreshold " << |
386 |
" data rate " << dataRate << |
| 386 |
maxThreshold << " last snr observed " << |
387 |
" threshold " << threshold << " last snr observed " << |
| 387 |
station->m_lastSnrObserved << " cached " << |
388 |
station->m_lastSnrObserved << " cached " << |
| 388 |
station->m_lastSnrCached); |
389 |
station->m_lastSnrCached); |
| 389 |
if (threshold > maxThreshold && threshold < station->m_lastSnrObserved) |
390 |
if (dataRate > bestRate && threshold < station->m_lastSnrObserved) |
| 390 |
{ |
391 |
{ |
| 391 |
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () << |
392 |
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () << |
|
|
393 |
" data rate " << dataRate << |
| 392 |
" threshold " << threshold << |
394 |
" threshold " << threshold << |
| 393 |
" last snr observed " << |
395 |
" last snr observed " << |
| 394 |
station->m_lastSnrObserved); |
396 |
station->m_lastSnrObserved); |
| 395 |
maxThreshold = threshold; |
397 |
bestRate = dataRate; |
| 396 |
maxMode = mode; |
398 |
maxMode = mode; |
| 397 |
selectedNss = nss; |
399 |
selectedNss = nss; |
| 398 |
} |
400 |
} |
|
|
| 407 |
{ |
409 |
{ |
| 408 |
continue; |
410 |
continue; |
| 409 |
} |
411 |
} |
| 410 |
uint8_t maxNss = GetPhy ()->GetMaxSupportedTxSpatialStreams (); |
412 |
for (uint8_t nss = 1; nss <= GetNumberOfSupportedStreams (station); nss++) |
| 411 |
for (uint8_t nss = 1; nss <= maxNss; nss++) |
|
|
| 412 |
{ |
413 |
{ |
| 413 |
// If the peer does not support more streams, stop searching. |
|
|
| 414 |
if (GetNumberOfSupportedStreams (station) < nss) |
| 415 |
{ |
| 416 |
break; |
| 417 |
} |
| 418 |
txVector.SetNss (nss); |
414 |
txVector.SetNss (nss); |
| 419 |
if (WifiPhy::IsValidTxVector (txVector) == false) |
415 |
if (WifiPhy::IsValidTxVector (txVector) == false) |
| 420 |
{ |
416 |
{ |
|
|
| 424 |
continue; |
420 |
continue; |
| 425 |
} |
421 |
} |
| 426 |
double threshold = GetSnrThreshold (txVector); |
422 |
double threshold = GetSnrThreshold (txVector); |
|
|
423 |
uint64_t dataRate = mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), nss); |
| 427 |
NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () << |
424 |
NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () << |
| 428 |
" threshold " << threshold << " maxThreshold " << |
425 |
" data rate " << dataRate << |
| 429 |
maxThreshold << " last snr observed " << |
426 |
" threshold " << threshold << " last snr observed " << |
| 430 |
station->m_lastSnrObserved << " cached " << |
427 |
station->m_lastSnrObserved << " cached " << |
| 431 |
station->m_lastSnrCached); |
428 |
station->m_lastSnrCached); |
| 432 |
if (threshold > maxThreshold && threshold < station->m_lastSnrObserved) |
429 |
if (dataRate > bestRate && threshold < station->m_lastSnrObserved) |
| 433 |
{ |
430 |
{ |
| 434 |
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () << |
431 |
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () << |
|
|
432 |
" data rate " << dataRate << |
| 435 |
" threshold " << threshold << |
433 |
" threshold " << threshold << |
| 436 |
" last snr observed " << |
434 |
" last snr observed " << |
| 437 |
station->m_lastSnrObserved); |
435 |
station->m_lastSnrObserved); |
| 438 |
maxThreshold = threshold; |
436 |
bestRate = dataRate; |
| 439 |
maxMode = mode; |
437 |
maxMode = mode; |
| 440 |
selectedNss = nss; |
438 |
selectedNss = nss; |
| 441 |
} |
439 |
} |
|
|
| 454 |
txVector.SetNss (selectedNss); |
452 |
txVector.SetNss (selectedNss); |
| 455 |
txVector.SetChannelWidth (GetChannelWidthForMode (mode)); |
453 |
txVector.SetChannelWidth (GetChannelWidthForMode (mode)); |
| 456 |
double threshold = GetSnrThreshold (txVector); |
454 |
double threshold = GetSnrThreshold (txVector); |
|
|
455 |
uint64_t dataRate = mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), txVector.GetNss ()); |
| 457 |
NS_LOG_DEBUG ("mode = " << mode.GetUniqueName () << |
456 |
NS_LOG_DEBUG ("mode = " << mode.GetUniqueName () << |
| 458 |
" threshold " << threshold << |
457 |
" threshold " << threshold << |
| 459 |
" last snr observed " << |
458 |
" last snr observed " << |
| 460 |
station->m_lastSnrObserved); |
459 |
station->m_lastSnrObserved); |
| 461 |
if (threshold > maxThreshold && threshold < station->m_lastSnrObserved) |
460 |
if (dataRate > bestRate && threshold < station->m_lastSnrObserved) |
| 462 |
{ |
461 |
{ |
| 463 |
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () << |
462 |
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () << |
|
|
463 |
" data rate " << dataRate << |
| 464 |
" threshold " << threshold << |
464 |
" threshold " << threshold << |
| 465 |
" last snr observed " << |
465 |
" last snr observed " << |
| 466 |
station->m_lastSnrObserved); |
466 |
station->m_lastSnrObserved); |
| 467 |
maxThreshold = threshold; |
467 |
bestRate = dataRate; |
| 468 |
maxMode = mode; |
468 |
maxMode = mode; |
| 469 |
} |
469 |
} |
| 470 |
} |
470 |
} |