/*
 * Copyright (c) 2011-2014, 2016-2017, 2019 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  limSession.c
  
  \brief implementation for lim Session related APIs

  \author Sunit Bhatia
  
  
  ========================================================================*/


/*--------------------------------------------------------------------------
  Include Files
  ------------------------------------------------------------------------*/
#include "aniGlobal.h"
#include "limDebug.h"
#include "limSession.h"
#include "limUtils.h"
#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
#include "eseApi.h"
#endif

/*--------------------------------------------------------------------------
  
  \brief peInitBeaconParams() - Initialize the beaconParams structure


  \param tpPESession          - pointer to the session context or NULL if session can not be created.
  \return void
  \sa

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

void peInitBeaconParams(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
    psessionEntry->beaconParams.beaconInterval = 0;
    psessionEntry->beaconParams.fShortPreamble = 0;
    psessionEntry->beaconParams.llaCoexist = 0;
    psessionEntry->beaconParams.llbCoexist = 0;
    psessionEntry->beaconParams.llgCoexist = 0;
    psessionEntry->beaconParams.ht20Coexist = 0;
    psessionEntry->beaconParams.llnNonGFCoexist = 0;
    psessionEntry->beaconParams.fRIFSMode = 0;
    psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = 0;
    psessionEntry->beaconParams.gHTObssMode = 0;

    // Number of legacy STAs associated 
    vos_mem_set((void*)&psessionEntry->gLim11bParams, sizeof(tLimProtStaParams), 0);
    vos_mem_set((void*)&psessionEntry->gLim11aParams, sizeof(tLimProtStaParams), 0);
    vos_mem_set((void*)&psessionEntry->gLim11gParams, sizeof(tLimProtStaParams), 0);
    vos_mem_set((void*)&psessionEntry->gLimNonGfParams, sizeof(tLimProtStaParams), 0);
    vos_mem_set((void*)&psessionEntry->gLimHt20Params, sizeof(tLimProtStaParams), 0);
    vos_mem_set((void*)&psessionEntry->gLimLsigTxopParams, sizeof(tLimProtStaParams), 0);
    vos_mem_set((void*)&psessionEntry->gLimOlbcParams, sizeof(tLimProtStaParams), 0);
}

/*--------------------------------------------------------------------------
  
  \brief peCreateSession() - creates a new PE session given the BSSID

  This function returns the session context and the session ID if the session 
  corresponding to the passed BSSID is found in the PE session table.
    
  \param pMac                   - pointer to global adapter context
  \param bssid                   - BSSID of the new session
  \param sessionId             -session ID is returned here, if session is created.
  
  \return tpPESession          - pointer to the session context or NULL if session can not be created.
  
  \sa
  
  --------------------------------------------------------------------------*/
tpPESession peCreateSession(tpAniSirGlobal pMac, tANI_U8 *bssid , tANI_U8* sessionId, tANI_U16 numSta)
{
    tANI_U8 i;
    for(i =0; i < pMac->lim.maxBssId; i++)
    {
        /* Find first free room in session table */
        if(pMac->lim.gpSession[i].valid == FALSE)
        {
            vos_mem_set((void*)&pMac->lim.gpSession[i], sizeof(tPESession), 0);

            //Allocate space for Station Table for this session.
            pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = vos_mem_vmalloc(
                                                  sizeof(tpDphHashNode)*numSta);
            if ( NULL == pMac->lim.gpSession[i].dph.dphHashTable.pHashTable )
            {
                limLog(pMac, LOGE, FL("memory allocate for size %lu failed!"),
                            (long unsigned int) sizeof(tpDphHashNode)*numSta);
                return NULL;
            }

            pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray = vos_mem_vmalloc(
                                                       sizeof(tDphHashNode)*numSta);
            if ( NULL == pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray )
            {
                limLog(pMac, LOGE, FL("memory allocate failed for Node array"
                                                               "of size %lu"),
                             (long unsigned int) sizeof(tDphHashNode)*numSta);
                vos_mem_vfree(pMac->lim.gpSession[i].dph.dphHashTable.pHashTable);
                pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = NULL;
                return NULL;
            }
            pMac->lim.gpSession[i].dph.dphHashTable.size = numSta;

            dphHashTableClassInit(pMac, 
                           &pMac->lim.gpSession[i].dph.dphHashTable);

            pMac->lim.gpSession[i].gpLimPeerIdxpool = vos_mem_vmalloc(sizeof(
                                *pMac->lim.gpSession[i].gpLimPeerIdxpool) * (numSta+1));
            if ( NULL == pMac->lim.gpSession[i].gpLimPeerIdxpool )
            {
                limLog(pMac, LOGE, FL("memory allocate failed "
                "for peerId pool of size %lu!"), (long unsigned int)
                sizeof(*pMac->lim.gpSession[i].gpLimPeerIdxpool) * (numSta+1));
                vos_mem_vfree(pMac->lim.gpSession[i].dph.dphHashTable.pHashTable);
                vos_mem_vfree(pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray);
                pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = NULL;
                pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray = NULL;
                return NULL;
            }
            vos_mem_set(pMac->lim.gpSession[i].gpLimPeerIdxpool,
                  sizeof(*pMac->lim.gpSession[i].gpLimPeerIdxpool) * (numSta+1), 0);
            pMac->lim.gpSession[i].freePeerIdxHead = 0;
            pMac->lim.gpSession[i].freePeerIdxTail = 0;
            pMac->lim.gpSession[i].gLimNumOfCurrentSTAs = 0;

            /* Copy the BSSID to the session table */
            sirCopyMacAddr(pMac->lim.gpSession[i].bssId, bssid);
            pMac->lim.gpSession[i].valid = TRUE;
            
            /* Intialize the SME and MLM states to IDLE */
            pMac->lim.gpSession[i].limMlmState = eLIM_MLM_IDLE_STATE;
            pMac->lim.gpSession[i].limSmeState = eLIM_SME_IDLE_STATE;
            pMac->lim.gpSession[i].limCurrentAuthType = eSIR_OPEN_SYSTEM;
            peInitBeaconParams(pMac, &pMac->lim.gpSession[i]);
#ifdef WLAN_FEATURE_VOWIFI_11R
            pMac->lim.gpSession[i].is11Rconnection = FALSE;
#endif

#ifdef FEATURE_WLAN_ESE
            pMac->lim.gpSession[i].isESEconnection = FALSE;
#endif

#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
            pMac->lim.gpSession[i].isFastTransitionEnabled = FALSE;
#endif
#ifdef FEATURE_WLAN_LFR
            pMac->lim.gpSession[i].isFastRoamIniFeatureEnabled = FALSE;
#endif
            *sessionId = i;

            pMac->lim.gpSession[i].gLimPhyMode = WNI_CFG_PHY_MODE_11G; //TODO :Check with the team what should be default mode
            /* Initialize CB mode variables when session is created */
            pMac->lim.gpSession[i].htSupportedChannelWidthSet = 0;
            pMac->lim.gpSession[i].htRecommendedTxWidthSet = 0;
            pMac->lim.gpSession[i].htSecondaryChannelOffset = 0;
#ifdef FEATURE_WLAN_TDLS
            vos_mem_set(pMac->lim.gpSession[i].peerAIDBitmap,
                  sizeof(pMac->lim.gpSession[i].peerAIDBitmap), 0);
            pMac->lim.gpSession[i].tdlsChanSwitProhibited = 0;
#endif
            pMac->lim.gpSession[i].fWaitForProbeRsp = 0;
            pMac->lim.gpSession[i].fIgnoreCapsChange = 0;
            limLog(pMac, LOG1, FL("Create a new sessionId (%d) with BSSID: "
               MAC_ADDRESS_STR " Max No. of STA %d"),
               pMac->lim.gpSession[i].peSessionId,
               MAC_ADDR_ARRAY(bssid), numSta);
            return(&pMac->lim.gpSession[i]);
        }
    }
    limLog(pMac, LOGE, FL("Session can not be created.. Reached Max permitted sessions "));
    return NULL;
}


/*--------------------------------------------------------------------------
  \brief peFindSessionByBssid() - looks up the PE session given the BSSID.

  This function returns the session context and the session ID if the session 
  corresponding to the given BSSID is found in the PE session table.
    
  \param pMac                   - pointer to global adapter context
  \param bssid                   - BSSID of the session
  \param sessionId             -session ID is returned here, if session is found. 
  
  \return tpPESession          - pointer to the session context or NULL if session is not found.
  
  \sa
  --------------------------------------------------------------------------*/
tpPESession peFindSessionByBssid(tpAniSirGlobal pMac,  tANI_U8*  bssid,    tANI_U8* sessionId)
{
    tANI_U8 i;

    for(i =0; i < pMac->lim.maxBssId; i++)
    {
        /* If BSSID matches return corresponding tables address*/
        if( (pMac->lim.gpSession[i].valid) && (sirCompareMacAddr(pMac->lim.gpSession[i].bssId, bssid)))
        {
            *sessionId = i;
            return(&pMac->lim.gpSession[i]);
        }
    }

    limLog(pMac, LOG4, FL("Session lookup fails for BSSID: "));
    limPrintMacAddr(pMac, bssid, LOG4);
    return(NULL);

}

tANI_S8 limGetInfraSessionId(tpAniSirGlobal pMac)
{
    tANI_U8 i;
    for (i = 0; i < pMac->lim.maxBssId; i++)
    {
        if ((pMac->lim.gpSession[i].valid) &&
           (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE))
        {
            return i;
        }
    }
    limLog(pMac, LOG4, FL("Session lookup fails for infra mode"));
    return -1;
}

/*--------------------------------------------------------------------------
  \brief peFindSessionByBssIdx() - looks up the PE session given the bssIdx.

  This function returns the session context  if the session
  corresponding to the given bssIdx is found in the PE session table.
  \param pMac                   - pointer to global adapter context
  \param bssIdx                   - bss index of the session
  \return tpPESession          - pointer to the session context or NULL if session is not found.
  \sa
  --------------------------------------------------------------------------*/
tpPESession peFindSessionByBssIdx(tpAniSirGlobal pMac,  tANI_U8 bssIdx)
{
    tANI_U8 i;
    for (i = 0; i < pMac->lim.maxBssId; i++)
    {
        /* If BSSID matches return corresponding tables address*/
        if ( (pMac->lim.gpSession[i].valid) && (pMac->lim.gpSession[i].bssIdx == bssIdx))
        {
            return &pMac->lim.gpSession[i];
        }
    }
    limLog(pMac, LOG4, FL("Session lookup fails for bssIdx: %d"), bssIdx);
    return NULL;
}

tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx,
                                              tANI_U8 sme_session_id)
{
   uint8_t i;

   for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
       if ((mac_ctx->lim.gpSession[i].valid) &&
           (mac_ctx->lim.gpSession[i].smeSessionId == sme_session_id))
           return &mac_ctx->lim.gpSession[i];
   }
   limLog(mac_ctx, LOG4, FL("Session lookup fails for smeSessionID: %d"),
          sme_session_id);

   return NULL;
}

/*--------------------------------------------------------------------------
  \brief peFindSessionBySessionId() - looks up the PE session given the session ID.

  This function returns the session context  if the session 
  corresponding to the given session ID is found in the PE session table.
    
  \param pMac                   - pointer to global adapter context
  \param sessionId             -session ID for which session context needs to be looked up.
  
  \return tpPESession          - pointer to the session context or NULL if session is not found.
  
  \sa
  --------------------------------------------------------------------------*/
 tpPESession peFindSessionBySessionId(tpAniSirGlobal pMac , tANI_U8 sessionId)
{
    if(sessionId >=  pMac->lim.maxBssId)
    {
        limLog(pMac, LOGE, FL("Invalid sessionId: %d "), sessionId);
        return(NULL);
    }
    if((pMac->lim.gpSession[sessionId].valid == TRUE))
    {
        return(&pMac->lim.gpSession[sessionId]);
    }
    return(NULL);

}


/*--------------------------------------------------------------------------
  \brief peFindSessionByStaId() - looks up the PE session given staid.

  This function returns the session context and the session ID if the session 
  corresponding to the given StaId is found in the PE session table.
    
  \param pMac                   - pointer to global adapter context
  \param staid                   - StaId of the session
  \param sessionId             -session ID is returned here, if session is found. 
  
  \return tpPESession          - pointer to the session context or NULL if session is not found.
  
  \sa
  --------------------------------------------------------------------------*/
tpPESession peFindSessionByStaId(tpAniSirGlobal pMac,  tANI_U8  staid,    tANI_U8* sessionId)
{
    tANI_U8 i, j;

    for(i =0; i < pMac->lim.maxBssId; i++)
    {
       if(pMac->lim.gpSession[i].valid)
       {
          for(j = 0; j < pMac->lim.gpSession[i].dph.dphHashTable.size; j++)
          {
             if((pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].valid) &&
                 (pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].added) &&
                (staid == pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].staIndex))
             {
                *sessionId = i;
                return(&pMac->lim.gpSession[i]);
             }
          }
       }
    }

    limLog(pMac, LOG4, FL("Session lookup fails for StaId: %d\n "), staid);
    return(NULL);
}



/*--------------------------------------------------------------------------
  \brief peDeleteSession() - deletes the PE session given the session ID.

    
  \param pMac                   - pointer to global adapter context
  \param sessionId             -session ID of the session which needs to be deleted.
    
  \sa
  --------------------------------------------------------------------------*/
void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry)
{
    tANI_U16 i = 0;
    tANI_U16 n;
    TX_TIMER *timer_ptr;
    eHalStatus lock_status = eHAL_STATUS_SUCCESS;

    limLog(pMac, LOGW, FL("Trying to delete a session %d Opmode %d BssIdx %d"
           " BSSID: " MAC_ADDRESS_STR), psessionEntry->peSessionId,
           psessionEntry->operMode, psessionEntry->bssIdx,
           MAC_ADDR_ARRAY(psessionEntry->bssId));

    for (n = 0; n < pMac->lim.maxStation; n++)
    {
        timer_ptr = &pMac->lim.limTimers.gpLimCnfWaitTimer[n];

        if(psessionEntry->peSessionId == timer_ptr->sessionId)
        {
            if(VOS_TRUE == tx_timer_running(timer_ptr))
            {
                tx_timer_deactivate(timer_ptr);
            }
        }
    }

#ifdef WLAN_FEATURE_11AC

    /* Unblock the MuBF for other session if the MuBf session is deleted
     */
    if(psessionEntry->txMuBformee)
    {
        pMac->isMuBfsessionexist = FALSE;
    }

#endif

    if (psessionEntry->pLimStartBssReq != NULL)
    {
        vos_mem_free( psessionEntry->pLimStartBssReq );
        psessionEntry->pLimStartBssReq = NULL;
    }

    if(psessionEntry->pLimJoinReq != NULL)
    {
        vos_mem_free( psessionEntry->pLimJoinReq );
        psessionEntry->pLimJoinReq = NULL;
    }

    if(psessionEntry->pLimReAssocReq != NULL)
    {
        vos_mem_free( psessionEntry->pLimReAssocReq );
        psessionEntry->pLimReAssocReq = NULL;
    }

    if(psessionEntry->pLimMlmJoinReq != NULL)
    {
        vos_mem_free( psessionEntry->pLimMlmJoinReq );
        psessionEntry->pLimMlmJoinReq = NULL;
    }

    lock_status =  pe_AcquireGlobalLock(&pMac->lim);
    if (eHAL_STATUS_SUCCESS == lock_status)
    {
         if (psessionEntry->dph.dphHashTable.pHashTable != NULL)
         {
             vos_mem_vfree(psessionEntry->dph.dphHashTable.pHashTable);
             psessionEntry->dph.dphHashTable.pHashTable = NULL;
         }
    }
    pe_ReleaseGlobalLock(&pMac->lim);

    if(psessionEntry->dph.dphHashTable.pDphNodeArray != NULL)
    {
        vos_mem_vfree(psessionEntry->dph.dphHashTable.pDphNodeArray);
        psessionEntry->dph.dphHashTable.pDphNodeArray = NULL;
    }

    if(psessionEntry->gpLimPeerIdxpool != NULL)
    {
        vos_mem_vfree(psessionEntry->gpLimPeerIdxpool);
        psessionEntry->gpLimPeerIdxpool = NULL;
    }

    if(psessionEntry->beacon != NULL)
    {
        vos_mem_free( psessionEntry->beacon);
        psessionEntry->beacon = NULL;
    }

    if(psessionEntry->assocReq != NULL)
    {
        vos_mem_free( psessionEntry->assocReq);
        psessionEntry->assocReq = NULL;
    }

    if(psessionEntry->assocRsp != NULL)
    {
        vos_mem_free( psessionEntry->assocRsp);
        psessionEntry->assocRsp = NULL;
    }


    if(psessionEntry->parsedAssocReq != NULL)
    {
        // Cleanup the individual allocation first
        for (i=0; i < psessionEntry->dph.dphHashTable.size; i++)
        {
            if ( psessionEntry->parsedAssocReq[i] != NULL )
            {
                if( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrame )
                {
                   vos_mem_free(((tpSirAssocReq)
                                (psessionEntry->parsedAssocReq[i]))->assocReqFrame);
                   ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrame = NULL;
                   ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrameLength = 0;
                }
                vos_mem_free(psessionEntry->parsedAssocReq[i]);
                psessionEntry->parsedAssocReq[i] = NULL;
            }
        }
        // Cleanup the whole block
        vos_mem_free(psessionEntry->parsedAssocReq);
        psessionEntry->parsedAssocReq = NULL;
    }
    if (NULL != psessionEntry->limAssocResponseData)
    {
        vos_mem_free( psessionEntry->limAssocResponseData);
        psessionEntry->limAssocResponseData = NULL;
    }

#if  defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
    if (NULL != psessionEntry->pLimMlmReassocRetryReq)
    {
        vos_mem_free( psessionEntry->pLimMlmReassocRetryReq);
        psessionEntry->pLimMlmReassocRetryReq = NULL;
    }
#endif

    if (NULL != psessionEntry->pLimMlmReassocReq)
    {
        vos_mem_free( psessionEntry->pLimMlmReassocReq);
        psessionEntry->pLimMlmReassocReq = NULL;
    }

#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD)
    limCleanupEseCtxt(pMac, psessionEntry);
#endif

    psessionEntry->valid = FALSE;
    return;
}


/*--------------------------------------------------------------------------
  \brief peFindSessionByPeerSta() - looks up the PE session given the Station Address.

  This function returns the session context and the session ID if the session 
  corresponding to the given station address is found in the PE session table.
    
  \param pMac                   - pointer to global adapter context
  \param sa                       - Peer STA Address of the session
  \param sessionId             -session ID is returned here, if session is found. 
  
  \return tpPESession          - pointer to the session context or NULL if session is not found.
  
  \sa
  --------------------------------------------------------------------------*/


tpPESession peFindSessionByPeerSta(tpAniSirGlobal pMac,  tANI_U8*  sa,    tANI_U8* sessionId)
{
   tANI_U8 i;
   tpDphHashNode pSta;   
   tANI_U16  aid;
   
   for(i =0; i < pMac->lim.maxBssId; i++)
   {
      if( (pMac->lim.gpSession[i].valid))
      {
         pSta = dphLookupHashEntry(pMac, sa, &aid, &pMac->lim.gpSession[i].dph.dphHashTable);
         if (pSta != NULL) 
         {
            *sessionId = i;
            return &pMac->lim.gpSession[i];
         }
      }
   }   

   limLog(pMac, LOG1, FL("Session lookup fails for Peer StaId: "));
   limPrintMacAddr(pMac, sa, LOG1);
   return NULL;
}









