📄 mlme.c
字号:
// if (INFRA_ON(pAd) && time_after(pAd->Mlme.Now, pAd->PortCfg.LastBeaconRxTime + 1 * HZ) && ((pAd->BulkInDataOneSecCount + pAd->BulkOutDataOneSecCount) < 600)) { if (pAd->PortCfg.Channel <= 14) { RTUSBWriteBBPRegister(pAd, BBP_R17, pAd->BbpTuning.R17LowerBoundG); } else { RTUSBWriteBBPRegister(pAd, BBP_R17, pAd->BbpTuning.R17LowerBoundA); } }#if 0 //Move the flowing code to RTUSBHardTransmit, after prepare EAPOL frame that idicated MIC error //To meet the WiFi Test Plan "The STAUT must deauthenticate itself from the AP". //Also need to bloc association frame. //The flowing code on here can't send disassociation frame to the AP, since AP may send deauthentication // frame, on the meanwhile, station will call link down and then this code can't be performed. // Check for EAPOL frame sent after MIC countermeasures if (pAd->PortCfg.MicErrCnt >= 3) { MLME_DISASSOC_REQ_STRUCT DisassocReq; // disassoc from current AP first DBGPRINT(RT_DEBUG_TRACE, ("MLME - disassociate with current AP after sending second continuous EAPOL frame\n")); DisassocParmFill(pAd, &DisassocReq, pAd->PortCfg.Bssid, REASON_MIC_FAILURE); MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; pAd->PortCfg.bBlockAssoc = TRUE; }#endif // send out a NULL frame every 10 sec. for what??? inform "PwrMgmt" bit? if ((pAd->Mlme.PeriodicRound % 10) == 8) RTMPSendNullFrame(pAd, pAd->PortCfg.TxRate); if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality)) { DBGPRINT(RT_DEBUG_TRACE, "MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%d\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount);#if WPA_SUPPLICANT_SUPPORT if (pAd->PortCfg.WPA_Supplicant == TRUE) { // send disassoc event to wpa_supplicant memset(&wrqu, 0, sizeof(wrqu)); wrqu.data.flags = RT_DISASSOC_EVENT_FLAG; wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL); }#endif // Lost AP, send disconnect & link down event RTUSBEnqueueInternalCmd(pAd, RT_OID_LINK_DOWN); // RTMPPatchMacBbpBug(pAd); MlmeAutoReconnectLastSSID(pAd); } else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality)) { pAd->RalinkCounters.BadCQIAutoRecoveryCount ++; DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Bad CQI. Auto Recovery attempt #%d\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount); MlmeAutoReconnectLastSSID(pAd); }// TODO: temp removed#if 0 else if (CQI_IS_POOR(pAd->Mlme.ChannelQuality)) { // perform aggresive roaming only when SECURITY OFF or WEP64/128; // WPA and WPA-PSK has no aggresive roaming because re-negotiation // between 802.1x supplicant and authenticator/AAA server is required // but can't be guaranteed. if (pAd->PortCfg.AuthMode < Ndis802_11AuthModeWPA) MlmeCheckForRoaming(pAd, pAd->Mlme.Now); }#endif // fast roaming if (pAd->PortCfg.bFastRoaming) { // Check the RSSI value, we should begin the roaming attempt DBGPRINT(RT_DEBUG_TRACE, "RxSignal %d\n", pAd->PortCfg.LastRssi - pAd->BbpRssiToDbmDelta); // Only perform action when signal is less than or equal to setting from the UI or registry if (pAd->PortCfg.LastRssi <= (pAd->BbpRssiToDbmDelta - pAd->PortCfg.dBmToRoam)) { MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now); } } } // !!! Regard the IBSS network as established one while both ADHOC_ON and fOP_STATUS_MEDIA_STATE_CONNECTED are TRUE !!!#ifndef SINGLE_ADHOC_LINKUP else if (ADHOC_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { // 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 (time_after(pAd->Mlme.Now,pAd->PortCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME)) { DBGPRINT(RT_DEBUG_TRACE, "MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); // clean up previous SCAN result, add current BSS back to table if any BssTableDeleteEntry(&pAd->ScanTab, pAd->PortCfg.Bssid, pAd->PortCfg.Channel); pAd->PortCfg.LastScanTime = pAd->Mlme.Now; } }#endif else // no INFRA nor ADHOC connection { if (!ADHOC_ON(pAd) && !INFRA_ON(pAd)) { DBGPRINT(RT_DEBUG_INFO, "- %s, no association so far\n", __FUNCTION__); if ((pAd->PortCfg.bAutoReconnect == TRUE) && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) { if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)) { MLME_SCAN_REQ_STRUCT ScanReq; if (time_after(pAd->Mlme.Now, pAd->PortCfg.LastScanTime + 10 * HZ)) { DBGPRINT(RT_DEBUG_TRACE, "CNTL - No matching BSS, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid); ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, 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; RTUSBMlmeUp(pAd); // Reset Missed scan number pAd->PortCfg.LastScanTime = pAd->Mlme.Now; } else if (pAd->PortCfg.BssType == BSS_ADHOC) // Quit the forever scan when in a very clean room { MlmeAutoReconnectLastSSID(pAd); } } else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) { if ((pAd->Mlme.PeriodicRound % 20) == 8) { MlmeAutoScan(pAd); pAd->PortCfg.LastScanTime = pAd->Mlme.Now; } else if ((pAd->Mlme.PeriodicRound % 2) == 0) { MlmeAutoReconnectLastSSID(pAd); } DBGPRINT(RT_DEBUG_INFO, "pAd->PortCfg.bAutoReconnect is TRUE\n"); } // after once scanning, set wpanone-psk key in the case of using configuration file //if (pAd->Mlme.PeriodicRound >= 4) //{ if ((pAd->PortCfg.BssType == BSS_ADHOC) && (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPANone)&& ((pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) || (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled)) && (pAd->PortCfg.WpaState == SS_START)) { RTMPWPANoneAddKeyProc(pAd, pAd->PortCfg.PskKey.Key); // turn on the flag of PortCfg.WpaState as reading profile // and reset after adding key pAd->PortCfg.WpaState = SS_NOTUSE; } //} } } } // if all 11b peers leave this BSS more than 5 seconds, update Tx rate, // restore outgoing BEACON to support B/G-mixed mode if (ADHOC_ON(pAd)) { // 1. 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails // the "TX BEACON competition" for the entire past 1 sec. // So that even when ASIC's BEACONgen engine been blocked // by peer's BEACON due to slower system clock, this STA still can send out // minimum BEACON to tell the peer I'm alive. // drawback is that this BEACON won't be well aligned at TBTT boundary. // 2. avoid mlme-queue full while doing radar detection if ((pAd->PortCfg.bIEEE80211H == 0) || (pAd->PortCfg.RadarDetect.RDMode == RD_NORMAL_MODE)) EnqueueBeaconFrame(pAd); // software send BEACON if ((pAd->PortCfg.Channel <= 14) && (pAd->PortCfg.MaxTxRate <= RATE_11) && (pAd->PortCfg.MaxDesiredRate > RATE_11) && (time_after(pAd->Mlme.Now, pAd->PortCfg.Last11bBeaconRxTime + 5 * HZ))) { DBGPRINT(RT_DEBUG_TRACE, "MMCHK - last 11B peer left, update Tx rates\n"); memcpy(pAd->ActiveCfg.SupRate, pAd->PortCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES); pAd->ActiveCfg.SupRateLen = pAd->PortCfg.SupRateLen; RTUSBEnqueueInternalCmd(pAd, RT_OID_UPDATE_TX_RATE); //MlmeUpdateTxRates(pAd, FALSE); AsicEnableIbssSync(pAd); // copy to on-chip memory } //radar detect if (((pAd->PortCfg.PhyMode == PHY_11A) || (pAd->PortCfg.PhyMode == PHY_11ABG_MIXED)) && (pAd->PortCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->PortCfg.Channel)) { // need to check channel availability, after switch channel if (pAd->PortCfg.RadarDetect.RDMode == RD_SILENCE_MODE) { pAd->PortCfg.RadarDetect.RDCount++; // channel availability check time is 60sec if (pAd->PortCfg.RadarDetect.RDCount > 65) { if (RadarDetectionStop(pAd)) { pAd->ExtraInfo = DETECT_RADAR_SIGNAL; pAd->PortCfg.RadarDetect.RDCount = 0; // stat at silence mode and detect radar signal DBGPRINT(RT_DEBUG_TRACE, "Found radar signal!!!\n\n"); } else { DBGPRINT(RT_DEBUG_TRACE, "Not found radar signal, start send beacon\n"); AsicEnableIbssSync(pAd); pAd->PortCfg.RadarDetect.RDMode = RD_NORMAL_MODE; } } } } } if (((pAd->Mlme.PeriodicRound % 2) == 0) && (INFRA_ON(pAd) || ADHOC_ON(pAd))) { RTMPSetSignalLED(pAd, pAd->PortCfg.LastRssi - pAd->BbpRssiToDbmDelta); } if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { // // Modify retry times (maximum 15) on low data traffic. // Should fix ping lost. // dbm = pAd->PortCfg.AvgRssi - pAd->BbpRssiToDbmDelta; // // Only on infrastructure mode will change the RetryLimit. // if (INFRA_ON(pAd)) { if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MAX_RETRY_ENABLED)) { if (pAd->RalinkCounters.OneSecTxNoRetryOkCount > 15) { RTUSBReadMACRegister(pAd, TXRX_CSR4, &CurTxRxCsr4.word); CurTxRxCsr4.field.ShortRetryLimit = 0x07; CurTxRxCsr4.field.LongRetryLimit = 0x04; RTUSBWriteMACRegister(pAd, TXRX_CSR4, CurTxRxCsr4.word); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MAX_RETRY_ENABLED); } } else { if (pAd->RalinkCounters.OneSecTxNoRetryOkCount <= 15) { RTUSBReadMACRegister(pAd, TXRX_CSR4, &CurTxRxCsr4.word); CurTxRxCsr4.field.ShortRetryLimit = 0x0f; CurTxRxCsr4.field.LongRetryLimit = 0x0f; RTUSBWriteMACRegister(pAd, TXRX_CSR4, CurTxRxCsr4.word); OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MAX_RETRY_ENABLED); } } } if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RTS_PROTECTION_ENABLE)) { if ((dbm > -60) || (pAd->RalinkCounters.OneSecTxNoRetryOkCount > 15)) OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_RTS_PROTECTION_ENABLE); } else { // // for long distance case, turn on RTS to protect data frame. // if ((dbm <= -60) && (pAd->RalinkCounters.OneSecTxNoRetryOkCount <= 15)) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RTS_PROTECTION_ENABLE); } } } // // Clear Tx/Rx Traffic one second count. // pAd->BulkLastOneSecCount = pAd->BulkOutDataOneSecCount + pAd->BulkInDataOneSecCount; pAd->BulkOutDataOneSecCount = 0; pAd->BulkInDataOneSecCount = 0; // clear all OneSecxxx counters. pAd->RalinkCounters.OneSecBeaconSentCnt = 0; pAd->RalinkCounters.OneSecFalseCCACnt = 0; pAd->RalinkCounters.OneSecRxFcsErrCnt = 0; pAd->RalinkCounters.OneSecRxOkCnt = 0; pAd->RalinkCounters.OneSecTxFailCount = 0; pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0; pAd->RalinkCounters.OneSecTxRetryOkCount = 0; // TODO: for debug only. to be removed pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0; pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0; pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0; pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0; pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0; pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0; pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0; pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0; pAd->RalinkCounters.OneSecTxDoneCount = 0; pAd->RalinkCounters.OneSecTxAggregationCount = 0; pAd->RalinkCounters.OneSecRxAggregationCount = 0; pAd->Mlme.PeriodicRound ++;}VOID LinkDownExec( IN unsigned long data){ //RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;}VOID MlmeAutoScan( IN PRTMP_ADAPTER pAd){ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request // tell CNTL state machine NOT to call NdisMSetInformationComplete() after completing // this request, because this request is initiated by driver itself. pAd->MlmeAux.CurrReqIsFromNdis = FALSE; if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) { DBGPRINT(RT_DEBUG_TRACE, "MMCHK - Driver auto scan\n"); MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_BSSID_LIST_SCAN, 0, NULL); RTUSBMlmeUp(pAd); }}VOID MlmeAutoRecoverNetwork( IN PRTMP_ADAPTER 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; memcpy(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->MlmeAux.CurrReqIsFromNdis = FALSE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID, sizeof(NDIS_802_11_SSID),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -