728 lines
25 KiB
C
728 lines
25 KiB
C
/*
|
|
***************************************************************************
|
|
* 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:
|
|
sta_sync.c
|
|
|
|
Abstract:
|
|
|
|
Revision History:
|
|
Who When What
|
|
-------- ---------- ----------------------------------------------
|
|
Fonchi 2006-06-23 modified for rt61-APClinent
|
|
*/
|
|
|
|
#ifdef APCLI_SUPPORT
|
|
|
|
#include "rt_config.h"
|
|
|
|
static VOID ApCliProbeTimeout(
|
|
IN PVOID SystemSpecific1,
|
|
IN PVOID FunctionContext,
|
|
IN PVOID SystemSpecific2,
|
|
IN PVOID SystemSpecific3);
|
|
|
|
static VOID ApCliMlmeProbeReqAction(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN MLME_QUEUE_ELEM *Elem);
|
|
|
|
static VOID ApCliPeerProbeRspAtJoinAction(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN MLME_QUEUE_ELEM *Elem);
|
|
|
|
static VOID ApCliProbeTimeoutAtJoinAction(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN MLME_QUEUE_ELEM *Elem);
|
|
|
|
static VOID ApCliInvalidStateWhenJoin(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN MLME_QUEUE_ELEM *Elem);
|
|
|
|
static VOID ApCliEnqueueProbeRequest(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN UCHAR SsidLen,
|
|
OUT PCHAR Ssid,
|
|
IN USHORT ifIndex);
|
|
|
|
DECLARE_TIMER_FUNCTION(ApCliProbeTimeout);
|
|
BUILD_TIMER_FUNCTION(ApCliProbeTimeout);
|
|
|
|
/*
|
|
==========================================================================
|
|
Description:
|
|
The sync state machine,
|
|
Parameters:
|
|
Sm - pointer to the state machine
|
|
Note:
|
|
the state machine looks like the following
|
|
==========================================================================
|
|
*/
|
|
VOID ApCliSyncStateMachineInit(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN STATE_MACHINE *Sm,
|
|
OUT STATE_MACHINE_FUNC Trans[])
|
|
{
|
|
UCHAR i;
|
|
|
|
StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans,
|
|
APCLI_MAX_SYNC_STATE, APCLI_MAX_SYNC_MSG,
|
|
(STATE_MACHINE_FUNC)Drop, APCLI_SYNC_IDLE,
|
|
APCLI_SYNC_MACHINE_BASE);
|
|
|
|
/* column 1 */
|
|
StateMachineSetAction(Sm, APCLI_SYNC_IDLE, APCLI_MT2_MLME_PROBE_REQ, (STATE_MACHINE_FUNC)ApCliMlmeProbeReqAction);
|
|
|
|
/*column 2 */
|
|
StateMachineSetAction(Sm, APCLI_JOIN_WAIT_PROBE_RSP, APCLI_MT2_MLME_PROBE_REQ, (STATE_MACHINE_FUNC)ApCliInvalidStateWhenJoin);
|
|
StateMachineSetAction(Sm, APCLI_JOIN_WAIT_PROBE_RSP, APCLI_MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)ApCliPeerProbeRspAtJoinAction);
|
|
StateMachineSetAction(Sm, APCLI_JOIN_WAIT_PROBE_RSP, APCLI_MT2_PROBE_TIMEOUT, (STATE_MACHINE_FUNC)ApCliProbeTimeoutAtJoinAction);
|
|
StateMachineSetAction(Sm, APCLI_JOIN_WAIT_PROBE_RSP, APCLI_MT2_PEER_BEACON, (STATE_MACHINE_FUNC)ApCliPeerProbeRspAtJoinAction);
|
|
|
|
#if 0
|
|
/* timer init */
|
|
RTMPInitTimer(pAd, &pAd->ApCfg.ApCliTab[0].MlmeAux.ProbeTimer, GET_TIMER_FUNCTION(ApCliProbeTimeout), pAd, FALSE);
|
|
#endif
|
|
|
|
for (i = 0; i < MAX_APCLI_NUM; i++)
|
|
{
|
|
/* timer init */
|
|
RTMPInitTimer(pAd, &pAd->ApCfg.ApCliTab[i].MlmeAux.ProbeTimer, GET_TIMER_FUNCTION(ApCliProbeTimeout), pAd, FALSE);
|
|
|
|
pAd->ApCfg.ApCliTab[i].SyncCurrState = APCLI_SYNC_IDLE;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
==========================================================================
|
|
Description:
|
|
Becaon timeout handler, executed in timer thread
|
|
==========================================================================
|
|
*/
|
|
static VOID ApCliProbeTimeout(
|
|
IN PVOID SystemSpecific1,
|
|
IN PVOID FunctionContext,
|
|
IN PVOID SystemSpecific2,
|
|
IN PVOID SystemSpecific3)
|
|
{
|
|
RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("ApCli_SYNC - ProbeReqTimeout\n"));
|
|
|
|
MlmeEnqueue(pAd, APCLI_SYNC_STATE_MACHINE, APCLI_MT2_PROBE_TIMEOUT, 0, NULL, 0);
|
|
RTMP_MLME_HANDLER(pAd);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
==========================================================================
|
|
Description:
|
|
MLME PROBE req state machine procedure
|
|
==========================================================================
|
|
*/
|
|
static VOID ApCliMlmeProbeReqAction(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN MLME_QUEUE_ELEM *Elem)
|
|
{
|
|
BOOLEAN Cancelled;
|
|
APCLI_MLME_JOIN_REQ_STRUCT *Info = (APCLI_MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
|
|
USHORT ifIndex = (USHORT)(Elem->Priv);
|
|
PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState;
|
|
APCLI_STRUCT *pApCliEntry = NULL;
|
|
|
|
DBGPRINT(RT_DEBUG_OFF, ("ApCli SYNC - ApCliMlmeProbeReqAction(Ssid %s)\n", Info->Ssid));
|
|
|
|
if (ifIndex >= MAX_APCLI_NUM)
|
|
return;
|
|
|
|
pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
|
|
|
|
/* reset all the timers */
|
|
RTMPCancelTimer(&(pApCliEntry->MlmeAux.ProbeTimer), &Cancelled);
|
|
|
|
pApCliEntry->MlmeAux.Rssi = -9999;
|
|
|
|
#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
|
|
//Get Channel from ScanTable
|
|
pApCliEntry->MlmeAux.SupRateLen = pAd->cfg80211_ctrl.P2pSupRateLen;
|
|
NdisMoveMemory(pApCliEntry->MlmeAux.SupRate, pAd->cfg80211_ctrl.P2pSupRate, pAd->cfg80211_ctrl.P2pSupRateLen);
|
|
|
|
pApCliEntry->MlmeAux.ExtRateLen = pAd->cfg80211_ctrl.P2pExtRateLen;
|
|
NdisMoveMemory(pApCliEntry->MlmeAux.ExtRate, pAd->cfg80211_ctrl.P2pExtRate, pAd->cfg80211_ctrl.P2pExtRateLen);
|
|
|
|
#else
|
|
pApCliEntry->MlmeAux.Channel = pAd->CommonCfg.Channel;
|
|
|
|
pApCliEntry->MlmeAux.SupRateLen = pAd->CommonCfg.SupRateLen;
|
|
NdisMoveMemory(pApCliEntry->MlmeAux.SupRate, pAd->CommonCfg.SupRate, pAd->CommonCfg.SupRateLen);
|
|
|
|
/* Prepare the default value for extended rate */
|
|
pApCliEntry->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
|
|
NdisMoveMemory(pApCliEntry->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, pAd->CommonCfg.ExtRateLen);
|
|
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */
|
|
|
|
RTMPSetTimer(&(pApCliEntry->MlmeAux.ProbeTimer), PROBE_TIMEOUT);
|
|
|
|
ApCliEnqueueProbeRequest(pAd, Info->SsidLen, (PCHAR) Info->Ssid, ifIndex);
|
|
|
|
DBGPRINT(RT_DEBUG_OFF, ("ApCli SYNC - Start Probe the SSID %s on channel =%d\n", pApCliEntry->MlmeAux.Ssid, pApCliEntry->MlmeAux.Channel));
|
|
|
|
*pCurrState = APCLI_JOIN_WAIT_PROBE_RSP;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
==========================================================================
|
|
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;
|
|
struct wifi_dev *wdev;
|
|
#ifdef DOT11_N_SUPPORT
|
|
UCHAR CentralChannel;
|
|
#endif /* DOT11_N_SUPPORT */
|
|
USHORT ifIndex = (USHORT)(Elem->Priv);
|
|
ULONG *pCurrState;
|
|
BCN_IE_LIST *ie_list = NULL;
|
|
|
|
if (ifIndex >= MAX_APCLI_NUM)
|
|
return;
|
|
|
|
/* 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));
|
|
|
|
pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState;
|
|
if (PeerBeaconAndProbeRspSanity(pAd,
|
|
Elem->Msg,
|
|
Elem->MsgLen,
|
|
Elem->Channel,
|
|
ie_list,
|
|
&LenVIE,
|
|
pVIE,
|
|
TRUE))
|
|
{
|
|
/*
|
|
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;
|
|
#if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA)
|
|
CHAR Rssi0 = ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_0);
|
|
CHAR Rssi1 = ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_1);
|
|
CHAR Rssi2 = ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_2);
|
|
LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2));
|
|
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */
|
|
|
|
|
|
/* Update ScanTab */
|
|
Bssidx = BssTableSearch(&pAd->ScanTab, ie_list->Bssid, ie_list->Channel);
|
|
if (Bssidx == BSS_NOT_FOUND || Bssidx >= MAX_LEN_OF_BSS_TABLE)
|
|
{
|
|
/* discover new AP of this network, create BSS entry */
|
|
Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, ie_list, -127, LenVIE, pVIE);
|
|
|
|
if (Bssidx == BSS_NOT_FOUND || Bssidx >= MAX_LEN_OF_BSS_TABLE) /* return if BSS table full */
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR, ("ERROR: Driver ScanTable Full In Apcli ProbeRsp Join\n"));
|
|
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);
|
|
}
|
|
|
|
#if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA)
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Info: Update the SSID %s in Kernel Table\n", ie_list->Ssid));
|
|
RT_CFG80211_SCANNING_INFORM(pAd, Bssidx, ie_list->Channel, (UCHAR *)Elem->Msg, Elem->MsgLen, RealRssi);
|
|
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */
|
|
|
|
|
|
pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
|
|
wdev = &pApCliEntry->wdev;
|
|
|
|
/* 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
|
|
&& ((pApCliEntry->WscControl.WscConfMode == WSC_DISABLE) ||
|
|
(pApCliEntry->WscControl.bWscTrigger == FALSE))
|
|
#endif /* WSC_AP_SUPPORT */
|
|
#if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA)
|
|
/* When using CFG80211 and trigger WPS, do not check security. */
|
|
&& ! (pApCliEntry->wpa_supplicant_info.WpaSupplicantUP & WPA_SUPPLICANT_ENABLE_WPS)
|
|
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */
|
|
)
|
|
{
|
|
if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex))
|
|
{
|
|
pApCliEntry->MlmeAux.VarIELen = LenVIE;
|
|
NdisMoveMemory(pApCliEntry->MlmeAux.VarIEs, pVIE, pApCliEntry->MlmeAux.VarIELen);
|
|
}
|
|
else
|
|
{
|
|
/* ignore this response */
|
|
pApCliEntry->MlmeAux.VarIELen = 0;
|
|
DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n"));
|
|
goto LabelErr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pApCliEntry->wdev.AuthMode >= Ndis802_11AuthModeWPA
|
|
#ifdef WSC_AP_SUPPORT
|
|
&& ((pApCliEntry->WscControl.WscConfMode == WSC_DISABLE) ||
|
|
(pApCliEntry->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;
|
|
}
|
|
|
|
pApCliEntry->MlmeAux.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->rssi_info, RSSI_IDX_0);
|
|
CHAR Rssi1 = ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_1);
|
|
CHAR Rssi2 = ConvertToRssi(pAd, &Elem->rssi_info, RSSI_IDX_2);
|
|
LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2));
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->MlmeAux.Rssi, (LONG)RealRssi));
|
|
if (pApCliEntry->MlmeAux.Rssi > (LONG)RealRssi)
|
|
goto LabelErr;
|
|
else
|
|
pApCliEntry->MlmeAux.Rssi = RealRssi;
|
|
}
|
|
else
|
|
{
|
|
BOOLEAN Cancelled;
|
|
RTMPCancelTimer(&pApCliEntry->MlmeAux.ProbeTimer, &Cancelled);
|
|
}
|
|
|
|
NdisMoveMemory(pApCliEntry->MlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen);
|
|
pApCliEntry->MlmeAux.SsidLen = ie_list->SsidLen;
|
|
|
|
NdisMoveMemory(pApCliEntry->MlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN);
|
|
pApCliEntry->MlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
|
|
pApCliEntry->MlmeAux.BssType = ie_list->BssType;
|
|
pApCliEntry->MlmeAux.BeaconPeriod = ie_list->BeaconPeriod;
|
|
pApCliEntry->MlmeAux.Channel = ie_list->Channel;
|
|
pApCliEntry->MlmeAux.AtimWin = ie_list->AtimWin;
|
|
pApCliEntry->MlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod;
|
|
pApCliEntry->MlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration;
|
|
pApCliEntry->MlmeAux.APRalinkIe = ie_list->RalinkIe;
|
|
|
|
/* Copy AP's supported rate to MlmeAux for creating assoication request */
|
|
/* Also filter out not supported rate */
|
|
pApCliEntry->MlmeAux.SupRateLen = ie_list->SupRateLen;
|
|
NdisMoveMemory(pApCliEntry->MlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen);
|
|
RTMPCheckRates(pAd, pApCliEntry->MlmeAux.SupRate, &pApCliEntry->MlmeAux.SupRateLen);
|
|
pApCliEntry->MlmeAux.ExtRateLen = ie_list->ExtRateLen;
|
|
NdisMoveMemory(pApCliEntry->MlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen);
|
|
RTMPCheckRates(pAd, pApCliEntry->MlmeAux.ExtRate, &pApCliEntry->MlmeAux.ExtRateLen);
|
|
|
|
#ifdef DOT11_N_SUPPORT
|
|
#ifdef RELEASE_EXCLUDE
|
|
/*
|
|
Must Clear the RxMcsSet or the APClient will use the RxMCs of the previous connected AP.
|
|
For example, if ApClient connect to B/G Mixed AP after connecting to N-Mode AP.
|
|
APMlmeDynamicTxRateSwitching->APMlmeSelectTxRateTable (Select N Table based on MCS)
|
|
APMlmeDynamicTxRateSwitching->APMlmeSetTxRate(Use N Rate on the selected Table)
|
|
*/
|
|
#endif /* RELEASE_EXCLUDE */
|
|
NdisZeroMemory(pApCliEntry->RxMcsSet,sizeof(pApCliEntry->RxMcsSet));
|
|
/* filter out un-supported ht rates */
|
|
if ((ie_list->HtCapabilityLen > 0) &&
|
|
#ifndef RT_CFG80211_P2P_CONCURRENT_DEVICE
|
|
(pApCliEntry->wdev.DesiredHtPhyInfo.bHtEnable) &&
|
|
#endif /*RT_CFG80211_P2P_CONCURRENT_DEVICE */
|
|
WMODE_CAP_N(pAd->CommonCfg.PhyMode) &&
|
|
/* For Dissallow TKIP rule on STA */
|
|
!(pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus)))
|
|
{
|
|
RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
|
|
pApCliEntry->MlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset;
|
|
pApCliEntry->MlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen;
|
|
ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo);
|
|
|
|
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_OFF, ("PeerBeaconAtJoinAction HT===>CentralCh = %d, ControlCh = %d\n",
|
|
CentralChannel, ie_list->AddHtInfo.ControlChan));
|
|
}
|
|
}
|
|
else
|
|
#endif /* DOT11_N_SUPPORT */
|
|
{
|
|
RTMPZeroMemory(&pApCliEntry->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
|
|
RTMPZeroMemory(&pApCliEntry->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
|
|
pApCliEntry->MlmeAux.HtCapabilityLen = 0;
|
|
}
|
|
#if 0 //Move to ApCliPeerAssocRspAction.
|
|
#ifdef DOT11_VHT_AC
|
|
if (ie_list->vht_cap_len && ie_list->vht_op_len)
|
|
{
|
|
RTMPZeroMemory(&pApCliEntry->MlmeAux.vht_cap, sizeof(VHT_CAP_IE));
|
|
NdisMoveMemory(&pApCliEntry->MlmeAux.vht_cap, &(ie_list->vht_cap_ie), ie_list->vht_cap_len);
|
|
RTMPZeroMemory(&pApCliEntry->MlmeAux.vht_op, sizeof(VHT_OP_IE));
|
|
NdisMoveMemory(&pApCliEntry->MlmeAux.vht_op, &(ie_list->vht_op_ie), ie_list->vht_op_len);
|
|
}
|
|
#endif /* DOT11_VHT_AC */
|
|
#endif
|
|
ApCliUpdateMlmeRate(pAd, ifIndex);
|
|
|
|
#ifdef DOT11_N_SUPPORT
|
|
/* copy QOS related information */
|
|
if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
|
|
{
|
|
NdisMoveMemory(&pApCliEntry->MlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM));
|
|
NdisMoveMemory(&pApCliEntry->MlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM));
|
|
NdisMoveMemory(&pApCliEntry->MlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM));
|
|
}
|
|
else
|
|
#endif /* DOT11_N_SUPPORT */
|
|
{
|
|
NdisZeroMemory(&pApCliEntry->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
|
|
NdisZeroMemory(&pApCliEntry->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
|
|
NdisZeroMemory(&pApCliEntry->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
|
|
}
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
|
|
pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.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;
|
|
|
|
#ifdef WSC_AP_SUPPORT
|
|
#ifdef DOT11_N_SUPPORT
|
|
if ((pApCliEntry->WscControl.WscConfMode != WSC_DISABLE) &&
|
|
(pApCliEntry->WscControl.bWscTrigger == TRUE))
|
|
{
|
|
ADD_HTINFO RootApHtInfo, ApHtInfo;
|
|
ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo;
|
|
RootApHtInfo = ie_list->AddHtInfo.AddHtInfo;
|
|
if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
|
|
(RootApHtInfo.RecomWidth) &&
|
|
(RootApHtInfo.ExtChanOffset != ApHtInfo.ExtChanOffset))
|
|
{
|
|
if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE)
|
|
Set_HtExtcha_Proc(pAd, "1");
|
|
else
|
|
Set_HtExtcha_Proc(pAd, "0");
|
|
|
|
goto LabelErr;
|
|
}
|
|
}
|
|
#endif /* DOT11_N_SUPPORT */
|
|
#endif /* WSC_AP_SUPPORT */
|
|
if(bssidEqualFlag == TRUE)
|
|
{
|
|
*pCurrState = APCLI_SYNC_IDLE;
|
|
|
|
ApCliCtrlMsg.Status = MLME_SUCCESS;
|
|
#ifdef MAC_REPEATER_SUPPORT
|
|
ApCliCtrlMsg.BssIdx = ifIndex;
|
|
ApCliCtrlMsg.CliIdx = 0xFF;
|
|
#endif /* MAC_REPEATER_SUPPORT */
|
|
|
|
MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP,
|
|
sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
LabelErr:
|
|
if (VarIE != NULL)
|
|
os_free_mem(NULL, VarIE);
|
|
if (ie_list != NULL)
|
|
os_free_mem(NULL, ie_list);
|
|
|
|
return;
|
|
}
|
|
|
|
static VOID ApCliProbeTimeoutAtJoinAction(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN MLME_QUEUE_ELEM *Elem)
|
|
{
|
|
APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
|
|
USHORT ifIndex = (USHORT)(Elem->Priv);
|
|
PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState;
|
|
APCLI_STRUCT *pApCliEntry = NULL;
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("APCLI_SYNC - ProbeTimeoutAtJoinAction\n"));
|
|
|
|
if (ifIndex >= MAX_APCLI_NUM)
|
|
return;
|
|
|
|
pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
|
|
*pCurrState = SYNC_IDLE;
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("APCLI_SYNC - MlmeAux.Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
PRINT_MAC(pApCliEntry->MlmeAux.Bssid)));
|
|
|
|
if(!MAC_ADDR_EQUAL(pApCliEntry->MlmeAux.Bssid, ZERO_MAC_ADDR))
|
|
{
|
|
ApCliCtrlMsg.Status = MLME_SUCCESS;
|
|
#ifdef MAC_REPEATER_SUPPORT
|
|
ApCliCtrlMsg.BssIdx = ifIndex;
|
|
ApCliCtrlMsg.CliIdx = 0xFF;
|
|
#endif /* MAC_REPEATER_SUPPORT */
|
|
|
|
MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP,
|
|
sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
|
|
} else
|
|
{
|
|
MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_JOIN_REQ_TIMEOUT, 0, NULL, ifIndex);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
==========================================================================
|
|
Description:
|
|
==========================================================================
|
|
*/
|
|
static VOID ApCliInvalidStateWhenJoin(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN MLME_QUEUE_ELEM *Elem)
|
|
{
|
|
APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
|
|
USHORT ifIndex = (USHORT)(Elem->Priv);
|
|
PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState;
|
|
|
|
*pCurrState = APCLI_SYNC_IDLE;
|
|
ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT;
|
|
#ifdef MAC_REPEATER_SUPPORT
|
|
ApCliCtrlMsg.BssIdx = ifIndex;
|
|
ApCliCtrlMsg.CliIdx = 0xFF;
|
|
#endif /* MAC_REPEATER_SUPPORT */
|
|
|
|
MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP,
|
|
sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("APCLI_AYNC - ApCliInvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", *pCurrState));
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
==========================================================================
|
|
Description:
|
|
==========================================================================
|
|
*/
|
|
static VOID ApCliEnqueueProbeRequest(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN UCHAR SsidLen,
|
|
OUT PCHAR Ssid,
|
|
IN USHORT ifIndex)
|
|
{
|
|
NDIS_STATUS NState;
|
|
PUCHAR pOutBuffer;
|
|
ULONG FrameLen = 0;
|
|
HEADER_802_11 Hdr80211;
|
|
UCHAR SsidIe = IE_SSID;
|
|
UCHAR SupRateIe = IE_SUPP_RATES;
|
|
UCHAR ssidLen;
|
|
CHAR ssid[MAX_LEN_OF_SSID];
|
|
APCLI_STRUCT *pApCliEntry = NULL;
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
|
|
|
|
if (ifIndex >= MAX_APCLI_NUM)
|
|
return;
|
|
|
|
pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];
|
|
|
|
NState = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */
|
|
if(NState != NDIS_STATUS_SUCCESS)
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("EnqueueProbeRequest() allocate memory fail\n"));
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if (MAC_ADDR_EQUAL(pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, ZERO_MAC_ADDR)) {
|
|
ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
|
|
BROADCAST_ADDR, BROADCAST_ADDR, ifIndex);
|
|
} else {
|
|
#if 1
|
|
/* Fix WFD Certification 6.1.21B and IOT issue:
|
|
* DUT will not reply probe response
|
|
* if we send the probe request by unicast
|
|
*/
|
|
DBGPRINT(RT_DEBUG_TRACE,
|
|
("force out a ProbeRequest by broadcast but not unicast...\n"));
|
|
ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
|
|
BROADCAST_ADDR, BROADCAST_ADDR, ifIndex);
|
|
#else
|
|
ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
|
|
pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, ifIndex);
|
|
#endif
|
|
}
|
|
|
|
ssidLen = SsidLen;
|
|
NdisZeroMemory(ssid, MAX_LEN_OF_SSID);
|
|
NdisMoveMemory(ssid, Ssid, ssidLen);
|
|
|
|
/* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */
|
|
MakeOutgoingFrame(pOutBuffer, &FrameLen,
|
|
sizeof(HEADER_802_11), &Hdr80211,
|
|
1, &SsidIe,
|
|
1, &ssidLen,
|
|
ssidLen, ssid,
|
|
1, &SupRateIe,
|
|
1, &pApCliEntry->MlmeAux.SupRateLen,
|
|
pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.SupRate,
|
|
END_OF_ARGS);
|
|
|
|
/* Add the extended rate IE */
|
|
if (pApCliEntry->MlmeAux.ExtRateLen != 0)
|
|
{
|
|
ULONG tmp;
|
|
|
|
MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
|
|
1, &ExtRateIe,
|
|
1, &pApCliEntry->MlmeAux.ExtRateLen,
|
|
pApCliEntry->MlmeAux.ExtRateLen, pApCliEntry->MlmeAux.ExtRate,
|
|
END_OF_ARGS);
|
|
FrameLen += tmp;
|
|
}
|
|
|
|
#ifdef DOT11_VHT_AC
|
|
if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) &&
|
|
(pAd->CommonCfg.Channel > 14))
|
|
{
|
|
FrameLen += build_vht_cap_ie(pAd, (UCHAR *)&pApCliEntry->MlmeAux.vht_cap);
|
|
pApCliEntry->MlmeAux.vht_cap_len = sizeof(VHT_CAP_IE);
|
|
}
|
|
#endif /* DOT11_VHT_AC */
|
|
|
|
#if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA)
|
|
if ((pAd->StaCfg.wpa_supplicant_info.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
|
|
(pAd->cfg80211_ctrl.ExtraIeLen > 0))
|
|
{
|
|
ULONG ExtraIeTmpLen = 0;
|
|
|
|
MakeOutgoingFrame(pOutBuffer+ FrameLen, &ExtraIeTmpLen,
|
|
pAd->cfg80211_ctrl.ExtraIeLen, pAd->cfg80211_ctrl.pExtraIe,
|
|
END_OF_ARGS);
|
|
|
|
FrameLen += ExtraIeTmpLen;
|
|
}
|
|
#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */
|
|
|
|
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
|
|
MlmeFreeMemory(pAd, pOutBuffer);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
#endif /* APCLI_SUPPORT */
|
|
|