/*
 * Copyright (C) 2010 NXP Semiconductors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*!
 * \file phLibNfc.c

 * Project: NFC FRI / HALDL
 *
 * $Date: Tue Jun  1 14:53:48 2010 $
 * $Author: ing07385 $
 * $Revision: 1.89 $
 * $Aliases: NFC_FRI1.1_WK1024_SDK $
 *
 */


/*
************************* Header Files ****************************************
*/

#include <phLibNfc.h>
#include <phDal4Nfc.h>
#include <phHal4Nfc.h>
#include <phOsalNfc.h>
#include <phLibNfc_Internal.h>
#include <phLibNfc_ndef_raw.h>
#include <phLibNfc_initiator.h>
#include <phLibNfc_discovery.h>
#include <phNfcStatus.h>
#include <cutils/log.h>
/*
*************************** Macro's  ******************************************
*/

#ifndef STATIC_DISABLE
#define STATIC static
#else
#define STATIC
#endif


/*
*************************** Global Variables **********************************
*/


pphLibNfc_LibContext_t gpphLibContext=NULL;

/*
*************************** Static Function Declaration ***********************
*/

/* Init callback */
STATIC void phLibNfc_InitCb(void *pContext,NFCSTATUS status);

/* Shutdown callback */
STATIC void phLibNfc_ShutdownCb(void *pContext,NFCSTATUS status);

/**Default notification handler registered with lower layer immediately after 
   successful initialization*/
STATIC void phLibNfc_DefaultHandler(
                                void                        *context,                                 
                                phHal_eNotificationType_t    type,
                                phHal4Nfc_NotificationInfo_t info,
                                NFCSTATUS                    status
                                );
/*
*************************** Function Definitions ******************************
*/

NFCSTATUS phLibNfc_Mgt_ConfigureDriver (pphLibNfc_sConfig_t     psConfig,
                                        void **                 ppDriverHandle)
{
    if(NULL != gpphLibContext)
    {
        return NFCSTATUS_ALREADY_INITIALISED;
    }   

    return phDal4Nfc_Config(psConfig, ppDriverHandle);
}

NFCSTATUS phLibNfc_Mgt_UnConfigureDriver (void *                 pDriverHandle)
{
    if(NULL != gpphLibContext)
    {
        return NFCSTATUS_ALREADY_INITIALISED;
    }   

   return phDal4Nfc_ConfigRelease(pDriverHandle);
}

NFCSTATUS phLibNfc_HW_Reset ()
{
    NFCSTATUS Status = NFCSTATUS_SUCCESS;

    Status = phDal4Nfc_Reset(0);
    Status = phDal4Nfc_Reset(1);

    return Status;
}

NFCSTATUS phLibNfc_Download_Mode ()
{
   return phDal4Nfc_Download();
}


extern uint8_t nxp_nfc_isoxchg_timeout;
NFCSTATUS phLibNfc_SetIsoXchgTimeout(uint8_t timeout) {
    nxp_nfc_isoxchg_timeout = timeout;
    return NFCSTATUS_SUCCESS;
}

extern uint32_t nxp_nfc_hci_response_timeout;
NFCSTATUS phLibNfc_SetHciTimeout(uint32_t timeout_in_ms) {
    nxp_nfc_hci_response_timeout = timeout_in_ms;
    return NFCSTATUS_SUCCESS;
}

/**
*    Initialize the phLibNfc interface.
*/

NFCSTATUS phLibNfc_Mgt_Initialize(void                *pDriverHandle,
                                 pphLibNfc_RspCb_t    pInitCb,
                                 void                 *pContext)
{
     NFCSTATUS Status = NFCSTATUS_SUCCESS;     
     if((NULL == pDriverHandle)||(NULL == pInitCb))
     {
        Status = NFCSTATUS_INVALID_PARAMETER;
     }
     else if(NULL == gpphLibContext)
     {
        /* Initialize the Lib context */
        gpphLibContext=(pphLibNfc_LibContext_t)phOsalNfc_GetMemory(
                                        (uint32_t)sizeof(phLibNfc_LibContext_t));
        if(NULL == gpphLibContext)
        {
            Status=NFCSTATUS_INSUFFICIENT_RESOURCES;
        }
        else
        {
            (void)memset((void *)gpphLibContext,0,(
                                    (uint32_t)sizeof(phLibNfc_LibContext_t)));

            /* Store the Callback and context in LibContext structure*/
            gpphLibContext->CBInfo.pClientInitCb=pInitCb;
            gpphLibContext->CBInfo.pClientInitCntx=pContext;
            /* Initialize the HwReferece structure */
            gpphLibContext->psHwReference=(phHal_sHwReference_t *)
                                    phOsalNfc_GetMemory((uint32_t)sizeof(phHal_sHwReference_t));
            (void)memset((void *)gpphLibContext->psHwReference,0,
                                        ((uint32_t)sizeof(phHal_sHwReference_t)));
            /* Allocate the Memory for the Transceive info */
            if( gpphLibContext->psHwReference!=NULL)
            {
                gpphLibContext->psHwReference->p_board_driver = pDriverHandle;
                Status = phLibNfc_UpdateNextState(gpphLibContext,
                                            eLibNfcHalStateInitandIdle);
                if(Status==NFCSTATUS_SUCCESS)
                {
                    Status=phHal4Nfc_Open(
                                    gpphLibContext->psHwReference,
                                    eInitDefault,
                                    phLibNfc_InitCb,
                                    (void *)gpphLibContext);
                }
            }
            else
            {
                Status = NFCSTATUS_INSUFFICIENT_RESOURCES;
            }
            phLibNfc_Ndef_Init();
        }
    }
    else if(gpphLibContext->LibNfcState.next_state==eLibNfcHalStateShutdown)
    {
        Status = NFCSTATUS_SHUTDOWN;
    }
    else
    {
        Status=NFCSTATUS_ALREADY_INITIALISED;
    }
   return Status;
}

/*
 * This function called by the HAL4 when the initialization seq is completed.
 */
STATIC void phLibNfc_InitCb(void *pContext,NFCSTATUS status)
{
    pphLibNfc_LibContext_t   pLibContext=NULL;
    pphLibNfc_RspCb_t          pClientCb=NULL;
    void                        *pUpperLayerContext=NULL;


    /* Initialize the local variable */
    pLibContext  = (pphLibNfc_LibContext_t)pContext;

    pClientCb =pLibContext->CBInfo.pClientInitCb;
    pUpperLayerContext=pLibContext->CBInfo.pClientInitCntx;
    if(status == NFCSTATUS_SUCCESS)
    {
        /* Get the Lib context */
        pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;
        gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeOff;
        if(pLibContext->psHwReference->uicc_connected==TRUE)
        {
            /* populate state of the secured element */
            gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeDefault;
            sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState=phLibNfc_SE_Active;
            pLibContext->sSeContext.uUiccActivate=TRUE;
        }		
        if(pLibContext->psHwReference->smx_connected==TRUE)
        {
            /* populate state of the secured element */
            gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeDefault;
            sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState=phLibNfc_SE_Inactive; 
            pLibContext->sSeContext.uSmxActivate =FALSE;
        }

        phLibNfc_UpdateCurState(status,pLibContext);
        (void)phHal4Nfc_RegisterNotification(                                            
                                pLibContext->psHwReference,
                                eRegisterDefault,
                                phLibNfc_DefaultHandler,
                                (void*)pLibContext
                                ); 
        /* call the upper layer register function */
        (*pClientCb)(pUpperLayerContext,status);

    }
    else
    {
        /*Change the status code failed*/
        status = NFCSTATUS_FAILED;
        /* Get the Lib context */
        pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;

        phLibNfc_UpdateCurState(status,pLibContext);



        /* Allocate the Memory for the Transceive info */
        if(pLibContext->psHwReference!= NULL)
        {
            phOsalNfc_FreeMemory(pLibContext->psHwReference);
            pLibContext->psHwReference = NULL;
        }
        (*pClientCb)(pUpperLayerContext, status);

        phOsalNfc_FreeMemory(pLibContext);
        pLibContext= NULL;
        gpphLibContext = NULL;
        
    }
    return;
}

/**Default notification handler registered with lower layer immediately after 
   successful initialization*/
STATIC void phLibNfc_DefaultHandler(
                                void                        *context,                                 
                                phHal_eNotificationType_t    type,
                                phHal4Nfc_NotificationInfo_t info,
                                NFCSTATUS                    status
                                )
{
    if(context != (void *)gpphLibContext)
    {
        phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
    }
    else
    {
        info = info;
        if((NFC_EVENT_NOTIFICATION == type) &&
            (NFCSTATUS_BOARD_COMMUNICATION_ERROR == status))
        {
            phLibNfc_UpdateCurState(NFCSTATUS_FAILED,gpphLibContext);
            phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
        }
    }
    return;
}
/**
* De-Initialize the LIB NFC.
*/
NFCSTATUS phLibNfc_Mgt_DeInitialize(void *                      pDriverHandle,
                                   pphLibNfc_RspCb_t            pDeInitCb,
                                   void*                        pContext
                                   )
{
    NFCSTATUS Status = NFCSTATUS_SUCCESS;
    pphLibNfc_LibContext_t pLibContext = gpphLibContext;
    if(NULL==pDriverHandle)
    {
        /*Check for valid parameters */
        Status = NFCSTATUS_INVALID_PARAMETER;
    }
    else if((pLibContext==NULL)
        || (pLibContext->LibNfcState.cur_state
            == eLibNfcHalStateShutdown))
    {   /*Lib Nfc not initlized*/
        Status = NFCSTATUS_NOT_INITIALISED;
    }
    else
    {
        if(pDeInitCb==NULL)
        {
            phHal4Nfc_Hal4Reset(pLibContext->psHwReference,(void *)pLibContext);
            if(pLibContext->psHwReference!=NULL)
            {
                phOsalNfc_FreeMemory(pLibContext->psHwReference);
                pLibContext->psHwReference = NULL;
            }
            /*Free the memory allocated during NDEF read,write
              and NDEF formatting*/
            phLibNfc_Ndef_DeInit();
            phOsalNfc_FreeMemory(pLibContext);
            gpphLibContext=NULL;
            pLibContext= NULL;
        }
        else
        {
            if (NULL!= pLibContext->CBInfo.pClientShutdownCb)
            {
                /* Previous callback pending */
                Status = NFCSTATUS_BUSY;
            }
          Status = NFCSTATUS_PENDING;
          if(TRUE != pLibContext->status.GenCb_pending_status)
          {
              Status = phHal4Nfc_Close(pLibContext->psHwReference,
                                  phLibNfc_ShutdownCb,
                                  (void *)pLibContext);
          }
          if(Status== NFCSTATUS_PENDING)
          {
              pLibContext->CBInfo.pClientShutdownCb = pDeInitCb;
              pLibContext->CBInfo.pClientShtdwnCntx = pContext;
              pLibContext->status.GenCb_pending_status=TRUE;
              pLibContext->LibNfcState.next_state= eLibNfcHalStateShutdown;
          }
          else
          {
              Status =NFCSTATUS_FAILED;
          }
        }       
    }
    return Status;
}
/* shutdown callback -
  Free the allocated memory here */
STATIC void phLibNfc_ShutdownCb(void *pContext,NFCSTATUS status)
{
    pphLibNfc_RspCb_t           pClientCb=NULL;
    void                        *pUpperLayerContext=NULL;
    pphLibNfc_LibContext_t      pLibContext=NULL;

    PHNFC_UNUSED_VARIABLE(pContext);
    /* Get the Lib context */
    pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;

    if(pLibContext == NULL)
    {
        status = NFCSTATUS_FAILED;
    }
    else
    {
        /* Initialize the local variable */
        pClientCb =pLibContext->CBInfo.pClientShutdownCb;
        pUpperLayerContext=pLibContext->CBInfo.pClientShtdwnCntx;
        if(status == NFCSTATUS_SUCCESS)
        {
            pLibContext->LibNfcState.cur_state = eLibNfcHalStateShutdown;
            phLibNfc_UpdateCurState(status,pLibContext);

            pLibContext->status.GenCb_pending_status=FALSE;
            
            /* Allocate the Memory for the Transceive info */
            if(pClientCb!=NULL)
            {
                (*pClientCb)(pUpperLayerContext, status);
            }
            if(pLibContext->psHwReference!=NULL)
            {
                phOsalNfc_FreeMemory(pLibContext->psHwReference);
                pLibContext->psHwReference = NULL;
            }
            if(NULL != gpphLibContext->psBufferedAuth)
            {
                if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
                {
                    phOsalNfc_FreeMemory(
                        gpphLibContext->psBufferedAuth->sRecvData.buffer);
                }
                if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
                {
                    phOsalNfc_FreeMemory(
                        gpphLibContext->psBufferedAuth->sSendData.buffer);
                }
                phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
                gpphLibContext->psBufferedAuth = NULL;
            }
            /*Free the memory allocated during NDEF read,write
              and NDEF formatting*/
            phLibNfc_Ndef_DeInit();        
                phOsalNfc_FreeMemory(pLibContext);
                gpphLibContext=NULL;
                pLibContext= NULL;
       
        }
        else
        {
            /* shutdown sequence failed by HAL 4 */
            status= NFCSTATUS_FAILED;
            pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;
            phLibNfc_UpdateCurState(status,pLibContext);
            pLibContext->status.GenCb_pending_status=FALSE;
            if(pClientCb!=NULL)
            {
                (*pClientCb)(pUpperLayerContext,status);
            }
        }
    }
}
/**
*    Pending shutdown call.
*/


void phLibNfc_Pending_Shutdown(void)
{
    NFCSTATUS RetStatus = NFCSTATUS_SUCCESS ;
    gpphLibContext->status.GenCb_pending_status = FALSE;
    RetStatus = phHal4Nfc_Close(
                        gpphLibContext->psHwReference,
                        phLibNfc_ShutdownCb,
                        (void *)gpphLibContext);
    PHNFC_UNUSED_VARIABLE(RetStatus);
    return;
}


/**
* Reset the LIB NFC.
*/
NFCSTATUS phLibNfc_Mgt_Reset(void  *pContext)
{
    NFCSTATUS Status = NFCSTATUS_SUCCESS;
    phLibNfc_LibContext_t   *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)pContext;

    if((pLibNfc_Ctxt == NULL)
        || (gpphLibContext->LibNfcState.cur_state
            == eLibNfcHalStateShutdown))
    {   /*Lib Nfc not initlized*/
        Status = NFCSTATUS_NOT_INITIALISED;
    }  
    else if(NULL == pContext) 
    {
        Status = NFCSTATUS_INVALID_PARAMETER;
    }
    /* Check for valid state,If De initialize is called then
    return NFCSTATUS_SHUTDOWN */
    else if(gpphLibContext->LibNfcState.next_state
                            == eLibNfcHalStateShutdown)
    {
        Status = NFCSTATUS_SHUTDOWN;
    }
    else
    {                     
        /*Reset all callback status*/
        (void) memset(&(gpphLibContext->RegNtfType),0,
                        sizeof(phLibNfc_Registry_Info_t));
        (void) memset(&(gpphLibContext->sADDconfig),0,
                        sizeof(phLibNfc_sADD_Cfg_t));
        (void) memset(&(gpphLibContext->ndef_cntx),0,
                        sizeof(phLibNfc_NdefInfo_t));
        (void) memset(&(gpphLibContext->sNfcIp_Context),0,
                        sizeof(phLibNfc_NfcIpInfo_t));
        (void) memset(&(gpphLibContext->sCardEmulCfg),0,
                        sizeof(phHal_sEmulationCfg_t));
        (void) memset(&(gpphLibContext->Discov_handle),0,
                        MAX_REMOTE_DEVICES);

        /*Free memory allocated for NDEF records*/
        if(NULL != gpphLibContext->psBufferedAuth)
        {
            if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
            {
                phOsalNfc_FreeMemory(
                    gpphLibContext->psBufferedAuth->sRecvData.buffer);
                gpphLibContext->psBufferedAuth->sRecvData.buffer = NULL;
            }
            if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
            {
                phOsalNfc_FreeMemory(
                    gpphLibContext->psBufferedAuth->sSendData.buffer);
                gpphLibContext->psBufferedAuth->sSendData.buffer = NULL;
            }
            phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
            gpphLibContext->psBufferedAuth = NULL;
        }
        if(NULL != gpphLibContext->psTransInfo)
        {
            phOsalNfc_FreeMemory(gpphLibContext->psTransInfo);
            gpphLibContext->psTransInfo = NULL;
        }
        if(NULL != gpphLibContext->ndef_cntx.psNdefMap)
        {
            if(NULL != gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf)
            {
                phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf);
                gpphLibContext->ndef_cntx.psNdefMap->SendRecvBuf = NULL;
            }
            phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.psNdefMap);
            gpphLibContext->ndef_cntx.psNdefMap = NULL;
        }
        if(NULL != gpphLibContext->psOverHalCtxt)
        {
            phOsalNfc_FreeMemory(gpphLibContext->psOverHalCtxt);
            gpphLibContext->psTransInfo = NULL;
        }
        if(NULL != gpphLibContext->psDevInputParam)
        {
            phOsalNfc_FreeMemory(gpphLibContext->psDevInputParam);
            gpphLibContext->psDevInputParam = NULL;
        }
        if(NULL != gpphLibContext->ndef_cntx.ndef_fmt)
        {
            phOsalNfc_FreeMemory(gpphLibContext->ndef_cntx.ndef_fmt);
            gpphLibContext->ndef_cntx.ndef_fmt = NULL;
        }
        if(NULL != pNdefRecord) 
        {
            if(NULL != pNdefRecord->Id)
            {
                phOsalNfc_FreeMemory(pNdefRecord->Id);
                pNdefRecord->Id = NULL;
            }
            if(NULL != pNdefRecord->Type)
            {
                phOsalNfc_FreeMemory(pNdefRecord->Type);
                pNdefRecord->Type = NULL;
            }
            if(NULL != pNdefRecord->PayloadData)
            {
                phOsalNfc_FreeMemory(pNdefRecord->PayloadData);
                pNdefRecord->PayloadData = NULL;
            }
        }
        if(NULL != NdefInfo.pNdefRecord)
        {
            phOsalNfc_FreeMemory(NdefInfo.pNdefRecord);
            NdefInfo.pNdefRecord = NULL;
        }          
        if(NULL != gpphLibContext->phLib_NdefRecCntx.NdefCb)
        {
            phOsalNfc_FreeMemory(gpphLibContext->phLib_NdefRecCntx.NdefCb);
            gpphLibContext->phLib_NdefRecCntx.NdefCb = NULL;
        }
        if(NULL != gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer)
        {
            phOsalNfc_FreeMemory(gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer);
            gpphLibContext->phLib_NdefRecCntx.ndef_message.buffer = NULL;
        }
        /* No device is connected */
        gpphLibContext->Connected_handle = 0x00;       
        gpphLibContext->Prev_Connected_handle = 0x00;
        gpphLibContext->ReleaseType = NFC_INVALID_RELEASE_TYPE;        
        gpphLibContext->eLibNfcCfgMode = NFC_DISCOVERY_STOP;
        /*Lib Nfc Stack is initilized and in idle state*/
        gpphLibContext->LibNfcState.cur_state = eLibNfcHalStateInitandIdle;

        /* Reset all callback status */
        gpphLibContext->CBInfo.pClientCkNdefCb = NULL;
        gpphLibContext->CBInfo.pClientCkNdefCntx = NULL;
        gpphLibContext->CBInfo.pClientConCntx = NULL;
        gpphLibContext->CBInfo.pClientConnectCb = NULL;
        gpphLibContext->CBInfo.pClientDConCntx = NULL;
        gpphLibContext->CBInfo.pClientDisCfgCntx = NULL;
        gpphLibContext->CBInfo.pClientDisConfigCb = NULL;
        gpphLibContext->CBInfo.pClientInitCb = NULL;
        gpphLibContext->CBInfo.pClientInitCntx = gpphLibContext;
        gpphLibContext->CBInfo.pClientNdefNtfRespCb = NULL;
        gpphLibContext->CBInfo.pClientNdefNtfRespCntx = NULL;
        gpphLibContext->CBInfo.pClientNtfRegRespCB = NULL;
        gpphLibContext->CBInfo.pClientNtfRegRespCntx = NULL;
        gpphLibContext->CBInfo.pClientPresChkCb = NULL;
        gpphLibContext->CBInfo.pClientPresChkCntx = NULL;
        gpphLibContext->CBInfo.pClientRdNdefCb = NULL;
        gpphLibContext->CBInfo.pClientRdNdefCntx = NULL;
        gpphLibContext->CBInfo.pClientShtdwnCntx = NULL;
        gpphLibContext->CBInfo.pClientShutdownCb = NULL;
        gpphLibContext->CBInfo.pClientTransceiveCb = NULL;
        gpphLibContext->CBInfo.pClientTranseCntx = NULL;
        gpphLibContext->CBInfo.pClientWrNdefCb = NULL;
        gpphLibContext->CBInfo.pClientWrNdefCntx = NULL;
        gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = NULL;
        gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = NULL;
        gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL;
        gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = NULL;
        gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL;
        gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = NULL;
        gpphLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb = NULL;
        gpphLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt = NULL;
        gpphLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb = NULL;
        gpphLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCtxt = NULL;
        /*No callback is pending*/
        gpphLibContext->status.GenCb_pending_status = FALSE;        
                    
    }
    return Status;
}
/**
*    LibNfc state machine next state update.
*/

NFCSTATUS
phLibNfc_UpdateNextState(
                         pphLibNfc_LibContext_t   pLibContext,
                         phLibNfc_State_t        next_state
                         )
{
    NFCSTATUS       status = NFCSTATUS_INVALID_STATE;
    switch(pLibContext->LibNfcState.cur_state)
    {
    case eLibNfcHalStateShutdown:
        {
            switch(next_state)
            {
            case eLibNfcHalStateShutdown:
            case eLibNfcHalStateInitandIdle:
                status = NFCSTATUS_SUCCESS;
                break;
            default:
                break;
            }
        }
        break;
    case eLibNfcHalStateConfigReady:
        {
            switch(next_state)
            {
            case eLibNfcHalStateShutdown:
            case eLibNfcHalStateConfigReady:
            case eLibNfcHalStateInitandIdle:
            case eLibNfcHalStateConnect:
                status = NFCSTATUS_SUCCESS;
                break;
            default:
                break;
            }
        }
        break;
    case eLibNfcHalStateConnect:
        {
            switch(next_state)
            {
            case eLibNfcHalStateShutdown:
            case eLibNfcHalStateRelease:
            case eLibNfcHalStateTransaction:
            case eLibNfcHalStatePresenceChk:
                status = NFCSTATUS_SUCCESS;
                break;
            default:
                break;
            }
        }
        break;
    case eLibNfcHalStatePresenceChk:
        {
            switch(next_state)
            {
            case eLibNfcHalStateShutdown:
            case eLibNfcHalStateConfigReady:
            case eLibNfcHalStateRelease:
            case eLibNfcHalStateTransaction:
            case eLibNfcHalStatePresenceChk:
                status = NFCSTATUS_SUCCESS;
                break;
            default:
                break;
            }
        }
        break;
    case eLibNfcHalStateInitandIdle:
        {
            switch(next_state)
            {
            case eLibNfcHalStateShutdown:
            case eLibNfcHalStateConfigReady:
                status = NFCSTATUS_SUCCESS;
                break;
            default:
                break;
            }
        }
        break;
    default:
        break;
    }
    pLibContext->LibNfcState.next_state = 
        (uint8_t)((NFCSTATUS_SUCCESS == status)?next_state:pLibContext->LibNfcState.next_state);

    return status;
}

/**
*    LibNfc state machine current state update.
*/

void
phLibNfc_UpdateCurState(
                        NFCSTATUS      status,
                        pphLibNfc_LibContext_t psLibContext
                        )
{
    switch(psLibContext->LibNfcState.next_state)
    {
    case eLibNfcHalStateTransaction:
        psLibContext->LibNfcState.cur_state = (uint8_t)eLibNfcHalStateConnect;
        break;
    case eLibNfcHalStateRelease:
        psLibContext->LibNfcState.cur_state
            = (uint8_t)(psLibContext->status.DiscEnbl_status == TRUE?
              eLibNfcHalStateInitandIdle:eLibNfcHalStateConfigReady);
        break;
    case eLibNfcHalStateInvalid:
        break;
    default:
        psLibContext->LibNfcState.cur_state
            = (uint8_t)((NFCSTATUS_SUCCESS == status)?
            psLibContext->LibNfcState.next_state:
        psLibContext->LibNfcState.cur_state);
    }
    psLibContext->LibNfcState.next_state = (uint8_t)eLibNfcHalStateInvalid;
    return;
}
/* Interface to stack capabilities */

NFCSTATUS phLibNfc_Mgt_GetstackCapabilities(
                    phLibNfc_StackCapabilities_t *phLibNfc_StackCapabilities,
                    void                         *pContext)
{
    NFCSTATUS RetVal = NFCSTATUS_FAILED;
    /*Check Lib Nfc stack is initilized*/
    if((NULL == gpphLibContext)|| 
        (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
    {
        RetVal = NFCSTATUS_NOT_INITIALISED;
    }   
    /*Check application has sent the valid parameters*/
    else if((NULL == phLibNfc_StackCapabilities)
        || (NULL == pContext))
    {
        RetVal= NFCSTATUS_INVALID_PARAMETER;
    }   
    else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
    {
        RetVal = NFCSTATUS_SHUTDOWN;
    }
    else if(TRUE == gpphLibContext->status.GenCb_pending_status)       
    {
        /*Previous operation is pending  */
        RetVal = NFCSTATUS_BUSY;
    }    
    else
    {
        /* Tag Format Capabilities*/
        phLibNfc_StackCapabilities->psFormatCapabilities.Desfire = TRUE;
        phLibNfc_StackCapabilities->psFormatCapabilities.MifareStd = TRUE;
        phLibNfc_StackCapabilities->psFormatCapabilities.MifareUL = TRUE;
        phLibNfc_StackCapabilities->psFormatCapabilities.FeliCa = FALSE;
        phLibNfc_StackCapabilities->psFormatCapabilities.Jewel = FALSE;
        phLibNfc_StackCapabilities->psFormatCapabilities.ISO14443_4A = FALSE;
        phLibNfc_StackCapabilities->psFormatCapabilities.ISO14443_4B = FALSE;
        phLibNfc_StackCapabilities->psFormatCapabilities.MifareULC = TRUE;
         phLibNfc_StackCapabilities->psFormatCapabilities.ISO15693 = FALSE;

        /* Tag Mapping Capabilities */
        phLibNfc_StackCapabilities->psMappingCapabilities.FeliCa = TRUE;
        phLibNfc_StackCapabilities->psMappingCapabilities.Desfire = TRUE;
        phLibNfc_StackCapabilities->psMappingCapabilities.ISO14443_4A = TRUE;
        phLibNfc_StackCapabilities->psMappingCapabilities.ISO14443_4B = TRUE;
        phLibNfc_StackCapabilities->psMappingCapabilities.MifareStd = TRUE;
        phLibNfc_StackCapabilities->psMappingCapabilities.MifareUL = TRUE;
        phLibNfc_StackCapabilities->psMappingCapabilities.MifareULC = TRUE;     
        phLibNfc_StackCapabilities->psMappingCapabilities.Jewel = TRUE;
        phLibNfc_StackCapabilities->psMappingCapabilities.ISO15693 = FALSE;
        
        /*Call Hal4 Get Dev Capabilities to get info about protocols supported
          by Lib Nfc*/
        PHDBG_INFO("LibNfc:Get Stack capabilities ");
        RetVal= phHal4Nfc_GetDeviceCapabilities(                                          
                        gpphLibContext->psHwReference,                            
                        &(phLibNfc_StackCapabilities->psDevCapabilities),
                        (void *)gpphLibContext); 

        LIB_NFC_VERSION_SET(phLibNfc_StackCapabilities->psDevCapabilities.hal_version,
                            PH_HAL4NFC_VERSION,
                            PH_HAL4NFC_REVISION,
                            PH_HAL4NFC_PATCH,
                            PH_HAL4NFC_BUILD);
                
        phLibNfc_StackCapabilities->psDevCapabilities.fw_version=
            gpphLibContext->psHwReference->device_info.fw_version;
        phLibNfc_StackCapabilities->psDevCapabilities.hci_version=
            gpphLibContext->psHwReference->device_info.hci_version;
        phLibNfc_StackCapabilities->psDevCapabilities.hw_version=
            gpphLibContext->psHwReference->device_info.hw_version;
        phLibNfc_StackCapabilities->psDevCapabilities.model_id=
            gpphLibContext->psHwReference->device_info.model_id;        
        (void)memcpy(phLibNfc_StackCapabilities->psDevCapabilities.full_version,
            gpphLibContext->psHwReference->device_info.full_version,NXP_FULL_VERSION_LEN);
        
        /* Check the firmware version */
        phLibNfc_StackCapabilities->psDevCapabilities.firmware_update_info = memcmp(phLibNfc_StackCapabilities->psDevCapabilities.full_version, nxp_nfc_full_version,
                   NXP_FULL_VERSION_LEN);

        if(NFCSTATUS_SUCCESS != RetVal)
        {       
            RetVal = NFCSTATUS_FAILED;
        }
    }
    return RetVal;
}






NFCSTATUS phLibNfc_Mgt_ConfigureTestMode(void   *pDriverHandle,
                                 pphLibNfc_RspCb_t   pTestModeCb,
                                 phLibNfc_Cfg_Testmode_t eTstmode,
                                 void                *pContext)
{
     NFCSTATUS Status = NFCSTATUS_SUCCESS;  
     phHal4Nfc_InitType_t eInitType=eInitDefault;
     
     if((NULL == pDriverHandle)||(NULL == pTestModeCb))
     {
        Status = NFCSTATUS_INVALID_PARAMETER;
     }
     else if((NULL != gpphLibContext) && \
         (gpphLibContext->LibNfcState.next_state==eLibNfcHalStateShutdown))
     { 
        Status = NFCSTATUS_SHUTDOWN;
     } 
     else if( (eTstmode == phLibNfc_TstMode_On) && (NULL != gpphLibContext))
     {
        Status=NFCSTATUS_ALREADY_INITIALISED;
     }
     else if( (eTstmode == phLibNfc_TstMode_Off) && (NULL == gpphLibContext))
     {
        Status = NFCSTATUS_NOT_INITIALISED;
     }
     else if( (eTstmode == phLibNfc_TstMode_Off) && (NULL != gpphLibContext))
     {          
        if (NULL!= gpphLibContext->CBInfo.pClientShutdownCb)
        {   /* Previous callback pending */
            Status = NFCSTATUS_BUSY;
        }
        else
        {
            Status = NFCSTATUS_PENDING;
            if(TRUE != gpphLibContext->status.GenCb_pending_status)
            {
                Status = phHal4Nfc_Close(gpphLibContext->psHwReference,
                                    phLibNfc_ShutdownCb,
                                    (void *)gpphLibContext);
            }
            if(Status== NFCSTATUS_PENDING)
            {
                gpphLibContext->CBInfo.pClientShutdownCb = pTestModeCb;
                gpphLibContext->CBInfo.pClientShtdwnCntx = pContext;
                gpphLibContext->status.GenCb_pending_status=TRUE;
                gpphLibContext->LibNfcState.next_state= eLibNfcHalStateShutdown;
            }
            else
            {
                Status =NFCSTATUS_FAILED;
            }
        }       
     }
     else 
     {
            /* Initialize the Lib context */
        gpphLibContext=(pphLibNfc_LibContext_t)phOsalNfc_GetMemory(
                                        (uint32_t)sizeof(phLibNfc_LibContext_t));
        if(NULL == gpphLibContext)
        {
            Status=NFCSTATUS_INSUFFICIENT_RESOURCES;
        }
        else
        {
            (void)memset((void *)gpphLibContext,0,(
                                    (uint32_t)sizeof(phLibNfc_LibContext_t)));

            /* Store the Callback and context in LibContext structure*/
            gpphLibContext->CBInfo.pClientInitCb=pTestModeCb;
            gpphLibContext->CBInfo.pClientInitCntx=pContext;
            /* Initialize the HwReferece structure */
            gpphLibContext->psHwReference=(phHal_sHwReference_t *)
                                    phOsalNfc_GetMemory((uint32_t)sizeof(phHal_sHwReference_t));
            (void)memset((void *)gpphLibContext->psHwReference,0,
                                        ((uint32_t)sizeof(phHal_sHwReference_t)));
            /* Allocate the Memory for the Transceive info */
            if( gpphLibContext->psHwReference!=NULL)
            {
                gpphLibContext->psHwReference->p_board_driver = pDriverHandle;
                Status = phLibNfc_UpdateNextState(gpphLibContext,
                                            eLibNfcHalStateInitandIdle);
                if(Status==NFCSTATUS_SUCCESS)
                {
                    if(eTstmode == phLibNfc_TstMode_On)
                        eInitType = eInitTestModeOn;
                    if(eTstmode == phLibNfc_TstMode_Off)
                        eInitType = eInitDefault;
                    Status=phHal4Nfc_Open(
                                    gpphLibContext->psHwReference,
                                    eInitType,
                                    phLibNfc_InitCb,
                                    (void *)gpphLibContext);
                }
            }
            else
            {
                Status = NFCSTATUS_INSUFFICIENT_RESOURCES;
            }
            phLibNfc_Ndef_Init();
        }
    }
    
   return Status;
}

