sync.c

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

C
1,606
字号
        whenever driver need to start a site survey of all supported channels.
    Return:
        ch - the first channel number of current country code setting
    ==========================================================================
 */
UCHAR FirstChannel(
    IN PRTMP_ADAPTER pAd)
{
	return pAd->ChannelList[0].Channel;
}

/* 
    ==========================================================================
    Description:
        This routine returns the next channel number. This routine is called
        during driver need to start a site survey of all supported channels.
    Return:
        next_channel - the next channel number valid in current country code setting.
    Note:
        return 0 if no more next channel
    ==========================================================================
 */
UCHAR NextChannel(
	IN PRTMP_ADAPTER pAd, 
	IN UCHAR channel)
{
	int i;
    UCHAR next_channel = 0;
			
    for (i = 0; i < (pAd->ChannelListNum - 1); i++)
        if (channel == pAd->ChannelList[i].Channel)
        {
            next_channel = pAd->ChannelList[i+1].Channel;
			break;
	}	
    return next_channel;
}

/* 
    ==========================================================================
    Description:
        Update PortCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
        and 3) PHY-mode user selected.
        The outcome is used by driver when doing site survey.
    ==========================================================================
 */
VOID BuildChannelList(
	IN PRTMP_ADAPTER pAd)
{
    UCHAR i, j, index=0, num=0;
    PUCHAR	pChannelList=NULL;
	
    NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
    
    // if not 11a-only mode, channel list starts from 2.4Ghz band
    if (pAd->PortCfg.PhyMode != PHY_11A)
    {
        switch (pAd->PortCfg.CountryRegion & 0x7f)
        {
            case REGION_0_BG_BAND:	// 1 -11
                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
                index += BG_BAND_REGION_0_SIZE;
                break;
            case REGION_1_BG_BAND:	// 1 - 13
                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
                index += BG_BAND_REGION_1_SIZE;
                break;
            case REGION_2_BG_BAND:	// 10 - 11
                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
                index += BG_BAND_REGION_2_SIZE;
                break;
            case REGION_3_BG_BAND:	// 10 - 13
                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
                index += BG_BAND_REGION_3_SIZE;
                break;
            case REGION_4_BG_BAND:	// 14
                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
                index += BG_BAND_REGION_4_SIZE;
                break;
            case REGION_5_BG_BAND:	// 1 - 14
                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
                index += BG_BAND_REGION_5_SIZE;
                break;
            case REGION_6_BG_BAND:	// 3 - 9
                NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
                index += BG_BAND_REGION_6_SIZE;
                break;
            default:            // Error. should never happen
                break;
        }   
    }
    
    if (pAd->PortCfg.PhyMode == PHY_11A)
    {
    	switch (pAd->PortCfg.CountryRegionForABand & 0x7f)
        {
            case REGION_0_A_BAND:
            	num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
	            pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
                break;
            case REGION_1_A_BAND:
            	num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
            	pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
                break;
            case REGION_2_A_BAND:
            	num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
            	pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
                break;
            case REGION_3_A_BAND:
            	num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
            	pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
                break;
            case REGION_4_A_BAND:
            	num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
            	pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
                break;
            case REGION_5_A_BAND:
            	num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
            	pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
                break;
            case REGION_6_A_BAND:
            	num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
            	pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
                break;
            case REGION_7_A_BAND:
            	num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
            	pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
                break;
	    case REGION_8_A_BAND:
            	num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
            	pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
                break;

            case REGION_9_A_BAND:
                num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
                pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
                break;
            case REGION_10_A_BAND:
                num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
                pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
                break;  
	
            default:            // Error. should never happen
            	DBGPRINT(RT_DEBUG_WARN,"countryregion=%d not support", pAd->PortCfg.CountryRegionForABand);
                break;
        }   

		if (num != 0)
		{
	        for (i=0; i<num; i++)
	        {
	        	for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
	        	{
	        		if (pChannelList[i] == pAd->TxPower[j].Channel)
	        		{
			        	NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
	        		}
	        	}
	        }
	        index += num;
		}
    }
    
    pAd->ChannelListNum = index;
    DBGPRINT(RT_DEBUG_TRACE,"country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n", 
        pAd->PortCfg.CountryRegion, pAd->PortCfg.CountryRegionForABand, pAd->RfIcType, pAd->PortCfg.PhyMode, pAd->ChannelListNum);
    for (i=0;i<index;i++)
    {
        DBGPRINT(RT_DEBUG_TRACE,"channel #%d\n", pAd->ChannelList[i].Channel);
    }
}

/* 
    ==========================================================================
    Description:
        MLME SCAN req state machine procedure
    ==========================================================================
 */
VOID MlmeScanReqAction(
	IN PRTMP_ADAPTER pAd, 
	IN MLME_QUEUE_ELEM *Elem)
{
	UCHAR          Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType;
	ULONG          Now;

	// Suspend MSDU transmission here
	RTMPSuspendMsduTransmission(pAd);

	// first check the parameter sanity
	if (MlmeScanReqSanity(pAd, Elem->Msg, Elem->MsgLen, &BssType, Ssid, &SsidLen, &ScanType))
	{
		DBGPRINT(RT_DEBUG_TRACE, "SYNC - MlmeScanReqAction\n");
		Now = jiffies;
		pAd->LastScanTime = Now;

		RTMPCancelTimer(&pAd->Mlme.SyncAux.ScanTimer);

		// record desired BSS parameters
		pAd->Mlme.SyncAux.BssType = BssType;
		pAd->Mlme.SyncAux.ScanType = ScanType;
		pAd->Mlme.SyncAux.SsidLen = SsidLen;
		NdisMoveMemory(pAd->Mlme.SyncAux.Ssid, Ssid, SsidLen);

		// start from the first channel
		pAd->Mlme.SyncAux.Channel = FirstChannel(pAd);
		ScanNextChannel(pAd);
	}
	else
	{
		DBGPRINT(RT_DEBUG_ERROR, "SYNC - MlmeScanReqAction() sanity check fail. BUG!!!\n");
		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
	}
}

/*
    ==========================================================================
    Description:
        Process the received ProbeRequest from clients
    Parameters:
        Elem - msg containing the ProbeReq frame
    ==========================================================================
 */
VOID PeerProbeReqAction(
    IN PRTMP_ADAPTER pAd, 
    IN MLME_QUEUE_ELEM *Elem) 
{
    UCHAR       Addr2[MAC_ADDR_LEN];
    CHAR          Ssid[MAX_LEN_OF_SSID];
    UCHAR         SsidLen, apidx = 0;
    HEADER_802_11        ProbeRspHdr;
    PUCHAR        pOutBuffer = NULL;
    ULONG         FrameLen = 0, TmpLen;
    LONGLONG      FakeTimestamp;
    UCHAR         SsidIe = IE_SSID, DsIe = IE_DS_PARM, SuppIe = IE_SUPP_RATES, 
                  DsLen = 1, RSNIe = IE_WPA, RSNIe2 = IE_WPA2;
    
    pAd->PortCfg.bGetAPConfig = FALSE;
    
    if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
        return;

    for (apidx = MAIN_MBSSID; apidx < pAd->PortCfg.BssidNum; apidx++)
    {
    	// if in bridge mode, no need to reply probe req.
	    if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
	        break;
	    
		if (((SsidLen == 0) && (pAd->PortCfg.MBSSID[apidx].bHideSsid == 0))
            || ((SsidLen == pAd->PortCfg.MBSSID[apidx].SsidLen) && NdisEqualMemory(Ssid, pAd->PortCfg.MBSSID[apidx].Ssid, (ULONG)SsidLen)))
	    {
	        // allocate and send out ProbeRsp frame
	        pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG);
	        if(pOutBuffer == NULL)
		        break;

	        DBGPRINT(RT_DEBUG_INFO, "SYNC - IF(ra%d)Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", apidx,
	            Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5] );

	        MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, 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;

	        // Append RSN_IE when  WPA OR WPAPSK, 
	        if (((pAd->PortCfg.PhyMode == PHY_11BG_MIXED) || (pAd->PortCfg.PhyMode == PHY_11G)) 
	            && (pAd->PortCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA))
	        {
	            UCHAR SupportedRatesLen = 4, ErpLen = 1;
	            UCHAR ExtendedRatesIe = IE_EXT_SUPP_RATES, ErpIe = IE_ERP;
	            UCHAR ExtendedRatesLen = pAd->PortCfg.SupportedRatesLen - SupportedRatesLen;
	                
	            MakeOutgoingFrame(pOutBuffer,                       &FrameLen, 
	                          sizeof(HEADER_802_11),                &ProbeRspHdr, 
	                          TIMESTAMP_LEN,                        &FakeTimestamp,
	                          2,                                    &pAd->PortCfg.BeaconPeriod,
	                          2,                                    &pAd->PortCfg.MBSSID[apidx].CapabilityInfo,
	                          1,                                    &SsidIe, 
	                          1,                                    &pAd->PortCfg.MBSSID[apidx].SsidLen, 
	                          pAd->PortCfg.MBSSID[apidx].SsidLen,    pAd->PortCfg.MBSSID[apidx].Ssid,
	                          1,                                    &SuppIe, 
	                          1,                                    &SupportedRatesLen,
	                          SupportedRatesLen,                    pAd->PortCfg.SupportedRates, 
	                          1,                                    &DsIe, 
	                          1,                                    &DsLen, 
	                          1,                                    &pAd->PortCfg.Channel,
	                          1,                                    &ErpIe,
	                          1,                                    &ErpLen,
	                          1,                                    &pAd->Mlme.ErpIeContent,
	                          1,                                    &ExtendedRatesIe,
	                          1,                                    &ExtendedRatesLen,
	                          ExtendedRatesLen,                     &pAd->PortCfg.SupportedRates[SupportedRatesLen],
	                          END_OF_ARGS);
	        }
	        else if(  pAd->PortCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA)
	        {
	            MakeOutgoingFrame(pOutBuffer,                       &FrameLen, 
	                        sizeof(HEADER_802_11),                  &ProbeRspHdr, 
	                        TIMESTAMP_LEN,                          &FakeTimestamp,
	                        2,                                      &pAd->PortCfg.BeaconPeriod,
	                        2,                                      &pAd->PortCfg.MBSSID[apidx].CapabilityInfo,
	                        1,                                      &SsidIe, 
	                        1,                                      &pAd->PortCfg.MBSSID[apidx].SsidLen, 
	                        pAd->PortCfg.MBSSID[apidx].SsidLen,      pAd->PortCfg.MBSSID[apidx].Ssid,
	                        1,                                      &SuppIe, 
	                        1,                                      &pAd->PortCfg.SupportedRatesLen,
	                        pAd->PortCfg.SupportedRatesLen,         pAd->PortCfg.SupportedRates, 
	                        1,                                      &DsIe, 
	                        1,                                      &DsLen, 
	                        1,                                      &pAd->PortCfg.Channel,
	                        END_OF_ARGS);
	        }
	        else if (((pAd->PortCfg.PhyMode == PHY_11BG_MIXED) || (pAd->PortCfg.PhyMode == PHY_11G)) 
	            && ((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) ||(pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSKWPA2PSK)))
	        {
	            UCHAR SupportedRatesLen = 4, ErpLen = 1;
	            UCHAR ExtendedRatesIe = IE_EXT_SUPP_RATES, ErpIe = IE_ERP;
	            UCHAR ExtendedRatesLen = pAd->PortCfg.SupportedRatesLen - SupportedRatesLen;
	                
	            MakeOutgoingFrame(pOutBuffer,                       &FrameLen, 
	                          sizeof(HEADER_802_11),                &ProbeRspHdr, 

⌨️ 快捷键说明

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