📄 wlan_ccx.c
字号:
* @param enableCcxPwrLimit boolean CCX transmit power control * @return number of bytes added to the assoc. request */ int wlan_ccx_process_association_req(u8** ppAssocBuf, CCX_BSS_Info_t* pCcxBssInfo, WPA_SUPPLICANT* pWpaInfo, UCHAR *timestamp, int enableCcxPwrLimit){ u8* pBufSav; u16 passThroughLen = 0; MrvlIEtypesHeader_t ieHeader; UCHAR minPower; UCHAR maxPower; DBGPRINT(DBG_CCX, ("CCX: process assoc req: ccxEnabled: %d, enableCcxPwrLimit: %d\n", pCcxBssInfo->ccxEnabled, enableCcxPwrLimit)); pCcxAdapter->isCiscoAP = FALSE; /* Null checks */ if (ppAssocBuf == 0) return 0; if (*ppAssocBuf == 0) return 0; if (pCcxBssInfo == 0) return 0; /* ** Return immediately if CCX support isn't required by this specific AP ** we are attempting to associate with. Flag set during scan result ** processing. */ if (pCcxBssInfo->ccxEnabled == FALSE) { return 0; } pCcxAdapter->isCiscoAP = TRUE; /* Save off the original buffer pointer */ pBufSav = *ppAssocBuf; /* Increment the buffer pointer by the size of the Marvell TLV header. ** Skip past the buffer space for the header to append the CCX version ** IE. When we get the size of the version IE, then append the ** marvell TLV header with the appropriate size */ *ppAssocBuf += sizeof(MrvlIEtypesHeader_t); /* ** Append the version IE to the association buffer. passThroughLen holds ** the amount of data inserted (used for the passthrough TLV header len */ passThroughLen += append_ccx_version_ie(ppAssocBuf); /* ** Append the TLV Header to the saved buffer pointer (insert it before ** the version IE that was just appended). Set the TLV ID to the ** PASSTHROUGH type and encode the length as the size of the version IE ** previously added. */#ifdef CCX passThroughLen += append_ccx_aironet_ie(ppAssocBuf);#if 1 // WPA supplicant if ((pWpaInfo!=NULL) && (pWpaInfo->Wpa_ie_len)) { int len = pWpaInfo->Wpa_ie[1] ; if ( len == 24 ) {// DBGPRINT(DBG_CCX, ("ASSO_EXT: change to WPA 22\n")); pWpaInfo->Wpa_ie[1] = 22; len = 22; } len += 2; memcpy(*ppAssocBuf, (u8*)&(pWpaInfo->Wpa_ie[0]), len); *ppAssocBuf += len; passThroughLen += len; }#endif#endif ieHeader.Type = TLV_TYPE_PASSTHROUGH; ieHeader.Len = passThroughLen; memcpy(pBufSav, &ieHeader, sizeof(ieHeader));#ifdef CCX_CCKM // Implement for CCKM if (pCcxBssInfo->cckmEnabled == TRUE) { DBGPRINT(DBG_CCX, ("[wlan_ccx_process_assoc_req] cckmEnabled\n")); if ( ccxCCKMState == CCX_CCKM_START ) { wlan_ccx_cckmStart(timestamp); return -1; } else { //DBGPRINT(DBG_CCX, ("[wlan_ccx_process_assoc_req] CCX_CCKM_REQUEST: IE length=%d\n", ccxAssociationRequestIELength)); if ( ccxAssociationRequestIELength > 0 ) { DBGPRINT(DBG_CCX, ("[wlan_ccx_process_assoc_req] copy ccxAssociationRequestIE, len=%d\n", ccxAssociationRequestIELength)); NdisMoveMemory(*ppAssocBuf, ccxAssociationRequestIE, ccxAssociationRequestIELength); *ppAssocBuf += ccxAssociationRequestIELength; } } }#endif#ifdef CCX_TPC /* ** If a CCX power IE was sensed in the scan response, and CCX Power ** limiting is enabled (i.e. no AP 11h support), add a power capability ** TLV to the association request setting the max power to the AP ** specified maximum */ DBGPRINT(DBG_CCX, ("CCX: maxPowerValid=%x, enableCcxPwrLimit=%x\n", pCcxBssInfo->maxPowerValid, enableCcxPwrLimit)); if (pCcxBssInfo->maxPowerValid && enableCcxPwrLimit) { minPower = CCX_TPC_MinPowerValue; maxPower = pCcxBssInfo->maxPower; if ( maxPower < minPower ) maxPower = minPower; if ( maxPower > CCX_TPC_MaxPowerValue ) maxPower = CCX_TPC_MaxPowerValue; ifNeedTPC = 1; ccxTPCMaxPower = maxPower; ccxTPCMinPower = minPower; // Looks like it doesn't need power capability for CCX TPC //passThroughLen = append_mrvl_power_capability(ppAssocBuf, minPower, maxPower); //ccx_set_txpower(minPower, maxPower); } else { ifNeedTPC = 0; }#endif /* Return the length we've appended to the buffer */// DBGPRINT(DBG_CCX, ("[wlan_ccx_proc_asoc_req] return size=%d\n", (*ppAssocBuf-pBufSav))); return (*ppAssocBuf - pBufSav);}/** * @brief This function processes an element in a description * * @param pCcxBssInfo CCX information * @param pBssElem BSS IE for CCX relevance evaluation * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE */int wlan_ccx_process_bss_elem(CCX_BSS_Info_t* pCcxBssInfo, u8* pBssElem){ CCX_IE_Version_t* pVersionIe; CCX_IE_Cell_Power_Limit_t* pCellPowerIe; CCX_IE_OUI_Hdr_t* pOuiHdr = (CCX_IE_OUI_Hdr_t*)pBssElem; int enableBssCcxExt = FALSE; // DBGPRINT(DBG_CCX, ("CCX: process bss element: %d (0x%x)\n", // pOuiHdr->elemId, pOuiHdr->elemId)); /* ** Switch statement based on the element ID encoded in the Header */ switch (pOuiHdr->elemId) { case VENDOR_SPECIFIC_221: /* ** Vendor Specific Element ID 221 passes information for a variety ** of protocols. The CCX elements are identified by the Cisco ** OUI (0x004096), check for it and then the OUI Type to correctly ** parse a CCX Element */ if (NdisEqualMemory(pOuiHdr->oui, cisco_oui, sizeof(cisco_oui)) == 1) { /* Flag the presence of CCX elements */ enableBssCcxExt = TRUE; switch (pOuiHdr->ouiType) { case CCX_OUI_TYPE_VERSION: /* ** CCX Version IE, just identify it for now. May need ** to customize the CCX behavior in the driver and ** supplicant based on the version of CCX the AP supports */ pVersionIe = (CCX_IE_Version_t*)pOuiHdr; //DBGPRINT(DBG_CCX, ("CCX: Version IE found: CCX Version %d\n", // pVersionIe->version)); break; case CCX_OUI_TYPE_QOS_PARAM: /* ** No longer used in CCX V2 specification v2.13 */ //DBGPRINT(DBG_CCX, ("CCX: QOS Param Set IE found: Deprecated\n")); break; default: /* ** Aironet/Cisco OUI specified, but unidentified subtype */ //DBGPRINT(DBG_CCX, ("CCX: unhandled oui type: %x (%d)\n", // pOuiHdr->ouiType, pOuiHdr->ouiType)); break; } } break; case CCX_IE_CELL_POWER_LIMIT: if (NdisEqualMemory(pOuiHdr->oui, cisco_oui, sizeof(cisco_oui)) == 1) { /* Flag the presence of CCX elements */ enableBssCcxExt = TRUE; /* ** Set the max power indicated by the Cell Power Limit IE ** in the CCX BSS information structure for this AP. ** Mark it as valid. Used in association processing. */ pCellPowerIe = (CCX_IE_Cell_Power_Limit_t*)pOuiHdr; pCcxBssInfo->maxPowerValid = TRUE; pCcxBssInfo->maxPower = pCellPowerIe->maxPower; DBGPRINT(DBG_CCX, ("CCX: Cell Power Limit IE found: Max Power = %d\n", pCellPowerIe->maxPower)); } break; default: /* ** Not a CCX element */ DBGPRINT(DBG_CCX, ("CCX: Unhandled IE: %d\n", pOuiHdr->elemId)); break; } /* ** If the parsing routines above find CCX elements, set the enable ** flag in the BSS info structure for this AP. Triggers CCX support ** in association processing. */ pCcxBssInfo->ccxEnabled = enableBssCcxExt; /* Succssful return */ return WLAN_STATUS_SUCCESS;}ULONG wlan_ccx_getFlags(void){ return ccx_flags;}void wlan_ccx_setFlags(ULONG flags){ ccx_flags = flags;}ULONG wlan_ccx_getEAPState(void){ return ccx_EAPstate;}void wlan_ccx_setEAPState(ULONG state){ ccx_EAPstate = state;}void wlan_ccx_setRogueAP(FSW_CCX_ROGUE_AP_DETECTED *pRogueAP){ int ix; for (ix=0;ix < CCX_ROGUE_AP_COUNT;ix++) { if (NdisEqualMemory(pRogueAP, &(ccxRogueAP[ix]), sizeof(FSW_CCX_ROGUE_AP_DETECTED)) ) { //DBGPRINT(DBG_CCX, ("[CCX:wlan_ccx_setRogueAP] Rogue AP already exists in the list\n")); break; } if ( ccxRogueAP[ix].FailureReason != 0 ) { continue; /* not empty */ } //DBGPRINT(DBG_CCX, ("[CCX] Rogue AP [%d] : ", ix)); //HexDump(DBG_CCX,"Data: ", (PCHAR) pRogueAP, sizeof(FSW_CCX_ROGUE_AP_DETECTED)); NdisMoveMemory(&ccxRogueAP[ix], pRogueAP, sizeof(FSW_CCX_ROGUE_AP_DETECTED)); break; } if ( ix == CCX_ROGUE_AP_COUNT ) { DBGPRINT(DBG_ERROR, ("[CCX:wlan_ccx_setRogueAP] No empty in Rogue AP list\n")); } }void wlan_ccx_sendRogueAPList( IN PMRVDRV_ADAPTER Adapter ){ int i; for (i=0; i<CCX_ROGUE_AP_COUNT; i++) { if ( ccxRogueAP[i].FailureReason == 0 ) continue; // No failure ccx_send_packet(Adapter, pCCXPacket[i], &(ccxRogueAP[i])); ccxRogueAP[i].FailureReason = 0; // clear after sending } }///crlo:fastroam ++void wlan_ccx_fillFrameHeader(PMRVDRV_ADAPTER pAdapter, u8* pktBufPt){ PMRVPKTDESC pPktMsg = (PMRVPKTDESC)pktBufPt; u8* bufPt = pktBufPt; NdisMoveMemory(pPktMsg->dstAddr, pAdapter->CurrentBSSID, MRVDRV_ETH_ADDR_LEN); NdisMoveMemory(pPktMsg->srcAddr, pAdapter->PermanentAddr, MRVDRV_ETH_ADDR_LEN); pPktMsg->protocolLen[0] = 0; pPktMsg->protocolLen[1] = 0; ///pCCXMsg->tmp[0] = pCCXMsg->tmp[1] = 0; bufPt += sizeof(MRVPKTDESC); ///NdisMoveMemory(bufPt, ccxSnapHdr, sizeof(ccxSnapHdr)); return ;}/** * @brief This function processes an element in a description * * @param pCcxBssInfo CCX information * @param pBssElem BSS IE for CCX relevance evaluation * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE */void wlan_ccx_fillDDPINFOPkt(PMRVDRV_ADAPTER pAdapter, u8* pktBufPt){ PCCX_DDPINFO pDDPINFOPkt = (CCX_DDPINFO*)pktBufPt; PCCX_IAPP_HEADER pIAPPFrameHdr = &pDDPINFOPkt->iappHdr; PCCX_DDPINF_CONTENT pFrameContent = &pDDPINFOPkt->Content; ///UCHAR *pAPssid = pktBufPt+sizeof(PCCX_IAPP_CONTENT); OS_UINT16 tmp; OS_UINT16 currTm; UINT fillPktLen = 0; int i; /// ///Fill the IAPP header /// tmp = (WORD)sizeof(CCX_DDPINFO); pIAPPFrameHdr->Length = GetBigEndian((OS_UINT8 *) &tmp); pIAPPFrameHdr->Type = CCX_IAPP_TYPE_REPORT_INFORM; pIAPPFrameHdr->Func_SubType = 0x00; NdisMoveMemory((PVOID)pIAPPFrameHdr->imDest, pAdapter->ccxCurrentAP.alMACAddr, MRVDRV_ETH_ADDR_LEN); NdisMoveMemory((PVOID)pIAPPFrameHdr->imSrc, pAdapter->PermanentAddr, MRVDRV_ETH_ADDR_LEN); ///Fill the IAPP IE tmp = 0x009b; pFrameContent->imTag = GetBigEndian((OS_UINT8 *) &tmp); pFrameContent->imIEOUI[0] = 0x00; pFrameContent->imIEOUI[1] = 0x40; pFrameContent->imIEOUI[2] = 0x96; pFrameContent->imIEOUI[3] = 0x00; pFrameContent->imSSIDLength = GetBigEndian((OS_UINT8 *) &(pAdapter->ccxLastAP.ssid.SsidLength)); pFrameContent->imChannel = GetBigEndian((OS_UINT8 *) &(pAdapter->ccxLastAP.alChannel)); ///tmp = (WORD)(16 + pAdapter->ccxLastAP.ssid.SsidLength); ///length of element not including 4 byte header tmp = sizeof(CCX_DDPINFO_CONTENT) - 4; pFrameContent->imIELength = GetBigEndian((OS_UINT8 *) &tmp); NdisMoveMemory((PVOID)pFrameContent->imPreAPMac, pAdapter->ccxLastAP.alMACAddr, MRVDRV_ETH_ADDR_LEN); NdisMoveMemory((PVOID)pFrameContent->ssid, (PVOID)pAdapter->ccxLastAP.ssid.Ssid, (pAdapter->ccxLastAP.ssid.SsidLength<32)?pAdapter->ccxLastAP.ssid.SsidLength:32); RETAILMSG(1,(TEXT("SsidLength: %d\n"), pAdapter->ccxLastAP.ssid.SsidLength)); for (i=pAdapter->ccxLastAP.ssid.SsidLength ; i<32 ; i++) { pFrameContent->ssid[i] = '\0'; } currTm = (OS_UINT16)((GetTickCount() - pAdapter->ccxLastAP.alDisassocTime)/1000); RETAILMSG(1,(TEXT("DissAssocTime: %d (%d, %d)\n"), currTm, GetTickCount(), pAdapter->ccxLastAP.alDisassocTime)); pFrameContent->disassocTime = GetBigEndian((OS_INT8*)&currTm); return;}NDIS_STATUSccx_send( IN PMRVDRV_ADAPTER Adapter, IN PNDIS_PACKET pPacket, IN CHAR* pktbuf, IN UINT pktlen ){ PNDIS_BUFFER pBuffer; PUCHAR pBufVM; UINT bufLen;
NDIS_STATUS status;/// PCCX_MSG_T pCCXMsg; PrintMacro("ccx_send(%u)\n", pktlen); RETAILMSG(1,(TEXT("ccx_send(%u)\n"), pktlen)); NdisQueryPacket(pPacket, NULL, NULL, &pBuffer, NULL); NdisQueryBufferSafe(pBuffer, (void *)&pBufVM, &bufLen, NormalPagePriority); NdisAdjustBufferLength(pBuffer, pktlen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -