📄 connect.c
字号:
NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen; // step 2. find all matching BSS in the lastest SCAN result (inBssTab) // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n", pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid)); NdisGetSystemUpTime(&Now); if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) && NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid)) { // Case 1. already connected with an AP who has the desired SSID // with highest RSSI // Add checking Mode "LEAP" for CCX 1.0 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) { // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo // connection process DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n")); DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING); MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; } else if (pAd->bConfigChanged == TRUE) { // case 1.2 Important Config has changed, we have to reconnect to the same AP DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n")); DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING); MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; } else { // case 1.3. already connected to the SSID with highest RSSI. DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n")); // // (HCT 12.1) 1c_wlan_mediaevents required // media connect events are indicated when associating with the same AP // if (INFRA_ON(pAd)) { // // Since MediaState already is NdisMediaStateConnected // We just indicate the connect event again to meet the WHQL required. // pAd->IndicateMediaState = NdisMediaStateConnected; RTMP_IndicateMediaState(pAd); pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up } pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, &pAd->MlmeAux.Bssid[0], NULL, 0);#endif // NATIVE_WPA_SUPPLICANT_SUPPORT // } } else if (INFRA_ON(pAd)) { // // For RT61 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect // But media status is connected, so the SSID not report correctly. // if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)) { // // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event. // pAd->MlmeAux.CurrReqIsFromNdis = TRUE; } // case 2. active INFRA association existent // roaming is done within miniport driver, nothing to do with configuration // utility. so upon a new SET(OID_802_11_SSID) is received, we just // disassociate with the current associated AP, // then perform a new association with this new SSID, no matter the // new/old SSID are the same or not. DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n")); DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING); MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; } else { if (ADHOC_ON(pAd)) { DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n")); LinkDown(pAd, FALSE); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); pAd->IndicateMediaState = NdisMediaStateDisconnected; RTMP_IndicateMediaState(pAd); pAd->ExtraInfo = GENERAL_LINK_DOWN; DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n")); } if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) && (pAd->StaCfg.bAutoReconnect == TRUE) && (pAd->MlmeAux.BssType == BSS_INFRA) && (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE) ) { MLME_SCAN_REQ_STRUCT ScanReq; DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n")); ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, 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->StaCfg.LastScanTime = Now; } else { pAd->MlmeAux.BssIdx = 0; IterateOnBssTab(pAd); } } }/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ==========================================================================*/VOID CntlOidRTBssidProc( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM * Elem) { ULONG BssIdx; PUCHAR pOidBssid = (PUCHAR)Elem->Msg; MLME_DISASSOC_REQ_STRUCT DisassocReq; MLME_JOIN_REQ_STRUCT JoinReq;#ifdef RALINK_ATE/* No need to perform this routine when ATE is running. */ if (ATE_ON(pAd)) return;#endif // RALINK_ATE // // record user desired settings COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid); pAd->MlmeAux.BssType = pAd->StaCfg.BssType; // find the desired BSS in the latest SCAN result table BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel); if (BssIdx == BSS_NOT_FOUND) { MLME_SCAN_REQ_STRUCT ScanReq; DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n")); //pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. start a new scan\n")); ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, 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 NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); return; } // // Update Reconnect Ssid, that user desired to connect. // NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID); pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen; NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen); // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why? // Because we need this entry to become the JOIN target in later on SYNC state machine pAd->MlmeAux.BssIdx = 0; pAd->MlmeAux.SsidBssTab.BssNr = 1; NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY)); // Add SSID into MlmeAux for site surey joining hidden SSID pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen; NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen); { if (INFRA_ON(pAd)) { // disassoc from current AP first DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n")); DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING); MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; } else { if (ADHOC_ON(pAd)) { DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n")); LinkDown(pAd, FALSE); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); pAd->IndicateMediaState = NdisMediaStateDisconnected; RTMP_IndicateMediaState(pAd); pAd->ExtraInfo = GENERAL_LINK_DOWN; DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n")); } // Change the wepstatus to original wepstatus pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus; pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus; pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus; // Check cipher suite, AP must have more secured cipher than station setting // Set the Pairwise and Group cipher to match the intended AP setting // We can only connect to AP with less secured cipher setting if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) { pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher; if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher) pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher; else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled) pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux; else // There is no PairCipher Aux, downgrade our capability to TKIP pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled; } else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) { pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher; if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher) pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher; else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled) pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux; else // There is no PairCipher Aux, downgrade our capability to TKIP pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled; // RSN capability pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability; } // Set Mix cipher flag pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE; /*if (pAd->StaCfg.bMixCipher == TRUE) { // If mix cipher, re-build RSNIE RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0); }*/ // No active association, join the BSS immediately DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n", pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5])); JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx); MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN; } } }// Roaming is the only external request triggering CNTL state machine// despite of other "SET OID" operation. All "SET OID" related oerations // happen in sequence, because no other SET OID will be sent to this device// until the the previous SET operation is complete (successful o failed).// So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?// or been corrupted by other "SET OID"?//// IRQL = DISPATCH_LEVELVOID CntlMlmeRoamingProc( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR BBPValue = 0; DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n")); { //Let BBP register at 20MHz to do (fast) roaming. RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab)); pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr; BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab); pAd->MlmeAux.BssIdx = 0; IterateOnBssTab(pAd); }}#ifdef QOS_DLS_SUPPORT/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ==========================================================================*/VOID CntlOidDLSSetupProc( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem){ PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg; MLME_DLS_REQ_STRUCT MlmeDlsReq; INT i; USHORT reason = REASON_UNSPECIFY; DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n", pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5], pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer)); if (!pAd->CommonCfg.bDLSCapable) return; // DLS will not be supported when Adhoc mode if (INFRA_ON(pAd)) { for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++) { if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) { // 1. Same setting, just drop it DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n")); break; } else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) { // 2. Disable DLS link case, just tear down DLS link reason = REASON_QOS_UNWANTED_MECHANISM; pAd->StaCfg.DLSEntry[i].Valid = FALSE; pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason); MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq); DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n")); break; } else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid) { // 3. Enable case, start DLS setup procedure NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI)); //Update countdown timer pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut; DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason); MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq); DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n")); break; } else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) { // 4. update mac case, tear down old DLS and setup new DLS reason = REASON_QOS_UNWANTED_MECHANISM; pAd->StaCfg.DLSEntry[i].Valid = FALSE; pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason); MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -