📄 zdpsmon.c
字号:
#ifndef __ZDPSMON_C__
#define __ZDPSMON_C__
#include "zd80211.h"
#include "zddebug.h"
#define GetEntry(pMac) (((pMac->mac[3]) ^ (pMac->mac[4]) ^ (pMac->mac[5])) & (MAX_AID-1))
Hash_t *FreeHashList;
Hash_t HashBuf[MAX_RECORD];
Hash_t *HashTbl[MAX_RECORD];
Hash_t *sstByAid[MAX_RECORD];
U32 freeHashCount;
extern void zd1205_config_dyn_key(u8 DynKeyMode, u8 *pkey, int idx);
Hash_t *HashInsert(MacAddr_t *pMac);
void CleanupHash(Hash_t *hash)
{
memset(hash->mac, 0, 6);
hash->asoc = STATION_STATE_DIS_ASOC;
hash->auth = STATION_STATE_NOT_AUTH;
hash->psm = PSMODE_STA_ACTIVE;
hash->encryMode = WEP_NOT_USED;
hash->ZydasMode = 0;
hash->pkInstalled = 0;
hash->AlreadyIn = 0;
hash->ContSuccFrames = 0;
hash->ttl = 0;
hash->bValid = FALSE;
hash->Preamble = 0;
hash->keyLength = 0;
hash->KeyId = 0;
memset(hash->wepIv, 0, 4);
memset(&hash->TxSeed, 0, sizeof(Seedvar));
memset(&hash->RxSeed, 0, sizeof(Seedvar));
memset(&hash->TxMicKey, 0, sizeof(MICvar));
memset(&hash->RxMicKey, 0, sizeof(MICvar));
hash->SuccessFrames = 0;
hash->FailedFrames = 0;
hash->bJustRiseRate = FALSE;
hash->RiseConditionCount = 0;
hash->DownConditionCount = 0;
hash->vapId = 0;
#if defined(OFDM)
hash->bErpSta = TRUE;
#else
hash->bErpSta = FALSE;
#endif
}
void CleanupKeyInfo(Hash_t *hash)
{
hash->encryMode = WEP_NOT_USED;
hash->pkInstalled = 0;
hash->keyLength = 0;
hash->KeyId = 0;
memset(hash->wepIv, 0, 4);
memset(&hash->TxSeed, 0, sizeof(Seedvar));
memset(&hash->RxSeed, 0, sizeof(Seedvar));
memset(&hash->TxMicKey, 0, sizeof(MICvar));
memset(&hash->RxMicKey, 0, sizeof(MICvar));
}
void initHashBuf(void)
{
int i;
freeHashCount = MAX_RECORD;
for (i=0; i<MAX_AID; i++){ //from 0 to 31
HashBuf[i].pNext = &HashBuf[i+1];
sstByAid[i] = &HashBuf[i];
HashBuf[i].aid = i;
CleanupHash(&HashBuf[i]);
}
//aid 32 is here
HashBuf[MAX_AID].pNext = NULL;
sstByAid[MAX_AID] = &HashBuf[MAX_AID];
HashBuf[MAX_AID].aid = MAX_AID;
CleanupHash(&HashBuf[MAX_AID]);
FreeHashList = &HashBuf[1]; //by pass aid = 0
//deal with aid = 0
HashBuf[0].pNext = NULL;
}
Hash_t *allocHashBuf(void)
{
Hash_t *hash = NULL;
U32 flags;
//HSDEBUG("*****allocHashBuf*****");
flags = pdot11Obj->EnterCS();
if (FreeHashList != NULL){
hash = FreeHashList;
FreeHashList = FreeHashList->pNext;
hash->pNext = NULL;
freeHashCount--;
}
pdot11Obj->ExitCS(flags);
return hash;
}
void freeHashBuf(Hash_t *hash)
{
U32 flags;
//HSDEBUG("*****freeHashBuf*****");
flags = pdot11Obj->EnterCS();
if (hash->AlreadyIn){
if (mCurrConnUser > 0)
mCurrConnUser--;
if (hash->bErpSta == FALSE && mNumBOnlySta > 0)
{
mNumBOnlySta--;
if (mNumBOnlySta==0)
{
pdot11Obj->ConfigFlag &= ~NON_ERP_PRESENT_SET;
mErp.buf[2] &= ~NON_ERP_PRESENT;
}
}
}
if (hash->psm == PSMODE_POWER_SAVE){
if (mPsStaCnt > 0)
mPsStaCnt--;
}
#if defined(AMAC)
HW_CAM_ClearRollTbl(pdot11Obj, hash->aid);
#endif
CleanupHash(hash);
hash->pNext = FreeHashList;
FreeHashList = hash;
freeHashCount++;
pdot11Obj->ExitCS(flags);
}
void InitHashTbl(void)
{
int i;
for (i=0; i<MAX_RECORD; i++){
HashTbl[i] = NULL;
}
}
Hash_t *HashSearch(MacAddr_t *pMac)
{
U8 entry;
Hash_t *hash = NULL;
U32 flags;
U16 loopCheck = 0;
if (mBssType == INFRASTRUCTURE_BSS){
if (memcmp(&mBssId, pMac, 6) != 0){
return NULL;
}
else
return sstByAid[0];
}
//HSDEBUG("HashSearch");
entry = GetEntry(pMac);
flags = pdot11Obj->EnterCS();
if (HashTbl[entry] == NULL) {
goto exit;
}
else{
hash = HashTbl[entry];
do {
//to prevent hash->pNext equals to its self
if(loopCheck++ > 100)
{
printk("infinite loop occurs in %s\n", __FUNCTION__);
loopCheck = 0;
break;
}
if (memcmp(hash->mac, (U8 *)pMac, 6) == 0){
//HSDEBUG("Search got one");
goto exit;
}
else
hash = hash->pNext;
}while(hash != NULL);
}
exit:
pdot11Obj->ExitCS(flags);
if (hash){
#if 0
printf("macaddr = %02x:%02x:%02x:%02x:%02x:%02x\n",
hash->mac[0], hash->mac[1], hash->mac[2],
hash->mac[3], hash->mac[4], hash->mac[5]);
printf("asoc = %x\n", hash->asoc);
printf("auth = %x\n", hash->auth);
printf("psm = %x\n", hash->psm);
printf("aid = %x\n", hash->aid);
printf("lsInterval = %x\n", hash->lsInterval);
#endif
}
else
;//HSDEBUG("Search no one");
return hash;
}
Hash_t *HashInsert(MacAddr_t *pMac)
{
U8 entry;
Hash_t *hash;
U32 flags;
HSDEBUG("HashInsert");
if (mBssType == INFRASTRUCTURE_BSS){
hash = sstByAid[0];
memcpy(hash->mac, (U8 *)pMac, 6);
hash->ttl = HW_GetNow(pdot11Obj);
hash->bValid = TRUE;
return hash;
}
hash = allocHashBuf();
if (!hash){
HSDEBUG("No free one");
//Age Hash table
AgeHashTbl();
return NULL; // no free one
}
else{
entry = GetEntry(pMac);
HSDEBUG_V("entry", entry);
if (HashTbl[entry] == NULL){ //entry is null
HashTbl[entry] = hash;
HSDEBUG("Entry is null");
}
else{ //insert list head
flags = pdot11Obj->EnterCS();
hash->pNext = HashTbl[entry];
HashTbl[entry] = hash;
pdot11Obj->ExitCS(flags);
HSDEBUG("Insert to list head");
}
memcpy(hash->mac, (U8 *)pMac, 6);
hash->ttl = HW_GetNow(pdot11Obj);
hash->bValid = TRUE;
return hash;
}
}
BOOLEAN AgeHashTbl(void)
{
U32 now, ttl, idleTime;
U8 entry, firstLayer;
U16 loopCheck = 0;
int i;
MacAddr_t *pMac;
Hash_t *hash, *preHash = NULL;
BOOLEAN ret = FALSE;
HSDEBUG("*****AgeHashTbl*****");
now = HW_GetNow(pdot11Obj);
for (i=1; i<(MAX_AID+1); i++){
ttl = sstByAid[i]->ttl;
if (now > ttl)
idleTime = now - ttl;
else
idleTime = (0xffffffff - ttl) + now;
if (sstByAid[i]->bValid){
if (idleTime > IDLE_TIMEOUT ){
HSDEBUG("*****Age one*****");
HSDEBUG_V("aid", i);
HSDEBUG_V("now", now);
HSDEBUG_V("ttl", ttl);
HSDEBUG_V("idleTime", idleTime);
pMac = (MacAddr_t *)&sstByAid[i]->mac[0];
entry = GetEntry(pMac);
HSDEBUG_V("entry", entry);
hash = HashTbl[entry];
firstLayer = 1;
do {
// For AP only
if(loopCheck++ > 100)
{
printk("infinite loop occurs in %s\n", __FUNCTION__);
loopCheck = 0;
break;
}
if (hash == sstByAid[i]){
if (firstLayer == 1){
HSDEBUG("*****firstLayer*****");
if (hash->pNext != NULL)
HashTbl[entry] = hash->pNext;
else
HashTbl[entry] = NULL;
}
else{
HSDEBUG("*****Not firstLayer*****");
preHash->pNext = hash->pNext;
}
zd_CmdProcess(CMD_DISASOC, &hash->mac[0], ZD_INACTIVITY);
freeHashBuf(hash);
break;
}
else{
preHash = hash;
hash = hash->pNext;
firstLayer = 0;
}
}while(hash != NULL);
ret = TRUE;
}
else {
if (sstByAid[i]->ZydasMode == 1)
mZyDasModeClient = TRUE;
if (sstByAid[i]->bErpSta == FALSE && mMacMode != PURE_A_MODE){
pdot11Obj->ConfigFlag |= NON_ERP_PRESENT_SET;
pdot11Obj->ConfigFlag |= ENABLE_PROTECTION_SET;
if (sstByAid[i]->Preamble == 0){ //long preamble
pdot11Obj->ConfigFlag |= BARKER_PREAMBLE_SET;
}
}
}
}
}
//HSDEBUG_V("ret", ret);
return ret;
}
void ResetPSMonitor(void)
{
ZDEBUG("ResetPSMonitor");
initHashBuf();
InitHashTbl();
mPsStaCnt = 0;
}
Hash_t *RxInfoIndicate(MacAddr_t *sta, PsMode psm, U8 rate)
{
Hash_t *pHash;
ZDEBUG("RxInfoIndicate");
//if (isGroup(sta))
//return NULL;
pHash = HashSearch(sta);
if (!pHash){
if (mBssType == PSEUDO_IBSS){
pHash = HashInsert(sta);
if (!pHash)
return NULL;
else{
pHash->asoc = STATION_STATE_ASOC;
zd1205_dump_data(" HashInsert macAddr = ", (U8 *)&pHash->mac[0], 6);
goto updateInfo;
}
}
else
return NULL;
}
else{
PsMode oldPsm = pHash->psm;
StationState asoc = pHash->asoc;
updateInfo:
if (rate > pHash->MaxRate)
pHash->MaxRate = rate;
pHash->RxRate = rate;
pHash->ttl = HW_GetNow(pdot11Obj);
if (mBssType == AP_BSS){
if (psm == PSMODE_STA_ACTIVE){
if (oldPsm == PSMODE_POWER_SAVE){
StaWakeup(sta);
if (asoc == STATION_STATE_ASOC){
if (mPsStaCnt >0){
mPsStaCnt--;
}
}
}
}
else {
if (oldPsm == PSMODE_STA_ACTIVE){
if (asoc == STATION_STATE_ASOC){
if (mPsStaCnt < MAX_AID){
mPsStaCnt++;
}
}
}
else if (oldPsm == PSMODE_POWER_SAVE){
if (asoc == STATION_STATE_ASOC){
if (mPsStaCnt == 0)
mPsStaCnt++;
}
}
}
}
pHash->psm = psm;
}
return pHash;
}
void RxInfoUpdate(Hash_t *pHash, PsMode psm, U8 rate)
{
PsMode oldPsm = pHash->psm;
StationState asoc = pHash->asoc;
if (rate > pHash->MaxRate)
pHash->MaxRate = rate;
pHash->RxRate = rate;
pHash->ttl = HW_GetNow(pdot11Obj);
if (psm == PSMODE_STA_ACTIVE){
if (oldPsm == PSMODE_POWER_SAVE){
StaWakeup((MacAddr_t *)pHash->mac);
if (asoc == STATION_STATE_ASOC){
if (mPsStaCnt >0){
mPsStaCnt--;
}
}
}
}
else {
if (oldPsm == PSMODE_STA_ACTIVE){
if (asoc == STATION_STATE_ASOC){
if (mPsStaCnt < MAX_AID){
mPsStaCnt++;
}
}
}
else if (oldPsm == PSMODE_POWER_SAVE){
if (asoc == STATION_STATE_ASOC){
if (mPsStaCnt == 0)
mPsStaCnt++;
}
}
}
pHash->psm = psm;
}
BOOLEAN UpdateStaStatus(MacAddr_t *sta, StationState staSte, U8 vapId)
{
Hash_t *pHash;
U16 loopCheck = 0;
ZDEBUG("UpdateStaStatus");
if (mBssType == AP_BSS){
pHash = HashSearch(sta);
if (pHash)
goto UpdateStatus;
else{
if ((STATION_STATE_AUTH_OPEN == staSte) || (STATION_STATE_AUTH_KEY == staSte)){
if ((mCurrConnUser + 1) > mLimitedUser){
//AgeHashTbl();
return FALSE;
}
else{
pHash = HashInsert(sta);
if (!pHash)
return FALSE;
}
}
else
return FALSE;
}
}
else if (mBssType == INFRASTRUCTURE_BSS){
if ((STATION_STATE_AUTH_OPEN == staSte) || (STATION_STATE_AUTH_KEY == staSte)){
CleanupHash(sstByAid[0]);
pHash = HashInsert(sta);
} else {
pHash = sstByAid[0]; //use aid = 0 to store AP's info
}
}
else if (mBssType == INDEPENDENT_BSS){
pHash = HashSearch(sta);
if (pHash)
goto UpdateStatus;
else {
pHash = HashInsert(sta);
if (!pHash)
return FALSE;
else
zd1205_dump_data(" HashInsert macAddr = ", (U8 *)&pHash->mac[0], 6);
}
}
else
return FALSE;
UpdateStatus:
switch(staSte){
case STATION_STATE_AUTH_OPEN:
case STATION_STATE_AUTH_KEY:
pHash->auth = staSte;
break;
case STATION_STATE_ASOC:
if (mBssType == AP_BSS){
if (((mCurrConnUser + 1) > mLimitedUser) && (!pHash->AlreadyIn)){
return FALSE;
}
if (pHash->psm == PSMODE_POWER_SAVE){
if (mPsStaCnt > 0){
mPsStaCnt--;
}
}
pHash->asoc = STATION_STATE_ASOC;
/*if (!pHash->AlreadyIn){
pHash->AlreadyIn = 1;
mCurrConnUser++;
}*/
}else{
pHash->asoc = STATION_STATE_ASOC;
}
if (mBssType != INDEPENDENT_BSS)
CleanupKeyInfo(pHash);
memcpy(&pdot11Obj->CurrSsid[0], (U8 *)&mSsid, mSsid.buf[1]+2);
break;
case STATION_STATE_NOT_AUTH:
case STATION_STATE_DIS_ASOC:
if (mBssType == AP_BSS){
if (pHash->asoc == STATION_STATE_ASOC){
if (pHash->psm == PSMODE_POWER_SAVE){
FlushQ(pPsQ[pHash->aid]);
if (mPsStaCnt > 0){
mPsStaCnt--;
if (mPsStaCnt == 0){
FlushQ(pAwakeQ);
FlushQ(pPsQ[0]);
}
}
}
/*if (pHash->AlreadyIn){
pHash->AlreadyIn = 0;
mCurrConnUser--;
}*/
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -