/* ========================================================================== Description: When waiting joining the (I)BSS, beacon received from external ========================================================================== */ static VOID ApCliPeerProbeRspAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { USHORT LenVIE; UCHAR *VarIE = NULL; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PAPCLI_STRUCT pApCliEntry = NULL; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel = 0; #endif /* DOT11_N_SUPPORT */ USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState; BCN_IE_LIST *ie_list = NULL; /* Init Variable IE structure */ os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN); if (VarIE == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); goto LabelErr; } pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__)); goto LabelErr; } NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, ie_list, &LenVIE, pVIE)) { /* BEACON from desired BSS/IBSS found. We should be able to decide most BSS parameters here. Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? Do we need to receover back all parameters belonging to previous BSS? A. Should be not. There's no back-door recover to previous AP. It still need a new JOIN-AUTH-ASSOC sequence. */ INT ssidEqualFlag = FALSE; INT ssidEmptyFlag = FALSE; INT bssidEqualFlag = FALSE; INT bssidEmptyFlag = FALSE; INT matchFlag = FALSE; ULONG Bssidx; #ifdef P2P_SUPPORT MlmeEnqueue(pAd, P2P_DISC_STATE_MACHINE, P2P_DISC_PEER_PROB_RSP, Elem->MsgLen, Elem->Msg, ie_list->Channel); #endif /* P2P_SUPPORT */ /* Update ScanTab */ Bssidx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel); if (Bssidx == BSS_NOT_FOUND) { /* discover new AP of this network, create BSS entry */ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) /* return if BSS table full */ goto LabelErr; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); pAd->ScanTab.BssEntry[Bssidx].MinSNR = Elem->Signal % 10; if (pAd->ScanTab.BssEntry[Bssidx].MinSNR == 0) pAd->ScanTab.BssEntry[Bssidx].MinSNR = -5; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].MacAddr, ie_list->Addr2, MAC_ADDR_LEN); } pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; /* Check the Probe-Rsp's Bssid. */ if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid); else bssidEmptyFlag = TRUE; /* Check the Probe-Rsp's Ssid. */ if(pApCliEntry->CfgSsidLen != 0) ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen); else ssidEmptyFlag = TRUE; /* bssid and ssid, Both match. */ if (bssidEqualFlag && ssidEqualFlag) matchFlag = TRUE; /* ssid match but bssid doesn't be indicate. */ else if(ssidEqualFlag && bssidEmptyFlag) matchFlag = TRUE; /* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */ else if (bssidEmptyFlag && ssidEmptyFlag) matchFlag = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag)); if (matchFlag) { /* Validate RSN IE if necessary, then copy store this information */ if ((LenVIE > 0) #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex)) { pAd->ApCliMlmeAux.VarIELen = LenVIE; NdisMoveMemory(pAd->ApCliMlmeAux.VarIEs, pVIE, pAd->ApCliMlmeAux.VarIELen); } else { /* ignore this response */ pAd->ApCliMlmeAux.VarIELen = 0; DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n")); goto LabelErr; } } else { if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA #ifdef WSC_AP_SUPPORT && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE)) #endif /* WSC_AP_SUPPORT */ ) { /* ignore this response */ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n")); goto LabelErr; } pAd->ApCliMlmeAux.VarIELen = 0; } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel)); /* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */ if (bssidEqualFlag == FALSE) { /* caculate real rssi value. */ CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0, Elem->AntSel, BW_20); CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1, Elem->AntSel, BW_20); CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2, Elem->AntSel, BW_20); LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2)); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pAd->ApCliMlmeAux.Rssi, (LONG)RealRssi)); if (pAd->ApCliMlmeAux.Rssi > (LONG)RealRssi) goto LabelErr; else pAd->ApCliMlmeAux.Rssi = RealRssi; } else { BOOLEAN Cancelled; RTMPCancelTimer(&pAd->ApCliMlmeAux.ProbeTimer, &Cancelled); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { /* Stop Scan and resume */ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); pAd->MlmeAux.Channel = 0; ScanNextChannel(pAd, OPMODE_AP); } DBGPRINT(RT_DEBUG_TRACE, ("%s:: Swich Channel = %d. and STOP Scanning!!\n", __FUNCTION__, ie_list->Channel)); } NdisMoveMemory(pAd->ApCliMlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen); pAd->ApCliMlmeAux.SsidLen = ie_list->SsidLen; NdisMoveMemory(pAd->ApCliMlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN); pAd->ApCliMlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pAd->ApCliMlmeAux.BssType = ie_list->BssType; pAd->ApCliMlmeAux.BeaconPeriod = ie_list->BeaconPeriod; pAd->ApCliMlmeAux.Channel = ie_list->Channel; pAd->ApCliMlmeAux.AtimWin = ie_list->AtimWin; pAd->ApCliMlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod; pAd->ApCliMlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration; pAd->ApCliMlmeAux.APRalinkIe = ie_list->RalinkIe; /* Copy AP's supported rate to MlmeAux for creating assoication request */ /* Also filter out not supported rate */ pAd->ApCliMlmeAux.SupRateLen = ie_list->SupRateLen; NdisMoveMemory(pAd->ApCliMlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen); RTMPCheckRates(pAd, pAd->ApCliMlmeAux.SupRate, &pAd->ApCliMlmeAux.SupRateLen); pAd->ApCliMlmeAux.ExtRateLen = ie_list->ExtRateLen; NdisMoveMemory(pAd->ApCliMlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen); RTMPCheckRates(pAd, pAd->ApCliMlmeAux.ExtRate, &pAd->ApCliMlmeAux.ExtRateLen); #ifdef DOT11_N_SUPPORT NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet,sizeof(pAd->ApCfg.ApCliTab[ifIndex].RxMcsSet)); /* filter out un-supported ht rates */ if ((ie_list->HtCapabilityLen > 0) && (pApCliEntry->DesiredHtPhyInfo.bHtEnable) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { #ifdef P2P_SUPPORT BOOLEAN P2PGroup_BW; UCHAR BwFallBack = 0; #endif /* P2P_SUPPORT */ RTMPZeroMemory(&pAd->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE); pAd->ApCliMlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset; pAd->ApCliMlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen; ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo); RTMPMoveMemory(&pAd->ApCliMlmeAux.AddHtInfo, &ie_list->AddHtInfo, SIZE_ADD_HT_INFO_IE); if (ie_list->AddHtInfoLen > 0) { CentralChannel = ie_list->AddHtInfo.ControlChan; /* Check again the Bandwidth capability of this AP. */ CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo, &ie_list->HtCapability); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, ie_list->AddHtInfo.ControlChan)); } #ifdef P2P_SUPPORT if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != CentralChannel) && (pAd->StaActive.SupportedHtPhy.ChannelWidth == BW_40)) { DBGPRINT(RT_DEBUG_OFF, ("PeerBeaconAtJoinAction HT===> Channel offset = %d not match INFRA Channel offset %d .\n", pAd->MlmeAux.CentralChannel, CentralChannel)); //goto LabelErr; } /*P2PChannelInit(pAd, MAIN_MBSSID); */ pAd->ApCliMlmeAux.CentralChannel = CentralChannel; //P2PInitChannelRelatedValue(pAd); if (pAd->ApCliMlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40) P2PGroup_BW = TRUE; else P2PGroup_BW = FALSE; AdjustChannelRelatedValue(pAd, &BwFallBack, ifIndex, P2PGroup_BW, pAd->ApCliMlmeAux.Channel, pAd->ApCliMlmeAux.CentralChannel); if (BwFallBack == 1) { DBGPRINT(RT_DEBUG_TRACE, ("Infra STA connection to 40MHz AP, but Infra extra and P2P Group extra is different!!!\n")); pAd->ApCliMlmeAux.HtCapability.HtCapInfo.ChannelWidth = BW_20; pAd->ApCliMlmeAux.CentralChannel = pAd->ApCliMlmeAux.Channel; pAd->ApCliMlmeAux.bBwFallBack = TRUE; } else { pAd->ApCliMlmeAux.bBwFallBack = FALSE; } pAd->ApCliMlmeAux.ConCurrentCentralChannel = pAd->CommonCfg.CentralChannel; #endif /* P2P_SUPPORT */ } else #endif /* DOT11_N_SUPPORT */ { RTMPZeroMemory(&pAd->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE); RTMPZeroMemory(&pAd->ApCliMlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); pAd->ApCliMlmeAux.HtCapabilityLen = 0; } #ifdef P2P_SUPPORT P2PUpdateMlmeRate(pAd); #else RTMPUpdateMlmeRate(pAd); #endif /* P2P_SUPPORT */ #ifdef DOT11_N_SUPPORT /* copy QOS related information */ if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { NdisMoveMemory(&pAd->ApCliMlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pAd->ApCliMlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->ApCliMlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else #endif /* DOT11_N_SUPPORT */ { NdisZeroMemory(&pAd->ApCliMlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pAd->ApCliMlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pAd->ApCliMlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pAd->ApCliMlmeAux.SupRateLen, pAd->ApCliMlmeAux.ExtRateLen)); if (ie_list->AironetCellPowerLimit != 0xFF) { /*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */ ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit); } else /*Used the default TX Power Percentage. */ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; if(bssidEqualFlag == TRUE) { *pCurrState = APCLI_SYNC_IDLE; ApCliCtrlMsg.Status = MLME_SUCCESS; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } } /* not to me BEACON, ignored */ } /* sanity check fail, ignore this frame */ LabelErr: if (VarIE != NULL) os_free_mem(NULL, VarIE); if (ie_list != NULL) os_free_mem(NULL, ie_list); return; }
VOID PeerBeaconAtJoinAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe, DtimCount, DtimPeriod, BcastFlag, NewChannel; LARGE_INTEGER TimeStamp; USHORT BeaconPeriod, AtimWin, CapabilityInfo; CF_PARM Cf; BOOLEAN TimerCancelled; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; UCHAR CkipFlag; USHORT LenVIE; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; USHORT Status; UCHAR VarIE[MAX_VIE_LEN]; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; ULONG RalinkIe; ULONG Idx; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; #ifdef DOT11_N_SUPPORT UCHAR CentralChannel; BOOLEAN bAllowNrate = FALSE; #endif pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, (PCHAR)Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &Cf, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, &PreNHtCapabilityLen, &HtCapability, &AddHtInfoLen, &AddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE)) { if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12)) return; if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel)); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled); pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0); pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1); pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2); pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0; pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3; pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1; pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3; pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2; pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3; if (pAd->MlmeAux.SsidLen == 0) { NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); pAd->MlmeAux.SsidLen = SsidLen; } else { Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel); if (Idx == BSS_NOT_FOUND) { CHAR Rssi = 0; Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (CHAR *) Ssid, SsidLen, BssType, BeaconPeriod, &Cf, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); if (Idx != BSS_NOT_FOUND) { NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; } } else { CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; } } NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN); pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pAd->MlmeAux.BssType = BssType; pAd->MlmeAux.BeaconPeriod = BeaconPeriod; pAd->MlmeAux.Channel = Channel; pAd->MlmeAux.AtimWin = AtimWin; pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod; pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration; pAd->MlmeAux.APRalinkIe = RalinkIe; pAd->MlmeAux.SupRateLen = SupRateLen; NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); pAd->MlmeAux.ExtRateLen = ExtRateLen; NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16); #ifdef DOT11_N_SUPPORT if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled)) || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) { bAllowNrate = TRUE; } pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen; RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (bAllowNrate))) { RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE); NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16); pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE; pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE; if (PreNHtCapabilityLen > 0) pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE; RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n", pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth)); if (AddHtInfoLen > 0) { CentralChannel = AddHtInfo.ControlChan; if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = AddHtInfo.ControlChan - 2; } else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40)) { CentralChannel = AddHtInfo.ControlChan + 2; } if (pAd->MlmeAux.CentralChannel != CentralChannel) DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel)); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan)); } } else #endif { if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0)) pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel; pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; pAd->MlmeAux.NewExtChannelOffset = 0xff; RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); pAd->MlmeAux.HtCapabilityLen = 0; RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); } RTMPUpdateMlmeRate(pAd); if ((pAd->CommonCfg.bWmmCapable) #ifdef DOT11_N_SUPPORT || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) #endif ) { NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else { NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen)); if (AironetCellPowerLimit != 0xFF) { ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); } else pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status); } } }
VOID FT_OTD_PeerRspAtSeq2Action( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR TargetAddr[MAC_ADDR_LEN]; USHORT Status; BOOLEAN TimerCancelled; ULONG BssIdx = 0; FT_FTIE FtIe; FT_MDIE MdIe; PFRAME_802_11 pFrame = (PFRAME_802_11) Elem->Msg; MLME_ASSOC_REQ_STRUCT AssocReq; UCHAR BBPValue = 0; DBGPRINT(RT_DEBUG_TRACE, ("FT_OTD_ACTION - PeerFtRspAtSeq2Action MlmeAux.Bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->MlmeAux.Bssid))); if (PeerFtRspSanity (pAd, Elem->Msg, Elem->MsgLen, TargetAddr, &FtIe, &MdIe, &Status)) { if (MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pFrame->Hdr.Addr2)) { DBGPRINT(RT_DEBUG_TRACE, ("FT_OTD_ACTION - Receive FT_RSP seq#2 to me ( Status=%d)\n", Status)); RTMPCancelTimer(&pAd->MlmeAux.FtOtdActTimer, &TimerCancelled); if (Status == MLME_SUCCESS) { UINT8 ptk_len; PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[MCAST_WCID]; NdisMoveMemory(pEntry->SNonce, FtIe.SNonce, 32); /* Get ANonce from authentication-response */ NdisMoveMemory(pEntry->ANonce, FtIe.ANonce, 32); hex_dump("anonce", pEntry->ANonce, 32); hex_dump("snonce", pEntry->SNonce, 32); FT_DerivePMKR1(pAd->StaCfg.Dot11RCommInfo.PMKR0, pAd->StaCfg.Dot11RCommInfo.PMKR0Name, TargetAddr, /*pAd->MlmeAux.Bssid, */ pAd->CurrentAddress, pEntry->FT_PMK_R1, pEntry->FT_PMK_R1_NAME); if (pEntry->WepStatus == Ndis802_11TKIPEnable) ptk_len = 32 + 32; else ptk_len = 32 + 16; /* Derive FT PTK and PTK-NAME */ FT_DerivePTK(pEntry->FT_PMK_R1, pEntry->FT_PMK_R1_NAME, pEntry->ANonce, pEntry->SNonce, TargetAddr, /*pAd->MlmeAux.Bssid, */ pAd->CurrentAddress, ptk_len, pEntry->PTK, pEntry->PTK_NAME); /* How to know there is resource request session now ???????? */ if ((pAd->StaCfg.Dot11RCommInfo.bSupportResource) && (pAd->MlmeAux.MdIeInfo.FtCapPlc.field.RsrReqCap)) { /* Prepare to send FT Confirm packet. */ DBGPRINT(RT_DEBUG_TRACE, ("FT_OTD_ACTION - Receive FT_RSP seq#2 to me, Prepare to send FT Confirm. \n")); pAd->Mlme.FtOtdActMachine.CurrState = FT_OTD_WAIT_SEQ4; } else { BSS_ENTRY *pBss = NULL; /* Doesn't need to send FT Confirm packet. */ DBGPRINT(RT_DEBUG_TRACE, ("FT_OTD_ACTION - Receive FT_RSP seq#2 to me, Prepare to send Reassoc. \n")); pAd->StaCfg.Dot11RCommInfo.FtRspSuccess = FT_OTD_RESPONSE; pAd->Mlme.FtOtdActMachine.CurrState = FT_OTD_IDLE; RTMPMoveMemory(pAd->MlmeAux.Bssid, TargetAddr, MAC_ADDR_LEN); /* find the desired BSS in the latest SCAN result table search 2.4G band first */ BssIdx = BssTableSearch(&pAd->ScanTab, TargetAddr, 1); /* search 5G band, if AP does not exist in 2.4G band */ if (BssIdx == BSS_NOT_FOUND) BssIdx = BssTableSearch(&pAd->ScanTab, TargetAddr, 36); if (BssIdx == BSS_NOT_FOUND) { DBGPRINT(RT_DEBUG_TRACE, ("FT_OTD_ACTION - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n")); pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; return; } pBss = &pAd->ScanTab.BssEntry[BssIdx]; pAd->MlmeAux.Channel = pBss->Channel; pAd->MlmeAux.CentralChannel = pBss->CentralChannel; RTMPZeroMemory(pAd->MlmeAux.ExtRate, MAX_LEN_OF_SUPPORTED_RATES); RTMPZeroMemory(pAd->MlmeAux.SupRate, MAX_LEN_OF_SUPPORTED_RATES); pAd->MlmeAux.ExtRateLen = pBss->ExtRateLen; RTMPMoveMemory(pAd->MlmeAux.ExtRate, pBss->ExtRate, pBss->ExtRateLen); pAd->MlmeAux.SupRateLen = pBss->SupRateLen; RTMPMoveMemory(pAd->MlmeAux.SupRate, pBss->SupRate, pBss->SupRateLen); RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); pAd->MlmeAux.SsidLen = pBss->SsidLen; RTMPMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen); /* StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability */ if (pBss->HtCapabilityLen) { RTMPMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, pBss->HtCapability.MCSSet, 16); } else { NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16); } bbp_set_bw(pAd, BW_20); AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE); AsicLockChannel(pAd, pAd->MlmeAux.Channel); RTMPUpdateMlmeRate(pAd); AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo, ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount); MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ, sizeof (MLME_ASSOC_REQ_STRUCT), &AssocReq, 0); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC; } } else { pAd->StaCfg.AuthFailReason = Status; COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, pFrame->Hdr.Addr2); pAd->Mlme.FtOtdActMachine.CurrState = FT_OTD_IDLE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_FT_OTD_CONF, 2, &Status, 0); } } } else { DBGPRINT(RT_DEBUG_TRACE, ("FT_OTD_ACTION - PeerFtRspSanity() sanity check fail\n")); } }