/************************************************************************ * 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; }
/** * \fn scanCncnOsSm_ActionStartAScan * \brief Scan concentartor OS state machine start scan on A action function * * Scan concentartor OS state machine start scan on A action function. * Starts a sacn on A using all allowed channels * * \param hScanCncn - handle to the scan concentartor object * \return None */ void scanCncnOsSm_ActionStartAScan (TI_HANDLE hScanCncn) { TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; paramInfo_t tParam; TI_UINT32 uValidChannelsCount; TI_BOOL bRegulatoryDomainEnabled; /* if the STA is not configured for G band or dual band, send a scan complete event to the SM */ tParam.paramType = SITE_MGR_DESIRED_DOT11_MODE_PARAM; siteMgr_getParam (pScanCncn->hSiteManager, &tParam); if ((DOT11_A_MODE != tParam.content.siteMgrDot11Mode) && (DOT11_DUAL_MODE != tParam.content.siteMgrDot11Mode)) { TRACE0(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnOsSm_ActionStartAScan: STA does not work on 5.0 GHz, quitting\n"); genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_SCAN_COMPLETE, hScanCncn); return; } /* build scan command header */ pScanCncn->tOsScanParams.band = RADIO_BAND_5_0_GHZ; pScanCncn->tOsScanParams.Tid = 0; /* query the regulatory domain if 802.11d is in use */ tParam.paramType = REGULATORY_DOMAIN_ENABLED_PARAM; regulatoryDomain_getParam (pScanCncn->hRegulatoryDomain, &tParam ); bRegulatoryDomainEnabled = tParam.content.regulatoryDomainEnabled; /* Get country code status */ tParam.paramType = REGULATORY_DOMAIN_IS_COUNTRY_FOUND; tParam.content.eRadioBand = RADIO_BAND_5_0_GHZ; regulatoryDomain_getParam (pScanCncn->hRegulatoryDomain, &tParam); /* scan type is passive if 802.11d is enabled and country IE was not yet found, active otherwise */ if (((TI_TRUE == bRegulatoryDomainEnabled) && (TI_FALSE == tParam.content.bIsCountryFound)) || SCAN_TYPE_TRIGGERED_PASSIVE == pScanCncn->tOsScanParams.scanType) { pScanCncn->tOsScanParams.scanType = SCAN_TYPE_TRIGGERED_PASSIVE; } /* All paramters in the func are hard coded, due to that we set to active if not passive */ else { pScanCncn->tOsScanParams.scanType = SCAN_TYPE_TRIGGERED_ACTIVE; /* also set number and rate of probe requests */ pScanCncn->tOsScanParams.probeReqNumber = SCAN_OID_DEFAULT_PROBE_REQUEST_NUMBER_A; pScanCncn->tOsScanParams.probeRequestRate = (ERateMask)SCAN_OID_DEFAULT_PROBE_REQUEST_RATE_A; } /* add supported channels on G */ if (SCAN_TYPE_NORMAL_PASSIVE == pScanCncn->tOsScanParams.scanType ) { uValidChannelsCount = scanCncnOsSm_FillAllAvailableChannels (hScanCncn, RADIO_BAND_5_0_GHZ, SCAN_TYPE_NORMAL_PASSIVE, &(pScanCncn->tOsScanParams.channelEntry[0]), SCAN_OID_DEFAULT_MAX_DWELL_TIME_PASSIVE_A, SCAN_OID_DEFAULT_MIN_DWELL_TIME_PASSIVE_A, SCAN_OID_DEFAULT_EARLY_TERMINATION_EVENT_PASSIVE_A, SCAN_OID_DEFAULT_EARLY_TERMINATION_COUNT_PASSIVE_A ); } else { uValidChannelsCount = scanCncnOsSm_FillAllAvailableChannels (hScanCncn, RADIO_BAND_5_0_GHZ, SCAN_TYPE_NORMAL_ACTIVE, &(pScanCncn->tOsScanParams.channelEntry[0]), SCAN_OID_DEFAULT_MAX_DWELL_TIME_ACTIVE_A, SCAN_OID_DEFAULT_MIN_DWELL_TIME_ACTIVE_A, SCAN_OID_DEFAULT_EARLY_TERMINATION_EVENT_ACTIVE_A, SCAN_OID_DEFAULT_EARLY_TERMINATION_COUNT_ACTIVE_A ); } pScanCncn->tOsScanParams.numOfChannels = uValidChannelsCount; /* check that some channels are available */ if ( uValidChannelsCount > 0 ) { EScanCncnResultStatus eResult; /* send command to scan concentrator APP SM */ eResult = scanCncn_Start1ShotScan (hScanCncn, SCAN_SCC_APP_ONE_SHOT, &(pScanCncn->tOsScanParams)); /* if scan failed, send scan complete event to the SM */ if (SCAN_CRS_SCAN_RUNNING != eResult) { TRACE0(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncnOsSm_ActionStartAScan: scan failed on 5.0 GHz, quitting\n"); genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_SCAN_COMPLETE, hScanCncn); } } else { TRACE0(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncnOsSm_ActionStartGScan: no valid cahnnels on 5.0 GHz, quitting\n"); /* no channels to scan, send a scan complete event */ genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_SCAN_COMPLETE, hScanCncn); } }
/** * \fn scanCncnOsSm_FillAllAvailableChannels * \brief Fills a chhanel array with valid channels (and their params) according to band and scan type * * Fills a chhanel array with valid channels (and their params) according to band and scan type * * \param hScanCncn - handle to the scan concentrator object * \param eBand - band to extract channels for * \param eScanType - scan type tp ectract channels for * \param pChannelArray - where to store allowed channels information * \param uMaxDwellTime - maximum dwell time value to be used for each channel * \param uMinDwellTime - minimum dwell time value to be used for each channel * \param eETCondition - early termination condition value to be used for each channel * \param uETFrameNumber - early termination frame number value to be used for each channel * \return Number of allowed channels (that were placed in the given channels array) */ TI_UINT32 scanCncnOsSm_FillAllAvailableChannels (TI_HANDLE hScanCncn, ERadioBand eBand, EScanType eScanType, TScanChannelEntry *pChannelArray, TI_UINT32 uMaxDwellTime, TI_UINT32 uMinChannelTime, EScanEtCondition eETCondition, TI_UINT8 uETFrameNumber) { TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; TI_UINT32 i, j, uAllowedChannelsCount, uValidChannelsCnt = 0; paramInfo_t tParam; TI_UINT8 uTempChannelList[ SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND ]; /* get the numnber of supported channels for this band */ tParam.paramType = REGULATORY_DOMAIN_ALL_SUPPORTED_CHANNELS; tParam.content.siteMgrRadioBand = eBand; regulatoryDomain_getParam (pScanCncn->hRegulatoryDomain, &tParam); uAllowedChannelsCount = tParam.content.supportedChannels.sizeOfList; /* for the time being don't scan more channels than fit in one command */ if (uAllowedChannelsCount > SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND) { uAllowedChannelsCount = SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND; } /* Copy allowed channels to reuse param var */ os_memoryCopy (pScanCncn->hOS, uTempChannelList, tParam.content.supportedChannels.listOfChannels, uAllowedChannelsCount ); /* preapre the param var to request channel allowance for the requested scan type */ tParam.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; tParam.content.channelCapabilityReq.band = eBand; /* add default values to channels allowed for the requested scan type and band */ for (i = 0; i < uAllowedChannelsCount; i++) { /* get specific channel allowance for scan type */ if ((eScanType == SCAN_TYPE_NORMAL_PASSIVE) || (eScanType == SCAN_TYPE_TRIGGERED_PASSIVE) || (eScanType == SCAN_TYPE_SPS)) { tParam.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; } else { tParam.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; } tParam.content.channelCapabilityReq.channelNum = uTempChannelList[ i ]; regulatoryDomain_getParam( pScanCncn->hRegulatoryDomain, &tParam ); if (TI_TRUE == tParam.content.channelCapabilityRet.channelValidity) { /* add the channel ID */ pChannelArray[ uValidChannelsCnt ].normalChannelEntry.channel = uTempChannelList[ i ]; /* add other default parameters */ pChannelArray[ uValidChannelsCnt ].normalChannelEntry.minChannelDwellTime = uMinChannelTime; pChannelArray[ uValidChannelsCnt ].normalChannelEntry.maxChannelDwellTime = uMaxDwellTime; pChannelArray[ uValidChannelsCnt ].normalChannelEntry.earlyTerminationEvent = eETCondition; pChannelArray[ uValidChannelsCnt ].normalChannelEntry.ETMaxNumOfAPframes = uETFrameNumber; pChannelArray[ uValidChannelsCnt ].normalChannelEntry.txPowerDbm = tParam.content.channelCapabilityRet.maxTxPowerDbm; /* Fill broadcast BSSID */ for (j = 0; j < 6; j++) { pChannelArray[ uValidChannelsCnt ].normalChannelEntry.bssId[ j ] = 0xff; } uValidChannelsCnt++; } } /* return the number of channels that are actually allowed for the requested scan type on the requested band */ return uValidChannelsCnt; }
/** * \fn sme_updateScanCycles * \brief Updates the scan intervals and cycle number according to 802.11d status, country availability and WSC PB mode * * Updates the scan intervals and cycle number according to 802.11d status, country availability and WSC PB mode. * Possible scenarios - D disabled - WSC PB off - scan forever with supplied intervals * - D enabled - country unknown - WSC PB off - scan forever with supplied intervals * - D disabled - WSC PB on - scan for two minutes with zero intervals * - D enabled - country unknown - WSC PB on - scan for two minutes with zero intervals * - D enabled - country known - WSC PB off - scan until country expiry with supplied intervals * - D enabled - country known - WSC PB on - scan for the minimu of two minutes and country expiry with zero intervals * * \param hSme - handle to the SME object * \param bDEnabled - TRUE if 802.11d is enabled * \param bCountryValid - TRUE if a country IE is valid for a band on which we scan * \param bConstantScan - TRUE if WSC PB mode is on * \return None * \sa sme_CalculateCyclesNumber, sme_StartScan */ void sme_updateScanCycles (TI_HANDLE hSme, TI_BOOL bDEnabled, TI_BOOL bCountryValid, TI_BOOL bConstantScan) { TSme *pSme = (TSme*)hSme; TI_UINT32 uIndex, uScanPeriodMs, uScanDurationMs; paramInfo_t *pParam; /* 802.11d is disabled, or no country is valid */ if ((TI_FALSE == bDEnabled) || (TI_FALSE == bCountryValid)) { /* WSC PB mode is disabled */ if (TI_FALSE == bConstantScan) { /* * copy intervals * In order to avoid tight loop of scan-select or scan-select-connecting operation, * the prepare scan function takes into account the value of the scan_count when setting the 16 periods in the scan command */ os_memoryCopy (pSme->hOS, &(pSme->tScanParams.uCycleIntervalMsec[ 0 ]), &(pSme->tInitParams.uScanIntervals[ pSme->uScanCount ]), sizeof (TI_UINT32) * (PERIODIC_SCAN_MAX_INTERVAL_NUM - pSme->uScanCount)); for (uIndex = (PERIODIC_SCAN_MAX_INTERVAL_NUM - pSme->uScanCount); uIndex < PERIODIC_SCAN_MAX_INTERVAL_NUM; uIndex++) { pSme->tScanParams.uCycleIntervalMsec[ uIndex ] = pSme->tInitParams.uScanIntervals[ PERIODIC_SCAN_MAX_INTERVAL_NUM - 1 ]; } /* scan for default number (until a result is found) */ pSme->tScanParams.uCycleNum = pSme->tInitParams.uCycleNum; } /* WSC PB mode is enabled */ else { /* nullify all intervals */ os_memoryZero (pSme->hOS, &(pSme->tScanParams.uCycleIntervalMsec[ 0 ]), sizeof (TI_UINT32) * PERIODIC_SCAN_MAX_INTERVAL_NUM); /* calculate the duration of one scan cycle */ uScanDurationMs = 0; for (uIndex = 0; uIndex < pSme->tScanParams.uChannelNum; uIndex++) { uScanDurationMs += pSme->tScanParams.tChannels[ uIndex ].uMaxDwellTimeMs; } /* set the number of cycles - 2 minutes divided by one cycle duration */ pSme->tScanParams.uCycleNum = (120000 / uScanDurationMs) + 1; } } /* 802.11d is enabled, and country is valid on at least one band */ else { pParam = (paramInfo_t *)os_memoryAlloc(pSme->hOS, sizeof(paramInfo_t)); if (!pParam) { return; } /* get country expiry time */ pParam->paramType = REGULATORY_DOMAIN_TIME_TO_COUNTRY_EXPIRY; regulatoryDomain_getParam (pSme->hRegDomain, pParam); /* WSC PB mode is disabled */ if (TI_FALSE == bConstantScan) { /* * copy intervals * In order to avoid tight loop of scan-select or scan-select-connecting operation, * the prepare scan function takes into account the value of the scan_count when setting the 16 periods in the scan command */ os_memoryCopy (pSme->hOS, &(pSme->tScanParams.uCycleIntervalMsec[ 0 ]), &(pSme->tInitParams.uScanIntervals[ pSme->uScanCount ]), sizeof (TI_UINT32) * (PERIODIC_SCAN_MAX_INTERVAL_NUM - pSme->uScanCount)); for (uIndex = (PERIODIC_SCAN_MAX_INTERVAL_NUM - pSme->uScanCount); uIndex < PERIODIC_SCAN_MAX_INTERVAL_NUM; uIndex++) { pSme->tScanParams.uCycleIntervalMsec[ uIndex ] = pSme->tInitParams.uScanIntervals[ PERIODIC_SCAN_MAX_INTERVAL_NUM - 1 ]; } /* set cycle number according to country expiry time */ sme_CalculateCyclesNumber (hSme, pParam->content.uTimeToCountryExpiryMs); } /* WSC PB mode is enabled */ else { /* turn off WSC PB mode (for next scan) */ pSme->bConstantScan = TI_FALSE; /* set scan period to minimum of WSC PB duration (2 minutes) and country expiry time */ uScanPeriodMs = TI_MIN (120000, pParam->content.uTimeToCountryExpiryMs); /* nullify all intervals */ os_memoryZero (pSme->hOS, &(pSme->tScanParams.uCycleIntervalMsec[ 0 ]), sizeof (TI_UINT32) * PERIODIC_SCAN_MAX_INTERVAL_NUM); /* calculate the duration of one scan cycle */ uScanDurationMs = 0; for (uIndex = 0; uIndex < pSme->tScanParams.uChannelNum; uIndex++) { uScanDurationMs += pSme->tScanParams.tChannels[ uIndex ].uMaxDwellTimeMs; } if (uScanDurationMs != 0) { /* set the number of cycles - scan period divided by one cycle duration */ pSme->tScanParams.uCycleNum = (uScanPeriodMs / uScanDurationMs) + 1; } else { pSme->tScanParams.uCycleNum = pSme->tInitParams.uCycleNum; } } os_memoryFree(pSme->hOS, pParam, sizeof(paramInfo_t)); } /* in case independent mode and to avoid supplicant send disconnect event after 60s */ if (pSme->eBssType != BSS_INFRASTRUCTURE) { pSme->tScanParams.uCycleNum = 1; } }
/** * Called when the SCR callbacks with a RUN response or if the SCR * returned a RUN response when we requested it. * * @date 05-Jan-2006 */ static TI_STATUS measurementMgrSM_acStartMeasurement(void * pData) { measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) pData; /* Cryptic: the first struct is the requestHandler request while */ /* the second one is the measurementSRV request */ MeasurementRequest_t * pRequestArr[MAX_NUM_REQ]; TMeasurementRequest request; paramInfo_t *pParam; TI_UINT8 numOfRequestsInParallel; TI_UINT8 requestIndex; TI_UINT32 timePassed; TI_BOOL requestedBeaconMeasurement= TI_FALSE; TI_STATUS status; TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Starting Measurement operation\n"); pParam = (paramInfo_t *)os_memoryAlloc(pMeasurementMgr->hOs, sizeof(paramInfo_t)); if (!pParam) { return TI_NOK; } request.channel = pMeasurementMgr->measuredChannelID; request.startTime = 0; /* ignored by MeasurementSRV for now - for .11k */ request.numberOfTypes = 0; TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measured Channel = %d\n", pMeasurementMgr->measuredChannelID); pParam->paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; pParam->content.channelCapabilityReq.channelNum = pMeasurementMgr->measuredChannelID; pParam->content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; if (pMeasurementMgr->measuredChannelID <= MAX_CHANNEL_IN_BAND_2_4) { request.band = RADIO_BAND_2_4_GHZ; pParam->content.channelCapabilityReq.band = RADIO_BAND_2_4_GHZ; } else { request.band = RADIO_BAND_5_0_GHZ; pParam->content.channelCapabilityReq.band = RADIO_BAND_5_0_GHZ; } regulatoryDomain_getParam(pMeasurementMgr->hRegulatoryDomain, pParam); request.txPowerDbm = pParam->content.channelCapabilityRet.maxTxPowerDbm; request.eTag = SCAN_RESULT_TAG_MEASUREMENT; os_memoryFree(pMeasurementMgr->hOs, pParam, sizeof(paramInfo_t)); TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Querying Request Handler for the next request in the queue\n"); /* Getting the next request/requests from the request handler */ status = requestHandler_getNextReq(pMeasurementMgr->hRequestH, TI_TRUE, pRequestArr, &numOfRequestsInParallel); if (status != TI_OK) { TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_ERROR, ": Failed getting next request from Request Handler\n"); return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), MEASUREMENTMGR_EVENT_COMPLETE, pMeasurementMgr); } /* Save the number of requests in parallel so that once the */ /* measurement operation ends we can get rid of this amount of requests */ /* from the requestHandler */ pMeasurementMgr->currentNumOfRequestsInParallel = numOfRequestsInParallel; for (requestIndex = 0; requestIndex < numOfRequestsInParallel; requestIndex++) { if (pRequestArr[requestIndex]->Type == MSR_TYPE_BEACON_MEASUREMENT) { requestedBeaconMeasurement = TI_TRUE; if (pRequestArr[requestIndex]->ScanMode == MSR_SCAN_MODE_BEACON_TABLE) { TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Beacon Table request encountered, building report now\n"); /* building Report for beacon table request */ pMeasurementMgr->buildReport(pMeasurementMgr, *pRequestArr[requestIndex], NULL); continue; } } /* save the request so we can reference it when results arrive */ pMeasurementMgr->currentRequest[request.numberOfTypes] = pRequestArr[requestIndex]; /* add the measurement type to the request's list */ request.msrTypes[request.numberOfTypes].duration = pRequestArr[requestIndex]->DurationTime; request.msrTypes[request.numberOfTypes].scanMode = pRequestArr[requestIndex]->ScanMode; request.msrTypes[request.numberOfTypes].msrType = pRequestArr[requestIndex]->Type; TRACE3(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ":\n\nMeasurement Request #%d Details: Type = %d, Duration = %d\n\n", request.numberOfTypes+1, request.msrTypes[request.numberOfTypes].msrType, request.msrTypes[request.numberOfTypes].duration); request.numberOfTypes++; } if (requestedBeaconMeasurement == TI_TRUE) { /* build a probe request template and send it to the HAL */ TSetTemplate templateStruct; probeReqTemplate_t probeReqTemplate; TSsid broadcastSSID; templateStruct.ptr = (TI_UINT8 *) &probeReqTemplate; templateStruct.type = PROBE_REQUEST_TEMPLATE; templateStruct.eBand = request.band; templateStruct.uRateMask = RATE_MASK_UNSPECIFIED; broadcastSSID.len = 0; TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Sending probe request template...\n"); buildProbeReqTemplate( pMeasurementMgr->hSiteMgr, &templateStruct, &broadcastSSID, request.band ); #ifdef XCC_MODULE_INCLUDED { /* Insert Radio Mngt Capability IE according XCC4*/ TI_UINT32 len = 0; measurementMgr_radioMngtCapabilityBuild (pMeasurementMgr, templateStruct.ptr + templateStruct.len, (TI_UINT8*)&len); templateStruct.len += len; } #endif TWD_CmdTemplate (pMeasurementMgr->hTWD, &templateStruct, NULL, NULL); } /* Check if the maximum time to wait for the measurement request to */ /* finish has already passed */ timePassed = os_timeStampMs(pMeasurementMgr->hOs) - pMeasurementMgr->currentRequestStartTime; if (timePassed > MSR_START_MAX_DELAY) { TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Maximum delay to perform measurement operation has passed (%d / %d)\n", MSR_START_MAX_DELAY, (os_timeStampMs(pMeasurementMgr->hOs) - pMeasurementMgr->currentRequestStartTime)); pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequestsInParallel, MSR_REJECT_MAX_DELAY_PASSED); return measurementMgrSM_event((TI_UINT8 *) &(pMeasurementMgr->currentState), MEASUREMENTMGR_EVENT_COMPLETE, pMeasurementMgr); } /* Yalla, start measuring */ TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Finished preparing request. Handing over to MeasurementSRV...\n"); TWD_StartMeasurement (pMeasurementMgr->hTWD, &request, MSR_START_MAX_DELAY - timePassed, NULL, NULL, measurementMgr_MeasurementCompleteCB, pMeasurementMgr); return TI_OK; }
/** * \fn smeSm_PreConnect * \brief Initiates the connection process * * Initiates the connection process - for automatic mode, start scan, for manual mode - triggers connection * * \param hSme - handle to the SME object * \return None * \sa smeSm_Connect, smeSm_ConnectSuccess */ void smeSm_PreConnect (TI_HANDLE hSme) { TSme *pSme = (TSme *)hSme; paramInfo_t *pParam; /* set the connection mode with which this connection attempt is starting */ pSme->eLastConnectMode = pSme->eConnectMode; /* mark that no authentication/assocaition was yet sent */ pSme->bAuthSent = TI_FALSE; /* try to find a connection candidate (manual mode have already performed scann */ pSme->pCandidate = sme_Select (hSme); if (NULL != pSme->pCandidate) { /* candidate is available - attempt connection */ sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme); } /* no candidate */ else { if (CONNECT_MODE_AUTO == pSme->eConnectMode) { /* automatic mode - start scanning */ if (TI_OK != sme_StartScan (hSme)) { pSme->bRadioOn = TI_FALSE; sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); } /* update scan count counter */ if (pSme->uScanCount < PERIODIC_SCAN_MAX_INTERVAL_NUM) { pSme->uScanCount++; } } else { /* Manual mode */ /* for IBSS or any, if no entries where found, add the self site */ if (pSme->eBssType == BSS_INFRASTRUCTURE) { /* makr whether we need to stop the attempt connection in manual mode */ pSme->bConnectRequired = TI_FALSE; /* manual mode and no connection candidate is available - connection failed */ sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); } else { /* IBSS */ TI_UINT8 uDesiredChannel; TI_BOOL channelValidity; pSme->bConnectRequired = TI_FALSE; pParam = (paramInfo_t *)os_memoryAlloc(pSme->hOS, sizeof(paramInfo_t)); if (!pParam) { return; } pParam->paramType = SITE_MGR_DESIRED_CHANNEL_PARAM; siteMgr_getParam(pSme->hSiteMgr, pParam); uDesiredChannel = pParam->content.siteMgrDesiredChannel; if (uDesiredChannel >= SITE_MGR_CHANNEL_A_MIN) { pParam->content.channelCapabilityReq.band = RADIO_BAND_5_0_GHZ; } else { pParam->content.channelCapabilityReq.band = RADIO_BAND_2_4_GHZ; } /* update the regulatory domain with the selected band */ /* Check if the selected channel is valid according to regDomain */ pParam->paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; pParam->content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; pParam->content.channelCapabilityReq.channelNum = uDesiredChannel; regulatoryDomain_getParam (pSme->hRegDomain, pParam); channelValidity = pParam->content.channelCapabilityRet.channelValidity; os_memoryFree(pSme->hOS, pParam, sizeof(paramInfo_t)); if (!channelValidity) { sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); return; } pSme->pCandidate = (TSiteEntry *)addSelfSite(pSme->hSiteMgr); if (pSme->pCandidate == NULL) { sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); return; } /* a connection candidate is available, send a connect event */ sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme); } } } }
/** * \fn sme_StartScan * \brief Set scan parameters and calls scan concnetartor to start the scan operation. * * Set scan parameters and calls scan concnetartor to start the scan operation. * * Scan parameters are set according to scan target - find country IE, find desired SSID, or both * (one on each band). To find country IE we use passive scan forever, to find the desired SSID we * use active scan until the current country IE expires. In addition, we take into account the WSC PB * mode - scan constantly for two minutes (but under the country validity and expiry constraints) * * \param hSme - handle to the SME object * \return TI_OK if scan started successfully, TI_NOK otherwise * \sa smeSm_PreConnect */ TI_STATUS sme_StartScan (TI_HANDLE hSme) { TSme *pSme = (TSme*)hSme; paramInfo_t *pParam; TI_BOOL bDEnabled, bCountryValid; TI_BOOL bBandChannelExist[ RADIO_BAND_NUM_OF_BANDS ]; TI_BOOL bBandCountryFound[ RADIO_BAND_NUM_OF_BANDS ]; TI_STATUS tStatus; TI_UINT32 uIndex; /* get 802.11d enable state */ pParam = (paramInfo_t *)os_memoryAlloc(pSme->hOS, sizeof(paramInfo_t)); if (!pParam) { return TI_NOK; } pParam->paramType = REGULATORY_DOMAIN_ENABLED_PARAM; regulatoryDomain_getParam (pSme->hRegDomain, pParam); bDEnabled = pParam->content.regulatoryDomainEnabled; pParam->paramType = REGULATORY_DOMAIN_IS_COUNTRY_FOUND; /* get country validity for all bands */ for (uIndex = 0; uIndex < RADIO_BAND_NUM_OF_BANDS; uIndex++) { pParam->content.eRadioBand = (ERadioBand)uIndex; regulatoryDomain_getParam (pSme->hRegDomain, pParam); bBandCountryFound[ uIndex ] = pParam->content.bIsCountryFound; /* also nullify the channel exist indication for this band */ bBandChannelExist[ uIndex ] = TI_FALSE; } os_memoryFree(pSme->hOS, pParam, sizeof(paramInfo_t)); /* First fill the channels */ for (uIndex = 0; uIndex < pSme->tInitParams.uChannelNum; uIndex++) { /* for each channel, if country is found, set active scan */ pSme->tScanParams.tChannels[ uIndex ].eBand = pSme->tInitParams.tChannelList[ uIndex ].eBand; pSme->tScanParams.tChannels[ uIndex ].uChannel = pSme->tInitParams.tChannelList[ uIndex ].uChannel; pSme->tScanParams.tChannels[ uIndex ].uMaxDwellTimeMs = pSme->tInitParams.uMaxScanDuration; pSme->tScanParams.tChannels[ uIndex ].uMinDwellTimeMs = pSme->tInitParams.uMinScanDuration; pSme->tScanParams.tChannels[ uIndex ].uTxPowerLevelDbm = DEF_TX_POWER; /* if 802.11d is disabled, or country is available for this band */ if ((TI_FALSE == bDEnabled) || (TI_TRUE == bBandCountryFound[ pSme->tInitParams.tChannelList[ uIndex ].eBand ])) { /* set active scan */ pSme->tScanParams.tChannels[ uIndex ].eScanType = SCAN_TYPE_NORMAL_ACTIVE; } /* 802.11d is enabled and no country available */ else { /* set passive scan */ pSme->tScanParams.tChannels[ uIndex ].eScanType = SCAN_TYPE_NORMAL_PASSIVE; /* * in order to fined country set uMaxDwellTimeMs ( that at passive scan set the passiveScanDuration ) * to significant value */ pSme->tScanParams.tChannels[ uIndex ].uMaxDwellTimeMs = SCAN_CNCN_REGULATORY_DOMAIN_PASSIVE_DWELL_TIME_DEF; } /* mark that a channel exists for this band */ bBandChannelExist[ pSme->tInitParams.tChannelList[ uIndex ].eBand ] = TI_TRUE; } /* set number of channels */ pSme->tScanParams.uChannelNum = pSme->tInitParams.uChannelNum; /* now, fill global parameters */ pSme->tScanParams.uProbeRequestNum = pSme->tInitParams.uProbeReqNum; pSme->tScanParams.iRssiThreshold = pSme->tInitParams.iRssiThreshold; pSme->tScanParams.iSnrThreshold = pSme->tInitParams.iSnrThreshold; pSme->tScanParams.bTerminateOnReport = TI_TRUE; pSme->tScanParams.uFrameCountReportThreshold = 1; /* * if for at least one band country is known and scan is performed on this band - means we need to * take into consideration country expiry, plus we are scanning for the desired SSID */ bCountryValid = ((TI_TRUE == bBandChannelExist[ RADIO_BAND_2_4_GHZ ]) && (TI_TRUE == bBandCountryFound[ RADIO_BAND_2_4_GHZ ])) || ((TI_TRUE == bBandChannelExist[ RADIO_BAND_5_0_GHZ ]) && (TI_TRUE == bBandCountryFound[ RADIO_BAND_5_0_GHZ ])); /* set SSID(s) and BSS type according to 802.11d status, and country availability */ /* if 802.11d is disabled */ if (TI_FALSE == bDEnabled) { pSme->tScanParams.eBssType = pSme->eBssType; /* set the deisred SSID, or any SSID if this is the desired SSID */ if (SSID_TYPE_ANY == pSme->eSsidType) { pSme->tScanParams.uSsidNum = 0; pSme->tScanParams.uSsidListFilterEnabled = 1; } else { pSme->tScanParams.tDesiredSsid[ 0 ].eVisability = SCAN_SSID_VISABILITY_HIDDEN; os_memoryCopy (pSme->hOS, &(pSme->tScanParams.tDesiredSsid[ 0 ].tSsid), &(pSme->tSsid), sizeof (TSsid)); pSme->tScanParams.uSsidNum = 1; pSme->tScanParams.uSsidListFilterEnabled = 1; #ifdef XCC_MODULE_INCLUDED pSme->tScanParams.uSsidListFilterEnabled = (TI_UINT8)TI_FALSE; pSme->tScanParams.uSsidNum = 2; pSme->tScanParams.tDesiredSsid[ 1 ].tSsid.len = 0; pSme->tScanParams.tDesiredSsid[ 1 ].eVisability = SCAN_SSID_VISABILITY_PUBLIC; #endif } } /* Country code exists and scan is performed on this band - take country expiry timr into account */ else if (TI_TRUE == bCountryValid) { /* we already know that at least on one band we know the country IE, so we scan for our SSID */ pSme->tScanParams.tDesiredSsid[ 0 ].eVisability = SCAN_SSID_VISABILITY_HIDDEN; os_memoryCopy (pSme->hOS, &(pSme->tScanParams.tDesiredSsid[ 0 ].tSsid), &(pSme->tSsid), sizeof (TSsid)); /* * if, in addition, we scan the other band to find its country, and the desired SSDI is not any SSID, * add an empty SSID */ if ((SSID_TYPE_ANY != pSme->eSsidType) && (((TI_TRUE == bBandChannelExist[ RADIO_BAND_2_4_GHZ ]) && (TI_FALSE == bBandCountryFound[ RADIO_BAND_2_4_GHZ ])) || ((TI_TRUE == bBandChannelExist[ RADIO_BAND_5_0_GHZ ]) && (TI_FALSE == bBandCountryFound[ RADIO_BAND_5_0_GHZ ])))) { pSme->tScanParams.tDesiredSsid[ 1 ].eVisability = SCAN_SSID_VISABILITY_PUBLIC; pSme->tScanParams.tDesiredSsid[ 1 ].tSsid.len = 0; pSme->tScanParams.uSsidNum = 2; pSme->tScanParams.uSsidListFilterEnabled = 1; /* * since we are also looking for an AP with country IE (not include in IBSS), we need to make sure * the desired BSS type include infrastructure BSSes. */ if (BSS_INDEPENDENT == pSme->eBssType) { /* the desired is only IBSS - scan for any */ pSme->tScanParams.eBssType = BSS_ANY; } else { /* the desired is either infrastructure or any - use it */ pSme->tScanParams.eBssType = pSme->eBssType; } } else { pSme->tScanParams.uSsidNum = 1; pSme->tScanParams.uSsidListFilterEnabled = 1; /* only looking for the desired SSID - set the desired BSS type */ pSme->tScanParams.eBssType = pSme->eBssType; } } /* no scanned band has a counrty code - meaning all scan is passive (to find country) */ else { pSme->tScanParams.eBssType = BSS_INFRASTRUCTURE; /* only an AP would transmit a country IE */ pSme->tScanParams.uSsidNum = 0; pSme->tScanParams.uSsidListFilterEnabled = 1; } /* update scan cycle number and scan intervals according to 802.11d status and country availability */ sme_updateScanCycles (hSme, bDEnabled, bCountryValid, pSme->bConstantScan); /* Finally(!!!), start the scan */ tStatus = scanCncn_StartPeriodicScan (pSme->hScanCncn, SCAN_SCC_DRIVER, &(pSme->tScanParams)); if (SCAN_CRS_SCAN_RUNNING != tStatus) { return TI_NOK; } return TI_OK; }
/** * Checks whether the given measurement request is valid. * * @param hMeasurementMgr A handle to the Measurement Manager module. * @param pRequestArr The measurement request. * @param numOfRequest Number of type requests * * @return True iff the request is valid * * @date 01-Jan-2006 */ static TI_BOOL measurementMgr_isRequestValid(TI_HANDLE hMeasurementMgr, MeasurementRequest_t *pRequestArr[], TI_UINT8 numOfRequest) { measurementMgr_t * pMeasurementMgr = (measurementMgr_t *) hMeasurementMgr; TI_UINT8 requestIndex; paramInfo_t param; /* Checking validity of the measured channel number */ param.content.channel = pRequestArr[0]->channelNumber; param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED; regulatoryDomain_getParam(pMeasurementMgr->hRegulatoryDomain, ¶m); if ( !param.content.bIsChannelSupprted ) { TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request rejected due to invalid channel\n"); if (pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST) pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequest, MSR_REJECT_INVALID_CHANNEL); return TI_FALSE; } else { TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request channel is Valid\n"); } TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Starting to check each request:\n"); /* Check Validity of each request */ for (requestIndex = 0; requestIndex < numOfRequest; requestIndex++) { TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Checking request #%d:\n", requestIndex+1); /* Checking validity of the Request Type */ if (pMeasurementMgr->isTypeValid(hMeasurementMgr, pRequestArr[requestIndex]->Type, pRequestArr[requestIndex]->ScanMode) == TI_FALSE) { TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request rejected due to invalid measurement type of request #%d (type = %d)\n", requestIndex+1, pRequestArr[requestIndex]->Type); if(pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST) pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequest, MSR_REJECT_INVALID_MEASUREMENT_TYPE); return TI_FALSE; } else { TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Measurement type of request #%d is supported (type = %d)\n", requestIndex+1, pRequestArr[requestIndex]->Type); } /* For measurement types different than Beacon Table */ if ((pRequestArr[requestIndex]->Type != MSR_TYPE_BEACON_MEASUREMENT) || (pRequestArr[requestIndex]->ScanMode != MSR_SCAN_MODE_BEACON_TABLE)) { /* Checking Measurement request's duration only when request is on a non-serving channel */ if (pMeasurementMgr->servingChannelID != pRequestArr[requestIndex]->channelNumber) { TI_UINT8 dtimPeriod; TI_UINT32 beaconInterval; TI_UINT32 dtimDuration; /* Checking duration doesn't exceed given max duration */ if (pRequestArr[requestIndex]->DurationTime > pMeasurementMgr->maxDurationOnNonServingChannel) { TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Request #%d rejected because duration exceeds maximum duration\n", requestIndex+1); TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Duration = %d, MaxDurationOnNonServingChannel = %d\n", pRequestArr[requestIndex]->DurationTime, pMeasurementMgr->maxDurationOnNonServingChannel); if (pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST) pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequest, MSR_REJECT_DURATION_EXCEED_MAX_DURATION); return TI_FALSE; } else { TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": Duration of request #%d doesn't exceed max duration\n", requestIndex+1); } /* Checking DTIM */ /* Getting the DTIM count */ param.paramType = SITE_MGR_DTIM_PERIOD_PARAM; siteMgr_getParam(pMeasurementMgr->hSiteMgr, ¶m); dtimPeriod = param.content.siteMgrDtimPeriod; /* Getting the beacon Interval */ param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM; siteMgr_getParam(pMeasurementMgr->hSiteMgr, ¶m); beaconInterval = param.content.beaconInterval; dtimDuration = beaconInterval * MEASUREMENT_BEACON_INTERVAL_IN_MICRO_SEC/MEASUREMENT_MSEC_IN_MICRO*dtimPeriod; if (pRequestArr[requestIndex]->DurationTime > dtimDuration) { TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_WARNING, ": Request rejected due to DTIM overlap of request #%d\n", requestIndex+1); TRACE2(pMeasurementMgr->hReport, REPORT_SEVERITY_WARNING, ": Duration = %d, DTIM Duration = %d\n", pRequestArr[requestIndex]->DurationTime, dtimDuration); if (pMeasurementMgr->currentFrameType == MSR_FRAME_TYPE_UNICAST) pMeasurementMgr->buildRejectReport(pMeasurementMgr, pRequestArr, numOfRequest, MSR_REJECT_DTIM_OVERLAP); return TI_FALSE; } else { TRACE1(pMeasurementMgr->hReport, REPORT_SEVERITY_INFORMATION, ": DTIM of request #%d doesn't overlap\n", requestIndex+1); } } } } return TI_TRUE; }
/** * \fn sme_ScanResultCB * \brief Callback function from scan concentrator for results and scan complete indications * * Callback function from scan concentrator for results and scan complete indications * * \param hSme - handle to the SME object * \param eStatus - the reason for calling the CB * \param pFrameInfo - frame information (if the CB is called due to received frame) * \param uSPSStatus - SPS attened channels (if the CB is called to inidcate an SPS scan complete) * \return None */ void sme_ScanResultCB (TI_HANDLE hSme, EScanCncnResultStatus eStatus, TScanFrameInfo* pFrameInfo, TI_UINT16 uSPSStatus) { TSme *pSme = (TSme*)hSme; paramInfo_t param; switch (eStatus) { /* a frame was received - update the scan result table */ case SCAN_CRS_RECEIVED_FRAME: TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: received frame from BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); /* * in auto mode in order to find country IE only !!! * filter frames according to desired SSID, in case we are also trying to find * country IE in passive scan, to avoid a table overflow (in manual mode, the SME table must be equal to the app * table, the app is responsible to decide which SSIDs to use for scan) */ if (CONNECT_MODE_AUTO == pSme->eConnectMode) { if (SSID_TYPE_SPECIFIC == pSme->eSsidType) { #ifndef XCC_MODULE_INCLUDED if ((pSme->tSsid.len == pFrameInfo->parsedIEs->content.iePacket.pSsid->hdr[ 1 ]) && (0 == os_memoryCompare (pSme->hOS, &(pSme->tSsid.str[ 0 ]), &(pFrameInfo->parsedIEs->content.iePacket.pSsid->serviceSetId[ 0 ]), pSme->tSsid.len))) #endif { if (TI_OK != scanResultTable_UpdateEntry (pSme->hScanResultTable, pFrameInfo->bssId, pFrameInfo)) { TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: unable to update specific enrty for BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); } } } else { if (TI_OK != scanResultTable_UpdateEntry (pSme->hScanResultTable, pFrameInfo->bssId, pFrameInfo)) { TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: unable to update enrty for BSSID %02x:%02x:%02x:%02x:%02x:%02x because table is full\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); } } } else /* manual mode */ { if (TI_OK != scanResultTable_UpdateEntry (pSme->hScanResultTable, pFrameInfo->bssId, pFrameInfo)) { TRACE6(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: unable to update application scan enrty for BSSID %02x:%02x:%02x:%02x:%02x:%02x\n", (*pFrameInfo->bssId)[ 0 ], (*pFrameInfo->bssId)[ 1 ], (*pFrameInfo->bssId)[ 2 ], (*pFrameInfo->bssId)[ 3 ], (*pFrameInfo->bssId)[ 4 ], (*pFrameInfo->bssId)[ 5 ]); } } break; /* scan was completed successfully */ case SCAN_CRS_SCAN_COMPLETE_OK: /* an error occured, try selecting a site anyway */ case SCAN_CRS_SCAN_ABORTED_FW_RESET: case SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY: case SCAN_CRS_SCAN_FAILED: case SCAN_CRS_TSF_ERROR: TRACE1(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: received scan complete indication with status %d\n", eStatus); /* stablizie the scan result table - delete its contenst if no results were recived during last scan */ scanResultTable_SetStableState (pSme->hScanResultTable); if (CONNECT_MODE_AUTO == pSme->eConnectMode) { /* try to select a site */ pSme->pCandidate = sme_Select (hSme); /* if no matching site was found */ if (NULL == pSme->pCandidate) { /* for IBSS or any, if no entries where found, add the self site */ if (pSme->eBssType == BSS_INFRASTRUCTURE) { TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: No candidate available, sending connect failure\n"); genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); break; } { TI_UINT8 uDesiredChannel; param.paramType = SITE_MGR_DESIRED_CHANNEL_PARAM; siteMgr_getParam(pSme->hSiteMgr, ¶m); uDesiredChannel = param.content.siteMgrDesiredChannel; if (uDesiredChannel >= SITE_MGR_CHANNEL_A_MIN) { param.content.channelCapabilityReq.band = RADIO_BAND_5_0_GHZ; } else { param.content.channelCapabilityReq.band = RADIO_BAND_2_4_GHZ; } /* update the regulatory domain with the selected band */ /* Check if the selected channel is valid according to regDomain */ param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; param.content.channelCapabilityReq.channelNum = uDesiredChannel; regulatoryDomain_getParam (pSme->hRegDomain,¶m); if (!param.content.channelCapabilityRet.channelValidity) { TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "IBSS SELECT FAILURE - No channel !!!\n\n"); genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); break; } pSme->pCandidate = (TSiteEntry *)addSelfSite(pSme->hSiteMgr); if (pSme->pCandidate == NULL) { TRACE0(pSme->hReport, REPORT_SEVERITY_ERROR , "IBSS SELECT FAILURE - could not open self site !!!\n\n"); genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); break; } #ifdef REPORT_LOG TRACE6(pSme->hReport, REPORT_SEVERITY_CONSOLE,"%%%%%%%%%%%%%% SELF SELECT SUCCESS, bssid: %X-%X-%X-%X-%X-%X %%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5]); WLAN_OS_REPORT (("%%%%%%%%%%%%%% SELF SELECT SUCCESS, bssid: %02x.%02x.%02x.%02x.%02x.%02x %%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5])); #endif } } /* a connection candidate is available, send a connect event */ genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme); } break; /* * scan was stopped according to SME request (should happen when moving to disconnecting from scanning), send a * connect failure event to move out of disconnecting */ case SCAN_CRS_SCAN_STOPPED: TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_ScanResultCB: received scan stopped indication\n"); genSM_Event (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); break; default: TRACE1(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_ScanResultCB: received unrecognized status %d\n", eStatus); break; } }
void switchChannel_recvCmd(TI_HANDLE hSwitchChannel, dot11_CHANNEL_SWITCH_t *channelSwitch, TI_UINT8 channel) { switchChannel_t *pSwitchChannel = (switchChannel_t *)hSwitchChannel; paramInfo_t param; if (pSwitchChannel==NULL) { return; } param.paramType = REGULATORY_DOMAIN_DFS_CHANNELS_RANGE; regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain, ¶m); if (!pSwitchChannel->dot11SpectrumManagementRequired || (channel < param.content.DFS_ChannelRange.minDFS_channelNum) || (channel > param.content.DFS_ChannelRange.maxDFS_channelNum)) { /* Do not parse Switch Channel IE, when SpectrumManagement is disabled, or the channel is non-DFS channel */ return; } #ifdef TI_DBG /* for debug purposes only */ if (pSwitchChannel->ignoreCancelSwitchChannelCmd != 0) { return; } #endif if (channelSwitch == NULL) { /* No SC IE, update regDomain */ param.paramType = REGULATORY_DOMAIN_UPDATE_CHANNEL_VALIDITY; param.content.channel = channel; regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m); } else { /* SC IE exists */ /* Checking channel number validity */ param.content.channel = channelSwitch->channelNumber; param.paramType = REGULATORY_DOMAIN_IS_CHANNEL_SUPPORTED; regulatoryDomain_getParam(pSwitchChannel->hRegulatoryDomain,¶m); if ( ( !param.content.bIsChannelSupprted ) || (channelSwitch->channelSwitchCount == 0) || (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS)) { /* Trigger Roaming, if TX mode is disabled, the new channel number is invalid, or the TBTT count is 0 */ if (channelSwitch->channelSwitchMode == SC_SWITCH_CHANNEL_MODE_TX_SUS) { param.paramType = REGULATORY_DOMAIN_SET_CHANNEL_VALIDITY; param.content.channelValidity.channelNum = channel; param.content.channelValidity.channelValidity = TI_FALSE; regulatoryDomain_setParam(pSwitchChannel->hRegulatoryDomain, ¶m); } if (TI_TRUE == pSwitchChannel->switchChannelStarted) { apConn_reportRoamingEvent(pSwitchChannel->hApConn, ROAMING_TRIGGER_SWITCH_CHANNEL, NULL); } } else { /* Invoke Switch Channel command */ /* update the new SCC params */ pSwitchChannel->curChannelSwitchCmdParams.channelNumber = channelSwitch->channelNumber; pSwitchChannel->curChannelSwitchCmdParams.channelSwitchCount = channelSwitch->channelSwitchCount; pSwitchChannel->curChannelSwitchCmdParams.channelSwitchMode = channelSwitch->channelSwitchMode; switchChannel_smEvent((TI_UINT8*)&pSwitchChannel->currentState, SC_EVENT_SC_CMD, pSwitchChannel); } } }
/** * Configures the Measurement Manager module. * * @param pStadHandles Handles to other modules the Measurement Manager needs. * * @date 16-Dec-2005 */ void measurementMgr_init (TStadHandlesList *pStadHandles) { measurementMgr_t *pMeasurementMgr = (measurementMgr_t *)(pStadHandles->hMeasurementMgr); paramInfo_t param; /* Init Handlers */ pMeasurementMgr->hRegulatoryDomain = pStadHandles->hRegulatoryDomain; pMeasurementMgr->hkkkMngr = pStadHandles->hkkkMngr; pMeasurementMgr->hSiteMgr = pStadHandles->hSiteMgr; pMeasurementMgr->hTWD = pStadHandles->hTWD; pMeasurementMgr->hMlme = pStadHandles->hMlme; pMeasurementMgr->hTrafficMonitor = pStadHandles->hTrafficMon; pMeasurementMgr->hReport = pStadHandles->hReport; pMeasurementMgr->hOs = pStadHandles->hOs; pMeasurementMgr->hScr = pStadHandles->hSCR; pMeasurementMgr->hApConn = pStadHandles->hAPConnection; pMeasurementMgr->hTxCtrl = pStadHandles->hTxCtrl; pMeasurementMgr->hTimer = pStadHandles->hTimer; pMeasurementMgr->hSme = pStadHandles->hSme; /* initialize variables to default values */ pMeasurementMgr->Enabled = TI_TRUE; pMeasurementMgr->bSuspended = TI_FALSE; pMeasurementMgr->Connected = TI_FALSE; pMeasurementMgr->Capabilities = MEASUREMENT_CAPABILITIES_NONE; pMeasurementMgr->Mode = MSR_MODE_NONE; pMeasurementMgr->fDisabledCb = NULL; pMeasurementMgr->hDisabledCb = NULL; /* Getting management capability status */ param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM; regulatoryDomain_getParam (pMeasurementMgr->hRegulatoryDomain, ¶m); if (param.content.spectrumManagementEnabled) { pMeasurementMgr->Capabilities |= MEASUREMENT_CAPABILITIES_DOT11H; } /* Init Functions */ pMeasurementMgr->parserFrameReq = NULL; pMeasurementMgr->isTypeValid = NULL; pMeasurementMgr->buildReport = NULL; pMeasurementMgr->buildRejectReport = NULL; pMeasurementMgr->sendReportAndCleanObj = NULL; /* initialize variables */ pMeasurementMgr->currentState = MEASUREMENTMGR_STATE_IDLE; pMeasurementMgr->isModuleRegistered = TI_FALSE; pMeasurementMgr->currentFrameType = MSR_FRAME_TYPE_NO_ACTIVE; pMeasurementMgr->measuredChannelID = 0; pMeasurementMgr->currentNumOfRequestsInParallel = 0; pMeasurementMgr->bMeasurementScanExecuted = TI_FALSE; /* config sub modules */ RequestHandler_config(pStadHandles->hMeasurementMgr, pMeasurementMgr->hRequestH, pStadHandles->hReport, pStadHandles->hOs); /* Register to the SCR module */ scr_registerClientCB(pMeasurementMgr->hScr, SCR_CID_kkk_MEASURE, measurementMgr_scrResponseCB, (TI_HANDLE)pMeasurementMgr); measurementMgrSM_config ((TI_HANDLE)pMeasurementMgr); TRACE0(pMeasurementMgr->hReport, REPORT_SEVERITY_INIT , ": Measurement Manager configured successfully\n"); }
/** * \fn smeSm_PreConnect * \brief Initiates the connection process * * Initiates the connection process - for automatic mode, start scan, for manual mode - triggers connection * * \param hSme - handle to the SME object * \return None * \sa smeSm_Connect, smeSm_ConnectSuccess */ void smeSm_PreConnect (TI_HANDLE hSme) { TSme *pSme = (TSme *)hSme; paramInfo_t *pParam; //joetest TRACE0(pSme->hReport, REPORT_SEVERITY_SM , "smeSm_PreConnect: !!!\n"); /* set the connection mode with which this connection attempt is starting */ pSme->eLastConnectMode = pSme->eConnectMode; /* mark that no authentication/assocaition was yet sent */ pSme->bAuthSent = TI_FALSE; /* try to find a connection candidate (manual mode have already performed scann */ pSme->pCandidate = sme_Select (hSme); if (NULL != pSme->pCandidate) { /* candidate is available - attempt connection */ sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme); } /* no candidate */ else { if (CONNECT_MODE_AUTO == pSme->eConnectMode) { /* automatic mode - start scanning */ if (TI_OK != sme_StartScan (hSme)) { TRACE0(pSme->hReport, REPORT_SEVERITY_ERROR , "smeSm_PreConnect: unable to start scan, stopping the SME\n"); pSme->bRadioOn = TI_FALSE; sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); } /* update scan count counter */ if(pSme->uScanCount < PERIODIC_SCAN_MAX_INTERVAL_NUM) { pSme->uScanCount++; } } else /* Manual mode */ { /* for IBSS or any, if no entries where found, add the self site */ if (pSme->eBssType == BSS_INFRASTRUCTURE) { /* makr whether we need to stop the attempt connection in manual mode */ pSme->bConnectRequired = TI_FALSE; TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "smeSm_PreConnect: No candidate available, sending connect failure\n"); /* manual mode and no connection candidate is available - connection failed */ //joetest TRACE0(pSme->hReport, REPORT_SEVERITY_SM , "smeSm_PreConnect!!!\n"); } else /* IBSS */ { TI_UINT8 uDesiredChannel; TI_BOOL channelValidity; pSme->bConnectRequired = TI_FALSE; pParam = (paramInfo_t *)os_memoryAlloc(pSme->hOS, sizeof(paramInfo_t)); if (!pParam) { return; } pParam->paramType = SITE_MGR_DESIRED_CHANNEL_PARAM; siteMgr_getParam(pSme->hSiteMgr, pParam); uDesiredChannel = pParam->content.siteMgrDesiredChannel; if (uDesiredChannel >= SITE_MGR_CHANNEL_A_MIN) { pParam->content.channelCapabilityReq.band = RADIO_BAND_5_0_GHZ; } else { pParam->content.channelCapabilityReq.band = RADIO_BAND_2_4_GHZ; } /* update the regulatory domain with the selected band */ /* Check if the selected channel is valid according to regDomain */ pParam->paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; pParam->content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; pParam->content.channelCapabilityReq.channelNum = uDesiredChannel; regulatoryDomain_getParam (pSme->hRegDomain,pParam); channelValidity = pParam->content.channelCapabilityRet.channelValidity; os_memoryFree(pSme->hOS, pParam, sizeof(paramInfo_t)); if (!channelValidity) { TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "IBSS SELECT FAILURE - No channel !!!\n\n"); sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); return; } pSme->pCandidate = (TSiteEntry *)addSelfSite(pSme->hSiteMgr); if (pSme->pCandidate == NULL) { TRACE0(pSme->hReport, REPORT_SEVERITY_ERROR , "IBSS SELECT FAILURE - could not open self site !!!\n\n"); sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT_FAILURE, hSme); return; } #ifdef REPORT_LOG TRACE6(pSme->hReport, REPORT_SEVERITY_CONSOLE,"%%%%%%%%%%%%%% SELF SELECT SUCCESS, bssid: %X-%X-%X-%X-%X-%X %%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5]); WLAN_OS_REPORT (("%%%%%%%%%%%%%% SELF SELECT SUCCESS, bssid: %02x.%02x.%02x.%02x.%02x.%02x %%%%%%%%%%%%%%\n\n", pSme->pCandidate->bssid[0], pSme->pCandidate->bssid[1], pSme->pCandidate->bssid[2], pSme->pCandidate->bssid[3], pSme->pCandidate->bssid[4], pSme->pCandidate->bssid[5])); #endif /* a connection candidate is available, send a connect event */ sme_SmEvent (pSme->hSmeSm, SME_SM_EVENT_CONNECT, hSme); } } } }
/** * \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; ECipherSuite rsnEncryption; *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); rsnEncryption = param.content.rsnEncryptionStatus; 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; */ } /* if chiper = TKIP/WEP then 11n is not used */ if (rsnEncryption != TWD_CIPHER_TKIP && rsnEncryption != TWD_CIPHER_WEP && rsnEncryption != TWD_CIPHER_WEP104) { /* 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_assocRequestMsgBuild * \brief buils association request * * The function builds the association request according to the given parames * * \param pCtx - pointer to mlme_t * \param reqBuf - <output> pointer to built assoc request buffer * \param reqLen - <output> length of built assoc request buffer * * \return TI_OK if auth send successfully * TI_NOK otherwise * * \sa mlme_sendAssocRequest */ TI_STATUS mlme_assocRequestMsgBuild(mlme_t *pCtx, TI_UINT8* reqBuf, TI_UINT32* reqLen) { TI_STATUS status; TI_UINT8 *pRequest; TI_UINT32 len; paramInfo_t param; TTwdParamInfo tTwdParam; TI_UINT16 capabilities; TI_BOOL spectrumManagementEnabled; ECipherSuite eCipherSuite = TWD_CIPHER_NONE; /* To be used for checking whether AP supports HT rates and TKIP */ pRequest = reqBuf; *reqLen = 0; /* insert capabilities */ status = mlme_assocCapBuild(pCtx, &capabilities); if (status == TI_OK) { *(TI_UINT16*)pRequest = ENDIAN_HANDLE_WORD(capabilities); } else { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build assoc Capa\n"); return TI_NOK; } pRequest += sizeof(TI_UINT16); *reqLen += sizeof(TI_UINT16); /* insert listen interval */ tTwdParam.paramType = TWD_LISTEN_INTERVAL_PARAM_ID; status = TWD_GetParam (pCtx->hTWD, &tTwdParam); if (status == TI_OK) { *(TI_UINT16*)pRequest = ENDIAN_HANDLE_WORD((TI_UINT16)tTwdParam.content.halCtrlListenInterval); } else { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to get listen interval\n"); return TI_NOK; } pRequest += sizeof(TI_UINT16); *reqLen += sizeof(TI_UINT16); if (pCtx->reAssoc) { /* Insert currentAPAddress element only in reassoc request*/ param.paramType = SITE_MGR_PREV_SITE_BSSID_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (status == TI_OK) { MAC_COPY (pRequest, param.content.siteMgrDesiredBSSID); TRACE6(pCtx->hReport, REPORT_SEVERITY_INFORMATION, "ASSOC_SM: ASSOC_REQ - prev AP = %x-%x-%x-%x-%x-%x\n", param.content.siteMgrDesiredBSSID[0], param.content.siteMgrDesiredBSSID[1], param.content.siteMgrDesiredBSSID[2], param.content.siteMgrDesiredBSSID[3], param.content.siteMgrDesiredBSSID[4], param.content.siteMgrDesiredBSSID[5]); pRequest += MAC_ADDR_LEN; *reqLen += MAC_ADDR_LEN; } else { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: ASSOC_REQ - No prev AP \n"); return status; } } /* insert SSID element */ status = mlme_assocSSIDBuild(pCtx, pRequest, &len); if (status != TI_OK) { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build SSID IE\n"); return TI_NOK; } pRequest += len; *reqLen += len; /* insert Rates element */ status = mlme_assocRatesBuild(pCtx, pRequest, &len); if (status != TI_OK) { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build rates IE\n"); return TI_NOK; } pRequest += len; *reqLen += len; /* Checking if the station supports Spectrum Management (802.11h) */ param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM; status = regulatoryDomain_getParam(pCtx->hRegulatoryDomain,¶m); spectrumManagementEnabled = param.content.spectrumManagementEnabled; /* Checking the selected AP capablities */ param.paramType = SITE_MGR_SITE_CAPABILITY_PARAM; status = siteMgr_getParam(pCtx->hSiteMgr,¶m); if (status == TI_OK && spectrumManagementEnabled && param.content.siteMgrSiteCapability & (DOT11_SPECTRUM_MANAGEMENT != 0)) { /* insert Power capability element */ status = mlme_assocPowerCapabilityBuild(pCtx, pRequest, &len); if (status != TI_OK) { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build Power IE\n"); return TI_NOK; } pRequest += len; *reqLen += len; } /* Get Simple-Config state */ param.paramType = SITE_MGR_SIMPLE_CONFIG_MODE; status = siteMgr_getParam(pCtx->hSiteMgr, ¶m); if (param.content.siteMgrWSCMode.WSCMode == TIWLN_SIMPLE_CONFIG_OFF) { /* insert RSN information elements */ status = rsn_getInfoElement(pCtx->hRsn, pRequest, &len); if (status != TI_OK) { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build RSN IE\n"); return TI_NOK; } pRequest += len; *reqLen += len; } /* Privacy - Used later on HT */ param.paramType = RSN_ENCRYPTION_STATUS_PARAM; status = rsn_getParam(pCtx->hRsn, ¶m); if(status == TI_OK) { eCipherSuite = param.content.rsnEncryptionStatus; } /* Primary Site support HT ? */ param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT; siteMgr_getParam(pCtx->hSiteMgr, ¶m); /* Disallow TKIP with HT Rates: If this is the case - discard HT rates from Association Request */ if((TI_TRUE == param.content.bPrimarySiteHtSupport) && (eCipherSuite != TWD_CIPHER_TKIP) && (eCipherSuite != TWD_CIPHER_WEP) && (eCipherSuite != TWD_CIPHER_WEP104) ) { status = StaCap_GetHtCapabilitiesIe (pCtx->hStaCap, pRequest, &len); if (status != TI_OK) { return TI_NOK; } pRequest += len; *reqLen += len; } status = qosMngr_assocReqBuild(pCtx->hQosMngr,pRequest,&len); if (status != TI_OK) { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build QoS IE\n"); return TI_NOK; } pRequest += len; *reqLen += len; status = apConn_getVendorSpecificIE(pCtx->hApConn, pRequest, &len); if (status != TI_OK) { TRACE0(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build vendor IE\n"); return TI_NOK; } pRequest += len; *reqLen += len; if (*reqLen>=MAX_ASSOC_MSG_LENGTH) { TRACE1(pCtx->hReport, REPORT_SEVERITY_ERROR, "mlme_assocRequestMsgBuild: failed to build, reqLen = %u\n", *reqLen); return TI_NOK; } return TI_OK; }