/*
 * Copyright (c) 2012-2014, 2016,2018 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/**=========================================================================
  
  \file  sme_Rrm.c
  
  \brief implementation for SME RRM APIs
  
  
  ========================================================================*/

/* $Header$ */

#if defined WLAN_FEATURE_VOWIFI
/*--------------------------------------------------------------------------
  Include Files
  ------------------------------------------------------------------------*/
#include "aniGlobal.h"
#include "smeInside.h"
#include "sme_Api.h"
#include "smsDebug.h"
#include "cfgApi.h"

#ifdef FEATURE_WLAN_DIAG_SUPPORT
#include "vos_diag_core_event.h"
#include "vos_diag_core_log.h"
#endif /* FEATURE_WLAN_DIAG_SUPPORT */

#include "csrInsideApi.h"

#include "rrmGlobal.h"

#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
#include "csrEse.h"
#endif

/* Roam score for a neighbor AP will be calculated based on the below definitions.
    The calculated roam score will be used to select the roamable candidate from neighbor AP list */
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY             0   /* When we support 11r over the DS, this should have a non-zero value */
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY                 10
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE                20
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT 0   /* Not used */
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS           5
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD          3
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM           8
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA    0   /* We dont support delayed BA */
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA  3
#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN          30

#ifdef FEATURE_WLAN_ESE
#define RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST                       30
#endif

v_TIME_t RRM_scan_timer;

/**---------------------------------------------------------------------------
  
  \brief rrmLLPurgeNeighborCache() - 
    This function purges all the entries in the neighbor cache and frees up all the internal nodes   

  \param  - pMac  - Pointer to the Hal Handle.
          - pList - Pointer the List that should be purged.
  \return - void
  
  --------------------------------------------------------------------------*/
static void rrmLLPurgeNeighborCache(tpAniSirGlobal pMac, tDblLinkList *pList)
{
    tListElem *pEntry;
    tRrmNeighborReportDesc *pNeighborReportDesc;
    
    csrLLLock(pList);
    
    while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_NOLOCK)) != NULL)
    {
        pNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
        vos_mem_free(pNeighborReportDesc->pNeighborBssDescription);
        vos_mem_free(pNeighborReportDesc);
    }
    
    csrLLUnlock(pList);   
     
    return;
}

/**---------------------------------------------------------------------------
  
  \brief rrmIndicateNeighborReportResult() - 
        This function calls the callback register by the caller while requesting for 
        neighbor report. This function gets invoked if a neighbor report is received from an AP
        or neighbor response wait timer expires.

  \param  - pMac - Pointer to the Hal Handle.
          - vosStatus - VOS_STATUS_SUCCESS/VOS_STATUS_FAILURE based on whether a valid report is 
            received or neighbor timer expired
  \return - void
  
  --------------------------------------------------------------------------*/
void rrmIndicateNeighborReportResult(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
{
    NeighborReportRspCallback callback;
    void                      *callbackContext;

    /* Reset the neighbor response pending status */
    pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE;

    /* Stop the timer if it is already running. The timer should be running only in the SUCCESS case. */
    if (VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer))
    {
        smsLog( pMac, LOG1, FL("No entry in neighbor report cache"));
        vos_timer_stop(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer);
    }
    callback = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback;
    callbackContext = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext;
    
    /* Reset the callback and the callback context before calling the callback. It is very likely that there may be a registration in 
            callback itself. */
    pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback = NULL;
    pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext = NULL;
    
    /* Call the callback with the status received from caller */
    if (callback)
        callback(callbackContext, vosStatus);
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
    // We came here with IAPP AP List
    // Make sure we inform CSR of the neighbor list
    // for ESE Associations. First clear the cache.
    else
    if (csrNeighborRoamIsESEAssoc(pMac))
    {
        ProcessIAPPNeighborAPList(pMac);
    }
#endif

    return;

}

/**---------------------------------------------------------------------------
  
  \brief sme_RrmBeaconReportXmitInd() - 

   Create and send the beacon report Xmit ind message to PE.

  \param  - pMac - Pointer to the Hal Handle.
              - pResult - scan result.
              - measurementDone - flag to indicate that the measurement is done.        
  \return - 0 for success, non zero for failure
  
  --------------------------------------------------------------------------*/
static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac,
                                                  tCsrScanResultInfo **pResultArr,
                                                  tANI_U8 measurementDone,
                                                  tANI_U8 bss_count )
{
   tpSirBssDescription pBssDesc = NULL;
   tpSirBeaconReportXmitInd pBeaconRep;
   tANI_U16 length, ie_len;
   tANI_U8 bssCounter=0, msgCounter=0;
   tCsrScanResultInfo *pCurResult=NULL;
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;


#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, "Beacon report xmit Ind to PE");
#endif

   if( NULL == pResultArr && !measurementDone )
   {
      smsLog( pMac, LOGE, "Beacon report xmit Ind to PE Failed");
      return eHAL_STATUS_FAILURE;
   }

   if (pResultArr)
       pCurResult=pResultArr[bssCounter];

   do 
   {
       length = sizeof(tSirBeaconReportXmitInd);
       pBeaconRep = vos_mem_malloc ( length );
       if ( NULL == pBeaconRep )
       {
          smsLog( pMac, LOGP, "Unable to allocate memory for beacon report");
          return eHAL_STATUS_FAILED_ALLOC;
       }
       vos_mem_zero( pBeaconRep, length );
#if defined WLAN_VOWIFI_DEBUG
       smsLog( pMac, LOGE, FL("Allocated memory for pBeaconRep"));
#endif
       pBeaconRep->messageType = eWNI_SME_BEACON_REPORT_RESP_XMIT_IND;
       pBeaconRep->length = length;
       pBeaconRep->uDialogToken = pSmeRrmContext->token;
       pBeaconRep->duration = pSmeRrmContext->duration[0];
       pBeaconRep->regClass = pSmeRrmContext->regClass;
       vos_mem_copy( pBeaconRep->bssId, pSmeRrmContext->sessionBssId, sizeof(tSirMacAddr) );

       msgCounter=0;
       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));
               if (NULL == pBeaconRep->pBssDescription[msgCounter])
                   break;
               vos_mem_zero(pBeaconRep->pBssDescription[msgCounter],
                            ie_len+sizeof(tSirBssDescription));
               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 = "MAC_ADDRESS_STR" chan= %d, rssi = -%d",
                   MAC_ADDR_ARRAY(pBeaconRep->pBssDescription[msgCounter]->bssId),
                   pBeaconRep->pBssDescription[msgCounter]->channelId,
                   pBeaconRep->pBssDescription[msgCounter]->rssi * (-1));

               pBeaconRep->numBssDesc++;

               if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC)
                   break;

               pCurResult = pResultArr[bssCounter + msgCounter];
           }
           else
           {
               pCurResult = NULL;
               break;
           }
       }

       bssCounter+=msgCounter; 
       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, LOG1,
              "SME Sending BcnRepXmit to PE numBss %d msgCounter %d bssCounter %d",
              pBeaconRep->numBssDesc, msgCounter, bssCounter);

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

   } while (pCurResult);

   return status;
}

#if defined(FEATURE_WLAN_ESE_UPLOAD)
/**---------------------------------------------------------------------------

  \brief sme_EseSendBeaconReqScanResults()

   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_EseSendBeaconReqScanResults(tpAniSirGlobal pMac,
                                                  tANI_U32       sessionId,
                                                  tANI_U8        channel,
                                                  tCsrScanResultInfo **pResultArr,
                                                  tANI_U8        measurementDone,
                                                  tANI_U8        bss_count)
{
   eHalStatus              status         = eHAL_STATUS_FAILURE;
   tSirRetStatus           fillIeStatus;
   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;
   tSirEseBcnReportRsp     bcnReport;
   tpSirEseBcnReportRsp    pBcnReport     = &bcnReport;
   tpCsrEseBeaconReqParams 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(tSirEseBcnReportRsp));
   do
   {
       pCurMeasReqIe = NULL;
       for (i = 0; i < pSmeRrmContext->eseBcnReqInfo.numBcnReqIe; i++)
       {
           if(pSmeRrmContext->eseBcnReqInfo.bcnReq[i].channel == channel)
           {
               pCurMeasReqIe = &pSmeRrmContext->eseBcnReqInfo.bcnReq[i];
               break;
           }
       }
       if(NULL != pCurMeasReqIe)
           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;
               if(NULL != pCurMeasReqIe)
                   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));

               fillIeStatus = sirFillBeaconMandatoryIEforEseBcnReport(pMac,
                                                                      (tANI_U8 *)pBssDesc->ieFields,
                                                                      ie_len,
                                                                      &(pBcnReport->bcnRepBssInfo[msgCounter].pBuf),
                                                                      &outIeLen);
               if (eSIR_FAILURE == fillIeStatus)
               {
                  continue;
               }
               pBcnReport->bcnRepBssInfo[msgCounter].ieLen = outIeLen;

               smsLog( pMac, LOG1,"Bssid("MAC_ADDRESS_STR") Channel=%d Rssi=%d",
                       MAC_ADDR_ARRAY(pBssDesc->bssId),
                       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) flag(%d)",
                pBcnReport->numBss, msgCounter, bssCounter, pBcnReport->flag);

       roamInfo.pEseBcnReportRsp = pBcnReport;
       status = csrRoamCallCallback(pMac, sessionId, &roamInfo,
                           0, eCSR_ROAM_ESE_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_ESE_UPLOAD */

/**---------------------------------------------------------------------------
  
  \brief sme_RrmSendScanRequest() - 

   This function is called to get the scan result from CSR and send the beacon report
   xmit ind message to PE.

  \param  - pMac - Pointer to the Hal Handle.
              - num_chan - number of channels.
              - channel list - list of channels to fetch the result from.
              - measurementDone - flag to indicate that the measurement is done.        
  \return - 0 for success, non zero for failure
  
  --------------------------------------------------------------------------*/
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];
   eHalStatus status;
   tANI_U8 counter=0;
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
   tANI_U32 sessionId;
   tCsrRoamInfo *roam_info;

#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, "Send scan result to PE ");
#endif

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

   filter.BSSIDs.numOfBSSIDs = 1;
   filter.BSSIDs.bssid = &pSmeRrmContext->bssId;

   if( pSmeRrmContext->ssId.length )
   {
      filter.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
      if( filter.SSIDs.SSIDList == NULL )
      {
         smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
         return eHAL_STATUS_FAILURE;
      }
#if defined WLAN_VOWIFI_DEBUG
      smsLog( pMac, LOGE, FL("Allocated memory for SSIDList"));
#endif
      vos_mem_zero( filter.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) );

      filter.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length;
      vos_mem_copy(filter.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length);
      filter.SSIDs.numOfSSIDs = 1;
   }
   else
   {
      filter.SSIDs.numOfSSIDs = 0;
   }

   filter.ChannelInfo.numOfChannels = num_chan;
   filter.ChannelInfo.ChannelList = chanList; 

   filter.fMeasurement = TRUE; 

   csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId );
   status = sme_ScanGetResult(pMac, (tANI_U8)sessionId, &filter, &pResult);

   if( filter.SSIDs.SSIDList )
   {
      //Free the memory allocated for SSIDList.
      vos_mem_free( filter.SSIDs.SSIDList );
#if defined WLAN_VOWIFI_DEBUG
      smsLog( pMac, LOGE, FL("Free memory for SSIDList") );
#endif
   }

   smsLog(pMac, LOG1, FL("RRM Measurement Done %d"), measurementDone);

   if (NULL == pResult)
   {
      // no scan results
      //
      // Spec. doesnt say anything about such condition. 
      // Since section 7.4.6.2 (IEEE802.11k-2008) says-rrm report frame should contain
      // one or more report IEs. It probably means dont send any respose if no matching
      // BSS found. Moreover, there is no flag or field in measurement report IE(7.3.2.22)
      // OR beacon report IE(7.3.2.22.6) that can be set to indicate no BSS found on a given channel.
      //
      // If we finished measurement on all the channels, we still need to
      // send a xmit indication with moreToFollow set to MEASURMENT_DONE
      // so that PE can clean any context allocated.
      if( measurementDone )
      {
#if defined(FEATURE_WLAN_ESE_UPLOAD)
         if (eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource)
         {
             status = sme_EseSendBeaconReqScanResults(pMac,
                                                  sessionId,
                                                  chanList[0],
                                                  NULL,
                                                  measurementDone,
                                                  0);
         }
         else
#endif /*FEATURE_WLAN_ESE_UPLOAD*/
             status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0);
      }
      return status;
   }

   pScanResult = sme_ScanResultGetFirst(pMac, pResult);

   if( NULL == pScanResult && measurementDone )
   {
#if defined(FEATURE_WLAN_ESE_UPLOAD)
       if (eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource)
       {
           status = sme_EseSendBeaconReqScanResults(pMac,
                                                 sessionId,
                                                 chanList[0],
                                                 NULL,
                                                 measurementDone,
                                                 0);
       }
       else
#endif /*FEATURE_WLAN_ESE_UPLOAD*/
           status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0 );
   }

   counter=0;
   while (pScanResult)
   {
      pNextResult = sme_ScanResultGetNext(pMac, pResult);
      smsLog(pMac, LOG1, "Scan res timer:%lu, rrm scan timer:%lu",
             pScanResult->timer, RRM_scan_timer);
      if (pScanResult->timer >= RRM_scan_timer) {
          roam_info = vos_mem_malloc(sizeof(*roam_info));
          if (NULL == roam_info) {
              smsLog(pMac, LOGW, FL("vos_mem_malloc failed:"));
              status =  eHAL_STATUS_FAILED_ALLOC;
              goto rrm_send_scan_results_done;
          }
          vos_mem_zero(roam_info, sizeof(*roam_info));
          roam_info->pBssDesc = &pScanResult->BssDescriptor;
          csrRoamCallCallback(pMac, sessionId, roam_info, 0,
                           eCSR_ROAM_UPDATE_SCAN_RESULT, eCSR_ROAM_RESULT_NONE);
          vos_mem_free(roam_info);
          pScanResultsArr[counter++] = pScanResult;
      }
      pScanResult = pNextResult; //sme_ScanResultGetNext(hHal, pResult);
      if (counter >= SIR_BCN_REPORT_MAX_BSS_DESC)
         break;
      }

   smsLog(pMac, LOG1, " Number of BSS Desc with RRM Scan %d ", counter);
   /*
    * The beacon report should be sent whether the counter is zero or non-zero.
    * There might be a few scan results in the cache but not actually are a
    * result of this scan. During that scenario, the counter will be zero.
    * The report should be sent and LIM will further cleanup the RRM to
    * accept the further incoming requests
    * In case the counter is Zero, the pScanResultsArr will be NULL.
    * The next level routine does a check for the measurementDone to determine
    * whether to send a report or not.
    */

   if (counter || measurementDone) {
#if defined(FEATURE_WLAN_ESE_UPLOAD)
       if (eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource)
       {
           status = sme_EseSendBeaconReqScanResults(pMac,
                                                sessionId,
                                                chanList[0],
                                                pScanResultsArr,
                                                measurementDone,
                                                counter);
       }
       else
#endif /*FEATURE_WLAN_ESE_UPLOAD*/
           status = sme_RrmSendBeaconReportXmitInd( pMac,
                                                pScanResultsArr,
                                                measurementDone,
                                                counter);
   }

rrm_send_scan_results_done:
   sme_ScanResultPurge(pMac, pResult); 

   return status;
}
/**---------------------------------------------------------------------------
  
  \brief sme_RrmScanRequestCallback() - 

   The sme module calls this callback function once it finish the scan request
   and this function send the beacon report xmit to PE and starts a timer of
   random interval to issue next request.

  \param  - halHandle - Pointer to the Hal Handle.
              - pContext - Pointer to the data context.
              - scanId - Scan ID.
              - status - CSR Status.        
  \return - 0 for success, non zero for failure
  
  --------------------------------------------------------------------------*/

static eHalStatus sme_RrmScanRequestCallback(tHalHandle halHandle, void *pContext,
                         tANI_U32 scanId, eCsrScanStatus status)
{

   tANI_U16 interval;
   tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
   tANI_U32 time_tick; 



#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, "Scan Request callback ");
#endif
   //if any more channels are pending, start a timer of a random value within randomization interval.
   //
   //
   if( (pSmeRrmContext->currentIndex + 1) < pSmeRrmContext->channelList.numOfChannels )
   {
      sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], false );

      pSmeRrmContext->currentIndex++; //Advance the current index.
      //start the timer to issue next request. 
      //From timer tick get a random number within 10ms and max randmization interval.
      time_tick = vos_timer_get_system_ticks();
      interval = time_tick % (pSmeRrmContext->randnIntvl - 10 + 1) + 10;

#if defined WLAN_VOWIFI_DEBUG
      smsLog( pMac, LOGE, "Set timer for interval %d ", interval);
#endif
      vos_timer_start( &pSmeRrmContext->IterMeasTimer, interval );

   }
   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 );
#if defined WLAN_VOWIFI_DEBUG
      smsLog( pMac, LOGE, FL("Free memory for ChannelList") );
#endif
   }

   return eHAL_STATUS_SUCCESS;
}

/*--------------------------------------------------------------------------
  \brief sme_RrmIssueScanReq() - This is called to send a scan request as part 
         of beacon report request .
  
  \param  pMac  - pMac global pointer
  
  \return eHAL_STATUS_SUCCESS - Validation is successful.
  
  \sa
  
  --------------------------------------------------------------------------*/
eHalStatus sme_RrmIssueScanReq( tpAniSirGlobal pMac )
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
   tSirScanType scanType;

   if ((pSmeRrmContext->currentIndex) >= pSmeRrmContext->channelList.numOfChannels)
       return status;

   if( eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource ||
       eRRM_MSG_SOURCE_LEGACY_ESE == pSmeRrmContext->msgSource )
       scanType = pSmeRrmContext->measMode[pSmeRrmContext->currentIndex];
   else
       scanType = pSmeRrmContext->measMode[0];

   if ((eSIR_ACTIVE_SCAN == scanType) || (eSIR_PASSIVE_SCAN == scanType))
   {
       tCsrScanRequest scanRequest;
       v_U32_t scanId = 0;
       tANI_U32 sessionId;
#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, "Issue scan request " );
#endif

       vos_mem_zero( &scanRequest, sizeof(scanRequest));

       /* set scanType, active or passive */
       scanRequest.scanType = scanType;

       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 (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"));
#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);
       }

       /* set min and max channel time */
       scanRequest.minChnTime = 0; //pSmeRrmContext->duration; Dont use min timeout.
       if( eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource ||
           eRRM_MSG_SOURCE_LEGACY_ESE == pSmeRrmContext->msgSource )
          scanRequest.maxChnTime = pSmeRrmContext->duration[pSmeRrmContext->currentIndex];
       else
          scanRequest.maxChnTime = pSmeRrmContext->duration[0];

       smsLog( pMac, LOG1, "Scan Type(%s (%d)) Max Dwell Time(%d)",
               lim_ScanTypetoString(scanRequest.scanType),
               scanRequest.scanType,
               scanRequest.maxChnTime );

       RRM_scan_timer = vos_timer_get_system_time();

#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
       }
   }
   else if (2 == scanType)  /* beacon table */
   {
       /*In beacon table mode, scan results are taken directly from scan cache
         without issuing any scan request. So, it is not proper to update
         RRM_scan_timer with latest time and hence made it to zero to satisfy
         pScanResult->timer >= RRM_scan_timer */
       RRM_scan_timer = 0;
       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(%s (%d))",
               lim_ScanTypetoString(scanType), 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;
}

/*--------------------------------------------------------------------------
  \brief sme_RrmProcessBeaconReportReqInd() - This is called to process the Beacon 
         report request from peer AP forwarded through PE .
  
  \param pMsgBuf - a pointer to a buffer that maps to various structures base 
                   on the message type.
                   The beginning of the buffer can always map to tSirSmeRsp.
  
  \return eHAL_STATUS_SUCCESS - Validation is successful.
  
  \sa
  
  --------------------------------------------------------------------------*/
void sme_RrmProcessBeaconReportReqInd(tpAniSirGlobal pMac, void *pMsgBuf)
{
   tpSirBeaconReportReqInd pBeaconReq = (tpSirBeaconReportReqInd) pMsgBuf;
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
   tANI_U32 len = 0, i = 0;

#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, "Received Beacon report request ind Channel = %d", pBeaconReq->channelInfo.channelNum );
#endif

   if (pBeaconReq->channelList.numChannels > SIR_ESE_MAX_MEAS_IE_REQS) {
        smsLog( pMac, LOGP, "Beacon report request numChannels: %u exceeds "
               "max num channels", pBeaconReq->channelList.numChannels);
        return;
   }
   //section 11.10.8.1 (IEEE Std 802.11k-2008) 
   //channel 0 and 255 has special meaning.
   if( (pBeaconReq->channelInfo.channelNum == 0)  || 
       ((pBeaconReq->channelInfo.channelNum == 255) && (pBeaconReq->channelList.numChannels == 0) ) ) 
   {
      //Add all the channel in the regulatory domain.
      wlan_cfgGetStrLen( pMac, WNI_CFG_VALID_CHANNEL_LIST, &len );
      pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len );
      if( pSmeRrmContext->channelList.ChannelList == NULL )
      {
         smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
         return;
      }
#if defined WLAN_VOWIFI_DEBUG
      smsLog( pMac, LOGE, FL("Allocated memory for ChannelList") );
#endif
      csrGetCfgValidChannels( pMac, pSmeRrmContext->channelList.ChannelList, &len );
      pSmeRrmContext->channelList.numOfChannels = (tANI_U8)len;
#if defined WLAN_VOWIFI_DEBUG
      smsLog( pMac, LOGE, "channel == 0 performing on all channels");
#endif
   }
   else
   { 
      len = 0;
      pSmeRrmContext->channelList.numOfChannels = 0;

      //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;
#if defined WLAN_VOWIFI_DEBUG
      else
         smsLog( pMac, LOGE, "channel == 255");
#endif

      len += pBeaconReq->channelList.numChannels;

      pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len );
      if( pSmeRrmContext->channelList.ChannelList == NULL )
      {
         smsLog( pMac, LOGP, FL("vos_mem_malloc failed") );
         return;
      }
#if defined WLAN_VOWIFI_DEBUG
      smsLog( pMac, LOGE, FL("Allocated memory for ChannelList") );
#endif

      if ( pBeaconReq->channelInfo.channelNum != 255 )
      {
#if defined WLAN_VOWIFI_DEBUG
         smsLog( pMac, LOGE, "channel == %d  ", pBeaconReq->channelInfo.channelNum );
#endif
         if(csrRoamIsChannelValid( pMac, pBeaconReq->channelInfo.channelNum ))
            pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels++] = pBeaconReq->channelInfo.channelNum;
#if defined WLAN_VOWIFI_DEBUG
         else
            smsLog( pMac, LOGE, "is Invalid channel, Ignoring this channel" );
#endif
      }

      for ( i = 0 ; i < pBeaconReq->channelList.numChannels; i++ )
      {
         if(csrRoamIsChannelValid( pMac, pBeaconReq->channelList.channelNumber[i] ))
         {
            pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels] = pBeaconReq->channelList.channelNumber[i];
            pSmeRrmContext->channelList.numOfChannels++;
         }
      }
   }

   //Copy session bssid
   vos_mem_copy( pSmeRrmContext->sessionBssId, pBeaconReq->bssId, sizeof(tSirMacAddr) );

   //copy measurement bssid
   vos_mem_copy( pSmeRrmContext->bssId, pBeaconReq->macaddrBssid, sizeof(tSirMacAddr) );

   //Copy ssid
   vos_mem_copy( &pSmeRrmContext->ssId, &pBeaconReq->ssId, sizeof(tAniSSID) ); 

   pSmeRrmContext->token = pBeaconReq->uDialogToken;
   pSmeRrmContext->regClass = pBeaconReq->channelInfo.regulatoryClass;
   pSmeRrmContext->randnIntvl = VOS_MAX( pBeaconReq->randomizationInterval, pSmeRrmContext->rrmConfig.maxRandnInterval );
   pSmeRrmContext->currentIndex = 0;
   pSmeRrmContext->msgSource = pBeaconReq->msgSource;
   vos_mem_copy((tANI_U8*)&pSmeRrmContext->measMode, (tANI_U8*)&pBeaconReq->fMeasurementtype, SIR_ESE_MAX_MEAS_IE_REQS);
   vos_mem_copy((tANI_U8*)&pSmeRrmContext->duration, (tANI_U8*)&pBeaconReq->measurementDuration, SIR_ESE_MAX_MEAS_IE_REQS);

   sme_RrmIssueScanReq( pMac );

   return;
}

/*--------------------------------------------------------------------------
  \brief sme_RrmNeighborReportRequest() - This is API can be used to trigger a 
         Neighbor report from the peer.
  
  \param sessionId - session identifier on which the request should be made.       
  \param pNeighborReq - a pointer to a neighbor report request.
  
  \return eHAL_STATUS_SUCCESS - Validation is successful.
  
  \sa
  
  --------------------------------------------------------------------------*/
VOS_STATUS sme_RrmNeighborReportRequest(tpAniSirGlobal pMac, tANI_U8 sessionId, 
                                    tpRrmNeighborReq pNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpSirNeighborReportReqInd pMsg;
   tCsrRoamSession *pSession;

#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, FL("Request to send Neighbor report request received "));
#endif
   if( !CSR_IS_SESSION_VALID( pMac, sessionId ) )
   {  
      smsLog( pMac, LOGE, FL("Invalid session %d"), sessionId );
      return VOS_STATUS_E_INVAL;
   }
   pSession = CSR_GET_SESSION( pMac, sessionId );

   /* If already a report is pending, return failure */
   if (eANI_BOOLEAN_TRUE == pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending)
   {
       smsLog( pMac, LOGE, FL("Neighbor request already pending.. Not allowed"));
       return VOS_STATUS_E_AGAIN;
   }
   
   pMsg = vos_mem_malloc ( sizeof(tSirNeighborReportReqInd) );
   if ( NULL == pMsg )
   {
      smsLog( pMac, LOGE, "Unable to allocate memory for Neighbor request");
      return VOS_STATUS_E_NOMEM;
   }

   
   vos_mem_zero( pMsg, sizeof(tSirNeighborReportReqInd) );
#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, FL(" Allocated memory for Neighbor request") );
#endif

   rrmLLPurgeNeighborCache(pMac, &pMac->rrm.rrmSmeContext.neighborReportCache);

#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, FL("Purged the neighbor cache before sending Neighbor request: Status = %d"), status );
#endif

   pMsg->messageType = eWNI_SME_NEIGHBOR_REPORT_REQ_IND;
   pMsg->length = sizeof( tSirNeighborReportReqInd );
   vos_mem_copy( &pMsg->bssId, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) );
   pMsg->noSSID = pNeighborReq->no_ssid;
   vos_mem_copy( &pMsg->ucSSID, &pNeighborReq->ssid, sizeof(tSirMacSSid));

   status = palSendMBMessage(pMac->hHdd, pMsg);
   if( status != eHAL_STATUS_SUCCESS )
      return VOS_STATUS_E_FAILURE;

   /* Neighbor report request message sent successfully to PE. Now register the callbacks */
   pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback = 
                                                            callbackInfo->neighborRspCallback;
   pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext = 
                                                            callbackInfo->neighborRspCallbackContext;
   pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_TRUE;

   /* Start neighbor response wait timer now */
   vos_timer_start(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer, callbackInfo->timeout);
   
   return VOS_STATUS_SUCCESS;
}

/*--------------------------------------------------------------------------
  \brief rrmCalculateNeighborAPRoamScore() - This API is called while handling 
                individual neighbor reports from the APs neighbor AP report to 
                calculate the cumulative roam score before storing it in neighbor 
                cache.
  
  \param pNeighborReportDesc - Neighbor BSS Descriptor node for which roam score 
                                should be calculated
  
  \return void.
--------------------------------------------------------------------------*/
static void rrmCalculateNeighborAPRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc)
{
    tpSirNeighborBssDescripton  pNeighborBssDesc;
    tANI_U32    roamScore = 0;
    
    if (NULL == pNeighborReportDesc)
    {
        VOS_ASSERT(0);
        return;
    }
    if (NULL == pNeighborReportDesc->pNeighborBssDescription)
    {
        VOS_ASSERT(0);
        return;
    }

    pNeighborBssDesc = pNeighborReportDesc->pNeighborBssDescription;

    if (pNeighborBssDesc->bssidInfo.rrmInfo.fMobilityDomain)
    {
        roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN;
        if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameSecurityMode)
        {
            roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY;
            if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameAuthenticator)
            {
                roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE;
                if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapRadioMeasurement)
                {
                    roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM;
                    if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapSpectrumMeasurement)
                        roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT;
                    if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapQos)
                        roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS;
                    if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapApsd)
                        roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD;
                    if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapDelayedBlockAck)
                        roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA;
                    if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapImmediateBlockAck)
                        roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA;
                    if (pNeighborBssDesc->bssidInfo.rrmInfo.fApPreauthReachable)
                        roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY;
                }
            }
        }
    }
#ifdef FEATURE_WLAN_ESE
    // It has come in the report so its the best score
    if (csrNeighborRoamIs11rAssoc(pMac) == FALSE)
    {
        // IAPP Route so lets make use of this info
        // save all AP, as the list does not come all the time
        // Save and reuse till the next AP List comes to us.
        // Even save our own MAC address. Will be useful next time around.
        roamScore += RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST;
    }
#endif
    pNeighborReportDesc->roamScore = roamScore;

    return;
}

/*--------------------------------------------------------------------------
  \brief rrmStoreNeighborRptByRoamScore() - This API is called to store a given 
                        Neighbor BSS descriptor to the neighbor cache. This function 
                        stores the neighbor BSS descriptors in such a way that descriptors 
                        are sorted by roamScore in descending order

  \param pNeighborReportDesc - Neighbor BSS Descriptor node to be stored in cache
  
  \return void.
--------------------------------------------------------------------------*/
void rrmStoreNeighborRptByRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc)
{
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
   tListElem       *pEntry;
   tRrmNeighborReportDesc  *pTempNeighborReportDesc;

   if (NULL == pNeighborReportDesc)
   {
       VOS_ASSERT(0);
       return;
   }
   if (NULL == pNeighborReportDesc->pNeighborBssDescription)
   {
       VOS_ASSERT(0);
       return;
   }

   if (csrLLIsListEmpty(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK))
   {
       smsLog(pMac, LOGE, FL("Neighbor report cache is empty.. Adding a entry now"));
        /* Neighbor list cache is empty. Insert this entry in the tail */
       csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
       return;
   }
   else
   {
       /* Should store the neighbor BSS description in the order sorted by roamScore in descending
              order. APs with highest roamScore should be the 1st entry in the list */
        pEntry = csrLLPeekHead(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK);
        while (pEntry != NULL)
        {
            pTempNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
            if (pTempNeighborReportDesc->roamScore < pNeighborReportDesc->roamScore)
                break;
            pEntry = csrLLNext(&pSmeRrmContext->neighborReportCache, pEntry, LL_ACCESS_LOCK);
        } 

        if (pEntry)
            /* This BSS roamscore is better than something in the list. Insert this before that one */
            csrLLInsertEntry(&pSmeRrmContext->neighborReportCache, pEntry, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
        else
            /* All the entries in the list has a better roam Score than this one. Insert this at the last */
            csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
   }
   return;
}

/*--------------------------------------------------------------------------
  \brief sme_RrmProcessNeighborReport() - This is called to process the Neighbor 
         report received from PE.
  
  \param pMsgBuf - a pointer to a buffer that maps to various structures base 
                   on the message type.
                   The beginning of the buffer can always map to tSirSmeRsp.
  
  \return eHAL_STATUS_SUCCESS - Validation is successful.
  
  \sa
  
  --------------------------------------------------------------------------*/
eHalStatus sme_RrmProcessNeighborReport(tpAniSirGlobal pMac, void *pMsgBuf)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpSirNeighborReportInd pNeighborRpt = (tpSirNeighborReportInd) pMsgBuf;
   tpRrmNeighborReportDesc  pNeighborReportDesc;
   tANI_U8 i = 0;
   VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;

#ifdef FEATURE_WLAN_ESE
   // Clear the cache for ESE.
   if (csrNeighborRoamIsESEAssoc(pMac))
   {
       rrmLLPurgeNeighborCache(pMac, 
           &pMac->rrm.rrmSmeContext.neighborReportCache);
   }
#endif

   for (i = 0; i < pNeighborRpt->numNeighborReports; i++)
   {
       pNeighborReportDesc = vos_mem_malloc(sizeof(tRrmNeighborReportDesc));
       if (NULL == pNeighborReportDesc)
       {
           smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report desc");
           status = eHAL_STATUS_FAILED_ALLOC;
           goto end;
            
       }

       vos_mem_zero(pNeighborReportDesc, sizeof(tRrmNeighborReportDesc));
       pNeighborReportDesc->pNeighborBssDescription = vos_mem_malloc(sizeof(tSirNeighborBssDescription));
       if (NULL == pNeighborReportDesc->pNeighborBssDescription)
       {
           smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report BSS Description");
           vos_mem_free(pNeighborReportDesc);
           status = eHAL_STATUS_FAILED_ALLOC;
           goto end;
       }
       vos_mem_zero(pNeighborReportDesc->pNeighborBssDescription, sizeof(tSirNeighborBssDescription));
       vos_mem_copy(pNeighborReportDesc->pNeighborBssDescription, &pNeighborRpt->sNeighborBssDescription[i], 
                                                sizeof(tSirNeighborBssDescription));

#if defined WLAN_VOWIFI_DEBUG
       smsLog( pMac, LOGE, "Received neighbor report with Neighbor BSSID: "MAC_ADDRESS_STR,
                            MAC_ADDR_ARRAY(pNeighborRpt->sNeighborBssDescription[i].bssId));
#endif

       /* Calculate the roam score based on the BSS Capability in the BSSID Information and store it in Neighbor report Desc */
       rrmCalculateNeighborAPRoamScore(pMac, pNeighborReportDesc);

       /* Store the Neighbor report Desc in the cache based on the roam score */
       if ( pNeighborReportDesc->roamScore > 0)
       {
          rrmStoreNeighborRptByRoamScore(pMac, pNeighborReportDesc);
       }
       else
       {
           smsLog(pMac, LOGE, FL("Roam score of BSSID  "MAC_ADDRESS_STR" is 0, Ignoring.."),
                        MAC_ADDR_ARRAY(pNeighborRpt->sNeighborBssDescription[i].bssId));

           vos_mem_free(pNeighborReportDesc->pNeighborBssDescription);
           vos_mem_free(pNeighborReportDesc);
       }
   }
end:  
   
   if (!csrLLCount(&pMac->rrm.rrmSmeContext.neighborReportCache))
      vosStatus = VOS_STATUS_E_FAILURE;
 
   /* Received a report from AP. Indicate SUCCESS to the caller if there are some valid reports */
   rrmIndicateNeighborReportResult(pMac, vosStatus);

   return status;
}
/*--------------------------------------------------------------------------
  \brief sme_RrmMsgProcessor() - sme_ProcessMsg() calls this function for the 
  messages that are handled by SME RRM module.
  
  \param pMac - Pointer to the global MAC parameter structure.
  \param msg_type - the type of msg passed by PE as defined in wniApi.h
  \param pMsgBuf - a pointer to a buffer that maps to various structures base 
                   on the message type.
                   The beginning of the buffer can always map to tSirSmeRsp.
  
  \return eHAL_STATUS_SUCCESS - Validation is successful.
  
  \sa
  
  --------------------------------------------------------------------------*/
eHalStatus sme_RrmMsgProcessor( tpAniSirGlobal pMac,  v_U16_t msg_type, 
                                void *pMsgBuf)
{
   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, 
         FL(" Msg = %d for RRM measurement") , msg_type );

   //switch on the msg type & make the state transition accordingly
   switch(msg_type)
   {
      case eWNI_SME_NEIGHBOR_REPORT_IND:
         sme_RrmProcessNeighborReport( pMac, pMsgBuf );
         break;

      case eWNI_SME_BEACON_REPORT_REQ_IND:
         sme_RrmProcessBeaconReportReqInd( pMac, pMsgBuf );
         break;

      default:
         //err msg
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
               FL("sme_RrmMsgProcessor:unknown msg type = %d"), msg_type);

         break;
   }

   return eHAL_STATUS_SUCCESS;
}

/* ---------------------------------------------------------------------------

    \fn rrmIterMeasTimerHandle

    \brief  Timer handler to handlet the timeout condition when a specific BT

            stop event does not come back, in which case to restore back the

            heartbeat timer.

    \param  pMac - The handle returned by macOpen.

    \return VOID

  ---------------------------------------------------------------------------*/

void rrmIterMeasTimerHandle( v_PVOID_t userData )
{
   tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, "Randomization timer expired...send on next channel ");
#endif
    //Issue a scan req for next channel.
    sme_RrmIssueScanReq( pMac ); 
}

/* ---------------------------------------------------------------------------
    
    \fn rrmNeighborRspTimeoutHandler
    
    \brief  Timer handler to handle the timeout condition when a neighbor request is sent 
                    and no neighbor response is received from the AP
    
    \param  pMac - The handle returned by macOpen.
    
    \return VOID
    
---------------------------------------------------------------------------*/
    
void rrmNeighborRspTimeoutHandler
( v_PVOID_t userData )
{
   tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
#if defined WLAN_VOWIFI_DEBUG
   smsLog( pMac, LOGE, "Neighbor Response timed out ");
#endif
    rrmIndicateNeighborReportResult(pMac, VOS_STATUS_E_FAILURE);
    return;
}

/* ---------------------------------------------------------------------------

    \fn rrmOpen

    \brief  

    \param  pMac - The handle returned by macOpen.

    \return VOS_STATUS

            VOS_STATUS_E_FAILURE  success

            VOS_STATUS_SUCCESS  failure

  ---------------------------------------------------------------------------*/

VOS_STATUS rrmOpen (tpAniSirGlobal pMac)

{

   VOS_STATUS vosStatus;
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
   eHalStatus   halStatus = eHAL_STATUS_SUCCESS;

   pSmeRrmContext->rrmConfig.maxRandnInterval = 50; //ms

   vosStatus = vos_timer_init( &pSmeRrmContext->IterMeasTimer,

                      VOS_TIMER_TYPE_SW,

                      rrmIterMeasTimerHandle,

                      (void*) pMac);

   if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {

       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer");

       return VOS_STATUS_E_FAILURE;
   }

   vosStatus = vos_timer_init( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer,

                      VOS_TIMER_TYPE_SW,

                      rrmNeighborRspTimeoutHandler,

                      (void*) pMac);

   if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {

       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer");

       return VOS_STATUS_E_FAILURE;
   }

   pSmeRrmContext->neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE;

   halStatus = csrLLOpen(pMac->hHdd, &pSmeRrmContext->neighborReportCache);
   if (eHAL_STATUS_SUCCESS != halStatus)
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to open neighbor cache result");
       return VOS_STATUS_E_FAILURE;
   }

   return VOS_STATUS_SUCCESS;
}


/* ---------------------------------------------------------------------------

    \fn rrmClose

    \brief  

    \param  pMac - The handle returned by macOpen.

    \return VOS_STATUS

            VOS_STATUS_E_FAILURE  success

            VOS_STATUS_SUCCESS  failure

  ---------------------------------------------------------------------------*/

VOS_STATUS rrmClose (tpAniSirGlobal pMac)

{

   VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;

   if( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( &pSmeRrmContext->IterMeasTimer ) )
   {
      vosStatus = vos_timer_stop( &pSmeRrmContext->IterMeasTimer );
      if(!VOS_IS_STATUS_SUCCESS(vosStatus))
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Timer stop fail") );
      }
   }

   vosStatus = vos_timer_destroy( &pSmeRrmContext->IterMeasTimer );
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {

       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Fail to destroy timer") );

   }

   if( VOS_TIMER_STATE_RUNNING ==
          vos_timer_getCurrentState( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ) )
   {
      vosStatus = vos_timer_stop( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer );
      if(!VOS_IS_STATUS_SUCCESS(vosStatus))
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Timer stop fail") );
      }
   }

   vosStatus = vos_timer_destroy( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer );
   if (!VOS_IS_STATUS_SUCCESS(vosStatus))
   {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Fail to destroy timer") );

   }

   rrmLLPurgeNeighborCache(pMac, &pSmeRrmContext->neighborReportCache);

   csrLLClose(&pSmeRrmContext->neighborReportCache);

   return vosStatus;

}




/* ---------------------------------------------------------------------------

    \fn rrmReady

    \brief  fn

    \param  pMac - The handle returned by macOpen.

    \return VOS_STATUS

  ---------------------------------------------------------------------------*/

VOS_STATUS rrmReady (tpAniSirGlobal pMac)

{

    return VOS_STATUS_SUCCESS;
}

/* ---------------------------------------------------------------------------

    \fn rrmChangeDefaultConfigParam
    \brief  fn

    \param  pMac - The handle returned by macOpen.
    \param  pRrmConfig - pointer to new rrm configs.

    \return VOS_STATUS

  ---------------------------------------------------------------------------*/
VOS_STATUS rrmChangeDefaultConfigParam(tpAniSirGlobal pMac, tpRrmConfigParam pRrmConfig)
{
   vos_mem_copy( &pMac->rrm.rrmSmeContext.rrmConfig, pRrmConfig, sizeof( tRrmConfigParam ) ); 

   return VOS_STATUS_SUCCESS;
}

/* ---------------------------------------------------------------------------
    
    \fn smeRrmGetFirstBssEntryFromNeighborCache()
    
    \brief  This function returns the first entry from the neighbor cache to the caller

    \param  pMac - The handle returned by macOpen.
    
    \return VOID
    
---------------------------------------------------------------------------*/
tRrmNeighborReportDesc* smeRrmGetFirstBssEntryFromNeighborCache( tpAniSirGlobal pMac)
{
   tListElem *pEntry;
   tRrmNeighborReportDesc *pTempBssEntry = NULL;
   tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;


   pEntry = csrLLPeekHead( &pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK );

   if(!pEntry || !csrLLCount(&pSmeRrmContext->neighborReportCache))
   {
      //list empty
      smsLog(pMac, LOGW, FL("List empty"));
      return NULL;
   }

   pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );

   return pTempBssEntry;
}

/* ---------------------------------------------------------------------------
    
    \fn smeRrmGetNextBssEntryFromNeighborCache()
    
    \brief  This function returns the entry next to the given entry from the 
                neighbor cache to the caller

    \param  pMac - The handle returned by macOpen.
    
    \return VOID
    
---------------------------------------------------------------------------*/
tRrmNeighborReportDesc* smeRrmGetNextBssEntryFromNeighborCache( tpAniSirGlobal pMac, 
                                                        tpRrmNeighborReportDesc pBssEntry)
{
   tListElem *pEntry;
   tRrmNeighborReportDesc *pTempBssEntry = NULL;

   pEntry = csrLLNext(&pMac->rrm.rrmSmeContext.neighborReportCache, &pBssEntry->List, LL_ACCESS_LOCK);

   if(!pEntry)
   {
      //list empty
      smsLog(pMac, LOGW, FL("List empty"));
      return NULL;
   }

   pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );

   return pTempBssEntry;
}

#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
void csrEseSendAdjacentApRepMsg(tpAniSirGlobal pMac, tCsrRoamSession *pSession)
{
   tpSirAdjacentApRepInd pAdjRep;
   tANI_U16 length;
   tANI_U32 roamTS2;
   
   smsLog( pMac, LOG1, "Adjacent AP Report Msg to PE");

   length = sizeof(tSirAdjacentApRepInd );
   pAdjRep = vos_mem_malloc ( length );

   if ( NULL == pAdjRep )
   {
       smsLog( pMac, LOGP, "Unable to allocate memory for Adjacent AP report");
       return;
   }

   vos_mem_zero( pAdjRep, length );
   pAdjRep->messageType = eWNI_SME_ESE_ADJACENT_AP_REPORT;
   pAdjRep->length = length;
   pAdjRep->channelNum = pSession->prevOpChannel;
   vos_mem_copy( pAdjRep->bssid, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) );
   vos_mem_copy( pAdjRep->prevApMacAddr, &pSession->prevApBssid, sizeof(tSirMacAddr) );
   vos_mem_copy( &pAdjRep->prevApSSID, &pSession->prevApSSID, sizeof(tSirMacSSid) );
   roamTS2 = vos_timer_get_system_time();
   pAdjRep->tsmRoamdelay = roamTS2 - pSession->roamTS1;
   pAdjRep->roamReason =SIR_ESE_ASSOC_REASON_UNSPECIFIED;
   pAdjRep->clientDissSecs =(pAdjRep->tsmRoamdelay/1000);

   palSendMBMessage(pMac->hHdd, pAdjRep);

   return;
}
#endif   /* FEATURE_WLAN_ESE */
#endif
