/*
 * 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 ****************************************
*/

#define LOG_TAG "NFC"

#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  ******************************************
*/

extern int dlopen_firmware();

#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(1);
    Status = phDal4Nfc_Reset(0);
    Status = phDal4Nfc_Reset(1);

    return Status;
}

NFCSTATUS phLibNfc_Download_Mode ()
{
   return phDal4Nfc_Download();
}

int phLibNfc_Load_Firmware_Image ()
{
    int status;
    status = dlopen_firmware();
    return status;
}


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

int phLibNfc_GetIsoXchgTimeout() {
    return nxp_nfc_isoxchg_timeout;
}

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;
}

int phLibNfc_GetHciTimeout() {
    return nxp_nfc_hci_response_timeout;
}

extern uint32_t nxp_nfc_felica_timeout;
NFCSTATUS phLibNfc_SetFelicaTimeout(uint8_t timeout_in_ms) {
    nxp_nfc_felica_timeout = timeout_in_ms;
    return NFCSTATUS_SUCCESS;
}

int phLibNfc_GetFelicaTimeout() {
    return nxp_nfc_felica_timeout;
}

extern uint8_t nxp_nfc_mifareraw_timeout;
NFCSTATUS phLibNfc_SetMifareRawTimeout(uint8_t timeout) {
    nxp_nfc_mifareraw_timeout = timeout;
    return NFCSTATUS_SUCCESS;
}

int phLibNfc_GetMifareRawTimeout() {
    return nxp_nfc_mifareraw_timeout;
}

/**
*    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 */
        if (nxp_nfc_full_version == NULL) {
            // Couldn't load firmware, just pretend we're up to date.
            ALOGW("Firmware image not available: this device might be running old NFC firmware!");
            phLibNfc_StackCapabilities->psDevCapabilities.firmware_update_info = 0;
        } else {
            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;
}

