⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtmp_data.c

📁 Linux下的RT系列无线网卡驱动,可以直接在x86平台上编译
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ************************************************************************* * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * * (c) Copyright 2002-2007, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify  *  * it under the terms of the GNU General Public License as published by  *  * the Free Software Foundation; either version 2 of the License, or     *  * (at your option) any later version.                                   *  *                                                                       *  * This program is distributed in the hope that it will be useful,       *  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *  * GNU General Public License for more details.                          *  *                                                                       *  * You should have received a copy of the GNU General Public License     *  * along with this program; if not, write to the                         *  * Free Software Foundation, Inc.,                                       *  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *  *                                                                       *  ************************************************************************* 	Module Name:	rtmp_data.c	Abstract:	Data path subroutines	Revision History:	Who 		When			What	--------	----------		----------------------------------------------	John		      Aug/17/04		major modification for RT2561/2661	Jan Lee	      Mar/17/06		major modification for RT2860 New Ring Design*/#include "rt_config.h"VOID STARxEAPOLFrameIndicate(	IN	PRTMP_ADAPTER	pAd,	IN	MAC_TABLE_ENTRY	*pEntry,	IN	RX_BLK			*pRxBlk,	IN	UCHAR			FromWhichBSSID){	PRXD_STRUC		pRxD = &(pRxBlk->RxD);	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;	UCHAR			*pTmpBuf;#ifdef WPA_SUPPLICANT_SUPPORT	if (pAd->StaCfg.WpaSupplicantUP)	{		// All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)		// TBD : process fragmented EAPol frames		{			// In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable			if ( pAd->StaCfg.IEEE8021X == TRUE &&				 (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))			{				PUCHAR	Key; 							UCHAR 	CipherAlg;				int     idx = 0;				MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];				DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));				pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;					                if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)                {                    idx = pAd->StaCfg.DesireSharedKeyId;                    CipherAlg = pAd->StaCfg.DesireSharedKey[idx].CipherAlg;					Key = pAd->StaCfg.DesireSharedKey[idx].Key;                                        if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)    				{						// Set key material and cipherAlg to Asic						AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);						// Assign group key info  						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);						// Assign pairwise key info						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);    				}                }			}			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);			return; 		}	}	else#endif // WPA_SUPPLICANT_SUPPORT //                        	{		// Special DATA frame that has to pass to MLME		//	 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process		//	 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process		{			pTmpBuf = pRxBlk->pData - LENGTH_802_11;			NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);			REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);			DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));		}	}	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);	return;}VOID STARxDataFrameAnnounce(	IN	PRTMP_ADAPTER	pAd,	IN	MAC_TABLE_ENTRY	*pEntry,	IN	RX_BLK			*pRxBlk,	IN	UCHAR			FromWhichBSSID){	// non-EAP frame	if (!RTMPCheckWPAframe(pAd, pRxBlk->pData, pRxBlk->DataSize))	{		// drop all non-EAP DATA frame before		// this client's Port-Access-Control is secured		if (pRxBlk->pHeader->FC.Wep)		{			// unsupported cipher suite			if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)			{				// release packet				RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);				return;			}		}		else		{			// encryption in-use but receive a non-EAPOL clear text frame, drop it 			if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) && 				(pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))			{				// release packet				RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);				return;			}		}		if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))		{			// Normal legacy, AMPDU or AMSDU			CmmRxnonRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);					}		else		{			// ARALINK			CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);		}	}	else 	{		// Determin the destination of the EAP frame		//  to WPA state machine or upper layer		STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);	}}// For TKIP frame, calculate the MIC value						BOOLEAN STACheckTkipMICValue(	IN	PRTMP_ADAPTER	pAd,	IN	MAC_TABLE_ENTRY	*pEntry,	IN	RX_BLK			*pRxBlk){	PHEADER_802_11	pHeader = pRxBlk->pHeader;	UCHAR			*pData = pRxBlk->pData;	USHORT			DataSize = pRxBlk->DataSize;	PCIPHER_KEY		pWpaKey;	UCHAR			*pDA, *pSA;	pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];	// Minus MIC length	DataSize -= 8;	pDA = pHeader->Addr1;	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))	{		pSA = pHeader->Addr3;	}	else 	{		pSA = pHeader->Addr2;	}	if (RTMPTkipCompareMICValue(pAd,								pData,								pDA,								pSA,								pWpaKey->RxMic,								DataSize) == FALSE)	{		DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));#ifdef WPA_SUPPLICANT_SUPPORT		if (pAd->StaCfg.WpaSupplicantUP)		{			WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);		}		else #endif // WPA_SUPPLICANT_SUPPORT //		{			RTMPReportMicError(pAd, pWpaKey);		}				// release packet		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);		return FALSE;	}	return TRUE;}//// All Rx routines use RX_BLK structure to hande rx events// It is very important to build pRxBlk attributes//  1. pHeader pointer to 802.11 Header//  2. pData pointer to payload including LLC (just skip Header)//  3. set payload size including LLC to DataSize//  4. set some flags with RX_BLK_SET_FLAG()// VOID STAHandleRxDataFrame(	IN	PRTMP_ADAPTER	pAd,	IN	RX_BLK			*pRxBlk){	PRXD_STRUC						pRxD = &(pRxBlk->RxD);	PRXWI_STRUC						pRxWI = pRxBlk->pRxWI;	PHEADER_802_11					pHeader = pRxBlk->pHeader;	PNDIS_PACKET					pRxPacket = pRxBlk->pRxPacket;	BOOLEAN 						bFragment = FALSE;	MAC_TABLE_ENTRY	    			*pEntry = NULL;	UCHAR							FromWhichBSSID = BSS0;	// before LINK UP, all DATA frames are rejected	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))	{		// release packet		RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);		return;	}	// Drop not my BSS frames	if (pRxD->MyBss == 0)	{		// release packet		RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);		return;	}	if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))	{		UCHAR *pData;		DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));		// Qos bit 4		pData = (PUCHAR)pHeader + LENGTH_802_11;		if ((*pData >> 4) & 0x01)		{			DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));			pAd->CommonCfg.bInServicePeriod = FALSE;			// Force driver to fall into sleep mode when rcv EOSP frame			if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))			{				USHORT  TbttNumToNextWakeUp;				USHORT  NextDtim = pAd->StaCfg.DtimPeriod;				ULONG   Now;				NdisGetSystemUpTime(&Now);				NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;				TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))					TbttNumToNextWakeUp = NextDtim;				MlmeSetPsmBit(pAd, PWR_SAVE);				// if WMM-APSD is failed, try to disable following line				AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);			}		}		if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))		{			DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));			//STA should not send trigger frame, the trigger frame should be level 3.									//RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);		}	}	// Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame	if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA	{		// release packet		RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);		return;	}    // Drop not my BSS frame (we can not only check the MyBss bit in RxD)	if (INFRA_ON(pAd))	{		// Infrastructure mode, check address 2 for BSSID		if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))		{			// Receive frame not my BSSID            // release packet            RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);			return;		}	}	else	// Ad-Hoc mode or Not associated	{		// Ad-Hoc mode, check address 3 for BSSID		if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))		{			// Receive frame not my BSSID            // release packet            RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);			return;		}	}	//	// find pEntry	// 	if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)	{		pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];	}	else 	{		// 1. release packet if infra mode 		// 2. new a pEntry if ad-hoc mode		RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);		return;	}	// infra or ad-hoc	if (INFRA_ON(pAd))	{		RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);		ASSERT(pRxWI->WirelessCliID == BSSID_WCID);	}		// check Atheros Client	if ((pEntry->bIAmBadAtheros == FALSE) &&  (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))	{		pEntry->bIAmBadAtheros = TRUE;		pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;		pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;		if (!STA_AES_ON(pAd))		{			AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);		}		DBGPRINT(RT_DEBUG_INFO, ("Atheros Problem. Turn on RTS/CTS!!!\n"));	}	pRxBlk->pData = (UCHAR *)pHeader;	//	// update RxBlk->pData, DataSize	// 802.11 Header, QOS, HTC, Hw Padding	// 	// 1. skip 802.11 HEADER	pRxBlk->pData += LENGTH_802_11;	pRxBlk->DataSize -= LENGTH_802_11;	// 2. QOS	if (pHeader->FC.SubType & 0x08)	{		RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);		// bit 7 in QoS Control field signals the HT A-MSDU format		if ((*pRxBlk->pData) & 0x80)		{			RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);		}		// skip QOS contorl field		pRxBlk->pData += 2;		pRxBlk->DataSize -=2;	}	// 3. Order bit: A-Ralink or HTC+	if (pHeader->FC.Order)	{#ifdef AGGREGATION_SUPPORT		if ((pRxWI->PHYMODE < MODE_HTMIX) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))		{			RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);		}		else#endif		{			RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);			// skip HTC contorl field			pRxBlk->pData += 4;			pRxBlk->DataSize -= 4;		}	}	// 4. skip HW padding 	if (pRxD->L2PAD)	{		// just move pData pointer 		// because DataSize excluding HW padding 		RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);		pRxBlk->pData += 2;	}	if (pRxD->BA)	{		RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);	}	// 	// Case I  Process Broadcast & Multicast data frame	//	if (pRxD->Bcast || pRxD->Mcast)	{		INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);		// Drop Mcast/Bcast frame with fragment bit on

⌨️ 快捷键说明

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