/************************************************************************ * 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; }
/************************************************************************ * bitMapToNetworkStringRates * ************************************************************************ DESCRIPTION: Converts bit map to the rates string INPUT: suppRatesBitMap - bit map of supported rates basicRatesBitMap - bit map of basic rates OUTPUT: string - network format rates array, len - rates array length firstOFDMrateLoc - the index of first OFDM rate in the rates array. RETURN: None ************************************************************************/ TI_STATUS rate_DrvBitmapToNetStrIncluding11n (TI_UINT32 uSuppRatesBitMap, TI_UINT32 uBasicRatesBitMap, TI_UINT8 *string, TI_UINT32 *pFirstOfdmRate) { TI_UINT32 i = 0; rate_DrvBitmapToNetStr (uSuppRatesBitMap, uBasicRatesBitMap, string, &i, pFirstOfdmRate); if (uSuppRatesBitMap & DRV_RATE_MASK_MCS_0_OFDM) { if (uBasicRatesBitMap & DRV_RATE_MASK_MCS_0_OFDM) { string[i++] = NET_RATE_MCS0_BASIC; } else { string[i++] = NET_RATE_MCS0; } } if (uSuppRatesBitMap & DRV_RATE_MASK_MCS_1_OFDM) { if (uBasicRatesBitMap & DRV_RATE_MASK_MCS_1_OFDM) { string[i++] = NET_RATE_MCS1_BASIC; } else { string[i++] = NET_RATE_MCS1; } } if (uSuppRatesBitMap & DRV_RATE_MASK_MCS_2_OFDM) { if (uBasicRatesBitMap & DRV_RATE_MASK_MCS_2_OFDM) { string[i++] = NET_RATE_MCS2_BASIC; } else { string[i++] = NET_RATE_MCS2; } } if (uSuppRatesBitMap & DRV_RATE_MASK_MCS_3_OFDM) { if (uBasicRatesBitMap & DRV_RATE_MASK_MCS_3_OFDM) { string[i++] = NET_RATE_MCS3_BASIC; } else { string[i++] = NET_RATE_MCS3; } } if (uSuppRatesBitMap & DRV_RATE_MASK_MCS_4_OFDM) { if (uBasicRatesBitMap & DRV_RATE_MASK_MCS_4_OFDM) { string[i++] = NET_RATE_MCS4_BASIC; } else { string[i++] = NET_RATE_MCS4; } } if (uSuppRatesBitMap & DRV_RATE_MASK_MCS_5_OFDM) { if (uBasicRatesBitMap & DRV_RATE_MASK_MCS_5_OFDM) { string[i++] = NET_RATE_MCS5_BASIC; } else { string[i++] = NET_RATE_MCS5; } } if (uSuppRatesBitMap & DRV_RATE_MASK_MCS_6_OFDM) { if (uBasicRatesBitMap & DRV_RATE_MASK_MCS_6_OFDM) { string[i++] = NET_RATE_MCS6_BASIC; } else { string[i++] = NET_RATE_MCS6; } } if (uSuppRatesBitMap & DRV_RATE_MASK_MCS_7_OFDM) { if (uBasicRatesBitMap & DRV_RATE_MASK_MCS_7_OFDM) { string[i++] = NET_RATE_MCS7_BASIC; } else { string[i++] = NET_RATE_MCS7; } } return TI_OK; }
/** * \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; }
/** * \fn mlme_assocRatesBuild * \brief builds the rates IE of assoc request * * builds the rates IE of assoc request according to the mlme params * * \param pCtx - pointer to mlme_t * \param pRates - <output> pointer to the built rates buffer * \param ratesLen - <output> length of the built rates buffer * \return TI_OK if auth send successfully * TI_NOK otherwise * * \sa mlme_assocRequestMsgBuild */ TI_STATUS mlme_assocRatesBuild(mlme_t *pCtx, TI_UINT8 *pRates, TI_UINT32 *ratesLen) { paramInfo_t param; TI_STATUS status; TI_UINT32 rateSuppMask, rateBasicMask; dot11_RATES_t *pDot11Rates; TI_UINT32 len = 0, ofdmIndex = 0; TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES]; EDot11Mode mode; TI_UINT32 suppRatesLen, extSuppRatesLen, i; pDot11Rates = (dot11_RATES_t*)pRates; /* 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; } /* get operational mode */ 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; /* convert the bit map to the rates array */ /* remove MCS rates from Extended Supported Rates IE */ rateSuppMask &= ~(DRV_RATE_MASK_MCS_0_OFDM | DRV_RATE_MASK_MCS_1_OFDM | DRV_RATE_MASK_MCS_2_OFDM | DRV_RATE_MASK_MCS_3_OFDM | DRV_RATE_MASK_MCS_4_OFDM | DRV_RATE_MASK_MCS_5_OFDM | DRV_RATE_MASK_MCS_6_OFDM | DRV_RATE_MASK_MCS_7_OFDM ); rate_DrvBitmapToNetStr (rateSuppMask, rateBasicMask, ratesBuf, &len, &ofdmIndex); if(mode != DOT11_G_MODE || ofdmIndex == len ) { pDot11Rates->hdr[0] = SUPPORTED_RATES_IE_ID; pDot11Rates->hdr[1] = len; os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, len); *ratesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); } else { /* fill in the supported rates */ pDot11Rates->hdr[0] = SUPPORTED_RATES_IE_ID; pDot11Rates->hdr[1] = ofdmIndex; os_memoryCopy(NULL, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); suppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); /* fill in the extended supported rates */ pDot11Rates = (dot11_RATES_t*)(pRates + suppRatesLen); pDot11Rates->hdr[0] = EXT_SUPPORTED_RATES_IE_ID; pDot11Rates->hdr[1] = len - ofdmIndex; os_memoryCopy(NULL, (void *)pDot11Rates->rates, &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]); extSuppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); *ratesLen = suppRatesLen + extSuppRatesLen; } TRACE3(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - bitmapSupp= 0x%X,bitMapBasic = 0x%X, len = %d\n", rateSuppMask,rateBasicMask,len); for(i=0; i<len; i++) { TRACE2(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - ratesBuf[%d] = 0x%X\n", i, ratesBuf[i]); } return TI_OK; }
/** * \fn scanResultTable_GetBssidList * \brief Retrieves the site table content * * Retrieves the site table content * * \param hScanResultTable - handle to the scan result table object * \param pBssidList - pointer to a buffer large enough to hols the BSSID list * \param plength - length of the supplied buffer, will be overwritten with the actual list length * \param bAllVarIes - whether to include all variable size IEs * \return None * \sa scanResultTable_CalculateBssidListSize */ TI_STATUS scanResultTable_GetBssidList (TI_HANDLE hScanResultTable, OS_802_11_BSSID_LIST_EX *pBssidList, TI_UINT32 *pLength, TI_BOOL bAllVarIes) { TScanResultTable *pScanResultTable = (TScanResultTable*)hScanResultTable; TI_UINT32 uLength, uSiteIndex, rsnIndex, rsnIeLength, len, firstOFDMloc = 0; TSiteEntry *pSiteEntry; OS_802_11_BSSID_EX *pBssid; OS_802_11_FIXED_IEs *pFixedIes; OS_802_11_VARIABLE_IEs *pVarIes; TI_UINT8 *pData; /* verify the supplied length is enough */ uLength = scanResultTable_CalculateBssidListSize (hScanResultTable, bAllVarIes); if (uLength > *pLength) { *pLength = uLength; return TI_NOK; } /* Nullify number of items in the BSSID list */ pBssidList->NumberOfItems = 0; /* set length to list header size (only list count) */ uLength = sizeof(OS_802_11_BSSID_LIST_EX) - sizeof(OS_802_11_BSSID_EX); /* set data pointer to first item in list */ pData = (TI_UINT8*)&(pBssidList->Bssid[0]); for (uSiteIndex = 0; uSiteIndex < pScanResultTable->uCurrentSiteNumber; uSiteIndex++) { /* set BSSID entry pointer to current location in buffer */ pBssid = (OS_802_11_BSSID_EX*)pData; /* set pointer to site entry */ pSiteEntry = &(pScanResultTable->pTable[ uSiteIndex ]); /* start copy stuff: */ /* MacAddress */ MAC_COPY (pBssid->MacAddress, pSiteEntry->bssid); /* Capabilities */ pBssid->Capabilities = pSiteEntry->capabilities; /* SSID */ os_memoryZero (pScanResultTable->hOS, &(pBssid->Ssid.Ssid), MAX_SSID_LEN); if (pSiteEntry->ssid.len > MAX_SSID_LEN) { pSiteEntry->ssid.len = MAX_SSID_LEN; } os_memoryCopy (pScanResultTable->hOS, (void *)pBssid->Ssid.Ssid, (void *)pSiteEntry->ssid.str, pSiteEntry->ssid.len); pBssid->Ssid.SsidLength = pSiteEntry->ssid.len; /* privacy */ pBssid->Privacy = pSiteEntry->privacy; /* RSSI */ pBssid->Rssi = pSiteEntry->rssi; pBssid->Configuration.Length = sizeof(OS_802_11_CONFIGURATION); pBssid->Configuration.BeaconPeriod = pSiteEntry->beaconInterval; pBssid->Configuration.ATIMWindow = pSiteEntry->atimWindow; pBssid->Configuration.Union.channel = Chan2Freq(pSiteEntry->channel); if (pSiteEntry->bssType == BSS_INDEPENDENT) pBssid->InfrastructureMode = os802_11IBSS; else pBssid->InfrastructureMode = os802_11Infrastructure; /* Supported Rates */ os_memoryZero (pScanResultTable->hOS, (void *)pBssid->SupportedRates, sizeof(OS_802_11_RATES_EX)); rate_DrvBitmapToNetStr (pSiteEntry->rateMask.supportedRateMask, pSiteEntry->rateMask.basicRateMask, (TI_UINT8*)pBssid->SupportedRates, &len, &firstOFDMloc); /* set network type acording to band and rates */ if (RADIO_BAND_2_4_GHZ == pSiteEntry->eBand) { if (firstOFDMloc == len) { pBssid->NetworkTypeInUse = os802_11DS; } else { pBssid->NetworkTypeInUse = os802_11OFDM24; } } else { pBssid->NetworkTypeInUse = os802_11OFDM5; } /* start copy IE's: first nullify length */ pBssid->IELength = 0; /* copy fixed IEs from site entry */ pFixedIes = (OS_802_11_FIXED_IEs*)&(pBssid->IEs[ pBssid->IELength ]); os_memoryCopy (pScanResultTable->hOS, (void*)pFixedIes->TimeStamp, &(pSiteEntry->tsfTimeStamp[ 0 ]), TIME_STAMP_LEN); pFixedIes->BeaconInterval = pSiteEntry->beaconInterval; pFixedIes->Capabilities = pSiteEntry->capabilities; pBssid->IELength += sizeof(OS_802_11_FIXED_IEs); /* set pointer for variable length IE's */ pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]); if (!bAllVarIes) { /* copy only some variable IEs */ /* copy SSID */ pVarIes->ElementID = SSID_IE_ID; pVarIes->Length = pSiteEntry->ssid.len; os_memoryCopy (pScanResultTable->hOS, (void *)pVarIes->data, (void *)pSiteEntry->ssid.str, pSiteEntry->ssid.len); pBssid->IELength += (pVarIes->Length + 2); /* copy RATES */ pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]); pVarIes->ElementID = SUPPORTED_RATES_IE_ID; rate_DrvBitmapToNetStr (pSiteEntry->rateMask.supportedRateMask, pSiteEntry->rateMask.basicRateMask, (TI_UINT8 *)pVarIes->data, &len, &firstOFDMloc); pVarIes->Length = len; pBssid->IELength += (pVarIes->Length + 2); /* copy DS */ pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]); pVarIes->ElementID = DS_PARAMETER_SET_IE_ID; pVarIes->Length = DOT11_DS_PARAMS_ELE_LEN; os_memoryCopy (pScanResultTable->hOS, (void *)pVarIes->data, &(pSiteEntry->channel), DOT11_DS_PARAMS_ELE_LEN); pBssid->IELength += (pVarIes->Length + 2); /* copy RSN information elements */ if (0 < pSiteEntry->rsnIeLen) { rsnIeLength = 0; for (rsnIndex=0; rsnIndex < MAX_RSN_IE && pSiteEntry->pRsnIe[ rsnIndex ].hdr[1] > 0; rsnIndex++) { pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength + rsnIeLength ]); pVarIes->ElementID = pSiteEntry->pRsnIe[ rsnIndex ].hdr[0]; pVarIes->Length = pSiteEntry->pRsnIe[ rsnIndex ].hdr[1]; os_memoryCopy (pScanResultTable->hOS, (void *)pVarIes->data, (void *)pSiteEntry->pRsnIe[ rsnIndex ].rsnIeData, pSiteEntry->pRsnIe[ rsnIndex ].hdr[1]); rsnIeLength += pSiteEntry->pRsnIe[ rsnIndex ].hdr[1] + 2; } pBssid->IELength += pSiteEntry->rsnIeLen; } /* QOS_WME/XCC */ if (TI_TRUE == pSiteEntry->WMESupported) { /* oui */ TI_UINT8 ouiWME[3] = {0x50, 0xf2, 0x01}; dot11_WME_PARAM_t *pWMEParams; /* fill in the general element parameters */ pVarIes = (OS_802_11_VARIABLE_IEs*)&(pBssid->IEs[ pBssid->IELength ]); pVarIes->ElementID = DOT11_WME_ELE_ID; pVarIes->Length = DOT11_WME_PARAM_ELE_LEN; /* fill in the specific element parameters */ pWMEParams = (dot11_WME_PARAM_t*)pVarIes; os_memoryCopy (pScanResultTable->hOS, (void *)pWMEParams->OUI, ouiWME, 3); pWMEParams->OUIType = dot11_WME_OUI_TYPE; pWMEParams->OUISubType = dot11_WME_OUI_SUB_TYPE_PARAMS_IE; pWMEParams->version = dot11_WME_VERSION; pWMEParams->ACInfoField = dot11_WME_ACINFO_MASK & pSiteEntry->lastWMEParameterCnt; /* fill in the data */ os_memoryCopy (pScanResultTable->hOS, &(pWMEParams->WME_ACParameteres), &(pSiteEntry->WMEParameters), sizeof(dot11_ACParameters_t)); /* update the general length */ pBssid->IELength += (pVarIes->Length + 2); } /* Copy the unknown IEs */ if ( 0 < pSiteEntry->unknownIeLen ) { os_memoryCopy (pScanResultTable->hOS, (void *)(&pBssid->IEs[ pBssid->IELength ]), (void *)pSiteEntry->pUnknownIe, pSiteEntry->unknownIeLen ); pBssid->IELength += pSiteEntry->unknownIeLen; } } else { /* Copy all variable IEs */ if (pSiteEntry->probeRecv) { /* It looks like it never happens. Anyway decided to check */ if ( pSiteEntry->probeRespLength > MAX_BEACON_BODY_LENGTH ) /* it may have sense to check the Len here for 0 or MIN_BEACON_BODY_LENGTH also */ { handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); return TI_NOK; } os_memoryCopy (pScanResultTable->hOS, pVarIes, pSiteEntry->probeRespBuffer, pSiteEntry->probeRespLength); pBssid->IELength += pSiteEntry->probeRespLength; } else { /* It looks like it never happens. Anyway decided to check */ if ( pSiteEntry->beaconLength > MAX_BEACON_BODY_LENGTH ) /* it may have sense to check the Len here for 0 or MIN_BEACON_BODY_LENGTH also */ { handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); return TI_NOK; } os_memoryCopy (pScanResultTable->hOS, pVarIes, pSiteEntry->beaconBuffer, pSiteEntry->beaconLength); pBssid->IELength += pSiteEntry->beaconLength; } } /* -1 to remove the IEs[1] placeholder in OS_802_11_BSSID_EX which is taken into account in pBssid->IELength */ pBssid->Length = sizeof(OS_802_11_BSSID_EX) + pBssid->IELength - 1; /* make sure length is 4 bytes aligned */ if (pBssid->Length % 4) { pBssid->Length += (4 - (pBssid->Length % 4)); } pData += pBssid->Length; uLength += pBssid->Length; } pBssidList->NumberOfItems = pScanResultTable->uCurrentSiteNumber; *pLength = uLength; return TI_OK; }