/*
 * Copyright (c) 2012, 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.
 */

/*
 * Copyright (c) 2008 QUALCOMM Incorporated. All Rights Reserved.
 * Qualcomm Confidential and Proprietary 
 */

#if defined WLAN_FEATURE_P2P

#include "sme_Api.h"
#include "smsDebug.h"
#include "csrInsideApi.h"
#include "smeInside.h"
#include "p2p_Api.h"
#include "limApi.h"
#include "cfgApi.h"

#ifdef WLAN_FEATURE_P2P_INTERNAL
#include "p2p_ie.h"
#include "p2pFsm.h"

extern tp2pie gP2PIe;

static eHalStatus p2pSendActionFrame(tpAniSirGlobal pMac, tANI_U8 SessionID, eP2PFrameType actionFrameType);
static eHalStatus p2pListenStateDiscoverableCallback(tHalHandle halHandle, void *pContext, eHalStatus retStatus);
static eHalStatus p2pRemainOnChannelReadyCallback(tHalHandle halHandle, void *pContext, eHalStatus scan_status);
static tANI_BOOLEAN p2pIsGOportEnabled(tpAniSirGlobal pMac);
#endif

eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd);
/*------------------------------------------------------------------
 *
 * handle SME remain on channel request.
 *
 *------------------------------------------------------------------*/

eHalStatus p2pProcessRemainOnChannelCmd(tpAniSirGlobal pMac, tSmeCmd *p2pRemainonChn)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tSirRemainOnChnReq* pMsg;
    tANI_U16 len;
    tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, p2pRemainonChn->sessionId );

    if(!pSession)
    {
       smsLog(pMac, LOGE, FL("  session %d not found "), p2pRemainonChn->sessionId);
       return eHAL_STATUS_FAILURE;
    }

#ifdef WLAN_FEATURE_P2P_INTERNAL
    tANI_U8 P2PsessionId = getP2PSessionIdFromSMESessionId(pMac, p2pRemainonChn->sessionId);
    tp2pContext *p2pContext = &pMac->p2pContext[P2PsessionId];
    tANI_U32 ieLen = 0;
#endif

#ifdef WLAN_FEATURE_P2P_INTERNAL
    if( !pSession->sessionActive || (CSR_SESSION_ID_INVALID == P2PsessionId)) 
    {
       smsLog(pMac, LOGE, FL("  session %d (P2P session %d) is invalid or listen is disabled "), 
            p2pRemainonChn->sessionId, P2PsessionId);
       return eHAL_STATUS_FAILURE;
    }
#else
    if(!pSession->sessionActive) 
    {
       smsLog(pMac, LOGE, FL("  session %d is invalid or listen is disabled "), 
            p2pRemainonChn->sessionId);
       return eHAL_STATUS_FAILURE;
    }
#endif
#ifdef WLAN_FEATURE_P2P_INTERNAL
    P2P_GetIE(p2pContext, 
              p2pContext->sessionId, eP2P_PROBE_RSP, 
              &p2pContext->probeRspIe, &ieLen);
    p2pContext->probeRspIeLength = ieLen;
    len = sizeof(tSirRemainOnChnReq) + ieLen;
#else
    len = sizeof(tSirRemainOnChnReq) + pMac->p2pContext.probeRspIeLength;
#endif

    status = palAllocateMemory(pMac->hHdd, (void**)&pMsg, len );
    if(HAL_STATUS_SUCCESS(status))
    {
        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s call\n", __FUNCTION__);
        palZeroMemory(pMac->hHdd, pMsg, sizeof(tSirRemainOnChnReq));
        pMsg->messageType = eWNI_SME_REMAIN_ON_CHANNEL_REQ;
        pMsg->length = len;
        palCopyMemory( pMac, pMsg->selfMacAddr, pSession->selfMacAddr, sizeof(tSirMacAddr) ); 
        pMsg->chnNum = p2pRemainonChn->u.remainChlCmd.chn;
        pMsg->phyMode = p2pRemainonChn->u.remainChlCmd.phyMode;
        pMsg->duration = p2pRemainonChn->u.remainChlCmd.duration;
        pMsg->sessionId = p2pRemainonChn->sessionId;
#ifdef WLAN_FEATURE_P2P_INTERNAL
        pMsg->sessionId = pSession->sessionId;
        if( p2pContext->probeRspIeLength )
        {
            palCopyMemory(pMac->hHdd, (void *)pMsg->probeRspIe,
                         (void *)p2pContext->probeRspIe, 
                         p2pContext->probeRspIeLength);
        }
#else
        if( pMac->p2pContext.probeRspIeLength )
           palCopyMemory(pMac->hHdd, (void *)pMsg->probeRspIe, (void *)pMac->p2pContext.probeRspIe, pMac->p2pContext.probeRspIeLength);
#endif
        status = palSendMBMessage(pMac->hHdd, pMsg);
    }
    
    return status;
}


/*------------------------------------------------------------------
 *
 * handle LIM remain on channel rsp: Success/failure.
 *
 *------------------------------------------------------------------*/

eHalStatus sme_remainOnChnRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg)
{
    eHalStatus                         status = eHAL_STATUS_SUCCESS;
    tListElem                          *pEntry = NULL;
    tSmeCmd                            *pCommand = NULL;

    pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
    if( pEntry )
    {
        pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
        if( eSmeCommandRemainOnChannel == pCommand->command )
        {
            remainOnChanCallback callback = pCommand->u.remainChlCmd.callback;
            /* process the msg */
            if( callback )
                callback(pMac, pCommand->u.remainChlCmd.callbackCtx, 0);
             
            if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) )
            {
                //Now put this command back on the avilable command list
                smeReleaseCommand(pMac, pCommand);
            }
            smeProcessPendingQueue( pMac );
        }
    }
    return status;
}


/*------------------------------------------------------------------
 *
 * Handle the Mgmt frm ind from LIM and forward to HDD.
 *
 *------------------------------------------------------------------*/

eHalStatus sme_mgmtFrmInd( tHalHandle hHal, tpSirSmeMgmtFrameInd pSmeMgmtFrm)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus  status = eHAL_STATUS_SUCCESS;
    tCsrRoamInfo pRoamInfo = {0};
#ifndef WLAN_FEATURE_P2P_INTERNAL
    tANI_U32 SessionId = pSmeMgmtFrm->sessionId;
#endif

#ifdef WLAN_FEATURE_P2P_INTERNAL
    tANI_U8 i;

    //For now, only action frames are needed.
    if(SIR_MAC_MGMT_ACTION == pSmeMgmtFrm->frameType)
    {
       pRoamInfo.nFrameLength = pSmeMgmtFrm->mesgLen - sizeof(tSirSmeMgmtFrameInd);
       pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf;
       pRoamInfo.frameType = pSmeMgmtFrm->frameType;
       pRoamInfo.rxChan   = pSmeMgmtFrm->rxChan;

       //Somehow we don't get the right sessionId.
       for(i = 0; i < CSR_ROAM_SESSION_MAX; i++)
       {
          if( CSR_IS_SESSION_VALID( pMac, i ) )
          {
              status = eHAL_STATUS_SUCCESS;
              /* forward the mgmt frame to all active sessions*/
              csrRoamCallCallback(pMac, i, &pRoamInfo, 0, eCSR_ROAM_INDICATE_MGMT_FRAME, 0);
          }
       }
    }
#else
    pRoamInfo.nFrameLength = pSmeMgmtFrm->mesgLen - sizeof(tSirSmeMgmtFrameInd);
    pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf;
    pRoamInfo.frameType = pSmeMgmtFrm->frameType;
    pRoamInfo.rxChan   = pSmeMgmtFrm->rxChan;

    /* forward the mgmt frame to HDD */
    csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, eCSR_ROAM_INDICATE_MGMT_FRAME, 0);
#endif

    return status;
}


/*------------------------------------------------------------------
 *
 * Handle the remain on channel ready indication from PE
 *
 *------------------------------------------------------------------*/

eHalStatus sme_remainOnChnReady( tHalHandle hHal, tANI_U8* pMsg)
{
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
    eHalStatus  status = eHAL_STATUS_SUCCESS;
    tListElem *pEntry = NULL;
    tSmeCmd *pCommand = NULL;
    tCsrRoamInfo RoamInfo; 
#ifdef WLAN_FEATURE_P2P_INTERNAL
    tSirSmeRsp *pRsp = (tSirSmeRsp *)pMsg;
    //pRsp->sessionId is SME's session index
    tANI_U8  P2PSessionID = getP2PSessionIdFromSMESessionId(pMac, pRsp->sessionId);

    if(CSR_SESSION_ID_INVALID == P2PSessionID)
    {
       return eHAL_STATUS_FAILURE;
    }
#endif

    pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
    if( pEntry )
    {
        pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
        if( eSmeCommandRemainOnChannel == pCommand->command )
        {

#ifdef WLAN_FEATURE_P2P_INTERNAL
            if (pMac->p2pContext[P2PSessionID].PeerFound)
            {
                p2pRemainOnChannelReadyCallback(pMac, &pMac->p2pContext[P2PSessionID], eHAL_STATUS_SUCCESS);
            }
#else
            /* forward the indication to HDD */
            RoamInfo.pRemainCtx = pCommand->u.remainChlCmd.callbackCtx;
            csrRoamCallCallback(pMac, ((tSirSmeRsp*)pMsg)->sessionId, &RoamInfo, 
                                0, eCSR_ROAM_REMAIN_CHAN_READY, 0);
#endif
        }
    }
  
    return status;
}


eHalStatus sme_sendActionCnf( tHalHandle hHal, tANI_U8* pMsg)
{
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   eHalStatus  status = eHAL_STATUS_SUCCESS;
   tCsrRoamInfo RoamInfo;
   tSirSmeRsp* pSmeRsp = (tSirSmeRsp*)pMsg;

#ifdef WLAN_FEATURE_P2P_INTERNAL
   tSirResultCodes rspStatus = pSmeRsp->statusCode;
   tANI_U8 HDDsessionId = getP2PSessionIdFromSMESessionId(pMac, pSmeRsp->sessionId);
   tANI_U8 *pBuf = NULL;
   tp2pContext *pP2pContext;

   if(CSR_SESSION_ID_INVALID == HDDsessionId)
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
         " %s fail to get HDD sessionID (SMESessionID %d)", __FUNCTION__, pSmeRsp->sessionId);
      return eHAL_STATUS_INVALID_PARAMETER;
   }

   pP2pContext = &pMac->p2pContext[HDDsessionId];

   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s status %d Action Frame %d actionFrameTimeout %d\n", 
         __FUNCTION__, pSmeRsp->statusCode, pP2pContext->actionFrameType
         , pP2pContext->actionFrameTimeout);
   vos_mem_zero(&RoamInfo, sizeof(tCsrRoamInfo));

   if (pSmeRsp->statusCode != eSIR_SME_SUCCESS && !pP2pContext->actionFrameTimeout
         && pP2pContext->pSentActionFrame)
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Action frame:Ack not received. Retransmitting\n", __FUNCTION__);

      if(NULL == pP2pContext->pNextActionFrm)
      {
         status = palTimerStart(pMac->hHdd, pP2pContext->retryActionFrameTimer, 
                        ACTION_FRAME_RETRY_TIMEOUT * PAL_TIMER_TO_MS_UNIT, eANI_BOOLEAN_FALSE);
         if (!HAL_STATUS_SUCCESS(status))
         {
            smsLog(pMac, LOGE, " %s fail to start retryActionFrameTimerHandler\n", 
               __FUNCTION__, pP2pContext->NextActionFrameType);
         }
         return status;
      }
      //In case if there is new frame to send, finish the current frame
      else
      {
         smsLog(pMac, LOGE, " %s send next action frame type %d Last frame status (%d)",
            __FUNCTION__, rspStatus);
         //Force it to be success
         rspStatus = eSIR_SME_SUCCESS;
      }
   }

   if (pP2pContext->actionFrameTimer)
   {
      status = palTimerStop(pMac, pP2pContext->actionFrameTimer);
   }

   if (pP2pContext->retryActionFrameTimer)
   {
      status = palTimerStop(pMac, pP2pContext->retryActionFrameTimer);
   }

   if(pP2pContext->pSentActionFrame)
   {
      csrRoamCallCallback((tpAniSirGlobal)pP2pContext->hHal, 
                     pP2pContext->SMEsessionId, &RoamInfo, 0, 
                     eCSR_ROAM_SEND_ACTION_CNF, 
                     ((rspStatus == eSIR_SME_SUCCESS) ? 
                     eCSR_ROAM_RESULT_NONE: eCSR_ROAM_RESULT_SEND_ACTION_FAIL));
   }

   if(VOS_IS_STATUS_SUCCESS(vos_spin_lock_acquire(&pP2pContext->lState)))
   {
      if(pP2pContext->pSentActionFrame)
      {
         pBuf = pP2pContext->pSentActionFrame;
         pP2pContext->pSentActionFrame = NULL;
      }
      vos_spin_lock_release(&pP2pContext->lState);

      if(NULL != pBuf)
      {
         vos_mem_free(pBuf);
         pBuf = NULL;
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, "%s pSentActionFrame is null \n", __FUNCTION__);
      }
      if(pP2pContext->pNextActionFrm)
      {
         //need to send the next action frame
         pP2pContext->pSentActionFrame = pP2pContext->pNextActionFrm;
         pP2pContext->ActionFrameLen = pP2pContext->nNextFrmLen;
         pP2pContext->actionFrameType = pP2pContext->NextActionFrameType;
         pP2pContext->pNextActionFrm = NULL;
         pP2pContext->ActionFrameSendTimeout = pP2pContext->nNextFrameTimeOut;
      }
   }
   else
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s cannot get lock1", __FUNCTION__);
   }

   if(NULL != pP2pContext->pSentActionFrame)
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, " sending next frame %d type\n", 
                  pP2pContext->NextActionFrameType);
      status = palTimerStart(pMac->hHdd, pP2pContext->actionFrameTimer, 
                        pP2pContext->ActionFrameSendTimeout * PAL_TIMER_TO_MS_UNIT, eANI_BOOLEAN_FALSE);
      if (!HAL_STATUS_SUCCESS(status))
      {
         smsLog(pMac, LOGE, FL(" %s fail to start timer status %d"), __FUNCTION__, status);
         //Without the timer we cannot continue
         csrRoamCallCallback((tpAniSirGlobal)pP2pContext->hHal, 
                     pP2pContext->SMEsessionId, &RoamInfo, 0, 
                     eCSR_ROAM_SEND_ACTION_CNF, 
                     eCSR_ROAM_RESULT_SEND_ACTION_FAIL);
         vos_spin_lock_acquire(&pP2pContext->lState);
         pBuf = pP2pContext->pSentActionFrame;
         pP2pContext->pSentActionFrame = NULL;
         vos_spin_lock_release(&pP2pContext->lState);
         vos_mem_free(pBuf);
         pBuf = NULL;
         p2pFsm(pP2pContext, eP2P_TRIGGER_DISCONNECTED);
         return status;
      }
      status = p2pSendActionFrame(pMac, pP2pContext->sessionId, pP2pContext->actionFrameType);
      if(!HAL_STATUS_SUCCESS(status))
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, " sending next frame %d type\n", 
                  pP2pContext->NextActionFrameType);
         status = palTimerStart(pMac->hHdd, pP2pContext->retryActionFrameTimer, 
                     ACTION_FRAME_RETRY_TIMEOUT * PAL_TIMER_TO_MS_UNIT, eANI_BOOLEAN_FALSE);
         if (!HAL_STATUS_SUCCESS(status))
         {
            smsLog(pMac, LOGE, " %s fail to start retryActionFrameTimerHandler\n", __FUNCTION__);
         }
      }
   }
   else
   {
      p2pFsm(pP2pContext, eP2P_TRIGGER_DISCONNECTED);
   }
    
#else  
    /* forward the indication to HDD */
    //RoamInfo can be passed as NULL....todo
    csrRoamCallCallback(pMac, pSmeRsp->sessionId, &RoamInfo, 0, 
                        eCSR_ROAM_SEND_ACTION_CNF, 
                       (pSmeRsp->statusCode == eSIR_SME_SUCCESS) ? 0:
                        eCSR_ROAM_RESULT_SEND_ACTION_FAIL);
#endif    
    return status;
}


#ifdef WLAN_FEATURE_P2P_INTERNAL
void p2pResetContext(tp2pContext *pP2pContext)
{
   if(NULL != pP2pContext)
   {
      tpAniSirGlobal pMac = PMAC_STRUCT(pP2pContext->hHal);
      int i;

      //When it is resetting a GO or client session, we
      //need to reset the group capability back to the original one
      if( (OPERATION_MODE_P2P_GROUP_OWNER == pP2pContext->operatingmode) ||
         (OPERATION_MODE_P2P_CLIENT == pP2pContext->operatingmode) )
      {
         for( i = 0; i < MAX_NO_OF_P2P_SESSIONS; i++ )
         {
            if(OPERATION_MODE_P2P_DEVICE == pMac->p2pContext[i].operatingmode)
            {
               gP2PIe[i].p2pCapabilityAttrib.groupCapability = pMac->p2pContext[i].OriginalGroupCapability;
            }
         }
      }

      pP2pContext->state = eP2P_STATE_DISCONNECTED;
      pP2pContext->currentSearchIndex = 0;
      pP2pContext->listenIndex = 1;

      pP2pContext->actionFrameType = eP2P_INVALID_FRM;

      pP2pContext->dialogToken = 0;
      pP2pContext->PeerFound = FALSE;
      pP2pContext->GroupFormationPending = FALSE;
      pP2pContext->directedDiscovery = FALSE;
      pP2pContext->listenDiscoverableState = eStateDisabled;


      if(pP2pContext->pSentActionFrame)
      {
         vos_mem_free(pP2pContext->pSentActionFrame);
         pP2pContext->pSentActionFrame = NULL;
      }
      if(pP2pContext->pNextActionFrm)
      {
         vos_mem_free(pP2pContext->pSentActionFrame);
         pP2pContext->pSentActionFrame = NULL;
      }      
      if( pP2pContext->probeRspIe )
      {
         vos_mem_free( pP2pContext->probeRspIe );
         pP2pContext->probeRspIe = NULL;
         pP2pContext->probeRspIeLength = 0;
      }

      if( pP2pContext->DiscoverReqIeField )
      {
         vos_mem_free(pP2pContext->DiscoverReqIeField );
         pP2pContext->DiscoverReqIeField = NULL;
         pP2pContext->DiscoverReqIeLength = 0;
      }

      if( pP2pContext->GoNegoCnfIeField )
      {
         vos_mem_free( pP2pContext->GoNegoCnfIeField);
         pP2pContext->GoNegoCnfIeField = NULL;
         pP2pContext->GoNegoCnfIeLength = 0;
      }

      if( pP2pContext->GoNegoReqIeField )
      {
         vos_mem_free( pP2pContext->GoNegoReqIeField );
         pP2pContext->GoNegoReqIeField = NULL;
         pP2pContext->GoNegoReqIeLength = 0;
      }

      if( pP2pContext->GoNegoResIeField )
      {
         vos_mem_free( pP2pContext->GoNegoResIeField );
         pP2pContext->GoNegoResIeField = NULL;
         pP2pContext->GoNegoResIeLength = 0;
      }

      if( pP2pContext->ProvDiscReqIeField )
      {
         vos_mem_free( pP2pContext->ProvDiscReqIeField );
         pP2pContext->ProvDiscReqIeField = NULL;
         pP2pContext->ProvDiscReqIeLength = 0;
      }

      if( pP2pContext->ProvDiscResIeField )
      {
         vos_mem_free( pP2pContext->ProvDiscResIeField );
         pP2pContext->ProvDiscResIeLength = 0;
         pP2pContext->ProvDiscResIeField = NULL;
      }

      if (pP2pContext->actionFrameTimer)
      {
         palTimerStop(pMac->hHdd, pP2pContext->actionFrameTimer);
      }

      if (pP2pContext->discoverTimer)
      {
         palTimerStop(pMac->hHdd, pP2pContext->discoverTimer);
      }

      if (pP2pContext->listenTimerHandler)
      {
         palTimerStop(pMac->hHdd, pP2pContext->listenTimerHandler);
      }

      if (pP2pContext->WPSRegistrarCheckTimerHandler)
      {
         palTimerStop(pMac->hHdd, pP2pContext->WPSRegistrarCheckTimerHandler);
      }

      if (pP2pContext->directedDiscoveryFilter)
      {
         pP2pContext->uNumDeviceFilterAllocated = 0;
         vos_mem_free(pP2pContext->directedDiscoveryFilter);
         pP2pContext->directedDiscoveryFilter = NULL;
      }

      vos_mem_zero(pP2pContext->peerMacAddress, P2P_MAC_ADDRESS_LEN);
   }
}
#endif    


eHalStatus sme_p2pOpen( tHalHandle hHal )
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   eHalStatus status = eHAL_STATUS_SUCCESS;

#ifdef WLAN_FEATURE_P2P_INTERNAL
   int i;
   tp2pContext *pP2pContext;

   for ( i=0; i < MAX_NO_OF_P2P_SESSIONS; i++ ) 
   {
      pP2pContext = &pMac->p2pContext[i];
      pP2pContext->hHal = hHal;

      pP2pContext->socialChannel[0] = 1;
      pP2pContext->socialChannel[1] = 6;
      pP2pContext->socialChannel[2] = 11;

      vos_spin_lock_init(&pP2pContext->lState);

      p2pResetContext(pP2pContext);

      status = palTimerAlloc(pMac->hHdd, &pP2pContext->actionFrameTimer, 
                                    p2pActionFrameTimerHandler, pP2pContext);
      if (!HAL_STATUS_SUCCESS(status))
      {
         smsLog(pMac, LOGE, " %s fail to alloc actionFrame timer for session %d\n", __FUNCTION__, i);
         break;
      }
      status = palTimerAlloc(pMac->hHdd, &pP2pContext->listenTimerHandler, 
                              p2pListenDiscoverTimerHandler, pP2pContext);
      if (!HAL_STATUS_SUCCESS(status))
      {
         smsLog(pMac, LOGE, " %s fail to alloc listen timer for session %d\n", __FUNCTION__, i);
         break;
      } 
      status = palTimerAlloc(pMac->hHdd, &pP2pContext->discoverTimer, p2pDiscoverTimerHandler, pP2pContext);
      if (!HAL_STATUS_SUCCESS(status))
      {
         smsLog(pMac, LOGE, " %s fail to alloc discover timer for session %d\n", __FUNCTION__, i);
         break;
      }

      status = palTimerAlloc(pMac->hHdd, &pP2pContext->retryActionFrameTimer, 
                     p2pRetryActionFrameTimerHandler, pP2pContext);
      if (!HAL_STATUS_SUCCESS(status))
      {
         smsLog(pMac, LOGE, " %s fail to alloc retryActionFrameTimerHandler timer for session %d\n", __FUNCTION__, i);
         break;
      }

      p2pCreateDefaultIEs(hHal, i);
   }
#else
   //If static structure is too big, Need to change this function to allocate memory dynamically
   vos_mem_zero( &pMac->p2pContext, sizeof( tp2pContext ) );
#endif

   if(!HAL_STATUS_SUCCESS(status))
   {
      sme_p2pClose(hHal);
    }

   return status;
}


eHalStatus p2pStop( tHalHandle hHal )
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

#ifdef WLAN_FEATURE_P2P_INTERNAL
   int i;

   for ( i = 0; i < MAX_NO_OF_P2P_SESSIONS; i++ ) 
   {
      p2pCloseSession(pMac, i);
   }
#else  
   if( pMac->p2pContext.probeRspIe )
   {
      vos_mem_free( pMac->p2pContext.probeRspIe );
      pMac->p2pContext.probeRspIe = NULL;
   }
  
   pMac->p2pContext.probeRspIeLength = 0;
#endif

   return eHAL_STATUS_SUCCESS;
}


eHalStatus sme_p2pClose( tHalHandle hHal )
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

#ifdef WLAN_FEATURE_P2P_INTERNAL
   tp2pContext *pContext;
   int i;

   p2pStop(hHal);

   for ( i = 0; i < MAX_NO_OF_P2P_SESSIONS; i++ ) 
   {
      p2pCloseSession(pMac, i);
      pContext = &pMac->p2pContext[i];
      if (pContext->actionFrameTimer)
      {
         palTimerFree(hHal, pContext->actionFrameTimer);
         pContext->actionFrameTimer = NULL;
      }

      if (pContext->discoverTimer)
      {
         palTimerFree(hHal, pContext->discoverTimer);
         pContext->discoverTimer = NULL;
      }

      if (pContext->listenTimerHandler)
      {
         palTimerFree(hHal, pContext->listenTimerHandler);
         pContext->listenTimerHandler = NULL;
      }

      if (pContext->WPSRegistrarCheckTimerHandler)
      {
         palTimerFree(hHal, pContext->WPSRegistrarCheckTimerHandler);
         pContext->WPSRegistrarCheckTimerHandler = NULL;
      }

      vos_spin_lock_destroy(&pContext->lState);
   }
#else  
    if( pMac->p2pContext.probeRspIe )
    {
        vos_mem_free( pMac->p2pContext.probeRspIe );
        pMac->p2pContext.probeRspIe = NULL;
    }
  
    pMac->p2pContext.probeRspIeLength = 0;
#endif

   return eHAL_STATUS_SUCCESS;
}


tSirRFBand GetRFBand(tANI_U8 channel)
{
    if ((channel >= SIR_11A_CHANNEL_BEGIN) &&
        (channel <= SIR_11A_CHANNEL_END))
        return SIR_BAND_5_GHZ;

    if ((channel >= SIR_11B_CHANNEL_BEGIN) &&
        (channel <= SIR_11B_CHANNEL_END))
        return SIR_BAND_2_4_GHZ;

    return SIR_BAND_UNKNOWN;
}

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

    \fn p2pRemainOnChannel
    \brief  API to post the remain on channel command.
    \param  hHal - The handle returned by macOpen.
    \param  sessinId - HDD session ID.
    \param  channel - Channel to remain on channel.
    \param  duration - Duration for which we should remain on channel
    \param  callback - callback function.
    \param  pContext - argument to the callback function
    \return eHalStatus

  -------------------------------------------------------------------------------*/
eHalStatus p2pRemainOnChannel(tHalHandle hHal, tANI_U8 sessionId,
         tANI_U8 channel, tANI_U32 duration,
        remainOnChanCallback callback, 
        void *pContext
#ifdef WLAN_FEATURE_P2P_INTERNAL
        , eP2PRemainOnChnReason reason
#endif
        )
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tSmeCmd *pRemainChlCmd = NULL;
    tANI_U32 phyMode;
  
    pRemainChlCmd = smeGetCommandBuffer(pMac);
    if(pRemainChlCmd == NULL)
        return eHAL_STATUS_FAILURE;
  
    if (SIR_BAND_5_GHZ == GetRFBand(channel))
    {
       phyMode = WNI_CFG_PHY_MODE_11A;
    }
    else
    {
       phyMode = WNI_CFG_PHY_MODE_11G;
    }
    
    cfgSetInt(pMac, WNI_CFG_PHY_MODE, phyMode);

    do
    {
        /* call set in context */
        pRemainChlCmd->command = eSmeCommandRemainOnChannel;
        pRemainChlCmd->sessionId = sessionId;
        pRemainChlCmd->u.remainChlCmd.chn = channel;
        pRemainChlCmd->u.remainChlCmd.duration = duration;
        pRemainChlCmd->u.remainChlCmd.callback = callback;
        pRemainChlCmd->u.remainChlCmd.callbackCtx = pContext;
    
        //Put it at the head of the Q if we just finish finding the peer and ready to send a frame
#ifdef WLAN_FEATURE_P2P_INTERNAL
        smePushCommand(pMac, pRemainChlCmd, (eP2PRemainOnChnReasonSendFrame == reason));
#else
        csrQueueSmeCommand(pMac, pRemainChlCmd, eANI_BOOLEAN_FALSE);
#endif
    } while(0);
  
    smsLog(pMac, LOGW, "exiting function %s\n", __FUNCTION__);
  
    return(status);
}

eHalStatus p2pSendAction(tHalHandle hHal, tANI_U8 sessionId,
         const tANI_U8 *pBuf, tANI_U32 len, tANI_U16 wait, tANI_BOOLEAN noack)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tSirMbMsgP2p *pMsg;
    tANI_U16 msgLen;

    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED,
       " %s sends action frame", __FUNCTION__);
    msgLen = (tANI_U16)((sizeof( tSirMbMsg )) + len);
    status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
    if(HAL_STATUS_SUCCESS(status))
    {
        palZeroMemory(pMac->hHdd, (void *)pMsg, msgLen);
        pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SEND_ACTION_FRAME_IND);
        pMsg->msgLen = pal_cpu_to_be16(msgLen);
        pMsg->sessionId = sessionId;
        pMsg->noack = noack;
        pMsg->wait = (tANI_U16)wait;
        palCopyMemory( pMac->hHdd, pMsg->data, pBuf, len );
        status = palSendMBMessage(pMac->hHdd, pMsg);
    }

    return( status );
}

eHalStatus p2pCancelRemainOnChannel(tHalHandle hHal, tANI_U8 sessionId)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
    tSirMbMsg *pMsg;
    tANI_U16 msgLen;

    //Need to check session ID to support concurrency

    msgLen = (tANI_U16)(sizeof( tSirMbMsg ));
    status = palAllocateMemory(pMac->hHdd, (void **)&pMsg, msgLen);
    if(HAL_STATUS_SUCCESS(status))
    {
        palZeroMemory(pMac->hHdd, (void *)pMsg, msgLen);
        pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_ABORT_REMAIN_ON_CHAN_IND);
        pMsg->msgLen = pal_cpu_to_be16(msgLen);
        status = palSendMBMessage(pMac->hHdd, pMsg);
    }                             

    return( status );
}

eHalStatus p2pSetPs(tHalHandle hHal, tP2pPsConfig *pNoA)
{
    tpP2pPsConfig pNoAParam;
    tSirMsgQ msg;
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

    status = palAllocateMemory(pMac->hHdd, (void**)&pNoAParam, sizeof(tP2pPsConfig));
    if(HAL_STATUS_SUCCESS(status))
    {
        palZeroMemory(pMac->hHdd, pNoAParam, sizeof(tP2pPsConfig));
        palCopyMemory(pMac->hHdd, pNoAParam, pNoA, sizeof(tP2pPsConfig)); 
        msg.type = eWNI_SME_UPDATE_NOA;
        msg.bodyval = 0;
        msg.bodyptr = pNoAParam;
        limPostMsgApi(pMac, &msg);
    }   
    return status;
}

#ifdef WLAN_FEATURE_P2P_INTERNAL
eHalStatus p2pGetConfigParam(tHalHandle hHal, tP2PConfigParam *pParam)
{
   eHalStatus status = eHAL_STATUS_INVALID_PARAMETER;
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   if(pParam)
   {
      pParam->P2PListenChannel = pMac->p2pContext[0].P2PListenChannel;
      pParam->P2POperatingChannel = pMac->p2pContext[0].P2POperatingChannel;
      pParam->P2POpPSCTWindow = pMac->p2pContext[0].pNoA.ctWindow;
      pParam->P2PPSSelection = pMac->p2pContext[0].pNoA.psSelection;
      pParam->P2POpPSCTWindow = pMac->p2pContext[0].pNoA.ctWindow;
      pParam->P2PNoADuration = pMac->p2pContext[0].pNoA.duration;
      pParam->P2PNoACount = pMac->p2pContext[0].pNoA.count;
      pParam->P2PNoAInterval = pMac->p2pContext[0].pNoA.interval;

      status = eHAL_STATUS_SUCCESS;
   }

   return (status);
}

eHalStatus p2pChangeDefaultConfigParam(tHalHandle hHal, tP2PConfigParam *pParam)
{
    eHalStatus status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   int i;
   tANI_U8 pBuf[P2P_COUNTRY_CODE_LEN];
   tANI_U8 uBufLen = P2P_COUNTRY_CODE_LEN;
   tP2P_OperatingChannel p2pChannel;

   status = sme_GetCountryCode( pMac, pBuf, &uBufLen );
   if ( !HAL_STATUS_SUCCESS( status ) )
   {
      status = eHAL_STATUS_FAILURE;
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s Cannot get the country code\n", __FUNCTION__);
   }

   vos_mem_copy(p2pChannel.countryString, pBuf, sizeof(pBuf));
   p2pChannel.regulatoryClass = 0x51;

   if(pParam)
   {
      for ( i=0; i < MAX_NO_OF_P2P_SESSIONS; i++ ) 
      {
         if (pParam->P2PListenChannel == 1 || pParam->P2PListenChannel == 6 
               || pParam->P2PListenChannel == 11)
         {
            pMac->p2pContext[i].P2PListenChannel = pParam->P2PListenChannel;
         }
         else
         {
            pMac->p2pContext[i].P2PListenChannel = P2P_OPERATING_CHANNEL;
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, 
               "Invalid P2P Listen Channel in config. Switch to default Listen Channel %d\n",
               __FUNCTION__, P2P_OPERATING_CHANNEL);
         }
         
         if(csrRoamIsChannelValid(pMac, pParam->P2POperatingChannel))
         {
            pMac->p2pContext[i].P2POperatingChannel = pParam->P2POperatingChannel;
         }
         else
         {
            pMac->p2pContext[i].P2POperatingChannel = P2P_OPERATING_CHANNEL;
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, 
               "Invalid P2P Operating Channel in config. Switch to default Channel %d\n", 
               __FUNCTION__, P2P_OPERATING_CHANNEL);
         }
         pMac->p2pContext[i].pNoA.ctWindow = pParam->P2POpPSCTWindow;
         pMac->p2pContext[i].pNoA.psSelection = pParam->P2PPSSelection;
         pMac->p2pContext[i].pNoA.ctWindow = pParam->P2POpPSCTWindow;
         pMac->p2pContext[i].pNoA.duration = pParam->P2PNoADuration;
         pMac->p2pContext[i].pNoA.count = pParam->P2PNoACount;
         pMac->p2pContext[i].pNoA.interval = pParam->P2PNoAInterval;

         p2pChannel.channel = pMac->p2pContext[i].P2POperatingChannel;
         P2P_UpdateIE(pMac, i, eWFD_OPERATING_CHANNEL, &p2pChannel, 1);
         p2pChannel.channel = pMac->p2pContext[i].P2PListenChannel;
         P2P_UpdateIE(pMac, i, eWFD_LISTEN_CHANNEL, &p2pChannel, 1);
      }
   }

    return status;
}

eHalStatus p2pPS(tHalHandle hHal, tANI_U8 sessionId)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   tP2pPsConfig pNoA;

   /* call set in context */
   pNoA.psSelection = pMac->p2pContext[sessionId].pNoA.psSelection;
   pNoA.sessionid = sessionId;

   if (pMac->p2pContext[sessionId].pNoA.psSelection == P2P_CLEAR_POWERSAVE)
   {
      return status;
   }

   if (pMac->p2pContext[sessionId].pNoA.psSelection == P2P_OPPORTUNISTIC_PS)
   {
      pNoA.opp_ps = TRUE;
      pNoA.ctWindow = pMac->p2pContext[sessionId].pNoA.ctWindow;
      pNoA.count = 0;
      pNoA.duration = 0;
      pNoA.interval = 0; 
      pNoA.single_noa_duration = 0;
   }
   else if (pMac->p2pContext[sessionId].pNoA.psSelection == P2P_PERIODIC_NOA)
   {
      pNoA.opp_ps = 0;
      pNoA.ctWindow = 0;
      pNoA.count = pMac->p2pContext[sessionId].pNoA.count;
      pNoA.duration = pMac->p2pContext[sessionId].pNoA.duration;
      pNoA.interval = pMac->p2pContext[sessionId].pNoA.interval; 
      pNoA.single_noa_duration = 0;
   } 
   else if(pMac->p2pContext[sessionId].pNoA.psSelection == P2P_SINGLE_NOA)
   {
      pNoA.opp_ps = 0;
      pNoA.ctWindow = 0;
      pNoA.count = 0;
      pNoA.duration = 0;
      pNoA.interval = 0; 
      pNoA.single_noa_duration = pMac->p2pContext[sessionId].pNoA.duration;
   }

   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, 
      " %s HDDSession %d set NoA parameters. Selection %d, opp_ps %d, ctWindow %d, count %d, "
      "duration %d, interval %d single NoA duration %d",
      __FUNCTION__, sessionId, pMac->p2pContext[sessionId].pNoA.psSelection,
      pNoA.opp_ps, pNoA.ctWindow, pNoA.count, pNoA.duration, 
      pNoA.interval, pNoA.single_noa_duration );

   status = sme_p2pSetPs(pMac, &pNoA);
   if(!HAL_STATUS_SUCCESS(status))
   {
      smsLog(pMac, LOGE, FL(" sme_p2pSetPs fail with status %d"), status);
      return status;
   }

   return status;
}

void P2P_UpdateMacHdr(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 *pBuf)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   tSirMacMgmtHdr *macHdr = (tSirMacMgmtHdr *)pBuf;

   macHdr->fc.protVer = 0;
   macHdr->fc.type = 0;
   macHdr->fc.subType = 13;
   macHdr->durationLo = 0;
   macHdr->durationHi = 0;
   vos_mem_copy(macHdr->da, pMac->p2pContext[SessionID].peerMacAddress, P2P_MAC_ADDRESS_LEN);
   vos_mem_copy(macHdr->sa, pMac->p2pContext[SessionID].selfMacAddress, P2P_MAC_ADDRESS_LEN);
   vos_mem_copy(macHdr->bssId, pMac->p2pContext[SessionID].peerMacAddress, P2P_MAC_ADDRESS_LEN);

   return;
}

static eHalStatus p2pRemainOnChannelReadyCallback(tHalHandle halHandle,
                     void *pContext,
                     eHalStatus scan_status)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tp2pContext *p2pContext = (tp2pContext*) pContext;

   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s GroupFormationPending %d  PeerFound %d\n", 
               __FUNCTION__, p2pContext->GroupFormationPending, p2pContext->PeerFound);

   if (p2pContext->PeerFound)
   {
      p2pContext->PeerFound = FALSE;

      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Sending actionframe\n", __FUNCTION__);
      if (p2pContext->pSentActionFrame)
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s calling p2pSendAction\n", __FUNCTION__);
         p2pSendAction(halHandle, p2pContext->SMEsessionId, (tANI_U8 *)p2pContext->pSentActionFrame, p2pContext->ActionFrameLen);
      }
   }

   return status;
}

eHalStatus p2pGrpFormationRemainOnChanRspCallback(tHalHandle halHandle, void *pContext, tANI_U32 scanId, eCsrScanStatus scan_status)
{
   return eHAL_STATUS_SUCCESS;
}

tANI_U8 p2pGetDialogToken(tHalHandle hHal, tANI_U8 SessionID, eP2PFrameType actionFrameType)
{
   tANI_U8 dialogToken = 0;

   dialogToken = (tANI_U8) vos_timer_get_system_ticks();

   return(dialogToken);
}

void p2pRetryActionFrameTimerHandler(void *pContext)
{
   tp2pContext *p2pContext = (tp2pContext*) pContext;
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpAniSirGlobal pMac = PMAC_STRUCT( p2pContext->hHal );

   p2pContext->PeerFound = TRUE;
   smsLog( pMac, LOGE, "%s Calling remain on channel \n", __FUNCTION__);
   status = p2pRemainOnChannel( pMac, p2pContext->SMEsessionId, p2pContext->P2PListenChannel/*pScanResult->BssDescriptor.channelId*/, P2P_REMAIN_ON_CHAN_TIMEOUT_LOW,
                                    NULL, NULL, eP2PRemainOnChnReasonSendFrame);
   if(status != eHAL_STATUS_SUCCESS)
   {
      smsLog( pMac, LOGE, "%s remain on channel failed\n", __FUNCTION__);
   }

   return;
}

void p2pActionFrameTimerHandler(void *pContext)
{
   tp2pContext *p2pContext = (tp2pContext*) pContext;
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tANI_U8 *pBuf = NULL, *pNextBuf = NULL;
   tCsrRoamInfo roamInfo;


   if(p2pContext->pSentActionFrame)
   {
      vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
      csrRoamCallCallback((tpAniSirGlobal)p2pContext->hHal, p2pContext->SMEsessionId, &roamInfo, 0, 
                          eCSR_ROAM_SEND_ACTION_CNF, 
                          eCSR_ROAM_RESULT_SEND_ACTION_FAIL);
   }

   if(VOS_IS_STATUS_SUCCESS(vos_spin_lock_acquire(&p2pContext->lState)))
   {
      if(p2pContext->pSentActionFrame)
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
            " %s actionframe timeout type %d", __FUNCTION__, p2pContext->actionFrameType);
         pBuf = p2pContext->pSentActionFrame;
         p2pContext->pSentActionFrame = NULL;
      }
      if(p2pContext->pNextActionFrm)
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
            " %s next actionframe timeout type %d", __FUNCTION__, p2pContext->NextActionFrameType);
         pNextBuf = p2pContext->pNextActionFrm;
         p2pContext->pNextActionFrm = NULL;
      }
      vos_spin_lock_release(&p2pContext->lState);

      if(pBuf)
      {
         vos_mem_free(pBuf);
      }
      if(pNextBuf)
      {
         //Inform the failure of the next frame.
         p2pContext->pSentActionFrame = pNextBuf;
         p2pContext->ActionFrameLen = p2pContext->nNextFrmLen;
         p2pContext->actionFrameType = p2pContext->NextActionFrameType;
         vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
         csrRoamCallCallback((tpAniSirGlobal)p2pContext->hHal, p2pContext->SMEsessionId, &roamInfo, 0, 
                          eCSR_ROAM_SEND_ACTION_CNF, 
                          eCSR_ROAM_RESULT_SEND_ACTION_FAIL);
         p2pContext->pSentActionFrame = NULL;
         vos_mem_free(pNextBuf);
      }
   }
   status = p2pFsm(p2pContext, eP2P_TRIGGER_DISCONNECTED);
   p2pContext->actionFrameTimeout = TRUE;
   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s timedout\n", __FUNCTION__);

   return;
}


eHalStatus p2pCreateActionFrame(tpAniSirGlobal pMac, tANI_U8 SessionID, void *p2pactionframe, 
                                 eP2PFrameType actionFrameType, tANI_U8 **ppFrm)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tANI_U32 len = 0;
   tANI_U32 nActionFrmlen = 0, pendingFrameLen;
   tANI_U8 *pActionFrm = NULL;
   tANI_U8 *pBuf = NULL, *pLocal = NULL;
   eP2PFrameType pendingActionFrameType;
   tp2pContext *pP2pContext = &pMac->p2pContext[SessionID];

   if(NULL == ppFrm)
   {
      smsLog(pMac, LOGE, FL("  invalid parameters"));
      return eHAL_STATUS_FAILURE;
   }

   csrScanAbortMacScan(pMac);

   switch (actionFrameType)
   {
   case eP2P_GONEGO_REQ:
      status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_GO_NEGOTIATION_REQUEST, p2pactionframe, len);
      break;

   case eP2P_GONEGO_RES:
      status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_GO_NEGOTIATION_RESPONSE, p2pactionframe, len);
      break;

   case eP2P_GONEGO_CNF:
      status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_GO_NEGOTIATION_CONFIRMATION, p2pactionframe, len);
      break;

   case eP2P_PROVISION_DISCOVERY_REQUEST:
      status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_PROVISION_DISCOVERY_REQUEST, p2pactionframe, len);
      break;

   case eP2P_PROVISION_DISCOVERY_RESPONSE:
      status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_PROVISION_DISCOVERY_RESPONSE, p2pactionframe, len);
      break;

   case eP2P_INVITATION_REQ:
      status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_INVITATION_REQUEST, p2pactionframe, len);
      break;

   case eP2P_INVITATION_RSP:
      status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_INVITATION_RESPONSE, p2pactionframe, len);
      break;
   default:
      return status;
   }

   status = P2P_GetActionFrame(pMac, SessionID, actionFrameType, &pActionFrm, &nActionFrmlen);
   if(!HAL_STATUS_SUCCESS(status))
   {
      smsLog(pMac, LOGE, FL(" P2P_GetActionFrame fail with status %d"), status);
      return status;
   }

   P2P_UpdateMacHdr(pMac, SessionID, pActionFrm);

   pBuf = (tANI_U8 *)vos_mem_malloc( nActionFrmlen);
   if(NULL == pBuf)
   {
      smsLog(pMac, LOGE, FL("  fail to allocate memory"));
      if (pActionFrm) 
         vos_mem_free(pActionFrm);
      return eHAL_STATUS_FAILURE;
   }

   vos_mem_copy(pBuf, pActionFrm, nActionFrmlen);
   vos_mem_free(pActionFrm);

   if( !VOS_IS_STATUS_SUCCESS(vos_spin_lock_acquire(&pP2pContext->lState)))
   {
      smsLog(pMac, LOGE, FL("  fail to acquire spinlock"));
      vos_mem_free(pBuf);
      return eHAL_STATUS_FAILURE;
   }

   if(NULL != pP2pContext->pSentActionFrame)
   {
      //If there is one pending frame already. Drop that one and save the new one
      pLocal = pP2pContext->pNextActionFrm;
      pendingActionFrameType = pP2pContext->NextActionFrameType;
      pendingFrameLen = pP2pContext->nNextFrmLen;
      pP2pContext->pNextActionFrm = pBuf;
      pP2pContext->nNextFrmLen = nActionFrmlen;
      pP2pContext->NextActionFrameType = actionFrameType;
      *ppFrm = NULL;
   }
   else
   {
      pP2pContext->pSentActionFrame = pBuf;
      pP2pContext->ActionFrameLen = nActionFrmlen;
      pP2pContext->actionFrameType = actionFrameType;
      *ppFrm = pBuf;
   }
   vos_spin_lock_release(&pP2pContext->lState);

   if(NULL != pLocal)
   {
      smsLog(pMac, LOGE, FL(" Drop a waiting action frame 0x%x, type %d lenth %d"), 
         pLocal, pendingActionFrameType, pendingFrameLen);
      vos_mem_free(pLocal);
   }

   return status;
}


extern eHalStatus p2pGetSSID(tANI_U8 *ssId, tANI_U32 *ssIdLen, tANI_U8 SessionID);

static eHalStatus p2pSendActionFrame(tpAniSirGlobal pMac, tANI_U8 HDDSessionID, eP2PFrameType actionFrameType)
{
   tCsrScanResultFilter filter;
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tScanResultHandle hScanResult = NULL;
   tCsrScanResultInfo   *pScanResult   = NULL;
   tANI_U8 ssId[SIR_MAC_MAX_SSID_LENGTH];
   tANI_U32 ssIdLen = 0;
   tp2pContext *pP2pContext = &pMac->p2pContext[HDDSessionID];

   pP2pContext->GroupFormationPending = TRUE;
   if (actionFrameType == eP2P_GONEGO_REQ || actionFrameType == eP2P_PROVISION_DISCOVERY_REQUEST 
      || actionFrameType == eP2P_INVITATION_REQ)
   {
      vos_mem_zero(&filter, sizeof(filter));
      filter.BSSIDs.numOfBSSIDs = 1;
      filter.BSSIDs.bssid = &pP2pContext->peerMacAddress;
      filter.bWPSAssociation = TRUE;
      filter.BSSType = eCSR_BSS_TYPE_ANY;

      status = csrScanGetResult(pMac, pP2pContext->SMEsessionId, &filter, &hScanResult);

      if (hScanResult)
      {
         pScanResult = csrScanResultGetFirst(pMac, hScanResult );
         if(pScanResult)
         {

            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s found match on channel %d", 
               __FUNCTION__, pScanResult->BssDescriptor.channelId);
            pP2pContext->formationReq.targetListenChannel = pScanResult->BssDescriptor.channelId;
            if(pP2pContext->P2PListenChannel != pScanResult->BssDescriptor.channelId)
            {
               VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, 
                  "%s adapt listen channel to %d", 
                  __FUNCTION__, pScanResult->BssDescriptor.channelId);
               p2pSetListenChannel(pMac, pP2pContext->sessionId, pScanResult->BssDescriptor.channelId);
            }
            vos_mem_copy(pP2pContext->formationReq.deviceAddress, pScanResult->BssDescriptor.bssId, P2P_MAC_ADDRESS_LEN);
         }
         csrScanResultPurge(pMac, hScanResult);
      } 
      else 
      {
         vos_mem_zero(&filter, sizeof(filter));
         filter.bWPSAssociation = TRUE;
         filter.BSSType = eCSR_BSS_TYPE_ANY;
         filter.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
         if( filter.SSIDs.SSIDList == NULL )
         {
            smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
            pP2pContext->GroupFormationPending = FALSE;
            return eHAL_STATUS_FAILURE;
         }
         vos_mem_zero( filter.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) );
         p2pGetSSID(ssId, &ssIdLen, HDDSessionID);

         if (ssIdLen)
         {
            filter.SSIDs.SSIDList->SSID.length = ssIdLen;
            vos_mem_copy(&filter.SSIDs.SSIDList[0].SSID.ssId, &ssId, ssIdLen);
            filter.SSIDs.numOfSSIDs = 1;
            status = csrScanGetResult(pMac, pP2pContext->SMEsessionId, &filter, &hScanResult);
            if (hScanResult)
            {
               pScanResult = csrScanResultGetFirst(pMac, hScanResult );
               pP2pContext->formationReq.targetListenChannel = pScanResult->BssDescriptor.channelId;
               vos_mem_copy(pP2pContext->formationReq.deviceAddress, pScanResult->BssDescriptor.bssId, P2P_MAC_ADDRESS_LEN);
               csrScanResultPurge(pMac, hScanResult);
            }
            else
            {
               VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s not found match\n", __FUNCTION__);
               pP2pContext->formationReq.targetListenChannel = 0;
               vos_mem_copy(pP2pContext->formationReq.deviceAddress, pP2pContext->peerMacAddress, P2P_MAC_ADDRESS_LEN);
               status = eHAL_STATUS_SUCCESS;
            }
            vos_mem_free(filter.SSIDs.SSIDList);
         }
         else
         {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s not found match\n", __FUNCTION__);
            pP2pContext->formationReq.targetListenChannel = 0;
            vos_mem_copy(pP2pContext->formationReq.deviceAddress, pP2pContext->peerMacAddress, P2P_MAC_ADDRESS_LEN);
            status = eHAL_STATUS_SUCCESS;
         }    
      }
      sme_CancelRemainOnChannel(pMac, pP2pContext->SMEsessionId );
      p2pFsm(pP2pContext, eP2P_TRIGGER_GROUP_FORMATION);     
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, " %s send action frame %d timeout %d\n", 
               __FUNCTION__, actionFrameType, pP2pContext->ActionFrameSendTimeout);
   } 
   else
   {
      pP2pContext->PeerFound = TRUE;

      status = p2pSendAction(pMac, pP2pContext->SMEsessionId, (tANI_U8 *)pP2pContext->pSentActionFrame, 
                              pP2pContext->ActionFrameLen);
      if(status != eHAL_STATUS_SUCCESS)
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,  
            "%s p2pSendAction failed to send frame type %d\n", __FUNCTION__, actionFrameType);
         pP2pContext->GroupFormationPending = FALSE;
         return status;
      }

      if ( actionFrameType == eP2P_GONEGO_RES )
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling p2pRemainOnChannel with duration"
            "%d on channel %d\n", __FUNCTION__, P2P_REMAIN_ON_CHAN_TIMEOUT, pP2pContext->P2PListenChannel);

         if(p2pRemainOnChannel( pMac, pP2pContext->SMEsessionId, 
                                      pP2pContext->P2PListenChannel, P2P_REMAIN_ON_CHAN_TIMEOUT_LOW,
                                      NULL, NULL, eP2PRemainOnChnReasonSendFrame))
         {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,  "%s remain on channel failed\n", __FUNCTION__);
         }
      }
   }

   return(status);
}


#define WLAN_P2P_DEF_ACTION_FRM_TIMEOUT_VALUE 1000  //1s

eHalStatus p2pCreateSendActionFrame(tHalHandle hHal, tANI_U8 HDDSessionID, 
   void *p2pactionframe, eP2PFrameType actionFrameType, tANI_U32 timeout)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   tANI_U8 *pBuf = NULL;
   tp2pContext *pP2pContext = &pMac->p2pContext[HDDSessionID];
   
   status = p2pCreateActionFrame(pMac, HDDSessionID, p2pactionframe, actionFrameType, &pBuf);
   if(!HAL_STATUS_SUCCESS(status))
   {
      smsLog(pMac, LOGE, FL("  fail to create action frame"));
      return status;
   }
      
   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, " %s send action frame %d timeout %d\n", 
                  __FUNCTION__, actionFrameType, timeout);

   if(NULL != pBuf)
   {
      if (timeout)
      {
         pP2pContext->ActionFrameSendTimeout = timeout;
      }
      else
      {
         pP2pContext->ActionFrameSendTimeout = WLAN_P2P_DEF_ACTION_FRM_TIMEOUT_VALUE;
      }

      status = palTimerStart(pMac->hHdd, pP2pContext->actionFrameTimer, 
                        pP2pContext->ActionFrameSendTimeout * PAL_TIMER_TO_MS_UNIT, eANI_BOOLEAN_FALSE);
      if (!HAL_STATUS_SUCCESS(status))
      {
         tCsrRoamInfo RoamInfo;

         vos_mem_zero(&RoamInfo, sizeof(tCsrRoamInfo));
         smsLog(pMac, LOGE, FL(" %s fail to start timer status %d"), __FUNCTION__, status);
         //Without the timer we cannot continue
         csrRoamCallCallback((tpAniSirGlobal)pP2pContext->hHal, 
                     pP2pContext->SMEsessionId, &RoamInfo, 0, 
                     eCSR_ROAM_SEND_ACTION_CNF, 
                     eCSR_ROAM_RESULT_SEND_ACTION_FAIL);
         vos_spin_lock_acquire(&pP2pContext->lState);
         pBuf = pP2pContext->pSentActionFrame;
         pP2pContext->pSentActionFrame = NULL;
         vos_spin_lock_release(&pP2pContext->lState);
         vos_mem_free(pBuf);
         pBuf = NULL;
         p2pFsm(pP2pContext, eP2P_TRIGGER_DISCONNECTED);
         return status;
      }
      //We can send this frame now
      status = p2pSendActionFrame(pMac, HDDSessionID, actionFrameType);
      if(!HAL_STATUS_SUCCESS(status))
      {
         smsLog(pMac, LOGE, FL("  fail to send action frame status %d"), status);
      }
      //Let them retry
      pP2pContext->actionFrameTimeout = FALSE;
   }
   else
   {
      //An action frame is pedning at lower layer
      smsLog(pMac, LOGW, FL("  An action frame is pending while trying to send frametype %d"), actionFrameType);
      if (timeout)
      {
         pP2pContext->nNextFrameTimeOut = timeout;
      }
      else
      {
         pP2pContext->nNextFrameTimeOut = WLAN_P2P_DEF_ACTION_FRM_TIMEOUT_VALUE;
      }
   }

   return status;
}


void p2pListenDiscoverTimerHandlerCB(void *pContext)
{
}

void p2pListenDiscoverTimerHandler(void *pContext)
{
   tp2pContext *p2pContext = (tp2pContext*) pContext;
   eHalStatus status = eHAL_STATUS_SUCCESS;

   if( (eP2P_STATE_DISCONNECTED == p2pContext->state) && 
       (eStateDisabled != p2pContext->listenDiscoverableState) )
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling RemainOnChannel with duration %d on channel %d\n", 
             __FUNCTION__, p2pContext->listenDuration, p2pContext->P2PListenChannel);
      status = p2pRemainOnChannel( p2pContext->hHal, p2pContext->SMEsessionId, p2pContext->P2PListenChannel, p2pContext->listenDuration, 
                                    p2pListenStateDiscoverableCallback, p2pContext, eP2PRemainOnChnReasonListen);
   }
   else
   {
      smsLog(((tpAniSirGlobal)p2pContext->hHal), LOGW, FL(" cannot call p2pRemainOnChannel state %d\n"), p2pContext->state);
   }

   return;
}


static eHalStatus p2pListenStateDiscoverableCallback(tHalHandle halHandle, void *pContext, eHalStatus retStatus)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpAniSirGlobal pMac = PMAC_STRUCT(halHandle);
   tp2pContext *p2pContext = (tp2pContext*) pContext;

   if( (eP2P_STATE_DISCONNECTED == p2pContext->state) && 
       (eStateDisabled != p2pContext->listenDiscoverableState) && 
       (NULL == p2pContext->p2pDiscoverCBFunc) )
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s restart listen timer expire time %d\n", 
                  __FUNCTION__, p2pContext->expire_time);
      //We can restart the listening
      status = palTimerStart(pMac->hHdd, p2pContext->listenTimerHandler, p2pContext->expire_time, eANI_BOOLEAN_FALSE);
      if (eHAL_STATUS_SUCCESS != status)
      {
         VOS_ASSERT(status);
      }
   }
   else
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s not restart listen timer  state (%d)\n", 
                  __FUNCTION__, p2pContext->state);
   }

   return status;
}


eHalStatus P2P_ListenStateDiscoverable(tHalHandle hHal, tANI_U8 sessionId,
                                       ep2pListenStateDiscoverability listenState)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   switch (listenState) 
   {
   case P2P_DEVICE_NOT_DISCOVERABLE:
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s P2P_NOT_DISCOVERABLE\n", __FUNCTION__);
      pMac->p2pContext[sessionId].listenDiscoverableState = eStateDisabled;
      pMac->p2pContext[sessionId].DiscoverableCfg = listenState;
      if (pMac->p2pContext[sessionId].state == eP2P_STATE_DISCONNECTED)
      {
         sme_CancelRemainOnChannel(hHal, sessionId );

         if (pMac->p2pContext[sessionId].listenTimerHandler)
         {
            status = palTimerStop(pMac->hHdd, pMac->p2pContext[sessionId].listenTimerHandler);
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Timer Stop status %d\n", 
                        __FUNCTION__, status);
         }
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s P2P_NOT_DISCOVERABLE not in right state (%d)",
            __FUNCTION__, pMac->p2pContext[sessionId].state);
      }
      break;

   case P2P_DEVICE_AUTO_AVAILABILITY:
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s P2P_AUTO_AVAILABILITY\n",__FUNCTION__);
      pMac->p2pContext[sessionId].listenDiscoverableState = eStateEnabled;
      pMac->p2pContext[sessionId].DiscoverableCfg = listenState;
      pMac->p2pContext[sessionId].expire_time = P2P_LISTEN_TIMEOUT_AUTO * PAL_TIMER_TO_MS_UNIT;
      pMac->p2pContext[sessionId].listenDuration = P2P_LISTEN_TIMEOUT;
      if (pMac->p2pContext[sessionId].state == eP2P_STATE_DISCONNECTED)
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling RemainOnChannel with diration %d on channel %d\n",
                     __FUNCTION__, pMac->p2pContext[sessionId].listenDuration, pMac->p2pContext[sessionId].P2PListenChannel);
         p2pRemainOnChannel( pMac, pMac->p2pContext[sessionId].SMEsessionId, pMac->p2pContext[sessionId].P2PListenChannel, 
                              pMac->p2pContext[sessionId].listenDuration, p2pListenStateDiscoverableCallback, 
                              &pMac->p2pContext[sessionId], eP2PRemainOnChnReasonListen);
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s P2P_AUTO_DISCOVERABLE not in right state (%d)",
            __FUNCTION__, pMac->p2pContext[sessionId].state);
      }
      break;

   case P2P_DEVICE_HIGH_AVAILABILITY:
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s P2P_HIGH_AVAILABILITY\n",__FUNCTION__);
      pMac->p2pContext[sessionId].listenDiscoverableState = eStateEnabled;
      pMac->p2pContext[sessionId].DiscoverableCfg = listenState;
      pMac->p2pContext[sessionId].expire_time = P2P_REMAIN_ON_CHAN_TIMEOUT_LOW * PAL_TIMER_TO_MS_UNIT;
      pMac->p2pContext[sessionId].listenDuration = P2P_LISTEN_TIMEOUT_HIGH;
      if (pMac->p2pContext[sessionId].state == eP2P_STATE_DISCONNECTED)
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling RemainOnChannel with diration %d on channel %d\n",
                     __FUNCTION__, pMac->p2pContext[sessionId].listenDuration, pMac->p2pContext[sessionId].P2PListenChannel);
         p2pRemainOnChannel( pMac, pMac->p2pContext[sessionId].SMEsessionId, pMac->p2pContext[sessionId].P2PListenChannel, 
                              pMac->p2pContext[sessionId].listenDuration, p2pListenStateDiscoverableCallback, 
                              &pMac->p2pContext[sessionId], eP2PRemainOnChnReasonListen);
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s P2P_HIGH_DISCOVERABLE not in right state (%d)",
            __FUNCTION__, pMac->p2pContext[sessionId].state);
      }
      break;

   case 234: //Not to use this as it enabling GO to be concurrent with P2P device P2P_DEVICE_HIGH_AVAILABILITY:
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s P2P_HIGH_AVAILABILITY\n",__FUNCTION__);
      pMac->p2pContext[sessionId].listenDiscoverableState = eStateEnabled;
      pMac->p2pContext[sessionId].DiscoverableCfg = listenState;

      if ((pMac->p2pContext[sessionId].P2POperatingChannel != pMac->p2pContext[sessionId].P2PListenChannel)
           && p2pIsGOportEnabled(pMac))
      {
         pMac->p2pContext[sessionId].expire_time = P2P_LISTEN_TIMEOUT_HIGH * PAL_TIMER_TO_MS_UNIT * 5;
         pMac->p2pContext[sessionId].listenDuration = P2P_REMAIN_ON_CHAN_TIMEOUT_LOW;
      } 
      else
      {
         pMac->p2pContext[sessionId].expire_time = P2P_LISTEN_TIMEOUT_HIGH * PAL_TIMER_TO_MS_UNIT;
         pMac->p2pContext[sessionId].listenDuration = P2P_LISTEN_TIMEOUT;
      }

      if (pMac->p2pContext[sessionId].state == eP2P_STATE_DISCONNECTED)
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling RemainOnChannel with diration %d on channel %d\n",
                     __FUNCTION__, pMac->p2pContext[sessionId].listenDuration, pMac->p2pContext[sessionId].P2PListenChannel);
         p2pRemainOnChannel( pMac, pMac->p2pContext[sessionId].SMEsessionId, pMac->p2pContext[sessionId].P2PListenChannel, 
                              pMac->p2pContext[sessionId].listenDuration, p2pListenStateDiscoverableCallback, 
                              &pMac->p2pContext[sessionId], eP2PRemainOnChnReasonListen);
      }
      
      break;

   default:
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
         "%s Unknown listen setting",__FUNCTION__, listenState);
      break;
   }

    return( status );
}


void p2pCallDiscoverCallback(tp2pContext *p2pContext, eP2PDiscoverStatus statusCode)
{
   if (p2pContext->p2pDiscoverCBFunc)
   {
      p2pDiscoverCompleteCallback pcallback = p2pContext->p2pDiscoverCBFunc;
      p2pContext->p2pDiscoverCBFunc = NULL;
      pcallback(p2pContext->hHal, p2pContext->pContext, statusCode);
   }
   p2pContext->directedDiscovery = FALSE;
}


void p2pDiscoverTimerHandler(void *pContext)
{
   tp2pContext *p2pContext = (tp2pContext*) pContext;
   eHalStatus status = eHAL_STATUS_SUCCESS;

   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s enter", __FUNCTION__);
   p2pCallDiscoverCallback(p2pContext, 
         (p2pContext->directedDiscovery) ? eP2P_DIRECTED_DISCOVER : eP2P_DISCOVER_SUCCESS);

   status = p2pFsm(p2pContext, eP2P_TRIGGER_DISCONNECTED);

   return;
}



eHalStatus p2pGetResultFilter(tp2pContext *pP2pContext,
                              tCsrScanResultFilter *pFilter)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   v_U32_t uNumDeviceFilters;
   tp2pDiscoverDeviceFilter *directedDiscoveryFilter;
   int i;
   tCsrBssid *bssid = NULL;

   do
   {
      if( (NULL != pP2pContext) && (NULL != pFilter) )
      {
         vos_mem_zero(pFilter, sizeof(tCsrScanResultFilter));
         uNumDeviceFilters = pP2pContext->uNumDeviceFilters;
         directedDiscoveryFilter = pP2pContext->directedDiscoveryFilter;
         for(i = 0; i < uNumDeviceFilters; i++)
         {
            if (directedDiscoveryFilter->ucBitmask & DISCOVERY_FILTER_BITMASK_DEVICE)
            {
               pFilter->BSSIDs.numOfBSSIDs++;
            }
            
            if ((directedDiscoveryFilter->ucBitmask != QCWLAN_P2P_DISCOVER_ANY) 
               && (directedDiscoveryFilter->ucBitmask & DISCOVERY_FILTER_BITMASK_GO))
            {
               //Matching Device ID and GroupSSID
               pFilter->BSSIDs.numOfBSSIDs++;
               if(directedDiscoveryFilter->GroupSSID.length)
               {
                  pFilter->SSIDs.numOfSSIDs++;
               }
            }
            directedDiscoveryFilter += sizeof(tp2pDiscoverDeviceFilter);
         }

         directedDiscoveryFilter = pP2pContext->directedDiscoveryFilter;
         if (pFilter->BSSIDs.numOfBSSIDs)
         {
            bssid = ( tCsrBssid *) vos_mem_malloc( sizeof( tCsrBssid ) * pFilter->BSSIDs.numOfBSSIDs );
            if(NULL == bssid)
            {
               VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
                  " %s fail to allocate bssid", __FUNCTION__);
               status = eHAL_STATUS_RESOURCES;
               break;
            }

            pFilter->BSSIDs.bssid = bssid;

            for (i = 0; i < uNumDeviceFilters; i++)
            {
               vos_mem_copy(bssid, directedDiscoveryFilter->DeviceID, P2P_MAC_ADDRESS_LEN);
               bssid += sizeof(tCsrBssid);
               directedDiscoveryFilter += sizeof(tp2pDiscoverDeviceFilter);
            }
         }

         directedDiscoveryFilter = pP2pContext->directedDiscoveryFilter;
         if (pFilter->SSIDs.numOfSSIDs)
         {
            pFilter->SSIDs.SSIDList = (tCsrSSIDInfo *)vos_mem_malloc( sizeof( *pFilter->SSIDs.SSIDList ) *
                                                      pFilter->SSIDs.numOfSSIDs );
            if(NULL == pFilter->SSIDs.SSIDList)
            {
               VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
                  " %s fail to allocate bssid", __FUNCTION__);
               status = eHAL_STATUS_RESOURCES;
               break;
            }

            if ( pFilter->SSIDs.SSIDList )
            {
               for ( i = 0; i < uNumDeviceFilters; i++ )
               {
                  if (directedDiscoveryFilter->ucBitmask == DISCOVERY_FILTER_BITMASK_GO)
                  {
                     if(directedDiscoveryFilter->GroupSSID.length)
                     {
                        pFilter->SSIDs.SSIDList[i].SSID.length = directedDiscoveryFilter->GroupSSID.length;
                        vos_mem_copy( pFilter->SSIDs.SSIDList[i].SSID.ssId,
                                       directedDiscoveryFilter->GroupSSID.ssId,
                                       directedDiscoveryFilter->GroupSSID.length );
                     }
                  }
                  directedDiscoveryFilter += sizeof(tp2pDiscoverDeviceFilter);
               }
            }
         }
      }

      pFilter->p2pResult = TRUE;
      pFilter->bWPSAssociation = TRUE;
      pFilter->BSSType = eCSR_BSS_TYPE_ANY;
   } while(0);

   if(!HAL_STATUS_SUCCESS(status))
   {
      if(pFilter->SSIDs.SSIDList)
      {
         vos_mem_free(pFilter->SSIDs.SSIDList);
         pFilter->SSIDs.SSIDList = NULL;
      }
      if( pFilter->BSSIDs.bssid )
      {
         vos_mem_free(pFilter->BSSIDs.bssid);
         pFilter->BSSIDs.bssid = NULL;
      }
   }

   return status;
}


/*
  @breif Function calls P2P_Fsm function to initiate the P2P Discover process

  @param[in] hHal - Handle to MAC structure.
        [in] sessionID - Session ID returned by sme_OpenSession
        [in] pDiscoverRequest - pointer to the tp2pDiscoverRequest structure
             whose parameters are filled in the HDD.
        [in] callback - HDD callback function to be called when Discover
             is complete
        [in] pContext - a pointer passed in for the callback

  @return eHAL_STATUS_FAILURE - If success.
          eHAL_STATUS_SUCCESS - If failure.
*/
eHalStatus P2P_DiscoverRequest(tHalHandle hHal,
                tANI_U8 SessionID,
                tP2PDiscoverRequest *pDiscoverRequest,
                p2pDiscoverCompleteCallback callback,
                void *pContext)
{
   eHalStatus           status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal       pMac = PMAC_STRUCT(hHal);
   tScanResultHandle    hScanResult = NULL;
   tCsrScanResultFilter filter;
   tANI_U32 uNumDeviceFilters;
   tp2pDiscoverDeviceFilter *pDeviceFilters;
   tANI_U32 i = 0;
   tp2pContext *pP2pContext = &pMac->p2pContext[SessionID];
   tCsrBssid *bssid = NULL;
   tp2pDiscoverDeviceFilter discoverFilter;
   tANI_BOOLEAN fDirect = FALSE;

   if (pDiscoverRequest == NULL)
   {
      return status;
   }

   pP2pContext->discoverType      = pDiscoverRequest->discoverType;
   pP2pContext->scanType          = pDiscoverRequest->scanType;
   pP2pContext->uDiscoverTimeout  = pDiscoverRequest->uDiscoverTimeout;

   if (pP2pContext->DiscoverReqIeField)
   {
      vos_mem_free(pP2pContext->DiscoverReqIeField);
      pP2pContext->DiscoverReqIeLength = 0;
      pP2pContext->DiscoverReqIeField = NULL;
   }

   if (pDiscoverRequest->uIELen)
   {
      pP2pContext->DiscoverReqIeField = (tANI_U8 *)vos_mem_malloc(pDiscoverRequest->uIELen);
      vos_mem_copy((tANI_U8 *)pP2pContext->DiscoverReqIeField, pDiscoverRequest->pIEField, pDiscoverRequest->uIELen);
      pP2pContext->DiscoverReqIeLength = pDiscoverRequest->uIELen;
   } 
   else
   {
      pP2pContext->DiscoverReqIeLength = 0;
   }

   vos_mem_zero(&filter, sizeof(filter));

   do
   {
      if (pDiscoverRequest->uNumDeviceFilters)
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s directed\n", __FUNCTION__);
         fDirect = TRUE;
         uNumDeviceFilters = pDiscoverRequest->uNumDeviceFilters;

         pP2pContext->uDiscoverTimeout = pP2pContext->uDiscoverTimeout;
         pP2pContext->uNumDeviceFilters = pDiscoverRequest->uNumDeviceFilters;
         if(pP2pContext->uNumDeviceFilterAllocated < pDiscoverRequest->uNumDeviceFilters)
         {
            if(pP2pContext->directedDiscoveryFilter)
            {
               pP2pContext->uNumDeviceFilterAllocated = 0;
               vos_mem_free(pP2pContext->directedDiscoveryFilter);
               pP2pContext->directedDiscoveryFilter = NULL;
            }
            pP2pContext->directedDiscoveryFilter = (tp2pDiscoverDeviceFilter *)
                  vos_mem_malloc(sizeof(tp2pDiscoverDeviceFilter) * uNumDeviceFilters);
            if(NULL == pP2pContext->directedDiscoveryFilter)
            {
               VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
                  "%s fail to allocate memory for discoverFilter", __FUNCTION__);
               status = eHAL_STATUS_RESOURCES;
               break;
            }
            pP2pContext->uNumDeviceFilterAllocated = uNumDeviceFilters;
         }

         pDeviceFilters = pDiscoverRequest->pDeviceFilters;
         if(NULL != pDeviceFilters)
         {
            vos_mem_copy ( pP2pContext->directedDiscoveryFilter, pDeviceFilters,
                              sizeof(tp2pDiscoverDeviceFilter) * uNumDeviceFilters);

            if(!HAL_STATUS_SUCCESS(status = p2pGetResultFilter(pP2pContext, &filter)))
            {
               VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
                  "%s fail to create filter", __FUNCTION__);
               break;
            }
         }//if(NULL != pDeviceFilters)

         status = csrScanGetResult(pMac, SessionID, &filter, &hScanResult);
         if (hScanResult)
         {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
               "%s calling p2pDiscoverCompleteCallback\n", __FUNCTION__);
            if (callback)
            {
               callback(hHal, pContext, eP2P_DIRECTED_DISCOVER);

            }       
            status =  eHAL_STATUS_SUCCESS;
            break;
         }
         else
         {
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
               "%s Directed find did not find BSSID in cache\n", __FUNCTION__);
            pP2pContext->formationReq.targetListenChannel = 0;
            if (pDiscoverRequest->uNumDeviceFilters == 1 && filter.BSSIDs.numOfBSSIDs == 1)
            {
               vos_mem_copy(&pP2pContext->formationReq.deviceAddress, 
                              pDiscoverRequest->pDeviceFilters->DeviceID, P2P_MAC_ADDRESS_LEN);
            }
         }
      }

      pP2pContext->p2pDiscoverCBFunc = callback;
      pP2pContext->pContext          = pContext;
      pP2pContext->directedDiscovery = fDirect;
      if(!pP2pContext->GroupFormationPending)
      {
         p2pFsm(&pMac->p2pContext[SessionID], eP2P_TRIGGER_DEVICE_MODE_DEVICE);
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, 
               "%s while group formation", __FUNCTION__);
      }

      pP2pContext->uDiscoverTimeout = pDiscoverRequest->uDiscoverTimeout;
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s Start discover", __FUNCTION__);
      status = palTimerStart(pMac->hHdd, pP2pContext->discoverTimer, 
                     pP2pContext->uDiscoverTimeout * 1000, eANI_BOOLEAN_FALSE);
      if(!HAL_STATUS_SUCCESS(status))
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
            "%s failt to start discover timer", __FUNCTION__);
            pP2pContext->p2pDiscoverCBFunc = NULL;
            pP2pContext->pContext          = NULL;
            if(callback)
            {
               callback(pMac, pContext, eP2P_DISCOVER_FAILURE);
            }
      }
   }while(0);

   if(filter.SSIDs.SSIDList)
   {
      vos_mem_free(filter.SSIDs.SSIDList);
   }
   if( hScanResult )
   {
      sme_ScanResultPurge( pMac, hScanResult );
   }
   if( filter.BSSIDs.bssid )
   {
      vos_mem_free(filter.BSSIDs.bssid);
   }

   return status;
}

eHalStatus p2pScanRequest(tp2pContext *p2pContext, p2pDiscoverCompleteCallback callback, void *pContext)
{
   tCsrScanRequest scanRequest;
   v_U32_t scanId = 0;
   tANI_U32 len = 0;
   tCsrSSIDInfo wcSSID = { {P2P_WILDCARD_SSID_LEN, P2P_WILDCARD_SSID}, 0, 0 };
   tANI_U8 Channel; 
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tP2P_OperatingChannel p2pOperatingChannel;
   tpAniSirGlobal pMac = PMAC_STRUCT(p2pContext->hHal);
   tANI_U8 *p2pIe = NULL;
   tANI_U32 p2pIeLen;

   vos_mem_zero( &scanRequest, sizeof(scanRequest));

   P2P_GetOperatingChannel(p2pContext->hHal, p2pContext->sessionId, &p2pOperatingChannel);
   Channel = p2pOperatingChannel.channel;
   
   if (Channel)
   {
      scanRequest.ChannelInfo.numOfChannels = 1;      
      scanRequest.ChannelInfo.ChannelList = &Channel;
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s Scan on channel %d p2pContext->sessionId %d\n", 
                  __FUNCTION__, Channel, p2pContext->sessionId);
   }
   else
   {
       getChannelInfo(p2pContext, &scanRequest.ChannelInfo, WFD_DISCOVER_TYPE_AUTO);
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s Scan on all channels\n", 
                  __FUNCTION__);
   }

   /* set the scan type to active */
   scanRequest.scanType = eSIR_ACTIVE_SCAN;

   vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );

   scanRequest.requestType = eCSR_SCAN_P2P_FIND_PEER;
   /* set min and max channel time to zero */
   scanRequest.minChnTime = 30;
   scanRequest.maxChnTime = 100;

   /* set BSSType to default type */
   scanRequest.BSSType = eCSR_BSS_TYPE_ANY;

   scanRequest.SSIDs.numOfSSIDs = 1;
   scanRequest.SSIDs.SSIDList = &wcSSID;
   scanRequest.p2pSearch = VOS_FALSE;
       
   P2P_GetIE(p2pContext, p2pContext->sessionId, eP2P_GROUP_ID, &p2pIe, &p2pIeLen);
   vos_mem_copy(scanRequest.bssid, ((tP2PGroupId *)p2pIe)->deviceAddress, P2P_MAC_ADDRESS_LEN);

   P2P_GetIE(p2pContext, p2pContext->sessionId, eP2P_PROBE_REQ,  &scanRequest.pIEField, &len);

   scanRequest.uIEFieldLen = len;

   status = csrScanRequest( p2pContext->hHal, p2pContext->SMEsessionId, &scanRequest, &scanId, callback, pContext );

   if(scanRequest.pIEField)
   {
      vos_mem_free(scanRequest.pIEField);
   }

   if(p2pIe)
   {
      vos_mem_free(p2pIe);
   }
   return status;
}

tANI_U8 getP2PSessionIdFromSMESessionId(tHalHandle hHal, tANI_U8 SessionID)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   tANI_U8 num_session;

   for (num_session = 0; num_session < MAX_NO_OF_P2P_SESSIONS; num_session++)
   {
      if(SessionID == pMac->p2pContext[num_session].SMEsessionId)
      {
         return pMac->p2pContext[num_session].sessionId;
      }
   }
   
   return CSR_SESSION_ID_INVALID;
}


/* SessionID is HDD session id, not SME sessionId*/
eHalStatus p2pCloseSession(tHalHandle hHal, tANI_U8 SessionID)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   tp2pContext *pContext = &pMac->p2pContext[SessionID];

   pContext->SMEsessionId = CSR_SESSION_ID_INVALID;
   p2pResetContext(pContext);

   return eHAL_STATUS_SUCCESS;
}


eHalStatus p2pSetSessionId(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 SmeSessionId)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   pMac->p2pContext[SessionID].sessionId = SessionID;
   pMac->p2pContext[SessionID].SMEsessionId = SmeSessionId;

   return eHAL_STATUS_SUCCESS;
}

static tANI_BOOLEAN p2pIsGOportEnabled(tpAniSirGlobal pMac)
{

   tANI_U8 num_session = 0;

   for (num_session = 0; num_session < MAX_NO_OF_P2P_SESSIONS ; num_session++)
   {
      if (pMac->p2pContext[num_session].operatingmode == OPERATION_MODE_P2P_GROUP_OWNER)
      {
         return eANI_BOOLEAN_TRUE;
      }
   }

   return eANI_BOOLEAN_FALSE;
}

tANI_BOOLEAN p2pIsOperatingChannEqualListenChann(tHalHandle hHal, tANI_U8 SessionID)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   if(pMac->p2pContext[SessionID].P2POperatingChannel == pMac->p2pContext[SessionID].P2PListenChannel)
   {
      return eANI_BOOLEAN_TRUE;
   }

   return eANI_BOOLEAN_FALSE;
}

eHalStatus p2pGetListenChannel(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 *channel)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);

   *channel = pMac->p2pContext[SessionID].P2PListenChannel;
  
   return eHAL_STATUS_SUCCESS;
}

eHalStatus p2pSetListenChannel(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 channel)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   tP2P_OperatingChannel p2pListenChannel;
   eHalStatus status = eHAL_STATUS_SUCCESS;

   if(csrRoamIsChannelValid(pMac, channel))
   {
      pMac->p2pContext[SessionID].P2PListenChannel = channel;
      p2pGetListenChannelAttrib(pMac, pMac->p2pContext[SessionID].sessionId, &p2pListenChannel);
      p2pListenChannel.channel = channel;
      p2pUpdateListenChannelAttrib(pMac, pMac->p2pContext[SessionID].sessionId, &p2pListenChannel);
   }
   else
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, 
         " %s fail with invalid channel %d", __FUNCTION__, channel);
      status = eHAL_STATUS_INVALID_PARAMETER;
   }
  
   return status;
}



eHalStatus p2pStopDiscovery(tHalHandle hHal, tANI_U8 SessionID)
{
   tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
   eHalStatus status = eHAL_STATUS_SUCCESS;

   status = palTimerStop(pMac->hHdd, pMac->p2pContext[SessionID].discoverTimer);
   if (status != eHAL_STATUS_SUCCESS)
   {
      VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s Timer Stop status %d\n",  __FUNCTION__, status);
      return status;
   }

   VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Timer Stop status %d\n",  __FUNCTION__, status);
   p2pCallDiscoverCallback(&pMac->p2pContext[SessionID],  eP2P_DIRECTED_DISCOVER);

   status = p2pFsm( &pMac->p2pContext[SessionID], eP2P_TRIGGER_DISCONNECTED );

   return status;
}

//Purge P2P device/GO from the list
eHalStatus p2pPurgeDeviceList(tpAniSirGlobal pMac, tDblLinkList *pList)
{
   eHalStatus status = eHAL_STATUS_SUCCESS;
   tListElem *pEntry, *pNext;
   tCsrScanResult *pBssResult;
   tDot11fBeaconIEs *pIes;
    
   csrLLLock(pList);
   
   pEntry = csrLLPeekHead(pList, LL_ACCESS_NOLOCK);
   while( NULL != pEntry )
   {
      pNext = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK);
      pBssResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link );
      pIes = NULL;
      if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pBssResult->Result.BssDescriptor, &pIes)))
      {
         VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
            " %s fail to parse IEs. pEntry (0x%X)",
            __FUNCTION__, pEntry);
         pEntry = pNext;
         continue;
      }
      if( pIes->P2PBeaconProbeRes.present )
      {
         //Found a P2P BSS
         if(csrLLRemoveEntry(pList, pEntry, LL_ACCESS_NOLOCK) )
         {
            csrFreeScanResultEntry( pMac, pBssResult );
         }
      }
      palFreeMemory(pMac->hHdd, pIes);
      pEntry = pNext;
   }

   csrLLUnlock(pList);

   return (status);
}


eHalStatus sme_p2pFlushDeviceList(tHalHandle hHal, tANI_U8 HDDSessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
   tp2pContext *pP2pContext = &pMac->p2pContext[HDDSessionId];

   smsLog(pMac, LOG2, FL("enter"));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      status = p2pPurgeDeviceList(pMac, &pMac->scan.scanResultList[pP2pContext->SMEsessionId]);
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}


eHalStatus sme_p2pResetSession(tHalHandle hHal, tANI_U8 HDDSessionId)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   smsLog(pMac, LOG2, FL("enter"));
   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if(MAX_NO_OF_P2P_SESSIONS > HDDSessionId)
      {
         p2pResetContext(&pMac->p2pContext[HDDSessionId]);
         status = eHAL_STATUS_SUCCESS;
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return (status);
}



eHalStatus sme_p2pGetResultFilter(tHalHandle hHal, tANI_U8 HDDSessionId,
                              tCsrScanResultFilter *pFilter)
{
   eHalStatus status = eHAL_STATUS_FAILURE;
   tpAniSirGlobal pMac = PMAC_STRUCT( hHal );

   status = sme_AcquireGlobalLock( &pMac->sme );
   if ( HAL_STATUS_SUCCESS( status ) )
   {
      if(MAX_NO_OF_P2P_SESSIONS > HDDSessionId)
      {
         status = p2pGetResultFilter(&pMac->p2pContext[HDDSessionId], pFilter);
      }
      sme_ReleaseGlobalLock( &pMac->sme );
   }

   return status;
}



#endif //WLAN_FEATURE_P2P_INTERNAL

eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd)
{
    tpP2pPsConfig pNoA;
    tSirMsgQ msg;
    eHalStatus status = eHAL_STATUS_SUCCESS;

    status = palAllocateMemory(pMac->hHdd, (void**)&pNoA, sizeof(tP2pPsConfig));
    if(HAL_STATUS_SUCCESS(status))
    {
        palZeroMemory(pMac->hHdd, pNoA, sizeof(tP2pPsConfig));
        pNoA->opp_ps = pNoACmd->u.NoACmd.NoA.opp_ps;
        pNoA->ctWindow = pNoACmd->u.NoACmd.NoA.ctWindow;
        pNoA->duration = pNoACmd->u.NoACmd.NoA.duration;
        pNoA->interval = pNoACmd->u.NoACmd.NoA.interval;
        pNoA->count = pNoACmd->u.NoACmd.NoA.count;
        pNoA->single_noa_duration = pNoACmd->u.NoACmd.NoA.single_noa_duration;
        pNoA->psSelection = pNoACmd->u.NoACmd.NoA.psSelection;
        pNoA->sessionid = pNoACmd->u.NoACmd.NoA.sessionid;
        msg.type = eWNI_SME_UPDATE_NOA;
        msg.bodyval = 0;
        msg.bodyptr = pNoA;
        limPostMsgApi(pMac, &msg);
    }   
    return status;
}




#endif //WLAN_FEATURE_P2P
