/* ========================================================================== Description: APCLI MLME JOIN req state machine procedure ========================================================================== */ static VOID ApCliCtrlJoinReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { APCLI_MLME_JOIN_REQ_STRUCT JoinReq; PAPCLI_STRUCT pApCliEntry; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState; #ifdef WSC_AP_SUPPORT PWSC_CTRL pWpsCtrl = &pAd->ApCfg.ApCliTab[ifIndex].WscControl; #endif /* WSC_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Start Probe Req.\n", __FUNCTION__)); if (ifIndex >= MAX_APCLI_NUM) return; if (ApScanRunning(pAd) == TRUE) return; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; NdisZeroMemory(&JoinReq, sizeof(APCLI_MLME_JOIN_REQ_STRUCT)); if (!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR)) { COPY_MAC_ADDR(JoinReq.Bssid, pApCliEntry->CfgApCliBssid); } #ifdef WSC_AP_SUPPORT if ((pWpsCtrl->WscConfMode != WSC_DISABLE) && (pWpsCtrl->bWscTrigger == TRUE)) { ULONG bss_idx = 0; NdisZeroMemory(JoinReq.Ssid, MAX_LEN_OF_SSID); JoinReq.SsidLen = pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.SsidLength; NdisMoveMemory(JoinReq.Ssid, pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscSsid.Ssid, JoinReq.SsidLen); { bss_idx = BssSsidTableSearch(&pAd->ScanTab, pAd->P2pCfg.Bssid, (PCHAR)JoinReq.Ssid, JoinReq.SsidLen, pAd->CommonCfg.Channel); if (bss_idx == BSS_NOT_FOUND) { *pCurrState = APCLI_CTRL_PROBE; ApSiteSurvey(pAd, NULL, SCAN_WSC_ACTIVE, FALSE); return; } else { BOOLEAN Cancelled; INT old_conf_mode = pWpsCtrl->WscConfMode, old_wsc_mode = pWpsCtrl->WscMode; ADD_HTINFO RootApHtInfo, ApHtInfo; UCHAR channel = pAd->CommonCfg.Channel, RootApChannel = pAd->ScanTab.BssEntry[bss_idx].Channel; UCHAR RootApCentralChannel = pAd->ScanTab.BssEntry[bss_idx].CentralChannel; ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo; RootApHtInfo = pAd->ScanTab.BssEntry[bss_idx].AddHtInfo.AddHtInfo; if (INFRA_ON(pAd) && (pAd->StaActive.SupportedHtPhy.ExtChanOffset != RootApHtInfo.ExtChanOffset) && (pAd->StaActive.SupportedHtPhy.ChannelWidth == BW_40)) { DBGPRINT(RT_DEBUG_OFF, ("%s :: Channel offset = %d not match INFRA Channel offset %d .\n", __FUNCTION__, pAd->MlmeAux.CentralChannel, RootApCentralChannel)); P2pLinkDown(pAd, P2P_CONNECT_FAIL); return; } if ((RootApChannel != channel) || ((RootApCentralChannel != RootApChannel) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && (ApHtInfo.ExtChanOffset != RootApHtInfo.ExtChanOffset))) { STRING ChStr[5] = {0}; if (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) { if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE) Set_HtExtcha_Proc(pAd, "1"); else Set_HtExtcha_Proc(pAd, "0"); } sprintf(ChStr, "%d", pAd->ScanTab.BssEntry[bss_idx].Channel); Set_Channel_Proc(pAd, ChStr); /* ApStop will call WscStop, we need to reset WscConfMode, WscMode & bWscTrigger here. */ pWpsCtrl->WscState = WSC_STATE_START; pWpsCtrl->WscStatus = STATUS_WSC_START_ASSOC; pWpsCtrl->WscMode = old_wsc_mode; pWpsCtrl->WscConfMode = old_conf_mode; pWpsCtrl->bWscTrigger = TRUE; return; } else { pAd->CommonCfg.Channel = pAd->ScanTab.BssEntry[bss_idx].Channel; AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); } } } } else #endif /* WSC_AP_SUPPORT */ if (pApCliEntry->CfgSsidLen != 0) { ULONG bss_idx = 0; bss_idx = BssSsidTableSearch(&pAd->ScanTab, JoinReq.Bssid, (PCHAR)pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, pAd->CommonCfg.Channel); if (bss_idx == BSS_NOT_FOUND) { DBGPRINT(RT_DEBUG_TRACE, ("%s:: can't find SSID[%s] in ScanTab.\n", __FUNCTION__, pApCliEntry->CfgSsid)); *pCurrState = APCLI_CTRL_PROBE; ApSiteSurvey(pAd, NULL, SCAN_ACTIVE, FALSE); return; } DBGPRINT(RT_DEBUG_TRACE, ("%s:: find SSID[%ld][%s] channel[%d-%d] in ScanTab.\n", __FUNCTION__, bss_idx, pApCliEntry->CfgSsid, pAd->ScanTab.BssEntry[bss_idx].Channel, pAd->ScanTab.BssEntry[bss_idx].CentralChannel)); /* BssSearch Table has found the pEntry, send Prob Req. directly */ pAd->CommonCfg.Channel = pAd->ScanTab.BssEntry[bss_idx].Channel; AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); JoinReq.SsidLen = pApCliEntry->CfgSsidLen; NdisMoveMemory(&(JoinReq.Ssid), pApCliEntry->CfgSsid, JoinReq.SsidLen); } if (pApCliEntry->CfgSsidLen == 0) { DBGPRINT(RT_DEBUG_TRACE, ("%s:: ApCliEntry SSID Len is 0 !!!.\n", __FUNCTION__)); *pCurrState = APCLI_CTRL_PROBE; ApSiteSurvey(pAd, NULL, SCAN_WSC_ACTIVE, FALSE); return; } DBGPRINT(RT_DEBUG_TRACE, ("(%s) Probe Ssid=%s, Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, JoinReq.Ssid, JoinReq.Bssid[0], JoinReq.Bssid[1], JoinReq.Bssid[2], JoinReq.Bssid[3], JoinReq.Bssid[4], JoinReq.Bssid[5])); *pCurrState = APCLI_CTRL_PROBE; MlmeEnqueue(pAd, APCLI_SYNC_STATE_MACHINE, APCLI_MT2_MLME_PROBE_REQ, sizeof(APCLI_MLME_JOIN_REQ_STRUCT), &JoinReq, ifIndex); 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); } } }