/*
 * 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  phHal4Nfc.c
 * \brief Hal4Nfc source.
 *
 * Project: NFC-FRI 1.1
 *
 * $Date: Fri Jun 11 09:32:23 2010 $
 * $Author: ing07385 $
 * $Revision: 1.192 $
 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $
 *
 */

/* ---------------------------Include files ---------------------------------*/

#include <phHal4Nfc.h>
#include <phHal4Nfc_Internal.h>
#include <phOsalNfc.h>
#include <phHciNfc.h>
#include <phLlcNfc.h>
#include <phDal4Nfc.h>
#include <phDnldNfc.h>
#include <phOsalNfc_Timer.h>

/* ------------------------------- Macros -----------------------------------*/
#ifndef HAL_UNIT_TEST
#define STATIC static
#else
#define STATIC
#endif/*#ifndef UNIT_TEST*/
#define HAL4_LAYERS                 3
#define LAYER_HCI                   2
#define LAYER_LLC                   1
#define LAYER_DAL                   0

/* --------------------Structures and enumerations --------------------------*/

phHal_sHwReference_t *gpphHal4Nfc_Hwref;

static void phHal4Nfc_IoctlComplete(
                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                                    void     *pInfo
                                    );

static void phHal4Nfc_LowerNotificationHandler(
                                        void    *pContext,
                                        void    *pHwRef,
                                        uint8_t  type,
                                        void     *pInfo
                                        );
static void phHal4Nfc_HandleEvent(
                              phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                              void     *pInfo
                              );

static void phHal4Nfc_OpenComplete(
                                   phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                                   void *pInfo
                                   );

static void phHal4Nfc_CloseComplete(
                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                                    void *pInfo
                                    );

static void phHal4Nfc_DownloadComplete(
                                void *pContext,
                                void *pHwRef,
                                uint8_t type,
                                void *pInfo
                                );

static NFCSTATUS phHal4Nfc_Configure_Layers(
                                phNfcLayer_sCfg_t       **pphLayer
                                );


/*Callback for Self tests*/
static void phHal4Nfc_SelfTestComplete(
                                       phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                                       void *pInfo
                                       );

/**
 *  The open callback function to be called by the HCI when open (initializaion)
 *  sequence is completed  or if there is an error in initialization.
 *  It is passed as a parameter to HCI when calling HCI Init.
 */

static void phHal4Nfc_OpenComplete(
                                   phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                                   void *pInfo
                                   )
{
    NFCSTATUS status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
    pphHal4Nfc_GenCallback_t pUpper_OpenCb
                                    = Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb;
    void                   *pUpper_Context
                                = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
    if(status == NFCSTATUS_SUCCESS)
    {
        PHDBG_INFO("Hal4:Open Successful");
#ifdef MERGE_SAK_SW1 /*Software Workaround*/
        if(eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState)
        {
            status = phHciNfc_System_Configure (
                                    Hal4Ctxt->psHciHandle,
                                    (void *)gpphHal4Nfc_Hwref,
                                    PH_HAL4NFC_TGT_MERGE_ADDRESS,
                                    PH_HAL4NFC_TGT_MERGE_SAK /*config value*/
                                    );
        }
        if(NFCSTATUS_PENDING != status)
#endif/*#ifdef MERGE_SAK_SW1*/
        {
            /*Update State*/
            Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
            Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
            Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb = NULL;
            if(NULL != pUpper_OpenCb)
            {
                /*Upper layer's Open Cb*/
                (*pUpper_OpenCb)(Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
                    NFCSTATUS_SUCCESS
                    );
            }
        }
    }
    else/*Open did not succeed.Go back to reset state*/
    {
        Hal4Ctxt->Hal4CurrentState = eHal4StateClosed;
        Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
        Hal4Ctxt->psHciHandle = NULL;
        phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
        Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
        phOsalNfc_FreeMemory((void *)Hal4Ctxt);
        gpphHal4Nfc_Hwref->hal_context = NULL;
        gpphHal4Nfc_Hwref = NULL;
        PHDBG_INFO("Hal4:Open Failed");
        /*Call upper layer's Open Cb with error status*/
        if(NULL != pUpper_OpenCb)
        {
            /*Upper layer's Open Cb*/
            (*pUpper_OpenCb)(pUpper_Context,status);
        }
    }
    return;
}

/**
 *  The close callback function called by the HCI when close  sequence is
 *  completed or if there is an error in closing.
 *  It is passed as a parameter to HCI when calling HCI Release.
 */
static void phHal4Nfc_CloseComplete(
                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                                    void *pInfo
                                    )
{
    NFCSTATUS   status= ((phNfc_sCompletionInfo_t *)pInfo)->status;
    pphHal4Nfc_GenCallback_t pUpper_CloseCb;
    void                    *pUpper_Context;
    uint8_t                 RemoteDevNumber = 0;
    pUpper_CloseCb = Hal4Ctxt->sUpperLayerInfo.pUpperCloseCb;
    pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
    /*Update state*/
    Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
    Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
    /*If Closed successfully*/
    if(NFCSTATUS_SUCCESS == status)
    {
        Hal4Ctxt->psHciHandle = NULL;
        /*Free all heap allocations*/
        phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
        Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
        /*Free ADD context info*/
        if(NULL != Hal4Ctxt->psADDCtxtInfo)
        {
            while(RemoteDevNumber < MAX_REMOTE_DEVICES)
            {
                if(NULL != Hal4Ctxt->rem_dev_list[RemoteDevNumber])
                {
                    phOsalNfc_FreeMemory((void *)
                                    (Hal4Ctxt->rem_dev_list[RemoteDevNumber]));
                    Hal4Ctxt->rem_dev_list[RemoteDevNumber] = NULL;
                }
                RemoteDevNumber++;
            }
            Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
            phOsalNfc_FreeMemory(Hal4Ctxt->psADDCtxtInfo);
        }/*if(NULL != Hal4Ctxt->psADDCtxtInfo)*/
        /*Free Trcv context info*/
        if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
        {
            if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
            {
                    phOsalNfc_FreeMemory(
                        Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
                        );
            }
            if((NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 
                && (NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData))
            {
                phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData);
            }
            phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo);
        }/*if(NULL != Hal4Ctxt->psTrcvCtxtInfo)*/
        /*Free Hal context and Hardware reference*/
        gpphHal4Nfc_Hwref->hal_context = NULL;
        gpphHal4Nfc_Hwref = NULL;
        phOsalNfc_FreeMemory((void *)Hal4Ctxt);
    }/* if(NFCSTATUS_SUCCESS == status)*/
    /*Call Upper layer's Close Cb with status*/
    (*pUpper_CloseCb)(pUpper_Context,status);
    return;
}


/*
* For configuring the various layers during the Initialization call
*
*
*/
static
NFCSTATUS
phHal4Nfc_Configure_Layers(
                        phNfcLayer_sCfg_t       **pphLayer
                        )
{
    uint8_t index = HAL4_LAYERS - 1;
    uint8_t i = 0;
    NFCSTATUS status = NFCSTATUS_SUCCESS ;
    PHDBG_INFO("Hal4:Configuring layers");
    *pphLayer = (phNfcLayer_sCfg_t *) phOsalNfc_GetMemory(
                            sizeof(phNfcLayer_sCfg_t) * HAL4_LAYERS);

    if( NULL == *pphLayer)
    {
        status = PHNFCSTVAL(CID_NFC_HAL,
                    NFCSTATUS_INSUFFICIENT_RESOURCES);/*Memory allocation error*/
    }
    else
    {

        (void)memset((void *)*pphLayer,0,(
                                sizeof(phNfcLayer_sCfg_t) * HAL4_LAYERS));

        for(i=0 ; i < HAL4_LAYERS ;i++, index-- )
        {
            (*pphLayer + i)->layer_index = index;
            switch(index)
            {
                case LAYER_HCI: /*Configure Hci*/
                {
                    (*pphLayer+i)->layer_name  =(uint8_t *) "Hci";
                    (*pphLayer+i)->layer_registry  = NULL;
                    (*pphLayer+i)->layer_next  =
                                    (((phNfcLayer_sCfg_t *)*pphLayer) + i + 1);
                    break;
                }
                case LAYER_LLC:/*Configure LLC*/
                {
                    (*pphLayer+i)->layer_registry  = phLlcNfc_Register;
                    (*pphLayer+i)->layer_name  = (uint8_t *)"Llc";
                    (*pphLayer+i)->layer_next  =
                                    (((phNfcLayer_sCfg_t *)*pphLayer) + i + 1);
                    break;
                }
                case LAYER_DAL: /*Configure the DAL*/
                {
                    (*pphLayer+i)->layer_registry  = phDal4Nfc_Register;
                    (*pphLayer+i)->layer_name  = (uint8_t *)"Dal";
                    (*pphLayer+i)->layer_next  = NULL ;
                    break;
                }
                default:
                    break;
            } /* End of Switch */
        }   /* End of For Loop */
    }   /* End of NULL Check */

    return status ;
}



#ifdef ANDROID

#define LOG_TAG "NFC-HCI"

#include <utils/Log.h>
#include <dlfcn.h>

#define FW_PATH "/vendor/firmware/libpn544_fw.so"

const unsigned char *nxp_nfc_full_version = NULL;
const unsigned char *nxp_nfc_fw = NULL;

int dlopen_firmware() {
    void *p;

    void *handle = dlopen(FW_PATH, RTLD_NOW);
    if (handle == NULL) {
        ALOGE("Could not open %s", FW_PATH);
        return -1;
    }

    p = dlsym(handle, "nxp_nfc_full_version");
    if (p == NULL) {
        ALOGE("Could not link nxp_nfc_full_version");
        return -1;
    }
    nxp_nfc_full_version = (unsigned char *)p;

    p = dlsym(handle, "nxp_nfc_fw");
    if (p == NULL) {
        ALOGE("Could not link nxp_nfc_fw");
        return -1;
    }
    nxp_nfc_fw = (unsigned char *)p;

    return 0;
}
#endif

/**
 *  The open function called by the upper HAL when HAL4 is to be opened
 *  (initialized).
 *
 */
NFCSTATUS phHal4Nfc_Open(
                         phHal_sHwReference_t       *psHwReference,
                         phHal4Nfc_InitType_t        InitType,
                         pphHal4Nfc_GenCallback_t    pOpenCallback,
                         void                       *pContext
                         )
{
    NFCSTATUS openRetVal = NFCSTATUS_SUCCESS;
    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    phHciNfc_Init_t   eHciInitType = (phHciNfc_Init_t)InitType;
    /*Set Default Clock settings once*/
    static phHal_sHwConfig_t sHwConfig = {
        {0},
        NXP_DEFAULT_CLK_REQUEST,
        NXP_DEFAULT_INPUT_CLK
        };
    /*NULL checks*/
    if(NULL == psHwReference || NULL == pOpenCallback)
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
        openRetVal = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
    }
    else if(NULL != gpphHal4Nfc_Hwref)
    {
        /*Hal4 context is open or open in progress ,return Ctxt already open*/
        openRetVal =  PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_ALREADY_INITIALISED);
    }
    else/*Do an initialization*/
    { 
#ifdef ANDROID
        dlopen_firmware();
#endif

        /*If hal4 ctxt in Hwreference is NULL create a new context*/
        if(NULL == ((phHal_sHwReference_t *)psHwReference)->hal_context)
        {
            Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)
                                phOsalNfc_GetMemory((uint32_t)sizeof(
                                                        phHal4Nfc_Hal4Ctxt_t)
                                                        );
            ((phHal_sHwReference_t *)psHwReference)->hal_context = Hal4Ctxt;
        }
        else/*Take context from Hw reference*/
        {
            Hal4Ctxt = ((phHal_sHwReference_t *)psHwReference)->hal_context;
        }
        if(NULL == Hal4Ctxt)
        {
            openRetVal = PHNFCSTVAL(CID_NFC_HAL,
                        NFCSTATUS_INSUFFICIENT_RESOURCES);
        }
        else
        {
            (void)memset((void *)Hal4Ctxt,
                        0,
                        ((uint32_t)sizeof(phHal4Nfc_Hal4Ctxt_t)));
            /* Configure layers if not configured */
            if( NULL == Hal4Ctxt->pHal4Nfc_LayerCfg )
            {
                openRetVal = phHal4Nfc_Configure_Layers(
                                                  &(Hal4Ctxt->pHal4Nfc_LayerCfg)
                                                  );
            }

            if( openRetVal == NFCSTATUS_SUCCESS )
            {
                /*update Next state*/
                Hal4Ctxt->Hal4NextState = (HCI_NFC_DEVICE_TEST == eHciInitType?
                                eHal4StateSelfTestMode:eHal4StateOpenAndReady);
                /*Store callback and context ,and set Default settings in Context*/
                Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb = pOpenCallback;
                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
                Hal4Ctxt->sTgtConnectInfo.EmulationState = NFC_EVT_DEACTIVATED;
                gpphHal4Nfc_Hwref = psHwReference;
                PHDBG_INFO("Hal4:Calling Hci-Init");
                openRetVal = phHciNfc_Initialise (
                                        (void *)&Hal4Ctxt->psHciHandle,
                                        psHwReference,
                                        eHciInitType,
                                        &sHwConfig,
                                        (pphNfcIF_Notification_CB_t)
                                            phHal4Nfc_LowerNotificationHandler,
                                        (void *)Hal4Ctxt,
                                        Hal4Ctxt->pHal4Nfc_LayerCfg
                                        );
                /*Hci Init did not succeed.free Resources and return*/
                if( (openRetVal != NFCSTATUS_SUCCESS)
                            && (PHNFCSTATUS (openRetVal) != NFCSTATUS_PENDING) )
                {                    
                    phOsalNfc_FreeMemory(Hal4Ctxt->pHal4Nfc_LayerCfg);
                    phOsalNfc_FreeMemory(Hal4Ctxt);
                    Hal4Ctxt = NULL;
                }
            }/*if( openRetVal == NFCSTATUS_SUCCESS )*/
            else/*Free the context*/
            {
                phOsalNfc_FreeMemory(Hal4Ctxt);
            }/*else*/
        }
    }
    return openRetVal;
}

/**  The I/O Control function allows the caller to use (vendor-) specific
*  functionality provided by the lower layer or by the hardware. */
NFCSTATUS phHal4Nfc_Ioctl(
                          phHal_sHwReference_t       *psHwReference,
                          uint32_t                    IoctlCode,
                          phNfc_sData_t              *pInParam,
                          phNfc_sData_t              *pOutParam,
                          pphHal4Nfc_IoctlCallback_t  pIoctlCallback,
                          void                       *pContext
                          )
{
    NFCSTATUS RetStatus = NFCSTATUS_FAILED;
    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    uint32_t config_type = 0;
    uint8_t ind = 0;
    /*NULL checks*/
    if((NULL == psHwReference)
        || (NULL == pIoctlCallback)
        )
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
        RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
    }
    /*Only the Ioctls NFC_FW_DOWNLOAD_CHECK and NFC_FW_DOWNLOAD are allowed in
      the uninitialized state of HAL*/
    else if(NULL == psHwReference->hal_context)
    {
#ifdef FW_DOWNLOAD

#if  !defined (NXP_FW_INTEGRITY_VERIFY)
        if(NFC_FW_DOWNLOAD_CHECK == IoctlCode)
        {
            RetStatus = phDnldNfc_Run_Check(
                psHwReference                       
                );
        }
        else
#endif /* !defined (NXP_FW_INTEGRITY_VERIFY) */
        if((NFC_FW_DOWNLOAD == IoctlCode)
            &&(NULL == gpphHal4Nfc_Hwref))/*Indicates current state is shutdown*/
        {
            Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)
                phOsalNfc_GetMemory((uint32_t)sizeof(
                                                phHal4Nfc_Hal4Ctxt_t)
                                                );      
            if(NULL == Hal4Ctxt)
            {
                RetStatus = PHNFCSTVAL(CID_NFC_HAL,
                    NFCSTATUS_INSUFFICIENT_RESOURCES);
            }
            else
            {
                ((phHal_sHwReference_t *)psHwReference)->hal_context 
                    = Hal4Ctxt;
                (void)memset((void *)Hal4Ctxt,
                                 0,
                                   ((uint32_t)sizeof(phHal4Nfc_Hal4Ctxt_t)));               
                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;                                              
                Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb
                    = pIoctlCallback;/*Register upper layer callback*/
                Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam = pOutParam;   
                /*Upgrade the firmware*/
                RetStatus = phDnldNfc_Upgrade (
                        psHwReference,
                        phHal4Nfc_DownloadComplete,
                        Hal4Ctxt
                        );
                if((NFCSTATUS_SUCCESS == RetStatus)
                    || (NFCSTATUS_PENDING != PHNFCSTATUS(RetStatus))
                    )
                {
                    phOsalNfc_FreeMemory(Hal4Ctxt);
                    ((phHal_sHwReference_t *)psHwReference)->hal_context = NULL;
                }
            }
        }
        else
#endif/*NFC_FW_DOWNLOAD*/
        {
            RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);     
        }
    }
    else/*Status is Initialised*/
    {
        /*Register upper layer context*/
        Hal4Ctxt = psHwReference->hal_context;
        Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam = pOutParam;
        switch(IoctlCode)
        {
        /*Self test Ioctls*/
        case DEVMGMT_ANTENNA_TEST:
        case DEVMGMT_SWP_TEST:
        case DEVMGMT_NFCWI_TEST:
            if(eHal4StateSelfTestMode ==Hal4Ctxt->Hal4CurrentState)
            {
                RetStatus = phHciNfc_System_Test(
                    Hal4Ctxt->psHciHandle,
                    (void *)psHwReference,
                    IoctlCode ,
                    pInParam
                    );
            }
            break;
        /*PRBS Test*/
        case DEVMGMT_PRBS_TEST:
            RetStatus = phHciNfc_PRBS_Test(
                Hal4Ctxt->psHciHandle,
                (void *)psHwReference,
                IoctlCode ,
                pInParam
                );
            break;
        /*To Set Antenna Power Level*/
        case NFC_ANTENNA_CWG:
            if(eHal4StateSelfTestMode ==Hal4Ctxt->Hal4CurrentState)
            {
                RetStatus = phHciNfc_System_Configure (
                    Hal4Ctxt->psHciHandle,
                    (void *)psHwReference,
                    NFC_ANTENNA_CWG,
                    pInParam->buffer[0] /**Set Power Level*/
                    );

            }
            break;
        /*Not allowed when Init is complete*/
        case NFC_FW_DOWNLOAD_CHECK:
        case NFC_FW_DOWNLOAD:
            RetStatus = PHNFCSTVAL(CID_NFC_HAL,
                NFCSTATUS_BUSY);
            break;
        /*Gpio read*/
        case NFC_GPIO_READ:
            /* if(eHal4StateSelfTestMode == Hal4Ctxt->Hal4CurrentState) */
            {
                RetStatus = phHciNfc_System_Get_Info(
                    Hal4Ctxt->psHciHandle,
                    (void *)psHwReference,
                    IoctlCode ,
                    pOutParam->buffer
                    );
            }
            break;
        /*Used to Read Memory/Registers .3 bytes of Array passed form the 
          address to read from in MSB first format.*/
        case NFC_MEM_READ:
            {
                if((NULL != pInParam)
                    && (pInParam->length == 3))
                {
                    for( ind = 0; ind < 3; ind++ )
                    {
                        config_type = ((config_type << BYTE_SIZE )
                                        | (pInParam->buffer[ind] ));
                    }
                    RetStatus = phHciNfc_System_Get_Info(
                        Hal4Ctxt->psHciHandle,
                        (void *)psHwReference,
                        config_type ,
                        pOutParam->buffer
                        );
                }
                else
                {
                    RetStatus = PHNFCSTVAL(CID_NFC_HAL,
                        NFCSTATUS_INVALID_PARAMETER);
                }
            }
            break;
        /*Used to Write Memory/Registers .First 3 bytes of Array passed in MSB 
          first format form the address to write to.The 4th Byte is the 8 bit 
          value to be written to the address*/
        case NFC_MEM_WRITE:
            {
                if((NULL != pInParam)
                    && (pInParam->length == 4))
                {
                    for( ind = 0; ind < 3; ind++ )
                    {
                        config_type = ((config_type << BYTE_SIZE ) 
                                        | (pInParam->buffer[ind] ));
                    }
                    RetStatus = phHciNfc_System_Configure (
                        Hal4Ctxt->psHciHandle,
                        (void *)psHwReference,
                        config_type,
                        pInParam->buffer[3] /*config value*/
                        );
                }
                else
                {
                    RetStatus = PHNFCSTVAL(CID_NFC_HAL , 
                        NFCSTATUS_INVALID_PARAMETER);
                }
            }
            break;
        default:
            break;
        }
        if(NFCSTATUS_PENDING == RetStatus)/*Callback Pending*/
        {
            /*Register upper layer callback and context*/
            Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
            Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb= pIoctlCallback;
            /*Store the Ioctl code*/
            Hal4Ctxt->Ioctl_Type = IoctlCode;
        }
    }
    return RetStatus;
}


/**
 *  The close function called by the upper layer when HAL4 is to be closed
 *  (shutdown).  
 */
NFCSTATUS phHal4Nfc_Close(
                          phHal_sHwReference_t *psHwReference,
                          pphHal4Nfc_GenCallback_t pCloseCallback,
                          void *pContext
                          )
{
    NFCSTATUS closeRetVal = NFCSTATUS_SUCCESS;
    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    /*NULL checks*/
    if(NULL == psHwReference || NULL == pCloseCallback)
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
        closeRetVal = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
    }
    else if((NULL == psHwReference->hal_context)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4CurrentState 
                                               < eHal4StateSelfTestMode)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4NextState 
                                               == eHal4StateClosed))
    {
        /*return already closed*/
        closeRetVal= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
    }
    else  /*Close the HAL*/
    {
        /*Get Hal4 context from Hw reference*/
        Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)((phHal_sHwReference_t *)
                                               psHwReference)->hal_context;
        /*Unregister Tag Listener*/
        if(NULL != Hal4Ctxt->psADDCtxtInfo)
        {
            Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
        }
        /*store Callback and Context*/
        Hal4Ctxt->sUpperLayerInfo.pUpperCloseCb = pCloseCallback;
        Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
        /*Call Hci Release*/
        PHDBG_INFO("Hal4:Calling Hci Release");
        closeRetVal =(NFCSTATUS)phHciNfc_Release(
                                    (void *)Hal4Ctxt->psHciHandle,
                                    psHwReference,
                                    (pphNfcIF_Notification_CB_t)
                                    phHal4Nfc_LowerNotificationHandler,
                                    (void *)Hal4Ctxt
                                    );
        /*Update Next state and exit*/
        if( PHNFCSTATUS (closeRetVal) == NFCSTATUS_PENDING )
        {
            Hal4Ctxt->Hal4NextState = eHal4StateClosed;
            Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
        }
        else
        {

        }
    }
    return closeRetVal;
}

/*Forcibly shutdown the HAl4.Frees all Resources in use by Hal4 before shutting
  down*/
void phHal4Nfc_Hal4Reset(
                         phHal_sHwReference_t *pHwRef,
                         void                 *pContext
                         )
{
    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    NFCSTATUS             closeRetVal = NFCSTATUS_SUCCESS;
    uint8_t               RemoteDevNumber = 0;
    if(pHwRef ==NULL)
    {
        closeRetVal = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
    }
    else if(pHwRef->hal_context != NULL)
    {
        /*Get the Hal context*/
        Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pHwRef->hal_context;
        /*store the upper layer context*/
        Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
        Hal4Ctxt->Hal4NextState = eHal4StateClosed;
        Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
        /*Call Hci Release*/
        PHDBG_INFO("Hal4:Calling Hci Release");
        closeRetVal =(NFCSTATUS)phHciNfc_Release(
                                            (void *)Hal4Ctxt->psHciHandle,
                                            pHwRef,
                                            (pphNfcIF_Notification_CB_t)NULL,
                                            (void *)Hal4Ctxt
                                            );/*Clean up Hci*/
        Hal4Ctxt->Hal4CurrentState = eHal4StateClosed;
        phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
        Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
        /*Free ADD context*/
        if(NULL != Hal4Ctxt->psADDCtxtInfo)
        {
            Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
            while(RemoteDevNumber < MAX_REMOTE_DEVICES)
            {
                if(NULL != Hal4Ctxt->rem_dev_list[RemoteDevNumber])
                {
                    phOsalNfc_FreeMemory((void *)
                            (Hal4Ctxt->rem_dev_list[RemoteDevNumber]));
                    Hal4Ctxt->rem_dev_list[RemoteDevNumber] = NULL;
                }
                RemoteDevNumber++;
            }
            Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
            phOsalNfc_FreeMemory(Hal4Ctxt->psADDCtxtInfo);
        }
        /*Free Trcv context*/
        if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
        {
            if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
            {
                phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo
                                                    ->sLowerRecvData.buffer);
            }
            if((NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) 
                && (NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData))
            {
                phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData);
            }
            phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo);
        }
        phOsalNfc_FreeMemory(Hal4Ctxt);/*Free the context*/
        pHwRef->hal_context = NULL;
        gpphHal4Nfc_Hwref = NULL;
    }
    else
    {
        /*Hal4 Context is already closed.Return Success*/
    }
    /*Reset Should always return Success*/
    if(closeRetVal != NFCSTATUS_SUCCESS)
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
    }
    return;
}

/**
 *  \if hal
 *   \ingroup grp_hal_common
 *  \else
 *   \ingroup grp_mw_external_hal_funcs
 *  \endif
 *
 *  Retrieves the capabilities of the device represented by the Hardware
 *  Reference parameter.
 *  The HW, SW versions, the MTU and other mandatory information are located
 *  inside the pDevCapabilities parameter.
 */
NFCSTATUS phHal4Nfc_GetDeviceCapabilities(
                            phHal_sHwReference_t          *psHwReference,
                            phHal_sDeviceCapabilities_t   *psDevCapabilities,
                            void                          *pContext
                            )
{
    NFCSTATUS retstatus = NFCSTATUS_SUCCESS;
    /*NULL checks*/
    if(psDevCapabilities == NULL || psHwReference == NULL || pContext == NULL)
    {
        retstatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
    }
    /*Check for Initialized state*/
    else if((NULL == psHwReference->hal_context)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4CurrentState 
                                               < eHal4StateOpenAndReady)
                        || (((phHal4Nfc_Hal4Ctxt_t *)
                                psHwReference->hal_context)->Hal4NextState 
                                               == eHal4StateClosed))
    {
        retstatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
    }
    else/*Provide Device capabilities and Version Info to the caller*/
    {
        (void)memcpy((void *)psDevCapabilities,
            (void *)&(psHwReference->device_info),
            sizeof(phHal_sDeviceCapabilities_t));
        psDevCapabilities->ReaderSupProtocol.Felica         = TRUE;
        psDevCapabilities->ReaderSupProtocol.ISO14443_4A    = TRUE;
        psDevCapabilities->ReaderSupProtocol.ISO14443_4B    = TRUE;
        psDevCapabilities->ReaderSupProtocol.ISO15693       = TRUE;
        psDevCapabilities->ReaderSupProtocol.Jewel          = TRUE;
        psDevCapabilities->ReaderSupProtocol.MifareStd      = TRUE;
        psDevCapabilities->ReaderSupProtocol.MifareUL       = TRUE;
        psDevCapabilities->ReaderSupProtocol.NFC            = TRUE;
        psDevCapabilities->EmulationSupProtocol.Felica      = FALSE;
        psDevCapabilities->EmulationSupProtocol.ISO14443_4A = FALSE;
        psDevCapabilities->EmulationSupProtocol.ISO14443_4B = FALSE;
        psDevCapabilities->EmulationSupProtocol.ISO15693    = FALSE;
        psDevCapabilities->EmulationSupProtocol.Jewel       = FALSE;
        psDevCapabilities->EmulationSupProtocol.MifareStd   = FALSE;
        psDevCapabilities->EmulationSupProtocol.MifareUL    = FALSE;
        psDevCapabilities->EmulationSupProtocol.NFC         = TRUE;
        psDevCapabilities->hal_version = (
                    (((PH_HAL4NFC_INTERFACE_VERSION << BYTE_SIZE)
                      |(PH_HAL4NFC_INTERFACE_REVISION)<<BYTE_SIZE)
                      |(PH_HAL4NFC_INTERFACE_PATCH)<<BYTE_SIZE)
                      |PH_HAL4NFC_INTERAFECE_BUILD
                      );
    }
    return retstatus;
}

/*
 * Handles all notifications received from HCI layer.
 *
 */
static void phHal4Nfc_LowerNotificationHandler(
                                    void    *pContext,
                                    void    *pHwRef,
                                    uint8_t  type,
                                    void     *pInfo
                                    )
{
    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    if((NULL == pInfo) || (NULL == pHwRef)
        || (NULL == pContext))
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
    }
    else
    {
        /*A copy of hardware reference is maintained in HAL for comparing passed
          and returned context.Set to NULL after a Shutdown*/
        if(NULL != gpphHal4Nfc_Hwref)/*Get context from Hw ref*/
        {
            Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)gpphHal4Nfc_Hwref->hal_context;
            if(NFC_INVALID_RELEASE_TYPE == Hal4Ctxt->sTgtConnectInfo.ReleaseType)
            {
                Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
                gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)pHwRef;
            }
        }
        else/*No Copy of Hw ref in HAL.Copy both Hwref and Hal context passed 
             by Hci*/
        {
            Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
            gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)pHwRef;
        }
        /*Check the type of notification received from Hci and handle it
          accordingly*/
        switch(type)
        {
            case NFC_NOTIFY_INIT_COMPLETED:
            case NFC_NOTIFY_INIT_FAILED:
                phHal4Nfc_OpenComplete(Hal4Ctxt,pInfo);
                break;
            case NFC_IO_SUCCESS:
            case NFC_IO_ERROR:
                phHal4Nfc_IoctlComplete(Hal4Ctxt,pInfo);
                break;
            case NFC_NOTIFY_RESULT:
                phHal4Nfc_SelfTestComplete(Hal4Ctxt,pInfo);
                break;
            case NFC_NOTIFY_DEINIT_COMPLETED:
            case NFC_NOTIFY_DEINIT_FAILED:
                phHal4Nfc_CloseComplete(Hal4Ctxt,pInfo);
                break;
            case NFC_NOTIFY_POLL_ENABLED:
            case NFC_NOTIFY_POLL_DISABLED:
            case NFC_NOTIFY_POLL_RESTARTED:
            case NFC_NOTIFY_CONFIG_ERROR:
            case NFC_NOTIFY_CONFIG_SUCCESS:
                phHal4Nfc_ConfigureComplete(Hal4Ctxt,pInfo,type);
                break;
            case NFC_NOTIFY_TARGET_DISCOVERED:
            case NFC_NOTIFY_DISCOVERY_ERROR:
                phHal4Nfc_TargetDiscoveryComplete(Hal4Ctxt,pInfo);
                break;
            case NFC_NOTIFY_TARGET_REACTIVATED:
                phHal4Nfc_ReactivationComplete(Hal4Ctxt,pInfo);
                break;
            case NFC_NOTIFY_EVENT:
                PHDBG_INFO("Hal4:Calling Event callback");
                phHal4Nfc_HandleEvent(Hal4Ctxt,pInfo);
                break;
            case NFC_NOTIFY_TARGET_CONNECTED:
                PHDBG_INFO("Hal4:Calling Hal4 Connect complete");
                phHal4Nfc_ConnectComplete(Hal4Ctxt,pInfo);
                break;

            case NFC_NOTIFY_TARGET_DISCONNECTED:
            {
                PHDBG_INFO("Hal4:Target Disconnected");
                if(Hal4Ctxt->Hal4NextState == eHal4StatePresenceCheck)
                {
                    phHal4Nfc_PresenceChkComplete(Hal4Ctxt,pInfo);
                }
                else
                {
                    phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo);
                }
                break;
            }
            case NFC_NOTIFY_TRANSCEIVE_COMPLETED:
            case NFC_NOTIFY_TRANSCEIVE_ERROR    :
                PHDBG_INFO("Hal4:Transceive Callback");
                if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
                {
#ifdef TRANSACTION_TIMER
                    if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
                        != PH_OSALNFC_INVALID_TIMER_ID)
                    {
                        phOsalNfc_Timer_Stop(
                            Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
                            );
                        phOsalNfc_Timer_Delete(
                            Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
                            );
                        Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
                                    = PH_OSALNFC_INVALID_TIMER_ID;
                    }
#endif /*TRANSACTION_TIMER*/
                    phHal4Nfc_TransceiveComplete(Hal4Ctxt,pInfo);
                }
                break;
            case NFC_NOTIFY_SEND_COMPLETED   :
                PHDBG_INFO("Hal4:NfcIp1 Send Callback");
                if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
                {
                    phHal4Nfc_SendCompleteHandler(Hal4Ctxt,pInfo);
                }
                break;
            case NFC_NOTIFY_TRANSACTION  :
                phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
                break;
            case NFC_NOTIFY_RECV_ERROR    :
            case NFC_NOTIFY_RECV_EVENT    :
                PHDBG_INFO("Hal4:Receive Event");
                if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
                {
                    if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
                        != PH_OSALNFC_INVALID_TIMER_ID)
                    {
                        phOsalNfc_Timer_Stop(
                            Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
                            );
                        phOsalNfc_Timer_Delete(
                            Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
                            );
                        Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
                            = PH_OSALNFC_INVALID_TIMER_ID;
                    }
                }
                phHal4Nfc_RecvCompleteHandler(Hal4Ctxt,pInfo);
                break;
            case NFC_NOTIFY_TARGET_PRESENT:
                phHal4Nfc_PresenceChkComplete(Hal4Ctxt,pInfo);
                break;
            case NFC_NOTIFY_DEVICE_ERROR:
            {
                NFCSTATUS status = NFCSTATUS_BOARD_COMMUNICATION_ERROR;
                pphHal4Nfc_GenCallback_t pUpper_OpenCb
                                                = Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb;
                void                   *pUpper_Context
                                            = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
                static phHal4Nfc_NotificationInfo_t uNotificationInfo;
                if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler)
                {                    
                    Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
                    Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler(
                        Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt,
                        NFC_EVENT_NOTIFICATION,
                        uNotificationInfo,
                        NFCSTATUS_BOARD_COMMUNICATION_ERROR
                        );
                }
                else if (( eHal4StateSelfTestMode == Hal4Ctxt->Hal4NextState )
                    || ( eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState ) )
                {
                    Hal4Ctxt->Hal4CurrentState = eHal4StateClosed;
                    Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
                    (void)phHciNfc_Release((void *)Hal4Ctxt->psHciHandle,
                                              pHwRef, (pphNfcIF_Notification_CB_t)NULL,
                                               (void *)Hal4Ctxt);/*Clean up Hci*/
                    Hal4Ctxt->psHciHandle = NULL;
                    phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
                    Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
                    phOsalNfc_FreeMemory((void *)Hal4Ctxt);
                    gpphHal4Nfc_Hwref->hal_context = NULL;
                    gpphHal4Nfc_Hwref = NULL;
                    PHDBG_INFO("Hal4:Open Failed");
                    /*Call upper layer's Open Cb with error status*/
                    if(NULL != pUpper_OpenCb)
                    {
                        /*Upper layer's Open Cb*/
                        (*pUpper_OpenCb)(pUpper_Context,status);
                    }
                }
                else
                {
                    Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
                    phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
                }
                break;
            }
            case NFC_NOTIFY_CONNECT_FAILED:
            case NFC_NOTIFY_DISCONNECT_FAILED:   
            /*Generic Error type received from Hci.Handle the error based on 
              Hal4 next state and which past callback was Pending*/
            case NFC_NOTIFY_ERROR:
            {
                PHDBG_WARNING("Hal4:Error Notification from HCI");
                switch(Hal4Ctxt->Hal4NextState)
                {
                    case eHal4StateClosed:
                        phHal4Nfc_CloseComplete(Hal4Ctxt,pInfo);
                        break;
                    case eHal4StateSelfTestMode:
                        phHal4Nfc_SelfTestComplete(Hal4Ctxt,pInfo);
                        break;
                    case eHal4StateConfiguring:
                        phHal4Nfc_ConfigureComplete(Hal4Ctxt,pInfo,type);
                        break;
                    case eHal4StateTargetDiscovered:
                    case eHal4StateTargetActivate:
                    {
                        if(NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)
                        {
                            if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
                            {
                                 phHal4Nfc_ConfigureComplete(Hal4Ctxt,pInfo,type);
                            }
                            else
                            {
                                phHal4Nfc_ConnectComplete(Hal4Ctxt,pInfo);
                            }
                        }
                        else
                        {
                            phHal4Nfc_TargetDiscoveryComplete(Hal4Ctxt,pInfo);
                        }
                        break;
                    }
                    case eHal4StateTargetConnected:
                        phHal4Nfc_ConnectComplete(Hal4Ctxt,pInfo);
                        break;
                    case eHal4StateOpenAndReady:
                        phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo);
                        break;
                    case eHal4StatePresenceCheck:
                        phHal4Nfc_PresenceChkComplete(Hal4Ctxt,pInfo);
                        break;
                    default:
                        PHDBG_WARNING("Unknown Error notification");
                        break;
                }
                break;
            }/*End of switch(Hal4Ctxt->Hal4State)*/
            default:
                phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
                break;
        }/*End of switch(type)*/
    }
    return;
}


/*Event handler for HAL-HCI interface*/
static void phHal4Nfc_HandleEvent(
                       phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                       void *pInfo
                       )
{
    phHal_sEventInfo_t *psEventInfo = (phHal_sEventInfo_t *)pInfo;
    static phNfc_sNotificationInfo_t sNotificationInfo;
    phHal4Nfc_NotificationInfo_t uNotificationInfo = {NULL};
    NFCSTATUS RetStatus = NFCSTATUS_FAILED;
    /*Check if Hal4 Close has already been called*/
    if(eHal4StateClosed != Hal4Ctxt->Hal4NextState)
    {
        switch(psEventInfo->eventType)
        {
        case NFC_EVT_ACTIVATED:/*Target Activated*/
        {
            if(psEventInfo->eventHost == phHal_eHostController)
            {
                switch(psEventInfo->eventSource)
                {
                    case phHal_eNfcIP1_Target:
                        phHal4Nfc_P2PActivateComplete(Hal4Ctxt,pInfo);
                        break;
                    case phHal_eISO14443_A_PICC:
                    case phHal_eISO14443_B_PICC:
                        sNotificationInfo.info = psEventInfo;
                        sNotificationInfo.status = NFCSTATUS_SUCCESS;
                        sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
                        pInfo = &sNotificationInfo;
                        phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
                        break;
                    default:
                        break;
                }           
            }
        }
            break;
        case NFC_EVT_DEACTIVATED:/*Target Deactivated*/
        {
            if(psEventInfo->eventHost == phHal_eHostController)
            {
                switch(psEventInfo->eventSource)
                {
                case phHal_eNfcIP1_Target:
                    phHal4Nfc_HandleP2PDeActivate(Hal4Ctxt,pInfo);
                    break;
                case phHal_eISO14443_A_PICC:
                case phHal_eISO14443_B_PICC:
                    sNotificationInfo.info = psEventInfo;
                    sNotificationInfo.status = NFCSTATUS_SUCCESS;
                    sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
                    pInfo = &sNotificationInfo;
                    phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
                    break;
                default:
                    break;
                }
            }
        }
            break;
        /*Set Protection Event*/
        case NFC_EVT_PROTECTED:
        {
#ifdef IGNORE_EVT_PROTECTED
            /*Ignore_Event_Protected is set to false during Field Off event and 
              Set protection Configuration.After a NFC_EVT_PROTECTED is received
              once all subsequent NFC_EVT_PROTECTED events are ignored*/
            if(FALSE == Hal4Ctxt->Ignore_Event_Protected)
            {
                Hal4Ctxt->Ignore_Event_Protected = TRUE;
#endif/*#ifdef IGNORE_EVT_PROTECTED*/
                sNotificationInfo.info = psEventInfo;
                sNotificationInfo.status = NFCSTATUS_SUCCESS;
                sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
                pInfo = &sNotificationInfo;            
                phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
#ifdef IGNORE_EVT_PROTECTED
            }
#endif/*#ifdef IGNORE_EVT_PROTECTED*/
            break;
        }
        /*NFC_UICC_RDPHASES_DEACTIVATE_REQ*/
        case NFC_UICC_RDPHASES_DEACTIVATE_REQ:
        {
            if(NULL != gpphHal4Nfc_Hwref)
            {
                gpphHal4Nfc_Hwref->uicc_rdr_active = FALSE;
            }
            break;
        }
        case NFC_UICC_RDPHASES_ACTIVATE_REQ:
        {
            if(NULL != gpphHal4Nfc_Hwref)
            {
                gpphHal4Nfc_Hwref->uicc_rdr_active = TRUE;
            }
            /*If a NFC_UICC_RDPHASES_ACTIVATE_REQ is received before a configure
             discovery,then create a ADD context info*/
            if (NULL == Hal4Ctxt->psADDCtxtInfo)
            {
                Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
                    phOsalNfc_GetMemory((uint32_t)
                    (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
                if(NULL != Hal4Ctxt->psADDCtxtInfo)
                {
                    (void)memset(Hal4Ctxt->psADDCtxtInfo,0,
                        sizeof(phHal4Nfc_ADDCtxtInfo_t)
                        );
                }
            }
            if(NULL != Hal4Ctxt->psADDCtxtInfo)
            {
                Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollEnabled 
                                |= psEventInfo->eventInfo.rd_phases;
                /*Configure HCI Discovery*/ 
                RetStatus = phHciNfc_Config_Discovery(
                    (void *)Hal4Ctxt->psHciHandle,
                    gpphHal4Nfc_Hwref,
                    &(Hal4Ctxt->psADDCtxtInfo->sADDCfg)
                    ); 
                Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus?
                                                eHal4StateConfiguring:
                                                Hal4Ctxt->Hal4NextState);
            }
            break;
        }   
        /*Call Default Event handler for these Events*/
        case NFC_INFO_TXLDO_OVERCUR:
        case NFC_INFO_MEM_VIOLATION:
        case NFC_INFO_TEMP_OVERHEAT:
        case NFC_INFO_LLC_ERROR:
        {
            sNotificationInfo.info = psEventInfo;
            sNotificationInfo.status = NFCSTATUS_SUCCESS;
            sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
            pInfo = &sNotificationInfo;
            PHDBG_INFO("Hal4:Exception events");
            if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler)
            {
                /*Pass on Event notification info from Hci to Upper layer*/
                uNotificationInfo.psEventInfo = psEventInfo;
                Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler(
                    Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt,
                    sNotificationInfo.type,
                    uNotificationInfo,
                    NFCSTATUS_SUCCESS
                    );
            }
            break;
        }
        /*Call emulation Event handler fto handle these Events*/
        case NFC_EVT_TRANSACTION:
        case NFC_EVT_START_OF_TRANSACTION:
        case NFC_EVT_END_OF_TRANSACTION:
        case NFC_EVT_CONNECTIVITY:   
        case NFC_EVT_OPERATION_ENDED:
        case NFC_EVT_MIFARE_ACCESS:
        case NFC_EVT_APDU_RECEIVED:
        case NFC_EVT_EMV_CARD_REMOVAL:
            sNotificationInfo.info = psEventInfo;
            sNotificationInfo.status = NFCSTATUS_SUCCESS;
            sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
            pInfo = &sNotificationInfo;
            PHDBG_INFO("Hal4:Event transaction\n");
            phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
            break;
        case NFC_EVT_FIELD_ON:
            Hal4Ctxt->psEventInfo = sNotificationInfo.info = psEventInfo;
            sNotificationInfo.status = NFCSTATUS_SUCCESS;
            sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
            pInfo = &sNotificationInfo;
            PHDBG_INFO("Hal4:Event Field ON\n");
            phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);        
            break;
        case NFC_EVT_FIELD_OFF:
    #ifdef IGNORE_EVT_PROTECTED
            Hal4Ctxt->Ignore_Event_Protected = FALSE;
    #endif/*#ifdef IGNORE_EVT_PROTECTED*/
            Hal4Ctxt->psEventInfo = sNotificationInfo.info = psEventInfo;
            sNotificationInfo.status = NFCSTATUS_SUCCESS;
            sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
            pInfo = &sNotificationInfo;
            PHDBG_INFO("Hal4:Event Field OFF\n");
            phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo); 
            break;
        default:
            PHDBG_WARNING("Hal4:Unhandled Event type received");
            break;
        }/*End of switch*/
    }/*if(eHal4StateClosed != Hal4Ctxt->Hal4NextState)*/
    return;
}


/*Callback handler for Self Test Ioctl completion*/
static void phHal4Nfc_SelfTestComplete(
                                       phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                                       void *pInfo
                                       )
{
    NFCSTATUS status = NFCSTATUS_FAILED;
    phNfc_sData_t *SelfTestResults
        = (phNfc_sData_t *)(((phNfc_sCompletionInfo_t *)pInfo)->info);
    pphHal4Nfc_IoctlCallback_t pUpper_IoctlCb
        = Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb;
    void  *pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
    /*check for Success*/
    if(( DEVMGMT_SWP_TEST == Hal4Ctxt->Ioctl_Type )
        || ( DEVMGMT_ANTENNA_TEST == Hal4Ctxt->Ioctl_Type ))
    {
        status = NFCSTATUS_SUCCESS;
    }
    else if((SelfTestResults->length > 0) && (0 == SelfTestResults->buffer[0]))
    {
        status = NFCSTATUS_SUCCESS;
    }
    else
    {
        if (NULL != pInfo)
        {
            status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
        }
    }

    /*Copy response buffer and length*/
    (void)memcpy(Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->buffer,
                 SelfTestResults->buffer,
                 SelfTestResults->length);
    Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->length
                                        = SelfTestResults->length;
    /*Call registered Ioctl callback*/
    (*pUpper_IoctlCb)(
                pUpper_Context,
                Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam,
                status
                );
    return;
}


static void phHal4Nfc_IoctlComplete(
                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
                                    void *pInfo
                                    )
{
    /*Copy status*/
    NFCSTATUS status = (((phNfc_sCompletionInfo_t *)pInfo)->status);
    pphHal4Nfc_IoctlCallback_t pUpper_IoctlCb 
                                    = Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb;
#ifdef MERGE_SAK_SW2
    pphHal4Nfc_GenCallback_t pConfigCallback = 
        Hal4Ctxt->sUpperLayerInfo.pConfigCallback;
#endif/*#ifdef MERGE_SAK_SW2*/
    void  *pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
    Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb = NULL;    
#ifdef MERGE_SAK_SW1 /*Software workaround 1*/
    if(eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState)
    {
        Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
        Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
        /*Upper layer's Open Cb*/
        (*Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb)(
            Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
            NFCSTATUS_SUCCESS
            );
    }
#endif/*#ifdef MERGE_SAK_SW1*/    
#ifdef MERGE_SAK_SW2 /*Software workaround 2*/
    else if((eHal4StateConfiguring == Hal4Ctxt->Hal4NextState)
            &&(NULL != pConfigCallback))
    {
        Hal4Ctxt->sUpperLayerInfo.pConfigCallback = NULL;
        Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
        (*pConfigCallback)(
            Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,status
            );
    }
    else
#endif/*#ifdef MERGE_SAK_SW2*/
    {
        /*for NFC_MEM_READ and NFC_GPIO_READ ,provide one Byte Response*/
        if ((NFC_MEM_READ == Hal4Ctxt->Ioctl_Type)
            || (NFC_GPIO_READ == Hal4Ctxt->Ioctl_Type)
            )
        {
            Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->length 
                = sizeof (uint8_t);
        }
         /*Call registered Ioctl callback*/
        if(NULL != pUpper_IoctlCb)
        {
            (*pUpper_IoctlCb)(
                pUpper_Context,
                Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam,
                status
                );
        }
    }
    return;
}

#ifdef FW_DOWNLOAD
/**Callback handler for Download completion*/
STATIC void phHal4Nfc_DownloadComplete(
                                void *pContext,
                                void *pHwRef,
                                uint8_t type,
                                void *pInfo
                                )
{
    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
    NFCSTATUS status = NFCSTATUS_FAILED;
    pphHal4Nfc_IoctlCallback_t pUpper_DnldCb = NULL;
    phNfc_sData_t *pIoctlOutParam = NULL;
    phHal_sHwReference_t *psHwRef = NULL;
    void  *pUpper_Context = NULL;
    /*NULL checks*/
    if((NULL == pInfo) || (NULL == pHwRef) || (NULL == pContext))
    {
        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
    }
    else
    {
        type = type;
        Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
        /*Copy back stored context/callback for the upper layer*/
        pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
        pIoctlOutParam = Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam;
        pUpper_DnldCb = Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb;
        Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb = NULL;
        /*Copy download status*/
        status = (((phNfc_sCompletionInfo_t *)pInfo)->status);
        /*copy hw reference*/
        psHwRef = (phHal_sHwReference_t *)pHwRef;
        /*Free the temporary hal context used only for the sake of download*/
        phOsalNfc_FreeMemory(psHwRef->hal_context);
        psHwRef->hal_context = NULL;
        /*Call upper layer callback*/
        if(NULL != pUpper_DnldCb)
        {
            (*pUpper_DnldCb)(
                pUpper_Context,
                pIoctlOutParam,
                status
                );
        }
    }
    return;
}
#endif /*FW_DOWNLOAD*/

