10#include "Minstrel_he.h"
12#define HE_GROUP_RATES 12
13#define HE_BANDWIDTHS 4
17#define HE_GetRateId(index,isHe) (int)(index%HE_GROUP_RATES)
18#define HE_GetGroupId(index,isHe) (int)(index/HE_GROUP_RATES)
19#define HE_GetIndex(grpId,rateId,isHe) (int)(grpId*HE_GROUP_RATES + rateId)
20#define HE_IsEqual(b1,g1,s1,b2,g2,s2) ((b1 == b2 && g1 == g2 && s1 ==s2) ? true:false)
22#define HE_SEED_r &NETWORK->ppstruDeviceList[0]->ulSeed[0],&NETWORK->ppstruDeviceList[0]->ulSeed[1]
23#define HE_rand01() (fn_NetSim_Utilities_GenerateRandomNo(HE_SEED_r)/NETSIM_RAND_MAX)
24#define HE_tSlot(phy) (phy->plmeCharacteristics.aSlotTime)
25#define HE_ackTime(phy) (phy->plmeCharacteristics.aSIFSTime + get_preamble_time(phy) + (getAckSize(phy) * 8)/phy->dControlFrameDataRate)
26#define HE_firstTransmissionTime(phy,byte,rate) (phy->plmeCharacteristics.aSIFSTime + get_preamble_time(phy)+ byte*8/rate)
27#define HE_transmissionTime(phy,byte,rate) (byte*8/rate)
29static Ptr_MinstrelHePerRemoteStation He_getMinstrelInfo(NETSIM_ID dev,NETSIM_ID ifid,NETSIM_ID recv)
31 Ptr_MinstrelHeWifiStation station = IEEE802_11_PHY(dev,ifid)->rateAdaptationData;
32 return station->minstrelHeInfo[recv];
36void He_InitMinstrel(NETSIM_ID nDevId,NETSIM_ID nifid){
38 Ptr_MinstrelHeWifiStation heWifiStation;
40 he_updateStatsTime = 100*1000;
41 he_lookAroundRate= 10;
45 heWifiStation = (Ptr_MinstrelHeWifiStation)calloc(1,
sizeof(MinstrelHeWifiStation));
46 heWifiStation->minstrelHeInfo = (Ptr_MinstrelHePerRemoteStation*)calloc(NETWORK->nDeviceCount+1,
sizeof(Ptr_MinstrelHePerRemoteStation));
47 heWifiStation->devId = nDevId;
48 heWifiStation->interfaceId = nifid;
49 for(i=0;i<=NETWORK->nDeviceCount;i++){
50 heWifiStation->minstrelHeInfo[i] = (Ptr_MinstrelHePerRemoteStation)calloc(1,
sizeof(MinstrelHePerRemoteStation));
51 heWifiStation->minstrelHeInfo[i]->remoteStationId = i;
52 heWifiStation->minstrelHeInfo[i]->stationId = nDevId;
53 heWifiStation->minstrelHeInfo[i]->stationInterface = nifid;
54 He_CheckInit(heWifiStation->minstrelHeInfo[i],nDevId,nifid);
56 IEEE802_11_PHY(nDevId,nifid)->rateAdaptationData = heWifiStation;
59static void He_CheckInit(Ptr_MinstrelHePerRemoteStation station,NETSIM_ID devid,NETSIM_ID ifid){
60 if(!station->isInitialized){
61 station->nextStatsUpdate = ldEventTime + he_updateStatsTime;
66 station->isInitialized=
true;
67 station->isSampling=
false;
68 station->isHe= (IEEE802_11_PHY(devid,ifid)->PhyType==HE);
69 station->longRetry= 0;
70 station->shortRetry= 0;
71 station->totalRetry= 0;
73 station->maxTpRate = 0;
74 station->maxTpRate2= 0;
75 station->maxProbRate= 0;
77 station->nGroup= HE_GROUPS;
78 station->nGroupRate= HE_GROUP_RATES;
81 station->phy = IEEE802_11_PHY(devid,ifid);
88 station->samplePacketCount= 0;
89 station->totalPacketCount= 0;
92 station->sampleRate = 0;
94 He_InitGroupTable(station);
95 He_InitSampleTable(station);
99static void He_InitSampleTable(Ptr_MinstrelHePerRemoteStation station){
102 station->sampleTable = calloc(station->nGroupRate,
sizeof(UINT*));
103 for(i=0;i<station->nGroupRate;i++){
104 station->sampleTable[i] = calloc(he_sampleCol,
sizeof(UINT));
105 for(j=0;j<he_sampleCol;j++)
106 station->sampleTable[i][j] = 10000;
111 for(j=0;j<he_sampleCol;j++){
112 for(i=0;i<station->nGroupRate;i++){
114 int random_var = (int)(station->nGroupRate*HE_rand01());
115 random_var = (i+random_var)%station->nGroupRate;
117 while(station->sampleTable[random_var][j] != 10000){
118 random_var = (random_var + 1)%station->nGroupRate;
120 station->sampleTable[random_var][j] = i;
125static void He_InitGroupTable(Ptr_MinstrelHePerRemoteStation station){
127 UINT i,j,ch,sgi,nss,maxCh,maxNss,startid;
129 station->
groupTable = calloc(station->nGroup,
sizeof(HE_GroupInfo));
134 for(ch=20;ch<=maxCh;ch*=2){
135 for(sgi=800;sgi<=3200;sgi*=2){
139 else if (sgi == 1600)
144 for(nss=1;nss<=maxNss;nss++){
145 PhyArray= get_phy_parameter_HE((
double)ch,nss);
148 if(HE_IsEqual(ch,sgi,nss,station->phy->dChannelBandwidth,station->phy->nGuardInterval,station->phy->NSS))
163 station->
groupTable[i].rateTable = calloc(station->nGroupRate,
sizeof(HeRateInfo));
165 for(j=0;j<station->nGroupRate;j++){
166 station->
groupTable[i].rateTable[j].currNumAttempt = 0;
167 station->
groupTable[i].rateTable[j].currNumSuccess = 0;
170 station->
groupTable[i].rateTable[j].numSampleSkipped= 0;
172 station->
groupTable[i].rateTable[j].prevNumAttempt= 0;
173 station->
groupTable[i].rateTable[j].prevNumSuccess= 0;
175 station->
groupTable[i].rateTable[j].rate= PhyArray[j+startid].dDataRate;
179 station->
groupTable[i].rateTable[j].totalNumAttempt= 0;
180 station->
groupTable[i].rateTable[j].totalNumSuccess= 0;
182 if(station->
groupTable[i].rateTable[j].rate <= 0)
193 station->maxTpRate= He_GetHighestIndex(station);
194 station->maxTpRate2 = He_GetLowestIndex(station);
195 station->maxProbRate = He_GetLowestIndex(station);
196 station->trRate = station->maxTpRate;
200void He_DoReportAmpduStatus(NETSIM_ID devid,NETSIM_ID ifid,NETSIM_ID recvid,UINT success,UINT failed){
201 UINT groupId, rateId;
202 Ptr_MinstrelHePerRemoteStation station = He_getMinstrelInfo(devid,ifid,recvid);
203 if(!station->isInitialized)
208 station->
ampduLen += success + failed;
211 He_UpdatePacketCounter(station,success,failed);
212 groupId = HE_GetGroupId(station->trRate,station->isHe);
213 rateId = HE_GetRateId(station->trRate,station->isHe);
216 station->
groupTable[groupId].rateTable[rateId].currNumAttempt += success + failed;
217 station->
groupTable[groupId].rateTable[rateId].currNumSuccess += success;
219 if(success== 0 && station->longRetry < He_CountRetries(station)){
221 He_UpdateRate(station);
224 station->isSampling =
false;
225 He_UpdateRetry(station);
227 if(ldEventTime >= station->nextStatsUpdate)
228 He_UpdateStats(station);
230 station->trRate = He_FindRate(station);
234static void He_UpdatePacketCounter(Ptr_MinstrelHePerRemoteStation station,UINT success,UINT failed){
235 station->totalPacketCount += success + failed;
237 if(station->isSampling){
238 station->samplePacketCount += success + failed;
242 if(station->totalPacketCount < 0){
243 station->samplePacketCount = 0;
244 station->totalPacketCount = 0;
254static void He_UpdateRetry(Ptr_MinstrelHePerRemoteStation station){
255 station->totalRetry += station->longRetry + station->shortRetry;
256 station->shortRetry = 0;
257 station->longRetry = 0;
260static void He_UpdateStats(Ptr_MinstrelHePerRemoteStation station){
264 station->nextStatsUpdate = ldEventTime + he_updateStatsTime;
277 for(i=0;i<station->nGroup;i++){
280 for(j=0;j<station->nGroupRate;j++){
288 if(station->
groupTable[i].rateTable[j].currNumAttempt > 0){
289 station->
groupTable[i].rateTable[j].numSampleSkipped = 0;
290 tempProb = (18000* station->
groupTable[i].rateTable[j].currNumSuccess)/station->
groupTable[i].rateTable[j].currNumAttempt;
291 tempProb = tempProb/18000;
296 if(station->
groupTable[i].rateTable[j].totalNumAttempt == 0){
304 tempProb = (tempProb * he_ewmaWeight + (100 - he_ewmaWeight)*station->
groupTable[i].rateTable[j].
ewmaProb)/100;
313 station->
groupTable[i].rateTable[j].numSampleSkipped++;
316 station->
groupTable[i].rateTable[j].totalNumAttempt += station->
groupTable[i].rateTable[j].currNumAttempt;
317 station->
groupTable[i].rateTable[j].totalNumSuccess += station->
groupTable[i].rateTable[j].currNumSuccess;
318 station->
groupTable[i].rateTable[j].prevNumAttempt = station->
groupTable[i].rateTable[j].currNumAttempt;
319 station->
groupTable[i].rateTable[j].prevNumSuccess = station->
groupTable[i].rateTable[j].currNumSuccess;
320 station->
groupTable[i].rateTable[j].currNumAttempt = 0;
321 station->
groupTable[i].rateTable[j].currNumSuccess = 0;
326 He_SetStationThRate(station);
327 He_SetStationProbRate(station);
330 He_CalculateRetransmits(station,station->maxTpRate);
331 He_CalculateRetransmits(station,station->maxTpRate2);
332 He_CalculateRetransmits(station,station->maxProbRate);
335static void He_UpdateRate(Ptr_MinstrelHePerRemoteStation station){
350 UINT maxTpRateId, maxTpGrpId, maxTp2RateId, maxTp2GrpId, maxProbRateId, maxProbGrpId;
351 if(!station->isInitialized)
354 station->longRetry++;
356 maxTpRateId = HE_GetRateId(station->maxTpRate ,station->isHe);
357 maxTpGrpId = HE_GetGroupId(station->maxTpRate, station->isHe);
358 maxTp2RateId = HE_GetRateId(station->maxTpRate2, station->isHe);
359 maxTp2GrpId = HE_GetGroupId(station->maxTpRate2, station->isHe);
360 maxProbRateId = HE_GetRateId(station->maxProbRate, station->isHe);
361 maxProbGrpId = HE_GetGroupId(station->maxProbRate, station->isHe);
365 if (!station->isSampling) {
368 station->trRate = station->maxTpRate;
372 station->trRate = station->maxTpRate2;
376 station->trRate = station->maxProbRate;
379 fnNetSimError(
"Invalid Retry Condition..!");
387 if(station->longRetry < 1 + station->
groupTable[maxTp2GrpId].rateTable[maxTp2RateId].
retryCount){
388 station->trRate = station->maxTpRate2;
391 else if(station->longRetry >= 1 + station->
groupTable[maxTp2GrpId].rateTable[maxTp2RateId].
retryCount){
392 station->trRate = station->maxProbRate;
395 fnNetSimError(
"Invalid Retry Condition..!");
400static UINT He_FindRate(Ptr_MinstrelHePerRemoteStation station){
401 if(station->totalPacketCount == 0){
402 return station->maxTpRate;
407 UINT sampleIdx = He_GetNextSample(station);
409 UINT sampleGroupId = HE_GetGroupId(sampleIdx,station->isHe);
410 UINT sampleRateId = HE_GetRateId(sampleIdx,station->isHe);
417 if(sampleIdx != station->maxTpRate && sampleIdx != station->maxTpRate2 && sampleIdx != station->maxProbRate && station->
groupTable[sampleGroupId].rateTable[sampleRateId].
ewmaProb <= 95){
419 UINT maxTp2GrpId = HE_GetGroupId(station->maxTpRate2,station->isHe);
420 UINT maxTp2RateId = HE_GetRateId(station->maxTpRate2,station->isHe);
421 UINT maxProbRateId = HE_GetRateId(station->maxProbRate,station->isHe);
422 UINT maxProbGrpId = HE_GetGroupId(station->maxProbRate, station->isHe);
424 UINT sampleRate = (UINT)station->
groupTable[sampleGroupId].rateTable[sampleRateId].rate;
425 UINT maxTp2Rate = (UINT)station->
groupTable[maxTp2GrpId].rateTable[maxTp2RateId].rate;
426 UINT maxProbRate = (UINT)station->
groupTable[maxProbGrpId].rateTable[maxProbRateId].rate;
428 UINT sampleStream = station->
groupTable[sampleGroupId].streams;
429 UINT maxTpStream = station->
groupTable[maxTp2GrpId].streams;
433 if(sampleRate > maxTp2Rate || (sampleStream <= maxTpStream -1 && sampleRate > maxProbRate)){
435 station->isSampling =
true;
437 station->sampleRate = sampleIdx;
442 if(station->
groupTable[sampleGroupId].rateTable[sampleRateId].numSampleSkipped >= 20 && station->
sampleSlow++ <=2){
444 station->isSampling =
true;
446 station->sampleRate = sampleIdx;
458 return station->maxTpRate;
461static void He_SetStationThRate(Ptr_MinstrelHePerRemoteStation station){
464 BOOL isHe = station->isHe;
465 UINT grpmaxThId,grpmaxTh2Id;
466 double grpmaxTh,grpmaxThProb,grpmaxTh2,grpmaxTh2Prob,th,prob;
468 UINT maxThId = He_GetLowestIndex(station);
469 double maxTh = station->
groupTable[HE_GetGroupId(maxThId,isHe)].rateTable[HE_GetRateId(maxThId,isHe)].
throughput;
470 double maxThProb = station->
groupTable[HE_GetGroupId(maxThId,isHe)].rateTable[HE_GetRateId(maxThId,isHe)].
ewmaProb;
473 UINT maxTh2Id = He_GetLowestIndex(station);
474 double maxTh2 = station->
groupTable[HE_GetGroupId(maxTh2Id,isHe)].rateTable[HE_GetRateId(maxTh2Id,isHe)].
throughput;
475 double maxTh2Prob = station->
groupTable[HE_GetGroupId(maxTh2Id,isHe)].rateTable[HE_GetRateId(maxTh2Id,isHe)].
ewmaProb;
476 for(i=0;i<station->nGroup;i++){
487 for(j=0;j<station->nGroupRate;j++){
494 if(th > grpmaxTh || (th == grpmaxTh && prob > grpmaxThProb)){
495 grpmaxTh2 = grpmaxTh;
496 grpmaxTh2Prob = grpmaxThProb;
497 grpmaxTh2Id = grpmaxThId;
504 else if(th > grpmaxTh2 || (th == grpmaxTh2 && prob > grpmaxTh2Prob)){
506 grpmaxTh2Prob = prob;
515 if(grpmaxTh > maxTh || (grpmaxTh == maxTh && grpmaxThProb > maxThProb)){
518 maxTh2Prob = maxThProb;
521 maxThId = HE_GetIndex(i,grpmaxThId,station->isHe);
522 maxThProb = grpmaxThProb;
524 else if(grpmaxTh > maxTh2 || (grpmaxTh == maxTh2 && grpmaxThProb > maxTh2Prob)){
526 maxTh2Prob = grpmaxThProb;
527 maxTh2Id = HE_GetIndex(i,grpmaxThId,station->isHe);
530 if(grpmaxTh2 > maxTh2 || (grpmaxTh2 == maxTh2 && grpmaxTh2Prob > maxTh2Prob)){
532 maxTh2Prob = grpmaxTh2Prob;
533 maxTh2Id = HE_GetIndex(i,grpmaxTh2Id,station->isHe);
539 station->maxTpRate = maxThId;
540 station->maxTpRate2 = maxTh2Id;
543static void He_SetStationProbRate(Ptr_MinstrelHePerRemoteStation station){
544 UINT i,j,grpmaxProbId;
545 BOOL isHe = station->isHe;
546 double th,prob,grpmaxProb,grpmaxProbTh;
548 UINT maxProbId= He_GetLowestIndex(station);
549 double maxProb= station->
groupTable[HE_GetGroupId(maxProbId,isHe)].rateTable[HE_GetRateId(maxProbId,isHe)].
ewmaProb;
550 double maxProbTh= station->
groupTable[HE_GetGroupId(maxProbId,isHe)].rateTable[HE_GetRateId(maxProbId,isHe)].
throughput;
551 for(i=0;i<station->nGroup;i++){
558 for(j=0;j<station->nGroupRate;j++){
565 if(th > grpmaxProbTh){
572 if(prob > grpmaxProb){
581 if(grpmaxProb > 0.75){
582 if(grpmaxProbTh > maxProbTh){
583 maxProbTh = grpmaxProbTh;
584 maxProb = grpmaxProb;
585 maxProbId = HE_GetIndex(i,grpmaxProbId,station->isHe);
589 if(grpmaxProb > maxProb){
590 maxProbTh = grpmaxProbTh;
591 maxProb = grpmaxProb;
592 maxProbId = HE_GetIndex(i,grpmaxProbId,station->isHe);
596 station->maxProbRate = maxProbId;
600static UINT He_GetNextSample(Ptr_MinstrelHePerRemoteStation station){
602 UINT row = station->
groupTable[sampleGroup].row;
603 UINT col = station->
groupTable[sampleGroup].col;
604 UINT sampleIndex = station->sampleTable[row][col];
605 UINT rateIndex = HE_GetIndex(sampleGroup, sampleIndex,station->isHe);
606 He_SetNextSample(station);
611static void He_SetNextSample(Ptr_MinstrelHePerRemoteStation station){
625static double He_CalculateEwmsd(
double oldEwmsd,
double currentProb,
double ewmaProb,
double ewmaWeight){
626 double diff, incr, tmp;
629 diff = currentProb - ewmaProb;
630 incr = (ewmaWeight) * diff / 100;
631 tmp = oldEwmsd * oldEwmsd;
632 tmp = (100- ewmaWeight)* (tmp + diff * incr) / 100;
638static double He_CalculateThroughput(Ptr_MinstrelHePerRemoteStation station,UINT grpId, UINT rateId){
643 double rate = station->
groupTable[grpId].rateTable[rateId].rate;
645 double TrTime = HE_firstTransmissionTime(station->phy,1500,rate) + HE_transmissionTime(station->phy,1500,rate)*(nPackets - 1);
646 return (max(ewmaProb,0.9)*8*1500*nPackets)/TrTime;
650static void He_CalculateRetransmits(Ptr_MinstrelHePerRemoteStation station,UINT index){
651 UINT grpId = HE_GetGroupId(index,station->isHe);
652 UINT rateId = HE_GetRateId(index,station->isHe);
655 double cwTime,txTime,dataTxTime,rate;
667 rate = station->
groupTable[grpId].rateTable[rateId].rate;
669 dataTxTime = HE_firstTransmissionTime(station->phy,1500,rate) + HE_transmissionTime(station->phy,1500,rate) * (station->
avgAmpduLen - 1);
672 cwTime = (HE_tSlot(station->phy)*cw)>>1;
673 cw = min((cw<<1)| 1,cwMax);
674 cwTime += (HE_tSlot(station->phy)*cw)>>1;
675 cw = min((cw<<1)| 1,cwMax);
677 txTime = cwTime + 2*(dataTxTime + HE_ackTime(station->phy));
680 cwTime = (HE_tSlot(station->phy)*cw)>>1;
681 cw = min((cw<<1)| 1,cwMax);
682 txTime += dataTxTime + HE_ackTime(station->phy) + cwTime;
688BOOL He_DoNeedDataRetransmission(NETSIM_ID devid,NETSIM_ID ifid,NETSIM_ID recvid){
689 Ptr_MinstrelHePerRemoteStation station = He_getMinstrelInfo(devid,ifid,recvid);
690 return (station->longRetry < He_CountRetries(station));
693static UINT He_CountRetries(Ptr_MinstrelHePerRemoteStation station){
695 BOOL isHe = station->isHe;
696 UINT th = station->maxTpRate;
697 UINT th2 = station->maxTpRate2;
698 UINT prob = station->maxProbRate;
699 if(!station->isSampling){
707static UINT He_GetLowestIndex(Ptr_MinstrelHePerRemoteStation station){
711 while(!(
int)grpId < (
int)station->nGroup &&
715 if(grpId == station->nGroup)
716 fnNetSimError(
"No groups supported..!");
718 while(rateId < station->nGroupRate && !station->
groupTable[grpId].rateTable[rateId].
supported)
721 if(rateId == station->nGroupRate)
722 fnNetSimError(
"No rates supported...!");
724 return HE_GetIndex(grpId,rateId,station->isHe);
727static UINT He_GetHighestIndex(Ptr_MinstrelHePerRemoteStation station){
728 int grpId = station->nGroup -1;
729 int rateId = station->nGroupRate -1;
730 while(grpId >= 0 && !station->
groupTable[grpId].supported)
734 fnNetSimError(
"No groups supported..!");
740 fnNetSimError(
"No rates supported..!");
742 return HE_GetIndex(grpId,rateId,station->isHe);
747 Ptr_MinstrelHePerRemoteStation station = He_getMinstrelInfo(devid,ifid,recvid);
748 UINT grpId = HE_GetGroupId(station->trRate,station->isHe);
749 UINT rateId = HE_GetRateId(station->trRate,station->isHe);
750 UINT W = station->groupTable[grpId].chWidth;
751 UINT S = station->groupTable[grpId].streams;
753 if(station->groupTable[grpId].sgi == 800){
756 else if (station->groupTable[grpId].sgi == 1600){
762 return get_phy_parameter_HE(W,S)[r];
766void HE_Minstrel_Free(NETSIM_ID nDevId, NETSIM_ID nifid)
768#pragma message(__LOC__"Implement the HE_Minstrel_Free")
769IEEE802_11_PHY(nDevId,nifid)->rateAdaptationData = NULL;
Data structure for physical layer parameters.
Ptr_HE_GroupInfo groupTable
Table of groups with stats.
UINT sampleSlow
Number of times a slow rate was sampled.
UINT sampleWait
How many transmission attempts to wait until a new sample.
double ampduLen
Number of MPDUs tried since last update.
double avgAmpduLen
Average number of MPDUs in an A-MPDU.
UINT sampleGroup
The group that the sample rate belongs to.
UINT ampduPacketCount
Number of A-MPDUs transmitted since last update.
UINT sampleTries
Number of sample tries after waiting sampleWait.
UINT sampleCount
Max number of samples per update interval.
UINT retryCount
Retry limit.
BOOL retryUpdated
If number of retries was updated already.
BOOL supported
If the rate is supported.
double throughput
Throughput of this rate (in pkts per second).
double prob
Current probability within last time interval. (# frame success )/(# total frames)
double ewmsdProb
Exponential weighted moving standard deviation of probability.