📄 mlme.c
字号:
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 + -