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 + -
显示快捷键?