|
|
| 44 |
|
44 |
|
| 45 |
namespace ns3 { |
45 |
namespace ns3 { |
| 46 |
|
46 |
|
| 47 |
/** |
|
|
| 48 |
* A struct to contain all information related to a data rate |
| 49 |
*/ |
| 50 |
struct RateInfo |
| 51 |
{ |
| 52 |
/** |
| 53 |
* Perfect transmission time calculation, or frame calculation |
| 54 |
* Given a bit rate and a packet length n bytes |
| 55 |
*/ |
| 56 |
Time perfectTxTime; |
| 57 |
|
| 58 |
|
| 59 |
uint32_t retryCount; ///< retry limit |
| 60 |
uint32_t adjustedRetryCount; ///< adjust the retry limit for this rate |
| 61 |
uint32_t numRateAttempt; ///< how many number of attempts so far |
| 62 |
uint32_t numRateSuccess; ///< number of successful pkts |
| 63 |
uint32_t prob; ///< (# pkts success )/(# total pkts) |
| 64 |
|
| 65 |
/** |
| 66 |
* EWMA calculation |
| 67 |
* ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100 |
| 68 |
*/ |
| 69 |
uint32_t ewmaProb; |
| 70 |
|
| 71 |
uint32_t prevNumRateAttempt; ///< from last rate |
| 72 |
uint32_t prevNumRateSuccess; ///< from last rate |
| 73 |
uint64_t successHist; ///< aggregate of all successes |
| 74 |
uint64_t attemptHist; ///< aggregate of all attempts |
| 75 |
uint32_t throughput; ///< throughput of a rate |
| 76 |
}; |
| 77 |
|
| 78 |
/** |
| 79 |
* Data structure for a Minstrel Rate table |
| 80 |
* A vector of a struct RateInfo |
| 81 |
*/ |
| 82 |
typedef std::vector<struct RateInfo> MinstrelRate; |
| 83 |
|
| 84 |
/** |
| 85 |
* Data structure for a Sample Rate table |
| 86 |
* A vector of a vector uint32_t |
| 87 |
*/ |
| 88 |
typedef std::vector<std::vector<uint32_t> > SampleRate; |
| 89 |
|
47 |
|
| 90 |
struct MinstrelWifiRemoteStation : public WifiRemoteStation |
48 |
struct MinstrelWifiRemoteStation : public WifiRemoteStation |
| 91 |
{ |
49 |
{ |
| 92 |
Time m_nextStatsUpdate; ///< 10 times every second |
50 |
Time m_nextStatsUpdate; ///< 10 times every second |
| 93 |
MinstrelRate m_minstrelTable; ///< minstrel table |
|
|
| 94 |
SampleRate m_sampleTable; ///< sample table |
| 95 |
|
51 |
|
| 96 |
/** |
52 |
/** |
| 97 |
* To keep track of the current position in the our random sample table |
53 |
* To keep track of the current position in the our random sample table |
|
|
| 164 |
} |
120 |
} |
| 165 |
|
121 |
|
| 166 |
MinstrelWifiManager::MinstrelWifiManager () |
122 |
MinstrelWifiManager::MinstrelWifiManager () |
| 167 |
{} |
123 |
{ |
|
|
124 |
m_nsupported = 0; |
| 125 |
} |
| 168 |
|
126 |
|
| 169 |
MinstrelWifiManager::~MinstrelWifiManager () |
127 |
MinstrelWifiManager::~MinstrelWifiManager () |
| 170 |
{} |
128 |
{} |
|
|
| 232 |
void |
190 |
void |
| 233 |
MinstrelWifiManager::CheckInit(MinstrelWifiRemoteStation *station) |
191 |
MinstrelWifiManager::CheckInit(MinstrelWifiRemoteStation *station) |
| 234 |
{ |
192 |
{ |
| 235 |
if (!station->m_initialized) |
193 |
if (!station->m_initialized && GetNSupported (station) > 1) |
| 236 |
{ |
194 |
{ |
| 237 |
// Note: we appear to be doing late initialization of the table |
195 |
// Note: we appear to be doing late initialization of the table |
| 238 |
// to make sure that the set of supported rates has been initialized |
196 |
// to make sure that the set of supported rates has been initialized |
| 239 |
// before we perform our own initialization. |
197 |
// before we perform our own initialization. |
| 240 |
station->m_minstrelTable = MinstrelRate(GetNSupported (station)); |
198 |
m_nsupported = GetNSupported (station); |
| 241 |
station->m_sampleTable = SampleRate(GetNSupported (station), std::vector<uint32_t> (m_sampleCol)); |
199 |
m_minstrelTable = MinstrelRate(m_nsupported); |
|
|
200 |
m_sampleTable = SampleRate(m_nsupported, std::vector<uint32_t> (m_sampleCol)); |
| 242 |
InitSampleTable (station); |
201 |
InitSampleTable (station); |
| 243 |
RateInit (station); |
202 |
RateInit (station); |
| 244 |
station->m_initialized = true; |
203 |
station->m_initialized = true; |
|
|
| 296 |
*/ |
255 |
*/ |
| 297 |
|
256 |
|
| 298 |
CheckInit(station); |
257 |
CheckInit(station); |
|
|
258 |
if (!station->m_initialized) |
| 259 |
{ |
| 260 |
return; |
| 261 |
} |
| 299 |
|
262 |
|
| 300 |
station->m_longRetry++; |
263 |
station->m_longRetry++; |
| 301 |
|
264 |
|
|
|
| 305 |
if (!station->m_isSampling) |
268 |
if (!station->m_isSampling) |
| 306 |
{ |
269 |
{ |
| 307 |
/// use best throughput rate |
270 |
/// use best throughput rate |
| 308 |
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount) |
271 |
if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount) |
| 309 |
{ |
272 |
{ |
| 310 |
; ///< there's still a few retries left |
273 |
; ///< there's still a few retries left |
| 311 |
} |
274 |
} |
| 312 |
|
275 |
|
| 313 |
/// use second best throughput rate |
276 |
/// use second best throughput rate |
| 314 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
277 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
| 315 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
278 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
| 316 |
{ |
279 |
{ |
| 317 |
station->m_txrate = station->m_maxTpRate2; |
280 |
station->m_txrate = station->m_maxTpRate2; |
| 318 |
} |
281 |
} |
| 319 |
|
282 |
|
| 320 |
/// use best probability rate |
283 |
/// use best probability rate |
| 321 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
284 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
| 322 |
station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + |
285 |
m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + |
| 323 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
286 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
| 324 |
{ |
287 |
{ |
| 325 |
station->m_txrate = station->m_maxProbRate; |
288 |
station->m_txrate = station->m_maxProbRate; |
| 326 |
} |
289 |
} |
| 327 |
|
290 |
|
| 328 |
/// use lowest base rate |
291 |
/// use lowest base rate |
| 329 |
else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
292 |
else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
| 330 |
station->m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + |
293 |
m_minstrelTable[station->m_maxTpRate2].adjustedRetryCount + |
| 331 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
294 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
| 332 |
{ |
295 |
{ |
| 333 |
station->m_txrate = 0; |
296 |
station->m_txrate = 0; |
| 334 |
} |
297 |
} |
|
|
| 341 |
if (station->m_sampleRateSlower) |
304 |
if (station->m_sampleRateSlower) |
| 342 |
{ |
305 |
{ |
| 343 |
/// use best throughput rate |
306 |
/// use best throughput rate |
| 344 |
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount) |
307 |
if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount) |
| 345 |
{ |
308 |
{ |
| 346 |
; ///< there are a few retries left |
309 |
; ///< there are a few retries left |
| 347 |
} |
310 |
} |
| 348 |
|
311 |
|
| 349 |
/// use random rate |
312 |
/// use random rate |
| 350 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
313 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
| 351 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
314 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
| 352 |
{ |
315 |
{ |
| 353 |
station->m_txrate = station->m_sampleRate; |
316 |
station->m_txrate = station->m_sampleRate; |
| 354 |
} |
317 |
} |
| 355 |
|
318 |
|
| 356 |
/// use max probability rate |
319 |
/// use max probability rate |
| 357 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
320 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
| 358 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount + |
321 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount + |
| 359 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount )) |
322 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount )) |
| 360 |
{ |
323 |
{ |
| 361 |
station->m_txrate = station->m_maxProbRate; |
324 |
station->m_txrate = station->m_maxProbRate; |
| 362 |
} |
325 |
} |
| 363 |
|
326 |
|
| 364 |
/// use lowest base rate |
327 |
/// use lowest base rate |
| 365 |
else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
328 |
else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
| 366 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount + |
329 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount + |
| 367 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
330 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount)) |
| 368 |
{ |
331 |
{ |
| 369 |
station->m_txrate = 0; |
332 |
station->m_txrate = 0; |
| 370 |
} |
333 |
} |
|
|
| 374 |
else |
337 |
else |
| 375 |
{ |
338 |
{ |
| 376 |
/// use random rate |
339 |
/// use random rate |
| 377 |
if (station->m_longRetry < station->m_minstrelTable[station->m_txrate].adjustedRetryCount) |
340 |
if (station->m_longRetry < m_minstrelTable[station->m_txrate].adjustedRetryCount) |
| 378 |
{ |
341 |
{ |
| 379 |
; ///< keep using it |
342 |
; ///< keep using it |
| 380 |
} |
343 |
} |
| 381 |
|
344 |
|
| 382 |
/// use the best rate |
345 |
/// use the best rate |
| 383 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
346 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
| 384 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
347 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
| 385 |
{ |
348 |
{ |
| 386 |
station->m_txrate = station->m_maxTpRate; |
349 |
station->m_txrate = station->m_maxTpRate; |
| 387 |
} |
350 |
} |
| 388 |
|
351 |
|
| 389 |
/// use the best probability rate |
352 |
/// use the best probability rate |
| 390 |
else if (station->m_longRetry <= (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
353 |
else if (station->m_longRetry <= (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
| 391 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount + |
354 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount + |
| 392 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
355 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
| 393 |
{ |
356 |
{ |
| 394 |
station->m_txrate = station->m_maxProbRate; |
357 |
station->m_txrate = station->m_maxProbRate; |
| 395 |
} |
358 |
} |
| 396 |
|
359 |
|
| 397 |
/// use the lowest base rate |
360 |
/// use the lowest base rate |
| 398 |
else if (station->m_longRetry > (station->m_minstrelTable[station->m_txrate].adjustedRetryCount + |
361 |
else if (station->m_longRetry > (m_minstrelTable[station->m_txrate].adjustedRetryCount + |
| 399 |
station->m_minstrelTable[station->m_maxTpRate].adjustedRetryCount + |
362 |
m_minstrelTable[station->m_maxTpRate].adjustedRetryCount + |
| 400 |
station->m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
363 |
m_minstrelTable[station->m_sampleRate].adjustedRetryCount)) |
| 401 |
{ |
364 |
{ |
| 402 |
station->m_txrate = 0; |
365 |
station->m_txrate = 0; |
| 403 |
} |
366 |
} |
|
|
| 415 |
station->m_sampleRateSlower=false; |
378 |
station->m_sampleRateSlower=false; |
| 416 |
|
379 |
|
| 417 |
CheckInit (station); |
380 |
CheckInit (station); |
|
|
381 |
if (!station->m_initialized) |
| 382 |
{ |
| 383 |
return; |
| 384 |
} |
| 418 |
|
385 |
|
| 419 |
station->m_minstrelTable[station->m_txrate].numRateSuccess++; |
386 |
m_minstrelTable[station->m_txrate].numRateSuccess++; |
| 420 |
station->m_minstrelTable[station->m_txrate].numRateAttempt++; |
387 |
m_minstrelTable[station->m_txrate].numRateAttempt++; |
| 421 |
|
388 |
|
| 422 |
UpdateRetry (station); |
389 |
UpdateRetry (station); |
| 423 |
|
390 |
|
| 424 |
station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry; |
391 |
m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry; |
| 425 |
station->m_packetCount++; |
392 |
station->m_packetCount++; |
| 426 |
|
393 |
|
| 427 |
if (GetNSupported (station) >= 1) |
394 |
if (m_nsupported >= 1) |
| 428 |
{ |
395 |
{ |
| 429 |
station->m_txrate = FindRate (station); |
396 |
station->m_txrate = FindRate (station); |
| 430 |
} |
397 |
} |
|
|
| 441 |
|
408 |
|
| 442 |
UpdateRetry (station); |
409 |
UpdateRetry (station); |
| 443 |
|
410 |
|
| 444 |
station->m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry; |
411 |
m_minstrelTable[station->m_txrate].numRateAttempt += station->m_retry; |
| 445 |
station->m_err++; |
412 |
station->m_err++; |
| 446 |
|
413 |
|
| 447 |
if (GetNSupported (station) >= 1) |
414 |
if (m_nsupported >= 1) |
| 448 |
{ |
415 |
{ |
| 449 |
station->m_txrate = FindRate (station); |
416 |
station->m_txrate = FindRate (station); |
| 450 |
} |
417 |
} |
|
|
| 468 |
CheckInit (station); |
435 |
CheckInit (station); |
| 469 |
|
436 |
|
| 470 |
/// start the rate at half way |
437 |
/// start the rate at half way |
| 471 |
station->m_txrate = GetNSupported (station) / 2; |
438 |
station->m_txrate = m_nsupported / 2; |
| 472 |
} |
439 |
} |
| 473 |
UpdateStats (station); |
440 |
UpdateStats (station); |
| 474 |
return GetSupported (station, station->m_txrate); |
441 |
return GetSupported (station, station->m_txrate); |
|
|
| 492 |
MinstrelWifiManager::GetNextSample (MinstrelWifiRemoteStation *station) |
459 |
MinstrelWifiManager::GetNextSample (MinstrelWifiRemoteStation *station) |
| 493 |
{ |
460 |
{ |
| 494 |
uint32_t bitrate; |
461 |
uint32_t bitrate; |
| 495 |
bitrate = station->m_sampleTable[station->m_index][station->m_col]; |
462 |
bitrate = m_sampleTable[station->m_index][station->m_col]; |
| 496 |
station->m_index++; |
463 |
station->m_index++; |
| 497 |
|
464 |
|
| 498 |
/// bookeeping for m_index and m_col variables |
465 |
/// bookeeping for m_index and m_col variables |
| 499 |
if (station->m_index > (GetNSupported (station) - 2)) |
466 |
if (station->m_index > (m_nsupported - 2)) |
| 500 |
{ |
467 |
{ |
| 501 |
station->m_index =0; |
468 |
station->m_index =0; |
| 502 |
station->m_col++; |
469 |
station->m_col++; |
|
|
| 558 |
} |
525 |
} |
| 559 |
|
526 |
|
| 560 |
/// error check |
527 |
/// error check |
| 561 |
if (idx >= GetNSupported (station) || idx < 0) |
528 |
if (idx >= m_nsupported || idx < 0) |
| 562 |
{ |
529 |
{ |
| 563 |
NS_LOG_DEBUG ("ALERT!!! ERROR"); |
530 |
NS_LOG_DEBUG ("ALERT!!! ERROR"); |
| 564 |
} |
531 |
} |
|
|
| 573 |
|
540 |
|
| 574 |
/// is this rate slower than the current best rate |
541 |
/// is this rate slower than the current best rate |
| 575 |
station->m_sampleRateSlower = |
542 |
station->m_sampleRateSlower = |
| 576 |
(station->m_minstrelTable[idx].perfectTxTime > station->m_minstrelTable[station->m_maxTpRate].perfectTxTime); |
543 |
(m_minstrelTable[idx].perfectTxTime > m_minstrelTable[station->m_maxTpRate].perfectTxTime); |
| 577 |
|
544 |
|
| 578 |
/// using the best rate instead |
545 |
/// using the best rate instead |
| 579 |
if (station->m_sampleRateSlower) |
546 |
if (station->m_sampleRateSlower) |
|
|
| 604 |
return; |
571 |
return; |
| 605 |
} |
572 |
} |
| 606 |
|
573 |
|
|
|
574 |
if (!station->m_initialized) |
| 575 |
{ |
| 576 |
return; |
| 577 |
} |
| 607 |
NS_LOG_DEBUG ("Updating stats="<<this); |
578 |
NS_LOG_DEBUG ("Updating stats="<<this); |
| 608 |
|
579 |
|
| 609 |
station->m_nextStatsUpdate = Simulator::Now () + m_updateStats; |
580 |
station->m_nextStatsUpdate = Simulator::Now () + m_updateStats; |
|
|
| 611 |
Time txTime; |
582 |
Time txTime; |
| 612 |
uint32_t tempProb; |
583 |
uint32_t tempProb; |
| 613 |
|
584 |
|
| 614 |
for (uint32_t i =0; i < GetNSupported (station); i++) |
585 |
for (uint32_t i =0; i < m_nsupported; i++) |
| 615 |
{ |
586 |
{ |
| 616 |
|
587 |
|
| 617 |
/// calculate the perfect tx time for this rate |
588 |
/// calculate the perfect tx time for this rate |
| 618 |
txTime = station->m_minstrelTable[i].perfectTxTime; |
589 |
txTime = m_minstrelTable[i].perfectTxTime; |
| 619 |
|
590 |
|
| 620 |
/// just for initialization |
591 |
/// just for initialization |
| 621 |
if (txTime.GetMicroSeconds () == 0) |
592 |
if (txTime.GetMicroSeconds () == 0) |
|
|
| 624 |
} |
595 |
} |
| 625 |
|
596 |
|
| 626 |
NS_LOG_DEBUG ("m_txrate=" << station->m_txrate << |
597 |
NS_LOG_DEBUG ("m_txrate=" << station->m_txrate << |
| 627 |
"\t attempt=" << station->m_minstrelTable[i].numRateAttempt << |
598 |
"\t attempt=" << m_minstrelTable[i].numRateAttempt << |
| 628 |
"\t success=" << station->m_minstrelTable[i].numRateSuccess); |
599 |
"\t success=" << m_minstrelTable[i].numRateSuccess); |
| 629 |
|
600 |
|
| 630 |
/// if we've attempted something |
601 |
/// if we've attempted something |
| 631 |
if (station->m_minstrelTable[i].numRateAttempt) |
602 |
if (m_minstrelTable[i].numRateAttempt) |
| 632 |
{ |
603 |
{ |
| 633 |
/** |
604 |
/** |
| 634 |
* calculate the probability of success |
605 |
* calculate the probability of success |
| 635 |
* assume probability scales from 0 to 18000 |
606 |
* assume probability scales from 0 to 18000 |
| 636 |
*/ |
607 |
*/ |
| 637 |
tempProb = (station->m_minstrelTable[i].numRateSuccess * 18000) / station->m_minstrelTable[i].numRateAttempt; |
608 |
tempProb = (m_minstrelTable[i].numRateSuccess * 18000) / m_minstrelTable[i].numRateAttempt; |
| 638 |
|
609 |
|
| 639 |
/// bookeeping |
610 |
/// bookeeping |
| 640 |
station->m_minstrelTable[i].successHist += station->m_minstrelTable[i].numRateSuccess; |
611 |
m_minstrelTable[i].successHist += m_minstrelTable[i].numRateSuccess; |
| 641 |
station->m_minstrelTable[i].attemptHist += station->m_minstrelTable[i].numRateAttempt; |
612 |
m_minstrelTable[i].attemptHist += m_minstrelTable[i].numRateAttempt; |
| 642 |
station->m_minstrelTable[i].prob = tempProb; |
613 |
m_minstrelTable[i].prob = tempProb; |
| 643 |
|
614 |
|
| 644 |
/// ewma probability (cast for gcc 3.4 compatibility) |
615 |
/// ewma probability (cast for gcc 3.4 compatibility) |
| 645 |
tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (station->m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100); |
616 |
tempProb = static_cast<uint32_t>(((tempProb * (100 - m_ewmaLevel)) + (m_minstrelTable[i].ewmaProb * m_ewmaLevel) )/100); |
| 646 |
|
617 |
|
| 647 |
station->m_minstrelTable[i].ewmaProb = tempProb; |
618 |
m_minstrelTable[i].ewmaProb = tempProb; |
| 648 |
|
619 |
|
| 649 |
/// calculating throughput |
620 |
/// calculating throughput |
| 650 |
station->m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds()); |
621 |
m_minstrelTable[i].throughput = tempProb * (1000000 / txTime.GetMicroSeconds()); |
| 651 |
|
622 |
|
| 652 |
} |
623 |
} |
| 653 |
|
624 |
|
| 654 |
/// bookeeping |
625 |
/// bookeeping |
| 655 |
station->m_minstrelTable[i].prevNumRateAttempt = station->m_minstrelTable[i].numRateAttempt; |
626 |
m_minstrelTable[i].prevNumRateAttempt = m_minstrelTable[i].numRateAttempt; |
| 656 |
station->m_minstrelTable[i].prevNumRateSuccess = station->m_minstrelTable[i].numRateSuccess; |
627 |
m_minstrelTable[i].prevNumRateSuccess = m_minstrelTable[i].numRateSuccess; |
| 657 |
station->m_minstrelTable[i].numRateSuccess = 0; |
628 |
m_minstrelTable[i].numRateSuccess = 0; |
| 658 |
station->m_minstrelTable[i].numRateAttempt = 0; |
629 |
m_minstrelTable[i].numRateAttempt = 0; |
| 659 |
|
630 |
|
| 660 |
/// Sample less often below 10% and above 95% of success |
631 |
/// Sample less often below 10% and above 95% of success |
| 661 |
if ((station->m_minstrelTable[i].ewmaProb > 17100) || (station->m_minstrelTable[i].ewmaProb < 1800)) |
632 |
if ((m_minstrelTable[i].ewmaProb > 17100) || (m_minstrelTable[i].ewmaProb < 1800)) |
| 662 |
{ |
633 |
{ |
| 663 |
/** |
634 |
/** |
| 664 |
* retry count denotes the number of retries permitted for each rate |
635 |
* retry count denotes the number of retries permitted for each rate |
| 665 |
* # retry_count/2 |
636 |
* # retry_count/2 |
| 666 |
*/ |
637 |
*/ |
| 667 |
station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount >> 1; |
638 |
m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount >> 1; |
| 668 |
if (station->m_minstrelTable[i].adjustedRetryCount > 2) |
639 |
if (m_minstrelTable[i].adjustedRetryCount > 2) |
| 669 |
{ |
640 |
{ |
| 670 |
station->m_minstrelTable[i].adjustedRetryCount = 2 ; |
641 |
m_minstrelTable[i].adjustedRetryCount = 2 ; |
| 671 |
} |
642 |
} |
| 672 |
} |
643 |
} |
| 673 |
else |
644 |
else |
| 674 |
{ |
645 |
{ |
| 675 |
station->m_minstrelTable[i].adjustedRetryCount = station->m_minstrelTable[i].retryCount; |
646 |
m_minstrelTable[i].adjustedRetryCount = m_minstrelTable[i].retryCount; |
| 676 |
} |
647 |
} |
| 677 |
|
648 |
|
| 678 |
/// if it's 0 allow one retry limit |
649 |
/// if it's 0 allow one retry limit |
| 679 |
if (station->m_minstrelTable[i].adjustedRetryCount == 0) |
650 |
if (m_minstrelTable[i].adjustedRetryCount == 0) |
| 680 |
{ |
651 |
{ |
| 681 |
station->m_minstrelTable[i].adjustedRetryCount = 1; |
652 |
m_minstrelTable[i].adjustedRetryCount = 1; |
| 682 |
} |
653 |
} |
| 683 |
} |
654 |
} |
| 684 |
|
655 |
|
|
|
| 686 |
uint32_t max_prob = 0, index_max_prob =0, max_tp =0, index_max_tp=0, index_max_tp2=0; |
657 |
uint32_t max_prob = 0, index_max_prob =0, max_tp =0, index_max_tp=0, index_max_tp2=0; |
| 687 |
|
658 |
|
| 688 |
/// go find max throughput, second maximum throughput, high probability succ |
659 |
/// go find max throughput, second maximum throughput, high probability succ |
| 689 |
for (uint32_t i =0; i < GetNSupported (station); i++) |
660 |
for (uint32_t i =0; i < m_nsupported; i++) |
| 690 |
{ |
661 |
{ |
| 691 |
NS_LOG_DEBUG ("throughput" << station->m_minstrelTable[i].throughput << |
662 |
NS_LOG_DEBUG ("throughput" << m_minstrelTable[i].throughput << |
| 692 |
"\n ewma" << station->m_minstrelTable[i].ewmaProb); |
663 |
"\n ewma" << m_minstrelTable[i].ewmaProb); |
| 693 |
|
664 |
|
| 694 |
if (max_tp < station->m_minstrelTable[i].throughput) |
665 |
if (max_tp < m_minstrelTable[i].throughput) |
| 695 |
{ |
666 |
{ |
| 696 |
index_max_tp = i; |
667 |
index_max_tp = i; |
| 697 |
max_tp = station->m_minstrelTable[i].throughput; |
668 |
max_tp = m_minstrelTable[i].throughput; |
| 698 |
} |
669 |
} |
| 699 |
|
670 |
|
| 700 |
if (max_prob < station->m_minstrelTable[i].ewmaProb) |
671 |
if (max_prob < m_minstrelTable[i].ewmaProb) |
| 701 |
{ |
672 |
{ |
| 702 |
index_max_prob = i; |
673 |
index_max_prob = i; |
| 703 |
max_prob = station->m_minstrelTable[i].ewmaProb; |
674 |
max_prob = m_minstrelTable[i].ewmaProb; |
| 704 |
} |
675 |
} |
| 705 |
} |
676 |
} |
| 706 |
|
677 |
|
| 707 |
|
678 |
|
| 708 |
max_tp = 0; |
679 |
max_tp = 0; |
| 709 |
/// find the second highest max |
680 |
/// find the second highest max |
| 710 |
for (uint32_t i =0; i < GetNSupported (station); i++) |
681 |
for (uint32_t i =0; i < m_nsupported; i++) |
| 711 |
{ |
682 |
{ |
| 712 |
if ((i != index_max_tp) && (max_tp < station->m_minstrelTable[i].throughput)) |
683 |
if ((i != index_max_tp) && (max_tp < m_minstrelTable[i].throughput)) |
| 713 |
{ |
684 |
{ |
| 714 |
index_max_tp2 = i; |
685 |
index_max_tp2 = i; |
| 715 |
max_tp = station->m_minstrelTable[i].throughput; |
686 |
max_tp = m_minstrelTable[i].throughput; |
| 716 |
} |
687 |
} |
| 717 |
} |
688 |
} |
| 718 |
|
689 |
|
|
|
| 737 |
{ |
708 |
{ |
| 738 |
NS_LOG_DEBUG ("RateInit="<<station); |
709 |
NS_LOG_DEBUG ("RateInit="<<station); |
| 739 |
|
710 |
|
| 740 |
for (uint32_t i = 0; i < GetNSupported (station); i++) |
711 |
for (uint32_t i = 0; i < m_nsupported; i++) |
| 741 |
{ |
712 |
{ |
| 742 |
station->m_minstrelTable[i].numRateAttempt = 0; |
713 |
m_minstrelTable[i].numRateAttempt = 0; |
| 743 |
station->m_minstrelTable[i].numRateSuccess = 0; |
714 |
m_minstrelTable[i].numRateSuccess = 0; |
| 744 |
station->m_minstrelTable[i].prob = 0; |
715 |
m_minstrelTable[i].prob = 0; |
| 745 |
station->m_minstrelTable[i].ewmaProb = 0; |
716 |
m_minstrelTable[i].ewmaProb = 0; |
| 746 |
station->m_minstrelTable[i].prevNumRateAttempt = 0; |
717 |
m_minstrelTable[i].prevNumRateAttempt = 0; |
| 747 |
station->m_minstrelTable[i].prevNumRateSuccess = 0; |
718 |
m_minstrelTable[i].prevNumRateSuccess = 0; |
| 748 |
station->m_minstrelTable[i].successHist = 0; |
719 |
m_minstrelTable[i].successHist = 0; |
| 749 |
station->m_minstrelTable[i].attemptHist = 0; |
720 |
m_minstrelTable[i].attemptHist = 0; |
| 750 |
station->m_minstrelTable[i].throughput = 0; |
721 |
m_minstrelTable[i].throughput = 0; |
| 751 |
station->m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i)); |
722 |
m_minstrelTable[i].perfectTxTime = GetCalcTxTime (GetSupported (station, i)); |
| 752 |
station->m_minstrelTable[i].retryCount = 1; |
723 |
m_minstrelTable[i].retryCount = 1; |
| 753 |
station->m_minstrelTable[i].adjustedRetryCount = 1; |
724 |
m_minstrelTable[i].adjustedRetryCount = 1; |
| 754 |
} |
725 |
} |
| 755 |
} |
726 |
} |
| 756 |
|
727 |
|
|
|
| 762 |
station->m_col = station->m_index = 0; |
733 |
station->m_col = station->m_index = 0; |
| 763 |
|
734 |
|
| 764 |
/// for off-seting to make rates fall between 0 and numrates |
735 |
/// for off-seting to make rates fall between 0 and numrates |
| 765 |
uint32_t numSampleRates = GetNSupported (station); |
736 |
uint32_t numSampleRates = m_nsupported; |
| 766 |
|
737 |
|
| 767 |
uint32_t newIndex; |
738 |
uint32_t newIndex; |
| 768 |
for (uint32_t col = 0; col < m_sampleCol; col++) |
739 |
for (uint32_t col = 0; col < m_sampleCol; col++) |
|
|
| 778 |
newIndex = (i + (uint32_t)uv.GetValue ()) % numSampleRates; |
749 |
newIndex = (i + (uint32_t)uv.GetValue ()) % numSampleRates; |
| 779 |
|
750 |
|
| 780 |
/// this loop is used for filling in other uninitilized places |
751 |
/// this loop is used for filling in other uninitilized places |
| 781 |
while (station->m_sampleTable[newIndex][col] != 0) |
752 |
while (m_sampleTable[newIndex][col] != 0) |
| 782 |
{ |
753 |
{ |
| 783 |
newIndex = (newIndex + 1)%GetNSupported (station); |
754 |
newIndex = (newIndex + 1) % m_nsupported; |
| 784 |
} |
755 |
} |
| 785 |
station->m_sampleTable[newIndex][col] = i; |
756 |
m_sampleTable[newIndex][col] = i; |
| 786 |
|
757 |
|
| 787 |
} |
758 |
} |
| 788 |
} |
759 |
} |
|
|
| 793 |
{ |
764 |
{ |
| 794 |
NS_LOG_DEBUG ("PrintSampleTable="<<station); |
765 |
NS_LOG_DEBUG ("PrintSampleTable="<<station); |
| 795 |
|
766 |
|
| 796 |
uint32_t numSampleRates = GetNSupported (station); |
767 |
uint32_t numSampleRates = m_nsupported; |
| 797 |
for (uint32_t i = 0; i < numSampleRates; i++) |
768 |
for (uint32_t i = 0; i < numSampleRates; i++) |
| 798 |
{ |
769 |
{ |
| 799 |
for (uint32_t j = 0; j < m_sampleCol; j++) |
770 |
for (uint32_t j = 0; j < m_sampleCol; j++) |
| 800 |
{ |
771 |
{ |
| 801 |
std::cout << station->m_sampleTable[i][j] << "\t"; |
772 |
std::cout << m_sampleTable[i][j] << "\t"; |
| 802 |
} |
773 |
} |
| 803 |
std::cout << std::endl; |
774 |
std::cout << std::endl; |
| 804 |
} |
775 |
} |
|
|
| 809 |
{ |
780 |
{ |
| 810 |
NS_LOG_DEBUG ("PrintTable="<<station); |
781 |
NS_LOG_DEBUG ("PrintTable="<<station); |
| 811 |
|
782 |
|
| 812 |
for (uint32_t i=0; i < GetNSupported (station); i++) |
783 |
for (uint32_t i=0; i < m_nsupported; i++) |
| 813 |
{ |
784 |
{ |
| 814 |
std::cout << "index(" << i << ") = " << station->m_minstrelTable[i].perfectTxTime<< "\n"; |
785 |
std::cout << "index(" << i << ") = " << m_minstrelTable[i].perfectTxTime<< "\n"; |
| 815 |
} |
786 |
} |
| 816 |
} |
787 |
} |
| 817 |
|
788 |
|