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

📄 mlme.c

📁 台湾RALink公司的 rt2570无线 802.11g 网卡的 驱动的源代码 ,支持linux2.4以上的 内河
💻 C
📖 第 1 页 / 共 5 页
字号:
			else
			{
				atomic_set(&(pAd->PortCfg.DataPacketsFromAP), 0);	
				MlmeCheckForPsmChange(pAd);
			}
		}
		else if (ADHOC_ON(pAd))
		{
			// If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
			// to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
			// join later.
			if ((pAd->PortCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < Now32) &&
				(pAd->MediaState == NdisMediaStateConnected))
			{
				DBGPRINT(RT_DEBUG_TRACE, "MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n");
				
				pAd->MediaState = NdisMediaStateDisconnected;
				NdisMIndicateStatus(pAd->AdapterHandle, NDIS_STATUS_MEDIA_DISCONNECT, (PVOID)NULL, 0);
				NdisMIndicateStatusComplete(pAd->AdapterHandle);
				
				// clean up previous SCAN result, add current BSS back to table if any
				BssTableDeleteEntry(&pAd->PortCfg.BssTab, &(pAd->PortCfg.Bssid));
				pAd->PortCfg.LastScanTime = Now32;
			}
			else
			{
				// if all 11b peers leave this BSS more than 5 seconds, update Tx rate
				if ((pAd->PortCfg.Channel <= 14)	&&
					(pAd->PortCfg.MaxTxRate <= RATE_11)	&&
					(pAd->PortCfg.MaxDesiredRate > RATE_11)	&&
					((pAd->PortCfg.Last11bBeaconRxTime + 5000) < Now32))
				{
					DBGPRINT(RT_DEBUG_TRACE, "last 11B peer left, update Tx rates\n");
					
					NdisMoveMemory(pAd->PortCfg.SupportedRates, pAd->PortCfg.IbssConfig.SupportedRates, MAX_LEN_OF_SUPPORTED_RATES);
					pAd->PortCfg.SupportedRatesLen = pAd->PortCfg.IbssConfig.SupportedRatesLen;
					RTUSBEnqueueInternalCmd(pAd, RT_OID_UPDATE_TX_RATE);
				}
			}
		}
		else
		{
			if ((pAd->PortCfg.bBlockAssoc == TRUE) && (pAd->PortCfg.LastMicErrorTime + (60 * 1000) < Now32))
			{
				pAd->PortCfg.bBlockAssoc = FALSE;
			}

			if ((pAd->PortCfg.AutoReconnect == TRUE) &&
				(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
				(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS)) &&
				(MlmeValidateSSID(pAd) == TRUE))
			{
				if (pAd->PortCfg.BssTab.BssNr==0)
				{
					MLME_SCAN_REQ_STRUCT	   ScanReq;
					CHAR					   BroadSsid[MAX_LEN_OF_SSID];
				
					if ((pAd->PortCfg.LastScanTime + 10 * 1000) < Now32)
					{
						DBGPRINT(RT_DEBUG_TRACE, "CNTL - No matching BSS, start a new scan\n");
	//					BroadSsid[0] = '\0';
						ScanParmFill(pAd, &ScanReq, BroadSsid, 0, BSS_ANY, SCAN_ACTIVE);
						MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
						pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
						// Reset Missed scan number
	//					pAd->PortCfg.IgnoredScanNumber = 0;
						pAd->PortCfg.LastScanTime = Now32;
					}
					else if (pAd->PortCfg.BssType == BSS_INDEP)	// Quit the forever scan when in a very clean room
						MlmeAutoReconnectLastSSID(pAd);					
				}
				else
				{
					if ((pAd->Mlme.PeriodicRound % 10) == 7)
					{
						if ((pAd->PortCfg.LastScanTime + 10 * 1000) < Now32)
						{
							//MlmeAutoScan(pAd);
							pAd->PortCfg.LastScanTime = Now32;
						}
						MlmeAutoReconnectLastSSID(pAd);
					}
					else if ((pAd->Mlme.PeriodicRound % 30) == 8)
					{
						MlmeEnqueue(pAd, 
								MLME_CNTL_STATE_MACHINE, 
								OID_802_11_BSSID_LIST_SCAN, 
								0, 
								NULL);
					}
					
				}
			}
		}

		RTUSBUp(pAd, (&(pAd->mlme_semaphore)));
	}while(0);

	if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
		(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
		(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)))
	{
		RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
	}

}

// IRQL = DISPATCH_LEVEL
VOID MlmeAutoScan(
    IN PRT2570ADAPTER pAd)
{
    // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
    if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
    {
        DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Driver auto scan\n");

        // tell CNTL state machine NOT to call NdisMSetInformationComplete() after completing
        // this request, because this request is initiated by driver itself.
        pAd->Mlme.CntlAux.CurrReqIsFromNdis = FALSE; 
        MlmeEnqueue(pAd, 
                    MLME_CNTL_STATE_MACHINE, 
                    OID_802_11_BSSID_LIST_SCAN, 
                    0, 
                    NULL);
	RTUSBUp(pAd, &pAd->mlme_semaphore);
    }
}
// IRQL = DISPATCH_LEVEL
VOID MlmeAutoRecoverNetwork(
    IN PRT2570ADAPTER pAd)
{
    // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
    if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
    {
        NDIS_802_11_SSID OidSsid;
        OidSsid.SsidLength = pAd->PortCfg.SsidLen;
        NdisMoveMemory(OidSsid.Ssid, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen);

        DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Driver auto recovering network - %s\n", pAd->PortCfg.Ssid);

        // tell CNTL state machine NOT to call NdisMSetInformationComplete() after completing
        // this request, because this request is initiated by driver itself.
        pAd->Mlme.CntlAux.CurrReqIsFromNdis = FALSE; 
                    
        MlmeEnqueue(pAd, 
                    MLME_CNTL_STATE_MACHINE, 
                    OID_802_11_SSID, 
                    sizeof(NDIS_802_11_SSID), 
                    &OidSsid);
	RTUSBUp(pAd, (&(pAd->mlme_semaphore)));
	//KeSetEvent(&pAd->MLMEEvent, 0, FALSE);			
    }
}

// IRQL = DISPATCH_LEVEL
VOID MlmeAutoReconnectLastSSID(
    IN PRT2570ADAPTER pAd)
{
    // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
    if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && (MlmeValidateSSID(pAd) == TRUE))
    {
        NDIS_802_11_SSID OidSsid;
        OidSsid.SsidLength = pAd->Mlme.CntlAux.SsidLen;
        NdisMoveMemory(OidSsid.Ssid, pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen);

        DBGPRINT(RT_DEBUG_TRACE, "Driver auto reconnect to last OID_802_11_SSID setting - %s\n", pAd->Mlme.CntlAux.Ssid);

		// We will only try this attemp once, therefore change the AutoReconnect flag afterwards.
        pAd->Mlme.CntlAux.CurrReqIsFromNdis = FALSE; 
                    
        MlmeEnqueue(pAd, 
                    MLME_CNTL_STATE_MACHINE, 
                    OID_802_11_SSID, 
                    sizeof(NDIS_802_11_SSID), 
                    &OidSsid);

	RTUSBUp(pAd, &pAd->mlme_semaphore);

    }
}

// Validate SSID for connection try and rescan purpose
// Valid SSID will have visible chars only.
// The valid length is from 0 to 32.
// IRQL = DISPATCH_LEVEL
BOOLEAN	MlmeValidateSSID(
    IN PRT2570ADAPTER pAd)
{
	NDIS_802_11_SSID OidSsid;
	ULONG	index;
	
	// Copy the SSID into local buffer
	OidSsid.SsidLength = pAd->Mlme.CntlAux.SsidLen;
	NdisMoveMemory(OidSsid.Ssid, pAd->Mlme.CntlAux.Ssid, pAd->Mlme.CntlAux.SsidLen);

	// First check the zero length "ANY" SSID
	if (OidSsid.SsidLength == 0)
		return (TRUE);
	else if (OidSsid.SsidLength > NDIS_802_11_LENGTH_SSID)
		return (FALSE);

	// Check each character value
	for (index = 0; index < OidSsid.SsidLength; index++)
	{
		if (OidSsid.Ssid[index] < 0x20)
			return (FALSE);
	}

	// All checked
	return (TRUE);
}

/*
    ==========================================================================
    Description:
        This routine checks if there're other APs out there capable for
        roaming. Caller should call this routine only when Massoc=TRUE and
        channel quality is below CQI_GOOD_THRESHOLD.
        
	IRQL = DISPATCH_LEVEL

    Output:
    ==========================================================================
 */
VOID MlmeCheckForRoaming(
    IN PRT2570ADAPTER pAd,
    IN ULONG    Now32)
{
	USHORT     i;
	BSS_TABLE  *pBssTab = &pAd->PortCfg.BssTab;
	BSS_TABLE  *pRoamTab = &pAd->Mlme.CntlAux.RoamTab;
	BSS_ENTRY  *pBss;

	DBGPRINT(RT_DEBUG_TRACE, "==> MlmeCheckForRoaming\n");
	// put all roaming candidates into RoamTab, and sort in RSSI order
	BssTableInit(pRoamTab);
	for (i = 0; i < pBssTab->BssNr; i++)
	{
		pBss = &pBssTab->BssEntry[i];

		if ((pBssTab->BssEntry[i].LastBeaconRxTime + BEACON_LOST_TIME) < Now32) 
			continue;    // AP disappear
		if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
			continue;    // RSSI too weak. forget it.
		if (MAC_ADDR_EQUAL(&pBssTab->BssEntry[i].Bssid, &pAd->PortCfg.Bssid))
			continue;    // skip current AP
		if (CQI_IS_FAIR(pAd->Mlme.ChannelQuality) && (pAd->PortCfg.LastRssi + RSSI_DELTA > pBss->Rssi)) 
			continue;    // we're still okay, only AP with stronger RSSI is eligible for roaming

		// AP passing all above rules is put into roaming candidate table        
		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
		pRoamTab->BssNr += 1;
	}

	if (pRoamTab->BssNr > 0)
	{
		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
		if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS)))
		{
		// tell CNTL state machine NOT to call NdisMSetInformationComplete() after completing
		// this request, because this request is initiated by driver itself, not from NDIS.
		pAd->Mlme.CntlAux.CurrReqIsFromNdis = FALSE; 

		pAd->RalinkCounters.PoorCQIRoamingCount ++;
		DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Roaming attempt #%d\n", pAd->RalinkCounters.PoorCQIRoamingCount);
		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
		RTUSBUp(pAd, (&(pAd->mlme_semaphore)));
		//KeSetEvent(&pAd->MLMEEvent, 0, FALSE);
		}
	}
	DBGPRINT(RT_DEBUG_TRACE, "<== MlmeCheckForRoaming\n");   
}

VOID PeriodicExec(
    IN PRT2570ADAPTER pAd)
{

    USHORT TxFailCount, TxNoRetryCnt, TxOneRetryCnt, TxMRetryCnt, TxRetryOkCount, TxOkCount, TxTotalCnt, TxPER, TxPRR = 0, TxRealOkCount;
	USHORT RxFailCnt;
    ULONG RxOkCnt, RxCnt, RxPER;
	ULONG Now32;
	ULONG OldValue;
	UCHAR UpRate, DownRate, CurrRate;

	if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)))
	{
		DBGPRINT(RT_DEBUG_TRACE, "PeriodicExec not execute! (pAd->Flags=0x%08x)\n", pAd->Flags);
		return ;
	}
	AsicAdjustTxPower(pAd);
 	RTUSBMultiReadMAC(pAd, STA_CSR0, (PUCHAR)pAd->MACCounters, 22);
	OldValue = pAd->WlanCounters.FCSErrorCount.vv.LowPart;
	pAd->WlanCounters.FCSErrorCount.vv.LowPart += pAd->MACCounters[0];
	if (pAd->WlanCounters.FCSErrorCount.vv.LowPart < OldValue)
	{
		pAd->WlanCounters.FCSErrorCount.vv.HighPart++;
	}
	OldValue = pAd->WlanCounters.NoRetryCount.vv.LowPart;
	pAd->WlanCounters.NoRetryCount.vv.LowPart += pAd->MACCounters[6];
	if (pAd->WlanCounters.NoRetryCount.vv.LowPart < OldValue)
	{
		pAd->WlanCounters.NoRetryCount.vv.HighPart++;
	}
	OldValue = pAd->WlanCounters.RetryCount.vv.LowPart;
	pAd->WlanCounters.RetryCount.vv.LowPart += pAd->MACCounters[7];
	if (pAd->WlanCounters.RetryCount.vv.LowPart < OldValue)
	{
		pAd->WlanCounters.RetryCount.vv.HighPart++;
	}
	OldValue = pAd->WlanCounters.MultipleRetryCount.vv.LowPart;
	pAd->WlanCounters.MultipleRetryCount.vv.LowPart += pAd->MACCounters[8];
	if (pAd->WlanCounters.MultipleRetryCount.vv.LowPart < OldValue)
	{
		pAd->WlanCounters.MultipleRetryCount.vv.HighPart++;
	}
	OldValue = pAd->WlanCounters.FailedCount.vv.LowPart;
	pAd->WlanCounters.FailedCount.vv.LowPart += pAd->MACCounters[9];
	if (pAd->WlanCounters.FailedCount.vv.LowPart < OldValue)
	{
		pAd->WlanCounters.FailedCount.vv.HighPart++;
	}
	OldValue = pAd->QACounters.RXOverFlowCount.vv.LowPart;
	pAd->QACounters.RXOverFlowCount.vv.LowPart += pAd->MACCounters[4];
	if (pAd->QACounters.RXOverFlowCount.vv.LowPart < OldValue)
	{
		pAd->QACounters.RXOverFlowCount.vv.HighPart++;
	}

    //
    // monitor TX counters change for the past period
    //
    TxFailCount = pAd->MACCounters[9];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -