📄 zdhci.c
字号:
if (mBssType == AP_BSS){
pDa = (MacAddr_t *)&pHdr[16]; //A3
pSa = (MacAddr_t *)&pHdr[10]; //A2
if (bDataFrm){
//don't care PS Bit in authenticate, (Re)assoicate and Probe Reguest frame
psm = (PsMode)((pHdr[1] & PW_SAVE_BIT) ? PSMODE_POWER_SAVE : PSMODE_STA_ACTIVE);
}
if (SaIndex == 0)
pHash = RxInfoIndicate(pSa, psm, rate); //12us update ps and rate information
else {
pHash = sstByAid[SaIndex];
if (pHash)
RxInfoUpdate(pHash, psm, rate);
}
}
else if (mBssType == INFRASTRUCTURE_BSS){
pDa = (MacAddr_t *)&pHdr[4]; //A1 will be my MAC
//pSa = (MacAddr_t *)&pHdr[16]; //A3
pSa = (MacAddr_t *)&pHdr[10]; //A2 for Asoc status check
pHash = sstByAid[0];
}
else{ // INDEPENDENT_BSS or PSEUDO_IBSS
pDa = (MacAddr_t *)&pHdr[4]; //A1
pSa = (MacAddr_t *)&pHdr[10]; //A2
pHash = RxInfoIndicate(pSa, 0, rate);
}
#if ZDCONF_LP_SUPPORT == 1
if(pHash) pHash->LP_CAP = LP;
#endif
if (bDataFrm){
if (!bodyLen)
goto rx_release;
if (!pHash){
zd_SendClass2ErrorFrame(pSa, vapId);
goto rx_release;
}
else {
sas = pHash->asoc;
if ((sas != STATION_STATE_ASOC) && (mBssType == AP_BSS)){
//if (sas != STATION_STATE_ASOC){
zd_SendClass3ErrorFrame(pSa, vapId);
printk(KERN_ERR "Class3ErrFrm:%02X %02X %02X %02X %02X %02X\n",pSa->mac[0],pSa->mac[1],pSa->mac[2],pSa->mac[3],pSa->mac[4],pSa->mac[5]);
goto rx_release;
}
}
if (sas == STATION_STATE_ASOC){ //association station
if (mBssType == AP_BSS){
if (isGroup(pDa)){
if (pHash->keyLength == 32){
//if (mDynKeyMode == DYN_KEY_TKIP){
if (!pHash->pkInstalled)
goto rx_release;
else if (!mGkInstalled)
goto rx_release;
else if ((pHdr[1] & WEP_BIT) && (hdrLen == 32)){
if (bSwCheckMIC){
if (!zd_CheckMic(pHdr, pBody, bodyLen, pHash, pEthHdr)){
goto rx_release;
}
else {
bodyLen -= MIC_LNG; //remove MIC
}
}
}
}
if (mCurrConnUser > 1){
mode = BC_FORWARD;
bcBuf = pdot11Obj->AllocBuffer(bodyLen, &pBcData);
if (bcBuf){
memcpy(pBcData, pBody, bodyLen);
zd_WirelessForward(pHdr, pBcData, bodyLen, bcBuf, mode, NULL, pEthHdr);
}
}
goto rx_ind;
}
else {
void *pTxHash = NULL;
if (mBlockBSS){ //discard IntraBSS packet
goto rx_release;
}
zd_QueryStaTable((U8 *)pDa, &pTxHash); //Automatic wireless forwarding
if (pTxHash){
if (bSwCheckMIC)
{
if ((pHash->keyLength==32) && (pHdr[1] & WEP_BIT) && (hdrLen == 32)){
if (!zd_CheckMic(pHdr, pBody, bodyLen, pHash, pEthHdr)){
goto rx_release;
}
else
bodyLen -= MIC_LNG; //remove MIC
}
}
mode = BSS_FORWARD;
zd_WirelessForward(pHdr, pBody, bodyLen, buf, mode, pTxHash, pEthHdr);
return;
}
}
}
// mic check
if (bSwCheckMIC) // For TKIP, always use sw-mic check.
{
//if ((pHash->keyLength==32) && (pHdr[1] & WEP_BIT) && (hdrLen == 32))
{
if (!zd_CheckMic(pHdr, pBody, bodyLen, pHash, pEthHdr))
{// sw-mic check failed, discard this packet.
goto rx_release;
}
else{// sw-mic check ok, remove MIC
bodyLen -= MIC_LNG;
}
}
}
rx_ind:
if(LP)
{
#if ZDCONF_LP_SUPPORT == 1
pData = pBody;
dataLen = bodyLen;
#endif
}
//If Typelen field is not used for len
else if(memcmp(pBody,zd_Snap_Apple_AARP,8)==0 || memcmp(pBody,zd_Snap_Apple_Type,8)==0) {
pData = pBody - 14;
dataLen = bodyLen + 14; /* Plus DA, SA and TypeLen */
pData[12] = (bodyLen>>8) & 0xFF;
pData[13] = bodyLen & 0xFF;
}
else if ((bodyLen > 5 ) && (memcmp(pBody, zd_Snap_Header, 6) == 0
|| memcmp(pBody, zd_SnapBridgeTunnel, 6) == 0)){
pData = pBody - 6;
dataLen = bodyLen + 6; /* Plus DA, SA*/
}
else{
pData = pBody - 14;
dataLen = bodyLen + 14; /* Plus DA, SA and TypeLen */
pData[12] = (bodyLen>>8) & 0xFF;
pData[13] = bodyLen & 0xFF;
}
if(!LP)
{
memcpy(pData, pEthHdr, 6); /* Set DA */
memcpy(pData+6, pEthHdr+6, 6); /* Set SA */
}
//if (Type == 0x888e)
//zd1205_dump_data("pData = ", pData, dataLen);
pdot11Obj->RxInd(pData, dataLen, buf, LP_MAP);
return;
}
}
else { //Mgt Frame
pRxSignal = allocSignal();
if (!pRxSignal){
FPRINT("zd_ReceivePkt out of signal");
FPRINT_V("freeSignalCount", freeSignalCount);
goto rx_release;
}
pRxFdesc = allocFdesc();
if (!pRxFdesc){
FPRINT("zd_ReceivePkt out of description");
FPRINT_V("freeFdescCount", freeFdescCount);
freeSignal(pRxSignal);
goto rx_release;
}
else{
//pRxFdesc->bDataFrm = bDataFrm;
pRxFdesc->signalStrength = signalStrength;
pRxFdesc->signalQuality = signalQuality;
pRxFrame = pRxFdesc->mpdu;
pRxFrame->HdrLen = hdrLen;
pRxFrame->bodyLen = bodyLen;
memcpy(pRxFrame->header, pHdr, hdrLen);
pRxFrame->body = pBody;
pRxSignal->buf = buf;
pRxSignal->vapId = vapId;
pRxSignal->frmInfo.frmDesc = pRxFdesc;
if (!RxMgtMpdu(pRxSignal)){
freeSignal(pRxSignal);
freeFdesc(pRxFdesc);
pdot11Obj->ReleaseBuffer(buf);
}
return;
}
}
rx_release:
pdot11Obj->ReleaseBuffer(buf);
return;
}
void zd_InitWepData(void)
{
mWepIv[0] = 0;
mWepIv[1] = 0;
mWepIv[2] = 0;
mWepIv[3] = 0;
mBcIv[0] = 0;
mBcIv[1] = 0;
mBcIv[2] = 0;
mBcIv[3] = 0;
}
void zd_Release_80211_Buffer(void)
{
releaseSignalBuf();
releaseFdescBuf();
}
//Cmd Functions
BOOLEAN zd_Reset80211(zd_80211Obj_t * pObj)
{
pdot11Obj = pObj;
initSignalBuf();
initFdescBuf();
ResetPSMonitor();
ResetPMFilter();
zd_InitWepData();
mBssCnt=0;
return TRUE;
}
BOOLEAN zd_HandlePsPoll(U8 *pHdr)
{
Frame_t psPollFrame;
//PSDEBUG("zd_HandlePsPoll");
psPollFrame.HdrLen = 16;
psPollFrame.bodyLen = 0;
memcpy(&psPollFrame.header[0], pHdr, 16);
RxPsPoll(&psPollFrame);
return TRUE;
}
BOOLEAN zd_StartAP(void)
{
void *reg = pdot11Obj->reg;
HW_SetRfChannel(pdot11Obj, mRfChannel, 1, mMacMode);
#if defined(AMAC)
pdot11Obj->SetReg(reg, ZD_BasicRateTbl, 0);
#endif
HW_SetSupportedRate(pdot11Obj, (U8 *)&mBrates);
#if defined(OFDM)
if(PURE_A_MODE != mMacMode)
HW_SetSupportedRate(pdot11Obj, (U8 *)&mExtRates);
#endif
/* Set CAM_MODE to AP Mode */
pdot11Obj->SetReg(reg, ZD_CAM_MODE, CAM_AP);
ConfigBcnFIFO();
HW_EnableBeacon(pdot11Obj, mBeaconPeriod, mDtimPeriod, AP_BSS);
HW_RadioOnOff(pdot11Obj, mRadioOn);
return TRUE;
}
BOOLEAN zd_ProbeReq(void)
{
Signal_t *signal;
//FPRINT("zd_ProbeReq");
if ((signal = allocSignal()) == NULL){
return FALSE;
}
signal->vapId=0;
signal->id = SIG_PROBE_REQ;
signal->block = BLOCK_SYNCH;
sigEnque(pMgtQ, (signal));
zd_SigProcess();
return TRUE;
}
BOOLEAN zd_ScanReq(void)
{
Signal_t *signal;
if ((signal = allocSignal()) == NULL){
return FALSE;
}
signal->vapId=0x12; //This member is not used in zd1211, we can use it to carry additional information, 0x1234 indicates we don't want to start a scantimer after sending a Probe Request frame.
signal->id = SIG_PROBE_REQ;
signal->block = BLOCK_SYNCH;
sigEnque(pMgtQ, (signal));
zd_SigProcess();
return TRUE;
}
#if 0
void zd_ScanEnd()
{
void *reg=pdot11Obj->reg;
if (mBssType == AP_BSS)
pdot11Obj->SetReg(reg, ZD_Rx_Filter, AP_RX_FILTER);
else
pdot11Obj->SetReg(reg, ZD_Rx_Filter, STA_RX_FILTER);
if (mAssoc) {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj, mRfChannel, 1,mMacMode);
}
mBssCnt=mBssNum;
pdot11Obj->ConfigFlag &= ((~ACTIVE_CHANNEL_SCAN_SET) & (~JUST_CHANNEL_SCAN));
}
void zd_ScanBegin()
{
void *reg=pdot11Obj->reg;
mBssNum=0;
pdot11Obj->ConfigFlag |= (ACTIVE_CHANNEL_SCAN_SET | JUST_CHANNEL_SCAN);
pdot11Obj->SetReg(reg, ZD_Rx_Filter, (BIT_5|BIT_8));
}
void zd_CmdScanReq(u16 channel)
{
if(mMacMode != PURE_A_MODE) {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj, channel, 1,mMacMode);
}
else {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj,dot11A_Channel[channel-1],1 ,mMacMode);
}
zd_ScanReq();
return;
}
#endif
BOOLEAN zd_CmdProbeReq(U8 bWithSSID)
{
void *reg = pdot11Obj->reg;
//FPRINT("zd_CmdProbeReq");
if (pdot11Obj->bChScanning){
FPRINT("Channel is under scanning....");
if (mRequestFlag & CHANNEL_SCAN_SET)
mRequestFlag &= ~CHANNEL_SCAN_SET;
return FALSE;
}
pdot11Obj->bChScanning=1;
pdot11Obj->SetReg(reg, ZD_Rx_Filter, (BIT_5|BIT_8)); //only accept beacon and ProbeRsp frame
pdot11Obj->ConfigFlag |= ACTIVE_CHANNEL_SCAN_SET;
mBssNum = 0;
if(mMacMode != PURE_A_MODE) {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj, CurrScanCH, 1,mMacMode);
}
else {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj, dot11A_Channel[CurrScanCH-1], 1,mMacMode);
}
zd_ProbeReq();
if (mRequestFlag & CHANNEL_SCAN_SET)
mRequestFlag &= ~CHANNEL_SCAN_SET;
//pdot11Obj->bChScanning = 1;
return TRUE;
}
BOOLEAN zd_StartSTA(BOOLEAN bEnable)
{
void *reg = pdot11Obj->reg;
//FPRINT("zd_StartSTA");
HW_SetSupportedRate(pdot11Obj, (U8 *)&mBrates);
HW_RadioOnOff(pdot11Obj, mRadioOn);
if (mBssType == INFRASTRUCTURE_BSS)
pdot11Obj->SetReg(reg, ZD_CAM_MODE, CAM_STA);
else
pdot11Obj->SetReg(reg, ZD_CAM_MODE, CAM_IBSS);
if (mBssType == PSEUDO_IBSS){
zd_PseudoIbssConnect();
}
else {
//if (!bEnable)
{
pdot11Obj->ConfigFlag |= SCAN_AND_CONNECT_SET;
mRequestFlag |= CHANNEL_SCAN_SET;
}
}
return TRUE;
}
BOOLEAN zd_CmdDisasoc(MacAddr_t *sta, U8 rCode)
{
Signal_t *signal;
//FPRINT("zd_CmdDisasoc");
//if (isGroup(sta))
// return FALSE;
if ((signal = allocSignal()) == NULL)
return FALSE;
signal->id = SIG_DIASSOC_REQ;
signal->block = BLOCK_ASOC;
if (mBssType == INFRASTRUCTURE_BSS){
memcpy(&signal->frmInfo.Sta, (U8 *)&mBssId, 6);
}
else {
memcpy(&signal->frmInfo.Sta, sta, 6);
}
signal->frmInfo.rCode = (ReasonCode)rCode;
sigEnque(pMgtQ, (signal));
return TRUE;
}
BOOLEAN zd_CmdDeauth(MacAddr_t *sta, U8 rCode)
{
Signal_t *signal;
if ((signal = allocSignal()) == NULL)
return FALSE;
signal->id = SIG_DEAUTH_REQ;
signal->block = BLOCK_AUTH_REQ;
memcpy(&signal->frmInfo.Sta, sta, 6);
signal->frmInfo.rCode = (ReasonCode)rCode;
sigEnque(pMgtQ, (signal));
return TRUE;
}
BOOLEAN zd_PassiveScan(void)
{
void *reg = pdot11Obj->reg;
//FPRINT("zd_PassiveScan");
if (pdot11Obj->ConfigFlag & PASSIVE_CHANNEL_SCAN_SET)
return FALSE;
pdot11Obj->ConfigFlag |= PASSIVE_CHANNEL_SCAN_SET;
pdot11Obj->SetReg(reg, ZD_Rx_Filter, 0x100); //only accept beacon frame
if(mMacMode != PURE_A_MODE) {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj, CurrScanCH, 1,mMacMode);
}
else {
// printk("HW_SetRfChannel:%s(%d)\n",__FILE__,__LINE__);
HW_SetRfChannel(pdot11Obj,dot11A_Channel[CurrScanCH-1],1 ,mMacMode);
}
pdot11Obj->StartTimer(SCAN_TIMEOUT, DO_SCAN);
return TRUE;
}
BOOLEAN zd_DisasocAll(U8 rCode)
{
int i;
MacAddr_t *sta;
if (mBssType == AP_BSS){
for (i=1; i<(MAX_AID+1); i++){
if (sstByAid[i]->asoc == STATION_STATE_ASOC){
sta = (MacAddr_t *)&sstByAid[i]->mac[0];
zd_CmdDisasoc(sta, rCode);
}
}
FlushQ(pTxQ);
}
else if (mBssType == INFRASTRUCTURE_BSS){
if (mAssoc)
zd_CmdDisasoc(&mBssId, rCode);
}
return TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -