connect.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 652 行 · 第 1/2 页
C
652 行
/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2002-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 attempt
* 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:
connect.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
John 2004-08-08 Major modification from RT2560
*/
#include "rt_config.h"
UCHAR PowerConstraintIE[3] = {IE_POWER_CONSTRAINT, 1, 3};
/*
==========================================================================
Description:
Pre-build All BEACON frame in the shared memory
==========================================================================
*/
VOID MakeAllBssBeacon(
IN PRTMP_ADAPTER pAd)
{
INT i, j;
ULONG csr5;
// before MakeBssBeacon, clear all beacon TxD's valid bit
for(i=0; i<4; i++)
{
for (j=0; j<TXINFO_SIZE; j++) // 24-byte TXINFO field
{
RTMP_IO_WRITE8(pAd, HW_BEACON_BASE0 + (i * HW_BEACON_OFFSET) + j, 0);
}
}
for(i=0; i<pAd->PortCfg.BssidNum; i++)
{
MakeBssBeacon(pAd, i);
}
// set MAC_CSR5 to turn on Unicast_to_me report
RTMP_IO_READ32(pAd, MAC_CSR5, &csr5);
csr5 &= 0xFFFCFFFF;
if (pAd->PortCfg.BssidNum == 1)
csr5 |= 0x00030000;
#ifdef MBSS_SUPPORT
else if (pAd->PortCfg.BssidNum == 2)
csr5 |= 0x00020000;
else
csr5 |= 0x00000000; // three or four BSSID
#endif /* MBSS_SUPPORT */
#ifdef APCLI_SUPPORT
csr5 &= 0xFFFCFFFF;
#endif
RTMP_IO_WRITE32(pAd, MAC_CSR5, csr5);
}
/*
==========================================================================
Description:
Pre-build All BEACON frame in the shared memory
==========================================================================
*/
VOID UpdateAllBeaconFrame(
IN PRTMP_ADAPTER pAd)
{
INT i;
for(i=0; i<pAd->PortCfg.BssidNum; i++)
{
UpdateBeaconFrame(pAd, i);
}
}
/*
==========================================================================
Description:
Update BEACON frame in the shared memory per TBTT
==========================================================================
*/
VOID MakeBssBeacon(
IN PRTMP_ADAPTER pAd,
IN INT apidx)
{
UCHAR SsidIe = IE_SSID, DsIe = IE_DS_PARM, SuppIe = IE_SUPP_RATES, RSNIe = IE_WPA, RSNIe2 = IE_WPA2,
SupportedRatesLen;
UCHAR DsLen = 1, SsidLen;
HEADER_802_11 BcnHdr;
LARGE_INTEGER FakeTimestamp;
ULONG FrameLen;
PTXD_STRUC pTxD = &pAd->PortCfg.MBSSID[apidx].BeaconTxD;
PUCHAR pBeaconFrame = pAd->PortCfg.MBSSID[apidx].BeaconBuf;
// Bridge mode doesn't send beacon.
if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
return;
if ((pAd->PortCfg.PhyMode == PHY_11BG_MIXED) || (pAd->PortCfg.PhyMode == PHY_11G))
SupportedRatesLen = 4;
else // include A band
SupportedRatesLen = pAd->PortCfg.SupportedRatesLen;
if (pAd->PortCfg.MBSSID[apidx].bHideSsid)
SsidLen = 0;
else
SsidLen = pAd->PortCfg.MBSSID[apidx].SsidLen;
MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, pAd->PortCfg.Broadcast, pAd->PortCfg.MBSSID[apidx].Bssid);
if ((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA) || (pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSK))
RSNIe = IE_WPA;
else if ((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2) || (pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2PSK))
RSNIe = IE_WPA2;
if ((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSKWPA2PSK))
{
MakeOutgoingFrame(pBeaconFrame, &FrameLen,
sizeof(HEADER_802_11), &BcnHdr,
TIMESTAMP_LEN, &FakeTimestamp,
2, &pAd->PortCfg.BeaconPeriod,
2, &pAd->PortCfg.MBSSID[apidx].CapabilityInfo,
1, &SsidIe,
1, &SsidLen,
SsidLen, pAd->PortCfg.MBSSID[apidx].Ssid,
1, &SuppIe,
1, &SupportedRatesLen,
SupportedRatesLen, pAd->PortCfg.SupportedRates,
1, &DsIe,
1, &DsLen,
1, &pAd->PortCfg.Channel,
1, &RSNIe,
1, &pAd->PortCfg.MBSSID[apidx].RSNIE_Len[0],
pAd->PortCfg.MBSSID[apidx].RSNIE_Len[0], pAd->PortCfg.MBSSID[apidx].RSN_IE[0],
1, &RSNIe2,
1, &pAd->PortCfg.MBSSID[apidx].RSNIE_Len[1],
pAd->PortCfg.MBSSID[apidx].RSNIE_Len[1], pAd->PortCfg.MBSSID[apidx].RSN_IE[1],
END_OF_ARGS);
}
else if (pAd->PortCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA)
{
MakeOutgoingFrame(pBeaconFrame, &FrameLen,
sizeof(HEADER_802_11), &BcnHdr,
TIMESTAMP_LEN, &FakeTimestamp,
2, &pAd->PortCfg.BeaconPeriod,
2, &pAd->PortCfg.MBSSID[apidx].CapabilityInfo,
1, &SsidIe,
1, &SsidLen,
SsidLen, pAd->PortCfg.MBSSID[apidx].Ssid,
1, &SuppIe,
1, &SupportedRatesLen,
SupportedRatesLen, pAd->PortCfg.SupportedRates,
1, &DsIe,
1, &DsLen,
1, &pAd->PortCfg.Channel,
1, &RSNIe,
1, &pAd->PortCfg.MBSSID[apidx].RSNIE_Len[0],
pAd->PortCfg.MBSSID[apidx].RSNIE_Len[0], pAd->PortCfg.MBSSID[apidx].RSN_IE[0],
END_OF_ARGS);
}
else
{
MakeOutgoingFrame(pBeaconFrame, &FrameLen,
sizeof(HEADER_802_11), &BcnHdr,
TIMESTAMP_LEN, &FakeTimestamp,
2, &pAd->PortCfg.BeaconPeriod,
2, &pAd->PortCfg.MBSSID[apidx].CapabilityInfo,
1, &SsidIe,
1, &SsidLen,
SsidLen, pAd->PortCfg.MBSSID[apidx].Ssid,
1, &SuppIe,
1, &SupportedRatesLen,
SupportedRatesLen, pAd->PortCfg.SupportedRates,
1, &DsIe,
1, &DsLen,
1, &pAd->PortCfg.Channel,
END_OF_ARGS);
}
#ifdef WMM_SUPPORT
// add WMM IE here
if (pAd->PortCfg.MBSSID[apidx].bWmmCapable)
{
ULONG TmpLen;
UCHAR i;
UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0};
WmeParmIe[8] = pAd->PortCfg.BssEdcaParm.EdcaUpdateCount & 0x0f;
WmeParmIe[8] |= (pAd->PortCfg.bAPSDCapable) ? 0x80 : 0x00;
for (i=QID_AC_BE; i<=QID_AC_VO; i++)
{
WmeParmIe[10+ (i*4)] = (i << 5) + // b5-6 is ACI
((UCHAR)pAd->PortCfg.BssEdcaParm.bACM[i] << 4) + // b4 is ACM
(pAd->PortCfg.BssEdcaParm.Aifsn[i] & 0x0f); // b0-3 is AIFSN
WmeParmIe[11+ (i*4)] = (pAd->PortCfg.BssEdcaParm.Cwmax[i] << 4) + // b5-8 is CWMAX
(pAd->PortCfg.BssEdcaParm.Cwmin[i] & 0x0f); // b0-3 is CWMIN
WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->PortCfg.BssEdcaParm.Txop[i] & 0xff); // low byte of TXOP
WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->PortCfg.BssEdcaParm.Txop[i] >> 8); // high byte of TXOP
}
MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
26, WmeParmIe,
END_OF_ARGS);
FrameLen += TmpLen;
}
#endif /* WMM_SUPPORT */
// add country IE, power constraint IE
if (pAd->PortCfg.bCountryFlag)
{
ULONG TmpLen, TmpLen2=0;
UCHAR TmpFrame[256];
UCHAR CountryIe = IE_COUNTRY;
UCHAR MaxTxPower=16;
// Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32)
// in beacons and probe response frames
if (pAd->PortCfg.PhyMode == PHY_11A && pAd->PortCfg.RadarDetect.IEEE80211H == TRUE)
{
// prepare power constraint IE
MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
3, PowerConstraintIE,
END_OF_ARGS);
FrameLen += TmpLen;
}
NdisZeroMemory(TmpFrame, sizeof(TmpFrame));
// prepare channel information
MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen,
1, &pAd->ChannelList[0].Channel,
1, &pAd->ChannelListNum,
1, &MaxTxPower,
END_OF_ARGS);
TmpLen2 += TmpLen;
// need to do the padding bit check, and concatenate it
if ((TmpLen2%2) == 0)
{
UCHAR TmpLen3 = TmpLen2+4;
MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
1, &CountryIe,
1, &TmpLen3,
3, pAd->PortCfg.CountryCode,
TmpLen2+1, TmpFrame,
END_OF_ARGS);
}
else
{
UCHAR TmpLen3 = TmpLen2+3;
MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
1, &CountryIe,
1, &TmpLen3,
3, pAd->PortCfg.CountryCode,
TmpLen2, TmpFrame,
END_OF_ARGS);
}
FrameLen += TmpLen;
}
#ifdef BIG_ENDIAN
RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
#endif
RTMPWriteTxDescriptor(pAd, pTxD, CIPHER_NONE, 0, 0, FALSE, FALSE, TRUE, SHORT_RETRY, IFS_BACKOFF,
pAd->PortCfg.MlmeRate, FrameLen, QID_MGMT, PTYPE_SPECIAL|PSUBTYPE_MGMT, NULL, NULL, pAd->PortCfg.MBSSID[apidx].bWmmCapable, FALSE, FALSE, FALSE);
pAd->PortCfg.MBSSID[apidx].TimIELocationInBeacon = (UCHAR)FrameLen;
pAd->PortCfg.MBSSID[apidx].CapabilityInfoLocationInBeacon = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2;
DBGPRINT(RT_DEBUG_TRACE,"MakeBssBeacon(ra%d)(FrameLen=%d,TimIELocateInBeacon=%d,CapInfoLocateInBeacon=%d)\n", apidx, FrameLen, pAd->PortCfg.MBSSID[apidx].TimIELocationInBeacon,pAd->PortCfg.MBSSID[apidx].CapabilityInfoLocationInBeacon);
}
VOID UpdateBeaconFrame(
IN PRTMP_ADAPTER pAd,
IN INT apidx)
{
PTXD_STRUC pTxD = &pAd->PortCfg.MBSSID[apidx].BeaconTxD;
PHEADER_802_11 pBcnHdr = (PHEADER_802_11)pAd->PortCfg.MBSSID[apidx].BeaconBuf;
UCHAR *ptr;
ULONG FrameLen = pAd->PortCfg.MBSSID[apidx].TimIELocationInBeacon;
UCHAR byte0 = (UCHAR)(pAd->PortCfg.MBSSID[apidx].TimBitmap & 0x000000fe); // skip AID#0
UCHAR byte1 = (UCHAR)((pAd->PortCfg.MBSSID[apidx].TimBitmap & 0x0000ff00) >> 8);
UCHAR byte2 = (UCHAR)((pAd->PortCfg.MBSSID[apidx].TimBitmap & 0x00ff0000) >> 16);
UCHAR byte3 = (UCHAR)((pAd->PortCfg.MBSSID[apidx].TimBitmap & 0xff000000) >> 24);
UCHAR byte4 = (UCHAR)(pAd->PortCfg.MBSSID[apidx].TimBitmap2 & 0x000000ff);
UCHAR byte5 = (UCHAR)((pAd->PortCfg.MBSSID[apidx].TimBitmap2 & 0x0000ff00) >> 8);
UCHAR byte6 = (UCHAR)((pAd->PortCfg.MBSSID[apidx].TimBitmap2 & 0x00ff0000) >> 16);
UCHAR byte7 = (UCHAR)((pAd->PortCfg.MBSSID[apidx].TimBitmap2 & 0xff000000) >> 24);
UINT i;
// Bridge mode doesn't send beacon.
if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
return;
// update BEACON's Capability
ptr = (UCHAR *)pBcnHdr + pAd->PortCfg.MBSSID[apidx].CapabilityInfoLocationInBeacon;
*ptr = (UCHAR)(pAd->PortCfg.MBSSID[apidx].CapabilityInfo & 0x00ff);
*(ptr+1) = (UCHAR)((pAd->PortCfg.MBSSID[apidx].CapabilityInfo & 0xff00) >> 8);
//
// fill up Channel Switch Announcement Element
//
if ((pAd->PortCfg.PhyMode == PHY_11A) && (pAd->PortCfg.RadarDetect.IEEE80211H == TRUE) && (pAd->PortCfg.RadarDetect.RDMode == RD_SWITCHING_MODE))
{
ptr = (UCHAR *)pBcnHdr + FrameLen;
*ptr = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
*(ptr + 1) = 3;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?