📄 soft_ap.c
字号:
if ((pEntry->Sst != SST_ASSOC) && (pEntry->NoDataIdleCount >= MAC_TABLE_ASSOC_TIMEOUT))
{
DBGPRINT(RT_DEBUG_TRACE, "%02x:%02x:%02x:%02x:%02x:%02x fail to complete ASSOC in %d sec\n",
pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
pEntry->Addr[4],pEntry->Addr[5],MAC_TABLE_ASSOC_TIMEOUT);
MacTableDeleteEntry(pAd, pEntry->Addr);
continue;
}
// 1. check if there's any associated STA in power-save mode. this affects outgoing
// MCAST/BCAST frames should be stored in PSQ till DtimCount=0
if (pEntry->PsMode == PWR_SAVE)
pAd->MacTab.fAnyStationInPsm = TRUE;
// 2. delete those MAC entry that has been idle for a long time
if (pEntry->NoDataIdleCount >= MAC_TABLE_AGEOUT_TIME)
{
DBGPRINT(RT_DEBUG_TRACE, "ageout %02x:%02x:%02x:%02x:%02x:%02x after %d-sec silence\n",
pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
pEntry->Addr[4],pEntry->Addr[5],MAC_TABLE_AGEOUT_TIME);
ApLogEvent(pAd, pEntry->Addr, EVENT_AGED_OUT, pEntry->ApIdx);
//notify 802.1x-deamon to discard the sta
RTMPHandleNotify8021xDiscardSta(pAd, pEntry);
MacTableDeleteEntry(pAd, pEntry->Addr);
continue;
}
RTMP_SEM_LOCK(&pAd->MacTabLock, IrqFlags);
// 3. garbage collect the PsQueue if the STA has being idle for a while
if (pEntry->PsQueue.Head)
{
pEntry->PsQIdleCount ++;
if (pEntry->PsQIdleCount > 12) // Patch for WMM-PS 4.8
{
CleanupPsQueue(pAd, &pEntry->PsQueue);
pEntry->PsQIdleCount = 0;
}
}
else
pEntry->PsQIdleCount = 0;
RTMP_SEM_UNLOCK(&pAd->MacTabLock, IrqFlags);
}
// 4. garbage collect pAd->MacTab.McastPsQueue if backlogged MCAST/BCAST frames
// stale in queue. Since MCAST/BCAST frames always been sent out whenever
// DtimCount==0, the only case to let them stale is surprise removal of the NIC,
// so that ASIC-based Tbcn interrupt stops and DtimCount dead.
#ifndef THREAD_ISR
RTMP_SEM_LOCK(&pAd->MacTabLock, IrqFlags);
#else
RTMP_IRQ_LOCK(IrqFlags);
#endif
if (pAd->MacTab.McastPsQueue.Head)
{
pAd->MacTab.PsQIdleCount ++;
if (pAd->MacTab.PsQIdleCount > 1)
{
CleanupPsQueue(pAd, &pAd->MacTab.McastPsQueue);
pAd->MacTab.PsQIdleCount = 0;
}
}
else
pAd->MacTab.PsQIdleCount = 0;
#ifndef THREAD_ISR
RTMP_SEM_UNLOCK(&pAd->MacTabLock, IrqFlags);
#else
RTMP_IRQ_UNLOCK(IrqFlags);
#endif
}
/*
==========================================================================
Description:
Look up a STA MAC table. Return its Sst to decide if an incoming
frame from this STA or an outgoing frame to this STA is permitted.
Return:
==========================================================================
*/
MAC_TABLE_ENTRY *SsPsInquiry(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
OUT SST *Sst,
OUT USHORT *Aid,
OUT UCHAR *PsMode,
OUT UCHAR *Rate)
{
MAC_TABLE_ENTRY *pEntry = NULL;
if (MAC_ADDR_IS_GROUP(pAddr)) // mcast & broadcast address
{
*Sst = SST_ASSOC;
*Aid = 0;
*PsMode = PWR_ACTIVE;
//*Rate = pAd->PortCfg.MlmeRate; //pAd->PortCfg.MaxBasicRate;
if (pAd->PortCfg.PhyMode == PHY_11A)
*Rate = RATE_6;
else
*Rate = RATE_11;
}
else // unicast address
{
pEntry = MacTableLookup(pAd, pAddr);
if (pEntry)
{
*Sst = pEntry->Sst;
*Aid = pEntry->Aid;
*PsMode = pEntry->PsMode;
if((pAd->PortCfg.MBSSID[pEntry->ApIdx].AuthMode >= Ndis802_11AuthModeWPA) && (pEntry->GTKState != REKEY_ESTABLISHED))
{
if (pAd->PortCfg.PhyMode == PHY_11A)
*Rate = RATE_6;
else
*Rate = RATE_11;
}
else
*Rate = pEntry->CurrTxRate;
}
else
{
*Sst = SST_NOT_AUTH;
*Aid = 0;
*PsMode = PWR_ACTIVE;
//*Rate = pAd->PortCfg.MlmeRate; //pAd->PortCfg.MaxBasicRate;
if (pAd->PortCfg.PhyMode == PHY_11A)
*Rate = RATE_6;
else
*Rate = RATE_11;
}
}
return pEntry;
}
#if BIG_ENDIAN == FALSE
extern unsigned long get_cmos_time(void);
#endif
/*
==========================================================================
Description:
This routine is called to log a specific event into the event table.
The table is a QUERY-n-CLEAR array that stop at full.
==========================================================================
*/
VOID ApLogEvent(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN USHORT Event,
IN UCHAR apidx)
{
if (pAd->EventTab.Num < MAX_NUM_OF_EVENT)
{
RT_802_11_EVENT_LOG *pLog = &pAd->EventTab.Log[pAd->EventTab.Num];
pLog->SystemTime = jiffies;
COPY_MAC_ADDR(&pLog->Addr, pAddr);
pLog->Event = Event;
pLog->ApIdx = apidx;
DBGPRINT(RT_DEBUG_TRACE,"LOG#%d %02x:%02x:%02x:%02x:%02x:%02x %s\n",
pAd->EventTab.Num, pAddr[0], pAddr[1], pAddr[2],
pAddr[3], pAddr[4], pAddr[5], pEventText[Event]);
pAd->EventTab.Num += 1;
}
}
/*
==========================================================================
Description:
Update ERP IE and CapabilityInfo based on STA association status.
The result will be auto updated into the next outgoing BEACON in next
TBTT interrupt service routine
==========================================================================
*/
VOID ApUpdateCapabilityAndErpIe(
IN PRTMP_ADAPTER pAd)
{
UCHAR i, ErpIeContent = 0, apidx;
BOOLEAN ShortSlotCapable = (BOOLEAN)pAd->PortCfg.UseShortSlotTime;
if ((pAd->PortCfg.PhyMode == PHY_11A) || (pAd->PortCfg.PhyMode == PHY_11B))
return;
for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
{
PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
if ((pEntry->Valid != TRUE) || (pEntry->Sst != SST_ASSOC))
continue;
// at least one 11b client associated, turn on ERP.NonERPPresent bit
// almost all 11b client won't support "Short Slot" time, turn off for maximum compatibility
if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
{
ShortSlotCapable = FALSE;
ErpIeContent |= 0x01;
}
// at least one client can't support short slot
if ((pEntry->CapabilityInfo & 0x0400) == 0)
ShortSlotCapable = FALSE;
}
// decide ErpIR.UseProtection bit, depending on pAd->PortCfg.UseBGProtection
// AUTO (0): UseProtection = 1 if any 11b STA associated
// ON (1): always USE protection
// OFF (2): always NOT USE protection
if (pAd->PortCfg.UseBGProtection == 0)
{
ErpIeContent = (ErpIeContent)? 0x03 : 0x00;
if ((pAd->Mlme.LastOLBCDetectTime + (5 * HZ)) > pAd->Mlme.Now32) // legacy BSS exit within 5 sec
{
DBGPRINT(RT_DEBUG_INFO, "ApUpdateCapabilityAndErpIe - Legacy 802.11b BSS overlaped\n");
ErpIeContent |= 0x02; // set Use_Protection bit
}
}
else if (pAd->PortCfg.UseBGProtection == 1)
ErpIeContent |= 0x02;
else
;
if((pAd->PortCfg.TxPreamble == Rt802_11PreambleLong) || (ApCheckLongPreambleSTA(pAd) == TRUE))
{
if (pAd->PortCfg.TxPreambleInUsed != Rt802_11PreambleLong)
MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
pAd->Mlme.ErpIeContent = (ErpIeContent | 0x04);
}
else
{
if (pAd->PortCfg.TxPreambleInUsed != Rt802_11PreambleShort)
MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
pAd->Mlme.ErpIeContent = ErpIeContent;
}
//
// deicide CapabilityInfo.ShortSlotTime bit
//
for (apidx = 0; apidx < pAd->PortCfg.BssidNum; apidx++)
{
if (ShortSlotCapable)
pAd->PortCfg.MBSSID[apidx].CapabilityInfo |= 0x0400;
else
pAd->PortCfg.MBSSID[apidx].CapabilityInfo &= 0xfbff;
DBGPRINT(RT_DEBUG_INFO, "ApUpdateCapabilityAndErpIe IF(ra%d)- Capability= 0x%04x, ERP is 0x%02x\n",
apidx, pAd->PortCfg.MBSSID[apidx].CapabilityInfo, pAd->Mlme.ErpIeContent);
}
AsicSetSlotTime(pAd, ShortSlotCapable);
}
/*
==========================================================================
Description:
Check to see the exist of long preamble STA in associated list
==========================================================================
*/
BOOLEAN ApCheckLongPreambleSTA(
IN PRTMP_ADAPTER pAd)
{
UCHAR i;
for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
{
PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
if ((pEntry->Valid != TRUE) || (pEntry->Sst != SST_ASSOC))
continue;
if (!CAP_IS_SHORT_PREAMBLE_ON(pEntry->CapabilityInfo))
{
DBGPRINT(RT_DEBUG_TRACE, "Long preamble capable STA exist\n");
return TRUE;
}
}
return FALSE;
}
BOOLEAN ApCheckAccessControlList(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr,
IN UCHAR Apidx)
{
BOOLEAN Result = TRUE;
if (pAd->PortCfg.MBSSID[Apidx].AccessControlList.Policy == 0) // ACL is disabled
Result = TRUE;
else
{
ULONG i;
if (pAd->PortCfg.MBSSID[Apidx].AccessControlList.Policy == 1) // ACL is a positive list
Result = FALSE;
else // ACL is a negative list
Result = TRUE;
for (i=0; i<pAd->PortCfg.MBSSID[Apidx].AccessControlList.Num; i++)
{
if (MAC_ADDR_EQUAL(pAddr, pAd->PortCfg.MBSSID[Apidx].AccessControlList.Entry[i].Addr))
{
Result = !Result;
break;
}
}
}
if (Result == FALSE)
{
DBGPRINT(RT_DEBUG_TRACE, "%02x:%02x:%02x:%02x:%02x:%02x failed ACL checking\n",
pAddr[0],pAddr[1],pAddr[2],pAddr[3],pAddr[4],pAddr[5]);
}
return Result;
}
VOID ApUpdateAccessControlList(
IN PRTMP_ADAPTER pAd,
IN UCHAR Apidx)
{
USHORT AclIdx, MacIdx;
BOOLEAN Matched;
// ACL is disabled. do nothing about the MAC table
if (pAd->PortCfg.MBSSID[Apidx].AccessControlList.Policy == 0)
return;
for (MacIdx=0; MacIdx < MAX_LEN_OF_MAC_TABLE; MacIdx++)
{
if (! pAd->MacTab.Content[MacIdx].Valid)
continue;
Matched = FALSE;
for (AclIdx = 0; AclIdx < pAd->PortCfg.MBSSID[Apidx].AccessControlList.Num; AclIdx++)
{
if (MAC_ADDR_EQUAL(&pAd->MacTab.Content[MacIdx].Addr, pAd->PortCfg.MBSSID[Apidx].AccessControlList.Entry[AclIdx].Addr))
{
Matched = TRUE;
break;
}
}
if ((Matched == FALSE) && (pAd->PortCfg.MBSSID[Apidx].AccessControlList.Policy == 1))
{
DBGPRINT(RT_DEBUG_TRACE, "STA not on positive ACL. remove it...\n");
MacTableDeleteEntry(pAd, pAd->MacTab.Content[MacIdx].Addr);
}
else if ((Matched == TRUE) && (pAd->PortCfg.MBSSID[Apidx].AccessControlList.Policy == 2))
{
DBGPRINT(RT_DEBUG_TRACE, "STA on negative ACL. remove it...\n");
MacTableDeleteEntry(pAd, pAd->MacTab.Content[MacIdx].Addr);
}
}
}
UCHAR APAutoSelectChannel(
IN PRTMP_ADAPTER pAd)
{
UCHAR ch, i;
UCHAR dirtyness[MAX_NUM_OF_CHANNELS+1], dirty;
UCHAR max_rssi[MAX_NUM_OF_CHANNELS+1];
ULONG FalseCca, FcsError;
BOOLEAN bFindIt = FALSE;
// passive scan. collect statistics
NdisZeroMemory(dirtyness, MAX_NUM_OF_CHANNELS+1);
if (pAd->PortCfg.PhyMode == PHY_11A)
{
if (pAd->PortCfg.RadarDetect.IEEE80211H)
{
while(TRUE)
{
struct timeval tv;
do_gettimeofday(&tv);
ch = pAd->ChannelList[tv.tv_usec%pAd->ChannelListNum].Channel;
if (ch == 0)
ch = FirstChannel(pAd);
// if (!RadarChannelCheck(pAd, ch))
// continue;
for (i=0; i<pAd->ChannelListNum; i++)
{
if (pAd->ChannelList[i].Channel == ch)
{
if (pAd->ChannelList[i].RemainingTimeForUse == 0)
bFindIt = TRUE;
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -