⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sta_sync.c

📁 Ralink RT61 SoftAP Driver source code. RT61:MiniPCI
💻 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
*/

#include "rt_config.h"


/*
    ==========================================================================
    Description:
        The sync state machine, 
    Parameters:
        Sm - pointer to the state machine
    Note:
        the state machine looks like the following
    ==========================================================================
 */
VOID StaSyncStateMachineInit(
	IN PRTMP_ADAPTER pAd,
	IN STA_STATE_MACHINE *Sm,
	OUT STA_STATE_MACHINE_FUNC Trans[])
{
	UCHAR i;

	StaStateMachineInit(Sm, (STA_STATE_MACHINE_FUNC*)Trans, STA_MAX_SYNC_STATE, STA_MAX_SYNC_MSG, (STA_STATE_MACHINE_FUNC)StaDrop, STA_SYNC_IDLE, STA_SYNC_MACHINE_BASE);

	// column 1
	StaStateMachineSetAction(Sm, STA_SYNC_IDLE, STA_MT2_MLME_PROBE_REQ, (STA_STATE_MACHINE_FUNC)StaMlmeProbeReqAction);

	//column 2
	StaStateMachineSetAction(Sm, STA_JOIN_WAIT_PROBE_RSP, STA_MT2_MLME_PROBE_REQ, (STA_STATE_MACHINE_FUNC)StaInvalidStateWhenJoin);
	StaStateMachineSetAction(Sm, STA_JOIN_WAIT_PROBE_RSP, STA_MT2_PEER_PROBE_RSP, (STA_STATE_MACHINE_FUNC)StaPeerProbeRspAtJoinAction);
	StaStateMachineSetAction(Sm, STA_JOIN_WAIT_PROBE_RSP, STA_MT2_PROBE_TIMEOUT, (STA_STATE_MACHINE_FUNC)StaProbeTimeoutAtJoinAction);

	// timer init
	RTMPInitTimer(pAd, &pAd->MlmeAux.ProbeTimer, (PVOID)&StaProbeTimeout);

	for (i = 0; i < MAX_APCLI_ENTRY; i++)
		pAd->ApCliTab.ApCliEntry[i].SyncCurrState = STA_SYNC_IDLE;

	return;
}

/* 
    ==========================================================================
    Description:
        Becaon timeout handler, executed in timer thread
    ==========================================================================
 */
VOID StaProbeTimeout(
	IN  unsigned long data) 
{
	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)data;

	DBGPRINT(RT_DEBUG_TRACE,"STA_SYNC - ProbeReqTimeout\n");

	StaMlmeEnqueue(pAd, STA_SYNC_STATE_MACHINE, STA_MT2_PROBE_TIMEOUT, 0, NULL, 0);
	MlmeHandler(pAd);

	return;
}

/* 
    ==========================================================================
    Description:
        MLME PROBE req state machine procedure
    ==========================================================================
 */
VOID StaMlmeProbeReqAction(
	IN PRTMP_ADAPTER pAd, 
	IN MLME_QUEUE_ELEM *Elem,
	OUT PULONG pCurrState,
	IN USHORT ifIndex) 
{
	MLME_JOIN_REQ_STRUCT *Info = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);

	DBGPRINT(RT_DEBUG_TRACE, "STA SYNC - StaMlmeProbeReqAction(Ssid %s)\n", Info->Ssid);

	// reset all the timers
	RTMPCancelTimer(&pAd->MlmeAux.ProbeTimer);

	pAd->MlmeAux.Channel = pAd->PortCfg.Channel;
	pAd->MlmeAux.SupRateLen = pAd->PortCfg.SupportedRatesLen;
	NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->PortCfg.SupportedRates, pAd->MlmeAux.SupRateLen);
    
	RTMPAddTimer(&pAd->MlmeAux.ProbeTimer, PROBE_TIMEOUT);
    
	EnqueueProbeRequest(pAd, Info->SsidLen, Info->Ssid, ifIndex);

	DBGPRINT(RT_DEBUG_TRACE, "APCLI SYNC - Start Probe the SSID %s on channel =%d\n", pAd->MlmeAux.Ssid, pAd->MlmeAux.Channel);

	*pCurrState = STA_JOIN_WAIT_PROBE_RSP;

	return;
}

/* 
    ==========================================================================
    Description:
        When waiting joining the (I)BSS, beacon received from external
    ==========================================================================
 */
VOID StaPeerProbeRspAtJoinAction(
	IN PRTMP_ADAPTER pAd, 
	IN MLME_QUEUE_ELEM *Elem,
	OUT PULONG pCurrState,
	IN USHORT ifIndex) 
{
	UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
	UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe, 
		DtimCount, DtimPeriod, BcastFlag; 
	LARGE_INTEGER TimeStamp;
	USHORT BeaconPeriod, AtimWin, CapabilityInfo;
//	UINT FrameLen = 0;
	CF_PARM Cf;
	UCHAR Erp;
	UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
	UCHAR SupRateLen, ExtRateLen;
	UCHAR CkipFlag;
	UCHAR LenVIE;
	UCHAR AironetCellPowerLimit;
	EDCA_PARM EdcaParm;
	QBSS_LOAD_PARM QbssLoad;
	QOS_CAPABILITY_PARM QosCapability;
	UCHAR VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
	NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
	ULONG RalinkIe;
	STA_CTRL_MSG_STRUCT StaCtrlMsg;

	// Init Variable IE structure
	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
	pVIE->Length = 0;
	if(PeerBeaconAndProbeRspSanity(
		pAd, 
		Elem->Msg, 
		Elem->MsgLen, 
		Addr2, 
		Bssid, 
		Ssid, 
		&SsidLen, 
		&BssType, 
		&BeaconPeriod, 
		&Channel,
		&TimeStamp, 
		&Cf, 
		&AtimWin, 
		&CapabilityInfo, 
		&Erp,
		&DtimCount, 
		&DtimPeriod, 
		&BcastFlag, 
		&MessageToMe, 
		SupRate,
		&SupRateLen,
		ExtRate,
		&ExtRateLen,
		&CkipFlag,
		&AironetCellPowerLimit,
		&EdcaParm,
		&QbssLoad,
		&QosCapability,
		&RalinkIe,
		&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;

		// Check the Probe-Rsp's Bssid.
		if(!MAC_ADDR_EQUAL(pAd->ApCliTab.ApCliEntry[0].CfgApCliBssid, ZERO_MAC_ADDR))
			bssidEqualFlag = MAC_ADDR_EQUAL(pAd->ApCliTab.ApCliEntry[0].CfgApCliBssid, Bssid);
		else
			bssidEmptyFlag = TRUE;

		// Check the Probe-Rsp's Ssid.
		if(pAd->ApCliTab.ApCliEntry[0].CfgSsidLen != 0)
			ssidEqualFlag = SSID_EQUAL(pAd->ApCliTab.ApCliEntry[0].CfgSsid, pAd->ApCliTab.ApCliEntry[0].CfgSsidLen, Ssid, 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)
			{
				if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE))
				{
					pAd->MlmeAux.VarIELen = LenVIE;
					NdisMoveMemory(pAd->MlmeAux.VarIEs, pVIE, pAd->MlmeAux.VarIELen);
				}
				else
				{
					// ignore this response
					pAd->MlmeAux.VarIELen = 0;
					printk("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n");
					return;
				}
			}
			else
			{
				if (pAd->PortCfg.MBSSID[MAIN_MBSSID].AuthMode >= Ndis802_11AuthModeWPA)
				{
					// ignore this response
					printk("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n");
					return;
				}	
				
				pAd->MlmeAux.VarIELen = 0;
			}
			
#ifdef RTL865X_SOC
			printk("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", Channel);
#else
			DBGPRINT(RT_DEBUG_TRACE, "SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", Channel);
#endif			

			// 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)
			{
				LONG RealRssi=0;

				// caculate real rssi value.
				RealRssi = (LONG)(ConvertToRssi(pAd, Elem->Rssi, RSSI_NO_1) + pAd->BbpRssiToDbmDelta);

				DBGPRINT(RT_DEBUG_TRACE, "SYNC - previous Rssi = %d current Rssi=%d\n", pAd->MlmeAux.Rssi, (LONG)RealRssi);
				if (pAd->MlmeAux.Rssi > (LONG)RealRssi)
					return;
				else
					pAd->MlmeAux.Rssi = RealRssi;
			} else
			{
				RTMPCancelTimer(&pAd->MlmeAux.ProbeTimer);
			}

			NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
			pAd->MlmeAux.SsidLen = SsidLen;

			NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
			pAd->MlmeAux.CapabilityInfo = CapabilityInfo & pAd->PortCfg.MBSSID[MAIN_MBSSID].CapabilityInfo;
			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;

			// Copy AP's supported rate to MlmeAux for creating assoication request
			// Also filter out not supported rate
			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);


			// copy QOS related information
			if(pAd->PortCfg.MBSSID[MAIN_MBSSID].bWmmCapable)
			{
				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, "APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", 
				pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen);

			if(bssidEqualFlag == TRUE)
			{
				*pCurrState = STA_SYNC_IDLE;

				StaCtrlMsg.Status = MLME_SUCCESS;
				StaMlmeEnqueue(pAd, STA_CTRL_STATE_MACHINE, STA_CTRL_PROBE_RSP,
					sizeof(STA_CTRL_MSG_STRUCT), &StaCtrlMsg, ifIndex);
			}
		}
		// not to me BEACON, ignored
	}
	// sanity check fail, ignore this frame

	return;
}

VOID StaProbeTimeoutAtJoinAction(
	IN PRTMP_ADAPTER pAd,
	IN MLME_QUEUE_ELEM *Elem,
	OUT PULONG pCurrState,
	IN USHORT ifIndex) 
{
	STA_CTRL_MSG_STRUCT StaCtrlMsg;

	DBGPRINT(RT_DEBUG_TRACE, "STA_SYNC - ProbeTimeoutAtJoinAction\n");
	*pCurrState = SYNC_IDLE;

	DBGPRINT(RT_DEBUG_TRACE, "STA_SYNC - MlmeAux.Bssid=%02x:%02x:%02x:%02x:%02x:%02x\n",
		pAd->MlmeAux.Bssid[0], pAd->MlmeAux.Bssid[1], pAd->MlmeAux.Bssid[2], pAd->MlmeAux.Bssid[3], pAd->MlmeAux.Bssid[4], pAd->MlmeAux.Bssid[5]);

	if(!MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, ZERO_MAC_ADDR))
	{
		StaCtrlMsg.Status = MLME_SUCCESS;
		StaMlmeEnqueue(pAd, STA_CTRL_STATE_MACHINE, STA_CTRL_PROBE_RSP,
			sizeof(STA_CTRL_MSG_STRUCT), &StaCtrlMsg, ifIndex);
	} else
	{
		StaMlmeEnqueue(pAd, STA_CTRL_STATE_MACHINE, STA_CTRL_JOIN_REQ_TIMEOUT, 0, NULL, ifIndex);
	}

	return;
}

/* 
    ==========================================================================
    Description:
    ==========================================================================
 */
VOID StaInvalidStateWhenJoin(
	IN PRTMP_ADAPTER pAd, 
	IN MLME_QUEUE_ELEM *Elem,
	OUT PULONG pCurrState,
	IN USHORT ifIndex) 
{
	STA_CTRL_MSG_STRUCT StaCtrlMsg;

	StaCtrlMsg.Status = MLME_STATE_MACHINE_REJECT;
	StaMlmeEnqueue(pAd, STA_CTRL_STATE_MACHINE, STA_CTRL_PROBE_RSP,
		sizeof(STA_CTRL_MSG_STRUCT), &StaCtrlMsg, ifIndex);

	DBGPRINT(RT_DEBUG_TRACE, "STA_AYNC - StaInvalidStateWhenJoin(state=%d). Reset SYNC machine\n", *pCurrState);

	return;
}

/* 
	==========================================================================
	Description:
	==========================================================================
 */
VOID EnqueueProbeRequest(
	IN PRTMP_ADAPTER pAd,
	IN UCHAR SsidLen,
	OUT PCHAR Ssid,
	IN USHORT ifIndex)
{
	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];

	DBGPRINT(RT_DEBUG_TRACE, "force out a ProbeRequest ...\n");

	pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG);

	if(pOutBuffer == NULL)
	{
		DBGPRINT(RT_DEBUG_TRACE, "EnqueueProbeRequest() allocate memory fail\n");
		return;
	} else
	{
		if(MAC_ADDR_EQUAL(pAd->ApCliTab.ApCliEntry[ifIndex].CfgApCliBssid, ZERO_MAC_ADDR))
			ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
				BROADCAST_ADDR, BROADCAST_ADDR, ifIndex);
		else
			ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
				pAd->ApCliTab.ApCliEntry[ifIndex].CfgApCliBssid, pAd->ApCliTab.ApCliEntry[ifIndex].CfgApCliBssid, ifIndex);

		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,                              &pAd->MlmeAux.SupRateLen,
			pAd->MlmeAux.SupRateLen,        pAd->MlmeAux.SupRate, 
			END_OF_ARGS);

#if 0
		// add Simple Config Information Element
		if(pAd->PortCfg.bWscCapable && pAd->PortCfg.WscIEProbeReq.ValueLen)
		{
			ULONG WscTmpLen = 0;

			MakeOutgoingFrame(pOutBuffer+FrameLen,        &WscTmpLen,
				pAd->PortCfg.WscIEProbeReq.ValueLen,   pAd->PortCfg.WscIEProbeReq.Value,
				END_OF_ARGS);
			FrameLen += WscTmpLen;
		}
#endif
		if(pAd->PortCfg.bGetAPConfig)
		{
			UCHAR RalinkSpecificIEForGetCfg[6] = {IE_VENDOR_SPECIFIC, 4, 0x00, 0x0c, 0x43, 0x80};
			ULONG Tmp = 0;
			MakeOutgoingFrame(pOutBuffer + FrameLen,        &Tmp,
				6,                            RalinkSpecificIEForGetCfg,
				END_OF_ARGS);
			FrameLen += Tmp;
		}
		MiniportMMRequest(pAd, pOutBuffer, FrameLen);
		kfree(pOutBuffer);
	}

	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -