⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soft_ap.c

📁 Ralink RT61 SoftAP Driver source code. RT61:MiniPCI
💻 C
📖 第 1 页 / 共 4 页
字号:
        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 + -