/*!
 * \brief Receives the HCI Admin Event from the corresponding peripheral device.
 *
 * This function receives  the HCI Admin Events from the connected NFC Pheripheral
 * device
 */
static
 NFCSTATUS
 phHciNfc_Recv_Admin_Event (
                        void                *psContext,
                        void                *pHwRef,
                        uint8_t             *pEvent,
#ifdef ONE_BYTE_LEN
                        uint8_t             length
#else
                        uint16_t            length
#endif
                     )
{
    phHciNfc_sContext_t         *psHciContext = 
                                    (phHciNfc_sContext_t *)psContext ;
    phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
    phHciNfc_HCP_Message_t      *hcp_message = NULL;
    uint8_t                     event = (uint8_t) HCP_MSG_INSTRUCTION_INVALID;
    NFCSTATUS                   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciContext) 
        || (NULL == pHwRef) 
        || (HCP_HEADER_LEN > length ) 
      )
    {
      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        hcp_packet = (phHciNfc_HCP_Packet_t *)pEvent;
        hcp_message = &hcp_packet->msg.message;
        /* Get the Command instruction bits from the Message Header */
        event = (uint8_t) GET_BITS8( hcp_message->msg_header,
            HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);

        if( EVT_HOT_PLUG ==   event )
        {
            status = phHciNfc_Send_Admin_Event ( psHciContext, pHwRef, 
                                EVT_HOT_PLUG, 0 ,NULL);

        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INSTRUCTION);
        }


    }
    return status;
}
static
NFCSTATUS
phHciNfc_Recv_Felica_Event(
                            void               *psContext,
                            void               *pHwRef,
                            uint8_t            *pEvent,
#ifdef ONE_BYTE_LEN
                            uint8_t             length
#else
                            uint16_t            length
#endif
                            )
{
    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
    phHciNfc_sContext_t         *psHciContext = 
                                (phHciNfc_sContext_t *)psContext ;

    HCI_PRINT ("HCI : phHciNfc_Recv_Felica_Event called...\n");
    if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent)
        || (0 == length))
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else if((NULL == psHciContext->p_felica_info) || 
        (HCI_FELICA_ENABLE != 
        ((phHciNfc_Felica_Info_t *)(psHciContext->p_felica_info))->
        enable_felica_gate))
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
    }
    else
    {
        phHciNfc_HCP_Packet_t       *p_packet = NULL;
        phHciNfc_Felica_Info_t      *p_fel_info = NULL;
        phHciNfc_HCP_Message_t      *message = NULL;
        uint8_t                     instruction=0, 
                                    i = 0;

        p_fel_info = (phHciNfc_Felica_Info_t *)
                                psHciContext->p_felica_info ;
        p_packet = (phHciNfc_HCP_Packet_t *)pEvent;
        message = &p_packet->msg.message;
        /* Get the instruction bits from the Message Header */
        instruction = (uint8_t) GET_BITS8( message->msg_header,
                    HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);

        HCI_DEBUG ("HCI : instruction : %02X\n", instruction);
        HCI_DEBUG ("HCI : Multiple tag found : %02X\n", message->payload[i]);
        if ((EVT_TARGET_DISCOVERED == instruction) 
            && ((FEL_MULTIPLE_TAGS_FOUND == message->payload[i] ) 
            || (FEL_SINGLE_TAG_FOUND == message->payload[i])) 
            )
        {
            static phNfc_sCompletionInfo_t      pCompInfo;

            if (FEL_MULTIPLE_TAGS_FOUND == message->payload[i])
            {
                p_fel_info->multiple_tgts_found = FEL_MULTIPLE_TAGS_FOUND;
                pCompInfo.status = NFCSTATUS_MULTIPLE_TAGS;
            }
            else
            {
                p_fel_info->multiple_tgts_found = FALSE;
                pCompInfo.status = NFCSTATUS_SUCCESS;
            }

            HCI_DEBUG ("HCI : psHciContext->host_rf_type : %02X\n", psHciContext->host_rf_type);
            HCI_DEBUG ("HCI : p_fel_info->felica_info.RemDevType : %02X\n", p_fel_info->felica_info.RemDevType);
            HCI_DEBUG ("HCI : p_fel_info->current_seq : %02X\n", p_fel_info->current_seq);

            psHciContext->host_rf_type = phHal_eFelica_PCD;
            p_fel_info->felica_info.RemDevType = phHal_eFelica_PICC;
            p_fel_info->current_seq = FELICA_SYSTEMCODE;

            /* Notify to the HCI Generic layer To Update the FSM */
            phHciNfc_Notify_Event(psHciContext, pHwRef, 
                                NFC_NOTIFY_TARGET_DISCOVERED, 
                                &pCompInfo);

        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
        }
    }
    HCI_PRINT ("HCI : phHciNfc_Recv_Felica_Event end\n");
    return status;
}
NFCSTATUS
phHciNfc_CoreRecvCB(void                           *pContext,
                    void                           *pInfo,
                    NFCSTATUS                      wStatus
                   )
{
    uint8_t bChainBit = 0;
    pphHciNfc_sCoreRecvBuff_List_t pNode = NULL;
    phHciNfc_ReceiveParams_t tHciNfcRxdParams;
    phNciNfc_TransactInfo_t        *pHciCoreReceiveInfo;
    NFCSTATUS wStat;

    if(pContext != NULL)
    {
        if(pInfo != NULL)
        {
            phHciNfc_HciContext_t      *pHciContext     = (phHciNfc_HciContext_t *) pContext;
            phHciNfc_HciCoreContext_t  *pHciCoreContext = &(pHciContext->pHciCoreContext);
            pHciCoreReceiveInfo                         = (phNciNfc_TransactInfo_t*)pInfo;

            if(wStatus == NFCSTATUS_SUCCESS)
            {
                bChainBit = (uint8_t) GET_BITS8(*(pHciCoreReceiveInfo->pbuffer),
                                                PHHCINFC_HCP_CHAINBIT_OFFSET,
                                                PHHCINFC_HCP_CHAINBIT_LEN);

                /* Store/Buffer HCP Header along with Data irrespective of whether chained or Unchained */
                if(pHciCoreReceiveInfo->wLength <= PHHCI_HCP_MAX_RECEIVE_PACKET_SIZE)
                {
                    /* Create the Data Node and copy the Data */
                    pNode = phHciNfc_CoreGetNewNode(pHciCoreContext,pHciCoreReceiveInfo->wLength);
                    if(pNode != NULL)
                    {
                        phOsalNfc_MemCopy((uint8_t*)&(pNode->tMem.aBuffer[0]),
                                          (uint8_t*)(pHciCoreReceiveInfo->pbuffer),
                                          pHciCoreReceiveInfo->wLength);
                        pNode->tMem.wLen      = pHciCoreReceiveInfo->wLength;
                    }else
                    {
                        PH_LOG_LIBNFC_CRIT_STR(" HCI Core Receive- Failed To Allocate Memory for Node");
                    }
                }else
                {
                    /* HCP Packet should not be bigger than PHHCI_HCP_MAX_PACKET_SIZE */
                }
                /* Check Chaining Bit to asceratain whether complete Message is received or Not*/
                if(bChainBit == HCP_CHAINBIT_UN_CHAINED)
                {
                    /* HCI message is complete extract the Data from linked list*/
                    tHciNfcRxdParams.pData = phOsalNfc_GetMemory(pHciCoreContext->tReceiveInfo.wPayloadSize);
                    wStat = phHciNfc_HciCoreExtractData(pHciCoreContext,&tHciNfcRxdParams);
                    if(wStat == NFCSTATUS_SUCCESS)
                    {
                        /*Once the HCI Packets are Extracted ,HCI packet info is captured so delete the linked list */
                        phHciNfc_CoreDeleteList(pHciCoreContext);
                        /* Send the Received Data To upper layer*/
                        /* TO DO Registration mechanism to be implemented*/
                        phHciNfc_ReceiveHandler(pHciContext,
                                                &tHciNfcRxdParams,
                                                wStatus
                                                );
                        phOsalNfc_FreeMemory(tHciNfcRxdParams.pData);
                    }else
                    {
                            PH_LOG_LIBNFC_CRIT_STR(" HCI Core - HCI Packet Extraction Failed");
                    }
                }
                else
                {
                    /* Chained HCI packets which are already buffered
                    ** No Action here waits for complete HCI Msg to be Rxd
                    */
                }
            }else
            {
                /* Failed Status from lower layer- Call the upper layer call back with the returned status */
                /* Send the Received Data To upper layer*/
                phHciNfc_ReceiveHandler(pHciContext->pHciCoreContext.pUpperLayerContext,
                                        NULL,
                                        wStatus
                                        );
            }
        }
        else
        {
            /* Do Nothing if no information is received from lower layer */
            PH_LOG_LIBNFC_CRIT_STR(" Invalid Receive Info Pointer received from lower layer ");
        }
    }else
    {
        PH_LOG_LIBNFC_CRIT_STR(" Invalid HCI Context received from Lower Layer ");
    }
    return wStatus;

}
static 
NFCSTATUS
phHciNfc_Recv_SWP_Event(
                        void                *psContext,
                        void                *pHwRef,
                        uint8_t             *pEvent,
#ifdef ONE_BYTE_LEN
                        uint8_t             length
#else
                        uint16_t            length
#endif
                       )
{
    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
    phHciNfc_sContext_t         *psHciContext = 
                                (phHciNfc_sContext_t *)psContext ;
    static phHal_sEventInfo_t   EventInfo;
    

    if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent)
        || (length == 0))
    {
      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else if(NULL == psHciContext->p_swp_info)
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
    }
    else
    {
        phHciNfc_SWP_Info_t     *ps_swp_info=NULL;

        ps_swp_info = (phHciNfc_SWP_Info_t *)
                        psHciContext->p_swp_info ;
        if( NULL == ps_swp_info->p_pipe_info)
        {
            status = PHNFCSTVAL(CID_NFC_HCI, 
                            NFCSTATUS_INVALID_HCI_INFORMATION);
        }
        else
        {
            phHciNfc_HCP_Packet_t       *p_packet = NULL;
            phHciNfc_HCP_Message_t      *message = NULL;
            uint8_t                     EventType = 0;                      

            p_packet = (phHciNfc_HCP_Packet_t *)pEvent;
            message = &(p_packet->msg.message);
            /* Get the instruction bits from the Message Header */
            EventType = (uint8_t) GET_BITS8( message->msg_header,
                HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);

            EventInfo.eventHost = phHal_eHostController;
            EventInfo.eventSource = phHal_ePICC_DevType;
            /* Occurrence of the Protected events for reporting */
            if (NXP_EVT_SWP_PROTECTED == EventType) 
            {
                EventInfo.eventType = NFC_EVT_PROTECTED;
            }
            else
            {
                status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
            }

            if (NFCSTATUS_SUCCESS == status )
            {
                phHciNfc_Notify_Event(  psHciContext, pHwRef, 
                NFC_NOTIFY_EVENT, (void*)&EventInfo);
            }

        }
    }
    return status;
}
void 
phLlcNfc_StopAllTimers (void)
{

#ifdef LLC_TIMER_ENABLE

    phLlcNfc_Timerinfo_t    *ps_timer_info = NULL;
    uint8_t                 timer_started = 0;
    uint32_t                timerid = 0;
    uint8_t                 timer_index = 0;
    

    ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo);

    PH_LLCNFC_PRINT("\n\nLLC : STOP ALL TIMERS CALLED \n\n");

    timerid = ps_timer_info->timer_id[timer_index];
    timer_started = (uint8_t)
                GET_BITS8(ps_timer_info->timer_flag, 
                        PH_LLCNFC_CON_TO_BIT, 
                        PH_LLCNFC_TO_NOOFBITS);

    PH_LLCNFC_DEBUG("CONNECTION TIMER ID: 0x%02X\n", timerid);

    if (0 != timer_started)
    {
        /* Connection timer is started, so now stop it */
        ps_timer_info->timer_flag = (uint8_t)
                        SET_BITS8 (ps_timer_info->timer_flag, 
                                    PH_LLCNFC_CON_TO_BIT, 
                                    PH_LLCNFC_TO_NOOFBITS, 0);
#if 0

        ps_timer_info->con_to_value = 0;

#endif /* #if 0 */

        phOsalNfc_Timer_Stop (timerid);
    }

    timer_index = (uint8_t)(timer_index + 1);
    timerid = ps_timer_info->timer_id[timer_index];
    timer_started = (uint8_t)GET_BITS8 (ps_timer_info->timer_flag, 
                                        PH_LLCNFC_GUARD_TO_BIT, 
                                        PH_LLCNFC_TO_NOOFBITS);

    if (0 != timer_started)
    {
        /* Guard timer is already started */
        ps_timer_info->timer_flag = (uint8_t)
                        SET_BITS8 (ps_timer_info->timer_flag, 
                                    PH_LLCNFC_GUARD_TO_BIT, 
                                    PH_LLCNFC_TO_NOOFBITS, 0);

        timer_index = 0;
        ps_timer_info->guard_to_count = 0;

#if 0

        /* Reset all the guard timer related variables */
        while (timer_index < ps_timer_info->guard_to_count)
        {            
            ps_timer_info->guard_to_value[timer_index] = 0;
            ps_timer_info->iframe_send_count[timer_index] = 0;

            timer_index = (uint8_t)(timer_index + 1);
        }        

#endif /* #if 0 */

        PH_LLCNFC_DEBUG("GUARD TIMER ID: 0x%02X\n", timerid);

        /* Stop the timer */
        phOsalNfc_Timer_Stop (timerid);

        PH_LLCNFC_PRINT("\n\nLLC : STOP ALL TIMERS END \n\n");
    }

#endif /* #ifdef LLC_TIMER_ENABLE */
}
NFCSTATUS 
phLlcNfc_StartTimers (
    uint8_t             TimerType, 
    uint8_t             ns_value
)
{
    NFCSTATUS               result = NFCSTATUS_SUCCESS;
#ifdef LLC_TIMER_ENABLE

    uint32_t                timerid = 0;
    uint8_t                 timerstarted = 0;
    uint8_t                 timer_count = 0;
    uint16_t                timer_resolution = 0;
    ppCallBck_t             Callback = NULL;
    phLlcNfc_Timerinfo_t    *ps_timer_info = NULL;

    ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo);
    PHNFC_UNUSED_VARIABLE(result);

    PH_LLCNFC_PRINT("\n\nLLC : START TIMER CALLED\n\n");
    /* Depending on the timer type, use the Osal callback */
    switch(TimerType)
    {
        case PH_LLCNFC_CONNECTIONTIMER:
        {
            /* Get the connection timer flag */
            timerstarted = (uint8_t)
                GET_BITS8(ps_timer_info->timer_flag, 
                        PH_LLCNFC_CON_TO_BIT, 
                        PH_LLCNFC_TO_NOOFBITS);
            if (0 == timerstarted)
            {
                /* Timer not started, so start the timer */
                gpphLlcNfc_Ctxt->s_timerinfo.timer_flag = (uint8_t)
                                SET_BITS8 (ps_timer_info->timer_flag,
                                        PH_LLCNFC_CON_TO_BIT, 
                                        PH_LLCNFC_TO_NOOFBITS, 
                                        (PH_LLCNFC_CON_TO_BIT + 1));
            }
            
            timerid = ps_timer_info->timer_id[PH_LLCNFC_CONNECTION_TO_INDEX];
            Callback = (ppCallBck_t)&phLlcNfc_ConnectionTimeoutCb;
            timer_resolution = ps_timer_info->con_to_value = (uint16_t)
                                            PH_LLCNFC_CONNECTION_TO_VALUE;
            break;
        }

        case PH_LLCNFC_GUARDTIMER:
        {
            if (ps_timer_info->guard_to_count < PH_LLCNFC_MAX_GUARD_TIMER)
            {
                timer_count = ps_timer_info->guard_to_count;
                timer_resolution = (uint16_t)PH_LLCNFC_RESOLUTION;

                PH_LLCNFC_DEBUG("RESOLUTION VALUE : 0x%02X\n", PH_LLCNFC_RESOLUTION);
                PH_LLCNFC_DEBUG("TIME-OUT VALUE : 0x%02X\n", PH_LLCNFC_GUARD_TO_VALUE);
                
                /* Get the guard timer flag */
                timerstarted = (uint8_t)
                    GET_BITS8 (ps_timer_info->timer_flag, 
                            PH_LLCNFC_GUARD_TO_BIT, 
                            PH_LLCNFC_TO_NOOFBITS);

                PH_LLCNFC_DEBUG("GUARD TIMER NS INDEX : 0x%02X\n", ns_value);
                PH_LLCNFC_DEBUG("GUARD TIMER COUNT : 0x%02X\n", timer_count);
                PH_LLCNFC_DEBUG("GUARD TIMER STARTED : 0x%02X\n", timerstarted);

                if (0 == timerstarted)
                {
                    /* Timer not started, so start the timer */
                    ps_timer_info->timer_flag = (uint8_t)
                        SET_BITS8 (ps_timer_info->timer_flag,
                                    PH_LLCNFC_GUARD_TO_BIT, 
                                    PH_LLCNFC_TO_NOOFBITS, 
                                    PH_LLCNFC_GUARD_TO_BIT);
                }
                
                timerid = ps_timer_info->timer_id[PH_LLCNFC_GUARDTIMER];
                Callback = (ppCallBck_t)&phLlcNfc_GuardTimeoutCb;

                /* Guard time out value */
                ps_timer_info->guard_to_value[timer_count] = (uint16_t)
                                        PH_LLCNFC_GUARD_TO_VALUE;

                ps_timer_info->timer_ns_value[timer_count] = ns_value;
                ps_timer_info->frame_type[timer_count] = (uint8_t)invalid_frame;
                ps_timer_info->iframe_send_count[timer_count] = 0;

                if ((timer_count > 0) && 
                    (ps_timer_info->guard_to_value[(timer_count - 1)] >= 
                    PH_LLCNFC_GUARD_TO_VALUE))
                {
                    /* If the timer has been started already and the 
                        value is same as the previous means that timer has still 
                        not expired, so the time out value is increased by 
                        a resolution */
                    ps_timer_info->guard_to_value[timer_count] = (uint16_t)
                            (ps_timer_info->guard_to_value[(timer_count - 1)] + 
                            PH_LLCNFC_RESOLUTION);
                }

                PH_LLCNFC_DEBUG("GUARD TIMER VALUE : 0x%04X\n", ps_timer_info->guard_to_value[timer_count]);

                
                ps_timer_info->guard_to_count = (uint8_t)(
                                        ps_timer_info->guard_to_count + 1);
            }
            else
            {
                /* TIMER should not start, because the time out count has readched the limit */
                timerstarted = TRUE;
            }
            break;
        }
        
#ifdef PIGGY_BACK

        case PH_LLCNFC_ACKTIMER:
        {
            /* Get the ack timer flag */
            timerstarted = (uint8_t)GET_BITS8 (
                                    ps_timer_info->timer_flag, 
                                    PH_LLCNFC_GUARD_TO_BIT, 
                                    PH_LLCNFC_TO_NOOFBITS);
            if (0 == timerstarted)
            {
                /* Timer not started, so start the timer */
                ps_timer_info->timer_flag = (uint8_t)
                                SET_BITS8 (ps_timer_info->timer_flag, 
                                        PH_LLCNFC_GUARD_TO_BIT
                                        PH_LLCNFC_TO_NOOFBITS
                                        (PH_LLCNFC_GUARD_TO_BIT - 1));
            }
            timerid = ps_timer_info->timer_id[PH_LLCNFC_ACKTIMER];
            Callback = (ppCallBck_t)&phLlcNfc_AckTimeoutCb;
            break;
        }

#endif /* #ifdef PIGGY_BACK */

        default:
        {
            result = PHNFCSTVAL(CID_NFC_LLC, 
                                NFCSTATUS_INVALID_PARAMETER);
            break;
        }
    }
    if ((NFCSTATUS_SUCCESS == result) && 
        (FALSE == timerstarted))
    {
        PH_LLCNFC_DEBUG("OSAL START TIMER CALLED TIMER ID : 0x%02X\n", timerid);
        phOsalNfc_Timer_Start (timerid, timer_resolution, Callback, NULL);
    }

    PH_LLCNFC_PRINT("\n\nLLC : START TIMER END\n\n");

#else /* #ifdef LLC_TIMER_ENABLE */

    PHNFC_UNUSED_VARIABLE(result);
    PHNFC_UNUSED_VARIABLE(TimerType);
    PHNFC_UNUSED_VARIABLE(ns_value);    

#endif /* #ifdef LLC_TIMER_ENABLE */
    return result;
}
/*!
 * \brief Receives the HCI Admin Commands from the corresponding peripheral device.
 *
 * This function receives  the HCI Admin Commands from the connected NFC Pheripheral
 * device
 */
static
 NFCSTATUS
 phHciNfc_Recv_Admin_Cmd (
                        void                *psContext,
                        void                *pHwRef,
                        uint8_t             *pCmd,
#ifdef ONE_BYTE_LEN
                        uint8_t             length
#else
                        uint16_t            length
#endif
                     )
{
    phHciNfc_sContext_t         *psHciContext = 
                                    (phHciNfc_sContext_t *)psContext ;
    phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
    phHciNfc_HCP_Message_t      *hcp_message = NULL;
    phHciNfc_AdminGate_Info_t   *p_admin_info=NULL;
    phHciNfc_Pipe_Info_t        *p_pipe_info = NULL;
    uint8_t                     index=0;
    uint8_t                     pipe_id = (uint8_t) HCI_UNKNOWN_PIPE_ID;
    uint8_t                     cmd = (uint8_t) HCP_MSG_INSTRUCTION_INVALID;
    uint8_t                     response = (uint8_t) ANY_OK;
    NFCSTATUS                   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciContext) 
        || (NULL == pHwRef) 
        || (HCP_HEADER_LEN > length ) 
      )
    {
      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        hcp_packet = (phHciNfc_HCP_Packet_t *)pCmd;
        hcp_message = &hcp_packet->msg.message;
        p_admin_info = psHciContext->p_admin_info;
        /* Get the Command instruction bits from the Message Header */
        cmd = (uint8_t) GET_BITS8( hcp_message->msg_header,
            HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);

        switch( cmd )
        {
            /* These are notifications sent by the Host Controller */
            case ADM_NOTIFY_PIPE_CREATED:
            {
                pipe_id = hcp_message->payload[RESPONSE_PIPEID_OFFSET];
                p_pipe_info = (phHciNfc_Pipe_Info_t *)
                        phOsalNfc_GetMemory(sizeof(phHciNfc_Pipe_Info_t));
                if(NULL != p_pipe_info)
                {
                    /* The Source Host is the UICC Host */
                    p_pipe_info->pipe.source.host_id = 
                                    hcp_message->payload[index++];
                    /* The Source Gate is same as the Destination Gate */
                    p_pipe_info->pipe.source.gate_id    = 
                                    hcp_message->payload[index++];
                    /* The Source Host is the Terminal Host */
                    p_pipe_info->pipe.dest.host_id = 
                                    hcp_message->payload[index++];
                    p_pipe_info->pipe.dest.gate_id  = 
                                    hcp_message->payload[index++];
                    p_pipe_info->pipe.pipe_id   = 
                                    hcp_message->payload[index++];
                }
                status = phHciNfc_Update_PipeInfo(psHciContext,
                    &(p_admin_info->pipe_seq), pipe_id, p_pipe_info);

                if( NFCSTATUS_SUCCESS == status )
                {
                    psHciContext->p_pipe_list[pipe_id] = p_pipe_info;
                    if (NULL != p_pipe_info)
                    {
                        p_pipe_info->pipe.pipe_id = pipe_id;
                    }
                }
                break;
            }
            case ADM_NOTIFY_PIPE_DELETED:
            {
                pipe_id = hcp_message->payload[index++];
                p_pipe_info = psHciContext->p_pipe_list[pipe_id];
                if ( NULL != p_pipe_info )
                {
                        status = phHciNfc_Update_PipeInfo(
                            psHciContext, &(p_admin_info->pipe_seq),
                             (uint8_t) HCI_UNKNOWN_PIPE_ID, p_pipe_info);
                    if(NFCSTATUS_SUCCESS == status )
                    {
                        phOsalNfc_FreeMemory(p_pipe_info);
                        psHciContext->p_pipe_list[pipe_id] = NULL;
                    }
                }
                break;
            }
            /* TODO: Since we receive the Host ID, we need to clear
             * all the pipes created with the host
             */
            case ADM_NOTIFY_ALL_PIPE_CLEARED:
            {
                break;
            }
            /* case ADM_CREATE_PIPE: */
            /* case ADM_DELETE_PIPE: */
            /* case ADM_CLEAR_ALL_PIPE: */
            default:
            {
                response = ANY_E_CMD_NOT_SUPPORTED;
                status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_COMMAND_NOT_SUPPORTED);
                break;
            }
        }
        hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
        phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
                                (uint8_t) HCI_ADMIN_PIPE_ID,
                                HCP_MSG_TYPE_RESPONSE, response );
        psHciContext->tx_total = HCP_HEADER_LEN;
        status = phHciNfc_Send_HCP( (void *)psHciContext, (void *)pHwRef );

        p_admin_info->admin_pipe_info->recv_msg_type = HCP_MSG_TYPE_COMMAND;
        p_admin_info->admin_pipe_info->sent_msg_type = HCP_MSG_TYPE_RESPONSE;
        p_admin_info->admin_pipe_info->prev_msg = response;
        p_admin_info->admin_pipe_info->prev_status = NFCSTATUS_PENDING;
    }
    return status;
}
static
NFCSTATUS
phHciNfc_Recv_ReaderB_Event(
                            void               *psContext,
                            void               *pHwRef,
                            uint8_t            *pEvent,
#ifdef ONE_BYTE_LEN
                            uint8_t             length
#else
                            uint16_t            length
#endif
                            )
{
    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
    phHciNfc_sContext_t         *psHciContext = 
                                (phHciNfc_sContext_t *)psContext ;
    if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent)
        || (length == 0))
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else if((NULL == psHciContext->p_reader_b_info) || 
        (HCI_READER_B_ENABLE != 
        ((phHciNfc_ReaderB_Info_t *)(psHciContext->p_reader_b_info))->
        enable_rdr_b_gate))
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
    }
    else
    {
        phHciNfc_HCP_Packet_t       *p_packet = NULL;
        phHciNfc_ReaderB_Info_t     *p_rdr_b_info=NULL;
        phHciNfc_HCP_Message_t      *message = NULL;
        uint8_t                     instruction=0, 
                                    i = 0;

        p_rdr_b_info = (phHciNfc_ReaderB_Info_t *)
                                    psHciContext->p_reader_b_info ;
        p_packet = (phHciNfc_HCP_Packet_t *)pEvent;
        message = &p_packet->msg.message;
        /* Get the instruction bits from the Message Header */
        instruction = (uint8_t) GET_BITS8( message->msg_header,
                        HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);

        if ((EVT_TARGET_DISCOVERED == instruction) 
            && ((RDR_B_MULTIPLE_TAGS_FOUND == message->payload[i] ) 
            || (RDR_B_SINGLE_TAG_FOUND == message->payload[i])) 
            )
        {
            phNfc_sCompletionInfo_t pCompInfo;

            if (RDR_B_MULTIPLE_TAGS_FOUND == message->payload[i])
            {
                p_rdr_b_info->multiple_tgts_found = RDR_B_MULTIPLE_TAGS_FOUND;
                pCompInfo.status = NFCSTATUS_MULTIPLE_TAGS;
            }
            else
            {
                p_rdr_b_info->multiple_tgts_found = FALSE;
                pCompInfo.status = NFCSTATUS_SUCCESS;
            }

            psHciContext->host_rf_type = phHal_eISO14443_B_PCD;
            p_rdr_b_info->reader_b_info.RemDevType = phHal_eISO14443_B_PICC;
            p_rdr_b_info->current_seq = RDR_B_PUPI;

            /* Notify to the HCI Generic layer To Update the FSM */
            phHciNfc_Notify_Event(psHciContext, pHwRef, 
                                    NFC_NOTIFY_TARGET_DISCOVERED, 
                                    &pCompInfo);

        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
        }
    }
    return status;
}