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