Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6a1d886 authored by Madan Mohan Koyyalamudi's avatar Madan Mohan Koyyalamudi
Browse files

wlan: rrm: Add support for multiple Beacon reports per channel

With the existing implementation, beacon report from STA reports
details pertaining to only one BSS per channel and this behaviour
is not meeting the VE cert test plan requirements. Hence support
is added to send multiple measurement reports corresponding to
multiple BSSs per channel as the STA identifies via scan.

Change-Id: I67c807308a6e3c8ae0a309490cdccec4441fd913
CRs-fixed: 538880
parent 263cec16
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -57,7 +57,8 @@

  ========================================================================*/

#define SIR_BCN_REPORT_MAX_BSS_DESC                4
#define SIR_BCN_REPORT_MAX_BSS_DESC_PER_ACTION_FRAME    3
#define SIR_BCN_REPORT_MAX_BSS_PER_CHANNEL             15

typedef enum eRrmRetStatus
{
@@ -99,7 +100,7 @@ typedef struct sSirBeaconReportXmitInd
   tANI_U16    duration;
   tANI_U8     regClass;
   tANI_U8     numBssDesc;
   tpSirBssDescription pBssDescription[SIR_BCN_REPORT_MAX_BSS_DESC];
   tpSirBssDescription pBssDescription[SIR_BCN_REPORT_MAX_BSS_DESC_PER_ACTION_FRAME];
} tSirBeaconReportXmitInd, * tpSirBeaconReportXmitInd;

typedef struct sSirNeighborReportReqInd
+111 −66
Original line number Diff line number Diff line
@@ -800,107 +800,149 @@ rrmProcessBeaconReportXmit( tpAniSirGlobal pMac,
                            tpSirBeaconReportXmitInd pBcnReport)
{
   tSirRetStatus status = eSIR_SUCCESS;
   tSirMacRadioMeasureReport report, *pReport;
   tSirMacRadioMeasureReport *pReport;
   tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq; 
   tpPESession pSessionEntry ;
   tANI_U8 sessionId;
   v_U8_t flagBSSPresent = FALSE;
   v_U8_t flagBSSPresent = FALSE, bssDescCnt = 0;

#if defined WLAN_VOWIFI_DEBUG
   PELOGE(limLog( pMac, LOGE, "Received beacon report xmit indication");)
#endif


   if (NULL == pBcnReport)
   {
      PELOGE(limLog( pMac, LOGE,
             "Received pBcnReport is NULL in PE");)
      return eSIR_FAILURE;
   }

   if ( pCurrentReq == NULL )
   if (NULL == pCurrentReq)
   {
      PELOGE(limLog( pMac, LOGE, "Received report xmit while there is no request pending in PE");)
      PELOGE(limLog( pMac, LOGE,
             "Received report xmit while there is no request pending in PE");)
      return eSIR_FAILURE;
   }
   if ((pSessionEntry = peFindSessionByBssid(pMac,pBcnReport->bssId,&sessionId))==NULL)

   if (NULL == (pSessionEntry = peFindSessionByBssid(pMac,
                                                     pBcnReport->bssId,
                                                     &sessionId)))
   {
      PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId"));)
      return eSIR_FAILURE;
   }

   pReport = &report;
   vos_mem_set(pReport, sizeof(tSirMacRadioMeasureReport), 0);
   pReport = vos_mem_malloc(pBcnReport->numBssDesc *
                           sizeof(tSirMacRadioMeasureReport));

   if (NULL == pReport)
   {
      PELOGE(limLog(pMac, LOGE,FL("RRM Report is NULL, allocation failed"));)
      return eSIR_FAILURE;
   }

   vos_mem_zero( pReport,
                 pBcnReport->numBssDesc * sizeof(tSirMacRadioMeasureReport) );

   for (bssDescCnt = 0; bssDescCnt < pBcnReport->numBssDesc; bssDescCnt++)
   {
       //Prepare the beacon report and send it to the peer.
   pReport->token = pBcnReport->uDialogToken;
   pReport->refused = 0;
   pReport->incapable = 0;
   pReport->type = SIR_MAC_RRM_BEACON_TYPE;
       pReport[bssDescCnt].token = pBcnReport->uDialogToken;
       pReport[bssDescCnt].refused = 0;
       pReport[bssDescCnt].incapable = 0;
       pReport[bssDescCnt].type = SIR_MAC_RRM_BEACON_TYPE;

   //If the scan result is NULL then send report request with option subelement as NULL..
   if ( NULL != pBcnReport->pBssDescription[0] )
       //If the scan result is NULL then send report request with
       //option subelement as NULL..
       if ( NULL != pBcnReport->pBssDescription[bssDescCnt] )
       {
           flagBSSPresent = TRUE;
       }

   //Valid response is included if the size of beacon xmit is == size of beacon xmit ind + ies
       //Valid response is included if the size of beacon xmit
       //is == size of beacon xmit ind + ies
       if ( pBcnReport->length >= sizeof( tSirBeaconReportXmitInd ) )
       {
      pReport->report.beaconReport.regClass =  pBcnReport->regClass;
           pReport[bssDescCnt].report.beaconReport.regClass =  pBcnReport->regClass;
           if ( flagBSSPresent )
           {
          pReport->report.beaconReport.channel = pBcnReport->pBssDescription[0]->channelId;
          vos_mem_copy( pReport->report.beaconReport.measStartTime,
                        pBcnReport->pBssDescription[0]->startTSF,
                        sizeof( pBcnReport->pBssDescription[0]->startTSF) );
          pReport->report.beaconReport.measDuration = SYS_MS_TO_TU(pBcnReport->duration);
          pReport->report.beaconReport.phyType = pBcnReport->pBssDescription[0]->nwType;
          pReport->report.beaconReport.bcnProbeRsp = 1;
          pReport->report.beaconReport.rsni = pBcnReport->pBssDescription[0]->sinr;
          pReport->report.beaconReport.rcpi = pBcnReport->pBssDescription[0]->rssi;

          pReport->report.beaconReport.antennaId = 0;
          pReport->report.beaconReport.parentTSF = pBcnReport->pBssDescription[0]->parentTSF;
          vos_mem_copy( pReport->report.beaconReport.bssid,
                        pBcnReport->pBssDescription[0]->bssId, sizeof(tSirMacAddr));
               pReport[bssDescCnt].report.beaconReport.channel =
                                 pBcnReport->pBssDescription[bssDescCnt]->channelId;
               vos_mem_copy( pReport[bssDescCnt].report.beaconReport.measStartTime,
                             pBcnReport->pBssDescription[bssDescCnt]->startTSF,
                             sizeof( pBcnReport->pBssDescription[bssDescCnt]->startTSF) );
               pReport[bssDescCnt].report.beaconReport.measDuration =
                                 SYS_MS_TO_TU(pBcnReport->duration);
               pReport[bssDescCnt].report.beaconReport.phyType =
                             pBcnReport->pBssDescription[bssDescCnt]->nwType;
               pReport[bssDescCnt].report.beaconReport.bcnProbeRsp = 1;
               pReport[bssDescCnt].report.beaconReport.rsni =
                             pBcnReport->pBssDescription[bssDescCnt]->sinr;
               pReport[bssDescCnt].report.beaconReport.rcpi =
                             pBcnReport->pBssDescription[bssDescCnt]->rssi;

               pReport[bssDescCnt].report.beaconReport.antennaId = 0;
               pReport[bssDescCnt].report.beaconReport.parentTSF =
                             pBcnReport->pBssDescription[bssDescCnt]->parentTSF;
               vos_mem_copy( pReport[bssDescCnt].report.beaconReport.bssid,
                             pBcnReport->pBssDescription[bssDescCnt]->bssId,
                             sizeof(tSirMacAddr));
           }

           switch ( pCurrentReq->request.Beacon.reportingDetail )
           {
         case BEACON_REPORTING_DETAIL_NO_FF_IE: //0 No need to include any elements.
               case BEACON_REPORTING_DETAIL_NO_FF_IE:
               //0 No need to include any elements.
#if defined WLAN_VOWIFI_DEBUG
               PELOGE(limLog(pMac, LOGE, "No reporting detail requested");)
#endif
               break;
         case BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE: //1: Include all FFs and Requested Ies.
               case BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE:
               //1: Include all FFs and Requested Ies.
#if defined WLAN_VOWIFI_DEBUG
            PELOGE(limLog(pMac, LOGE, "Only requested IEs in reporting detail requested");)
               PELOGE(limLog(pMac, LOGE,
               "Only requested IEs in reporting detail requested");)
#endif

               if ( flagBSSPresent )
               {
                rrmFillBeaconIes( pMac, (tANI_U8*) &pReport->report.beaconReport.Ies[0],
                      (tANI_U8*) &pReport->report.beaconReport.numIes, BEACON_REPORT_MAX_IES,
                      pCurrentReq->request.Beacon.reqIes.pElementIds, pCurrentReq->request.Beacon.reqIes.num,
                      pBcnReport->pBssDescription[0] );
                   rrmFillBeaconIes( pMac,
                      (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.Ies[0],
                      (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.numIes,
                      BEACON_REPORT_MAX_IES,
                      pCurrentReq->request.Beacon.reqIes.pElementIds,
                      pCurrentReq->request.Beacon.reqIes.num,
                      pBcnReport->pBssDescription[bssDescCnt] );
               }

               break;
         case BEACON_REPORTING_DETAIL_ALL_FF_IE: //2 / default - Include all FFs and all Ies.
               case BEACON_REPORTING_DETAIL_ALL_FF_IE:
               //2 / default - Include all FFs and all Ies.
               default:
#if defined WLAN_VOWIFI_DEBUG
               PELOGE(limLog(pMac, LOGE, "Default all IEs and FFs");)
#endif
               if ( flagBSSPresent )
               {
                rrmFillBeaconIes( pMac, (tANI_U8*) &pReport->report.beaconReport.Ies[0],
                      (tANI_U8*) &pReport->report.beaconReport.numIes, BEACON_REPORT_MAX_IES,
                   rrmFillBeaconIes( pMac,
                      (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.Ies[0],
                      (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.numIes,
                      BEACON_REPORT_MAX_IES,
                      NULL, 0,
                      pBcnReport->pBssDescription[0] );
                      pBcnReport->pBssDescription[bssDescCnt] );
               }
               break;
          }
       }
   }

#if defined WLAN_VOWIFI_DEBUG
   PELOGE(limLog( pMac, LOGE, "Sending Action frame ");)
#endif
      limSendRadioMeasureReportActionFrame( pMac, pCurrentReq->dialog_token, 1,
   limSendRadioMeasureReportActionFrame( pMac, pCurrentReq->dialog_token, bssDescCnt,
            pReport, pBcnReport->bssId, pSessionEntry );
   }


   if( pBcnReport->fMeasureDone )
   {
@@ -908,6 +950,9 @@ rrmProcessBeaconReportXmit( tpAniSirGlobal pMac,

      rrmCleanup(pMac);
   }

   vos_mem_free(pReport);

   return status;
}

+69 −30
Original line number Diff line number Diff line
@@ -186,7 +186,10 @@ void rrmIndicateNeighborReportResult(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
  \return - 0 for success, non zero for failure
  
  --------------------------------------------------------------------------*/
static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac, tCsrScanResultInfo **pResultArr, tANI_U8 measurementDone )
static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac,
                                                  tCsrScanResultInfo **pResultArr,
                                                  tANI_U8 measurementDone,
                                                  tANI_U8 bss_count )
{
   tpSirBssDescription pBssDesc = NULL;
   tpSirBeaconReportXmitInd pBeaconRep;
@@ -234,35 +237,62 @@ static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac, tCsrScanR
       while (pCurResult) 
       {
           pBssDesc = &pCurResult->BssDescriptor;
           if(pBssDesc != NULL)
           {
               ie_len = GET_IE_LEN_IN_BSS( pBssDesc->length );
           pBeaconRep->pBssDescription[msgCounter] = vos_mem_malloc ( ie_len+sizeof(tSirBssDescription) );
               pBeaconRep->pBssDescription[msgCounter] = vos_mem_malloc (
                                            ie_len+sizeof(tSirBssDescription));
               if (NULL == pBeaconRep->pBssDescription[msgCounter])
                   break;
           vos_mem_copy( pBeaconRep->pBssDescription[msgCounter], pBssDesc, sizeof(tSirBssDescription) );
           vos_mem_copy( &pBeaconRep->pBssDescription[msgCounter]->ieFields[0], pBssDesc->ieFields, ie_len  );
               vos_mem_copy( pBeaconRep->pBssDescription[msgCounter],
                             pBssDesc,
                             sizeof(tSirBssDescription) );
               vos_mem_copy( &pBeaconRep->pBssDescription[msgCounter]->ieFields[0],
                             pBssDesc->ieFields, ie_len  );
               smsLog( pMac, LOG1,
                   "...RRM Result Bssid = %02x-%02x-%02x-%02x-%02x-%02x chan= %d, rssi = -%d",
                   pBeaconRep->pBssDescription[msgCounter]->bssId[ 0 ],
                   pBeaconRep->pBssDescription[msgCounter]->bssId[ 1 ],
                   pBeaconRep->pBssDescription[msgCounter]->bssId[ 2 ],
                   pBeaconRep->pBssDescription[msgCounter]->bssId[ 3 ],
                   pBeaconRep->pBssDescription[msgCounter]->bssId[ 4 ],
                   pBeaconRep->pBssDescription[msgCounter]->bssId[ 5 ],
                   pBeaconRep->pBssDescription[msgCounter]->channelId,
                   pBeaconRep->pBssDescription[msgCounter]->rssi * (-1));

               pBeaconRep->numBssDesc++;

           if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC)
               if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC_PER_ACTION_FRAME)
                   break;

           if (csrRoamIs11rAssoc(pMac)) {
               pCurResult = pResultArr[bssCounter + msgCounter];
           }
           else
           {
               pCurResult = NULL;
               break;
           }

           pCurResult = pResultArr[msgCounter];
       }

       bssCounter+=msgCounter; 
       if (!pResultArr || !pCurResult || (bssCounter>=SIR_BCN_REPORT_MAX_BSS_DESC))
       if (!pResultArr || (pCurResult == NULL) || (bssCounter >= bss_count))
       {
           pCurResult = NULL;
           smsLog(pMac, LOG1,
                  "Reached to the max/last BSS in pCurResult list");
       }
       else
       {
           pCurResult = pResultArr[bssCounter];
           smsLog(pMac, LOG1,
                  "Move to the next BSS set in pCurResult list");
       }

       pBeaconRep->fMeasureDone = (pCurResult)?false:measurementDone;

       smsLog(pMac, LOGW, "SME Sending BcnRepXmit to PE numBss %d",
              pBeaconRep->numBssDesc);
       smsLog(pMac, LOG1,
              "SME Sending BcnRepXmit to PE numBss %d msgCounter %d bssCounter %d",
              pBeaconRep->numBssDesc, msgCounter, bssCounter);

       status = palSendMBMessage(pMac->hHdd, pBeaconRep);

@@ -285,12 +315,15 @@ static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac, tCsrScanR
  \return - 0 for success, non zero for failure
  
  --------------------------------------------------------------------------*/
static eHalStatus sme_RrmSendScanResult( tpAniSirGlobal pMac, tANI_U8 num_chan, tANI_U8* chanList, tANI_U8 measurementDone )
static eHalStatus sme_RrmSendScanResult( tpAniSirGlobal pMac,
                                         tANI_U8 num_chan,
                                         tANI_U8* chanList,
                                         tANI_U8 measurementDone )
{
   tCsrScanResultFilter filter;
   tScanResultHandle pResult;
   tCsrScanResultInfo *pScanResult, *pNextResult;
   tCsrScanResultInfo *pScanResultsArr[SIR_BCN_REPORT_MAX_BSS_DESC];
   tCsrScanResultInfo *pScanResultsArr[SIR_BCN_REPORT_MAX_BSS_PER_CHANNEL];
   eHalStatus status;
   tANI_U8 counter=0;
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
@@ -301,7 +334,7 @@ static eHalStatus sme_RrmSendScanResult( tpAniSirGlobal pMac, tANI_U8 num_chan,
#endif

   vos_mem_zero( &filter, sizeof(filter) );
   vos_mem_zero( pScanResultsArr, sizeof(pNextResult)*SIR_BCN_REPORT_MAX_BSS_DESC );
   vos_mem_zero( pScanResultsArr, sizeof(pNextResult)*SIR_BCN_REPORT_MAX_BSS_PER_CHANNEL );

   filter.BSSIDs.numOfBSSIDs = 1;
   filter.BSSIDs.bssid = &pSmeRrmContext->bssId;
@@ -359,14 +392,14 @@ static eHalStatus sme_RrmSendScanResult( tpAniSirGlobal pMac, tANI_U8 num_chan,
      // 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 );
         status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0 );
      return status;
   }

   pScanResult = sme_ScanResultGetFirst(pMac, pResult);

   if( NULL == pScanResult && measurementDone )
      status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone );
      status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0 );

   counter=0;
   while (pScanResult)
@@ -374,13 +407,19 @@ static eHalStatus sme_RrmSendScanResult( tpAniSirGlobal pMac, tANI_U8 num_chan,
      pNextResult = sme_ScanResultGetNext(pMac, pResult);
      pScanResultsArr[counter++] = pScanResult;
      pScanResult = pNextResult; //sme_ScanResultGetNext(hHal, pResult);
      if (counter >= SIR_BCN_REPORT_MAX_BSS_DESC)
      if (counter >= SIR_BCN_REPORT_MAX_BSS_PER_CHANNEL)
         break;
      }

   if (counter)
       status = sme_RrmSendBeaconReportXmitInd( pMac, pScanResultsArr, measurementDone);

   {
       status = sme_RrmSendBeaconReportXmitInd( pMac,
                                                pScanResultsArr,
                                                measurementDone,
                                                counter);
       smsLog(pMac, LOG1, " Number of BSS Desc with RRM Scan %d ",
              counter);
   }
   sme_ScanResultPurge(pMac, pResult); 

   return status;
@@ -668,7 +707,7 @@ void sme_RrmProcessBeaconReportReqInd(tpAniSirGlobal pMac, void *pMsgBuf)
         /* 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);
         sme_RrmSendBeaconReportXmitInd(pMac, NULL, true, 0);
         break;

   }