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

📄 zdasocsvc.c

📁 ZD1211LnxDrv_2_3_1_0無線網卡ZD1211
💻 C
字号:
#ifndef __ZDASOCSVC_C__
#define __ZDASOCSVC_C__

#include "zd80211.h"
#include "zd1205.h"

U8 AsocState = STE_ASOC_IDLE;
static MacAddr_t AsSta;
extern struct net_device *g_dev;


BOOLEAN Disasoc(Signal_t *signal)
{
	FrmDesc_t *pfrmDesc;
	Frame_t *rdu;
	MacAddr_t Sta;
	ReasonCode Rsn;
	U8 vapId = 0;
	
	//ZDEBUG("Disasoc");
	//FPRINT("Disasoc");
	pfrmDesc = signal->frmInfo.frmDesc;
	rdu = pfrmDesc->mpdu;
	memcpy((U8 *)&Sta, (U8 *)(addr2(rdu)), 6); // Get the address of the transmitter.
	Rsn = (ReasonCode)(reason(rdu));

	if (mBssType == INFRASTRUCTURE_BSS)
	{// This frame should be come from the associated AP.
	    if ((!mAssoc) || (memcmp(&Sta, (U8*)&mBssId, 6) != 0))
	    { //Not for this BSSID
		//discard this packet	
		freeFdesc(pfrmDesc);
		return TRUE;
	    }	
	    else 
	    {
		freeFdesc(pfrmDesc);
		UpdateStaStatus(&Sta, STATION_STATE_DIS_ASOC, vapId);
		pdot11Obj->StatusNotify(STA_DISASSOCIATED, (U8 *)&Sta);
		mAssoc = FALSE;
		memset((U8 *)&mBssId, 0, 6);
                printk(KERN_ERR "Rx Disasoc from AP(Rsn:%d),set DIS_CONNECT_SET\n",Rsn);
		mRequestFlag |= DIS_CONNECT_SET;
		return TRUE;
            }    
	} 
	else if (mBssType == AP_BSS)
	{	
	    if (memcmp(addr1(rdu), (U8*)&mBssId, 6))
	    { //Not for this BSSID
		freeFdesc(pfrmDesc);
		return TRUE;
            }
	    UpdateStaStatus(&Sta, STATION_STATE_DIS_ASOC, vapId);
	    freeFdesc(pfrmDesc);
	    //here to handle disassoc ind.
	    pdot11Obj->StatusNotify(STA_DISASSOCIATED, (U8 *)&Sta);
	    return TRUE;
	}	
	else 
	{
	    freeFdesc(pfrmDesc);
	    return TRUE;
	}	
}


BOOLEAN DisasocReq(Signal_t *signal)
{
	FrmDesc_t *pfrmDesc;
	MacAddr_t Sta;
	ReasonCode Rsn = RC_UNSPEC_REASON;
	U8 vapId = 0;

	//ZDEBUG("DisasocReq");
	//FPRINT("DisasocReq");
	
	memcpy((U8 *)&Sta, (U8 *)&signal->frmInfo.Sta, 6);
	Rsn = signal->frmInfo.rCode;
	pdot11Obj->StatusNotify(STA_DISASSOCIATED, (U8 *)&Sta);

	vapId = signal->vapId;
	UpdateStaStatus(&Sta, STATION_STATE_DIS_ASOC, vapId);
	
	pfrmDesc = allocFdesc();
	if(!pfrmDesc){
		sigEnque(pMgtQ, (signal));
		return FALSE;
	}

	mkDisAssoc_DeAuthFrm(pfrmDesc, ST_DISASOC, &Sta, Rsn, vapId);
	sendMgtFrame(signal, pfrmDesc);
	
	if (mBssType == INFRASTRUCTURE_BSS){
		if (memcmp((U8 *)&mBssId, (U8 *)&Sta, 6) == 0){ // my AP
			mAssoc = FALSE;
			memset((U8 *)&mBssId, 0, 6);
		}
	}		
	
	return FALSE;
}


BOOLEAN Re_Asociate(Signal_t *signal)
{
	struct zd1205_private *macp=g_dev->priv;
	Hash_t	*pHash;
	FrmDesc_t *pfrmDesc;
	Frame_t *rdu;
	MacAddr_t Sta;
	U16 aid = 0;
	StatusCode asStatus;
	U8 lsInterval;
	Element WPA;
	Element asSsid;
	Element asRates;
	Element extRates;
	U16 cap;
	U8 ZydasMode = 0;
	int i;
	U8 tmpMaxRate = 0x02;
	U8 MaxRate;
	U16 notifyStatus = STA_ASOC_REQ;
	U16 notifyStatus1 = STA_ASSOCIATED;
	TypeSubtype type = ST_ASOC_RSP;
	U8	Preamble = 0;
	U8	HigestBasicRate = 0;
	U8	vapId = 0;
	U8	Len;
	Element *pExtRate = NULL;
	
	BOOLEAN bErpSta = TRUE;
	pExtRate = &mExtRates;

	ZDEBUG("Re_Asociate");
	pfrmDesc = signal->frmInfo.frmDesc;

	if (mBssType == INFRASTRUCTURE_BSS){	
		freeFdesc(pfrmDesc);
		return TRUE;
	} else if (mBssType == AP_BSS){		
		rdu = pfrmDesc->mpdu;
		lsInterval = listenInt(pfrmDesc->mpdu);
		//FPRINT_V("lsInterval", lsInterval);
		cap = cap(rdu);
		memcpy((U8 *)&Sta, (U8 *)addr2(rdu), 6);
	
		if ((isGroup(addr2(rdu))) ||  (!getElem(rdu, EID_SSID, &asSsid))
			|| (!getElem(rdu, EID_SUPRATES, &asRates))){
			freeFdesc(pfrmDesc);
			return TRUE;
		}
	
		if ((eLen(&asSsid) != eLen(&dot11DesiredSsid) || 
			memcmp(&asSsid, &dot11DesiredSsid, eLen(&dot11DesiredSsid)+2) != 0)){
			freeFdesc(pfrmDesc);
			return TRUE;
		}		
		
		//check capability
		if (cap & CAP_SHORT_PREAMBLE){
			if (mPreambleType == LONG_PREAMBLE){ //we are long preamble, and STA is short preamble capability
				freeFdesc(pfrmDesc);
				return TRUE;
			}
			else	
				Preamble = 1;
		}	
		else {
			Preamble = 0;
		}	
		
		
		// Privacy not match
		if (cap & CAP_PRIVACY){
			if (!mPrivacyInvoked && macp->cardSetting.WPAIeLen==0){
			//if (!mPrivacyInvoked){
				freeFdesc(pfrmDesc);
				return TRUE;
			}	
		}
		else {
			if (mPrivacyInvoked){
				freeFdesc(pfrmDesc);
				return TRUE;
			}	
		}		
		
		//check short slot time
#if 0//defined(OFDM)	
		if (mMacMode != PURE_B_MODE){
			if (cap & CAP_SHORT_SLOT_TIME){
				if (!(mCap & CAP_SHORT_SLOT_TIME)){
					FPRINT("CAP_SHORT_SLOT_TIME not match!!");
					freeFdesc(pfrmDesc);
					return TRUE;
				}	
			}
			else {
				if (mCap & CAP_SHORT_SLOT_TIME){
					asStatus = (StatusCode)SC_UNSUP_SHORT_SLOT_TIME;
					goto check_failed;
				}	
			}	
		}	
	
		FPRINT_V("cap", cap);
#endif


		//check supported rates		
		Len = eLen(&asRates);	
		for (i=0; i<Len; i++){
			if ( (asRates.buf[2+i] & 0x7f) > tmpMaxRate ){
				tmpMaxRate = (asRates.buf[2+i] & 0x7f);
				if (asRates.buf[2+i] & 0x80)
					HigestBasicRate = asRates.buf[2+i];
			}	
				
			if (((asRates.buf[2+i] & 0x7f) == 0x21) && (!(cap & CAP_PBCC_ENABLE))){ //Zydas 16.5M
				ZydasMode = 1;
				mZyDasModeClient = TRUE;
			//FPRINT("ZydasMode");
			}	
		}	
	
		if (!getElem(rdu, EID_EXT_RATES, &extRates)){
			void *reg = pdot11Obj->reg;
			// 11b STA 
			//FPRINT("11b STA");
			if (mMacMode == PURE_G_MODE){ // don't support b only sta
				MaxRate = RateConvert((tmpMaxRate & 0x7f));	
				//MaxBasicRate = RateConvert((HigestBasicRate & 0x7f));	
				if (MaxRate < pdot11Obj->BasicRate){
					//FPRINT_V("MaxRate", MaxRate);
					//FPRINT_V("pdot11Obj->BasicRate", pdot11Obj->BasicRate);
					asStatus = SC_UNSUP_RATES;
					goto check_failed;
				}	
			}	
			bErpSta = FALSE;
            pdot11Obj->ConfigFlag |= NON_ERP_PRESENT_SET;
            pdot11Obj->ConfigFlag &= ~SHORT_SLOT_TIME_SET;
			mCap &= ~CAP_SHORT_SLOT_TIME;	
			pdot11Obj->SetReg(reg, ZD_CWmin_CWmax, CW_NORMAL_SLOT); 
			if(PURE_A_MODE == mMacMode) {
				pdot11Obj->ConfigFlag &= ~NON_ERP_PRESENT_SET;
				pdot11Obj->ConfigFlag |= SHORT_SLOT_TIME_SET;
				mCap |= CAP_SHORT_SLOT_TIME;
				pdot11Obj->SetReg(reg, ZD_CWmin_CWmax, CW_SHORT_SLOT);
			}

		}	
		else { //11g STA
			if (mMacMode != PURE_B_MODE && mMacMode != PURE_A_MODE){

				Len = eLen(&extRates);
				for (i=0; i<Len; i++){
					if ( (extRates.buf[2+i] & 0x7f) > tmpMaxRate ){
						tmpMaxRate = (extRates.buf[2+i] & 0x7f);
					}
				}
				bErpSta = TRUE;		
				//FPRINT("11g STA");
			}
			else {
				FPRINT("Pure B mode don't support G sta");
				asStatus = SC_UNSUP_RATES;
				goto check_failed;
			}		
		}	
	
		MaxRate = RateConvert((tmpMaxRate & 0x7f));			

        if (MaxRate > mMaxTxRate)
            MaxRate = mMaxTxRate;			
	
		if (signal->id == SIG_REASSOC)	
			notifyStatus = STA_REASOC_REQ;
		
		if (!pdot11Obj->StatusNotify(notifyStatus, (U8 *)&Sta))
		{ //Accept it
			//if ((mDynKeyMode == DYN_KEY_TKIP) || (mDynKeyMode == DYN_KEY_AES)){	
			if (macp->cardSetting.WPAIeLen)
            {
				if (getElem(rdu, EID_WPA, &WPA)||getElem(rdu,EID_RSN,&WPA))
				{
					//zd1205_OctetDump("AssocRequest = ", asRdu->body, asRdu->bodyLen);
					//zd1205_OctetDump("AssocRequest WPA_IE = ", &WPA.buf[2], WPA.buf[1]);
                    			if (pdot11Obj->AssocRequest)
                    			{
			    			if (pdot11Obj->AssocRequest((U8 *)&Sta, rdu->body, rdu->bodyLen))
						{ //reject
				    			asStatus = SC_UNSPEC_FAILURE;
				    			goto check_failed;
				    			//we need reason code here
						}
					}
				}
				else
				{
				    asStatus = SC_UNSPEC_FAILURE;
				    goto wpa_check_failed;		
				}		
			}		

//wpa_check_ok:			
			if (!UpdateStaStatus(&Sta, STATION_STATE_ASOC, vapId)){
				asStatus = SC_AP_FULL;
			}
			else{
				AssocInfoUpdate(&Sta, MaxRate, lsInterval, ZydasMode, Preamble, bErpSta, vapId);
				aid = AIdLookup(&Sta);
				printk(KERN_DEBUG "Re_Asoc: aid=%d\n", aid);
				pHash = HashSearch(&Sta);
				if (pHash != NULL)
				{
					if (!pHash->AlreadyIn)
					{
						pHash->AlreadyIn=1;
						mCurrConnUser++;
						if (bErpSta == FALSE)
						{
							printk(KERN_DEBUG "Increment mNumBOnlySta\n");
							mNumBOnlySta++;
						}
					}
				}

				asStatus = SC_SUCCESSFUL;
				if (signal->id == SIG_REASSOC)	
					notifyStatus1 = STA_REASSOCIATED;
				pdot11Obj->StatusNotify(notifyStatus1, (U8 *)&Sta);

				if (mMacMode != PURE_B_MODE && mMacMode != PURE_A_MODE){
					if (pdot11Obj->ConfigFlag & NON_ERP_PRESENT_SET){
						U32 tmpValue;
						void *reg = pdot11Obj->reg;
						
				 		// force enabled protection mode for debug
						mErp.buf[2] |= (NON_ERP_PRESENT | USE_PROTECTION);
						tmpValue = pdot11Obj->GetReg(reg, ZD_RTS_CTS_Rate); 
						tmpValue &= ~CTS_MOD_TYPE_OFDM;
						tmpValue |= CTS_RATE_11M;
						pdot11Obj->SetReg(reg, ZD_RTS_CTS_Rate, tmpValue);
		
						if (Preamble == 0){ //long preamble
							mErp.buf[2] |= BARKER_PREAMBLE;
							tmpValue = pdot11Obj->GetReg(reg, ZD_RTS_CTS_Rate); 
							tmpValue &= ~NON_BARKER_PMB_SET;
							tmpValue |= CTS_RATE_11M;
							pdot11Obj->SetReg(reg, ZD_RTS_CTS_Rate, tmpValue); 
							//FPRINT("Enable Barker Preamble");
						}	
						pdot11Obj->ConfigFlag |= ENABLE_PROTECTION_SET;
						//FPRINT("Enable Protection Mode");
					}
				}		
		
			}
		}
		else{
//wpa_check_failed:	
			asStatus = SC_UNSPEC_FAILURE;
		}	
wpa_check_failed:
	
		aid |= 0xC000;
		if (aid != 0xC000){
			FPRINT_V("Aid", aid);
			FPRINT_V("MaxRate", MaxRate);
		}	
	
check_failed:
		if (signal->id == SIG_REASSOC)	
			type = ST_REASOC_RSP;	
		mkRe_AsocRspFrm(pfrmDesc, type, &Sta, mCap, asStatus, aid, &mBrates, pExtRate, vapId);
		sendMgtFrame(signal, pfrmDesc);

		return FALSE;
	}
	else {
		freeFdesc(pfrmDesc);
		return TRUE;
	}
}

BOOLEAN Re_AsocReq(Signal_t *signal)
{
	FrmDesc_t *pfrmDesc;
	U8 vapId = 0;
	TypeSubtype subType = ST_ASOC_REQ;
	Element *pExtRate = NULL;
    	
	FPRINT("Re_AsocReq");
	if (memcmp(zeroMacAddress, (u8*)&mBssId, 6)==0)
	{
		sigEnque(pMgtQ, (signal));
		return FALSE;
	}
	
	pfrmDesc = allocFdesc();
	if(!pfrmDesc){
		sigEnque(pMgtQ, (signal));
		return FALSE;
	}

	
	if (signal->id == SIG_REASSOC_REQ){
		subType = ST_REASOC_REQ;
	}
    
	pExtRate = &mExtRates;

	memcpy((U8 *)&AsSta, (U8 *)&mBssId, 6);

	mkRe_AsocReqFrm(pfrmDesc, subType, &mBssId, mCap, mListenInterval, 
		&mOldAP, &mSsid, &mBrates, pExtRate, &mWPAIe, vapId);
	
	pdot11Obj->StartTimer(ASOC_TIMEOUT, DO_ASOC);	
	AsocState = STE_WAIT_ASOC_RSP;
	return sendMgtFrame(signal, pfrmDesc);
}	

BOOLEAN Re_AsocRsp(Signal_t *signal)
{
	Hash_t	*pHash;
	FrmDesc_t *pfrmDesc;
	Frame_t *rdu;
	U8 vapId = 0;	
	MacAddr_t Sta;
	U16 status;
		
	//ZDEBUG("Re_AsocRsp");
	FPRINT("Re_AsocRsp");
	
	pfrmDesc = signal->frmInfo.frmDesc;
	rdu = pfrmDesc->mpdu;
	
	memcpy((U8 *)&Sta, (U8 *)addr2(rdu), 6);
	if (memcmp(&AsSta, &Sta, 6) != 0){
		//FPRINT("Not for my Assoc AP");
		goto asoc_release;
	}
	
	pdot11Obj->StopTimer(DO_ASOC);
	AsocState = STE_ASOC_IDLE;

	
	status = status(rdu);
	if (status == SC_SUCCESSFUL){
		U8	Len;
		U8	tmpMaxRate = 0x02;
		U8	ZydasMode = 0;
		U8	Preamble = 0;
		U8	MaxRate;
		BOOLEAN bErpSta = FALSE;
		int i;
		U8	HigestBasicRate = 0;
		
		UpdateStaStatus(&Sta, STATION_STATE_ASOC, vapId);
		pHash = HashSearch(&Sta);
		if (pHash != NULL)
		{
			if (!pHash->AlreadyIn)
			{
				pHash->AlreadyIn=1;
				mCurrConnUser++;
			}
		}

		mAPCap = cap(rdu);
		
		//check capability
		if (mAPCap & CAP_SHORT_PREAMBLE){
			Preamble = 1;
		}	
		else {
			Preamble = 0;
		}	
		
		mAid = (aid(rdu) & 0x3FFF);
		getElem(rdu, EID_SUPRATES, &mAPBrates);
		//zd1205_dump_data("mAPBrates", &mAPBrates.buf[2], mAPBrates.buf[1]);
        
		if (getElem(rdu, EID_EXT_RATES, &mAPErates)){
			//zd1205_dump_data("mAPErates", &mAPErates.buf[2], mAPErates.buf[1]);
		}

		memcpy((U8 *)&mBssId, (U8 *)addr2(rdu), 6);
		mAssoc = TRUE;
		
		//update supported rates
		HW_SetSupportedRate(pdot11Obj, (U8 *)&mAPBrates);
		HW_SetSupportedRate(pdot11Obj, (U8 *)&mAPErates);

		Len = eLen(&mAPBrates);	
		for (i=0; i<Len; i++){
			if ((mAPBrates.buf[2+i] & 0x7f) > tmpMaxRate ){
				tmpMaxRate = (mAPBrates.buf[2+i] & 0x7f);
				if (mAPBrates.buf[2+i] & 0x80)
					HigestBasicRate = mAPBrates.buf[2+i];
			}	
				
			if (((mAPBrates.buf[2+i] & 0x7f) == 0x21) && (!(mAPCap & CAP_PBCC_ENABLE))){ //Zydas 16.5M
				ZydasMode = 1;
			}	
		}

       
		Len = eLen(&mAPErates);
		for (i=0; i<Len; i++){
			if ((mAPErates.buf[2+i] & 0x7f) > tmpMaxRate ){
				tmpMaxRate = (mAPErates.buf[2+i] & 0x7f);
				if (mAPErates.buf[2+i] & 0x80)
					HigestBasicRate = mAPErates.buf[2+i];
			}
		}

		//FPRINT_V("tmpMaxRate", tmpMaxRate);
		//FPRINT_V("mMaxTxRate", mMaxTxRate);
		MaxRate = RateConvert((tmpMaxRate & 0x7f));
		//FPRINT_V("MaxRate", MaxRate);
		if (MaxRate > mMaxTxRate)
			MaxRate = mMaxTxRate;
		memset(mAPBrates.buf, 0, sizeof(Element)); 
		memset(mAPErates.buf, 0, sizeof(Element));
		AssocInfoUpdate(&mBssId, MaxRate, mAid, ZydasMode, Preamble, bErpSta, vapId);
			
		pdot11Obj->StatusNotify(STA_ASSOCIATED, (U8 *)&mBssId);
		pdot11Obj->Aid = mAid;
		mConnRetryCnt = 0;

		FPRINT_V("Aid", mAid);
		FPRINT_V("MaxRate", MaxRate);
	} else {
		FPRINT("Asoc Failed!!!");
		FPRINT_V("Status Code", status);
	}	

asoc_release:
	freeFdesc(pfrmDesc);
	return TRUE;		
}	


BOOLEAN AsocTimeOut(Signal_t *signal)
{
	U8 vapId = 0;
	FPRINT("AsocTimeOut");
	
	if (AsocState == STE_WAIT_ASOC_RSP){
		AsocState = STE_ASOC_IDLE;
		UpdateStaStatus(&mBssId, STATION_STATE_DIS_ASOC, vapId);
	}
	
	mRequestFlag |= CONNECT_TOUT_SET;
	return FALSE;
}


BOOLEAN AsocEntry(Signal_t *signal)
{
	FrmDesc_t *pfrmDesc;
	
	if (AsocState == STE_ASOC_IDLE){
		switch(signal->id){
			case SIG_DIASSOC_REQ:
				return DisasocReq(signal);
			
			case SIG_DISASSOC:
				return Disasoc(signal);
			
			case SIG_ASSOC:
			case SIG_REASSOC:
				return Re_Asociate(signal);
				
			case SIG_ASSOC_REQ:
			case SIG_REASSOC_REQ:
				return Re_AsocReq(signal);
				
			default:
				goto asoc_discard;		
		}
	} else if (AsocState == STE_WAIT_ASOC_RSP){	
		switch(signal->id){
			case SIG_DIASSOC_REQ:
				return DisasocReq(signal);
			
			case SIG_DISASSOC:
				return Disasoc(signal);
			
			case SIG_ASSOC:
			case SIG_REASSOC:
				return Re_Asociate(signal);
				
			case SIG_ASSOC_REQ:
			case SIG_REASSOC_REQ:
				return Re_AsocReq(signal);	
				
			case SIG_ASSOC_RSP:
			case SIG_REASSOC_RSP:
				return Re_AsocRsp(signal);	
				
			case SIG_TO_ASOC:

				return AsocTimeOut(signal);		
			
			default:
				goto asoc_discard;	
		}
	} else
		goto asoc_discard;	
	
asoc_discard:
	pfrmDesc = signal->frmInfo.frmDesc;	
	freeFdesc(pfrmDesc);
	return TRUE;		
}

#endif

⌨️ 快捷键说明

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