/* *************************************************************************** * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * * (c) Copyright 2002-2006, Ralink Technology, Inc. * * All rights reserved. Ralink's source code is an unpublished work and the * use of a copyright notice does not imply otherwise. This source code * contains confidential trade secret material of Ralink Tech. Any attemp * or participation in deciphering, decoding, reverse engineering or in any * way altering the source code is stricitly prohibited, unless the prior * written consent of Ralink Technology, Inc. is obtained. *************************************************************************** Module Name: apcli_assoc.c Abstract: Revision History: Who When What -------- ---------- ---------------------------------------------- Fonchi 2006-6-23 modified for rt61-APClinent */ #ifdef APCLI_SUPPORT #include "rt_config.h" static VOID ApCliAssocTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3); #ifdef MAC_REPEATER_SUPPORT static VOID ApCliAssocTimeoutExt( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3); #endif /* MAC_REPEATER_SUPPORT */ static VOID ApCliMlmeAssocReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem); static VOID ApCliMlmeDisassocReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem); static VOID ApCliPeerAssocRspAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem); static VOID ApCliPeerDisassocAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem); static VOID ApCliAssocTimeoutAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem); static VOID ApCliInvalidStateWhenAssoc( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem); static VOID ApCliInvalidStateWhenDisassociate( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem); static VOID ApCliAssocPostProc( IN PRTMP_ADAPTER pAd, IN PUCHAR pAddr2, IN USHORT CapabilityInfo, IN USHORT IfIndex, IN UCHAR SupRate[], IN UCHAR SupRateLen, IN UCHAR ExtRate[], IN UCHAR ExtRateLen, IN PEDCA_PARM pEdcaParm, IN HT_CAPABILITY_IE *pHtCapability, IN UCHAR HtCapabilityLen, IN ADD_HT_INFO_IE *pAddHtInfo); DECLARE_TIMER_FUNCTION(ApCliAssocTimeout); BUILD_TIMER_FUNCTION(ApCliAssocTimeout); #ifdef MAC_REPEATER_SUPPORT DECLARE_TIMER_FUNCTION(ApCliAssocTimeoutExt); BUILD_TIMER_FUNCTION(ApCliAssocTimeoutExt); #endif /* MAC_REPEATER_SUPPORT */ /* ========================================================================== Description: association state machine init, including state transition and timer init Parameters: S - pointer to the association state machine Note: The state machine looks like the following ========================================================================== */ VOID ApCliAssocStateMachineInit( IN PRTMP_ADAPTER pAd, IN STATE_MACHINE *S, OUT STATE_MACHINE_FUNC Trans[]) { UCHAR i; #ifdef MAC_REPEATER_SUPPORT UCHAR j; #endif /* MAC_REPEATER_SUPPORT */ StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, APCLI_MAX_ASSOC_STATE, APCLI_MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, APCLI_ASSOC_IDLE, APCLI_ASSOC_MACHINE_BASE); /* first column */ StateMachineSetAction(S, APCLI_ASSOC_IDLE, APCLI_MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)ApCliMlmeAssocReqAction); StateMachineSetAction(S, APCLI_ASSOC_IDLE, APCLI_MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)ApCliMlmeDisassocReqAction); StateMachineSetAction(S, APCLI_ASSOC_IDLE, APCLI_MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)ApCliPeerDisassocAction); /* second column */ StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)ApCliInvalidStateWhenAssoc); StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)ApCliInvalidStateWhenDisassociate); StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)ApCliPeerDisassocAction); StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)ApCliPeerAssocRspAction); StateMachineSetAction(S, APCLI_ASSOC_WAIT_RSP, APCLI_MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ApCliAssocTimeoutAction); for (i=0; i < MAX_APCLI_NUM; i++) { pAd->ApCfg.ApCliTab[i].AssocCurrState = APCLI_ASSOC_IDLE; /* timer init */ RTMPInitTimer(pAd, &pAd->ApCfg.ApCliTab[i].MlmeAux.ApCliAssocTimer, GET_TIMER_FUNCTION(ApCliAssocTimeout), pAd, FALSE); #ifdef MAC_REPEATER_SUPPORT for (j = 0; j < MAX_EXT_MAC_ADDR_SIZE; j++) { pAd->ApCfg.ApCliTab[i].RepeaterCli[j].pAd = pAd; pAd->ApCfg.ApCliTab[i].RepeaterCli[j].MatchApCliIdx = i; pAd->ApCfg.ApCliTab[i].RepeaterCli[j].MatchLinkIdx = j; pAd->ApCfg.ApCliTab[i].RepeaterCli[j].AssocCurrState = APCLI_ASSOC_IDLE; /* timer init */ RTMPInitTimer(pAd, &pAd->ApCfg.ApCliTab[i].RepeaterCli[j].ApCliAssocTimer, GET_TIMER_FUNCTION(ApCliAssocTimeoutExt), &pAd->ApCfg.ApCliTab[i].RepeaterCli[j], FALSE); } #endif /* MAC_REPEATER_SUPPORT */ } return; } /* ========================================================================== Description: Association timeout procedure. After association timeout, this function will be called and it will put a message into the MLME queue Parameters: Standard timer parameters ========================================================================== */ static VOID ApCliAssocTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - enqueue APCLI_MT2_ASSOC_TIMEOUT \n")); MlmeEnqueue(pAd, APCLI_ASSOC_STATE_MACHINE, APCLI_MT2_ASSOC_TIMEOUT, 0, NULL, 0); RTMP_MLME_HANDLER(pAd); return; } #ifdef MAC_REPEATER_SUPPORT /* ========================================================================== Description: Association timeout procedure. After association timeout, this function will be called and it will put a message into the MLME queue Parameters: Standard timer parameters ========================================================================== */ static VOID ApCliAssocTimeoutExt( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PREPEATER_CLIENT_ENTRY pRepeaterCliEntry = (PREPEATER_CLIENT_ENTRY)FunctionContext; PRTMP_ADAPTER pAd; USHORT ifIndex = 0; DBGPRINT(RT_DEBUG_TRACE, ("Repeater Cli ASSOC - enqueue APCLI_MT2_ASSOC_TIMEOUT\n")); pAd = pRepeaterCliEntry->pAd; ifIndex = (64 + (16*pRepeaterCliEntry->MatchApCliIdx) + pRepeaterCliEntry->MatchLinkIdx); DBGPRINT(RT_DEBUG_ERROR, (" (%s) ifIndex = %d, CliIdx = %d !!!\n", __FUNCTION__, pRepeaterCliEntry->MatchApCliIdx, pRepeaterCliEntry->MatchLinkIdx)); MlmeEnqueue(pAd, APCLI_ASSOC_STATE_MACHINE, APCLI_MT2_ASSOC_TIMEOUT, 0, NULL, ifIndex); RTMP_MLME_HANDLER(pAd); return; } #endif /* MAC_REPEATER_SUPPORT */ /* ========================================================================== Description: mlme assoc req handling procedure Parameters: Adapter - Adapter pointer Elem - MLME Queue Element Pre: the station has been authenticated and the following information is stored in the config -# SSID -# supported rates and their length Post : -# An association request frame is generated and sent to the air -# Association timer starts -# Association state -> ASSOC_WAIT_RSP ========================================================================== */ static VOID ApCliMlmeAssocReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { NDIS_STATUS NStatus; BOOLEAN Cancelled; UCHAR ApAddr[6]; HEADER_802_11 AssocHdr; UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; USHORT ListenIntv; ULONG Timeout; USHORT CapabilityInfo; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG tmp = 0; UCHAR SsidIe = IE_SSID; UCHAR SupRateIe = IE_SUPP_RATES; UCHAR ExtRateIe = IE_EXT_SUPP_RATES; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = NULL; #ifdef WPA_SUPPLICANT_SUPPORT USHORT VarIesOffset = 0; #endif /* WPA_SUPPLICANT_SUPPORT */ UCHAR RSNIe = IE_WPA; APCLI_STRUCT *apcli_entry; struct wifi_dev *wdev; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; apcli_entry = &pAd->ApCfg.ApCliTab[ifIndex]; wdev = &apcli_entry->wdev; /* Block all authentication request durning WPA block period */ if (apcli_entry->bBlockAssoc == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Block Auth request durning WPA block period!\n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv)) { //RTMPCancelTimer(&apcli_entry->MlmeAux.ApCliAssocTimer, &Cancelled); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPCancelTimer(&apcli_entry->RepeaterCli[CliIdx].ApCliAssocTimer, &Cancelled); else #endif /* MAC_REPEATER_SUPPORT */ RTMPCancelTimer(&apcli_entry->MlmeAux.ApCliAssocTimer, &Cancelled); /* allocate and send out AssocRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() allocate memory failed \n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); return; } DBGPRINT(RT_DEBUG_OFF, ("APCLI_ASSOC - Send ASSOC request...\n")); ApCliMgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr, ifIndex); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) COPY_MAC_ADDR(AssocHdr.Addr2, apcli_entry->RepeaterCli[CliIdx].CurrentAddress); #endif /* MAC_REPEATER_SUPPORT */ /* Build basic frame first */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AssocHdr, 2, &CapabilityInfo, 2, &ListenIntv, 1, &SsidIe, 1, &apcli_entry->MlmeAux.SsidLen, apcli_entry->MlmeAux.SsidLen, apcli_entry->MlmeAux.Ssid, 1, &SupRateIe, 1, &apcli_entry->MlmeAux.SupRateLen, apcli_entry->MlmeAux.SupRateLen, apcli_entry->MlmeAux.SupRate, END_OF_ARGS); if(apcli_entry->MlmeAux.ExtRateLen != 0) { MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &apcli_entry->MlmeAux.ExtRateLen, apcli_entry->MlmeAux.ExtRateLen, apcli_entry->MlmeAux.ExtRate, END_OF_ARGS); FrameLen += tmp; } #ifdef DOT11_N_SUPPORT /* WFA recommend to restrict the encryption type in 11n-HT mode. So, the WEP and TKIP are not allowed in HT rate. */ if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus)) { /* Force to None-HT mode due to WiFi 11n policy */ apcli_entry->MlmeAux.HtCapabilityLen = 0; #ifdef DOT11_VHT_AC apcli_entry->MlmeAux.vht_cap_len = 0; #endif /* DOT11_VHT_AC */ DBGPRINT(RT_DEBUG_TRACE, ("%s : Force AP-client as Non-HT mode\n", __FUNCTION__)); } /* HT */ if ((apcli_entry->MlmeAux.HtCapabilityLen > 0) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ULONG TmpLen; HT_CAPABILITY_IE HtCapabilityTmp; NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE)); NdisMoveMemory(&HtCapabilityTmp, &apcli_entry->MlmeAux.HtCapability, apcli_entry->MlmeAux.HtCapabilityLen); /* WFD 6.1.21E: the peer devices will use BW based on HT Support Channel width in HT Capability IE */ if (pAd->CommonCfg.RegTransmitSetting.field.BW == HT_BW_20) HtCapabilityTmp.HtCapInfo.ChannelWidth = BW_20; #ifdef DOT11N_SS3_SUPPORT HtCapabilityTmp.MCSSet[2] = (apcli_entry->MlmeAux.HtCapability.MCSSet[2] & apcli_entry->RxMcsSet[2]); #endif /* DOT11N_SS3_SUPPORT */ #ifdef RT_BIG_ENDIAN *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* RT_BIG_ENDINA */ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &apcli_entry->MlmeAux.HtCapabilityLen, apcli_entry->MlmeAux.HtCapabilityLen, &HtCapabilityTmp, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->CommonCfg.Channel > 14) && (apcli_entry->MlmeAux.vht_cap_len)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer + FrameLen), SUBTYPE_ASSOC_REQ); } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ #ifdef AGGREGATION_SUPPORT /* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION Case I: (Aggregation + Piggy-Back) 1. user enable aggregation, AND 2. Mac support piggy-back 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON Case II: (Aggregation) 1. user enable aggregation, AND 2. AP annouces it's AGGREGATION-capable in BEACON */ if (pAd->CommonCfg.bAggregationCapable) { #ifdef PIGGYBACK_SUPPORT if ((pAd->CommonCfg.bPiggyBackCapable) && ((apcli_entry->MlmeAux.APRalinkIe & 0x00000003) == 3)) { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } else #endif /* PIGGYBACK_SUPPORT */ if (apcli_entry->MlmeAux.APRalinkIe & 0x00000001) { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } } else { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } #endif /* AGGREGATION_SUPPORT */ if (apcli_entry->MlmeAux.APEdcaParm.bValid) { if (apcli_entry->wdev.UapsdInfo.bAPSDCapable && apcli_entry->MlmeAux.APEdcaParm.bAPSDCapable) { QBSS_STA_INFO_PARM QosInfo; NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM)); QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE; QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK; QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI; QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO; QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength; WmeIe[8] |= *(PUCHAR)&QosInfo; } else { /* The Parameter Set Count is set to ¡§0¡¨ in the association request frames */ /* WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f); */ } MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 9, &WmeIe[0], END_OF_ARGS); FrameLen += tmp; } #if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA) apcli_entry->ReqVarIELen = 0; NdisZeroMemory(apcli_entry->ReqVarIEs, MAX_VIE_LEN); if ((apcli_entry->wpa_supplicant_info.WpaSupplicantUP & 0x7F ) == WPA_SUPPLICANT_ENABLE) { ULONG TmpWpaAssocIeLen = 0; DBGPRINT(RT_DEBUG_TRACE,("%s:: APCLI WPA_ASSOC_IE FROM SUPPLICANT\n", __FUNCTION__)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpWpaAssocIeLen, apcli_entry->wpa_supplicant_info.WpaAssocIeLen, apcli_entry->wpa_supplicant_info.pWpaAssocIe, END_OF_ARGS); FrameLen += TmpWpaAssocIeLen; VarIesOffset = 0; NdisMoveMemory(apcli_entry->ReqVarIEs + VarIesOffset, apcli_entry->wpa_supplicant_info.pWpaAssocIe, apcli_entry->wpa_supplicant_info.WpaAssocIeLen); VarIesOffset += apcli_entry->wpa_supplicant_info.WpaAssocIeLen; // Set Variable IEs Length apcli_entry->ReqVarIELen = VarIesOffset; } else #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */ /* Append RSN_IE when WPAPSK OR WPA2PSK, */ if (((wdev->AuthMode == Ndis802_11AuthModeWPAPSK) || (wdev->AuthMode == Ndis802_11AuthModeWPA2PSK) #ifdef WPA3_SUPPORT || (wdev->AuthMode == Ndis802_11AuthModeWPA3SAE) #endif ) #ifdef WPA_SUPPLICANT_SUPPORT || (wdev->AuthMode >= Ndis802_11AuthModeWPA) #endif /* WPA_SUPPLICANT_SUPPORT */ #ifdef WSC_AP_SUPPORT && ((apcli_entry->WscControl.WscConfMode == WSC_DISABLE) || ((apcli_entry->WscControl.WscConfMode != WSC_DISABLE) && !(apcli_entry->WscControl.bWscTrigger))) #endif /* WSC_AP_SUPPORT */ ) { RSNIe = IE_WPA; if ((wdev->AuthMode == Ndis802_11AuthModeWPA2PSK) #ifdef WPA3_SUPPORT || (wdev->AuthMode == Ndis802_11AuthModeWPA3SAE) #endif #ifdef WPA_SUPPLICANT_SUPPORT ||(wdev->AuthMode == Ndis802_11AuthModeWPA2) #endif /* WPA_SUPPLICANT_SUPPORT */ ) RSNIe = IE_WPA2; #ifdef WPA3_SUPPORT RTMPMakeRSNIE(pAd, wdev->AuthMode, wdev->WepStatus, (ifIndex + MIN_NET_DEVICE_FOR_APCLI)); #endif #ifdef WPA_SUPPLICANT_SUPPORT if (wdev->AuthMode == Ndis802_11AuthModeWPA2) { INT idx; BOOLEAN FoundPMK = FALSE; /* Search chched PMKID, append it if existed */ for (idx = 0; idx < PMKID_NO; idx++) { if (NdisEqualMemory(ApAddr, &apcli_entry->SavedPMK[idx].BSSID, 6)) { FoundPMK = TRUE; break; } } /* When AuthMode is WPA2-Enterprise and AP reboot or STA lost AP, AP would not do PMK cache with STA after STA re-connect to AP again. In this case, driver doesn't need to send PMKID to AP and WpaSupplicant. */ if ((wdev->AuthMode == Ndis802_11AuthModeWPA2) && (NdisEqualMemory(pAd->MlmeAux.Bssid, pAd->CommonCfg.LastBssid, MAC_ADDR_LEN))) { FoundPMK = FALSE; } if (FoundPMK) { // Set PMK number *(PUSHORT) &apcli_entry->RSN_IE[apcli_entry->RSNIE_Len] = 1; NdisMoveMemory(&apcli_entry->RSN_IE[apcli_entry->RSNIE_Len + 2], &apcli_entry->SavedPMK[idx].PMKID, 16); apcli_entry->RSNIE_Len += 18; } } #ifdef SIOCSIWGENIE if ((apcli_entry->wpa_supplicant_info.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE) && (apcli_entry->wpa_supplicant_info.bRSN_IE_FromWpaSupplicant == TRUE)) { ; } else #endif #endif /* WPA_SUPPLICANT_SUPPORT */ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &RSNIe, 1, &apcli_entry->RSNIE_Len, apcli_entry->RSNIE_Len, apcli_entry->RSN_IE, END_OF_ARGS); FrameLen += tmp; } MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPSetTimer(&apcli_entry->RepeaterCli[CliIdx].ApCliAssocTimer, Timeout); else #endif /* MAC_REPEATER_SUPPORT */ RTMPSetTimer(&apcli_entry->MlmeAux.ApCliAssocTimer, Timeout); *pCurrState = APCLI_ASSOC_WAIT_RSP; } else { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() sanity check failed. BUG!!!!!! \n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } return; } /* ========================================================================== Description: Upper layer issues disassoc request Parameters: Elem - ========================================================================== */ static VOID ApCliMlmeDisassocReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PMLME_DISASSOC_REQ_STRUCT pDisassocReq; HEADER_802_11 DisassocHdr; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; NDIS_STATUS NStatus; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = NULL; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; /* skip sanity check */ pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg); /* allocate and send out DeassocReq frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeDisassocReqAction() allocate memory failed\n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_FAIL_NO_RESOURCE; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = CliIdx; ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DEASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); return; } DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Send DISASSOC request [BSSID::%02x:%02x:%02x:%02x:%02x:%02x] \n", pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2], pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5])); ApCliMgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr, ifIndex); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) COPY_MAC_ADDR(DisassocHdr.Addr2, pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].CurrentAddress); #endif /* MAC_REPEATER_SUPPORT */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &DisassocHdr, 2, &pDisassocReq->Reason, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = CliIdx; ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DEASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); #ifdef WPA_SUPPLICANT_SUPPORT if (pAd->ApCfg.ApCliTab[ifIndex].wpa_supplicant_info.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) { /*send disassociate event to wpa_supplicant*/ RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0); } RtmpOSWrielessEventSend(pAd->net_dev, SIOCGIWAP, -1, NULL, NULL, 0); RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, NULL, BSS0, 0); #endif /* WPA_SUPPLICANT_SUPPORT */ #if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA) RT_CFG80211_LOST_GO_INFORM(pAd, pDisassocReq->Reason); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */ return; } /* ========================================================================== Description: peer sends assoc rsp back Parameters: Elme - MLME message containing the received frame ========================================================================== */ static VOID ApCliPeerAssocRspAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { BOOLEAN Cancelled; USHORT CapabilityInfo, Status, Aid; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen; UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen; UCHAR Addr2[MAC_ADDR_LEN]; EDCA_PARM EdcaParm; UCHAR CkipFlag; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; /* AP might use this additional ht info IE */ UCHAR HtCapabilityLen; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; USHORT ifIndex = (USHORT)(Elem->Priv); ULONG *pCurrState = NULL; #if defined(DOT11_VHT_AC) || defined(WPA3_SUPPORT) PAPCLI_STRUCT pApCliEntry = NULL; #endif /* DOT11_VHT_AC */ #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ IE_LISTS *ie_list = NULL; #ifdef WPA3_SUPPORT P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = NULL; #endif if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; #if defined(DOT11_VHT_AC) || defined(WPA3_SUPPORT) pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; #endif /* DOT11_VHT_AC */ os_alloc_mem(pAd, (UCHAR **)&ie_list, sizeof(IE_LISTS)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_OFF, ("%s():mem alloc failed!\n", __FUNCTION__)); return; } NdisZeroMemory((UCHAR *)ie_list, sizeof(IE_LISTS)); if (ApCliPeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &HtCapability, &AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag, ie_list)) { /* The frame is for me ? */ if(MAC_ADDR_EQUAL(Addr2, pAd->ApCfg.ApCliTab[ifIndex].MlmeAux.Bssid)) { PFRAME_802_11 pFrame; DBGPRINT(RT_DEBUG_OFF, ("APCLI_ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status)); #ifdef WPA3_SUPPORT /* The BSS from cfg80211_ops.assoc must give back to * cfg80211_send_rx_assoc() or to cfg80211_assoc_timeout(). * To ensure proper refcounting, new association requests * while already associating must be rejected. */ DBGPRINT(RT_DEBUG_TRACE, ("Report RX Assoc to upper layer, %s\n", pApCliEntry->ConnInfo.bss ? "DO IT" : "Oops")); if (pApCliEntry->ConnInfo.bss) { /*Report Rx assoc frame to upper layer*/ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) Elem->Msg; #if KERNEL_VERSION(3, 18, 0) <= CFG80211_VERSION_CODE /* [TODO] Set uapsd_queues field to zero first, fill it if needed */ cfg80211_rx_assoc_resp(pApCliEntry->wdev.if_dev, pApCliEntry->ConnInfo.bss, (const u8 *)prAssocRspFrame, Elem->MsgLen, 0); #else cfg80211_rx_assoc_resp(pApCliEntry->wdev.if_dev, pApCliEntry->ConnInfo.bss, (const u8 *)prAssocRspFrame, Elem->MsgLen); #endif DBGPRINT(RT_DEBUG_TRACE, ("Report RX Assoc to upper layer, Done\n")); pApCliEntry->ConnInfo.bss = NULL; } else DBGPRINT(RT_DEBUG_TRACE, ("Rx Assoc Resp without specific BSS\n")); #endif #if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA) /* Store the AssocRsp Frame to wpa_supplicant via CFG80211 */ NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].ResVarIEs, MAX_VIE_LEN); pAd->ApCfg.ApCliTab[ifIndex].ResVarIELen = 0; pFrame = (PFRAME_802_11) (Elem->Msg); pAd->ApCfg.ApCliTab[ifIndex].ResVarIELen = (USHORT)(Elem->MsgLen - 6 - sizeof(HEADER_802_11)); NdisCopyMemory(pAd->ApCfg.ApCliTab[ifIndex].ResVarIEs, &pFrame->Octet[6], pAd->ApCfg.ApCliTab[ifIndex].ResVarIELen); #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */ #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPCancelTimer(&pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].ApCliAssocTimer, &Cancelled); else #endif /* MAC_REPEATER_SUPPORT */ RTMPCancelTimer(&pAd->ApCfg.ApCliTab[ifIndex].MlmeAux.ApCliAssocTimer, &Cancelled); if(Status == MLME_SUCCESS) { /* go to procedure listed on page 376 */ #ifdef MAC_REPEATER_SUPPORT if (CliIdx == 0xFF) #endif /* MAC_REPEATER_SUPPORT */ { ApCliAssocPostProc(pAd, Addr2, CapabilityInfo, ifIndex, SupRate, SupRateLen, ExtRate, ExtRateLen, &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo); #ifdef DOT11_VHT_AC RTMPZeroMemory(&pApCliEntry->MlmeAux.vht_cap, sizeof(VHT_CAP_IE)); RTMPZeroMemory(&pApCliEntry->MlmeAux.vht_op, sizeof(VHT_OP_IE)); pApCliEntry->MlmeAux.vht_cap_len = 0; pApCliEntry->MlmeAux.vht_op_len = 0; if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && ie_list->vht_cap_len && ie_list->vht_op_len) { DBGPRINT(RT_DEBUG_TRACE, ("There is vht le at Assoc Rsp ifIndex=%d vht_cap_len=%d\n", ifIndex,ie_list->vht_cap_len)); NdisMoveMemory(&pApCliEntry->MlmeAux.vht_cap, &(ie_list->vht_cap), ie_list->vht_cap_len); pApCliEntry->MlmeAux.vht_cap_len = ie_list->vht_cap_len; NdisMoveMemory(&pApCliEntry->MlmeAux.vht_op, &(ie_list->vht_op), ie_list->vht_op_len); pApCliEntry->MlmeAux.vht_op_len = ie_list->vht_op_len; } #endif /* DOT11_VHT_AC */ } ApCliCtrlMsg.Status = MLME_SUCCESS; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = CliIdx; ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } else { ApCliCtrlMsg.Status = Status; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } *pCurrState = APCLI_ASSOC_IDLE; } } else { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliPeerAssocRspAction() sanity check fail\n")); } if (ie_list) os_free_mem(pAd, ie_list); return; } /* ========================================================================== Description: left part of IEEE 802.11/1999 p.374 Parameters: Elem - MLME message containing the received frame ========================================================================== */ static VOID ApCliPeerDisassocAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Addr2[MAC_ADDR_LEN]; USHORT Reason; USHORT ifIndex = (USHORT)(Elem->Priv); ULONG *pCurrState = NULL; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ #ifdef WPA3_SUPPORT P_WLAN_DISASSOC_FRAME_T prDisassocFrame; prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) Elem->Msg; DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Rx Disassoc frame from BSSID[%02x:%02x:%02x:%02x:%02x:%02x], DA[%02x:%02x:%02x:%02x:%02x:%02x] ReasonCode[0x%x]\n", PRINT_MAC(prDisassocFrame->aucBSSID), PRINT_MAC(prDisassocFrame->aucDestAddr), prDisassocFrame->u2ReasonCode)); #endif if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) { if (MAC_ADDR_EQUAL(pAd->ApCfg.ApCliTab[ifIndex].MlmeAux.Bssid, Addr2)) { #ifdef WPA3_SUPPORT DBGPRINT(RT_DEBUG_TRACE, ("notification of RX disassociation %ld\n", Elem->MsgLen)); cfg80211_rx_mlme_mgmt(pAd->ApCfg.ApCliTab[ifIndex].wdev.if_dev, (PUINT8)prDisassocFrame, (size_t)Elem->MsgLen); DBGPRINT(RT_DEBUG_TRACE, ("notification of RX disassociation Done\n")); #endif *pCurrState = APCLI_ASSOC_IDLE; #ifdef MAC_REPEATER_SUPPORT ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PEER_DISCONNECT_REQ, 0, NULL, ifIndex); #ifdef MAC_REPEATER_SUPPORT if ((pAd->ApCfg.bMACRepeaterEn == TRUE) && (ifIndex >= 64)) { RTMP_MLME_HANDLER(pAd); ifIndex = ((ifIndex - 64) / 16); RTMPRemoveRepeaterEntry(pAd, ifIndex, CliIdx); } #endif /* MAC_REPEATER_SUPPORT */ } } else { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliPeerDisassocAction() sanity check fail\n")); } return; } /* ========================================================================== Description: what the state machine will do after assoc timeout ========================================================================== */ static VOID ApCliAssocTimeoutAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = NULL; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliAssocTimeoutAction\n")); if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; *pCurrState = APCLI_ASSOC_IDLE; #ifdef MAC_REPEATER_SUPPORT ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_REQ_TIMEOUT, 0, NULL, ifIndex); return; } static VOID ApCliInvalidStateWhenAssoc( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = NULL; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliInvalidStateWhenAssoc(state=%ld), reset APCLI_ASSOC state machine\n", *pCurrState)); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT; #ifdef MAC_REPEATER_SUPPORT ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); return; } static VOID ApCliInvalidStateWhenDisassociate( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; USHORT ifIndex = (USHORT)(Elem->Priv); ULONG *pCurrState = NULL; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - InvalidStateWhenApCliDisassoc(state=%ld), reset APCLI_ASSOC state machine\n", *pCurrState)); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = CliIdx; ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DEASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); return; } /* ========================================================================== Description: procedures on IEEE 802.11/1999 p.376 Parametrs: ========================================================================== */ static VOID ApCliAssocPostProc( IN PRTMP_ADAPTER pAd, IN PUCHAR pAddr2, IN USHORT CapabilityInfo, IN USHORT IfIndex, IN UCHAR SupRate[], IN UCHAR SupRateLen, IN UCHAR ExtRate[], IN UCHAR ExtRateLen, IN PEDCA_PARM pEdcaParm, IN HT_CAPABILITY_IE *pHtCapability, IN UCHAR HtCapabilityLen, IN ADD_HT_INFO_IE *pAddHtInfo) { APCLI_STRUCT *pApCliEntry = NULL; if (IfIndex >= MAX_APCLI_NUM) return; pApCliEntry = &pAd->ApCfg.ApCliTab[IfIndex]; pApCliEntry->MlmeAux.BssType = BSS_INFRA; pApCliEntry->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; NdisMoveMemory(&pApCliEntry->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM)); /* filter out un-supported rates */ pApCliEntry->MlmeAux.SupRateLen = SupRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.SupRate, SupRate, SupRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.SupRate, &(pApCliEntry->MlmeAux.SupRateLen)); /* filter out un-supported rates */ pApCliEntry->MlmeAux.ExtRateLen = ExtRateLen; NdisMoveMemory(pApCliEntry->MlmeAux.ExtRate, ExtRate, ExtRateLen); RTMPCheckRates(pAd, pApCliEntry->MlmeAux.ExtRate, &(pApCliEntry->MlmeAux.ExtRateLen)); DBGPRINT(RT_DEBUG_TRACE, (HtCapabilityLen ? "%s===> 11n HT STA\n" : "%s===> legacy STA\n", __FUNCTION__)); #ifdef DOT11_N_SUPPORT if (HtCapabilityLen > 0 && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) ApCliCheckHt(pAd, IfIndex, pHtCapability, pAddHtInfo); #endif /* DOT11_N_SUPPORT */ } #ifdef WPA_SUPPLICANT_SUPPORT VOID ApcliSendAssocIEsToWpaSupplicant( IN RTMP_ADAPTER *pAd, IN UINT ifIndex) { RTMP_STRING custom[IW_CUSTOM_MAX] = {0}; if ((pAd->ApCfg.ApCliTab[ifIndex].ReqVarIELen + 17) <= IW_CUSTOM_MAX) { sprintf(custom, "ASSOCINFO_ReqIEs="); NdisMoveMemory(custom+17, pAd->ApCfg.ApCliTab[ifIndex].ReqVarIEs, pAd->ApCfg.ApCliTab[ifIndex].ReqVarIELen); RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_REQIE_EVENT_FLAG, NULL, (PUCHAR)custom, pAd->ApCfg.ApCliTab[ifIndex].ReqVarIELen + 17); RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_ASSOCINFO_EVENT_FLAG, NULL, NULL, 0); } else DBGPRINT(RT_DEBUG_TRACE, ("pAd->ApCfg.ApCliTab[%d].ReqVarIELen + 17 > MAX_CUSTOM_LEN\n",ifIndex)); return; } #endif /* WPA_SUPPLICANT_SUPPORT */ #endif /* APCLI_SUPPORT */