diff options
Diffstat (limited to 'drivers/staging/otus/80211core/cmmsta.c')
-rw-r--r-- | drivers/staging/otus/80211core/cmmsta.c | 5817 |
1 files changed, 0 insertions, 5817 deletions
diff --git a/drivers/staging/otus/80211core/cmmsta.c b/drivers/staging/otus/80211core/cmmsta.c deleted file mode 100644 index 0fda30d..0000000 --- a/drivers/staging/otus/80211core/cmmsta.c +++ /dev/null @@ -1,5817 +0,0 @@ -/* - * Copyright (c) 2007-2008 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "cprecomp.h" -#include "ratectrl.h" -#include "../hal/hpreg.h" - -/* TODO : change global variable to constant */ -u8_t zgWpaRadiusOui[] = { 0x00, 0x50, 0xf2, 0x01 }; -u8_t zgWpaAesOui[] = { 0x00, 0x50, 0xf2, 0x04 }; -u8_t zgWpa2RadiusOui[] = { 0x00, 0x0f, 0xac, 0x01 }; -u8_t zgWpa2AesOui[] = { 0x00, 0x0f, 0xac, 0x04 }; - -const u16_t zcCwTlb[16] = { 0, 1, 3, 7, 15, 31, 63, 127, - 255, 511, 1023, 2047, 4095, 4095, 4095, 4095}; - -void zfStaStartConnectCb(zdev_t* dev); - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaPutApIntoBlockingList */ -/* Put AP into blocking AP list. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* bssid : AP's BSSID */ -/* weight : weight of AP */ -/* */ -/* OUTPUTS */ -/* none */ -/* */ -/* AUTHOR */ -/* Stephen Chen Atheros Communications, INC. 2006.12 */ -/* */ -/************************************************************************/ -void zfStaPutApIntoBlockingList(zdev_t* dev, u8_t* bssid, u8_t weight) -{ - u16_t i, j; - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - if (weight > 0) - { - zmw_enter_critical_section(dev); - /*Find same bssid entry first*/ - for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++) - { - for (j=0; j<6; j++) - { - if(wd->sta.blockingApList[i].addr[j]!= bssid[j]) - { - break; - } - } - - if(j==6) - { - break; - } - } - /*This bssid doesn't have old record.Find an empty entry*/ - if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE) - { - for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++) - { - if (wd->sta.blockingApList[i].weight == 0) - { - break; - } - } - } - - /* If the list is full, pick one entry for replacement */ - if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE) - { - i = bssid[5] & (ZM_MAX_BLOCKING_AP_LIST_SIZE-1); - } - - /* Update AP address and weight */ - for (j=0; j<6; j++) - { - wd->sta.blockingApList[i].addr[j] = bssid[j]; - } - - wd->sta.blockingApList[i].weight = weight; - zmw_leave_critical_section(dev); - } - - return; -} - - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaIsApInBlockingList */ -/* Is AP in blocking list. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* bssid : AP's BSSID */ -/* */ -/* OUTPUTS */ -/* TRUE : AP in blocking list */ -/* FALSE : AP not in blocking list */ -/* */ -/* AUTHOR */ -/* Stephen Chen Atheros Communications, INC. 2006.12 */ -/* */ -/************************************************************************/ -u16_t zfStaIsApInBlockingList(zdev_t* dev, u8_t* bssid) -{ - u16_t i, j; - zmw_get_wlan_dev(dev); - //zmw_declare_for_critical_section(); - - //zmw_enter_critical_section(dev); - for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++) - { - if (wd->sta.blockingApList[i].weight != 0) - { - for (j=0; j<6; j++) - { - if (wd->sta.blockingApList[i].addr[j] != bssid[j]) - { - break; - } - } - if (j == 6) - { - //zmw_leave_critical_section(dev); - return TRUE; - } - } - } - //zmw_leave_critical_section(dev); - return FALSE; -} - - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaRefreshBlockList */ -/* Is AP in blocking list. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* flushFlag : flush whole blocking list */ -/* */ -/* OUTPUTS */ -/* none */ -/* */ -/* AUTHOR */ -/* Stephen Chen Atheros Communications, INC. 2006.12 */ -/* */ -/************************************************************************/ -void zfStaRefreshBlockList(zdev_t* dev, u16_t flushFlag) -{ - u16_t i; - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - zmw_enter_critical_section(dev); - for (i=0; i<ZM_MAX_BLOCKING_AP_LIST_SIZE; i++) - { - if (wd->sta.blockingApList[i].weight != 0) - { - if (flushFlag != 0) - { - wd->sta.blockingApList[i].weight = 0; - } - else - { - wd->sta.blockingApList[i].weight--; - } - } - } - zmw_leave_critical_section(dev); - return; -} - - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaConnectFail */ -/* Handle Connect failure. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* bssid : BSSID */ -/* reason : reason of failure */ -/* */ -/* OUTPUTS */ -/* none */ -/* */ -/* AUTHOR */ -/* Stephen Chen Atheros Communications, INC. 2006.12 */ -/* */ -/************************************************************************/ -void zfStaConnectFail(zdev_t* dev, u16_t reason, u16_t* bssid, u8_t weight) -{ - zmw_get_wlan_dev(dev); - - /* Change internal state */ - zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT); - - /* Improve WEP/TKIP performance with HT AP, detail information please look bug#32495 */ - //zfHpSetTTSIFSTime(dev, 0x8); - - /* Notify wrapper of connection status changes */ - if (wd->zfcbConnectNotify != NULL) - { - wd->zfcbConnectNotify(dev, reason, bssid); - } - - /* Put AP into internal blocking list */ - zfStaPutApIntoBlockingList(dev, (u8_t *)bssid, weight); - - /* Issue another SCAN */ - if ( wd->sta.bAutoReconnect ) - { - zm_debug_msg0("Start internal scan..."); - zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); - zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_INTERNAL); - } -} - -u8_t zfiWlanIBSSGetPeerStationsCount(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - - return wd->sta.oppositeCount; -} - -u8_t zfiWlanIBSSIteratePeerStations(zdev_t* dev, u8_t numToIterate, zfpIBSSIteratePeerStationCb callback, void *ctx) -{ - u8_t oppositeCount; - u8_t i; - u8_t index = 0; - - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - zmw_enter_critical_section(dev); - - oppositeCount = wd->sta.oppositeCount; - if ( oppositeCount > numToIterate ) - { - oppositeCount = numToIterate; - } - - for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) - { - if ( oppositeCount == 0 ) - { - break; - } - - if ( wd->sta.oppositeInfo[i].valid == 0 ) - { - continue; - } - - callback(dev, &wd->sta.oppositeInfo[i], ctx, index++); - oppositeCount--; - - } - - zmw_leave_critical_section(dev); - - return index; -} - - -s8_t zfStaFindFreeOpposite(zdev_t* dev, u16_t *sa, int *pFoundIdx) -{ - int oppositeCount; - int i; - - zmw_get_wlan_dev(dev); - - oppositeCount = wd->sta.oppositeCount; - - for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) - { - if ( oppositeCount == 0 ) - { - break; - } - - if ( wd->sta.oppositeInfo[i].valid == 0 ) - { - continue; - } - - oppositeCount--; - if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) ) - { - //wd->sta.oppositeInfo[i].aliveCounter++; - wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER; - - /* it is already stored */ - return 1; - } - } - - // Check if there's still space for new comer - if ( wd->sta.oppositeCount == ZM_MAX_OPPOSITE_COUNT ) - { - return -1; - } - - // Find an unused slot for new peer station - for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) - { - if ( wd->sta.oppositeInfo[i].valid == 0 ) - { - break; - } - } - - *pFoundIdx = i; - return 0; -} - -s8_t zfStaFindOppositeByMACAddr(zdev_t* dev, u16_t *sa, u8_t *pFoundIdx) -{ - u32_t oppositeCount; - u32_t i; - - zmw_get_wlan_dev(dev); - - oppositeCount = wd->sta.oppositeCount; - - for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) - { - if ( oppositeCount == 0 ) - { - break; - } - - if ( wd->sta.oppositeInfo[i].valid == 0 ) - { - continue; - } - - oppositeCount--; - if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) ) - { - *pFoundIdx = (u8_t)i; - - return 0; - } - } - - *pFoundIdx = 0; - return 1; -} - -static void zfStaInitCommonOppositeInfo(zdev_t* dev, int i) -{ - zmw_get_wlan_dev(dev); - - /* set the default rate to the highest rate */ - wd->sta.oppositeInfo[i].valid = 1; - wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER; - wd->sta.oppositeCount++; - -#ifdef ZM_ENABLE_IBSS_WPA2PSK - /* Set parameters for new opposite peer station !!! */ - wd->sta.oppositeInfo[i].camIdx = 0xff; // Not set key in this location - wd->sta.oppositeInfo[i].pkInstalled = 0; - wd->sta.oppositeInfo[i].wpaState = ZM_STA_WPA_STATE_INIT ; // No encryption -#endif -} - -int zfStaSetOppositeInfoFromBSSInfo(zdev_t* dev, struct zsBssInfo* pBssInfo) -{ - int i; - u8_t* dst; - u16_t sa[3]; - int res; - u32_t oneTxStreamCap; - - zmw_get_wlan_dev(dev); - - zfMemoryCopy((u8_t*) sa, pBssInfo->macaddr, 6); - - res = zfStaFindFreeOpposite(dev, sa, &i); - if ( res != 0 ) - { - goto zlReturn; - } - - dst = wd->sta.oppositeInfo[i].macAddr; - zfMemoryCopy(dst, (u8_t *)sa, 6); - - oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM); - - if (pBssInfo->extSupportedRates[1] != 0) - { - /* TODO : Handle 11n */ - if (pBssInfo->frequency < 3000) - { - /* 2.4GHz */ - if (pBssInfo->EnableHT == 1) - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40); - else - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, pBssInfo->SG40); - } - else - { - /* 5GHz */ - if (pBssInfo->EnableHT == 1) - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40); - else - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40); - } - } - else - { - /* TODO : Handle 11n */ - if (pBssInfo->frequency < 3000) - { - /* 2.4GHz */ - if (pBssInfo->EnableHT == 1) - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40); - else - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, pBssInfo->SG40); - } - else - { - /* 5GHz */ - if (pBssInfo->EnableHT == 1) - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40); - else - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40); - } - } - - - zfStaInitCommonOppositeInfo(dev, i); -zlReturn: - return 0; -} - -int zfStaSetOppositeInfoFromRxBuf(zdev_t* dev, zbuf_t* buf) -{ - int i; - u8_t* dst; - u16_t sa[3]; - int res = 0; - u16_t offset; - u8_t bSupportExtRate; - u32_t rtsctsRate = 0xffffffff; /* CTS:OFDM 6M, RTS:OFDM 6M */ - u32_t oneTxStreamCap; - - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - sa[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); - sa[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2); - sa[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4); - - zmw_enter_critical_section(dev); - - res = zfStaFindFreeOpposite(dev, sa, &i); - if ( res != 0 ) - { - goto zlReturn; - } - - dst = wd->sta.oppositeInfo[i].macAddr; - zfCopyFromRxBuffer(dev, buf, dst, ZM_WLAN_HEADER_A2_OFFSET, 6); - - if ( (wd->sta.currentFrequency < 3000) && !(wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) - { - bSupportExtRate = 0; - } else { - bSupportExtRate = 1; - } - - if ( (bSupportExtRate == 1) - && (wd->sta.currentFrequency < 3000) - && (wd->wlanMode == ZM_MODE_IBSS) - && (wd->wfc.bIbssGMode == 0) ) - { - bSupportExtRate = 0; - } - - wd->sta.connection_11b = 0; - oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM); - - if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff) - && (bSupportExtRate == 1) ) - { - /* TODO : Handle 11n */ - if (wd->sta.currentFrequency < 3000) - { - /* 2.4GHz */ - if (wd->sta.EnableHT == 1) - { - //11ng - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40); - } - else - { - //11g - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, wd->sta.SG40); - } - rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */ - } - else - { - /* 5GHz */ - if (wd->sta.EnableHT == 1) - { - //11na - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40); - } - else - { - //11a - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40); - } - rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */ - } - } - else - { - /* TODO : Handle 11n */ - if (wd->sta.currentFrequency < 3000) - { - /* 2.4GHz */ - if (wd->sta.EnableHT == 1) - { - //11ng - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40); - rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */ - } - else - { - //11b - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, wd->sta.SG40); - rtsctsRate = 0x0; /* CTS:CCK 1M, RTS:CCK 1M */ - wd->sta.connection_11b = 1; - } - } - else - { - /* 5GHz */ - if (wd->sta.EnableHT == 1) - { - //11na - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40); - } - else - { - //11a - zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40); - } - rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */ - } - } - - zfStaInitCommonOppositeInfo(dev, i); - -zlReturn: - zmw_leave_critical_section(dev); - - if (rtsctsRate != 0xffffffff) - { - zfHpSetRTSCTSRate(dev, rtsctsRate); - } - return res; -} - -void zfStaProtErpMonitor(zdev_t* dev, zbuf_t* buf) -{ - u16_t offset; - u8_t erp; - u8_t bssid[6]; - - zmw_get_wlan_dev(dev); - - if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&(zfStaIsConnected(dev)) ) - { - ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid); - - if (zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6)) - { - offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP); - if (offset != 0xffff) - { - erp = zmw_rx_buf_readb(dev, buf, offset+2); - - if ( erp & ZM_BIT_1 ) - { - //zm_debug_msg0("protection mode on"); - if (wd->sta.bProtectionMode == FALSE) - { - wd->sta.bProtectionMode = TRUE; - zfHpSetSlotTime(dev, 0); - } - } - else - { - //zm_debug_msg0("protection mode off"); - if (wd->sta.bProtectionMode == TRUE) - { - wd->sta.bProtectionMode = FALSE; - zfHpSetSlotTime(dev, 1); - } - } - } - } - //Check the existence of Non-N AP - //Follow the check the "pBssInfo->EnableHT" - offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); - if (offset != 0xffff) - {} - else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) - {} - else - {wd->sta.NonNAPcount++;} - } -} - -void zfStaUpdateWmeParameter(zdev_t* dev, zbuf_t* buf) -{ - u16_t tmp; - u16_t aifs[5]; - u16_t cwmin[5]; - u16_t cwmax[5]; - u16_t txop[5]; - u8_t acm; - u8_t ac; - u16_t len; - u16_t i; - u16_t offset; - u8_t rxWmeParameterSetCount; - - zmw_get_wlan_dev(dev); - - /* Update if WME parameter set count is changed */ - /* If connect to WME AP */ - if (wd->sta.wmeConnected != 0) - { - /* Find WME parameter element */ - offset = zfFindWifiElement(dev, buf, 2, 1); - if (offset != 0xffff) - { - len = zmw_rx_buf_readb(dev, buf, offset+1); - if (len >= 7) - { - rxWmeParameterSetCount=zmw_rx_buf_readb(dev, buf, offset+8); - if (rxWmeParameterSetCount != wd->sta.wmeParameterSetCount) - { - zm_msg0_mm(ZM_LV_0, "wmeParameterSetCount changed!"); - wd->sta.wmeParameterSetCount = rxWmeParameterSetCount; - /* retrieve WME parameter and update TxQ parameters */ - acm = 0xf; - for (i=0; i<4; i++) - { - if (len >= (8+(i*4)+4)) - { - tmp=zmw_rx_buf_readb(dev, buf, offset+10+i*4); - ac = (tmp >> 5) & 0x3; - if ((tmp & 0x10) == 0) - { - acm &= (~(1<<ac)); - } - aifs[ac] = ((tmp & 0xf) * 9) + 10; - tmp=zmw_rx_buf_readb(dev, buf, offset+11+i*4); - /* Convert to 2^n */ - cwmin[ac] = zcCwTlb[(tmp & 0xf)]; - cwmax[ac] = zcCwTlb[(tmp >> 4)]; - txop[ac]=zmw_rx_buf_readh(dev, buf, - offset+12+i*4); - } - } - - if ((acm & 0x4) != 0) - { - cwmin[2] = cwmin[0]; - cwmax[2] = cwmax[0]; - aifs[2] = aifs[0]; - txop[2] = txop[0]; - } - if ((acm & 0x8) != 0) - { - cwmin[3] = cwmin[2]; - cwmax[3] = cwmax[2]; - aifs[3] = aifs[2]; - txop[3] = txop[2]; - } - cwmin[4] = 3; - cwmax[4] = 7; - aifs[4] = 28; - - if ((cwmin[2]+aifs[2]) > ((cwmin[0]+aifs[0])+1)) - { - wd->sta.ac0PriorityHigherThanAc2 = 1; - } - else - { - wd->sta.ac0PriorityHigherThanAc2 = 0; - } - zfHpUpdateQosParameter(dev, cwmin, cwmax, aifs, txop); - } - } - } - } //if (wd->sta.wmeConnected != 0) -} -/* process 802.11h Dynamic Frequency Selection */ -void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf) -{ - //u8_t length, channel, is5G; - u16_t offset; - - zmw_get_wlan_dev(dev); - - /* - Channel Switch Announcement Element Format - +------+----------+------+-------------------+------------------+--------------------+ - |Format|Element ID|Length|Channel Switch Mode|New Channel Number|Channel Switch Count| - +------+----------+------+-------------------+------------------+--------------------+ - |Bytes | 1 | 1 | 1 | 1 | 1 | - +------+----------+------+-------------------+------------------+--------------------+ - |Value | 37 | 3 | 0 or 1 |unsigned integer |unsigned integer | - +------+----------+------+-------------------+------------------+--------------------+ - */ - - /* get EID(Channel Switch Announcement) */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE); - if (offset == 0xffff) - { - //zm_debug_msg0("EID(Channel Switch Announcement) not found"); - return; - } - else if ( zmw_rx_buf_readb(dev, buf, offset+1) == 0x3 ) - { - zm_debug_msg0("EID(Channel Switch Announcement) found"); - - //length = zmw_rx_buf_readb(dev, buf, offset+1); - //zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2); - - //Chanell Switch Mode set to 1, driver should disable transmit immediate - //we do this by poll CCA high - if (zmw_rx_buf_readb(dev, buf, offset+2) == 0x1 ) - { - //use ZM_OID_INTERNAL_WRITE,ZM_CMD_RESET to notice firmware flush quene and stop dma, - //then restart rx dma but not tx dma - if (wd->sta.DFSDisableTx != TRUE) - { - /* TODO : zfHpResetTxRx would cause Rx hang */ - //zfHpResetTxRx(dev); - wd->sta.DFSDisableTx = TRUE; - /* Trgger Rx DMA */ - zfHpStartRecv(dev); - } - //Adapter->ZD80211HSetting.DisableTxBy80211H=TRUE; - //AcquireCtrOfPhyReg(Adapter); - //ZD1205_WRITE_REGISTER(Adapter,CR24, 0x0); - //ReleaseDoNotSleep(Adapter); - } - - if (zmw_rx_buf_readb(dev, buf, offset+4) <= 0x2 ) - { - //Channel Switch - //if Channel Switch Count = 0 , STA should change channel immediately. - //if Channel Switch Count > 0 , STA should change channel after TBTT*count - //But it won't be accurate to let driver calculate TBTT*count, and the value of - //Channel Switch Count will decrease by one each when continue receving beacon - //So we change channel here when we receive count <=2. - - zfHpDeleteAllowChannel(dev, wd->sta.currentFrequency); - wd->frequency = zfChNumToFreq(dev, zmw_rx_buf_readb(dev, buf, offset+3), 0); - //zfHpAddAllowChannel(dev, wd->frequency); - zm_debug_msg1("CWY - jump to frequency = ", wd->frequency); - zfCoreSetFrequency(dev, wd->frequency); - wd->sta.DFSDisableTx = FALSE; - /* Increase rxBeaconCount to prevent beacon lost */ - if (zfStaIsConnected(dev)) - { - wd->sta.rxBeaconCount = 1 << 6; // 2 times of check would pass - } - //start tx dma to transmit packet - - //if (zmw_rx_buf_readb(dev, buf, offset+3) != wd->frequency) - //{ - // //ZDDbgPrint(("Radar Detect by AP\n")); - // zfCoreSetFrequency(); - // ProcessRadarDetectEvent(Adapter); - // Set_RF_Channel(Adapter, SwRfd->Rfd->RxBuffer[index+3], (UCHAR)Adapter->RF_Mode, 1); - // Adapter->CardSetting.Channel = SwRfd->Rfd->RxBuffer[index+3]; - // Adapter->SaveChannel = Adapter->CardSetting.Channel; - // Adapter->UtilityChannel = Adapter->CardSetting.Channel; - //} - } - } - -} -/* TODO : process 802.11h Transmission Power Control */ -void zfStaUpdateDot11HTPC(zdev_t* dev, zbuf_t* buf) -{ -} - -/* IBSS power-saving mode */ -void zfStaIbssPSCheckState(zdev_t* dev, zbuf_t* buf) -{ - u8_t i, frameCtrl; - - zmw_get_wlan_dev(dev); - - if ( !zfStaIsConnected(dev) ) - { - return; - } - - if ( wd->wlanMode != ZM_MODE_IBSS ) - { - return ; - } - - /* check BSSID */ - if ( !zfRxBufferEqualToStr(dev, buf, (u8_t*) wd->sta.bssid, - ZM_WLAN_HEADER_A3_OFFSET, 6) ) - { - return; - } - - frameCtrl = zmw_rx_buf_readb(dev, buf, 1); - - /* check power management bit */ - if ( frameCtrl & ZM_BIT_4 ) - { - for(i=1; i<ZM_MAX_PS_STA; i++) - { - if ( !wd->sta.staPSList.entity[i].bUsed ) - { - continue; - } - - /* check source address */ - if ( zfRxBufferEqualToStr(dev, buf, - wd->sta.staPSList.entity[i].macAddr, - ZM_WLAN_HEADER_A2_OFFSET, 6) ) - { - return; - } - } - - for(i=1; i<ZM_MAX_PS_STA; i++) - { - if ( !wd->sta.staPSList.entity[i].bUsed ) - { - wd->sta.staPSList.entity[i].bUsed = TRUE; - wd->sta.staPSList.entity[i].bDataQueued = FALSE; - break; - } - } - - if ( i == ZM_MAX_PS_STA ) - { - /* STA list is full */ - return; - } - - zfCopyFromRxBuffer(dev, buf, wd->sta.staPSList.entity[i].macAddr, - ZM_WLAN_HEADER_A2_OFFSET, 6); - - if ( wd->sta.staPSList.count == 0 ) - { - // enable ATIM window - //zfEnableAtimWindow(dev); - } - - wd->sta.staPSList.count++; - } - else if ( wd->sta.staPSList.count ) - { - for(i=1; i<ZM_MAX_PS_STA; i++) - { - if ( wd->sta.staPSList.entity[i].bUsed ) - { - if ( zfRxBufferEqualToStr(dev, buf, - wd->sta.staPSList.entity[i].macAddr, - ZM_WLAN_HEADER_A2_OFFSET, 6) ) - { - wd->sta.staPSList.entity[i].bUsed = FALSE; - wd->sta.staPSList.count--; - - if ( wd->sta.staPSList.entity[i].bDataQueued ) - { - /* send queued data */ - } - } - } - } - - if ( wd->sta.staPSList.count == 0 ) - { - /* disable ATIM window */ - //zfDisableAtimWindow(dev); - } - - } -} - -/* IBSS power-saving mode */ -u8_t zfStaIbssPSQueueData(zdev_t* dev, zbuf_t* buf) -{ - u8_t i; - u16_t da[3]; - - zmw_get_wlan_dev(dev); - - if ( !zfStaIsConnected(dev) ) - { - return 0; - } - - if ( wd->wlanMode != ZM_MODE_IBSS ) - { - return 0; - } - - if ( wd->sta.staPSList.count == 0 && wd->sta.powerSaveMode <= ZM_STA_PS_NONE ) - { - return 0; - } - - /* DA */ -#ifdef ZM_ENABLE_NATIVE_WIFI - da[0] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); - da[1] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 2); - da[2] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 4); -#else - da[0] = zmw_tx_buf_readh(dev, buf, 0); - da[1] = zmw_tx_buf_readh(dev, buf, 2); - da[2] = zmw_tx_buf_readh(dev, buf, 4); -#endif - - if ( ZM_IS_MULTICAST_OR_BROADCAST(da) ) - { - wd->sta.staPSList.entity[0].bDataQueued = TRUE; - wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf; - return 1; - } - - // Unicast packet... - - for(i=1; i<ZM_MAX_PS_STA; i++) - { - if ( zfMemoryIsEqual(wd->sta.staPSList.entity[i].macAddr, - (u8_t*) da, 6) ) - { - wd->sta.staPSList.entity[i].bDataQueued = TRUE; - wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf; - - return 1; - } - } - -#if 0 - if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE ) - { - wd->sta.staPSDataQueue[wd->sta.staPSDataCount++] = buf; - - return 1; - } -#endif - - return 0; -} - -/* IBSS power-saving mode */ -void zfStaIbssPSSend(zdev_t* dev) -{ - u8_t i; - u16_t bcastAddr[3] = {0xffff, 0xffff, 0xffff}; - - zmw_get_wlan_dev(dev); - - if ( !zfStaIsConnected(dev) ) - { - return ; - } - - if ( wd->wlanMode != ZM_MODE_IBSS ) - { - return ; - } - - for(i=0; i<ZM_MAX_PS_STA; i++) - { - if ( wd->sta.staPSList.entity[i].bDataQueued ) - { - if ( i == 0 ) - { - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM, - bcastAddr, - 0, 0, 0); - } - else if ( wd->sta.staPSList.entity[i].bUsed ) - { - // Send ATIM to prevent the peer to go to sleep - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM, - (u16_t*) wd->sta.staPSList.entity[i].macAddr, - 0, 0, 0); - } - - wd->sta.staPSList.entity[i].bDataQueued = FALSE; - } - } - - for(i=0; i<wd->sta.ibssPSDataCount; i++) - { - zfTxSendEth(dev, wd->sta.ibssPSDataQueue[i], 0, - ZM_EXTERNAL_ALLOC_BUF, 0); - } - - wd->sta.ibssPrevPSDataCount = wd->sta.ibssPSDataCount; - wd->sta.ibssPSDataCount = 0; -} - - -void zfStaReconnect(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE && - wd->wlanMode != ZM_MODE_IBSS ) - { - return; - } - - if ( (zfStaIsConnected(dev))||(zfStaIsConnecting(dev)) ) - { - return; - } - - if ( wd->sta.bChannelScan ) - { - return; - } - - /* Recover zero SSID length */ - if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) && (wd->ws.ssidLen == 0)) - { - zm_debug_msg0("zfStaReconnect: NOT Support!! Set SSID to any BSS"); - /* ANY BSS */ - zmw_enter_critical_section(dev); - wd->sta.ssid[0] = 0; - wd->sta.ssidLen = 0; - zmw_leave_critical_section(dev); - } - - // RAY: To ensure no TX pending before re-connecting - zfFlushVtxq(dev); - zfWlanEnable(dev); - zfScanMgrScanAck(dev); -} - -void zfStaTimer100ms(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - - if ( (wd->tick % 10) == 0 ) - { - zfPushVtxq(dev); -// zfPowerSavingMgrMain(dev); - } -} - - -void zfStaCheckRxBeacon(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - - if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) && (zfStaIsConnected(dev))) - { - if (wd->beaconInterval == 0) - { - wd->beaconInterval = 100; - } - if ( (wd->tick % ((wd->beaconInterval * 10) / ZM_MS_PER_TICK)) == 0 ) - { - /* Check rxBeaconCount */ - if (wd->sta.rxBeaconCount == 0) - { - if (wd->sta.beaconMissState == 1) - { - /*notify AP that we left*/ - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0); - /* Beacon Lost */ - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_BEACON_MISS, - wd->sta.bssid, 0); - } - else - { - wd->sta.beaconMissState = 1; - /* Reset channel */ - zfCoreSetFrequencyExV2(dev, wd->frequency, wd->BandWidth40, - wd->ExtOffset, NULL, 1); - } - } - else - { - wd->sta.beaconMissState = 0; - } - wd->sta.rxBeaconCount = 0; - } - } -} - - - -void zfStaCheckConnectTimeout(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE ) - { - return; - } - - if ( !zfStaIsConnecting(dev) ) - { - return; - } - - zmw_enter_critical_section(dev); - if ( (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN)|| - (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1)|| - (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2)|| - (wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE) ) - { - if ( (wd->tick - wd->sta.connectTimer) > ZM_INTERVAL_CONNECT_TIMEOUT ) - { - if ( wd->sta.connectByReasso ) - { - wd->sta.failCntOfReasso++; - if ( wd->sta.failCntOfReasso > 2 ) - { - wd->sta.connectByReasso = FALSE; - } - } - - wd->sta.connectState = ZM_STA_CONN_STATE_NONE; - zm_debug_msg1("connect timeout, state = ", wd->sta.connectState); - //zfiWlanDisable(dev); - goto failed; - } - } - - zmw_leave_critical_section(dev); - return; - -failed: - zmw_leave_critical_section(dev); - if(wd->sta.authMode == ZM_AUTH_MODE_AUTO) - { // Fix some AP not send authentication failed message to sta and lead to connect timeout ! - wd->sta.connectTimeoutCount++; - } - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_TIMEOUT, wd->sta.bssid, 2); - return; -} - -void zfMmStaTimeTick(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - - /* airopeek */ - if (wd->wlanMode != ZM_MODE_AP && !wd->swSniffer) - { - if ( wd->tick & 1 ) - { - zfTimerCheckAndHandle(dev); - } - - zfStaCheckRxBeacon(dev); - zfStaTimer100ms(dev); - zfStaCheckConnectTimeout(dev); - zfPowerSavingMgrMain(dev); - } - -#ifdef ZM_ENABLE_AGGREGATION - /* - * add by honda - */ - zfAggScanAndClear(dev, wd->tick); -#endif -} - -void zfStaSendBeacon(zdev_t* dev) -{ - zbuf_t* buf; - u16_t offset, seq; - - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - //zm_debug_msg0("\n"); - - /* TBD : Maximum size of beacon */ - buf = zfwBufAllocate(dev, 1024); - if (buf == NULL) - { - zm_debug_msg0("Allocate beacon buffer failed"); - return; - } - - offset = 0; - /* wlan header */ - /* Frame control */ - zmw_tx_buf_writeh(dev, buf, offset, 0x0080); - offset+=2; - /* Duration */ - zmw_tx_buf_writeh(dev, buf, offset, 0x0000); - offset+=2; - /* Address 1 */ - zmw_tx_buf_writeh(dev, buf, offset, 0xffff); - offset+=2; - zmw_tx_buf_writeh(dev, buf, offset, 0xffff); - offset+=2; - zmw_tx_buf_writeh(dev, buf, offset, 0xffff); - offset+=2; - /* Address 2 */ - zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]); - offset+=2; - zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]); - offset+=2; - zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); - offset+=2; - /* Address 3 */ - zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[0]); - offset+=2; - zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[1]); - offset+=2; - zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[2]); - offset+=2; - - /* Sequence number */ - zmw_enter_critical_section(dev); - seq = ((wd->mmseq++)<<4); - zmw_leave_critical_section(dev); - zmw_tx_buf_writeh(dev, buf, offset, seq); - offset+=2; - - /* 24-31 Time Stamp : hardware will fill this field */ - offset+=8; - - /* Beacon Interval */ - zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval); - offset+=2; - - /* Capability */ - zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[0]); - zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[1]); - - /* SSID */ - offset = zfStaAddIeSsid(dev, buf, offset); - - if(wd->frequency <= ZM_CH_G_14) // 2.4 GHz b+g - { - - /* Support Rate */ - offset = zfMmAddIeSupportRate(dev, buf, offset, - ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK); - - /* DS parameter set */ - offset = zfMmAddIeDs(dev, buf, offset); - - offset = zfStaAddIeIbss(dev, buf, offset); - - if( wd->wfc.bIbssGMode - && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) // Only accompany with enabling a mode . - { - /* ERP Information */ - wd->erpElement = 0; - offset = zfMmAddIeErp(dev, buf, offset); - } - - /* TODO : country information */ - /* RSN */ - if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK ) - { - offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH); - } - - if( wd->wfc.bIbssGMode - && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) // Only accompany with enabling a mode . - { - /* Enable G Mode */ - /* Extended Supported Rates */ - offset = zfMmAddIeSupportRate(dev, buf, offset, - ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM); - } - } - else // 5GHz a - { - /* Support Rate a Mode */ - offset = zfMmAddIeSupportRate(dev, buf, offset, - ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM); - - /* DS parameter set */ - offset = zfMmAddIeDs(dev, buf, offset); - - offset = zfStaAddIeIbss(dev, buf, offset); - - /* TODO : country information */ - /* RSN */ - if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK ) - { - offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH); - } - } - - if ( wd->wlanMode != ZM_MODE_IBSS ) - { - /* TODO : Need to check if it is ok */ - /* HT Capabilities Info */ - offset = zfMmAddHTCapability(dev, buf, offset); - - /* Extended HT Capabilities Info */ - offset = zfMmAddExtendedHTCapability(dev, buf, offset); - } - - if ( wd->sta.ibssAdditionalIESize ) - offset = zfStaAddIbssAdditionalIE(dev, buf, offset); - - /* 1212 : write to beacon fifo */ - /* 1221 : write to share memory */ - zfHpSendBeacon(dev, buf, offset); - - /* Free beacon buffer */ - //zfwBufFree(dev, buf, 0); -} - -void zfStaSignalStatistic(zdev_t* dev, u8_t SignalStrength, u8_t SignalQuality) //CWYang(+) -{ - zmw_get_wlan_dev(dev); - - /* Add Your Code to Do Works Like Moving Average Here */ - wd->SignalStrength = (wd->SignalStrength * 7 + SignalStrength * 3)/10; - wd->SignalQuality = (wd->SignalQuality * 7 + SignalQuality * 3)/10; - -} - -struct zsBssInfo* zfStaFindBssInfo(zdev_t* dev, zbuf_t* buf, struct zsWlanProbeRspFrameHeader *pProbeRspHeader) -{ - u8_t i; - u8_t j; - u8_t k; - u8_t isMatched, length, channel; - u16_t offset, frequency; - struct zsBssInfo* pBssInfo; - - zmw_get_wlan_dev(dev); - - pBssInfo = wd->sta.bssList.head; - if (pBssInfo == NULL) - { - return NULL; - } - - for( i=0; i<wd->sta.bssList.bssCount; i++ ) - { - //zm_debug_msg2("check pBssInfo = ", pBssInfo); - - /* Check BSSID */ - for( j=0; j<6; j++ ) - { - if ( pBssInfo->bssid[j] != pProbeRspHeader->bssid[j] ) - { - break; - } - } - - /* Check SSID */ - if (j == 6) - { - if (pProbeRspHeader->ssid[1] <= 32) - { - /* compare length and ssid */ - isMatched = 1; - if((pProbeRspHeader->ssid[1] != 0) && (pBssInfo->ssid[1] != 0)) - { - for( k=1; k<pProbeRspHeader->ssid[1] + 1; k++ ) - { - if ( pBssInfo->ssid[k] != pProbeRspHeader->ssid[k] ) - { - isMatched = 0; - break; - } - } - } - } - else - { - isMatched = 0; - } - } - else - { - isMatched = 0; - } - - /* Check channel */ - /* Add check channel to solve the bug #31222 */ - if (isMatched) { - offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS); - if (offset != 0xffff) { - length = zmw_rx_buf_readb(dev, buf, offset+1); - if (length == 1) { - channel = zmw_rx_buf_readb(dev, buf, offset+2); - if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0) { - frequency = 0; - } else { - frequency = zfChNumToFreq(dev, channel, 0);; - } - } else { - frequency = 0; - } - } else { - frequency = wd->sta.currentFrequency; - } - - if (frequency != 0) { - if ( ((frequency > 3000) && (pBssInfo->frequency > 3000)) - || ((frequency < 3000) && (pBssInfo->frequency < 3000)) ) { - /* redundant */ - break; - } - } - } - - pBssInfo = pBssInfo->next; - } - - if ( i == wd->sta.bssList.bssCount ) - { - pBssInfo = NULL; - } - - return pBssInfo; -} - -u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, - struct zsWlanProbeRspFrameHeader *pProbeRspHeader, - struct zsBssInfo* pBssInfo, struct zsAdditionInfo* AddInfo, u8_t type) -{ - u8_t length, channel, is5G; - u16_t i, offset; - u8_t apQosInfo; - u16_t eachIElength = 0; - u16_t accumulateLen = 0; - - zmw_get_wlan_dev(dev); - - if ((type == 1) && ((pBssInfo->flag & ZM_BSS_INFO_VALID_BIT) != 0)) - { - goto zlUpdateRssi; - } - - /* get SSID */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID); - if (offset == 0xffff) - { - zm_debug_msg0("EID(SSID) not found"); - goto zlError; - } - - length = zmw_rx_buf_readb(dev, buf, offset+1); - - { - u8_t Show_Flag = 0; - zfwGetShowZeroLengthSSID(dev, &Show_Flag); - - if(Show_Flag) - { - if (length > ZM_MAX_SSID_LENGTH ) - { - zm_debug_msg0("EID(SSID) is invalid"); - goto zlError; - } - } - else - { - if ( length == 0 || length > ZM_MAX_SSID_LENGTH ) - { - zm_debug_msg0("EID(SSID) is invalid"); - goto zlError; - } - - } - } - zfCopyFromRxBuffer(dev, buf, pBssInfo->ssid, offset, length+2); - - /* get DS parameter */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS); - if (offset != 0xffff) - { - length = zmw_rx_buf_readb(dev, buf, offset+1); - if ( length != 1 ) - { - zm_msg0_mm(ZM_LV_0, "Abnormal DS Param Set IE"); - goto zlError; - } - channel = zmw_rx_buf_readb(dev, buf, offset+2); - - if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0) - { - goto zlError2; - } - - pBssInfo->frequency = zfChNumToFreq(dev, channel, 0); // auto check - pBssInfo->channel = channel; - - - } - else - { - /* DS parameter not found */ - pBssInfo->frequency = wd->sta.currentFrequency; - pBssInfo->channel = zfChFreqToNum(wd->sta.currentFrequency, &is5G); - } - - /* initialize security type */ - pBssInfo->securityType = ZM_SECURITY_TYPE_NONE; - - /* get macaddr */ - for( i=0; i<6; i++ ) - { - pBssInfo->macaddr[i] = pProbeRspHeader->sa[i]; - } - - /* get bssid */ - for( i=0; i<6; i++ ) - { - pBssInfo->bssid[i] = pProbeRspHeader->bssid[i]; - } - - /* get timestamp */ - for( i=0; i<8; i++ ) - { - pBssInfo->timeStamp[i] = pProbeRspHeader->timeStamp[i]; - } - - /* get beacon interval */ - pBssInfo->beaconInterval[0] = pProbeRspHeader->beaconInterval[0]; - pBssInfo->beaconInterval[1] = pProbeRspHeader->beaconInterval[1]; - - /* get capability */ - pBssInfo->capability[0] = pProbeRspHeader->capability[0]; - pBssInfo->capability[1] = pProbeRspHeader->capability[1]; - - /* Copy frame body */ - offset = 36; // Copy from the start of variable IE - pBssInfo->frameBodysize = zfwBufGetSize(dev, buf)-offset; - if (pBssInfo->frameBodysize > (ZM_MAX_PROBE_FRAME_BODY_SIZE-1)) - { - pBssInfo->frameBodysize = ZM_MAX_PROBE_FRAME_BODY_SIZE-1; - } - accumulateLen = 0; - do - { - eachIElength = zmw_rx_buf_readb(dev, buf, offset + accumulateLen+1) + 2; //Len+(EID+Data) - - if ( (eachIElength >= 2) - && ((accumulateLen + eachIElength) <= pBssInfo->frameBodysize) ) - { - zfCopyFromRxBuffer(dev, buf, pBssInfo->frameBody+accumulateLen, offset+accumulateLen, eachIElength); - accumulateLen+=(u16_t)eachIElength; - } - else - { - zm_msg0_mm(ZM_LV_1, "probersp frameBodysize abnormal"); - break; - } - } - while(accumulateLen < pBssInfo->frameBodysize); - pBssInfo->frameBodysize = accumulateLen; - - /* get supported rates */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE); - if (offset == 0xffff) - { - zm_debug_msg0("EID(supported rates) not found"); - goto zlError; - } - - length = zmw_rx_buf_readb(dev, buf, offset+1); - if ( length == 0 || length > ZM_MAX_SUPP_RATES_IE_SIZE) - { - zm_msg0_mm(ZM_LV_0, "Supported rates IE length abnormal"); - goto zlError; - } - zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2); - - - - /* get Country information */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_COUNTRY); - if (offset != 0xffff) - { - length = zmw_rx_buf_readb(dev, buf, offset+1); - if (length > ZM_MAX_COUNTRY_INFO_SIZE) - { - length = ZM_MAX_COUNTRY_INFO_SIZE; - } - zfCopyFromRxBuffer(dev, buf, pBssInfo->countryInfo, offset, length+2); - /* check 802.11d support data */ - if (wd->sta.b802_11D) - { - zfHpGetRegulationTablefromISO(dev, (u8_t *)&pBssInfo->countryInfo, 3); - /* only set regulatory one time */ - wd->sta.b802_11D = 0; - } - } - - /* get ERP information */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP); - if (offset != 0xffff) - { - pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2); - } - - /* get extended supported rates */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE); - if (offset != 0xffff) - { - length = zmw_rx_buf_readb(dev, buf, offset+1); - if (length > ZM_MAX_SUPP_RATES_IE_SIZE) - { - zm_msg0_mm(ZM_LV_0, "Extended rates IE length abnormal"); - goto zlError; - } - zfCopyFromRxBuffer(dev, buf, pBssInfo->extSupportedRates, offset, length+2); - } - else - { - pBssInfo->extSupportedRates[0] = 0; - pBssInfo->extSupportedRates[1] = 0; - } - - /* get WPA IE */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE); - if (offset != 0xffff) - { - length = zmw_rx_buf_readb(dev, buf, offset+1); - if (length > ZM_MAX_IE_SIZE) - { - length = ZM_MAX_IE_SIZE; - } - zfCopyFromRxBuffer(dev, buf, pBssInfo->wpaIe, offset, length+2); - pBssInfo->securityType = ZM_SECURITY_TYPE_WPA; - } - else - { - pBssInfo->wpaIe[1] = 0; - } - - /* get WPS IE */ - offset = zfFindWifiElement(dev, buf, 4, 0xff); - if (offset != 0xffff) - { - length = zmw_rx_buf_readb(dev, buf, offset+1); - if (length > ZM_MAX_WPS_IE_SIZE ) - { - length = ZM_MAX_WPS_IE_SIZE; - } - zfCopyFromRxBuffer(dev, buf, pBssInfo->wscIe, offset, length+2); - } - else - { - pBssInfo->wscIe[1] = 0; - } - - /* get SuperG IE */ - offset = zfFindSuperGElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE); - if (offset != 0xffff) - { - pBssInfo->apCap |= ZM_SuperG_AP; - } - - /* get XR IE */ - offset = zfFindXRElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE); - if (offset != 0xffff) - { - pBssInfo->apCap |= ZM_XR_AP; - } - - /* get RSN IE */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE); - if (offset != 0xffff) - { - length = zmw_rx_buf_readb(dev, buf, offset+1); - if (length > ZM_MAX_IE_SIZE) - { - length = ZM_MAX_IE_SIZE; - } - zfCopyFromRxBuffer(dev, buf, pBssInfo->rsnIe, offset, length+2); - pBssInfo->securityType = ZM_SECURITY_TYPE_WPA; - } - else - { - pBssInfo->rsnIe[1] = 0; - } -#ifdef ZM_ENABLE_CENC - /* get CENC IE */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE); - if (offset != 0xffff) - { - length = zmw_rx_buf_readb(dev, buf, offset+1); - if (length > ZM_MAX_IE_SIZE ) - { - length = ZM_MAX_IE_SIZE; - } - zfCopyFromRxBuffer(dev, buf, pBssInfo->cencIe, offset, length+2); - pBssInfo->securityType = ZM_SECURITY_TYPE_CENC; - pBssInfo->capability[0] &= 0xffef; - } - else - { - pBssInfo->cencIe[1] = 0; - } -#endif //ZM_ENABLE_CENC - /* get WME Parameter IE, probe rsp may contain WME parameter element */ - //if ( wd->bQoSEnable ) - { - offset = zfFindWifiElement(dev, buf, 2, 1); - if (offset != 0xffff) - { - apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80; - pBssInfo->wmeSupport = 1 | apQosInfo; - } - else if ((offset = zfFindWifiElement(dev, buf, 2, 0)) != 0xffff) - { - apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80; - pBssInfo->wmeSupport = 1 | apQosInfo; - } - else - { - pBssInfo->wmeSupport = 0; - } - } - //CWYang(+) - offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); - if (offset != 0xffff) - { - /* 11n AP */ - pBssInfo->EnableHT = 1; - if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x02) - { - pBssInfo->enableHT40 = 1; - } - else - { - pBssInfo->enableHT40 = 0; - } - - if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x40) - { - pBssInfo->SG40 = 1; - } - else - { - pBssInfo->SG40 = 0; - } - } - else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) - { - /* 11n AP */ - pBssInfo->EnableHT = 1; - pBssInfo->apCap |= ZM_All11N_AP; - if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x02) - { - pBssInfo->enableHT40 = 1; - } - else - { - pBssInfo->enableHT40 = 0; - } - - if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x40) - { - pBssInfo->SG40 = 1; - } - else - { - pBssInfo->SG40 = 0; - } - } - else - { - pBssInfo->EnableHT = 0; - } - /* HT information */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY); - if (offset != 0xffff) - { - /* atheros pre n */ - pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+2) & 0x03; - } - else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff) - { - /* pre n 2.0 standard */ - pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+3) & 0x03; - } - else - { - pBssInfo->extChOffset = 0; - } - - if ( (pBssInfo->enableHT40 == 1) - && ((pBssInfo->extChOffset != 1) && (pBssInfo->extChOffset != 3)) ) - { - pBssInfo->enableHT40 = 0; - } - - if (pBssInfo->enableHT40 == 1) - { - if (zfHpIsAllowedChannel(dev, pBssInfo->frequency+((pBssInfo->extChOffset==1)?20:-20)) == 0) - { - /* if extension channel is not an allowed channel, treat AP as non-HT mode */ - pBssInfo->EnableHT = 0; - pBssInfo->enableHT40 = 0; - pBssInfo->extChOffset = 0; - } - } - - /* get ATH Extended Capability */ - if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)&& - ((offset = zfFindBrdcmMrvlRlnkExtCap(dev, buf)) == 0xffff)) - - { - pBssInfo->athOwlAp = 1; - } - else - { - pBssInfo->athOwlAp = 0; - } - - /* get Broadcom Extended Capability */ - if ( (pBssInfo->EnableHT == 1) //((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff) - && ((offset = zfFindBroadcomExtCap(dev, buf)) != 0xffff) ) - { - pBssInfo->broadcomHTAp = 1; - } - else - { - pBssInfo->broadcomHTAp = 0; - } - - /* get Marvel Extended Capability */ - offset = zfFindMarvelExtCap(dev, buf); - if (offset != 0xffff) - { - pBssInfo->marvelAp = 1; - } - else - { - pBssInfo->marvelAp = 0; - } - - /* get ATIM window */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_IBSS); - if (offset != 0xffff ) - { - pBssInfo->atimWindow = zmw_rx_buf_readh(dev, buf,offset+2); - } - - /* Fit for support mode */ - if (pBssInfo->frequency > 3000) { - if (wd->supportMode & ZM_WIRELESS_MODE_5_N) { -#if 0 - if (wd->supportMode & ZM_WIRELESS_MODE_5_54) { - /* support mode: a, n */ - /* do nothing */ - } else { - /* support mode: n */ - /* reject non-n bss info */ - if (!pBssInfo->EnableHT) { - goto zlError2; - } - } -#endif - } else { - if (wd->supportMode & ZM_WIRELESS_MODE_5_54) { - /* support mode: a */ - /* delete n mode information */ - pBssInfo->EnableHT = 0; - pBssInfo->enableHT40 = 0; - pBssInfo->apCap &= (~ZM_All11N_AP); - pBssInfo->extChOffset = 0; - pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, - pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY); - pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, - pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY); - pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, - pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY); - pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, - pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION); - } else { - /* support mode: none */ - goto zlError2; - } - } - } else { - if (wd->supportMode & ZM_WIRELESS_MODE_24_N) { -#if 0 - if (wd->supportMode & ZM_WIRELESS_MODE_24_54) { - if (wd->supportMode & ZM_WIRELESS_MODE_24_11) { - /* support mode: b, g, n */ - /* do nothing */ - } else { - /* support mode: g, n */ - /* reject b-only bss info */ - if ( (!pBssInfo->EnableHT) - && (pBssInfo->extSupportedRates[1] == 0) ) { - goto zlError2; - } - } - } else { - if (wd->supportMode & ZM_WIRELESS_MODE_24_11) { - /* support mode: b, n */ - /* 1. reject g-only bss info - * 2. if non g-only, delete g mode information - */ - if ( !pBssInfo->EnableHT ) { - if ( zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->supportedRates) - || zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->extSupportedRates) ) { - goto zlError2; - } else { - zfGatherBMode(dev, pBssInfo->supportedRates, - pBssInfo->extSupportedRates); - pBssInfo->erp = 0; - - pBssInfo->frameBodysize = zfRemoveElement(dev, - pBssInfo->frameBody, pBssInfo->frameBodysize, - ZM_WLAN_EID_ERP); - pBssInfo->frameBodysize = zfRemoveElement(dev, - pBssInfo->frameBody, pBssInfo->frameBodysize, - ZM_WLAN_EID_EXTENDED_RATE); - - pBssInfo->frameBodysize = zfUpdateElement(dev, - pBssInfo->frameBody, pBssInfo->frameBodysize, - pBssInfo->supportedRates); - } - } - } else { - /* support mode: n */ - /* reject non-n bss info */ - if (!pBssInfo->EnableHT) { - goto zlError2; - } - } - } -#endif - } else { - /* delete n mode information */ - pBssInfo->EnableHT = 0; - pBssInfo->enableHT40 = 0; - pBssInfo->apCap &= (~ZM_All11N_AP); - pBssInfo->extChOffset = 0; - pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, - pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY); - pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, - pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY); - pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, - pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY); - pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, - pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION); - - if (wd->supportMode & ZM_WIRELESS_MODE_24_54) { -#if 0 - if (wd->supportMode & ZM_WIRELESS_MODE_24_11) { - /* support mode: b, g */ - /* delete n mode information */ - } else { - /* support mode: g */ - /* delete n mode information */ - /* reject b-only bss info */ - if (pBssInfo->extSupportedRates[1] == 0) { - goto zlError2; - } - } -#endif - } else { - if (wd->supportMode & ZM_WIRELESS_MODE_24_11) { - /* support mode: b */ - /* delete n mode information */ - if ( zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->supportedRates) - || zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->extSupportedRates) ) { - goto zlError2; - } else { - zfGatherBMode(dev, pBssInfo->supportedRates, - pBssInfo->extSupportedRates); - pBssInfo->erp = 0; - - pBssInfo->frameBodysize = zfRemoveElement(dev, - pBssInfo->frameBody, pBssInfo->frameBodysize, - ZM_WLAN_EID_ERP); - pBssInfo->frameBodysize = zfRemoveElement(dev, - pBssInfo->frameBody, pBssInfo->frameBodysize, - ZM_WLAN_EID_EXTENDED_RATE); - - pBssInfo->frameBodysize = zfUpdateElement(dev, - pBssInfo->frameBody, pBssInfo->frameBodysize, - pBssInfo->supportedRates); - } - } else { - /* support mode: none */ - goto zlError2; - } - } - } - } - - pBssInfo->flag |= ZM_BSS_INFO_VALID_BIT; - -zlUpdateRssi: - /* Update Timer information */ - pBssInfo->tick = wd->tick; - - /* Update ERP information */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP); - if (offset != 0xffff) - { - pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2); - } - - if( (s8_t)pBssInfo->signalStrength < (s8_t)AddInfo->Tail.Data.SignalStrength1 ) - { - /* Update signal strength */ - pBssInfo->signalStrength = (u8_t)AddInfo->Tail.Data.SignalStrength1; - /* Update signal quality */ - pBssInfo->signalQuality = (u8_t)(AddInfo->Tail.Data.SignalStrength1 * 2); - - /* Update the sorting value */ - pBssInfo->sortValue = zfComputeBssInfoWeightValue(dev, - (pBssInfo->supportedRates[6] + pBssInfo->extSupportedRates[0]), - pBssInfo->EnableHT, - pBssInfo->enableHT40, - pBssInfo->signalStrength); - } - - return 0; - -zlError: - - return 1; - -zlError2: - - return 2; -} - -void zfStaProcessBeacon(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) //CWYang(m) -{ - /* Parse TIM and send PS-POLL in power saving mode */ - struct zsWlanBeaconFrameHeader* pBeaconHeader; - struct zsBssInfo* pBssInfo; - u8_t pBuf[sizeof(struct zsWlanBeaconFrameHeader)]; - u8_t bssid[6]; - int res; - - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - /* sta routine jobs */ - zfStaProtErpMonitor(dev, buf); /* check protection mode */ - - if (zfStaIsConnected(dev)) - { - ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid); - - if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) - { - if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6) ) - { - zfPowerSavingMgrProcessBeacon(dev, buf); - zfStaUpdateWmeParameter(dev, buf); - if (wd->sta.DFSEnable) - zfStaUpdateDot11HDFS(dev, buf); - if (wd->sta.TPCEnable) - zfStaUpdateDot11HTPC(dev, buf); - /* update signal strength and signal quality */ - zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1, - AddInfo->Tail.Data.SignalQuality); //CWYang(+) - wd->sta.rxBeaconCount++; - } - } - else if ( wd->wlanMode == ZM_MODE_IBSS ) - { - if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A3_OFFSET, 6) ) - { - int res; - struct zsPartnerNotifyEvent event; - - zm_debug_msg0("20070916 Receive opposite Beacon!"); - zmw_enter_critical_section(dev); - wd->sta.ibssReceiveBeaconCount++; - zmw_leave_critical_section(dev); - - res = zfStaSetOppositeInfoFromRxBuf(dev, buf); - if ( res == 0 ) - { - // New peer station found. Notify the wrapper now - zfInitPartnerNotifyEvent(dev, buf, &event); - if (wd->zfcbIbssPartnerNotify != NULL) - { - wd->zfcbIbssPartnerNotify(dev, 1, &event); - } - } - /* update signal strength and signal quality */ - zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1, - AddInfo->Tail.Data.SignalQuality); //CWYang(+) - } - //else if ( wd->sta.ibssPartnerStatus == ZM_IBSS_PARTNER_LOST ) - // Why does this happen in IBSS?? The impact of Vista since - // we need to tell it the BSSID -#if 0 - else if ( wd->sta.oppositeCount == 0 ) - { /* IBSS merge if SSID matched */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID); - if (offset != 0xffff) - { - if ( (wd->sta.ssidLen == zmw_buf_readb(dev, buf, offset+1))&& - (zfRxBufferEqualToStr(dev, buf, wd->sta.ssid, - offset+2, wd->sta.ssidLen)) ) - { - capabilityInfo = zmw_buf_readh(dev, buf, 34); - - if ( capabilityInfo & ZM_BIT_1 ) - { - if ( (wd->sta.capability[0] & ZM_BIT_4) == - (capabilityInfo & ZM_BIT_4) ) - { - zm_debug_msg0("IBSS merge"); - zfCopyFromRxBuffer(dev, buf, bssid, - ZM_WLAN_HEADER_A3_OFFSET, 6); - zfUpdateBssid(dev, bssid); - } - } - } - } - } -#endif - } - } - - /* return if not channel scan */ - if ( !wd->sta.bChannelScan ) - { - goto zlReturn; - } - - zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanBeaconFrameHeader)); - pBeaconHeader = (struct zsWlanBeaconFrameHeader*) pBuf; - - zmw_enter_critical_section(dev); - - //zm_debug_msg1("bss count = ", wd->sta.bssList.bssCount); - - pBssInfo = zfStaFindBssInfo(dev, buf, pBeaconHeader); - - if ( pBssInfo == NULL ) - { - /* Allocate a new entry if BSS not in the scan list */ - pBssInfo = zfBssInfoAllocate(dev); - if (pBssInfo != NULL) - { - res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 0); - //zfDumpSSID(pBssInfo->ssid[1], &(pBssInfo->ssid[2])); - if ( res != 0 ) - { - zfBssInfoFree(dev, pBssInfo); - } - else - { - zfBssInfoInsertToList(dev, pBssInfo); - } - } - } - else - { - res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 1); - if (res == 2) - { - zfBssInfoRemoveFromList(dev, pBssInfo); - zfBssInfoFree(dev, pBssInfo); - } - else if ( wd->wlanMode == ZM_MODE_IBSS ) - { - int idx; - - // It would reset the alive counter if the peer station is found! - zfStaFindFreeOpposite(dev, (u16_t *)pBssInfo->macaddr, &idx); - } - } - - zmw_leave_critical_section(dev); - -zlReturn: - - return; -} - - -void zfAuthFreqCompleteCb(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - zmw_enter_critical_section(dev); - - if (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_COMPLETED) - { - zm_debug_msg0("ZM_STA_CONN_STATE_ASSOCIATE"); - wd->sta.connectTimer = wd->tick; - wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE; - } - - zmw_leave_critical_section(dev); - return; -} - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfProcessAuth */ -/* Process authenticate management frame. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* buf : auth frame buffer */ -/* */ -/* OUTPUTS */ -/* none */ -/* */ -/* AUTHOR */ -/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ -/* */ -/************************************************************************/ -/* Note : AP allows one authenticating STA at a time, does not */ -/* support multiple authentication process. Make sure */ -/* authentication state machine will not be blocked due */ -/* to incompleted authentication handshake. */ -void zfStaProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) -{ - struct zsWlanAuthFrameHeader* pAuthFrame; - u8_t pBuf[sizeof(struct zsWlanAuthFrameHeader)]; - u32_t p1, p2; - - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - if ( !zfStaIsConnecting(dev) ) - { - return; - } - - pAuthFrame = (struct zsWlanAuthFrameHeader*) pBuf; - zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAuthFrameHeader)); - - if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN ) - { - if ( (zmw_le16_to_cpu(pAuthFrame->seq) == 2)&& - (zmw_le16_to_cpu(pAuthFrame->algo) == 0)&& - (zmw_le16_to_cpu(pAuthFrame->status) == 0) ) - { - - zmw_enter_critical_section(dev); - wd->sta.connectTimer = wd->tick; - zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_COMPLETED"); - wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_COMPLETED; - zmw_leave_critical_section(dev); - - //Set channel according to AP's configuration - //Move to here because of Cisco 11n AP feature - zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40, - wd->ExtOffset, zfAuthFreqCompleteCb); - - /* send association frame */ - if ( wd->sta.connectByReasso ) - { - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCREQ, - wd->sta.bssid, 0, 0, 0); - } - else - { - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ, - wd->sta.bssid, 0, 0, 0); - } - - - } - else - { - zm_debug_msg1("authentication failed, status = ", - pAuthFrame->status); - - if (wd->sta.authMode == ZM_AUTH_MODE_AUTO) - { - wd->sta.bIsSharedKey = 1; - zfStaStartConnect(dev, wd->sta.bIsSharedKey); - } - else - { - zm_debug_msg0("ZM_STA_STATE_DISCONNECT"); - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3); - } - } - } - else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1 ) - { - if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1) && - (zmw_le16_to_cpu(pAuthFrame->seq) == 2) && - (zmw_le16_to_cpu(pAuthFrame->status) == 0)) - //&& (pAuthFrame->challengeText[1] <= 255) ) - { - zfMemoryCopy(wd->sta.challengeText, pAuthFrame->challengeText, - pAuthFrame->challengeText[1]+2); - - /* send the 3rd authentication frame */ - p1 = 0x30001; - p2 = 0; - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, - wd->sta.bssid, p1, p2, 0); - - zmw_enter_critical_section(dev); - wd->sta.connectTimer = wd->tick; - - zm_debug_msg0("ZM_STA_SUB_STATE_AUTH_SHARE_2"); - wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_2; - zmw_leave_critical_section(dev); - } - else - { - zm_debug_msg1("authentication failed, status = ", - pAuthFrame->status); - - zm_debug_msg0("ZM_STA_STATE_DISCONNECT"); - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3); - } - } - else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2 ) - { - if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1)&& - (zmw_le16_to_cpu(pAuthFrame->seq) == 4)&& - (zmw_le16_to_cpu(pAuthFrame->status) == 0) ) - { - //Set channel according to AP's configuration - //Move to here because of Cisco 11n AP feature - zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40, - wd->ExtOffset, NULL); - - /* send association frame */ - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ, - wd->sta.bssid, 0, 0, 0); - - zmw_enter_critical_section(dev); - wd->sta.connectTimer = wd->tick; - - zm_debug_msg0("ZM_STA_SUB_STATE_ASSOCIATE"); - wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE; - zmw_leave_critical_section(dev); - } - else - { - zm_debug_msg1("authentication failed, status = ", - pAuthFrame->status); - - zm_debug_msg0("ZM_STA_STATE_DISCONNECT"); - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3); - } - } - else - { - zm_debug_msg0("unknown case"); - } -} - -void zfStaProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) -{ - - return; -} - -void zfStaProcessAsocRsp(zdev_t* dev, zbuf_t* buf) -{ - struct zsWlanAssoFrameHeader* pAssoFrame; - u8_t pBuf[sizeof(struct zsWlanAssoFrameHeader)]; - u16_t offset; - u32_t i; - u32_t oneTxStreamCap; - - zmw_get_wlan_dev(dev); - - if ( !zfStaIsConnecting(dev) ) - { - return; - } - - pAssoFrame = (struct zsWlanAssoFrameHeader*) pBuf; - zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAssoFrameHeader)); - - if ( wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE ) - { - if ( pAssoFrame->status == 0 ) - { - zm_debug_msg0("ZM_STA_STATE_CONNECTED"); - - if (wd->sta.EnableHT == 1) - { - wd->sta.wmeConnected = 1; - } - if ((wd->sta.wmeEnabled & ZM_STA_WME_ENABLE_BIT) != 0) //WME enabled - { - /* Asoc rsp may contain WME parameter element */ - offset = zfFindWifiElement(dev, buf, 2, 1); - if (offset != 0xffff) - { - zm_debug_msg0("WME enable"); - wd->sta.wmeConnected = 1; - if ((wd->sta.wmeEnabled & ZM_STA_UAPSD_ENABLE_BIT) != 0) - { - if ((zmw_rx_buf_readb(dev, buf, offset+8) & 0x80) != 0) - { - zm_debug_msg0("UAPSD enable"); - wd->sta.qosInfo = wd->sta.wmeQosInfo; - } - } - - zfStaUpdateWmeParameter(dev, buf); - } - } - - - //Store asoc response frame body, for VISTA only - wd->sta.asocRspFrameBodySize = zfwBufGetSize(dev, buf)-24; - if (wd->sta.asocRspFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE) - { - wd->sta.asocRspFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE; - } - for (i=0; i<wd->sta.asocRspFrameBodySize; i++) - { - wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24); - } - - zfStaStoreAsocRspIe(dev, buf); - if (wd->sta.EnableHT && - ((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) != 0) && - (wd->ExtOffset != 0)) - { - wd->sta.htCtrlBandwidth = 1; - } - else - { - wd->sta.htCtrlBandwidth = 0; - } - - //Set channel according to AP's configuration - //zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40, - // wd->ExtOffset, NULL); - - if (wd->sta.EnableHT == 1) - { - wd->addbaComplete = 0; - - if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_ENCRY_EN) == 0 && - (wd->sta.SWEncryptEnable & ZM_SW_WEP_ENCRY_EN) == 0) - { - wd->addbaCount = 1; - zfAggSendAddbaRequest(dev, wd->sta.bssid, 0, 0); - zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_ADDBA, 100); - } - } - - /* set RIFS support */ - if(wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RIFSMode) - { - wd->sta.HT2040 = 1; -// zfHpSetRifs(dev, wd->sta.EnableHT, 1, (wd->sta.currentFrequency < 3000)? 1:0); - } - - wd->sta.aid = pAssoFrame->aid & 0x3fff; - wd->sta.oppositeCount = 0; /* reset opposite count */ - zfStaSetOppositeInfoFromRxBuf(dev, buf); - - wd->sta.rxBeaconCount = 16; - - zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED); - wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev); - if (wd->zfcbConnectNotify != NULL) - { - if (wd->sta.EnableHT != 0) /* 11n */ - { - oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM); - if (wd->sta.htCtrlBandwidth == 1) /* HT40*/ - { - if(oneTxStreamCap) /* one Tx stream */ - { - if (wd->sta.SG40) - { - wd->CurrentTxRateKbps = 150000; - wd->CurrentRxRateKbps = 300000; - } - else - { - wd->CurrentTxRateKbps = 135000; - wd->CurrentRxRateKbps = 270000; - } - } - else /* Two Tx streams */ - { - if (wd->sta.SG40) - { - wd->CurrentTxRateKbps = 300000; - wd->CurrentRxRateKbps = 300000; - } - else - { - wd->CurrentTxRateKbps = 270000; - wd->CurrentRxRateKbps = 270000; - } - } - } - else /* HT20 */ - { - if(oneTxStreamCap) /* one Tx stream */ - { - wd->CurrentTxRateKbps = 650000; - wd->CurrentRxRateKbps = 130000; - } - else /* Two Tx streams */ - { - wd->CurrentTxRateKbps = 130000; - wd->CurrentRxRateKbps = 130000; - } - } - } - else /* 11abg */ - { - if (wd->sta.connection_11b != 0) - { - wd->CurrentTxRateKbps = 11000; - wd->CurrentRxRateKbps = 11000; - } - else - { - wd->CurrentTxRateKbps = 54000; - wd->CurrentRxRateKbps = 54000; - } - } - - - wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid); - } - wd->sta.connectByReasso = TRUE; - wd->sta.failCntOfReasso = 0; - - zfPowerSavingMgrConnectNotify(dev); - - /* Disable here because fixed rate is only for test, TBD. */ - //if (wd->sta.EnableHT) - //{ - // wd->txMCS = 7; //Rate = 65Mbps - // wd->txMT = 2; // Ht rate - // wd->enableAggregation = 2; // Enable Aggregation - //} - } - else - { - zm_debug_msg1("association failed, status = ", - pAssoFrame->status); - - zm_debug_msg0("ZM_STA_STATE_DISCONNECT"); - wd->sta.connectByReasso = FALSE; - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3); - } - } - -} - -void zfStaStoreAsocRspIe(zdev_t* dev, zbuf_t* buf) -{ - u16_t offset; - u32_t i; - u16_t length; - u8_t *htcap; - u8_t asocBw40 = 0; - u8_t asocExtOffset = 0; - - zmw_get_wlan_dev(dev); - - for (i=0; i<wd->sta.asocRspFrameBodySize; i++) - { - wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24); - } - - /* HT capabilities: 28 octets */ - if ( ((wd->sta.currentFrequency > 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_5_N)) - || ((wd->sta.currentFrequency < 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_24_N)) ) - { - /* not 11n AP */ - htcap = (u8_t *)&wd->sta.ie.HtCap; - for (i=0; i<28; i++) - { - htcap[i] = 0; - } - wd->BandWidth40 = 0; - wd->ExtOffset = 0; - return; - } - - offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); - if (offset != 0xffff) - { - /* atheros pre n */ - zm_debug_msg0("atheros pre n"); - htcap = (u8_t *)&wd->sta.ie.HtCap; - htcap[0] = zmw_rx_buf_readb(dev, buf, offset); - htcap[1] = 26; - for (i=1; i<=26; i++) - { - htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i); - zm_msg2_mm(ZM_LV_1, "ASOC: HT Capabilities, htcap=", htcap[i+1]); - } - } - else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) - { - /* pre n 2.0 standard */ - zm_debug_msg0("pre n 2.0 standard"); - htcap = (u8_t *)&wd->sta.ie.HtCap; - for (i=0; i<28; i++) - { - htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i); - zm_msg2_mm(ZM_LV_1, "ASOC: HT Capabilities, htcap=", htcap[i]); - } - } - else - { - /* not 11n AP */ - htcap = (u8_t *)&wd->sta.ie.HtCap; - for (i=0; i<28; i++) - { - htcap[i] = 0; - } - wd->BandWidth40 = 0; - wd->ExtOffset = 0; - return; - } - - asocBw40 = (u8_t)((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) >> 1); - - /* HT information */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY); - if (offset != 0xffff) - { - /* atheros pre n */ - zm_debug_msg0("atheros pre n HTINFO"); - length = 22; - htcap = (u8_t *)&wd->sta.ie.HtInfo; - htcap[0] = zmw_rx_buf_readb(dev, buf, offset); - htcap[1] = 22; - for (i=1; i<=22; i++) - { - htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i); - zm_msg2_mm(ZM_LV_1, "ASOC: HT Info, htinfo=", htcap[i+1]); - } - } - else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff) - { - /* pre n 2.0 standard */ - zm_debug_msg0("pre n 2.0 standard HTINFO"); - length = zmw_rx_buf_readb(dev, buf, offset + 1); - htcap = (u8_t *)&wd->sta.ie.HtInfo; - for (i=0; i<24; i++) - { - htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i); - zm_msg2_mm(ZM_LV_1, "ASOC: HT Info, htinfo=", htcap[i]); - } - } - else - { - zm_debug_msg0("no HTINFO"); - htcap = (u8_t *)&wd->sta.ie.HtInfo; - for (i=0; i<24; i++) - { - htcap[i] = 0; - } - } - asocExtOffset = wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_ExtChannelOffsetBelow; - - if ((wd->sta.EnableHT == 1) && (asocBw40 == 1) && ((asocExtOffset == 1) || (asocExtOffset == 3))) - { - wd->BandWidth40 = asocBw40; - wd->ExtOffset = asocExtOffset; - } - else - { - wd->BandWidth40 = 0; - wd->ExtOffset = 0; - } - - return; -} - -void zfStaProcessDeauth(zdev_t* dev, zbuf_t* buf) -{ - u16_t apMacAddr[3]; - - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - /* STA : if SA=connected AP then disconnect with AP */ - if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) - { - apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET); - apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2); - apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4); - if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2])) - { - if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame - { - if ( zfStaIsConnected(dev) ) - { - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DEAUTH, wd->sta.bssid, 2); - } - else if (zfStaIsConnecting(dev)) - { - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3); - } - else - { - } - } - } - } - else if ( wd->wlanMode == ZM_MODE_IBSS ) - { - u16_t peerMacAddr[3]; - u8_t peerIdx; - s8_t res; - - if ( zfStaIsConnected(dev) ) - { - peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); - peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2); - peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4); - - zmw_enter_critical_section(dev); - res = zfStaFindOppositeByMACAddr(dev, peerMacAddr, &peerIdx); - if ( res == 0 ) - { - wd->sta.oppositeInfo[peerIdx].aliveCounter = 0; - } - zmw_leave_critical_section(dev); - } - } -} - -void zfStaProcessDisasoc(zdev_t* dev, zbuf_t* buf) -{ - u16_t apMacAddr[3]; - - zmw_get_wlan_dev(dev); - - /* STA : if SA=connected AP then disconnect with AP */ - if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) - { - apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET); - apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2); - apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4); - - if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2])) - { - if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame - { - if ( zfStaIsConnected(dev) ) - { - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DISASOC, wd->sta.bssid, 2); - } - else - { - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3); - } - } - } - } -} - - - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfProcessProbeReq */ -/* Process probe request management frame. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* buf : auth frame buffer */ -/* */ -/* OUTPUTS */ -/* none */ -/* */ -/* AUTHOR */ -/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ -/* */ -/************************************************************************/ -void zfStaProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src) -{ - u16_t offset; - u8_t len; - u16_t i, j; - u16_t sendFlag; - - zmw_get_wlan_dev(dev); - - /* check mode : AP/IBSS */ - if ((wd->wlanMode != ZM_MODE_AP) && (wd->wlanMode != ZM_MODE_IBSS)) - { - zm_msg0_mm(ZM_LV_3, "Ignore probe req"); - return; - } - - /* check SSID */ - offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID); - if (offset == 0xffff) - { - zm_msg0_mm(ZM_LV_3, "probe req SSID not found"); - return; - } - - len = zmw_rx_buf_readb(dev, buf, offset+1); - - for (i=0; i<ZM_MAX_AP_SUPPORT; i++) - { - if ((wd->ap.apBitmap & (i<<i)) != 0) - { - sendFlag = 0; - /* boardcast SSID */ - if ((len == 0) && (wd->ap.hideSsid[i] == 0)) - { - sendFlag = 1; - } - /* Not broadcast SSID */ - else if (wd->ap.ssidLen[i] == len) - { - for (j=0; j<len; j++) - { - if (zmw_rx_buf_readb(dev, buf, offset+1+j) - != wd->ap.ssid[i][j]) - { - break; - } - } - if (j == len) - { - sendFlag = 1; - } - } - if (sendFlag == 1) - { - /* Send probe response */ - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBERSP, src, i, 0, 0); - } - } - } -} - -void zfStaProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) -{ - /* return if not channel scan */ - // Probe response is sent with unicast. Is this required? - // IBSS would send probe request and the code below would prevent - // the probe response from handling. - #if 0 - zmw_get_wlan_dev(dev); - - if ( !wd->sta.bChannelScan ) - { - return; - } - #endif - - zfProcessProbeRsp(dev, buf, AddInfo); -} - -void zfIBSSSetupBssDesc(zdev_t *dev) -{ -#ifdef ZM_ENABLE_IBSS_WPA2PSK - u8_t i; -#endif - struct zsBssInfo *pBssInfo; - u16_t offset = 0; - - zmw_get_wlan_dev(dev); - - pBssInfo = &wd->sta.ibssBssDesc; - zfZeroMemory((u8_t *)pBssInfo, sizeof(struct zsBssInfo)); - - pBssInfo->signalStrength = 100; - - zfMemoryCopy((u8_t *)pBssInfo->macaddr, (u8_t *)wd->macAddr,6); - zfMemoryCopy((u8_t *)pBssInfo->bssid, (u8_t *)wd->sta.bssid, 6); - - pBssInfo->beaconInterval[0] = (u8_t)(wd->beaconInterval) ; - pBssInfo->beaconInterval[1] = (u8_t)((wd->beaconInterval) >> 8) ; - - pBssInfo->capability[0] = wd->sta.capability[0]; - pBssInfo->capability[1] = wd->sta.capability[1]; - - pBssInfo->ssid[0] = ZM_WLAN_EID_SSID; - pBssInfo->ssid[1] = wd->sta.ssidLen; - zfMemoryCopy((u8_t *)&pBssInfo->ssid[2], (u8_t *)wd->sta.ssid, wd->sta.ssidLen); - zfMemoryCopy((u8_t *)&pBssInfo->frameBody[offset], (u8_t *)pBssInfo->ssid, - wd->sta.ssidLen + 2); - offset += wd->sta.ssidLen + 2; - - /* support rate */ - - /* DS parameter set */ - pBssInfo->channel = zfChFreqToNum(wd->frequency, NULL); - pBssInfo->frequency = wd->frequency; - pBssInfo->atimWindow = wd->sta.atimWindow; - -#ifdef ZM_ENABLE_IBSS_WPA2PSK - if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK ) - { - u8_t rsn[64]= - { - /* Element ID */ - 0x30, - /* Length */ - 0x14, - /* Version */ - 0x01, 0x00, - /* Group Cipher Suite, default=TKIP */ - 0x00, 0x0f, 0xac, 0x04, - /* Pairwise Cipher Suite Count */ - 0x01, 0x00, - /* Pairwise Cipher Suite, default=TKIP */ - 0x00, 0x0f, 0xac, 0x02, - /* Authentication and Key Management Suite Count */ - 0x01, 0x00, - /* Authentication type, default=PSK */ - 0x00, 0x0f, 0xac, 0x02, - /* RSN capability */ - 0x00, 0x00 - }; - - /* Overwrite Group Cipher Suite by AP's setting */ - zfMemoryCopy(rsn+4, zgWpa2AesOui, 4); - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) - { - /* Overwrite Pairwise Cipher Suite by AES */ - zfMemoryCopy(rsn+10, zgWpa2AesOui, 4); - } - - // RSN element id - pBssInfo->frameBody[offset++] = ZM_WLAN_EID_RSN_IE ; - - // RSN length - pBssInfo->frameBody[offset++] = rsn[1] ; - - // RSN information - for(i=0; i<rsn[1]; i++) - { - pBssInfo->frameBody[offset++] = rsn[i+2] ; - } - - zfMemoryCopy(pBssInfo->rsnIe, rsn, rsn[1]+2); - } -#endif -} - -void zfIbssConnectNetwork(zdev_t* dev) -{ - struct zsBssInfo* pBssInfo; - struct zsBssInfo tmpBssInfo; - u8_t macAddr[6], bssid[6], bssNotFound = TRUE; - u16_t i, j=100; - u16_t k; - struct zsPartnerNotifyEvent event; - u32_t channelFlags; - u16_t oppositeWepStatus; - - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - /* change state to CONNECTING and stop the channel scanning */ - zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING); - zfPowerSavingMgrWakeup(dev); - - /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */ - zfUpdateDefaultQosParameter(dev, 0); - - wd->sta.bProtectionMode = FALSE; - zfHpSetSlotTime(dev, 1); - - /* ESS bit off */ - wd->sta.capability[0] &= ~ZM_BIT_0; - /* IBSS bit on */ - wd->sta.capability[0] |= ZM_BIT_1; - /* not not use short slot time */ - wd->sta.capability[1] &= ~ZM_BIT_2; - - wd->sta.wmeConnected = 0; - wd->sta.psMgr.tempWakeUp = 0; - wd->sta.qosInfo = 0; - wd->sta.EnableHT = 0; - wd->BandWidth40 = 0; - wd->ExtOffset = 0; - - if ( wd->sta.bssList.bssCount ) - { - //Reorder BssList by RSSI--CWYang(+) - zfBssInfoReorderList(dev); - - zmw_enter_critical_section(dev); - - pBssInfo = wd->sta.bssList.head; - - for(i=0; i<wd->sta.bssList.bssCount; i++) - { - // 20070806 #1 Privacy bit - if ( pBssInfo->capability[0] & ZM_BIT_4 ) - { // Privacy Ibss network -// zm_debug_msg0("Privacy bit on"); - oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED; - - if ( pBssInfo->rsnIe[1] != 0 ) - { - if ( (pBssInfo->rsnIe[7] == 0x01) || (pBssInfo->rsnIe[7] == 0x05) ) - { // WEP-40 & WEP-104 -// zm_debug_msg0("WEP40 or WEP104"); - oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED; - } - else if ( pBssInfo->rsnIe[7] == 0x02 ) - { // TKIP -// zm_debug_msg0("TKIP"); - oppositeWepStatus = ZM_ENCRYPTION_TKIP; - } - else if ( pBssInfo->rsnIe[7] == 0x04 ) - { // AES -// zm_debug_msg0("CCMP-AES"); - oppositeWepStatus = ZM_ENCRYPTION_AES; - } - } - } - else - { -// zm_debug_msg0("Privacy bit off"); - oppositeWepStatus = ZM_ENCRYPTION_WEP_DISABLED; - } - - if ( (zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid, - wd->sta.ssidLen))&& - (wd->sta.ssidLen == pBssInfo->ssid[1])&& - (oppositeWepStatus == wd->sta.wepStatus) ) - { - /* Check support mode */ - if (pBssInfo->frequency > 3000) { - if ( (pBssInfo->EnableHT == 1) - || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP - { - channelFlags = CHANNEL_A_HT; - if (pBssInfo->enableHT40 == 1) { - channelFlags |= CHANNEL_HT40; - } - } else { - channelFlags = CHANNEL_A; - } - } else { - if ( (pBssInfo->EnableHT == 1) - || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP - { - channelFlags = CHANNEL_G_HT; - if(pBssInfo->enableHT40 == 1) { - channelFlags |= CHANNEL_HT40; - } - } else { - if (pBssInfo->extSupportedRates[1] == 0) { - channelFlags = CHANNEL_B; - } else { - channelFlags = CHANNEL_G; - } - } - } - - if ( ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0)) - || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1)) - || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2)) - || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) ) - { - pBssInfo = pBssInfo->next; - continue; - } - - /* Bypass DFS channel */ - if (zfHpIsDfsChannelNCS(dev, pBssInfo->frequency)) - { - zm_debug_msg0("Bypass DFS channel"); - continue; - } - - /* check IBSS bit */ - if ( pBssInfo->capability[0] & ZM_BIT_1 ) - { - /* may check timestamp here */ - j = i; - break; - } - } - - pBssInfo = pBssInfo->next; - } - - if ((j < wd->sta.bssList.bssCount) && (pBssInfo != NULL)) - { - zfwMemoryCopy((u8_t*)&tmpBssInfo, (u8_t*)(pBssInfo), sizeof(struct zsBssInfo)); - pBssInfo = &tmpBssInfo; - } - else - { - pBssInfo = NULL; - } - - zmw_leave_critical_section(dev); - - //if ( j < wd->sta.bssList.bssCount ) - if (pBssInfo != NULL) - { - int res; - - zm_debug_msg0("IBSS found"); - - /* Found IBSS, reset bssNotFoundCount */ - zmw_enter_critical_section(dev); - wd->sta.bssNotFoundCount = 0; - zmw_leave_critical_section(dev); - - bssNotFound = FALSE; - wd->sta.atimWindow = pBssInfo->atimWindow; - wd->frequency = pBssInfo->frequency; - //wd->sta.flagFreqChanging = 1; - zfCoreSetFrequency(dev, wd->frequency); - zfUpdateBssid(dev, pBssInfo->bssid); - zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO); - zfUpdateSupportRate(dev, pBssInfo->supportedRates); - zfUpdateSupportRate(dev, pBssInfo->extSupportedRates); - wd->beaconInterval = pBssInfo->beaconInterval[0] + - (((u16_t) pBssInfo->beaconInterval[1]) << 8); - - if (wd->beaconInterval == 0) - { - wd->beaconInterval = 100; - } - - /* rsn information element */ - if ( pBssInfo->rsnIe[1] != 0 ) - { - zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe, - pBssInfo->rsnIe[1]+2); - -#ifdef ZM_ENABLE_IBSS_WPA2PSK - /* If not use RSNA , run traditional */ - zmw_enter_critical_section(dev); - wd->sta.ibssWpa2Psk = 1; - zmw_leave_critical_section(dev); -#endif - } - else - { - wd->sta.rsnIe[1] = 0; - } - - /* privacy bit */ - if ( pBssInfo->capability[0] & ZM_BIT_4 ) - { - wd->sta.capability[0] |= ZM_BIT_4; - } - else - { - wd->sta.capability[0] &= ~ZM_BIT_4; - } - - /* preamble type */ - wd->preambleTypeInUsed = wd->preambleType; - if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO ) - { - if (pBssInfo->capability[0] & ZM_BIT_5) - { - wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT; - } - else - { - wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG; - } - } - - if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG) - { - wd->sta.capability[0] &= ~ZM_BIT_5; - } - else - { - wd->sta.capability[0] |= ZM_BIT_5; - } - - wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12; - - if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE) - { - wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE; - } - - for (k=0; k<8; k++) - { - wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k]; - } - wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0]; - wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1]; - wd->sta.beaconFrameBody[10] = pBssInfo->capability[0]; - wd->sta.beaconFrameBody[11] = pBssInfo->capability[1]; - //for (k=12; k<wd->sta.beaconFrameBodySize; k++) - for (k=0; k<pBssInfo->frameBodysize; k++) - { - wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k]; - } - - zmw_enter_critical_section(dev); - res = zfStaSetOppositeInfoFromBSSInfo(dev, pBssInfo); - if ( res == 0 ) - { - zfMemoryCopy(event.bssid, (u8_t *)(pBssInfo->bssid), 6); - zfMemoryCopy(event.peerMacAddr, (u8_t *)(pBssInfo->macaddr), 6); - } - zmw_leave_critical_section(dev); - - //zfwIbssPartnerNotify(dev, 1, &event); - goto connect_done; - } - } - - /* IBSS not found */ - if ( bssNotFound ) - { -#ifdef ZM_ENABLE_IBSS_WPA2PSK - u16_t offset ; -#endif - if ( wd->sta.ibssJoinOnly ) - { - zm_debug_msg0("IBSS join only...retry..."); - goto retry_ibss; - } - - if(wd->sta.bssNotFoundCount<2) - { - zmw_enter_critical_section(dev); - zm_debug_msg1("IBSS not found, do sitesurvey!! bssNotFoundCount=", wd->sta.bssNotFoundCount); - wd->sta.bssNotFoundCount++; - zmw_leave_critical_section(dev); - goto retry_ibss; - } - else - { - zmw_enter_critical_section(dev); - /* Fail IBSS found, TODO create IBSS */ - wd->sta.bssNotFoundCount = 0; - zmw_leave_critical_section(dev); - } - - - if (zfHpIsDfsChannel(dev, wd->frequency)) - { - wd->frequency = zfHpFindFirstNonDfsChannel(dev, wd->frequency > 3000); - } - - if( wd->ws.autoSetFrequency == 0 ) - { /* Auto set frequency */ - zm_debug_msg1("Create Ad Hoc Network Band ", wd->ws.adhocMode); - wd->frequency = zfFindCleanFrequency(dev, wd->ws.adhocMode); - wd->ws.autoSetFrequency = 0xff; - } - zm_debug_msg1("IBSS not found, created one in channel ", wd->frequency); - - wd->sta.ibssBssIsCreator = 1; - - //wd->sta.flagFreqChanging = 1; - zfCoreSetFrequency(dev, wd->frequency); - if (wd->sta.bDesiredBssid == TRUE) - { - for (k=0; k<6; k++) - { - bssid[k] = wd->sta.desiredBssid[k]; - } - } - else - { - #if 1 - macAddr[0] = (wd->macAddr[0] & 0xff); - macAddr[1] = (wd->macAddr[0] >> 8); - macAddr[2] = (wd->macAddr[1] & 0xff); - macAddr[3] = (wd->macAddr[1] >> 8); - macAddr[4] = (wd->macAddr[2] & 0xff); - macAddr[5] = (wd->macAddr[2] >> 8); - zfGenerateRandomBSSID(dev, (u8_t *)wd->macAddr, (u8_t *)bssid); - #else - for (k=0; k<6; k++) - { - bssid[k] = (u8_t) zfGetRandomNumber(dev, 0); - } - bssid[0] &= ~ZM_BIT_0; - bssid[0] |= ZM_BIT_1; - #endif - } - - zfUpdateBssid(dev, bssid); - //wd->sta.atimWindow = 0x0a; - - /* rate information */ - if(wd->frequency <= ZM_CH_G_14) // 2.4 GHz b+g - { - if ( wd->wfc.bIbssGMode - && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) - { - zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG); - } - else - { - zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_B); - } - } else { - zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG); - } - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED ) - { - wd->sta.capability[0] &= ~ZM_BIT_4; - } - else - { - wd->sta.capability[0] |= ZM_BIT_4; - } - - wd->preambleTypeInUsed = wd->preambleType; - if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG) - { - wd->sta.capability[0] &= ~ZM_BIT_5; - } - else - { - wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT; - wd->sta.capability[0] |= ZM_BIT_5; - } - - zfIBSSSetupBssDesc(dev); - -#ifdef ZM_ENABLE_IBSS_WPA2PSK - - // 20070411 Add WPA2PSK information to its IBSS network !!! - offset = 0 ; - - /* timestamp */ - offset += 8 ; - - /* beacon interval */ - wd->sta.beaconFrameBody[offset++] = (u8_t)(wd->beaconInterval) ; - wd->sta.beaconFrameBody[offset++] = (u8_t)((wd->beaconInterval) >> 8) ; - - /* capability information */ - wd->sta.beaconFrameBody[offset++] = wd->sta.capability[0] ; - wd->sta.beaconFrameBody[offset++] = wd->sta.capability[1] ; - #if 0 - /* ssid */ - // ssid element id - wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_SSID ; - // ssid length - wd->sta.beaconFrameBody[offset++] = wd->sta.ssidLen ; - // ssid information - for(i=0; i<wd->sta.ssidLen; i++) - { - wd->sta.beaconFrameBody[offset++] = wd->sta.ssid[i] ; - } - - /* support rate */ - rateSet = ZM_RATE_SET_CCK ; - if ( (rateSet == ZM_RATE_SET_OFDM)&&((wd->gRate & 0xff) == 0) ) - { - offset += 0 ; - } - else - { - // support rate element id - wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_SUPPORT_RATE ; - - // support rate length - lenOffset = offset++; - - // support rate information - for (i=0; i<4; i++) - { - if ((wd->bRate & (0x1<<i)) == (0x1<<i)) - { - wd->sta.beaconFrameBody[offset++] = - zg11bRateTbl[i]+((wd->bRateBasic & (0x1<<i))<<(7-i)) ; - len++; - } - } - - // support rate length - wd->sta.beaconFrameBody[lenOffset] = len ; - } - - /* DS parameter set */ - // DS parameter set elemet id - wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_DS ; - - // DS parameter set length - wd->sta.beaconFrameBody[offset++] = 1 ; - - // DS parameter set information - wd->sta.beaconFrameBody[offset++] = - zfChFreqToNum(wd->frequency, NULL) ; - - /* IBSS parameter set */ - // IBSS parameter set element id - wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_IBSS ; - - // IBSS parameter set length - wd->sta.beaconFrameBody[offset++] = 2 ; - - // IBSS parameter set information - wd->sta.beaconFrameBody[offset] = wd->sta.atimWindow ; - offset += 2 ; - - /* ERP Information and Extended Supported Rates */ - if ( wd->wfc.bIbssGMode - && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) - { - /* ERP Information */ - wd->erpElement = 0; - // ERP element id - wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_ERP ; - - // ERP length - wd->sta.beaconFrameBody[offset++] = 1 ; - - // ERP information - wd->sta.beaconFrameBody[offset++] = wd->erpElement ; - - /* Extended Supported Rates */ - if ( (rateSet == ZM_RATE_SET_OFDM)&&((wd->gRate & 0xff) == 0) ) - { - offset += 0 ; - } - else - { - len = 0 ; - - // Extended Supported Rates element id - wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_EXTENDED_RATE ; - - // Extended Supported Rates length - lenOffset = offset++ ; - - // Extended Supported Rates information - for (i=0; i<8; i++) - { - if ((wd->gRate & (0x1<<i)) == (0x1<<i)) - { - wd->sta.beaconFrameBody[offset++] = - zg11gRateTbl[i]+((wd->gRateBasic & (0x1<<i))<<(7-i)); - len++; - } - } - - // extended support rate length - wd->sta.beaconFrameBody[lenOffset] = len ; - } - } - #endif - - /* RSN : important information influence the result of creating an IBSS network */ - if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK ) - { - u8_t frameType = ZM_WLAN_FRAME_TYPE_AUTH ; - u8_t rsn[64]= - { - /* Element ID */ - 0x30, - /* Length */ - 0x14, - /* Version */ - 0x01, 0x00, - /* Group Cipher Suite, default=TKIP */ - 0x00, 0x0f, 0xac, 0x04, - /* Pairwise Cipher Suite Count */ - 0x01, 0x00, - /* Pairwise Cipher Suite, default=TKIP */ - 0x00, 0x0f, 0xac, 0x02, - /* Authentication and Key Management Suite Count */ - 0x01, 0x00, - /* Authentication type, default=PSK */ - 0x00, 0x0f, 0xac, 0x02, - /* RSN capability */ - 0x00, 0x00 - }; - - /* Overwrite Group Cipher Suite by AP's setting */ - zfMemoryCopy(rsn+4, zgWpa2AesOui, 4); - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) - { - /* Overwrite Pairwise Cipher Suite by AES */ - zfMemoryCopy(rsn+10, zgWpa2AesOui, 4); - } - - // RSN element id - wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_RSN_IE ; - - // RSN length - wd->sta.beaconFrameBody[offset++] = rsn[1] ; - - // RSN information - for(i=0; i<rsn[1]; i++) - wd->sta.beaconFrameBody[offset++] = rsn[i+2] ; - - zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2); - -#ifdef ZM_ENABLE_IBSS_WPA2PSK - /* If not use RSNA , run traditional */ - zmw_enter_critical_section(dev); - wd->sta.ibssWpa2Psk = 1; - zmw_leave_critical_section(dev); -#endif - } - - #if 0 - /* HT Capabilities Info */ - { - u8_t OUI[3] = { 0x0 , 0x90 , 0x4C } ; - - wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_WPA_IE ; - - wd->sta.beaconFrameBody[offset++] = wd->sta.HTCap.Data.Length + 4 ; - - for (i = 0; i < 3; i++) - { - wd->sta.beaconFrameBody[offset++] = OUI[i] ; - } - - wd->sta.beaconFrameBody[offset++] = wd->sta.HTCap.Data.ElementID ; - - for (i = 0; i < 26; i++) - { - wd->sta.beaconFrameBody[offset++] = wd->sta.HTCap.Byte[i+2] ; - } - } - - /* Extended HT Capabilities Info */ - { - u8_t OUI[3] = { 0x0 , 0x90 , 0x4C } ; - - wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_WPA_IE ; - - wd->sta.beaconFrameBody[offset++] = wd->sta.ExtHTCap.Data.Length + 4 ; - - for (i = 0; i < 3; i++) - { - wd->sta.beaconFrameBody[offset++] = OUI[i] ; - } - - wd->sta.beaconFrameBody[offset++] = wd->sta.ExtHTCap.Data.ElementID ; - - for (i = 0; i < 22; i++) - { - wd->sta.beaconFrameBody[offset++] = wd->sta.ExtHTCap.Byte[i+2] ; - } - } - #endif - - wd->sta.beaconFrameBodySize = offset ; - - if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE) - { - wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE; - } - - // 20070416 Let Create IBSS network could enter the zfwIbssPartnerNotify function - // bssNotFound = FALSE ; - - printk("The capability info 1 = %02x\n", wd->sta.capability[0]) ; - printk("The capability info 2 = %02x\n", wd->sta.capability[1]) ; - for(k=0; k<wd->sta.beaconFrameBodySize; k++) - { - printk("%02x ", wd->sta.beaconFrameBody[k]) ; - } - #if 0 - zmw_enter_critical_section(dev); - zfMemoryCopy(event.bssid, (u8_t *)bssid, 6); - zfMemoryCopy(event.peerMacAddr, (u8_t *)wd->macAddr, 6); - zmw_leave_critical_section(dev); - #endif -#endif - - //zmw_enter_critical_section(dev); - //wd->sta.ibssPartnerStatus = ZM_IBSS_PARTNER_LOST; - //zmw_leave_critical_section(dev); - } - else - { - wd->sta.ibssBssIsCreator = 0; - } - -connect_done: - zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow); - zfStaSendBeacon(dev); // Refresh Beacon content for ZD1211B HalPlus - zfHpSetAtimWindow(dev, wd->sta.atimWindow); - - // Start the IBSS timer to monitor for new stations - zmw_enter_critical_section(dev); - zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR); - zmw_leave_critical_section(dev); - - - if (wd->zfcbConnectNotify != NULL) - { - wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid); - } - zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED); - wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev); - -#ifdef ZM_ENABLE_IBSS_DELAYED_JOIN_INDICATION - if ( !bssNotFound ) - { - wd->sta.ibssDelayedInd = 1; - zfMemoryCopy((u8_t *)&wd->sta.ibssDelayedIndEvent, (u8_t *)&event, sizeof(struct zsPartnerNotifyEvent)); - } -#else - if ( !bssNotFound ) - { - if (wd->zfcbIbssPartnerNotify != NULL) - { - wd->zfcbIbssPartnerNotify(dev, 1, &event); - } - } -#endif - - return; - -retry_ibss: - zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING); - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0); - return; -} - -void zfStaProcessAtim(zdev_t* dev, zbuf_t* buf) -{ - zmw_get_wlan_dev(dev); - - zm_debug_msg0("Receiving Atim window notification"); - - wd->sta.recvAtim = 1; -} - -static struct zsBssInfo* zfInfraFindAPToConnect(zdev_t* dev, - struct zsBssInfo* candidateBss) -{ - struct zsBssInfo* pBssInfo; - struct zsBssInfo* pNowBssInfo=NULL; - u16_t i; - u16_t ret, apWepStatus; - u32_t k; - u32_t channelFlags; - - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - zmw_enter_critical_section(dev); - - pBssInfo = wd->sta.bssList.head; - - for(i=0; i<wd->sta.bssList.bssCount; i++) - { - if ( pBssInfo->capability[0] & ZM_BIT_4 ) - { - apWepStatus = ZM_ENCRYPTION_WEP_ENABLED; - } - else - { - apWepStatus = ZM_ENCRYPTION_WEP_DISABLED; - } - - if ( ((zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid, - wd->sta.ssidLen))&& - (wd->sta.ssidLen == pBssInfo->ssid[1]))|| - ((wd->sta.ssidLen == 0)&& - /* connect to any BSS: AP's ans STA's WEP status must match */ - (wd->sta.wepStatus == apWepStatus )&& - (pBssInfo->securityType != ZM_SECURITY_TYPE_WPA) )) - { - if ( wd->sta.ssidLen == 0 ) - { - zm_debug_msg0("ANY BSS found"); - } - - if ( ((wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED && apWepStatus == ZM_ENCRYPTION_WEP_ENABLED) || - (wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED && - (apWepStatus == ZM_ENCRYPTION_WEP_DISABLED && wd->sta.dropUnencryptedPkts == 1))) && - (wd->sta.authMode >= ZM_AUTH_MODE_OPEN && wd->sta.authMode <= ZM_AUTH_MODE_AUTO) ) - { - zm_debug_msg0("Privacy policy is inconsistent"); - pBssInfo = pBssInfo->next; - continue; - } - - /* for WPA negative test */ - if ( !zfCheckAuthentication(dev, pBssInfo) ) - { - pBssInfo = pBssInfo->next; - continue; - } - - /* Check bssid */ - if (wd->sta.bDesiredBssid == TRUE) - { - for (k=0; k<6; k++) - { - if (wd->sta.desiredBssid[k] != pBssInfo->bssid[k]) - { - zm_msg0_mm(ZM_LV_1, "desired bssid not matched 1"); - break; - } - } - - if (k != 6) - { - zm_msg0_mm(ZM_LV_1, "desired bssid not matched 2"); - pBssInfo = pBssInfo->next; - continue; - } - } - - /* Check support mode */ - if (pBssInfo->frequency > 3000) { - if ( (pBssInfo->EnableHT == 1) - || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP - { - channelFlags = CHANNEL_A_HT; - if (pBssInfo->enableHT40 == 1) { - channelFlags |= CHANNEL_HT40; - } - } else { - channelFlags = CHANNEL_A; - } - } else { - if ( (pBssInfo->EnableHT == 1) - || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP - { - channelFlags = CHANNEL_G_HT; - if(pBssInfo->enableHT40 == 1) { - channelFlags |= CHANNEL_HT40; - } - } else { - if (pBssInfo->extSupportedRates[1] == 0) { - channelFlags = CHANNEL_B; - } else { - channelFlags = CHANNEL_G; - } - } - } - - if ( ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0)) - || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1)) - || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2)) - || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) ) - { - pBssInfo = pBssInfo->next; - continue; - } - - /* Skip if AP in blocking list */ - ret = zfStaIsApInBlockingList(dev, pBssInfo->bssid); - if (ret == TRUE) - { - zm_msg0_mm(ZM_LV_0, "Candidate AP in blocking List, skip if there's stilla choice!"); - pNowBssInfo = pBssInfo; - pBssInfo = pBssInfo->next; - continue; - } - - if ( pBssInfo->capability[0] & ZM_BIT_0 ) // check if infra-BSS - { - pNowBssInfo = pBssInfo; - wd->sta.apWmeCapability = pBssInfo->wmeSupport; - - - goto done; - } - } - - pBssInfo = pBssInfo->next; - } - -done: - if (pNowBssInfo != NULL) - { - zfwMemoryCopy((void*)candidateBss, (void*)pNowBssInfo, sizeof(struct zsBssInfo)); - pNowBssInfo = candidateBss; - } - - zmw_leave_critical_section(dev); - - return pNowBssInfo; -} - - -void zfInfraConnectNetwork(zdev_t* dev) -{ - struct zsBssInfo* pBssInfo; - struct zsBssInfo* pNowBssInfo=NULL; - struct zsBssInfo candidateBss; - //u16_t i, j=100, quality=10000; - //u8_t ret=FALSE, apWepStatus; - u8_t ret=FALSE; - u16_t k; - u8_t density = ZM_MPDU_DENSITY_NONE; - - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - /* Reset bssNotFoundCount for Ad-Hoc:IBSS */ - /* Need review : IbssConn -> InfraConn -> IbssConn etc, flag/counter reset? */ - zmw_enter_critical_section(dev); - wd->sta.bssNotFoundCount = 0; - zmw_leave_critical_section(dev); - - /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */ - zfUpdateDefaultQosParameter(dev, 0); - - zfStaRefreshBlockList(dev, 0); - - /* change state to CONNECTING and stop the channel scanning */ - zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING); - zfPowerSavingMgrWakeup(dev); - - wd->sta.wmeConnected = 0; - wd->sta.psMgr.tempWakeUp = 0; - wd->sta.qosInfo = 0; - zfQueueFlush(dev, wd->sta.uapsdQ); - - wd->sta.connectState = ZM_STA_CONN_STATE_NONE; - - //Reorder BssList by RSSI--CWYang(+) - zfBssInfoReorderList(dev); - - pNowBssInfo = zfInfraFindAPToConnect(dev, &candidateBss); - - if (wd->sta.SWEncryptEnable != 0) - { - if (wd->sta.bSafeMode == 0) - { - zfStaDisableSWEncryption(dev);//Quickly reboot - } - } - if ( pNowBssInfo != NULL ) - { - //zm_assert(pNowBssInfo != NULL); - - pBssInfo = pNowBssInfo; - wd->sta.ssidLen = pBssInfo->ssid[1]; - zfMemoryCopy(wd->sta.ssid, &(pBssInfo->ssid[2]), pBssInfo->ssid[1]); - wd->frequency = pBssInfo->frequency; - //wd->sta.flagFreqChanging = 1; - - //zfCoreSetFrequency(dev, wd->frequency); - zfUpdateBssid(dev, pBssInfo->bssid); - zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO); - zfUpdateSupportRate(dev, pBssInfo->supportedRates); - zfUpdateSupportRate(dev, pBssInfo->extSupportedRates); - - wd->beaconInterval = pBssInfo->beaconInterval[0] + - (((u16_t) pBssInfo->beaconInterval[1]) << 8); - if (wd->beaconInterval == 0) - { - wd->beaconInterval = 100; - } - - /* ESS bit on */ - wd->sta.capability[0] |= ZM_BIT_0; - /* IBSS bit off */ - wd->sta.capability[0] &= ~ZM_BIT_1; - - /* 11n AP flag */ - wd->sta.EnableHT = pBssInfo->EnableHT; - wd->sta.SG40 = pBssInfo->SG40; -#ifdef ZM_ENABLE_CENC - if ( pBssInfo->securityType == ZM_SECURITY_TYPE_CENC ) - { - wd->sta.wmeEnabled = 0; //Disable WMM in CENC - cencInit(dev); - cencSetCENCMode(dev, NdisCENC_PSK); - wd->sta.wpaState = ZM_STA_WPA_STATE_INIT; - /* CENC */ - if ( pBssInfo->cencIe[1] != 0 ) - { - //wd->sta.wepStatus = ZM_ENCRYPTION_CENC; - //wd->sta.encryMode = ZM_CENC; - zfwCencHandleBeaconProbrespon(dev, (u8_t *)&pBssInfo->cencIe, - (u8_t *)&pBssInfo->ssid, (u8_t *)&pBssInfo->macaddr); - zfMemoryCopy(wd->sta.cencIe, pBssInfo->cencIe, - pBssInfo->cencIe[1]+2); - } - else - { - wd->sta.cencIe[1] = 0; - } - } -#endif //ZM_ENABLE_CENC - if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA ) - { - wd->sta.wpaState = ZM_STA_WPA_STATE_INIT; - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP ) - { - wd->sta.encryMode = ZM_TKIP; - - /* Turn on software encryption/decryption for TKIP */ - if (wd->sta.EnableHT == 1) - { - zfStaEnableSWEncryption(dev, (ZM_SW_TKIP_ENCRY_EN|ZM_SW_TKIP_DECRY_EN)); - } - - /* Do not support TKIP in 11n mode */ - //wd->sta.EnableHT = 0; - //pBssInfo->enableHT40 = 0; - } - else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) - { - wd->sta.encryMode = ZM_AES; - - /* If AP supports HT mode */ - if (wd->sta.EnableHT) - { - /* Set MPDU density to 8 us*/ - density = ZM_MPDU_DENSITY_8US; - } - } - - if ( pBssInfo->wpaIe[1] != 0 ) - { - zfMemoryCopy(wd->sta.wpaIe, pBssInfo->wpaIe, - pBssInfo->wpaIe[1]+2); - } - else - { - wd->sta.wpaIe[1] = 0; - } - - if ( pBssInfo->rsnIe[1] != 0 ) - { - zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe, - pBssInfo->rsnIe[1]+2); - } - else - { - wd->sta.rsnIe[1] = 0; - } - } - - - - /* check preamble bit */ - wd->preambleTypeInUsed = wd->preambleType; - if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO ) - { - if (pBssInfo->capability[0] & ZM_BIT_5) - { - wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT; - } - else - { - wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG; - } - } - - if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG) - { - wd->sta.capability[0] &= ~ZM_BIT_5; - } - else - { - wd->sta.capability[0] |= ZM_BIT_5; - } - - /* check 802.11n 40MHz Setting */ - if ((pBssInfo->enableHT40 == 1) && - ((pBssInfo->extChOffset == 1) || (pBssInfo->extChOffset == 3))) - { - wd->BandWidth40 = pBssInfo->enableHT40; - wd->ExtOffset = pBssInfo->extChOffset; - } - else - { - wd->BandWidth40 = 0; - wd->ExtOffset = 0; - } - - /* check 802.11H support bit */ - - /* check Owl Ap */ - if ( pBssInfo->athOwlAp & ZM_BIT_0 ) - { - /* In this function, FW retry will be enable, ZM_MAC_REG_RETRY_MAX - will be set to 0. - */ - zfHpDisableHwRetry(dev); - wd->sta.athOwlAp = 1; - /* Set MPDU density to 8 us*/ - density = ZM_MPDU_DENSITY_8US; - } - else - { - /* In this function, FW retry will be disable, ZM_MAC_REG_RETRY_MAX - will be set to 3. - */ - zfHpEnableHwRetry(dev); - wd->sta.athOwlAp = 0; - } - wd->reorder = 1; - - /* Set MPDU density */ - zfHpSetMPDUDensity(dev, density); - - /* check short slot time bit */ - if ( pBssInfo->capability[1] & ZM_BIT_2 ) - { - wd->sta.capability[1] |= ZM_BIT_2; - } - - if ( pBssInfo->erp & ZM_BIT_1 ) - { - //zm_debug_msg0("protection mode on"); - wd->sta.bProtectionMode = TRUE; - zfHpSetSlotTime(dev, 0); - } - else - { - //zm_debug_msg0("protection mode off"); - wd->sta.bProtectionMode = FALSE; - zfHpSetSlotTime(dev, 1); - } - - if (pBssInfo->marvelAp == 1) - { - wd->sta.enableDrvBA = 0; - /* - * 8701 : NetGear 3500 (MARVELL) - * Downlink issue : set slottime to 20. - */ - zfHpSetSlotTimeRegister(dev, 0); - } - else - { - wd->sta.enableDrvBA = 1; - - /* - * This is not good for here do reset slot time. - * I think it should reset when leave MARVELL ap - * or enter disconnect state etc. - */ - zfHpSetSlotTimeRegister(dev, 1); - } - - //Store probe response frame body, for VISTA only - wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12; - if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE) - { - wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE; - } - for (k=0; k<8; k++) - { - wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k]; - } - wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0]; - wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1]; - wd->sta.beaconFrameBody[10] = pBssInfo->capability[0]; - wd->sta.beaconFrameBody[11] = pBssInfo->capability[1]; - for (k=0; k<(wd->sta.beaconFrameBodySize - 12); k++) - { - wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k]; - } - - if ( ( pBssInfo->capability[0] & ZM_BIT_4 )&& - (( wd->sta.authMode == ZM_AUTH_MODE_OPEN )|| - ( wd->sta.authMode == ZM_AUTH_MODE_SHARED_KEY)|| - (wd->sta.authMode == ZM_AUTH_MODE_AUTO)) ) - { /* privacy enabled */ - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED ) - { - zm_debug_msg0("Adapter is no WEP, try to connect to WEP AP"); - ret = FALSE; - } - - /* Do not support WEP in 11n mode */ - if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED ) - { - /* Turn on software encryption/decryption for WEP */ - if (wd->sta.EnableHT == 1) - { - zfStaEnableSWEncryption(dev, (ZM_SW_WEP_ENCRY_EN|ZM_SW_WEP_DECRY_EN)); - } - - //wd->sta.EnableHT = 0; - //wd->BandWidth40 = 0; - //wd->ExtOffset = 0; - } - - wd->sta.capability[0] |= ZM_BIT_4; - - if ( wd->sta.authMode == ZM_AUTH_MODE_AUTO ) - { /* Try to use open and shared-key authehtication alternatively */ - if ( (wd->sta.connectTimeoutCount % 2) == 0 ) - wd->sta.bIsSharedKey = 0; - else - wd->sta.bIsSharedKey = 1; - } - else if ( wd->sta.authMode != ZM_AUTH_MODE_SHARED_KEY ) - { /* open or auto */ - //zfStaStartConnect(dev, 0); - wd->sta.bIsSharedKey = 0; - } - else if ( wd->sta.authMode != ZM_AUTH_MODE_OPEN ) - { /* shared key */ - //zfStaStartConnect(dev, 1) ; - wd->sta.bIsSharedKey = 1; - } - } - else - { - if ( (pBssInfo->securityType == ZM_SECURITY_TYPE_WPA)|| - (pBssInfo->capability[0] & ZM_BIT_4) ) - { - wd->sta.capability[0] |= ZM_BIT_4; - /* initialize WPA related parameters */ - } - else - { - wd->sta.capability[0] &= (~ZM_BIT_4); - } - - /* authentication with open system */ - //zfStaStartConnect(dev, 0); - wd->sta.bIsSharedKey = 0; - } - - /* Improve WEP/TKIP performance with HT AP, detail information please look bug#32495 */ - /* - if ( (pBssInfo->broadcomHTAp == 1) - && (wd->sta.SWEncryptEnable != 0) ) - { - zfHpSetTTSIFSTime(dev, 0xa); - } - else - { - zfHpSetTTSIFSTime(dev, 0x8); - } - */ - } - else - { - zm_debug_msg0("Desired SSID not found"); - goto zlConnectFailed; - } - - - zfCoreSetFrequencyV2(dev, wd->frequency, zfStaStartConnectCb); - return; - -zlConnectFailed: - zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0); - return; -} - -u8_t zfCheckWPAAuth(zdev_t* dev, struct zsBssInfo* pBssInfo) -{ - u8_t ret=TRUE; - u8_t pmkCount; - u8_t i; - u16_t encAlgoType = 0; - - zmw_get_wlan_dev(dev); - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP ) - { - encAlgoType = ZM_TKIP; - } - else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) - { - encAlgoType = ZM_AES; - } - - switch(wd->sta.authMode) - { - case ZM_AUTH_MODE_WPA: - case ZM_AUTH_MODE_WPAPSK: - if ( pBssInfo->wpaIe[1] == 0 ) - { - ret = FALSE; - break; - } - - pmkCount = pBssInfo->wpaIe[12]; - for(i=0; i < pmkCount; i++) - { - if ( pBssInfo->wpaIe[17 + 4*i] == encAlgoType ) - { - ret = TRUE; - goto done; - } - } - - ret = FALSE; - break; - - case ZM_AUTH_MODE_WPA2: - case ZM_AUTH_MODE_WPA2PSK: - if ( pBssInfo->rsnIe[1] == 0 ) - { - ret = FALSE; - break; - } - - pmkCount = pBssInfo->rsnIe[8]; - for(i=0; i < pmkCount; i++) - { - if ( pBssInfo->rsnIe[13 + 4*i] == encAlgoType ) - { - ret = TRUE; - goto done; - } - } - - ret = FALSE; - break; - } - -done: - return ret; -} - -u8_t zfCheckAuthentication(zdev_t* dev, struct zsBssInfo* pBssInfo) -{ - u8_t ret=TRUE; - u16_t encAlgoType; - u16_t UnicastCipherNum; - - zmw_get_wlan_dev(dev); - - /* Connecting to ANY has been checked */ - if ( wd->sta.ssidLen == 0 ) - { - return ret; - } - - - switch(wd->sta.authMode) - //switch(wd->ws.authMode)//Quickly reboot - { - case ZM_AUTH_MODE_WPA_AUTO: - case ZM_AUTH_MODE_WPAPSK_AUTO: - encAlgoType = 0; - if(pBssInfo->rsnIe[1] != 0) - { - UnicastCipherNum = (pBssInfo->rsnIe[8]) + - (pBssInfo->rsnIe[9] << 8); - - /* If there is only one unicast cipher */ - if (UnicastCipherNum == 1) - { - encAlgoType = pBssInfo->rsnIe[13]; - //encAlgoType = pBssInfo->rsnIe[7]; - } - else - { - u16_t ii; - u16_t desiredCipher = 0; - u16_t IEOffSet = 13; - - /* Enumerate all the supported unicast cipher */ - for (ii = 0; ii < UnicastCipherNum; ii++) - { - if (pBssInfo->rsnIe[IEOffSet+ii*4] > desiredCipher) - { - desiredCipher = pBssInfo->rsnIe[IEOffSet+ii*4]; - } - } - - encAlgoType = desiredCipher; - } - - if ( encAlgoType == 0x02 ) - { - wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; - - if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO ) - { - wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2; - } - else //ZM_AUTH_MODE_WPAPSK_AUTO - { - wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK; - } - } - else if ( encAlgoType == 0x04 ) - { - wd->sta.wepStatus = ZM_ENCRYPTION_AES; - - if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO ) - { - wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2; - } - else //ZM_AUTH_MODE_WPAPSK_AUTO - { - wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK; - } - } - else - { - ret = FALSE; - } - } - else if(pBssInfo->wpaIe[1] != 0) - { - UnicastCipherNum = (pBssInfo->wpaIe[12]) + - (pBssInfo->wpaIe[13] << 8); - - /* If there is only one unicast cipher */ - if (UnicastCipherNum == 1) - { - encAlgoType = pBssInfo->wpaIe[17]; - //encAlgoType = pBssInfo->wpaIe[11]; - } - else - { - u16_t ii; - u16_t desiredCipher = 0; - u16_t IEOffSet = 17; - - /* Enumerate all the supported unicast cipher */ - for (ii = 0; ii < UnicastCipherNum; ii++) - { - if (pBssInfo->wpaIe[IEOffSet+ii*4] > desiredCipher) - { - desiredCipher = pBssInfo->wpaIe[IEOffSet+ii*4]; - } - } - - encAlgoType = desiredCipher; - } - - if ( encAlgoType == 0x02 ) - { - wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; - - if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO ) - { - wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA; - } - else //ZM_AUTH_MODE_WPAPSK_AUTO - { - wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK; - } - } - else if ( encAlgoType == 0x04 ) - { - wd->sta.wepStatus = ZM_ENCRYPTION_AES; - - if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO ) - { - wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA; - } - else //ZM_AUTH_MODE_WPAPSK_AUTO - { - wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK; - } - } - else - { - ret = FALSE; - } - - - } - else - { - ret = FALSE; - } - - break; - - case ZM_AUTH_MODE_WPA: - case ZM_AUTH_MODE_WPAPSK: - case ZM_AUTH_MODE_WPA_NONE: - case ZM_AUTH_MODE_WPA2: - case ZM_AUTH_MODE_WPA2PSK: - { - if ( pBssInfo->securityType != ZM_SECURITY_TYPE_WPA ) - { - ret = FALSE; - } - - ret = zfCheckWPAAuth(dev, pBssInfo); - } - break; - - case ZM_AUTH_MODE_OPEN: - case ZM_AUTH_MODE_SHARED_KEY: - case ZM_AUTH_MODE_AUTO: - { - if ( pBssInfo->wscIe[1] ) - { - // If the AP is a Jumpstart AP, it's ok!! Ray - break; - } - else if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA ) - { - ret = FALSE; - } - } - break; - - default: - break; - } - - return ret; -} - -u8_t zfStaIsConnected(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - - if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTED ) - { - return TRUE; - } - - return FALSE; -} - -u8_t zfStaIsConnecting(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - - if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTING ) - { - return TRUE; - } - - return FALSE; -} - -u8_t zfStaIsDisconnect(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - - if ( wd->sta.adapterState == ZM_STA_STATE_DISCONNECT ) - { - return TRUE; - } - - return FALSE; -} - -u8_t zfChangeAdapterState(zdev_t* dev, u8_t newState) -{ - u8_t ret = TRUE; - - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - //if ( newState == wd->sta.adapterState ) - //{ - // return FALSE; - //} - - switch(newState) - { - case ZM_STA_STATE_DISCONNECT: - zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_DISCONNECT); - - #if 1 - zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); - #else - if ( wd->sta.bChannelScan ) - { - /* stop the action of channel scanning */ - wd->sta.bChannelScan = FALSE; - ret = TRUE; - break; - } - #endif - - break; - case ZM_STA_STATE_CONNECTING: - #if 1 - zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); - #else - if ( wd->sta.bChannelScan ) - { - /* stop the action of channel scanning */ - wd->sta.bChannelScan = FALSE; - ret = TRUE; - break; - } - #endif - - break; - case ZM_STA_STATE_CONNECTED: - break; - default: - break; - } - - //if ( ret ) - //{ - zmw_enter_critical_section(dev); - wd->sta.adapterState = newState; - zmw_leave_critical_section(dev); - - zm_debug_msg1("change adapter state = ", newState); - //} - - return ret; -} - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaMmAddIeSsid */ -/* Add information element SSID to buffer. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* buf : buffer to add information element */ -/* offset : add information element from this offset */ -/* */ -/* OUTPUTS */ -/* buffer offset after adding information element */ -/* */ -/* AUTHOR */ -/* Ji-Huang Lee ZyDAS Technology Corporation 2005.11 */ -/* */ -/************************************************************************/ -u16_t zfStaAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset) -{ - u16_t i; - - zmw_get_wlan_dev(dev); - - /* Element ID */ - zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID); - - /* Element Length */ - zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssidLen); - - /* Information : SSID */ - for (i=0; i<wd->sta.ssidLen; i++) - { - zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssid[i]); - } - - return offset; -} - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaMmAddIeWpa */ -/* Add information element SSID to buffer. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* buf : buffer to add information element */ -/* offset : add information element from this offset */ -/* */ -/* OUTPUTS */ -/* buffer offset after adding information element */ -/* */ -/* AUTHOR */ -/* Ji-Huang Lee ZyDAS Technology Corporation 2006.01 */ -/* */ -/************************************************************************/ -u16_t zfStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType) -{ - u32_t i; - u8_t ssn[64]={ - /* Element ID */ - 0xdd, - /* Length */ - 0x18, - /* OUI type */ - 0x00, 0x50, 0xf2, 0x01, - /* Version */ - 0x01, 0x00, - /* Group Cipher Suite, default=TKIP */ - 0x00, 0x50, 0xf2, 0x02, - /* Pairwise Cipher Suite Count */ - 0x01, 0x00, - /* Pairwise Cipher Suite, default=TKIP */ - 0x00, 0x50, 0xf2, 0x02, - /* Authentication and Key Management Suite Count */ - 0x01, 0x00, - /* Authentication type, default=PSK */ - 0x00, 0x50, 0xf2, 0x02, - /* WPA capability */ - 0x00, 0x00 - }; - - u8_t rsn[64]={ - /* Element ID */ - 0x30, - /* Length */ - 0x14, - /* Version */ - 0x01, 0x00, - /* Group Cipher Suite, default=TKIP */ - 0x00, 0x0f, 0xac, 0x02, - /* Pairwise Cipher Suite Count */ - 0x01, 0x00, - /* Pairwise Cipher Suite, default=TKIP */ - 0x00, 0x0f, 0xac, 0x02, - /* Authentication and Key Management Suite Count */ - 0x01, 0x00, - /* Authentication type, default=PSK */ - 0x00, 0x0f, 0xac, 0x02, - /* RSN capability */ - 0x00, 0x00 - }; - - zmw_get_wlan_dev(dev); - - if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPAPSK ) - { - /* Overwrite Group Cipher Suite by AP's setting */ - zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4); - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) - { - /* Overwrite Pairwise Cipher Suite by AES */ - zfMemoryCopy(ssn+14, zgWpaAesOui, 4); - } - - zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2); - zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2); - offset += (ssn[1]+2); - } - else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA ) - { - /* Overwrite Group Cipher Suite by AP's setting */ - zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4); - /* Overwrite Key Management Suite by WPA-Radius */ - zfMemoryCopy(ssn+20, zgWpaRadiusOui, 4); - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) - { - /* Overwrite Pairwise Cipher Suite by AES */ - zfMemoryCopy(ssn+14, zgWpaAesOui, 4); - } - - zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2); - zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2); - offset += (ssn[1]+2); - } - else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2PSK ) - { - /* Overwrite Group Cipher Suite by AP's setting */ - zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4); - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) - { - /* Overwrite Pairwise Cipher Suite by AES */ - zfMemoryCopy(rsn+10, zgWpa2AesOui, 4); - } - - if ( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ ) - { - for(i=0; i<wd->sta.pmkidInfo.bssidCount; i++) - { - if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid, - (u8_t*) wd->sta.bssid, 6) ) - { - /* matched */ - break; - } - - if ( i < wd->sta.pmkidInfo.bssidCount ) - { - // Fill PMKID Count in RSN information element - rsn[22] = 0x01; - rsn[23] = 0x00; - - // Fill PMKID in RSN information element - zfMemoryCopy(rsn+24, - wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16); - rsn[1] += 18; - } - } - } - - zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2); - zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2); - offset += (rsn[1]+2); - } - else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2 ) - { - /* Overwrite Group Cipher Suite by AP's setting */ - zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4); - /* Overwrite Key Management Suite by WPA2-Radius */ - zfMemoryCopy(rsn+16, zgWpa2RadiusOui, 4); - - if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) - { - /* Overwrite Pairwise Cipher Suite by AES */ - zfMemoryCopy(rsn+10, zgWpa2AesOui, 4); - } - - if (( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ || ( frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ ))) - { - - if (wd->sta.pmkidInfo.bssidCount != 0) { - // Fill PMKID Count in RSN information element - rsn[22] = 1; - rsn[23] = 0; - /* - * The caller is respnsible to give us the relevant PMKID. - * We'll only accept 1 PMKID for now. - */ - for(i=0; i<wd->sta.pmkidInfo.bssidCount; i++) - { - if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid, (u8_t*) wd->sta.bssid, 6) ) - { - zfMemoryCopy(rsn+24, wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16); - break; - } - } - rsn[1] += 18; - } - - } - - zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2); - zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2); - offset += (rsn[1]+2); - } - - return offset; -} - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaAddIeIbss */ -/* Add information element IBSS parameter to buffer. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* buf : buffer to add information element */ -/* offset : add information element from this offset */ -/* */ -/* OUTPUTS */ -/* buffer offset after adding information element */ -/* */ -/* AUTHOR */ -/* Ji-Huang Lee ZyDAS Technology Corporation 2005.12 */ -/* */ -/************************************************************************/ -u16_t zfStaAddIeIbss(zdev_t* dev, zbuf_t* buf, u16_t offset) -{ - zmw_get_wlan_dev(dev); - - /* Element ID */ - zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_IBSS); - - /* Element Length */ - zmw_tx_buf_writeb(dev, buf, offset++, 2); - - /* ATIM window */ - zmw_tx_buf_writeh(dev, buf, offset, wd->sta.atimWindow); - offset += 2; - - return offset; -} - - - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaAddIeWmeInfo */ -/* Add WME Information Element to buffer. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* buf : buffer to add information element */ -/* offset : add information element from this offset */ -/* */ -/* OUTPUTS */ -/* buffer offset after adding information element */ -/* */ -/* AUTHOR */ -/* Stephen Chen ZyDAS Technology Corporation 2006.6 */ -/* */ -/************************************************************************/ -u16_t zfStaAddIeWmeInfo(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t qosInfo) -{ - /* Element ID */ - zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE); - - /* Element Length */ - zmw_tx_buf_writeb(dev, buf, offset++, 7); - - /* OUI */ - zmw_tx_buf_writeb(dev, buf, offset++, 0x00); - zmw_tx_buf_writeb(dev, buf, offset++, 0x50); - zmw_tx_buf_writeb(dev, buf, offset++, 0xF2); - zmw_tx_buf_writeb(dev, buf, offset++, 0x02); - zmw_tx_buf_writeb(dev, buf, offset++, 0x00); - zmw_tx_buf_writeb(dev, buf, offset++, 0x01); - - /* QoS Info */ - zmw_tx_buf_writeb(dev, buf, offset++, qosInfo); - - return offset; -} - -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaAddIePowerCap */ -/* Add information element Power capability to buffer. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* buf : buffer to add information element */ -/* offset : add information element from this offset */ -/* */ -/* OUTPUTS */ -/* buffer offset after adding information element */ -/* */ -/* AUTHOR */ -/* Sharon 2007.12 */ -/* */ -/************************************************************************/ -u16_t zfStaAddIePowerCap(zdev_t* dev, zbuf_t* buf, u16_t offset) -{ - u8_t MaxTxPower; - u8_t MinTxPower; - - /* Element ID */ - zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY); - - /* Element Length */ - zmw_tx_buf_writeb(dev, buf, offset++, 2); - - MinTxPower = (u8_t)(zfHpGetMinTxPower(dev)/2); - MaxTxPower = (u8_t)(zfHpGetMaxTxPower(dev)/2); - - /* Min Transmit Power Cap */ - zmw_tx_buf_writeh(dev, buf, offset++, MinTxPower); - - /* Max Transmit Power Cap */ - zmw_tx_buf_writeh(dev, buf, offset++, MaxTxPower); - - return offset; -} -/************************************************************************/ -/* */ -/* FUNCTION DESCRIPTION zfStaAddIeSupportCh */ -/* Add information element supported channels to buffer. */ -/* */ -/* INPUTS */ -/* dev : device pointer */ -/* buf : buffer to add information element */ -/* offset : add information element from this offset */ -/* */ -/* OUTPUTS */ -/* buffer offset after adding information element */ -/* */ -/* AUTHOR */ -/* Sharon 2007.12 */ -/* */ -/************************************************************************/ -u16_t zfStaAddIeSupportCh(zdev_t* dev, zbuf_t* buf, u16_t offset) -{ - - u8_t i; - u16_t count_24G = 0; - u16_t count_5G = 0; - u16_t channelNum; - u8_t length; - - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - zmw_enter_critical_section(dev); - - for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) - { - if (wd->regulationTable.allowChannel[i].channel < 3000) - { // 2.4Hz - count_24G++; - } - else - { // 5GHz - count_5G++; - } - } - - length = (u8_t)(count_5G * 2 + 2); //5G fill by pair, 2,4G (continuous channels) fill 2 bytes - - /* Element ID */ - zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SUPPORTED_CHANNELS ); - - /* Element Length */ - zmw_tx_buf_writeb(dev, buf, offset++, length); - - // 2.4GHz (continuous channels) - /* First channel number */ - zmw_tx_buf_writeh(dev, buf, offset++, 1); //Start from channle 1 - /* Number of channels */ - zmw_tx_buf_writeh(dev, buf, offset++, count_24G); - - for (i = 0; i < wd->regulationTable.allowChannelCnt ; i++) - { - if (wd->regulationTable.allowChannel[i].channel > 4000 && wd->regulationTable.allowChannel[i].channel < 5000) - { // 5GHz 4000 -5000Mhz - channelNum = (wd->regulationTable.allowChannel[i].channel-4000)/5; - /* First channel number */ - zmw_tx_buf_writeh(dev, buf, offset++, channelNum); - /* Number of channels */ - zmw_tx_buf_writeh(dev, buf, offset++, 1); - } - else if (wd->regulationTable.allowChannel[i].channel >= 5000) - { // 5GHz >5000Mhz - channelNum = (wd->regulationTable.allowChannel[i].channel-5000)/5; - /* First channel number */ - zmw_tx_buf_writeh(dev, buf, offset++, channelNum); - /* Number of channels */ - zmw_tx_buf_writeh(dev, buf, offset++, 1); - } - } - zmw_leave_critical_section(dev); - - return offset; -} - -void zfStaStartConnectCb(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - - zfStaStartConnect(dev, wd->sta.bIsSharedKey); -} - -void zfStaStartConnect(zdev_t* dev, u8_t bIsSharedKey) -{ - u32_t p1, p2; - u8_t newConnState; - - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - /* p1_low = algorithm number, p1_high = transaction sequence number */ - if ( bIsSharedKey ) - { - //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_1; - newConnState = ZM_STA_CONN_STATE_AUTH_SHARE_1; - zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_SHARE_1"); - p1 = ZM_AUTH_ALGO_SHARED_KEY; - } - else - { - //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_OPEN; - newConnState = ZM_STA_CONN_STATE_AUTH_OPEN; - zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_OPEN"); - if( wd->sta.leapEnabled ) - p1 = ZM_AUTH_ALGO_LEAP; - else - p1 = ZM_AUTH_ALGO_OPEN_SYSTEM; - } - - /* status code */ - p2 = 0x0; - - zmw_enter_critical_section(dev); - wd->sta.connectTimer = wd->tick; - wd->sta.connectState = newConnState; - zmw_leave_critical_section(dev); - - /* send the 1st authentication frame */ - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, wd->sta.bssid, p1, p2, 0); - - return; -} - -void zfSendNullData(zdev_t* dev, u8_t type) -{ - zbuf_t* buf; - //u16_t addrTblSize; - //struct zsAddrTbl addrTbl; - u16_t err; - u16_t hlen; - u16_t header[(34+8+1)/2]; - u16_t bcastAddr[3] = {0xffff,0xffff,0xffff}; - u16_t *dstAddr; - - zmw_get_wlan_dev(dev); - - buf = zfwBufAllocate(dev, 1024); - if (buf == NULL) - { - zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); - return; - } - - zfwBufSetSize(dev, buf, 0); - - //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len); - - if ( wd->wlanMode == ZM_MODE_IBSS) - { - dstAddr = bcastAddr; - } - else - { - dstAddr = wd->sta.bssid; - } - - if (wd->sta.wmeConnected != 0) - { - /* If connect to a WMM AP, Send QoS Null data */ - hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_QOS_NULL, dstAddr, header, 0, buf, 0, 0); - } - else - { - hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_NULL, dstAddr, header, 0, buf, 0, 0); - } - - if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) - { - header[4] |= 0x0100; //TODS bit - } - - if ( type == 1 ) - { - header[4] |= 0x1000; - } - - /* Get buffer DMA address */ - //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) - //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) - //{ - // goto zlError; - //} - - /*increase unicast frame counter*/ - wd->commTally.txUnicastFrm++; - - err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff); - if (err != ZM_SUCCESS) - { - goto zlError; - } - - - return; - -zlError: - - zfwBufFree(dev, buf, 0); - return; - -} - -void zfSendPSPoll(zdev_t* dev) -{ - zbuf_t* buf; - //u16_t addrTblSize; - //struct zsAddrTbl addrTbl; - u16_t err; - u16_t hlen; - u16_t header[(8+24+1)/2]; - - zmw_get_wlan_dev(dev); - - buf = zfwBufAllocate(dev, 1024); - if (buf == NULL) - { - zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); - return; - } - - zfwBufSetSize(dev, buf, 0); - - //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len); - - zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_PSPOLL, wd->sta.bssid, header, 0, buf, 0, 0); - - header[0] = 20; - header[4] |= 0x1000; - header[5] = wd->sta.aid | 0xc000; //Both bit-14 and bit-15 are 1 - hlen = 16 + 8; - - /* Get buffer DMA address */ - //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) - //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) - //{ - // goto zlError; - //} - - err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff); - if (err != ZM_SUCCESS) - { - goto zlError; - } - - return; - -zlError: - - zfwBufFree(dev, buf, 0); - return; - -} - -void zfSendBA(zdev_t* dev, u16_t start_seq, u8_t *bitmap) -{ - zbuf_t* buf; - //u16_t addrTblSize; - //struct zsAddrTbl addrTbl; - u16_t err; - u16_t hlen; - u16_t header[(8+24+1)/2]; - u16_t i, offset = 0; - - zmw_get_wlan_dev(dev); - - buf = zfwBufAllocate(dev, 1024); - if (buf == NULL) - { - zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); - return; - } - - zfwBufSetSize(dev, buf, 12); // 28 = FC 2 + DU 2 + RA 6 + TA 6 + BAC 2 + SEQ 2 + BitMap 8 - // 12 = BAC 2 + SEQ 2 + BitMap 8 - - //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len); - - zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_BA, wd->sta.bssid, header, 0, buf, 0, 0); - - header[0] = 32; /* MAC header 16 + BA control 2 + BA info 10 + FCS 4*/ - header[1] = 0x4; /* No ACK */ - - /* send by OFDM 6M */ - header[2] = (u16_t)(zcRateToPhyCtrl[4] & 0xffff); - header[3] = (u16_t)(zcRateToPhyCtrl[4]>>16) & 0xffff; - - hlen = 16 + 8; /* MAC header 16 + control 8*/ - offset = 0; - zmw_tx_buf_writeh(dev, buf, offset, 0x05); /*compressed bitmap on*/ - offset+=2; - zmw_tx_buf_writeh(dev, buf, offset, start_seq); - offset+=2; - - for (i=0; i<8; i++) { - zmw_tx_buf_writeb(dev, buf, offset, bitmap[i]); - offset++; - } - - err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff); - if (err != ZM_SUCCESS) - { - goto zlError; - } - - return; - -zlError: - - zfwBufFree(dev, buf, 0); - return; - -} - -void zfStaGetTxRate(zdev_t* dev, u16_t* macAddr, u32_t* phyCtrl, - u16_t* rcProbingFlag) -{ - u8_t addr[6], i; - u8_t rate; - zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); - - ZM_MAC_WORD_TO_BYTE(macAddr, addr); - *phyCtrl = 0; - - if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) - { - zmw_enter_critical_section(dev); - rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[0].rcCell, rcProbingFlag); -//#ifdef ZM_FB50 - //rate = 27; -//#endif - *phyCtrl = zcRateToPhyCtrl[rate]; - zmw_leave_critical_section(dev); - } - else - { - zmw_enter_critical_section(dev); - for(i=0; i<wd->sta.oppositeCount; i++) - { - if ( addr[0] && 0x01 == 1 ) // The default beacon transmitted rate is CCK and 1 Mbps , but the a mode should use - // OFDM modulation and 6Mbps to transmit beacon. - { - //rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag); - rate = wd->sta.oppositeInfo[i].rcCell.operationRateSet[0]; - *phyCtrl = zcRateToPhyCtrl[rate]; - break; - } - else if ( zfMemoryIsEqual(addr, wd->sta.oppositeInfo[i].macAddr, 6) ) - { - rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag); - *phyCtrl = zcRateToPhyCtrl[rate]; - break; - } - } - zmw_leave_critical_section(dev); - } - - return; -} - -struct zsMicVar* zfStaGetRxMicKey(zdev_t* dev, zbuf_t* buf) -{ - u8_t keyIndex; - u8_t da0; - - zmw_get_wlan_dev(dev); - - /* if need not check MIC, return NULL */ - if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))|| - (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) ) - { - return NULL; - } - - da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); - - if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80) - keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/ - else - keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/ - keyIndex = (keyIndex & 0xc0) >> 6; - - return (&wd->sta.rxMicKey[keyIndex]); -} - -struct zsMicVar* zfStaGetTxMicKey(zdev_t* dev, zbuf_t* buf) -{ - zmw_get_wlan_dev(dev); - - /* if need not check MIC, return NULL */ - //if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))|| - // (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) ) - if ( (wd->sta.encryMode != ZM_TKIP) || (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) ) - { - return NULL; - } - - return (&wd->sta.txMicKey); -} - -u16_t zfStaRxValidateFrame(zdev_t* dev, zbuf_t* buf) -{ - u8_t frameType, frameCtrl; - u8_t da0; - //u16_t sa[3]; - u16_t ret; - //u8_t sa0; - - zmw_get_wlan_dev(dev); - - frameType = zmw_rx_buf_readb(dev, buf, 0); - da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); - //sa0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); - - if ( (!zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) ) - { - return ZM_ERR_DATA_BEFORE_CONNECTED; - } - - - if ( (zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) ) - { - /* check BSSID */ - if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) - { - /* Big Endian and Little Endian Compatibility */ - u16_t mac[3]; - mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]); - mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]); - mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]); - if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac, - ZM_WLAN_HEADER_A2_OFFSET, 6) ) - { -/*We will get lots of garbage data, especially in AES mode.*/ -/*To avoid sending too many deauthentication frames in STA mode, mark it.*/ -#if 0 - /* If unicast frame, send deauth to the transmitter */ - if (( da0 & 0x01 ) == 0) - { - for (i=0; i<3; i++) - { - sa[i] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+(i*2)); - } - /* If mutilcast address, don't send deauthentication*/ - if (( sa0 & 0x01 ) == 0) - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, sa, 7, 0, 0); - } -#endif - return ZM_ERR_DATA_BSSID_NOT_MATCHED; - } - } - else if ( wd->wlanMode == ZM_MODE_IBSS ) - { - /* Big Endian and Little Endian Compatibility */ - u16_t mac[3]; - mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]); - mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]); - mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]); - if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac, - ZM_WLAN_HEADER_A3_OFFSET, 6) ) - { - return ZM_ERR_DATA_BSSID_NOT_MATCHED; - } - } - - frameCtrl = zmw_rx_buf_readb(dev, buf, 1); - - /* check security bit */ - if ( wd->sta.dropUnencryptedPkts && - (wd->sta.wepStatus != ZM_ENCRYPTION_WEP_DISABLED )&& - ( !(frameCtrl & ZM_BIT_6) ) ) - { /* security on, but got data without encryption */ - - #if 1 - ret = ZM_ERR_DATA_NOT_ENCRYPTED; - if ( wd->sta.pStaRxSecurityCheckCb != NULL ) - { - ret = wd->sta.pStaRxSecurityCheckCb(dev, buf); - } - else - { - ret = ZM_ERR_DATA_NOT_ENCRYPTED; - } - if (ret == ZM_ERR_DATA_NOT_ENCRYPTED) - { - wd->commTally.swRxDropUnencryptedCount++; - } - return ret; - #else - if ( (wd->sta.wepStatus != ZM_ENCRYPTION_TKIP)&& - (wd->sta.wepStatus != ZM_ENCRYPTION_AES) ) - { - return ZM_ERR_DATA_NOT_ENCRYPTED; - } - #endif - } - } - - return ZM_SUCCESS; -} - -void zfStaMicFailureHandling(zdev_t* dev, zbuf_t* buf) -{ - u8_t da0; - u8_t micNotify = 1; - - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - if ( wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK ) - { - return; - } - - zmw_enter_critical_section(dev); - - wd->sta.cmMicFailureCount++; - - if ( wd->sta.cmMicFailureCount == 1 ) - { - zm_debug_msg0("get the first MIC failure"); - //zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT); - - /* Timer Resolution on WinXP is 15/16 ms */ - /* Decrease Time offset for <XP> Counter Measure */ - zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT - ZM_TICK_CM_TIMEOUT_OFFSET); - } - else if ( wd->sta.cmMicFailureCount == 2 ) - { - zm_debug_msg0("get the second MIC failure"); - /* reserve 2 second for OS to send MIC failure report to AP */ - wd->sta.cmDisallowSsidLength = wd->sta.ssidLen; - zfMemoryCopy(wd->sta.cmDisallowSsid, wd->sta.ssid, wd->sta.ssidLen); - //wd->sta.cmMicFailureCount = 0; - zfTimerCancel(dev, ZM_EVENT_CM_TIMER); - //zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT); - - /* Timer Resolution on WinXP is 15/16 ms */ - /* Decrease Time offset for <XP> Counter Measure */ - zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT - ZM_TICK_CM_DISCONNECT_OFFSET); - } - else - { - micNotify = 0; - } - - zmw_leave_critical_section(dev); - - if (micNotify == 1) - { - da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); - if ( da0 & 0x01 ) - { - if (wd->zfcbMicFailureNotify != NULL) - { - wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_GROUP_ERROR); - } - } - else - { - if (wd->zfcbMicFailureNotify != NULL) - { - wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_PAIRWISE_ERROR); - } - } - } -} - - -u8_t zfStaBlockWlanScan(zdev_t* dev) -{ - u8_t ret=FALSE; - - zmw_get_wlan_dev(dev); - - if ( wd->sta.bChannelScan ) - { - return TRUE; - } - - return ret; -} - -void zfStaResetStatus(zdev_t* dev, u8_t bInit) -{ - u8_t i; - - zmw_get_wlan_dev(dev); - - zfHpDisableBeacon(dev); - - wd->dtim = 1; - wd->sta.capability[0] = 0x01; - wd->sta.capability[1] = 0x00; - /* 802.11h */ - if (wd->sta.DFSEnable || wd->sta.TPCEnable) - wd->sta.capability[1] |= ZM_BIT_0; - - /* release queued packets */ - for(i=0; i<wd->sta.ibssPSDataCount; i++) - { - zfwBufFree(dev, wd->sta.ibssPSDataQueue[i], 0); - } - - for(i=0; i<wd->sta.staPSDataCount; i++) - { - zfwBufFree(dev, wd->sta.staPSDataQueue[i], 0); - } - - wd->sta.ibssPSDataCount = 0; - wd->sta.staPSDataCount = 0; - zfZeroMemory((u8_t*) &wd->sta.staPSList, sizeof(struct zsStaPSList)); - - wd->sta.wmeConnected = 0; - wd->sta.psMgr.tempWakeUp = 0; - wd->sta.qosInfo = 0; - zfQueueFlush(dev, wd->sta.uapsdQ); - - return; - -} - -void zfStaIbssMonitoring(zdev_t* dev, u8_t reset) -{ - u16_t i; - u16_t oppositeCount; - struct zsPartnerNotifyEvent event; - - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - //zm_debug_msg1("zfStaIbssMonitoring %d", wd->sta.oppositeCount); - - zmw_enter_critical_section(dev); - - if ( wd->sta.oppositeCount == 0 ) - { - goto done; - } - - if ( wd->sta.bChannelScan ) - { - goto done; - } - - oppositeCount = wd->sta.oppositeCount; - - for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) - { - if ( oppositeCount == 0 ) - { - break; - } - - if ( reset ) - { - wd->sta.oppositeInfo[i].valid = 0; - } - - if ( wd->sta.oppositeInfo[i].valid == 0 ) - { - continue; - } - - oppositeCount--; - - if ( wd->sta.oppositeInfo[i].aliveCounter ) - { - zm_debug_msg1("Setting alive to ", wd->sta.oppositeInfo[i].aliveCounter); - - zmw_leave_critical_section(dev); - - if ( wd->sta.oppositeInfo[i].aliveCounter != ZM_IBSS_PEER_ALIVE_COUNTER ) - { - zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, - (u16_t*)wd->sta.oppositeInfo[i].macAddr, 1, 0, 0); - } - - zmw_enter_critical_section(dev); - wd->sta.oppositeInfo[i].aliveCounter--; - } - else - { - zm_debug_msg0("zfStaIbssMonitoring remove the peer station"); - zfMemoryCopy(event.bssid, (u8_t *)(wd->sta.bssid), 6); - zfMemoryCopy(event.peerMacAddr, wd->sta.oppositeInfo[i].macAddr, 6); - - wd->sta.oppositeInfo[i].valid = 0; - wd->sta.oppositeCount--; - if (wd->zfcbIbssPartnerNotify != NULL) - { - zmw_leave_critical_section(dev); - wd->zfcbIbssPartnerNotify(dev, 0, &event); - zmw_enter_critical_section(dev); - } - } - } - -done: - if ( reset == 0 ) - { - zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR); - } - - zmw_leave_critical_section(dev); -} - -void zfInitPartnerNotifyEvent(zdev_t* dev, zbuf_t* buf, struct zsPartnerNotifyEvent *event) -{ - u16_t *peerMacAddr; - - zmw_get_wlan_dev(dev); - - peerMacAddr = (u16_t *)event->peerMacAddr; - - zfMemoryCopy(event->bssid, (u8_t *)(wd->sta.bssid), 6); - peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); - peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 2); - peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 4); -} - -void zfStaInitOppositeInfo(zdev_t* dev) -{ - int i; - - zmw_get_wlan_dev(dev); - - for(i=0; i<ZM_MAX_OPPOSITE_COUNT; i++) - { - wd->sta.oppositeInfo[i].valid = 0; - wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER; - } -} -#ifdef ZM_ENABLE_CENC -u16_t zfStaAddIeCenc(zdev_t* dev, zbuf_t* buf, u16_t offset) -{ - zmw_get_wlan_dev(dev); - - if (wd->sta.cencIe[1] != 0) - { - zfCopyToIntTxBuffer(dev, buf, wd->sta.cencIe, offset, wd->sta.cencIe[1]+2); - offset += (wd->sta.cencIe[1]+2); - } - return offset; -} -#endif //ZM_ENABLE_CENC -u16_t zfStaProcessAction(zdev_t* dev, zbuf_t* buf) -{ - u8_t category, actionDetails; - zmw_get_wlan_dev(dev); - - category = zmw_rx_buf_readb(dev, buf, 24); - actionDetails = zmw_rx_buf_readb(dev, buf, 25); - switch (category) - { - case 0: //Spectrum Management - switch(actionDetails) - { - case 0: //Measurement Request - break; - case 1: //Measurement Report - //ProcessActionSpectrumFrame_MeasurementReport(Adapter,pActionBody+3); - break; - case 2: //TPC request - //if (wd->sta.TPCEnable) - // zfStaUpdateDot11HTPC(dev, buf); - break; - case 3: //TPC report - //if (wd->sta.TPCEnable) - // zfStaUpdateDot11HTPC(dev, buf); - break; - case 4: //Channel Switch Announcement - if (wd->sta.DFSEnable) - zfStaUpdateDot11HDFS(dev, buf); - break; - default: - zm_debug_msg1("Action Frame contain not support action field ", actionDetails); - break; - } - break; - case ZM_WLAN_BLOCK_ACK_ACTION_FRAME: - zfAggBlockAckActionFrame(dev, buf); - break; - case 17: //Qos Management - break; - } - - return 0; -} - -/* Determine the time not send beacon , if more than some value , - re-write the beacon start address */ -void zfReWriteBeaconStartAddress(zdev_t* dev) -{ - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - zmw_enter_critical_section(dev); - wd->tickIbssSendBeacon++; // Increase 1 per 10ms . - zmw_leave_critical_section(dev); - - if ( wd->tickIbssSendBeacon == 40 ) - { -// DbgPrint("20070727"); - zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow); - zmw_enter_critical_section(dev); - wd->tickIbssSendBeacon = 0; - zmw_leave_critical_section(dev); - } -} - -struct zsTkipSeed* zfStaGetRxSeed(zdev_t* dev, zbuf_t* buf) -{ - u8_t keyIndex; - u8_t da0; - - zmw_get_wlan_dev(dev); - - /* if need not check MIC, return NULL */ - if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))|| - (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) ) - { - return NULL; - } - - da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); - - if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80) - keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/ - else - keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/ - keyIndex = (keyIndex & 0xc0) >> 6; - - return (&wd->sta.rxSeed[keyIndex]); -} - -void zfStaEnableSWEncryption(zdev_t *dev, u8_t value) -{ - zmw_get_wlan_dev(dev); - - wd->sta.SWEncryptEnable = value; - zfHpSWDecrypt(dev, 1); - zfHpSWEncrypt(dev, 1); -} - -void zfStaDisableSWEncryption(zdev_t *dev) -{ - zmw_get_wlan_dev(dev); - - wd->sta.SWEncryptEnable = 0; - zfHpSWDecrypt(dev, 0); - zfHpSWEncrypt(dev, 0); -} - -u16_t zfComputeBssInfoWeightValue(zdev_t *dev, u8_t isBMode, u8_t isHT, u8_t isHT40, u8_t signalStrength) -{ - u8_t weightOfB = 0; - u8_t weightOfAGBelowThr = 0; - u8_t weightOfAGUpThr = 15; - u8_t weightOfN20BelowThr = 15; - u8_t weightOfN20UpThr = 30; - u8_t weightOfN40BelowThr = 16; - u8_t weightOfN40UpThr = 32; - - if( isBMode == 0 ) - return (signalStrength + weightOfB); // pure b mode , do not add the weight value for this AP ! - else - { - if( isHT == 0 && isHT40 == 0 ) - { // a , g , b/g mode ! add the weight value 15 for this AP if it's signal strength is more than some value ! - if( signalStrength < 18 ) // -77 dBm - return signalStrength + weightOfAGBelowThr; - else - return (signalStrength + weightOfAGUpThr); - } - else if( isHT == 1 && isHT40 == 0 ) - { // 80211n mode use 20MHz - if( signalStrength < 23 ) // -72 dBm - return (signalStrength + weightOfN20BelowThr); - else - return (signalStrength + weightOfN20UpThr); - } - else // isHT == 1 && isHT40 == 1 - { // 80211n mode use 40MHz - if( signalStrength < 16 ) // -79 dBm - return (signalStrength + weightOfN40BelowThr); - else - return (signalStrength + weightOfN40UpThr); - } - } -} - -u16_t zfStaAddIbssAdditionalIE(zdev_t* dev, zbuf_t* buf, u16_t offset) -{ - u16_t i; - - zmw_get_wlan_dev(dev); - - for (i=0; i<wd->sta.ibssAdditionalIESize; i++) - { - zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ibssAdditionalIE[i]); - } - - return offset; -} |