sync.c

来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,606 行 · 第 1/5 页

C
1,606
字号
/****************************************************************************
 * Ralink Tech Inc.
 * 4F, No. 2 Technology 5th Rd.
 * Science-based Industrial Park
 * Hsin-chu, Taiwan, R.O.C.
 * (c) Copyright 2005, 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:
     sync.c
     
     Abstract:
     Synchronization state machine related services
     
     Revision History:
     Who         When          What
     --------    ----------    ----------------------------------------------
     John Chang  08-04-2003    created for 11g soft-AP
     
 */

#include "rt_config.h"

// 2.4 Ghz channel plan index in the TxPower arrays.
#define	BG_BAND_REGION_0_START	0			// 1,2,3,4,5,6,7,8,9,10,11	
#define	BG_BAND_REGION_0_SIZE	11
#define	BG_BAND_REGION_1_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13
#define	BG_BAND_REGION_1_SIZE	13
#define	BG_BAND_REGION_2_START	9			// 10,11
#define	BG_BAND_REGION_2_SIZE	2
#define	BG_BAND_REGION_3_START	9			// 10,11,12,13
#define	BG_BAND_REGION_3_SIZE	4
#define	BG_BAND_REGION_4_START	13			// 14
#define	BG_BAND_REGION_4_SIZE	1
#define	BG_BAND_REGION_5_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13,14 
#define	BG_BAND_REGION_5_SIZE	14
#define	BG_BAND_REGION_6_START	2			// 3,4,5,6,7,8,9
#define	BG_BAND_REGION_6_SIZE	7

// 5 Ghz channel plan index in the TxPower arrays.
UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={34, 38, 42, 46};
UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64}; 
/*
    ==========================================================================
    Description:
        The sync state machine, 
    Parameters:
        Sm - pointer to the state machine
    Note:
        the state machine looks like the following
        
                        SYNC_IDLE             
    MT2_PEER_PROBE_REQ  peer_probe_req_action    
    ==========================================================================
 */
VOID SyncStateMachineInit(
	IN PRTMP_ADAPTER pAd, 
	IN STATE_MACHINE *Sm, 
	OUT STATE_MACHINE_FUNC Trans[])
{
	StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);

	// idle state
	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAction);
	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);

	// scan_listen state
	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);

	RTMPInitTimer(pAd, &pAd->Mlme.SyncAux.ScanTimer, (PVOID)&ScanTimeout);
}

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

	DBGPRINT(RT_DEBUG_INFO,"SYNC - Scan Timeout \n");
	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL);
	MlmeHandler(pAd);
}

/* 
    ==========================================================================
    Description:
    ==========================================================================
 */
VOID InvalidStateWhenScan(
	IN PRTMP_ADAPTER pAd, 
	IN MLME_QUEUE_ELEM *Elem)
{
	DBGPRINT(RT_DEBUG_TRACE, "AYNC - InvalidStateWhenScan(state=%d). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState);
}

/* 
    ==========================================================================
    Description:
        Scan timeout procedure. basically add channel index by 1 and rescan
    ==========================================================================
 */
VOID ScanTimeoutAction(
	IN PRTMP_ADAPTER pAd, 
	IN MLME_QUEUE_ELEM *Elem)
{
	pAd->Mlme.SyncAux.Channel = NextChannel(pAd, pAd->Mlme.SyncAux.Channel);
	ScanNextChannel(pAd);
}

/* 
    ==========================================================================
    Description:
        peer sends beacon back when scanning
    ==========================================================================
 */
VOID PeerBeaconAtScanAction(
	IN PRTMP_ADAPTER pAd, 
	IN MLME_QUEUE_ELEM *Elem)
{
    UCHAR           Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
    UCHAR           Ssid[MAX_LEN_OF_SSID], BssType, Channel,  
                    SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
    CF_PARM         CfParm;
    USHORT          BeaconPeriod, AtimWin, CapabilityInfo;
    PFRAME_802_11   pFrame;
    LARGE_INTEGER   TimeStamp;
    UCHAR           Erp;
	UCHAR         	SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
	UCHAR		  	SupRateLen, ExtRateLen;
	UCHAR			CkipFlag;
	UCHAR			AironetCellPowerLimit;
	EDCA_PARM       EdcaParm;
	QBSS_LOAD_PARM  QbssLoad;
	QOS_CAPABILITY_PARM QosCapability;
    ULONG           RalinkIe;
	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
    UCHAR           LenVIE;
	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;

    pFrame = (PFRAME_802_11) Elem->Msg;
	// 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, 
                                &CfParm, 
                                &AtimWin, 
                                &CapabilityInfo, 
                                &Erp,
                                &DtimCount, 
                                &DtimPeriod, 
                                &BcastFlag, 
                                &MessageToMe, 
								SupRate,
								&SupRateLen,
								ExtRate,
								&ExtRateLen,
								&CkipFlag,
								&AironetCellPowerLimit,
								&EdcaParm,
								&QbssLoad,
								&QosCapability,
								&RalinkIe,
				                &LenVIE,
                                pVIE)) 
    {
		ULONG Idx;
		UCHAR Rssi = 0;
        CHAR  RealRssi;

		// This correct im-proper RSSI indication during SITE SURVEY issue.
		// Always report bigger RSSI during SCANNING when receiving multiple BEACONs from the same AP. 
		// This case happens because BEACONs come from adjacent channels, so RSSI become weaker as we 
		// switch to more far away channels.
        Idx = BssTableSearch(&pAd->ScanTab, Bssid);
		if (Idx != BSS_NOT_FOUND) 
            Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;

        // TODO: 2005-03-04 dirty patch. we should change all RSSI related variables to SIGNED SHORT for easy/efficient reading and calaulation
        RealRssi = ConvertToRssi(pAd, Elem->Rssi, RSSI_NO_1);
        if ((RealRssi + pAd->BbpRssiToDbmDelta) > Rssi)
            Rssi = RealRssi + pAd->BbpRssiToDbmDelta;

    	Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, 
                     BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, 
                     SupRateLen, ExtRate, ExtRateLen, Channel, Rssi, TimeStamp, CkipFlag, 
                     &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
	}
	// sanity check fail, ignored
}

/* 
    ==========================================================================
    Description:
        Scan next channel
    ==========================================================================
 */
VOID ScanNextChannel(
	IN PRTMP_ADAPTER pAd)
{
    HEADER_802_11   Hdr80211;
    PUCHAR          pOutBuffer = NULL;
    ULONG           FrameLen = 0;
    UCHAR           SsidLen = 0;
    USHORT          Status;
	UCHAR			SsidIe    = IE_SSID;
	UCHAR			SupRateIe = IE_SUPP_RATES;

    DBGPRINT(RT_DEBUG_INFO, "ScanNextChannel(ch=%d)\n",pAd->Mlme.SyncAux.Channel);

    if (pAd->Mlme.SyncAux.Channel == 0) 
    {
        DBGPRINT(RT_DEBUG_TRACE, "SYNC - End of SCAN, restore to channel %d\n",pAd->PortCfg.Channel);
        AsicSwitchChannel(pAd, pAd->PortCfg.Channel);
        AsicLockChannel(pAd, pAd->PortCfg.Channel);

        pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;

        RTMPResumeMsduTransmission(pAd);
        if (!((pAd->PortCfg.PhyMode == PHY_11A) && (pAd->PortCfg.RadarDetect.IEEE80211H == TRUE)))
        {
            AsicEnableBssSync(pAd);
        } 
    } 
    else 
    {
        AsicSwitchChannel(pAd, pAd->Mlme.SyncAux.Channel);
        AsicLockChannel(pAd, pAd->Mlme.SyncAux.Channel);
		
		// We need to shorten active scan time in order for WZC connect issue
		// Chnage the channel scan time for CISCO stuff based on its IAPP announcement
        if (pAd->Mlme.SyncAux.ScanType == SCAN_ACTIVE)
        {
			RTMPAddTimer(&pAd->Mlme.SyncAux.ScanTimer, (MIN_CHANNEL_TIME * HZ)/1000);
        }
        else // must be SCAN_PASSIVE
        {
        	if (pAd->PortCfg.PhyMode == PHY_11ABG_MIXED)
				RTMPAddTimer(&pAd->Mlme.SyncAux.ScanTimer, (MIN_CHANNEL_TIME * HZ)/1000);
			else
				RTMPAddTimer(&pAd->Mlme.SyncAux.ScanTimer, (MAX_CHANNEL_TIME * HZ)/1000);
        }

        if ((pAd->Mlme.SyncAux.ScanType == SCAN_ACTIVE) || 
            (pAd->Mlme.SyncAux.ScanType == SCAN_PASSIVE))
        {
        	pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG);
        	if (pOutBuffer == NULL)
	        {
    	        DBGPRINT(RT_DEBUG_TRACE, "SYNC - ScanNextChannel() allocate memory fail\n");
        	    pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
                Status = MLME_FAIL_NO_RESOURCE;
	            return;
    	    }

    		// There is no need to send broadcast probe request if active scan is in effect.
            if (pAd->Mlme.SyncAux.ScanType == SCAN_ACTIVE)
                SsidLen = pAd->Mlme.SyncAux.SsidLen;
            else
                SsidLen = 0;

    		MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->PortCfg.Broadcast, pAd->PortCfg.Broadcast);
            MakeOutgoingFrame(pOutBuffer,               &FrameLen,
                              sizeof(HEADER_802_11),    &Hdr80211,
                              1,                        &SsidIe,
                              1,                        &SsidLen,
                              SsidLen,			        pAd->Mlme.SyncAux.Ssid,
                              1,                        &SupRateIe,
                              1,                        &pAd->PortCfg.SupportedRatesLen,
	                          pAd->PortCfg.SupportedRatesLen, pAd->PortCfg.SupportedRates,
                              END_OF_ARGS);

            MiniportMMRequest(pAd, pOutBuffer, FrameLen);
        	kfree(pOutBuffer);
            DBGPRINT(RT_DEBUG_INFO, "SYNC - send ProbeReq @ channel=%d, Len=%d\n", pAd->Mlme.SyncAux.Channel, FrameLen);
        }

		// For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
		
        pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
    }
}

/* 
    ==========================================================================
    Description:
        This routine return the first channel number according to the country 
        code selection and RF IC selection (signal band or dual band). It is called

⌨️ 快捷键说明

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