/*
 * 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  phHciNfc.c                                                           *
* \brief HCI Interface Source for the HCI Management.                         *
*                                                                             *
*                                                                             *
* Project: NFC-FRI-1.1                                                        *
*                                                                             *
* $Date: Thu Apr 22 17:49:47 2010 $                                           *
* $Author: ing04880 $                                                         *
* $Revision: 1.90 $                                                           *
* $Aliases: NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $              
*                                                                             *
* =========================================================================== *
*/


/*
################################################################################
***************************** Header File Inclusion ****************************
################################################################################
*/

#include <phNfcConfig.h>
#include <phNfcCompId.h>
#include <phNfcIoctlCode.h>
#include <phHciNfc.h>
#include <phHciNfc_Sequence.h>
#include <phHciNfc_RFReader.h>
#include <phHciNfc_LinkMgmt.h>
#ifdef ENABLE_P2P
#include <phHciNfc_NfcIPMgmt.h>
#endif
#include <phHciNfc_Emulation.h>
#include <phHciNfc_SWP.h>
#include <phHciNfc_DevMgmt.h>
#include <phOsalNfc.h>

/**/

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


static
NFCSTATUS
phHciNfc_Config_Emulation (
                        void                            *psHciHandle,
                        void                            *pHwRef,
                        phHal_sEmulationCfg_t           *pEmulationConfig

                        );


/*
*************************** Function Definitions **************************
*/


/*!
 * \brief Initialises the HCI Interface
 *
 * This function initialises the resources for the HCI Command and
 * Response Mechanism
 */

 NFCSTATUS
 phHciNfc_Initialise (
                        void                            *psHciHandle,
                        void                            *pHwRef,
                        phHciNfc_Init_t                 init_mode,
                        phHal_sHwConfig_t               *pHwConfig,
                        pphNfcIF_Notification_CB_t       pHalNotify,
                        void                            *psContext,
                        phNfcLayer_sCfg_t               *psHciLayerCfg
                     )
{
    phHciNfc_sContext_t *psHciContext = NULL;
    phNfcIF_sReference_t hciReference = { NULL };
    phNfcIF_sCallBack_t  if_callback = { NULL, NULL, NULL, NULL };
    phNfc_sLowerIF_t    *plower_if = NULL;
    NFCSTATUS            status = NFCSTATUS_SUCCESS;
    uint8_t              lower_index=0;

    if( (NULL == psHciHandle) || (NULL == pHwRef) || (NULL == pHalNotify)
        || (NULL== psContext) || (NULL == psHciLayerCfg) || (NULL == pHwConfig)
    )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else if ( NULL != *(phHciNfc_sContext_t **)psHciHandle )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_ALREADY_INITIALISED );
    }
    else
    {
        /* Create the memory for HCI Context */
        psHciContext = (phHciNfc_sContext_t *) 
                        phOsalNfc_GetMemory(sizeof(phHciNfc_sContext_t));

        if(psHciContext != NULL)
        {
            (void)memset((void *)psHciContext,0,
                                            sizeof(phHciNfc_sContext_t));

            psHciContext->hci_state.cur_state = hciState_Reset;
            psHciContext->hci_mode = hciMode_Reset;
            psHciContext->p_hw_ref = pHwRef;
            psHciContext->host_rf_type = phHal_eUnknown_DevType;
            HCI_PRINT("HCI Initialisation in Progress.... \n");

#ifdef ESTABLISH_SESSION
            /*(void)memcpy(((phHal_sHwReference_t *)pHwRef)->session_id,
                DEFAULT_SESSION, (sizeof(DEFAULT_SESSION) > 0x01) ? 
                  sizeof(DEFAULT_SESSION):
                    sizeof(((phHal_sHwReference_t *)pHwRef)->session_id));*/
            (void)memcpy(pHwConfig->session_id,
                DEFAULT_SESSION, ((sizeof(DEFAULT_SESSION) > 0x01)
                                    && (sizeof(DEFAULT_SESSION) <= 0x08 )) ? 
                  sizeof(DEFAULT_SESSION):
                    sizeof(pHwConfig->session_id));
#endif
            HCI_DEBUG("Sizeof Default Session %u\n",sizeof(DEFAULT_SESSION));
            psHciContext->p_upper_notify = pHalNotify;
            psHciContext->p_upper_context = psContext;

            if_callback.pif_ctxt = psHciContext ;
            if_callback.send_complete = &phHciNfc_Send_Complete;
            if_callback.receive_complete= &phHciNfc_Receive_Complete;
            if_callback.notify = &phHciNfc_Notify_Event;
            plower_if = hciReference.plower_if = &(psHciContext->lower_interface);
            *((phHciNfc_sContext_t **)psHciHandle) = psHciContext;
            psHciContext->init_mode = init_mode;
            psHciContext->p_hci_layer = psHciLayerCfg ;
            lower_index = psHciLayerCfg->layer_index - 1;

            if(NULL != psHciLayerCfg->layer_next->layer_registry)
            {
                status = psHciLayerCfg->layer_next->layer_registry(
                                        &hciReference, if_callback, 
                                        (void *)&psHciLayerCfg[lower_index]);
                HCI_DEBUG("HCI Lower Layer Register, Status = %02X\n",status);
            }
            if( (NFCSTATUS_SUCCESS == status) && (NULL != plower_if->init) )
            {
                status = phHciNfc_FSM_Update ( psHciContext,
                                        hciState_Initialise
                                        );
                if(NFCSTATUS_SUCCESS == status)
                {
                    psHciContext->hci_seq = ADMIN_INIT_SEQ;
                    psHciContext->target_release = FALSE;
                    psHciContext->config_type = POLL_LOOP_CFG;
                    psHciContext->p_config_params = pHwConfig ;
                    status = plower_if->init((void *)plower_if->pcontext, 
                                            (void *)psHciContext->p_hw_ref);
                    HCI_DEBUG("HCI Lower Layer Initialisation, Status = %02X\n",status);
                    if( NFCSTATUS_PENDING != status )
                    {
                        /* Roll Back the State Machine to its Original State */
                        phHciNfc_FSM_Rollback ( psHciContext );
                    }
                }
                else
                {
                    /* TODO: Handle Initialisation in the Invalid State */
                }
            }/* End of Lower Layer Init */
        } /* End of Status Check for Memory */
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES);

            HCI_PRINT("HCI Context Memory Allocation Failed\n");
        }

    }
    return status;
}


/*!
 * \brief Release of the HCI Interface .
 *
 * This function Closes all the open pipes and frees all the resources used by
 * HCI Layer
 */

 NFCSTATUS
 phHciNfc_Release (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    pphNfcIF_Notification_CB_t      pHalReleaseCB,
                    void                            *psContext
                  )
{
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)  
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    /* This Scenario Forces the HCI and the lower layers 
     * to release its Resources 
     */
    else if ( NULL == pHalReleaseCB )
    {
        /* Release the lower layer Resources */
        phHciNfc_Release_Lower( psHciContext, pHwRef );
        /* Release the HCI layer Resources */
        phHciNfc_Release_Resources( &psHciContext );
    }
    else if ( NULL == psContext )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        HCI_PRINT("HCI Release in Progress.... \n");
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Release );
        if ((NFCSTATUS_SUCCESS == status)
#ifdef NXP_HCI_SHUTDOWN_OVERRIDE
            || (NFCSTATUS_INVALID_STATE == PHNFCSTATUS(status))
#endif
            )
        {
            psHciContext->p_upper_notify = pHalReleaseCB;
            psHciContext->p_upper_context = psContext;
            /* psHciContext->hci_seq = EMULATION_REL_SEQ;*/
            /* psHciContext->hci_seq = READER_MGMT_REL_SEQ; */
            if (HCI_SELF_TEST != psHciContext->init_mode)
            {
                psHciContext->hci_seq = PL_STOP_SEQ;
            }
            else
            {
                psHciContext->hci_seq = ADMIN_REL_SEQ;
            }

#ifdef NXP_HCI_SHUTDOWN_OVERRIDE
            if (NFCSTATUS_SUCCESS != status)
            {
                psHciContext->hci_state.next_state = (uint8_t) hciState_Release;
                status = NFCSTATUS_PENDING;
            }
            else
#endif
            {
                status = phHciNfc_Release_Sequence(psHciContext,pHwRef);
            }

            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            /* TODO: Return appropriate Error */
        }

    }

    return status;
}

#if 0
/*!
 * \brief  Interface to Starts the RF Device Discovery. 
 *
 * This function Starts the Discovery Wheel.
 */


 NFCSTATUS
 phHciNfc_Start_Discovery (
                        void                            *psHciHandle,
                        void                            *pHwRef
                     )
{
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if ( (NULL == psHciHandle) 
        || (NULL == pHwRef)
      )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        status = phHciNfc_ReaderMgmt_Enable_Discovery( psHciContext, pHwRef ); 
    }

    return status;
}


/*!
 * \brief  Interface to Stop the RF Device Discovery. 
 *
 * This function Stops the Discovery Wheel.
 */


 NFCSTATUS
 phHciNfc_Stop_Discovery (
                        void                            *psHciHandle,
                        void                            *pHwRef
                     )
{
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if ( (NULL == psHciHandle) 
        || (NULL == pHwRef)
      )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        status = phHciNfc_ReaderMgmt_Disable_Discovery( psHciContext, pHwRef ); 
    }

    return status;
}


#endif

/*!
 * \brief  Interface to Configure the Device With the appropriate
 * Configuration Parameters .
 *
 * This function configures the Devices with the provided
 * configuration attributes.
 */


 NFCSTATUS
 phHciNfc_Configure (
                        void                            *psHciHandle,
                        void                            *pHwRef,
                        phHal_eConfigType_t             config_type,
                        phHal_uConfig_t                 *pConfig
                     )
 {
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        || (NULL == pConfig)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        switch(config_type)
        {
            case NFC_P2P_CONFIG:
            {
#ifdef ENABLE_P2P
                phHciNfc_sContext_t  *psHciContext = 
                            ((phHciNfc_sContext_t *)psHciHandle);
                status = phHciNfc_FSM_Update ( psHciContext, hciState_Config );

                if (NFCSTATUS_SUCCESS == status)
                {
                    psHciContext->config_type = NFC_GENERAL_CFG;
                    psHciContext->p_config_params = &(pConfig->nfcIPConfig);
                    psHciContext->hci_seq = INITIATOR_GENERAL_SEQ;
                    status = phHciNfc_NfcIP_SetATRInfo( psHciHandle,
                                            pHwRef, NFCIP_INITIATOR, 
                                                    &(pConfig->nfcIPConfig));
                    if( NFCSTATUS_PENDING != status )
                    {
                        /* Roll Back the State Machine to its Original State */
                        phHciNfc_FSM_Rollback ( psHciContext );
                    }
                    else
                    {
                        psHciContext->hci_seq = TARGET_GENERAL_SEQ;
                    }
                }
#else
                status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);

#endif
                break;
            }
            case NFC_EMULATION_CONFIG:
            {
                status = phHciNfc_Config_Emulation( psHciHandle,
                                            pHwRef, &(pConfig->emuConfig));
                break;
            }
            case NFC_SE_PROTECTION_CONFIG:
            {
                phHciNfc_sContext_t  *psHciContext = 
                            ((phHciNfc_sContext_t *)psHciHandle);
                status = phHciNfc_FSM_Update ( psHciContext, hciState_Config );

                if (NFCSTATUS_SUCCESS == status)
                {
                    psHciContext->config_type = SWP_PROTECT_CFG;
                    psHciContext->p_config_params = &(pConfig->protectionConfig);
                    psHciContext->hci_seq = HCI_END_SEQ;
                    status = phHciNfc_SWP_Protection( psHciHandle,
                                pHwRef, pConfig->protectionConfig.mode);
                    if( NFCSTATUS_PENDING != status )
                    {
                        /* Roll Back the State Machine to its Original State */
                        phHciNfc_FSM_Rollback ( psHciContext );
                    }
                }
                break;
            }
            default:
            {
                status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
                break;
            } 
        }/* End of the Configuration Switch */
    }

    return status;
 }


/*!
 * \brief  Interface to Configure the RF Device Discovery using 
 * HCI Polling Loop Gate .
 *
 * This function configures the HCI Polling Loop Gate with the provided
 * configuration attributes.
 */

 NFCSTATUS
 phHciNfc_Config_Discovery (
                        void                            *psHciHandle,
                        void                            *pHwRef,
                        phHal_sADD_Cfg_t                *pPollConfig
                     )
{
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        || (NULL == pPollConfig)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        HCI_PRINT("HCI Poll Configuration .... \n");
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Config );

        if (NFCSTATUS_SUCCESS == status)
        {
#if 0
            if(pPollConfig->PollDevInfo.PollEnabled)
            {
                psHciContext->hci_seq = PL_DURATION_SEQ;
            }
            else
            {
                psHciContext->hci_seq = PL_CONFIG_PHASE_SEQ;
                /* psHciContext->hci_seq = (pPollConfig->NfcIP_Mode != 0 )?
                                                    PL_CONFIG_PHASE_SEQ:
                                                        READER_DISABLE_SEQ; */
            }
#endif
            psHciContext->hci_seq = PL_DURATION_SEQ;
            psHciContext->config_type = POLL_LOOP_CFG;
            psHciContext->p_config_params = pPollConfig;
            status = phHciNfc_PollLoop_Sequence( psHciContext, pHwRef );

            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            /* TODO: Return appropriate Error */
        }
    }
    return status;
}

/*!
 * \brief  Interface to Restart the RF Device Discovery. 
 *
 * This function restarts the Discovery Wheel.
 */


 NFCSTATUS
 phHciNfc_Restart_Discovery (
                        void                            *psHciHandle,
                        void                            *pHwRef,
                        uint8_t                         re_poll
                     )
{
    phHciNfc_sContext_t     *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS               status = NFCSTATUS_SUCCESS;
    phHal_eRemDevType_t     target_type = phHal_eUnknown_DevType;

    if ( (NULL == psHciHandle) 
        || (NULL == pHwRef)
      )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;

        /* To be back in the Poll State to Re-Poll the Target */
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Initialise );
        if (NFCSTATUS_SUCCESS == status)
        {
            switch (psHciContext->host_rf_type)
            {
                case phHal_eISO14443_A_PCD:
                {
                    target_type = phHal_eISO14443_A_PICC;
                    break;
                }
                case phHal_eNfcIP1_Initiator:
                {
                    target_type = phHal_eNfcIP1_Target;
                    break;
                }
#ifdef TYPE_B
                case phHal_eISO14443_B_PCD:
                {
                    target_type = phHal_eISO14443_B_PICC;
                    break;
                }
#endif
#ifdef TYPE_FELICA
                case phHal_eFelica_PCD:
                {
                    target_type = phHal_eFelica_PICC;
                    break;
                }
#endif
#ifdef TYPE_JEWEL
                case phHal_eJewel_PCD:
                {
                    target_type = phHal_eJewel_PICC;
                    break;
                }
#endif
#ifdef  TYPE_ISO15693
                case phHal_eISO15693_PCD:
                {
                    target_type = phHal_eISO15693_PICC;
                    break;
                }
#endif /* #ifdef    TYPE_ISO15693 */
#ifndef TYPE_B
                case phHal_eISO14443_B_PCD:
#endif
#ifndef TYPE_FELICA
                case phHal_eFelica_PCD:
#endif
#ifndef TYPE_JEWEL
                case phHal_eJewel_PCD:
#endif
#ifndef TYPE_B_PRIME
                case phHal_eISO14443_BPrime_PCD:
#endif
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
                    break;
                }
                case phHal_eUnknown_DevType:
                default:
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
                    break;
                }
            }/* End of the Remote Target Type Switch */
            if( NFCSTATUS_SUCCESS == status )
            {
                status = phHciNfc_ReaderMgmt_Deselect( 
                    psHciContext, pHwRef, target_type, re_poll);
                if( NFCSTATUS_PENDING != status )
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                }
                else
                {
                    psHciContext->host_rf_type = phHal_eUnknown_DevType;
                }
            }
        }
        else
        {
            /* TODO: Return appropriate Error */
        }
    }

    return status;
}



/*!
 * \brief  Interface to Configure the device to emulation as 
 * the tag, smart tag or p2p target .
 *
 * This function configures the HCI Polling Loop Gate with the provided
 * configuration attributes.
 */

 static
 NFCSTATUS
 phHciNfc_Config_Emulation (
                        void                            *psHciHandle,
                        void                            *pHwRef,
                        phHal_sEmulationCfg_t           *pEmulationCfg
                     )
{
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        || (NULL == pEmulationCfg)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;

        HCI_PRINT("HCI Configure Emulation .... \n");
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Config );

        if (NFCSTATUS_SUCCESS == status)
        {
            psHciContext->hci_seq = EMULATION_CONFIG_SEQ;
            psHciContext->p_config_params = pEmulationCfg;
            switch( pEmulationCfg->emuType )
            {
                case NFC_SMARTMX_EMULATION:
                {
                    psHciContext->config_type = SMX_WI_CFG;
                    status = phHciNfc_Emulation_Cfg(psHciContext, 
                                pHwRef, SMX_WI_CFG);
                    break;
                }
                case NFC_UICC_EMULATION:
                {
                    psHciContext->config_type = UICC_SWP_CFG;
                    psHciContext->hci_seq = EMULATION_CONFIG_SEQ;
                    (void)phHciNfc_SWP_Update_Sequence(
                                        psHciContext, CONFIG_SEQ );
                    status = phHciNfc_EmulationCfg_Sequence(
                                                psHciContext, pHwRef);
                    break;
                }
                case NFC_HOST_CE_A_EMULATION:
                case NFC_HOST_CE_B_EMULATION:
#if defined(HOST_EMULATION)
                {
                    if(TRUE == pEmulationCfg->config.
                        hostEmuCfg_A.enableEmulation)
                    {
                        psHciContext->hci_seq = ADMIN_CE_SEQ;
                    }
                    status = phHciNfc_EmulationCfg_Sequence(
                                                psHciContext, pHwRef);
                    break;
                }
#endif
                default:
                {
                    break;
                }

            } /* End of Config Switch */
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            /* TODO: Return appropriate Error */
        }
    }

    return status;
}
 
 NFCSTATUS
 phHciNfc_Switch_SwpMode (
                        void                            *psHciHandle,
                        void                            *pHwRef,
                        phHal_eSWP_Mode_t               swp_mode /* ,
                        void                            *pSwpCfg */
                     )
{
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;

        HCI_PRINT("HCI SWP Switch .... ");
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Config );
        if (NFCSTATUS_SUCCESS == status)
        {
            psHciContext->config_type = SWP_EVT_CFG;
            status = phHciNfc_SWP_Configure_Mode( psHciContext, pHwRef ,
                                                       (uint8_t) swp_mode );

            /* Send the Success Status as this is an event */
            status = ((status == NFCSTATUS_SUCCESS)?
                    NFCSTATUS_PENDING : status);

            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );

                HCI_PRINT(" Execution Error \n");
            }
            else
            {
                HCI_PRINT(" Successful \n");
            }
        }
        else
        {
            HCI_PRINT(" Not allowed - Invalid State \n");
            /* TODO: Return appropriate Error */
        }
    }

    return status;
}



/*!
 * \brief  Interface to Switch the Mode of the SmartMx from Virtual/Wired 
 * to the other mode.
 *
 * This function switches the mode of the SmartMX connected through WI(S2C)
 * Interface to virtual/wired mode.
 */


 NFCSTATUS
 phHciNfc_Switch_SmxMode (
                        void                            *psHciHandle,
                        void                            *pHwRef,
                        phHal_eSmartMX_Mode_t           smx_mode,
                        phHal_sADD_Cfg_t                *pPollConfig
                    )
{
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        || (NULL == pPollConfig)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;

        HCI_PRINT("HCI Smart MX Mode Switch .... \n");
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Config );

        if (NFCSTATUS_SUCCESS == status)
        {
            psHciContext->hci_seq = READER_DISABLE_SEQ;
            if ( (eSmartMx_Wired == psHciContext->smx_mode)
                && ( hciState_Connect == psHciContext->hci_state.cur_state)
                &&( eSmartMx_Wired != smx_mode)
                )
            {
                /* Workaround: For Wired Mode Disconnect
                   All the statemachine updates should be done only with the
                   Statemachine API and should not be overridden.
                 */
                 psHciContext->hci_state.cur_state = hciState_Disconnect;
            }
            psHciContext->config_type = SMX_WI_MODE;
            psHciContext->smx_mode = smx_mode;
            psHciContext->p_config_params = pPollConfig;
            status = phHciNfc_SmartMx_Mode_Sequence( psHciContext, pHwRef );
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            /* TODO: Return appropriate Error */
        }
    }

    return status;
}


/*!
 * \brief  Interface to Select the Next Remote Target Discovered during the
 * discovery sequence using the particular HCI Reader Gate .
 * 
 *
 * This function Selects and Activates the next Remote Target 
 * Detected using the particular HCI Reader Gate. 
 */



NFCSTATUS
phHciNfc_Select_Next_Target (
                    void                            *psHciHandle,
                    void                            *pHwRef
                    )
{
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS            status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Select );
        if (NFCSTATUS_SUCCESS == status)
        {
            psHciContext->hci_seq = READER_SELECT_SEQ;
            status = phHciNfc_ReaderMgmt_Activate_Next( psHciContext, pHwRef );
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_STATE);
        }
    }

    return status;

}


/*!
 * \brief  Interface to Connect the Remote Target Discovered during the
 * discovery sequence using the particular HCI Reader Gate .
 * 
 *
 * This function connects the Remote Target Detected using the particular 
 * HCI Reader Gate with the appropriate configuration setup.
 */


 NFCSTATUS
 phHciNfc_Connect (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    phHal_sRemoteDevInformation_t   *p_target_info
                 )
 {
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS            status = NFCSTATUS_SUCCESS;
    /* phHal_eRemDevType_t  target_type = phHal_eUnknown_DevType; */

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        || (NULL == p_target_info)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Connect );
        if (NFCSTATUS_SUCCESS == status)
        {
            psHciContext->hci_seq = READER_SELECT_SEQ;
            switch (p_target_info->RemDevType)
            {
                case phHal_eISO14443_A_PICC:
                case phHal_eISO14443_4A_PICC:
                case phHal_eMifare_PICC:
                case phHal_eISO14443_3A_PICC:
#ifdef ENABLE_P2P
                case phHal_eNfcIP1_Target:
#endif
#ifdef TYPE_B
                case phHal_eISO14443_B_PICC:
                case phHal_eISO14443_4B_PICC:
#endif
#ifdef TYPE_FELICA
                case phHal_eFelica_PICC:
#endif
#ifdef TYPE_JEWEL
                case phHal_eJewel_PICC:
#endif
#ifdef  TYPE_ISO15693
                case phHal_eISO15693_PICC:
#endif /* #ifdef    TYPE_ISO15693 */

                {
                    psHciContext->p_target_info = p_target_info;
                    status = phHciNfc_ReaderMgmt_Select( 
                                    psHciContext, pHwRef,
                                    p_target_info->RemDevType );
                    break;
                }
#ifndef TYPE_B_PRIME
                case phHal_eISO14443_BPrime_PICC:
#endif
                case phHal_eUnknown_DevType:
                default:
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
                    break;
                }
            }/* End of the Remote Target Type Switch */
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_STATE);
        }

    } /* End of the HCI Handle Validation */

    return status;
}


/*!
 * \brief  Interface to Reactivate the Remote Targets Discovered during the
 * discovery sequence using the particular HCI Reader Gate .
 * 
 *
 * This function reactivates the Remote Target Detected using the particular 
 * HCI Reader Gate with the appropriate configuration setup.
 */


 NFCSTATUS
 phHciNfc_Reactivate (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    phHal_sRemoteDevInformation_t   *p_target_info
                 )
 {
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS            status = NFCSTATUS_SUCCESS;
    /* phHal_eRemDevType_t  target_type = phHal_eUnknown_DevType; */

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        || (NULL == p_target_info)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Reactivate );
        if (NFCSTATUS_SUCCESS == status)
        {
            psHciContext->hci_seq = READER_REACTIVATE_SEQ;
            switch (p_target_info->RemDevType)
            {
                case phHal_eISO14443_A_PICC:
                case phHal_eISO14443_4A_PICC:
                case phHal_eMifare_PICC:
                case phHal_eISO14443_3A_PICC:
                {
                    psHciContext->host_rf_type = phHal_eISO14443_A_PCD;
                    break;
                }
                case phHal_eNfcIP1_Target:
                {
                    psHciContext->host_rf_type = phHal_eNfcIP1_Initiator;
                    break;
                }
#ifdef TYPE_B
                case phHal_eISO14443_4B_PICC:
                case phHal_eISO14443_B_PICC:
                {
                    psHciContext->host_rf_type = phHal_eISO14443_B_PCD;
                    break;
                }
#endif
#ifdef TYPE_FELICA
                case phHal_eFelica_PICC:
                {
                    psHciContext->host_rf_type = phHal_eFelica_PCD;
                    break;
                }
#endif
#ifdef TYPE_B_PRIME
                case phHal_eISO14443_BPrime_PICC:
#endif
                    /* Reactivate for Jewel is not Supported */
                case phHal_eJewel_PICC:
                case phHal_eUnknown_DevType:
                default:
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
                    break;
                }
            }/* End of the Remote Target Type Switch */
        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_STATE);
        }

        if(NFCSTATUS_SUCCESS == status )
        {
            psHciContext->p_target_info = p_target_info;
            status = phHciNfc_ReaderMgmt_Reactivate( 
                            psHciContext, pHwRef, p_target_info->RemDevType );
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
    } /* End of the HCI Handle Validation */


    return status;
}


/*!
 * \brief  Interface to Disconnect the selected target.
 *
 * This function disconnects the remote target selected.
 */


 NFCSTATUS
 phHciNfc_Disconnect (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    uint8_t                         re_poll
                 )
 {
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS            status = NFCSTATUS_SUCCESS;
    phHal_eRemDevType_t  target_type = phHal_eUnknown_DevType;
    /* phHal_eSmartMX_Mode_t smx_mode = (phHal_eSmartMX_Mode_t)type; */
    static  uint8_t      repoll=0;


    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        || ( NULL == psHciContext->p_target_info)
    )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        repoll = re_poll;
        psHciContext->p_config_params = &repoll;
        /* psHciContext->hci_seq = HCI_END_SEQ; */

        /* To be back in the Poll State to Re-Poll the Target */
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Disconnect );
        if (NFCSTATUS_SUCCESS == status)
        {
            psHciContext->hci_seq = READER_UICC_DISPATCH_SEQ;
            target_type = psHciContext->p_target_info->RemDevType;
            switch (target_type)
            {
                case phHal_eMifare_PICC:
                case phHal_eISO14443_A_PICC:
                case phHal_eISO14443_4A_PICC:
                case phHal_eISO14443_3A_PICC:
                case phHal_eNfcIP1_Target:
#ifdef TYPE_B
                case phHal_eISO14443_B_PICC:
                case phHal_eISO14443_4B_PICC:
#endif
#ifdef TYPE_FELICA
                case phHal_eFelica_PICC:
#endif
#ifdef TYPE_JEWEL
                case phHal_eJewel_PICC:
#endif
#ifdef  TYPE_ISO15693
                case phHal_eISO15693_PICC:
#endif /* #ifdef    TYPE_ISO15693 */

                {
                    status = phHciNfc_Disconnect_Sequence( 
                                    psHciContext, pHwRef );
                    break;
                }
#ifndef TYPE_B
                case phHal_eISO14443_B_PICC:
                case phHal_eISO14443_4B_PICC:
#endif
#ifndef TYPE_FELICA
                case phHal_eFelica_PICC:
#endif
#ifndef TYPE_JEWEL
                case phHal_eJewel_PICC:
#endif
#ifndef TYPE_B_PRIME
                case phHal_eISO14443_BPrime_PICC:
#endif
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
                    break;
                }
                case phHal_eUnknown_DevType:
                default:
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
                    break;
                }
            }/* End of the Remote Target Type Switch */
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            /* TODO: Return appropriate Error */
        }
    } /* End of the HCI Handle Validation */

    return status;
}

/*!
 * \brief  Interface to exchange the data to/from 
 * the selected target.
 * 
 * This function sends and receives the data to/from 
 * the selected remote target.
 */

 NFCSTATUS
 phHciNfc_Exchange_Data (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    phHal_sRemoteDevInformation_t   *p_target_info,
                    phHciNfc_XchgInfo_t             *p_xchg_info
                 )
 {
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        || (NULL == p_target_info)
        || (NULL == p_xchg_info)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else if (p_target_info != psHciContext->p_target_info )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_REMOTE_DEVICE);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Transact ); 
        if (NFCSTATUS_SUCCESS == status)
        {
            switch (p_target_info->RemDevType)
            {
                case phHal_eMifare_PICC:
                case phHal_eISO14443_A_PICC:
                case phHal_eISO14443_4A_PICC:
                case phHal_eISO14443_3A_PICC:
#ifdef TYPE_B
                case phHal_eISO14443_B_PICC:
                case phHal_eISO14443_4B_PICC:
#endif
#ifdef TYPE_FELICA
                case phHal_eFelica_PICC:
#endif
#ifdef TYPE_JEWEL
                case phHal_eJewel_PICC:
#endif
#ifdef  TYPE_ISO15693
                case phHal_eISO15693_PICC:
#endif /* #ifdef    TYPE_ISO15693 */
                {
                    psHciContext->p_xchg_info = p_xchg_info;
                    status = phHciNfc_ReaderMgmt_Exchange_Data( 
                                    psHciContext, pHwRef, p_xchg_info );
                    break;
                }
#ifndef TYPE_B
                case phHal_eISO14443_B_PICC:
                case phHal_eISO14443_4B_PICC:
#endif
#ifndef TYPE_FELICA
                case phHal_eFelica_PICC:
#endif
#ifndef TYPE_JEWEL
                case phHal_eJewel_PICC:
#endif
                case phHal_eNfcIP1_Target:
#ifndef TYPE_B_PRIME
                case phHal_eISO14443_BPrime_PICC:
#endif
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
                    break;
                }
                case phHal_eUnknown_DevType:
                default:
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
                    break;
                }

            }/* End of the Remote Target Type Switch */
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_STATE);
        }
    } /* End of the HCI Handle Validation */

    return status;
}

/*!
 * \brief  Interface to Send the data to/from 
 * the selected NfcIP.
 * 
 * This function sends and receives the data to/from 
 * the selected remote target.
 */

 NFCSTATUS
 phHciNfc_Send_Data (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    phHal_sRemoteDevInformation_t   *p_remote_dev_info,
                    phHciNfc_XchgInfo_t             *p_send_param
                 )
 {
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        || (NULL == p_send_param)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Transact ); 
        if (NFCSTATUS_SUCCESS == status)
        {
            switch (psHciContext->host_rf_type)
            {
                case phHal_eISO14443_A_PICC:
                case phHal_eISO14443_B_PICC:
                case phHal_eISO14443_4A_PICC:
                case phHal_eISO14443_4B_PICC:
                {
                    break;
                }
#ifdef ENABLE_P2P
                case phHal_eNfcIP1_Initiator:
                {
                    if (p_remote_dev_info != 
                                    psHciContext->p_target_info )
                    {
                        status = PHNFCSTVAL(CID_NFC_HCI, 
                                        NFCSTATUS_INVALID_REMOTE_DEVICE);
                    }
                    else
                    {
                        psHciContext->p_xchg_info = p_send_param;
                        status = phHciNfc_NfcIP_Send_Data( psHciContext, 
                                                    pHwRef, p_send_param );
                    }
                    break;
                }
                case phHal_eNfcIP1_Target:
                {
                    psHciContext->p_xchg_info = p_send_param;
                    status = phHciNfc_NfcIP_Send_Data( psHciContext, 
                                                pHwRef, p_send_param );
                    break;
                }
#endif
#ifdef TYPE_B_PRIME
                case phHal_eISO14443_BPrime_PCD:
                case phHal_eFelica_PCD:
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
                    break;
                }
#endif
                case phHal_eUnknown_DevType:
                default:
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
                    break;
                }

            }/* End of the Remote Target Type Switch */
#if defined( ENABLE_P2P ) || defined (TYPE_B_PRIME)
            if( NFCSTATUS_PENDING != status )
#endif
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_STATE);
        }
    } /* End of the HCI Handle Validation */

    return status;

 }

#if 0
    
/*!
 * \brief  Interface to Send the data from 
 * the selected NfcIP.
 * 
 * This function sends and receives the data to/from 
 * the selected remote target.
 */

 NFCSTATUS
 phHciNfc_Receive_Data (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    uint8_t                         *p_data,
                    uint8_t                         length
                 )
 {
    phHciNfc_sContext_t  *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
    NFCSTATUS   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciHandle) 
        || (NULL == pHwRef)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        if (NFCSTATUS_SUCCESS == status)
        {
            status = phHciNfc_Receive(psHciHandle, pHwRef, p_data, length);
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
    }
    return status;

 }

#endif

 /*!
 * \brief  Interface to Check for the presence of
 * the selected target in the field .
 * 
 * This function checks the presence of the 
 * the selected remote target in the field .
 */



NFCSTATUS
phHciNfc_Presence_Check (
                    void                            *psHciHandle,
                    void                            *pHwRef
                    )
{
    NFCSTATUS               status = NFCSTATUS_SUCCESS;
    phHciNfc_sContext_t     *psHciContext = 
                            ((phHciNfc_sContext_t *)psHciHandle);
    phHal_eRemDevType_t     target_type = phHal_eUnknown_DevType;

    if( (NULL == psHciContext) 
        || (NULL == pHwRef)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Presence ); 
        if (NFCSTATUS_SUCCESS == status)
        {
            target_type = psHciContext->p_target_info->RemDevType;
            switch (target_type)
            {
                case phHal_eISO14443_A_PICC:
                case phHal_eMifare_PICC:
                case phHal_eISO14443_4A_PICC:
                case phHal_eISO14443_3A_PICC:
#ifdef TYPE_B
                case phHal_eISO14443_B_PICC:
                case phHal_eISO14443_4B_PICC:
#endif
#ifdef TYPE_FELICA
                case phHal_eFelica_PICC:
#endif
#ifdef TYPE_JEWEL
                case phHal_eJewel_PICC:
#endif
#ifdef  TYPE_ISO15693
                case phHal_eISO15693_PICC:
#endif /* #ifdef    TYPE_ISO15693 */
#ifdef ENABLE_P2P
                case phHal_eNfcIP1_Target:
#endif
                {
                    status = phHciNfc_ReaderMgmt_Presence_Check( 
                                            psHciContext, pHwRef );
                    break;
                }
#ifdef TYPE_B_PRIME
                case phHal_eISO14443_BPrime_PICC:
#endif
#ifndef TYPE_B
                case phHal_eISO14443_B_PICC:
                case phHal_eISO14443_4B_PICC:
#endif
#ifndef TYPE_FELICA
                case phHal_eFelica_PICC:
#endif
#ifndef TYPE_JEWEL
                case phHal_eJewel_PICC:
#endif
                case phHal_eUnknown_DevType:
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
                    break;
                }
                default:
                {
                    /* Roll Back the State Machine to its Original State */
                    phHciNfc_FSM_Rollback ( psHciContext );
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
                    break;
                }

            }/* End of the Remote Target Type Switch */
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_STATE);
        }
    } /* End of the HCI Handle Validation */

    return status;
}

 NFCSTATUS
 phHciNfc_PRBS_Test (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    uint32_t                        test_type,
                    phNfc_sData_t                   *test_param
                 )
 {
    NFCSTATUS               status = NFCSTATUS_SUCCESS;
    phHciNfc_sContext_t     *psHciContext = 
                            ((phHciNfc_sContext_t *)psHciHandle);

    if( (NULL == psHciContext) 
        || (NULL == pHwRef)
        || (test_type != DEVMGMT_PRBS_TEST)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_IO ); 
        if (NFCSTATUS_SUCCESS == status)
        {
            status = phHciNfc_DevMgmt_Test(psHciContext, pHwRef,
                (uint8_t)(test_type & DEVMGMT_TEST_MASK), test_param);
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
    }
    return status;
 }


 NFCSTATUS
 phHciNfc_System_Test (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    uint32_t                        test_type,
                    phNfc_sData_t                   *test_param
                 )
{
    NFCSTATUS               status = NFCSTATUS_SUCCESS;
    phHciNfc_sContext_t     *psHciContext = 
                            ((phHciNfc_sContext_t *)psHciHandle);
    static phNfc_sData_t test_result;
    static uint8_t       gpio_status = 0;

    if( (NULL == psHciContext) 
        || (NULL == pHwRef)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_Test ); 
        if (NFCSTATUS_SUCCESS == status)
        {
            if (test_type != NFC_GPIO_READ)
            {
                status = phHciNfc_DevMgmt_Test(psHciContext, pHwRef,
                    (uint8_t)(test_type & DEVMGMT_TEST_MASK), test_param);
            }
            else
            {
                test_result.buffer = &gpio_status;
                status = phHciNfc_DevMgmt_Get_Info(psHciContext, pHwRef,
                    (uint16_t)NFC_GPIO_READ, test_result.buffer);

            }
            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
    }

     return status;
}


 NFCSTATUS
 phHciNfc_System_Configure (
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    uint32_t                        config_type,
                    uint8_t                         config_value
                 )
{
    NFCSTATUS               status = NFCSTATUS_SUCCESS;
    phHciNfc_sContext_t     *psHciContext = 
                            ((phHciNfc_sContext_t *)psHciHandle);

    if( (NULL == psHciContext) 
        || (NULL == pHwRef)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_IO ); 
        if (NFCSTATUS_SUCCESS == status)
        {
            status = phHciNfc_DevMgmt_Configure(psHciContext, pHwRef,
                (uint16_t)config_type, config_value);

            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
    }
 return status;
}

NFCSTATUS
 phHciNfc_System_Get_Info(
                    void                            *psHciHandle,
                    void                            *pHwRef,
                    uint32_t                        config_type,
                    uint8_t                         *p_config_value
                 )
{
    NFCSTATUS               status = NFCSTATUS_SUCCESS;
    phHciNfc_sContext_t     *psHciContext = 
                            ((phHciNfc_sContext_t *)psHciHandle);

    if( (NULL == psHciContext) 
        || (NULL == pHwRef)
        || (NULL == p_config_value)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_IO ); 
        if (NFCSTATUS_SUCCESS == status)
        {
            status = phHciNfc_DevMgmt_Get_Info(psHciContext, pHwRef,
                (uint16_t)config_type, p_config_value);

            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
    }

 return status;
}


 NFCSTATUS
 phHciNfc_Get_Link_Status(
                    void                            *psHciHandle,
                    void                            *pHwRef
                 )
{
    NFCSTATUS               status = NFCSTATUS_SUCCESS;
    phHciNfc_sContext_t     *psHciContext = 
                            ((phHciNfc_sContext_t *)psHciHandle);

    if( (NULL == psHciContext) 
        || (NULL == pHwRef)
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->p_hw_ref = pHwRef;
        status = phHciNfc_FSM_Update ( psHciContext, hciState_IO ); 
        if (NFCSTATUS_SUCCESS == status)
        {
            status = phHciNfc_LinkMgmt_Open(psHciContext, pHwRef);

            if( NFCSTATUS_PENDING != status )
            {
                /* Roll Back the State Machine to its Original State */
                phHciNfc_FSM_Rollback ( psHciContext );
            }
        }
    }

 return status;
}