wlan: ccx upload: Support ccx beacon report
This is to provide support for CCX radio measument beacon report.
Summary of changes include:
1. Support for CCXBEACONREQ device private command to receive
measurement request IE information.
2. Driver initiates scan and return the BSSID information using
IWEVCUSTOM event supporting 4 BSSID info per channel.
3. Fix for scan type and duration getting over-written with the
last channel scan type and duration.
4. IWEVCUSTOM has limitation of 256 bytes of event data, hence fill-in
only the mandatory IEs in the beacon report as per the spec.
Change-Id: If0324b1732ea537f64a48c22c5e702c49356504e
CRs-Fixed: 573479
diff --git a/CORE/SME/src/rrm/sme_rrm.c b/CORE/SME/src/rrm/sme_rrm.c
index 66c99f3..3f25ce7 100644
--- a/CORE/SME/src/rrm/sme_rrm.c
+++ b/CORE/SME/src/rrm/sme_rrm.c
@@ -229,7 +229,6 @@
pBeaconRep->messageType = eWNI_SME_BEACON_REPORT_RESP_XMIT_IND;
pBeaconRep->length = length;
pBeaconRep->uDialogToken = pSmeRrmContext->token;
- pBeaconRep->duration = pSmeRrmContext->duration;
pBeaconRep->regClass = pSmeRrmContext->regClass;
vos_mem_copy( pBeaconRep->bssId, pSmeRrmContext->sessionBssId, sizeof(tSirMacAddr) );
@@ -257,7 +256,7 @@
pBeaconRep->numBssDesc++;
- if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC_PER_ACTION_FRAME)
+ if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC)
break;
pCurResult = pResultArr[bssCounter + msgCounter];
@@ -296,6 +295,156 @@
return status;
}
+#if defined(FEATURE_WLAN_CCX_UPLOAD)
+/**---------------------------------------------------------------------------
+
+ \brief sme_CcxSendBeaconReqScanResults()
+
+ This function sends up the scan results received as a part of
+ beacon request scanning.
+ This function is called after receiving the scan results per channel
+ Due to the limitation on the size of the IWEVCUSTOM buffer, we send 3 BSSIDs of
+ beacon report information in one custom event;
+
+ \param - pMac - Pointer to the Hal Handle.
+ - sessionId - Session id
+ - channel - scan results belongs to this channel
+ - pResultArr - scan result.
+ - measurementDone - flag to indicate that the measurement is done.
+ - bss_count - number of bss found
+ \return - 0 for success, non zero for failure
+
+ --------------------------------------------------------------------------*/
+static eHalStatus sme_CcxSendBeaconReqScanResults(tpAniSirGlobal pMac,
+ tANI_U32 sessionId,
+ tANI_U8 channel,
+ tCsrScanResultInfo **pResultArr,
+ tANI_U8 measurementDone,
+ tANI_U8 bss_count)
+{
+ eHalStatus status = eHAL_STATUS_FAILURE;
+ tpSirBssDescription pBssDesc = NULL;
+ tANI_U32 ie_len = 0;
+ tANI_U32 outIeLen = 0;
+ tANI_U8 bssCounter = 0;
+ tCsrScanResultInfo *pCurResult = NULL;
+ tANI_U8 msgCounter = 0;
+ tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
+ tCsrRoamInfo roamInfo;
+ tSirCcxBcnReportRsp bcnReport;
+ tpSirCcxBcnReportRsp pBcnReport = &bcnReport;
+ tpCsrCcxBeaconReqParams pCurMeasReqIe = NULL;
+ tANI_U8 i = 0;
+
+ if (NULL == pSmeRrmContext)
+ {
+ smsLog( pMac, LOGE, "pSmeRrmContext is NULL");
+ return eHAL_STATUS_FAILURE;
+ }
+
+ if (NULL == pResultArr && !measurementDone)
+ {
+ smsLog( pMac, LOGE, "Beacon report xmit Ind to HDD Failed");
+ return eHAL_STATUS_FAILURE;
+ }
+
+ if (pResultArr)
+ pCurResult=pResultArr[bssCounter];
+
+ vos_mem_zero(&bcnReport, sizeof(tSirCcxBcnReportRsp));
+ do
+ {
+ pCurMeasReqIe = NULL;
+ for (i = 0; i < pSmeRrmContext->ccxBcnReqInfo.numBcnReqIe; i++)
+ {
+ if(pSmeRrmContext->ccxBcnReqInfo.bcnReq[i].channel == channel)
+ {
+ pCurMeasReqIe = &pSmeRrmContext->ccxBcnReqInfo.bcnReq[i];
+ break;
+ }
+ }
+ pBcnReport->measurementToken = pCurMeasReqIe->measurementToken;
+ smsLog( pMac, LOG1, "Channel(%d) MeasToken(%d)", channel, pBcnReport->measurementToken);
+
+ msgCounter=0;
+ while (pCurResult)
+ {
+ pBssDesc = &pCurResult->BssDescriptor;
+ if (NULL != pBssDesc)
+ {
+ ie_len = GET_IE_LEN_IN_BSS( pBssDesc->length );
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.ChanNum = pBssDesc->channelId;
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.Spare = 0;
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.MeasDuration = pCurMeasReqIe->measurementDuration;
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.PhyType = pBssDesc->nwType;
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.RecvSigPower = pBssDesc->rssi;
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.ParentTsf = pBssDesc->parentTSF;
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.TargetTsf[0] = pBssDesc->timeStamp[0];
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.TargetTsf[1] = pBssDesc->timeStamp[1];
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.BcnInterval = pBssDesc->beaconInterval;
+ pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.CapabilityInfo = pBssDesc->capabilityInfo;
+ vos_mem_copy(pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.Bssid,
+ pBssDesc->bssId, sizeof(tSirMacAddr));
+
+ sirFillBeaconMandatoryIEforCcxBcnReport(pMac, (tANI_U8 *)pBssDesc->ieFields, ie_len,
+ &(pBcnReport->bcnRepBssInfo[msgCounter].pBuf), &outIeLen);
+ pBcnReport->bcnRepBssInfo[msgCounter].ieLen = outIeLen;
+
+ smsLog( pMac, LOG1,"Bssid(%02X:%02X:%02X:%02X:%02X:%02X) Channel=%d Rssi=%d",
+ pBssDesc->bssId[0], pBssDesc->bssId[1], pBssDesc->bssId[2],
+ pBssDesc->bssId[3], pBssDesc->bssId[4], pBssDesc->bssId[5],
+ pBssDesc->channelId, (-1) * pBssDesc->rssi);
+
+ pBcnReport->numBss++;
+
+ if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC)
+ break;
+
+ pCurResult = pResultArr[msgCounter];
+ }
+ else
+ {
+ pCurResult = NULL;
+ break;
+ }
+ }
+
+ bssCounter += msgCounter;
+ if (!pResultArr || !pCurResult || (bssCounter >= SIR_BCN_REPORT_MAX_BSS_DESC))
+ {
+ pCurResult = NULL;
+ smsLog(pMac, LOGE,
+ "Reached to the max/last BSS in pCurResult list");
+ }
+ else
+ {
+ pCurResult = pResultArr[bssCounter];
+ smsLog(pMac, LOGE,
+ "Move to the next BSS set in pCurResult list");
+ }
+
+ pBcnReport->flag = (measurementDone << 1)|((pCurResult)?true:false);
+
+ smsLog(pMac, LOG1, "SME Sending BcnRep to HDD numBss(%d)"
+ " msgCounter(%d) bssCounter(%d)",
+ pBcnReport->numBss, msgCounter, bssCounter, pBcnReport->flag);
+
+ roamInfo.pCcxBcnReportRsp = pBcnReport;
+ csrRoamCallCallback(pMac, sessionId, &roamInfo,
+ 0, eCSR_ROAM_CCX_BCN_REPORT_IND, 0);
+
+ /* Free the memory allocated to IE */
+ for (i = 0; i < msgCounter; i++)
+ {
+ if (pBcnReport->bcnRepBssInfo[i].pBuf)
+ vos_mem_free(pBcnReport->bcnRepBssInfo[i].pBuf);
+ }
+ } while (pCurResult);
+ return status;
+}
+
+#endif /* FEATURE_WLAN_CCX_UPLOAD */
+
/**---------------------------------------------------------------------------
\brief sme_RrmSendScanRequest() -
@@ -318,7 +467,7 @@
tCsrScanResultFilter filter;
tScanResultHandle pResult;
tCsrScanResultInfo *pScanResult, *pNextResult;
- tCsrScanResultInfo *pScanResultsArr[SIR_BCN_REPORT_MAX_BSS_PER_CHANNEL];
+ tCsrScanResultInfo *pScanResultsArr[SIR_BCN_REPORT_MAX_BSS_DESC];
eHalStatus status;
tANI_U8 counter=0;
tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
@@ -329,7 +478,7 @@
#endif
vos_mem_zero( &filter, sizeof(filter) );
- vos_mem_zero( pScanResultsArr, sizeof(pNextResult)*SIR_BCN_REPORT_MAX_BSS_PER_CHANNEL );
+ vos_mem_zero( pScanResultsArr, sizeof(pNextResult)*SIR_BCN_REPORT_MAX_BSS_DESC );
filter.BSSIDs.numOfBSSIDs = 1;
filter.BSSIDs.bssid = &pSmeRrmContext->bssId;
@@ -387,7 +536,18 @@
// send a xmit indication with moreToFollow set to MEASURMENT_DONE
// so that PE can clean any context allocated.
if( measurementDone )
- status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0 );
+ {
+#if defined(FEATURE_WLAN_CCX_UPLOAD)
+ status = sme_CcxSendBeaconReqScanResults(pMac,
+ sessionId,
+ chanList[0],
+ NULL,
+ measurementDone,
+ 0);
+#else
+ status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0);
+#endif /*FEATURE_WLAN_CCX_UPLOAD*/
+ }
return status;
}
@@ -402,18 +562,26 @@
pNextResult = sme_ScanResultGetNext(pMac, pResult);
pScanResultsArr[counter++] = pScanResult;
pScanResult = pNextResult; //sme_ScanResultGetNext(hHal, pResult);
- if (counter >= SIR_BCN_REPORT_MAX_BSS_PER_CHANNEL)
+ if (counter >= SIR_BCN_REPORT_MAX_BSS_DESC)
break;
}
if (counter)
{
+ smsLog(pMac, LOG1, " Number of BSS Desc with RRM Scan %d ", counter);
+#if defined(FEATURE_WLAN_CCX_UPLOAD)
+ status = sme_CcxSendBeaconReqScanResults(pMac,
+ sessionId,
+ chanList[0],
+ pScanResultsArr,
+ measurementDone,
+ counter);
+#else
status = sme_RrmSendBeaconReportXmitInd( pMac,
pScanResultsArr,
measurementDone,
counter);
- smsLog(pMac, LOG1, " Number of BSS Desc with RRM Scan %d ",
- counter);
+#endif /*FEATURE_WLAN_CCX_UPLOAD*/
}
sme_ScanResultPurge(pMac, pResult);
@@ -485,7 +653,7 @@
\brief sme_RrmIssueScanReq() - This is called to send a scan request as part
of beacon report request .
- \param
+ \param pMac - pMac global pointer
\return eHAL_STATUS_SUCCESS - Validation is successful.
@@ -500,67 +668,101 @@
eHalStatus status = eHAL_STATUS_SUCCESS;
tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
tANI_U32 sessionId;
+ tSirScanType scanType;
+ if ((pSmeRrmContext->currentIndex) >= pSmeRrmContext->channelList.numOfChannels)
+ return status;
+
+ scanType = pSmeRrmContext->measMode[pSmeRrmContext->currentIndex];
+ if ((eSIR_ACTIVE_SCAN == scanType) || (eSIR_PASSIVE_SCAN == scanType))
+ {
#if defined WLAN_VOWIFI_DEBUG
smsLog( pMac, LOGE, "Issue scan request " );
#endif
- vos_mem_zero( &scanRequest, sizeof(scanRequest));
+ vos_mem_zero( &scanRequest, sizeof(scanRequest));
- /* set scanType, active or passive */
- scanRequest.bcnRptReqScan = TRUE;
- scanRequest.scanType = pSmeRrmContext->measMode;
+ /* set scanType, active or passive */
+ scanRequest.bcnRptReqScan = TRUE;
+ scanRequest.scanType = scanType;
- vos_mem_copy(scanRequest.bssid,
- pSmeRrmContext->bssId, sizeof(scanRequest.bssid) );
+ vos_mem_copy(scanRequest.bssid,
+ pSmeRrmContext->bssId, sizeof(scanRequest.bssid) );
- if( pSmeRrmContext->ssId.length )
- {
- scanRequest.SSIDs.numOfSSIDs = 1;
- scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
- if( scanRequest.SSIDs.SSIDList == NULL )
- {
- smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
- return eHAL_STATUS_FAILURE;
- }
+ if (pSmeRrmContext->ssId.length)
+ {
+ scanRequest.SSIDs.numOfSSIDs = 1;
+ scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
+ if (NULL == scanRequest.SSIDs.SSIDList)
+ {
+ smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
+ return eHAL_STATUS_FAILURE;
+ }
#if defined WLAN_VOWIFI_DEBUG
- smsLog( pMac, LOGE, FL("Allocated memory for pSSIDList"));
+ smsLog( pMac, LOGE, FL("Allocated memory for pSSIDList"));
#endif
- vos_mem_zero( scanRequest.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) );
- scanRequest.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length;
- vos_mem_copy(scanRequest.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length);
+ vos_mem_zero( scanRequest.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) );
+ scanRequest.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length;
+ vos_mem_copy(scanRequest.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length);
+ }
+
+ /* set min and max channel time */
+ scanRequest.minChnTime = 0; //pSmeRrmContext->duration; Dont use min timeout.
+ scanRequest.maxChnTime = pSmeRrmContext->duration[pSmeRrmContext->currentIndex];
+ smsLog( pMac, LOG1, "Scan Type(%d) Max Dwell Time(%d)", scanRequest.scanType,
+ scanRequest.maxChnTime );
+
+#if defined WLAN_VOWIFI_DEBUG
+ smsLog( pMac, LOGE, "For Duration %d ", scanRequest.maxChnTime );
+#endif
+
+ /* set BSSType to default type */
+ scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
+
+ /*Scan all the channels */
+ scanRequest.ChannelInfo.numOfChannels = 1;
+
+ scanRequest.ChannelInfo.ChannelList = &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex];
+#if defined WLAN_VOWIFI_DEBUG
+ smsLog( pMac, LOGE, "On channel %d ", pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex] );
+#endif
+
+ /* set requestType to full scan */
+ scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
+
+ csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId );
+ status = sme_ScanRequest( pMac, (tANI_U8)sessionId, &scanRequest, &scanId, &sme_RrmScanRequestCallback, NULL );
+
+ if ( pSmeRrmContext->ssId.length )
+ {
+ vos_mem_free(scanRequest.SSIDs.SSIDList);
+#if defined WLAN_VOWIFI_DEBUG
+ smsLog( pMac, LOGE, FL("Free memory for SSIDList"));
+#endif
+ }
}
-
- /* set min and max channel time */
- scanRequest.minChnTime = 0; //pSmeRrmContext->duration; Dont use min timeout.
- scanRequest.maxChnTime = pSmeRrmContext->duration;
-#if defined WLAN_VOWIFI_DEBUG
- smsLog( pMac, LOGE, "For Duration %d ", pSmeRrmContext->duration );
-#endif
-
- /* set BSSType to default type */
- scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
-
- /*Scan all the channels */
- scanRequest.ChannelInfo.numOfChannels = 1;
-
- scanRequest.ChannelInfo.ChannelList = &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex];
-#if defined WLAN_VOWIFI_DEBUG
- smsLog( pMac, LOGE, "On channel %d ", pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex] );
-#endif
-
- /* set requestType to full scan */
- scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
-
- csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId );
- status = sme_ScanRequest( pMac, (tANI_U8)sessionId, &scanRequest, &scanId, &sme_RrmScanRequestCallback, NULL );
-
- if ( pSmeRrmContext->ssId.length )
+ else if (2 == scanType) /* beacon table */
{
- vos_mem_free(scanRequest.SSIDs.SSIDList);
-#if defined WLAN_VOWIFI_DEBUG
- smsLog( pMac, LOGE, FL("Free memory for SSIDList"));
-#endif
+ if ((pSmeRrmContext->currentIndex + 1) < pSmeRrmContext->channelList.numOfChannels)
+ {
+ sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], false );
+ pSmeRrmContext->currentIndex++; //Advance the current index.
+ sme_RrmIssueScanReq(pMac);
+ }
+ else
+ {
+ //Done with the measurement. Clean up all context and send a message to PE with measurement done flag set.
+ sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], true );
+ vos_mem_free( pSmeRrmContext->channelList.ChannelList );
+ }
+ }
+ else
+ {
+ smsLog( pMac, LOGE, "Unknown beacon report request mode(%d)", scanType);
+ /* Indicate measurement completion to PE */
+ /* If this is not done, pCurrentReq pointer will not be freed and
+ PE will not handle subsequent Beacon requests */
+ sme_RrmSendBeaconReportXmitInd(pMac, NULL, true, 0);
}
return status;
@@ -583,7 +785,7 @@
{
tpSirBeaconReportReqInd pBeaconReq = (tpSirBeaconReportReqInd) pMsgBuf;
tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
- tANI_U32 len,i;
+ tANI_U32 len = 0, i = 0;
#if defined WLAN_VOWIFI_DEBUG
smsLog( pMac, LOGE, "Received Beacon report request ind Channel = %d", pBeaconReq->channelInfo.channelNum );
@@ -615,7 +817,7 @@
len = 0;
pSmeRrmContext->channelList.numOfChannels = 0;
- //If valid channel is present. We firt Measure on the given channel. and
+ //If valid channel is present. We first Measure on the given channel. and
//if there are additional channels present in APchannelreport, measure on these also.
if ( pBeaconReq->channelInfo.channelNum != 255 )
len = 1;
@@ -670,42 +872,12 @@
pSmeRrmContext->token = pBeaconReq->uDialogToken;
pSmeRrmContext->regClass = pBeaconReq->channelInfo.regulatoryClass;
-
- switch( pBeaconReq->fMeasurementtype )
- {
- case 0: //Passive
- case 1: //Active
- pSmeRrmContext->measMode = pBeaconReq->fMeasurementtype? eSIR_ACTIVE_SCAN : eSIR_PASSIVE_SCAN ;
- pSmeRrmContext->duration = pBeaconReq->measurementDuration;
pSmeRrmContext->randnIntvl = VOS_MAX( pBeaconReq->randomizationInterval, pSmeRrmContext->rrmConfig.maxRandnInterval );
pSmeRrmContext->currentIndex = 0;
-#if defined WLAN_VOWIFI_DEBUG
- smsLog( pMac, LOGE, "Send beacon report after scan " );
-#endif
- sme_RrmIssueScanReq( pMac );
- break;
- case 2: //Table
- //Get the current scan results for the given channel and send it.
-#if defined WLAN_VOWIFI_DEBUG
- smsLog( pMac, LOGE, "Send beacon report from table " );
-#endif
- sme_RrmSendScanResult( pMac, pSmeRrmContext->channelList.numOfChannels, pSmeRrmContext->channelList.ChannelList, true );
- vos_mem_free( pSmeRrmContext->channelList.ChannelList );
-#if defined WLAN_VOWIFI_DEBUG
- smsLog( pMac, LOGE, FL("Free memory for ChannelList") );
-#endif
- break;
- default:
-#if defined WLAN_VOWIFI_DEBUG
- smsLog( pMac, LOGE, "Unknown beacon report request mode");
-#endif
- /* Indicate measurement completion to PE */
- /* If this is not done, pCurrentReq pointer will not be freed and
- PE will not handle subsequent Beacon requests */
- sme_RrmSendBeaconReportXmitInd(pMac, NULL, true, 0);
- break;
+ vos_mem_copy((tANI_U8*)&pSmeRrmContext->measMode, (tANI_U8*)&pBeaconReq->fMeasurementtype, SIR_CCX_MAX_MEAS_IE_REQS);
+ vos_mem_copy((tANI_U8*)&pSmeRrmContext->duration, (tANI_U8*)&pBeaconReq->measurementDuration, SIR_CCX_MAX_MEAS_IE_REQS);
- }
+ sme_RrmIssueScanReq( pMac );
return;
}