/************************************************************************ * buildDisconnTemplate * ************************************************************************ DESCRIPTION: This function build a Death/Disassoc template to set to the HAL when joining an infrastructure network performs the following: - Build a template & set the template len, the template type is set in the site mgr INPUT: pSiteMgr - Handle to site manager pTemplate - Pointer to the template structure OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildDisconnTemplate(siteMgr_t *pSiteMgr, TSetTemplate *pTemplate) { paramInfo_t param; TI_UINT32 size; disconnTemplate_t *pBuffer = (disconnTemplate_t *)pTemplate->ptr; siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite; TI_UINT16 fc; os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(disconnTemplate_t)); /* * Header First */ /* Set destination address */ MAC_COPY (pBuffer->hdr.DA, pPrimarySite->bssid); /* Set BSSID address */ MAC_COPY (pBuffer->hdr.BSSID, pPrimarySite->bssid); /* Build Source address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY (pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress); fc = DOT11_FC_DISASSOC; /* will be change by firmware to DOT11_FC_DEAUTH if needed */ COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */ pBuffer->disconnReason = 0; /* filled by firmware */ size = sizeof(disconnTemplate_t); pTemplate->len = size; return TI_OK; }
/************************************************************************ * buildArpRspTemplate * ************************************************************************ DESCRIPTION: This function builds an ARP Response template to set to the HAL when joining an infrastructure network. The function's steps: - It builds the template & set the template len. - If QoS is inactive, it discards the QoS Control Field. ** The template type is set in the site mgr. INPUT: pSiteMgr - Handle to site manager. pTemplate - Pointer to the template structure. OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildArpRspTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate, TIpAddr staIp) { siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite; ArpRspTemplate_t *pBuffer = (ArpRspTemplate_t *) pTemplate->ptr; TI_UINT8 *ptr = (TI_UINT8 *) pBuffer; paramInfo_t param; /* To get Site and QoS params */ TI_UINT16 fc; /* Frame Control field in MAC header */ TI_UINT16 macAddrItr; TI_BOOL privacyInvoked; TI_UINT8 encryptionFieldSize, copyPayloadOffset, lenToCopy; /* Reset the buffer */ os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(ArpRspTemplate_t)); /* Turn on the To_DS bit in the Frame Control field */ fc = (1 << DOT11_FC_TO_DS_SHIFT); /* Set MAC header address fields: ----------------------------- Since To_DS is on and From_DS is off the address meaning is as follows: Address1 - BSSID Address2 - Source Address Address3 - Destination Address Address4 - Not present */ /* - Set BSSID */ if (pPrimarySite) { MAC_COPY(pBuffer->hdr.address1, pPrimarySite->bssid); } else { TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "No Primary site so cannot fill QosNullData template.\n"); } /* - Set Source Address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.address2, param.content.ctrlDataDeviceMacAddress); /* - Set Destination Address: ARP response should be sent with broadcast DA - Set accordingly */ for (macAddrItr = 0; macAddrItr < MAC_ADDR_LEN; macAddrItr++) { pBuffer->hdr.address3[macAddrItr] = 0xFF; } pBuffer->LLC.DSAP = 0xaa; pBuffer->LLC.SSAP = 0xaa; pBuffer->LLC.Control = 0x03; /* pBuffer->LLC.Control.OUI these 3 bytes are zeroed already */ pBuffer->LLC.Type = WLANTOHS((TI_UINT16) 0x806); pBuffer->hardType = WLANTOHS((TI_UINT16) 1); pBuffer->protType = WLANTOHS((TI_UINT16) 0x800); pBuffer->hardSize = 6; pBuffer->protSize = 4; pBuffer->op = WLANTOHS((TI_UINT16) 2); /*filled as for ARP-RSP, not for RARP_RSP */ MAC_COPY(pBuffer->StaMac, pBuffer->hdr.address2); IP_COPY(pBuffer->StaIp, staIp); pTemplate->len = sizeof(ArpRspTemplate_t); /* Get encryption status */ txCtrlParams_getCurrentEncryptionInfo(pSiteMgr->hTxCtrl, &privacyInvoked, &encryptionFieldSize); /* If no encryption is used, encryptionFieldSize has garbage value */ encryptionFieldSize = privacyInvoked ? encryptionFieldSize : 0; /* Set the subtype field of fc with WEP_BIT */ fc |= (privacyInvoked << DOT11_FC_WEP_SHIFT); /* Get QoS type to check if QoS is active */ param.paramType = QOS_MNGR_ACTIVE_PROTOCOL; qosMngr_getParams(pSiteMgr->hQosMngr, ¶m); if (param.content.qosSiteProtocol == QOS_NONE) { /* QoS is not active */ copyPayloadOffset = sizeof(pBuffer->hdr.qosControl) + AES_AFTER_HEADER_FIELD_SIZE - encryptionFieldSize; /* Set the subtype field of fc with DATA value (non Qos) */ fc |= DOT11_FC_DATA; } else { /* QoS is active */ copyPayloadOffset = AES_AFTER_HEADER_FIELD_SIZE - encryptionFieldSize; /* Set the subtype field of fc with DATA_QOS */ fc |= DOT11_FC_DATA_QOS; } /* Need to copy backward to overwrite security or QoS offset */ if (copyPayloadOffset > 0) { ptr = (TI_UINT8 *) & pBuffer->LLC.DSAP; /* Copy back the actual payload without header & security */ lenToCopy = sizeof(ArpRspTemplate_t) - sizeof(dot11_header_t) - AES_AFTER_HEADER_FIELD_SIZE; os_memoryCopy(pSiteMgr->hOs, ptr - copyPayloadOffset, ptr, lenToCopy); pTemplate->len -= copyPayloadOffset; } COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */ return TI_OK; }
/************************************************************************ * buildProbeRspTemplate * ************************************************************************ DESCRIPTION: This function build a probe response template to set to the HAL when joining an IBSS network. performs the following: - Build a template & set the template len, the template type is set in the site mgr - The template is built based on the chosen site attributes NOTE: This function is used to build beacon template too. The site manager set the template type (after thos function returns) to beacon or probe response accordingly. INPUT: pSiteMgr - Handle to site manager pTemplate - Pointer to the template structure OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildProbeRspTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate) { paramInfo_t param; TI_UINT8 *pBuf; probeRspTemplate_t *pBuffer = (probeRspTemplate_t *) pTemplate->ptr; siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite; TI_INT32 i, j; TI_UINT32 size; dot11_RATES_t *pDot11Rates; dot11_ERP_t *pdot11Erp; TI_UINT32 len = 0, ofdmIndex = 0; TI_BOOL extRates = TI_FALSE; TI_BOOL useProtection, NonErpPresent, barkerPreambleType; TCountry *pCountry = NULL; TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES]; TI_UINT32 supportedRateMask, basicRateMask; TI_UINT16 headerFC = DOT11_FC_PROBE_RESP; os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(probeRspTemplate_t)); /* * Build WLAN Header: * ================== */ /* Set destination address */ for (i = 0; i < MAC_ADDR_LEN; i++) pBuffer->hdr.DA[i] = 0xFF; /* Set BSSID address */ MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid); /* Build Source address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress); COPY_WLAN_WORD(&pBuffer->hdr.fc, &headerFC); size = sizeof(dot11_mgmtHeader_t); pBuf = (TI_UINT8 *) pBuffer->timeStamp; /* * Fixed Fields */ /* we skip the timestamp field */ size += TIME_STAMP_LEN; pBuf += TIME_STAMP_LEN; /* Beacon interval */ COPY_WLAN_WORD(pBuf, &pPrimarySite->beaconInterval); size += FIX_FIELD_LEN; pBuf += FIX_FIELD_LEN; /* capabilities */ COPY_WLAN_WORD(pBuf, &pPrimarySite->capabilities); size += FIX_FIELD_LEN; pBuf += FIX_FIELD_LEN; /* * Build Informataion Elements: * ============================ */ /* SSID IE */ /* It looks like it never happens. Anyway decided to check */ if (pPrimarySite->ssid.len > MAX_SSID_LEN) { TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "buildProbeRspTemplate. pPrimarySite->ssid.len=%d exceeds the limit %d\n", pPrimarySite->ssid.len, MAX_SSID_LEN); handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); return TI_NOK; } ((dot11_SSID_t *) (pBuf))->hdr[0] = DOT11_SSID_ELE_ID; ((dot11_SSID_t *) (pBuf))->hdr[1] = pPrimarySite->ssid.len; os_memoryCopy(pSiteMgr->hOs, pBuf + sizeof(dot11_eleHdr_t), (void *)pPrimarySite->ssid.str, pPrimarySite->ssid.len); size += sizeof(dot11_eleHdr_t) + pPrimarySite->ssid.len; pBuf += sizeof(dot11_eleHdr_t) + pPrimarySite->ssid.len; /* Rates IE */ pDot11Rates = (dot11_RATES_t *) pBuf; if (pPrimarySite->channel == SPECIAL_BG_CHANNEL) { supportedRateMask = rate_GetDrvBitmapForDefaultSupporteSet(); basicRateMask = rate_GetDrvBitmapForDefaultBasicSet(); } else { supportedRateMask = pSiteMgr->pDesiredParams->siteMgrMatchedSuppRateMask; basicRateMask = pSiteMgr->pDesiredParams->siteMgrMatchedBasicRateMask; } rate_DrvBitmapToNetStr(supportedRateMask, basicRateMask, ratesBuf, &len, &ofdmIndex); if (pSiteMgr->siteMgrOperationalMode != DOT11_G_MODE || pSiteMgr->pDesiredParams->siteMgrUseDraftNum == DRAFT_5_AND_EARLIER || ofdmIndex == len) { pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = len; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); } else { pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = ofdmIndex; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); extRates = TI_TRUE; } /* DS IE */ ((dot11_DS_PARAMS_t *) (pBuf))->hdr[0] = DOT11_DS_PARAMS_ELE_ID; ((dot11_DS_PARAMS_t *) (pBuf))->hdr[1] = DOT11_DS_PARAMS_ELE_LEN; ((dot11_DS_PARAMS_t *) (pBuf))->currChannel = pPrimarySite->channel; size += sizeof(dot11_eleHdr_t) + DOT11_DS_PARAMS_ELE_LEN; pBuf += sizeof(dot11_eleHdr_t) + DOT11_DS_PARAMS_ELE_LEN; /* IBSS IE */ ((dot11_IBSS_PARAMS_t *) (pBuf))->hdr[0] = DOT11_IBSS_PARAMS_ELE_ID; ((dot11_IBSS_PARAMS_t *) (pBuf))->hdr[1] = DOT11_IBSS_PARAMS_ELE_LEN; COPY_WLAN_WORD(&((dot11_IBSS_PARAMS_t *) (pBuf))->atimWindow, &pPrimarySite->atimWindow); size += sizeof(dot11_eleHdr_t) + DOT11_IBSS_PARAMS_ELE_LEN; pBuf += sizeof(dot11_eleHdr_t) + DOT11_IBSS_PARAMS_ELE_LEN; /* Country IE */ param.paramType = REGULATORY_DOMAIN_ENABLED_PARAM; regulatoryDomain_getParam(pSiteMgr->hRegulatoryDomain, ¶m); if (param.content.regulatoryDomainEnabled == TI_TRUE) { /* get country IE */ param.paramType = REGULATORY_DOMAIN_COUNTRY_PARAM; regulatoryDomain_getParam(pSiteMgr->hRegulatoryDomain, ¶m); pCountry = param.content.pCountry; /* Check if a country IE was found */ if (pCountry != NULL) { *pBuf = DOT11_COUNTRY_ELE_ID; pBuf++; size++; *pBuf = (TI_UINT8) (pCountry->len); pBuf++; size++; /* Note: The country structure is not byte-aligned so it is copied as follows to ensure that there are no gaps in the output structure (pBuf). */ os_memoryCopy(pSiteMgr->hOs, pBuf, &pCountry->countryIE.CountryString, DOT11_COUNTRY_STRING_LEN); pBuf += DOT11_COUNTRY_STRING_LEN; size += DOT11_COUNTRY_STRING_LEN; /* Loop on all tripletChannels. Each item has three fields ('i' counts rows and 'j' counts bytes). */ for (i = 0, j = 0; j < (pCountry->len - DOT11_COUNTRY_STRING_LEN); i++, j += 3) { *(pBuf + j) = pCountry->countryIE.tripletChannels[i]. firstChannelNumber; *(pBuf + j + 1) = pCountry->countryIE.tripletChannels[i]. maxTxPowerLevel; *(pBuf + j + 2) = pCountry->countryIE.tripletChannels[i]. numberOfChannels; } pBuf += (pCountry->len - DOT11_COUNTRY_STRING_LEN); size += (pCountry->len - DOT11_COUNTRY_STRING_LEN); } } /*ERP IE */ siteMgr_IsERP_Needed(pSiteMgr, &useProtection, &NonErpPresent, &barkerPreambleType); if (useProtection || NonErpPresent || barkerPreambleType) { pdot11Erp = (dot11_ERP_t *) pBuf; pdot11Erp->hdr[0] = DOT11_ERP_IE_ID; pdot11Erp->hdr[1] = 1; pdot11Erp->ctrl = 0; if (NonErpPresent) pdot11Erp->ctrl |= ERP_IE_NON_ERP_PRESENT_MASK; if (useProtection) pdot11Erp->ctrl |= ERP_IE_USE_PROTECTION_MASK; if (barkerPreambleType) pdot11Erp->ctrl |= ERP_IE_BARKER_PREAMBLE_MODE_MASK; size += pdot11Erp->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pdot11Erp->hdr[1] + sizeof(dot11_eleHdr_t); } /* Extended supported rates IE */ if (extRates) { pDot11Rates = (dot11_RATES_t *) pBuf; pDot11Rates->hdr[0] = DOT11_EXT_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = len - ofdmIndex; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]); size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); } /* no need to insert RSN information elements */ pTemplate->len = size; TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "Probe response template len = %d\n", size); return TI_OK; }
/************************************************************************ * buildProbeReqTemplate * ************************************************************************ DESCRIPTION: This function build a probe request template to set to the HAL in the scan process. performs the following: - Build a template & set the template len, the template type is set in the site mgr INPUT: pSiteMgr - Handle to site manager pTemplate - Pointer to the template structure pSsid - Desired SSID OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildProbeReqTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate, TSsid * pSsid, ERadioBand radioBand) { paramInfo_t param; char *pBuf; int i; probeReqTemplate_t *pBuffer = (probeReqTemplate_t *) pTemplate->ptr; TI_UINT32 size; dot11_RATES_t *pDot11Rates; TI_UINT32 len = 0, ofdmIndex = 0; TI_UINT32 suppRatesLen, extSuppRatesLen; TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES]; TI_UINT8 WSCOuiIe[DOT11_OUI_LEN] = { 0x00, 0x50, 0xf2, 0x04 }; TI_UINT32 supportedRateMask, basicRateMask; TI_UINT16 fc = DOT11_FC_PROBE_REQ; os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(probeReqTemplate_t)); /* * Header First */ /* Set destination address */ for (i = 0; i < MAC_ADDR_LEN; i++) pBuffer->hdr.DA[i] = 0xFF; /* Set BSSID address */ for (i = 0; i < MAC_ADDR_LEN; i++) pBuffer->hdr.BSSID[i] = 0xFF; /* Build Source address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress); COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */ size = sizeof(dot11_mgmtHeader_t); pBuf = (char *)&(pBuffer->infoElements); /* * Informataion elements */ /* SSID */ /* It looks like it never happens. Anyway decided to check */ if (pSsid->len > MAX_SSID_LEN) { TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "buildProbeReqTemplate. pSsid->len=%d exceeds the limit %d\n", pSsid->len, MAX_SSID_LEN); handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); return TI_NOK; } ((dot11_SSID_t *) (pBuf))->hdr[0] = DOT11_SSID_ELE_ID; ((dot11_SSID_t *) (pBuf))->hdr[1] = pSsid->len; os_memoryCopy(pSiteMgr->hOs, pBuf + sizeof(dot11_eleHdr_t), (void *)pSsid->str, pSsid->len); size += sizeof(dot11_eleHdr_t) + pSsid->len; pBuf += sizeof(dot11_eleHdr_t) + pSsid->len; /* Rates */ pDot11Rates = (dot11_RATES_t *) pBuf; /* * Supported rates in probe request will always use the default rates for BG or A bands, * regardless of the STA desired rates. */ if (radioBand == RADIO_BAND_2_4_GHZ) { /* Basic rates: 1,2,5.5,11 */ basicRateMask = rate_BasicToDrvBitmap((EBasicRateSet) (pSiteMgr->pDesiredParams-> siteMgrRegstryBasicRate [DOT11_G_MODE]), TI_FALSE); /* Extended: 6,9,12,18,24,36,48,54 */ supportedRateMask = rate_SupportedToDrvBitmap((ESupportedRateSet) (pSiteMgr->pDesiredParams-> siteMgrRegstrySuppRate [DOT11_G_MODE]), TI_FALSE); } else if (radioBand == RADIO_BAND_5_0_GHZ) { /* Basic rates: 6,12,24 */ basicRateMask = rate_BasicToDrvBitmap((EBasicRateSet) (pSiteMgr->pDesiredParams-> siteMgrRegstryBasicRate [DOT11_A_MODE]), TI_TRUE); /* Extended: 9,18,24,36,48,54 */ supportedRateMask = rate_SupportedToDrvBitmap((ESupportedRateSet) (pSiteMgr->pDesiredParams-> siteMgrRegstrySuppRate [DOT11_A_MODE]), TI_TRUE); } else { TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "buildProbeReqTemplate, radioBand =%d ???\n", radioBand); /* Use default and pray for the best */ /* Basic rates: 1,2,5.5,11 */ basicRateMask = rate_BasicToDrvBitmap(BASIC_RATE_SET_1_2_5_5_11, TI_FALSE); /* Extended: 6,9,12,18,24,36,48,54 */ supportedRateMask = rate_SupportedToDrvBitmap(SUPPORTED_RATE_SET_UP_TO_54, TI_FALSE); } rate_DrvBitmapToNetStr(supportedRateMask, basicRateMask, ratesBuf, &len, &ofdmIndex); TRACE5(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "buildProbeReqTemplate, supportedRateMask=0x%x, basicRateMask=0x%x, len=%d, ofdmIndex=%d, radioBand =%d\n", supportedRateMask, basicRateMask, len, ofdmIndex, radioBand); /* It looks like it never happens. Anyway decided to check */ if (len > DOT11_MAX_SUPPORTED_RATES) { TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "buildProbeReqTemplate. len=%d exceeds the limit %d\n", len, DOT11_MAX_SUPPORTED_RATES); handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); return TI_NOK; } if (radioBand == RADIO_BAND_5_0_GHZ || pSiteMgr->pDesiredParams->siteMgrUseDraftNum == DRAFT_5_AND_EARLIER || ofdmIndex == len) { pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = len; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); } else { pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = ofdmIndex; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); suppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pDot11Rates = (dot11_RATES_t *) (pBuf + suppRatesLen); pDot11Rates->hdr[0] = DOT11_EXT_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = len - ofdmIndex; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]); extSuppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); size += suppRatesLen + extSuppRatesLen; pBuf += suppRatesLen + extSuppRatesLen; } /* add HT capabilities IE */ StaCap_GetHtCapabilitiesIe(pSiteMgr->hStaCap, (TI_UINT8 *) pBuf, &len); size += len; pBuf += len; /* WiFi Simple Config */ if (pSiteMgr->includeWSCinProbeReq && (pSiteMgr->siteMgrWSCCurrMode != TIWLN_SIMPLE_CONFIG_OFF)) { ((dot11_WSC_t *) pBuf)->hdr[0] = DOT11_WSC_PARAM_ELE_ID; ((dot11_WSC_t *) pBuf)->hdr[1] = pSiteMgr->uWscIeSize + DOT11_OUI_LEN; pBuf += sizeof(dot11_eleHdr_t); os_memoryCopy(pSiteMgr->hOs, pBuf, &WSCOuiIe, DOT11_OUI_LEN); os_memoryCopy(pSiteMgr->hOs, pBuf + DOT11_OUI_LEN, &pSiteMgr->siteMgrWSCProbeReqParams, pSiteMgr->uWscIeSize); size += sizeof(dot11_eleHdr_t) + pSiteMgr->uWscIeSize + DOT11_OUI_LEN; pBuf += sizeof(dot11_eleHdr_t) + pSiteMgr->uWscIeSize + DOT11_OUI_LEN; } pTemplate->len = size; return TI_OK; }
TI_STATUS mlmeBuilder_sendFrame(TI_HANDLE hMlme, dot11MgmtSubType_e type, UINT8 *pDataBuff, UINT32 dataLen, UINT8 setWepOpt) { TI_STATUS status; mlme_t *pHandle; mem_MSDU_T *pMsdu; paramInfo_t daParam, saParam; dot11_mgmtFrame_t *pFrame; if (hMlme == NULL) { return NOK; } pHandle = (mlme_t*)hMlme; /* GET NEW MSDU !!! */ status = wlan_memMngrAllocMSDU(pHandle->hMemMgr, &pMsdu, MAX_MANAGEMENT_FRAME_BODY_LEN + configMgr_getPacketHeaderLength(pHandle->hConfigMgr, NULL, TX_DATA_MGMT_MSDU), MLME_MODULE); if (status != OK) return NOK; pFrame = (dot11_mgmtFrame_t*)(pMsdu->firstBDPtr->data + TX_TOTAL_OFFSET_BEFORE_DATA); status = mlmeBuilder_buildFrameCtrl(pHandle, type, (UINT16 *)&pFrame->hdr.fc, setWepOpt); if (status != OK) { wlan_memMngrFreeMSDU(pHandle->hMemMgr, pMsdu->handle); return NOK; } daParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; status = ctrlData_getParam(pHandle->hCtrlData, &daParam); if (status != OK) { wlan_memMngrFreeMSDU(pHandle->hMemMgr, pMsdu->handle); return NOK; } /* copy destination mac address */ MAC_COPY(pHandle->hOs, (&pFrame->hdr.DA), (&daParam.content.ctrlDataCurrentBSSID)); saParam.paramType = CTRL_DATA_MAC_ADDRESS; status = ctrlData_getParam(pHandle->hCtrlData, &saParam); if (status != OK) { wlan_memMngrFreeMSDU(pHandle->hMemMgr, pMsdu->handle); return NOK; } /* copy source mac address */ MAC_COPY(pHandle->hOs, (&pFrame->hdr.SA), (&saParam.content.ctrlDataCurrentBSSID)); /* copy BSSID (destination mac address) */ MAC_COPY(pHandle->hOs, (&pFrame->hdr.BSSID), (&daParam.content.ctrlDataCurrentBSSID)); if (pDataBuff != NULL) { os_memoryCopy(pHandle->hOs, (void *)pFrame->body, pDataBuff, dataLen); } /* Update MSDU parameters */ pMsdu->headerLen = sizeof(dot11_mgmtHeader_t); pMsdu->dataLen = sizeof(dot11_mgmtHeader_t) + dataLen; pMsdu->firstBDPtr->dataOffset = TX_TOTAL_OFFSET_BEFORE_DATA; pMsdu->firstBDPtr->length = pMsdu->dataLen + pMsdu->firstBDPtr->dataOffset; /* send the packet to the TX */ pMsdu->qosTag = 0; pMsdu->txFlags |= TX_DATA_MGMT_MSDU; /* * sign the Disassoc packet * A disassociate indication (if occurs) will be provided via TxComplete */ if (type == DIS_ASSOC) pMsdu->txCompleteFlags |= TX_DATA_DISASSOC_SYNC_TRIG; /* sign the De Auth packet * A De Auth indication (if occurs) will be provided via TxComplete */ if (type == DE_AUTH) pMsdu->txCompleteFlags |= TX_DATA_DEAUTH_SYNC_TRIG; status = txData_txSendMsdu(pHandle->hTxData, pMsdu); return status; }
/** * \fn mlme_assocCapBuild * \brief builds capabilties of assoc request * * builds capabilties of assoc request according to the mlme params * * \param pCtx - pointer to mlme_t * \param cap - <output> pointer to the built capablities * \return TI_OK if auth send successfully * TI_NOK otherwise * * \sa mlme_assocRequestMsgBuild */ TI_STATUS mlme_assocCapBuild(mlme_t *pCtx, TI_UINT16 *cap) { paramInfo_t param; TI_STATUS status; EDot11Mode mode; TI_UINT32 rateSuppMask, rateBasicMask; TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES]; TI_UINT32 len = 0, ofdmIndex = 0; TI_BOOL b11nEnable, bWmeEnable; *cap = 0; /* Bss type */ param.paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM; status = ctrlData_getParam(pCtx->hCtrlData, ¶m); if (status == TI_OK) { if (param.content.ctrlDataCurrentBssType == BSS_INFRASTRUCTURE) { *cap |= DOT11_CAPS_ESS; } else { *cap |= DOT11_CAPS_IBSS; } } else { return TI_NOK; } /* Privacy */ param.paramType = RSN_ENCRYPTION_STATUS_PARAM; status = rsn_getParam(pCtx->hRsn, ¶m); if (status == TI_OK) { if (param.content.rsnEncryptionStatus != TWD_CIPHER_NONE) { *cap |= DOT11_CAPS_PRIVACY; } } else { return TI_NOK; } /* Preamble */ param.paramType = SITE_MGR_DESIRED_PREAMBLE_TYPE_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status == TI_OK) { if (param.content.siteMgrCurrentPreambleType == PREAMBLE_SHORT) *cap |= DOT11_CAPS_SHORT_PREAMBLE; } else { return TI_NOK; } /* Pbcc */ param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status == TI_OK) { if(param.content.siteMgrCurrentRateMask.supportedRateMask & DRV_RATE_MASK_22_PBCC) *cap |= DOT11_CAPS_PBCC; } else { return TI_NOK; } /* Checking if the station supports Spectrum Management (802.11h) */ param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM; status = regulatoryDomain_getParam(pCtx->hRegulatoryDomain, ¶m); if (status == TI_OK ) { if( param.content.spectrumManagementEnabled) *cap |= DOT11_SPECTRUM_MANAGEMENT; } else { return TI_NOK; } /* slot time */ param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if(status == TI_OK) { mode = param.content.siteMgrDot11OperationalMode; } else return TI_NOK; if(mode == DOT11_G_MODE) { /* new requirement: the short slot time should be set only if the AP's modulation is OFDM (highest rate) */ /* get Rates */ param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status == TI_OK) { rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask; rateSuppMask = param.content.siteMgrCurrentRateMask.supportedRateMask; } else { return TI_NOK; } /* convert the bit map to the rates array */ rate_DrvBitmapToNetStr (rateSuppMask, rateBasicMask, ratesBuf, &len, &ofdmIndex); if(ofdmIndex < len) *cap |= DOT11_CAPS_SHORT_SLOT_TIME; /* param.paramType = SITE_MGR_CURRENT_MODULATION_TYPE_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if(param.content.siteMgrCurrentModulationType == DRV_MODULATION_OFDM) *cap |= DOT11_CAPS_SHORT_SLOT_TIME; */ } /* Primary Site support HT ? */ param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT; siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (param.content.bPrimarySiteHtSupport == TI_TRUE) { /* Immediate Block Ack subfield - (is WME on?) AND (is HT Enable?) */ /* verify 11n_Enable and Chip type */ StaCap_IsHtEnable (pCtx->hStaCap, &b11nEnable); /* verify that WME flag enable */ qosMngr_GetWmeEnableFlag (pCtx->hQosMngr, &bWmeEnable); if ((b11nEnable != TI_FALSE) && (bWmeEnable != TI_FALSE)) { *cap |= DOT11_CAPS_IMMEDIATE_BA; } } return TI_OK; }
TI_STATUS mlme_getParam(TI_HANDLE hMlme, paramInfo_t *pParam) { mlme_t *pMlme = (mlme_t *)hMlme; switch(pParam->paramType) { case MLME_LEGACY_TYPE_PARAM: pParam->content.mlmeLegacyAuthType = pMlme->authInfo.authType; break; case MLME_CAPABILITY_PARAM: pParam->content.mlmeLegacyAuthType = pMlme->legacyAuthType; mlme_assocCapBuild(pMlme, &(pParam->content.siteMgrSiteCapability)); break; case MLME_BEACON_RECV: pParam->content.siteMgrTiWlanCounters.BeaconsRecv = pMlme->BeaconsCounterPS; break; case MLME_AUTH_RESPONSE_TIMEOUT_PARAM: pParam->content.authResponseTimeout = pMlme->authInfo.timeout; break; case MLME_AUTH_COUNTERS_PARAM: pParam->content.siteMgrTiWlanCounters.AuthRejects = pMlme->authInfo.authRejectCount; pParam->content.siteMgrTiWlanCounters.AuthTimeouts = pMlme->authInfo.authTimeoutCount; break; case MLME_ASSOC_RESPONSE_TIMEOUT_PARAM: pParam->content.assocResponseTimeout = pMlme->assocInfo.timeout; break; case MLME_ASSOCIATION_REQ_PARAM: pParam->content.assocReqBuffer.buffer = pMlme->assocInfo.assocReqBuffer; pParam->content.assocReqBuffer.bufferSize = pMlme->assocInfo.assocReqLen; pParam->content.assocReqBuffer.reAssoc = pMlme->reAssoc; break; case MLME_ASSOCIATION_RESP_PARAM: pParam->content.assocReqBuffer.buffer = pMlme->assocInfo.assocRespBuffer; pParam->content.assocReqBuffer.bufferSize = pMlme->assocInfo.assocRespLen; pParam->content.assocReqBuffer.reAssoc = pMlme->assocInfo.reAssocResp; break; case MLME_ASSOC_COUNTERS_PARAM: pParam->content.siteMgrTiWlanCounters.AssocRejects = pMlme->assocInfo.assocRejectCount; pParam->content.siteMgrTiWlanCounters.AssocTimeouts = pMlme->assocInfo.assocTimeoutCount; break; case MLME_ASSOCIATION_INFORMATION_PARAM: { TI_UINT8 reqBuffIEOffset, respBuffIEOffset; TI_UINT32 RequestIELength = 0; TI_UINT32 ResponseIELength = 0; paramInfo_t *lParam; ScanBssType_enum bssType; TRACE0(pMlme->hReport, REPORT_SEVERITY_SM, "MLME: DEBUG - Association Information Get: \n"); lParam = (paramInfo_t *)os_memoryAlloc(pMlme->hOs, sizeof(paramInfo_t)); if (!lParam) { return TI_NOK; } /* Assoc exists only in Infrastructure */ lParam->paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM; ctrlData_getParam(pMlme->hCtrlData, lParam); bssType = lParam->content.ctrlDataCurrentBssType; os_memoryFree(pMlme->hOs, lParam, sizeof(paramInfo_t)); if (bssType != BSS_INFRASTRUCTURE) { TRACE0(pMlme->hReport, REPORT_SEVERITY_ERROR, "Not in Infrastructure BSS, No ASSOC Info for GET ASSOC_ASSOCIATION_INFORMATION_PARAM\n"); return TI_NOK; } /* Init the result buffer to 0 */ os_memoryZero(pMlme->hOs ,&pParam->content, sizeof(OS_802_11_ASSOCIATION_INFORMATION)); reqBuffIEOffset = 4; /* In Assoc request frame IEs are located from byte 4 */ respBuffIEOffset = 6; /* In Assoc response frame the IEs are located from byte 6 */ /* If the last associate was re-associciation, the current AP MAC address */ /* is placed before the IEs. Copy it to the result parameters. */ if (pMlme->reAssoc) { MAC_COPY (pParam->content.assocAssociationInformation.RequestFixedIEs.CurrentAPAddress, &pMlme->assocInfo.assocReqBuffer[reqBuffIEOffset]); reqBuffIEOffset += MAC_ADDR_LEN; } /* Calculate length of Info elements in assoc request and response frames */ if(pMlme->assocInfo.assocReqLen > reqBuffIEOffset) RequestIELength = pMlme->assocInfo.assocReqLen - reqBuffIEOffset; if(pMlme->assocInfo.assocRespLen > respBuffIEOffset) ResponseIELength = pMlme->assocInfo.assocRespLen - respBuffIEOffset; /* Copy the association request information */ pParam->content.assocAssociationInformation.Length = sizeof(OS_802_11_ASSOCIATION_INFORMATION); pParam->content.assocAssociationInformation.AvailableRequestFixedIEs = OS_802_11_AI_REQFI_CAPABILITIES | OS_802_11_AI_REQFI_LISTENINTERVAL; pParam->content.assocAssociationInformation.RequestFixedIEs.Capabilities = *(TI_UINT16*)&(pMlme->assocInfo.assocReqBuffer[0]); pParam->content.assocAssociationInformation.RequestFixedIEs.ListenInterval = *(TI_UINT16*)(&pMlme->assocInfo.assocReqBuffer[2]); pParam->content.assocAssociationInformation.RequestIELength = RequestIELength; pParam->content.assocAssociationInformation.OffsetRequestIEs = 0; if (RequestIELength > 0) { pParam->content.assocAssociationInformation.OffsetRequestIEs = (TI_UINT32)&pMlme->assocInfo.assocReqBuffer[reqBuffIEOffset]; } /* Copy the association response information */ pParam->content.assocAssociationInformation.AvailableResponseFixedIEs = OS_802_11_AI_RESFI_CAPABILITIES | OS_802_11_AI_RESFI_STATUSCODE | OS_802_11_AI_RESFI_ASSOCIATIONID; pParam->content.assocAssociationInformation.ResponseFixedIEs.Capabilities = *(TI_UINT16*)&(pMlme->assocInfo.assocRespBuffer[0]); pParam->content.assocAssociationInformation.ResponseFixedIEs.StatusCode = *(TI_UINT16*)&(pMlme->assocInfo.assocRespBuffer[2]); pParam->content.assocAssociationInformation.ResponseFixedIEs.AssociationId = *(TI_UINT16*)&(pMlme->assocInfo.assocRespBuffer[4]); pParam->content.assocAssociationInformation.ResponseIELength = ResponseIELength; pParam->content.assocAssociationInformation.OffsetResponseIEs = 0; if (ResponseIELength > 0) { pParam->content.assocAssociationInformation.OffsetResponseIEs = (TI_UINT32)&pMlme->assocInfo.assocRespBuffer[respBuffIEOffset]; } } break; default: TRACE1(pMlme->hReport, REPORT_SEVERITY_ERROR, "Get param, Params is not supported, %d\n\n", pParam->content.mlmeLegacyAuthType); return PARAM_NOT_SUPPORTED; } return TI_OK; }
TI_STATUS keyParserExternal_remove(struct _keyParser_t *pKeyParser, TI_UINT8 *pKeyData, TI_UINT32 keyDataLen) { TI_STATUS status; OS_802_11_KEY *pKeyDesc; paramInfo_t macParam; encodedKeyMaterial_t encodedKeyMaterial; TI_UINT8 broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; TI_UINT8 keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH]; if (pKeyData == NULL) { TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n"); return TI_NOK; } pKeyDesc = (OS_802_11_KEY*)pKeyData; if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) { /* Bit 31 should always be zero */ TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove TX bit in key index can't be 1\n"); return TI_NOK; } if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK) { /* Bits 8-29 should always be zero */ TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove none zero key index\n"); return TI_NOK; } encodedKeyMaterial.keyId = pKeyDesc->KeyIndex; encodedKeyMaterial.keyLen = 0; encodedKeyMaterial.pData = (char *) keyBuffer; if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK) { /* delete all pairwise keys or for the current BSSID */ if (!MAC_EQUAL(pKeyDesc->BSSID, broadcastMacAddr)) { MAC_COPY (keyBuffer, pKeyDesc->BSSID); } else { macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam); if (status != TI_OK) { TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n"); return TI_NOK; } MAC_COPY (keyBuffer, macParam.content.ctrlDataCurrentBSSID); } status = pKeyParser->pUcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial); } else { /* delete all group keys or for the current BSSID */ MAC_COPY (keyBuffer, broadcastMacAddr); status = pKeyParser->pBcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial); } return status; }
TI_STATUS keyParserExternal_recv(struct _keyParser_t *pKeyParser, TI_UINT8 *pKeyData, TI_UINT32 keyDataLen) { TI_STATUS status; OS_802_11_KEY *pKeyDesc; encodedKeyMaterial_t encodedKeyMaterial; paramInfo_t macParam; TI_BOOL macEqual2Associated=TI_FALSE; TI_BOOL macIsBroadcast=TI_FALSE; TI_BOOL wepKey = TI_FALSE; TI_UINT8 broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; TI_UINT8 nullMacAddr[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; TI_UINT8 keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH]; if (pKeyData == NULL) { TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n"); return TI_NOK; } pKeyDesc = (OS_802_11_KEY*)pKeyData; /* copy the key data, mac address and RSC */ MAC_COPY (keyBuffer, pKeyDesc->BSSID); /* configure keyRSC value (if needed) */ if (pKeyDesc->KeyIndex & EXT_KEY_RSC_KEY_MASK) { /* set key recieve sequence counter */ os_memoryCopy(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], (TI_UINT8*)&(pKeyDesc->KeyRSC), KEY_RSC_LEN); } else { os_memoryZero(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], KEY_RSC_LEN); } /* check type and validity of keys */ /* check MAC Address validity */ macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam); if (status != TI_OK) { TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n"); return TI_NOK; } /* check key length */ if((pKeyDesc->KeyLength != WEP_KEY_LEN_40) && (pKeyDesc->KeyLength != WEP_KEY_LEN_104) && (pKeyDesc->KeyLength != WEP_KEY_LEN_232) && (pKeyDesc->KeyLength != CKIP_KEY_LEN) && (pKeyDesc->KeyLength != TKIP_KEY_LEN) && (pKeyDesc->KeyLength != AES_KEY_LEN) ) { TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Incorrect key length - %d \n", pKeyDesc->KeyLength); return TI_NOK; } if (MAC_EQUAL(macParam.content.ctrlDataCurrentBSSID, pKeyDesc->BSSID)) { macEqual2Associated = TI_TRUE; } if (MAC_EQUAL (pKeyDesc->BSSID, broadcastMacAddr)) { macIsBroadcast = TI_TRUE; } if ((pKeyDesc->KeyLength == WEP_KEY_LEN_40) || (pKeyDesc->KeyLength == WEP_KEY_LEN_104) || (pKeyDesc->KeyLength == WEP_KEY_LEN_232)) { /* In Add WEP the MAC address is nulled, since it's irrelevant */ macEqual2Associated = TI_TRUE; wepKey = TI_TRUE; } if (pKeyDesc->KeyIndex & EXT_KEY_SUPP_AUTHENTICATOR_MASK) { /* The key is being set by an Authenticator - not allowed in IBSS mode */ if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS) { /* in IBSS only Broadcast MAC is allowed */ TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Authenticator set key in IBSS mode !!!\n"); return TI_NOK; } } if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK) { /* the reamining bits in the key index are not 0 (when they should be) */ TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Key index bits 8-27 should be 0 !!!\n"); return TI_NOK; } encodedKeyMaterial.pData = (char *) keyBuffer; /* Check key length according to the cipher suite - TKIP, etc...??? */ if (wepKey) { if (!((pKeyDesc->KeyLength == WEP_KEY_LEN_40) || (pKeyDesc->KeyLength == WEP_KEY_LEN_104) || (pKeyDesc->KeyLength == WEP_KEY_LEN_232))) { /*Invalid key length*/ TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "WEP_KEY_PARSER: ERROR: Invalid Key length: %d !!!\n", pKeyDesc->KeyLength); return TI_NOK; } os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength); if (MAC_EQUAL (nullMacAddr, pKeyDesc->BSSID)) { macIsBroadcast = TI_TRUE; } encodedKeyMaterial.keyLen = pKeyDesc->KeyLength; } else /* this is TKIP or CKIP */ { if ((pKeyDesc->KeyLength == CKIP_KEY_LEN) && (pKeyParser->pPaeConfig->unicastSuite == TWD_CIPHER_CKIP)) { os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength); encodedKeyMaterial.keyLen = pKeyDesc->KeyLength; } else { os_memoryCopy(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength); encodedKeyMaterial.keyLen = MAC_ADDR_LEN+KEY_RSC_LEN+pKeyDesc->KeyLength; } } encodedKeyMaterial.keyId = pKeyDesc->KeyIndex; TRACE2(pKeyParser->hReport, REPORT_SEVERITY_INFORMATION, "EXT_KEY_PARSER: Key received keyId=%x, keyLen=%d \n", pKeyDesc->KeyIndex, pKeyDesc->KeyLength ); if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK) { /* Pairwise key */ /* check that the lower 8 bits of the key index are 0 */ if (!wepKey && (pKeyDesc->KeyIndex & 0xff)) { TRACE0(pKeyParser->hReport, REPORT_SEVERITY_WARNING, "EXT_KEY_PARSER: ERROR: Pairwise key must have index 0 !!!\n"); return TI_NOK; } if (macIsBroadcast) { TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Broadcast MAC address for unicast !!!\n"); return TI_NOK; } if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) { /* tx only pairwase key */ /* set unicast keys */ if (pKeyParser->pUcastKey->recvSuccess!=NULL) { status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial); } } else { /* recieve only pairwase keys are not allowed */ TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: recieve only pairwase keys are not allowed !!!\n"); return TI_NOK; } } else { /* set broadcast keys */ if (!macIsBroadcast) { /* not broadcast MAC */ if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS) { /* in IBSS only Broadcast MAC is allowed */ TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: not broadcast MAC in IBSS mode !!!\n"); return TI_NOK; } else if (!macEqual2Associated) { /* ESS mode and MAC is different than the associated one */ /* save the key for later */ status = TI_OK; /* pKeyParser->pBcastKey->saveKey(pKeyParser->pBcastKey, &encodedKey);*/ } else { /* MAC is equal to the associated one - configure immediately */ if (!wepKey) { MAC_COPY (keyBuffer, broadcastMacAddr); } if (pKeyParser->pBcastKey->recvSuccess!=NULL) { status = pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial); } } } else { /* MAC is broadcast - configure immediately */ if (!wepKey) { MAC_COPY (keyBuffer, broadcastMacAddr); } /* set broadcast key */ if (pKeyParser->pBcastKey->recvSuccess!=NULL) { status = pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial); } if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) { /* Group key used to transmit */ /* set as unicast key as well */ if (pKeyParser->pUcastKey->recvSuccess!=NULL) { status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial); } } } } return status; }