/*
 * 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  hHciNfc_AdminMgmt.c                                                  *
* \brief HCI Admin Gate Management Routines.                                  *
*                                                                             *
*                                                                             *
* Project: NFC-FRI-1.1                                                        *
*                                                                             *
* $Date: Mon Apr  5 19:23:34 2010 $                                           *
* $Author: ing04880 $                                                         *
* $Revision: 1.47 $                                                           *
* $Aliases: NFC_FRI1.1_WK1007_R33_4,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 <phNfcCompId.h>
#include <phHciNfc_Pipe.h>
#include <phHciNfc_AdminMgmt.h>
#include <phHciNfc_DevMgmt.h>
#include <phOsalNfc.h>
/*
****************************** Macro Definitions *******************************
*/

#define SESSION_INDEX       0x01U
#define MAX_PIPE_INDEX      0x02U
#define WHITELIST_INDEX     0x03U
#define HOST_LIST_INDEX     0x04U

/* Max Whitelist Supported by the Device*/
#define SESSIONID_LEN       0x08U
#define WHITELIST_MAX_LEN   0x03U
#define HOST_LIST_MAX_LEN   0x05U

/* Address Definitions for HW Configuration */
#define NFC_ADDRESS_UICC_SESSION        0x9EA2U



/*
*************************** Structure and Enumeration ***************************
*/

typedef enum phHciNfc_Admin_Seq{
    ADMIN_PIPE_OPEN     = 0x00U,
    ADMIN_GET_HOST_LIST,
    ADMIN_GET_WHITE_LIST,
    ADMIN_GET_SESSION,
    ADMIN_VERIFY_SESSION,
    ADMIN_CLEAR_UICC_PIPES,
    ADMIN_CLEAR_PIPES,
    ADMIN_PIPE_REOPEN,
    ADMIN_CREATE_PIPES,
    ADMIN_SET_SESSION,
    ADMIN_SET_WHITE_LIST,
    ADMIN_UPDATE_PIPES,
    ADMIN_PIPE_CLOSE,
    ADMIN_DELETE_PIPES,
    ADMIN_END_SEQUENCE
} phHciNfc_Admin_Seq_t;


/* Information structure for the Admin Gate */
typedef struct phHciNfc_AdminGate_Info{
    /* Current running Sequence of the Admin Management */
    phHciNfc_Admin_Seq_t            current_seq;
    /* Next running Sequence of the Admin Management */
    phHciNfc_Admin_Seq_t            next_seq;
    /* Pointer to the Admin Pipe Information */
    phHciNfc_Pipe_Info_t            *admin_pipe_info;
    /* Sequence for the Pipe Initialisation */
    phHciNfc_PipeMgmt_Seq_t         pipe_seq;
    /* Session ID of the Device */
    uint8_t                         session_id[SESSIONID_LEN];
    /* Max number of pipes that can be created on the Device */
    uint8_t                         max_pipe;
    /* List of Hosts that can be access the device Admin Gate. */
    uint8_t                         whitelist[WHITELIST_MAX_LEN];
    /* Host List from the Host Controller */
    uint8_t                         host_list[HOST_LIST_MAX_LEN];
} phHciNfc_AdminGate_Info_t;

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

/**
 * \ingroup grp_hci_nfc
 *
 *  The phHciNfc_Recv_Admin_Response function interprets the received AdminGate
 *  response from the Host Controller Gate.
 *
 *  \param[in]  psHciContext            psHciContext is the pointer to HCI Layer
 *                                      context Structure.
 *  \param[in]  pHwRef                  pHwRef is the Information of
 *                                      the Device Interface Link .
 *  \param[in,out]  pResponse           Response received from the Host Cotroller
 *                                      Admin gate.
 *  \param[in]  length                  length contains the length of the
 *                                      response received from the Host Controller.
 *
 *  \retval NFCSTATUS_PENDING           AdminGate Response to be received is pending.
 *  \retval NFCSTATUS_SUCCESS           AdminGate Response received Successfully.
 *  \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
 *                                      could not be interpreted properly.
 *  \retval Other errors                Errors related to the other layers
 *
 */

static
NFCSTATUS
phHciNfc_Recv_Admin_Response(
                        void                *psHciContext,
                        void                *pHwRef,
                        uint8_t             *pResponse,
#ifdef ONE_BYTE_LEN
                        uint8_t             length
#else
                        uint16_t            length
#endif
                       );


static
NFCSTATUS
phHciNfc_Admin_InfoUpdate(
                                phHciNfc_sContext_t     *psHciContext,
                                phHal_sHwReference_t    *pHwRef,
                                uint8_t                 index,
                                uint8_t                 *reg_value,
                                uint8_t                 reg_length
                         );

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


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


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



/*!
 * \brief Initialisation of Admin Gate and Establish the Session .
 *
 * This function initialses the Admin Gates and Establishes the Session by creating
 * all the required pipes and sets the Session ID
 * 
 */

NFCSTATUS
phHciNfc_Admin_Initialise(
                                phHciNfc_sContext_t     *psHciContext,
                                void                    *pHwRef
                         )
{
    NFCSTATUS                           status = NFCSTATUS_SUCCESS;
    phHciNfc_Pipe_Info_t                *p_pipe_info = NULL;
    phHciNfc_AdminGate_Info_t           *p_admin_info=NULL;
    uint8_t                             length = 0;

    if( (NULL == psHciContext)
        || (NULL == pHwRef )
        )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        if( ( NULL == psHciContext->p_admin_info )
            && (phHciNfc_Allocate_Resource((void **)(&p_admin_info),
                    sizeof(phHciNfc_AdminGate_Info_t))== NFCSTATUS_SUCCESS)
          )
        {
            psHciContext->p_admin_info = (void *) p_admin_info;
            p_admin_info->current_seq = ADMIN_PIPE_OPEN;
            p_admin_info->next_seq = ADMIN_END_SEQUENCE;
            p_admin_info->admin_pipe_info = NULL;
        }
        else
        {
            p_admin_info = (phHciNfc_AdminGate_Info_t * )
                                psHciContext->p_admin_info ;
        }

        if( NULL == p_admin_info)
        {
            status = PHNFCSTVAL(CID_NFC_HCI,
                        NFCSTATUS_INSUFFICIENT_RESOURCES);
        }
        else
        {
            switch(p_admin_info->current_seq)
            {
                /* Admin pipe open sequence , Initially open the Admin Pipe */
                case ADMIN_PIPE_OPEN:
                {
                    if(phHciNfc_Allocate_Resource((void **)(&p_pipe_info),
                        sizeof(phHciNfc_Pipe_Info_t))!= NFCSTATUS_SUCCESS)
                    {
                        status = PHNFCSTVAL(CID_NFC_HCI,
                                NFCSTATUS_INSUFFICIENT_RESOURCES);
                    }
                    else
                    {
                        /* Populate the pipe information in the pipe handle */
                        ((phHciNfc_Pipe_Info_t *)p_pipe_info)->pipe.pipe_id = 
                                        PIPETYPE_STATIC_ADMIN;
                        ((phHciNfc_Pipe_Info_t *)p_pipe_info)->recv_resp = 
                                        &phHciNfc_Recv_Admin_Response;
                        ((phHciNfc_Pipe_Info_t *)p_pipe_info)->recv_cmd = 
                                        &phHciNfc_Recv_Admin_Cmd;
                        ((phHciNfc_Pipe_Info_t *)p_pipe_info)->recv_event = 
                                        &phHciNfc_Recv_Admin_Event;
                        psHciContext->p_pipe_list[PIPETYPE_STATIC_ADMIN] =
                                                                    p_pipe_info ;
                        status = phHciNfc_Open_Pipe( psHciContext,
                                                            pHwRef,p_pipe_info );
                        if(status == NFCSTATUS_SUCCESS)
                        {
                            p_admin_info->admin_pipe_info = p_pipe_info ;
                            p_admin_info->next_seq = ADMIN_GET_SESSION;
                            status = NFCSTATUS_PENDING;
                        }
                    }
                    break;
                }
                case ADMIN_GET_SESSION:
                {
                    p_pipe_info = p_admin_info->admin_pipe_info;
                    p_pipe_info->reg_index = SESSION_INDEX;
                    p_pipe_info->prev_status = 
                        phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, 
                            (uint8_t)HCI_ADMIN_PIPE_ID,
                                (uint8_t)ANY_GET_PARAMETER);
                    if(NFCSTATUS_PENDING == p_pipe_info->prev_status )
                    {
#ifdef UICC_SESSION_RESET
                        p_admin_info->next_seq = ADMIN_CLEAR_UICC_PIPES;
#elif defined (ESTABLISH_SESSION)
                        p_admin_info->next_seq = ADMIN_VERIFY_SESSION;
#else
                        p_admin_info->next_seq = ADMIN_CLEAR_PIPES;
#endif
                        status = NFCSTATUS_PENDING;
                    }
                    break;
                }
#ifdef UICC_SESSION_RESET
                case ADMIN_CLEAR_UICC_PIPES:
                {
                    uint8_t config = 0x00;
                    p_pipe_info = p_admin_info->admin_pipe_info;
                     /* TODO: Implement the Clear UICC PIPES Using
                      * Memory configuration.
                      */
                    status = phHciNfc_DevMgmt_Configure( psHciContext, pHwRef,
                            NFC_ADDRESS_UICC_SESSION , config );
                    if(NFCSTATUS_PENDING == status )
                    {
                        p_admin_info->next_seq = ADMIN_CLEAR_PIPES;
                        status = NFCSTATUS_PENDING;
                    }
                    break;
                }
#endif
                case ADMIN_VERIFY_SESSION:
                {
                    phHal_sHwConfig_t *p_hw_config = 
                             (phHal_sHwConfig_t *) psHciContext->p_config_params;
                    phHal_sHwReference_t *p_hw_ref = 
                             (phHal_sHwReference_t *) pHwRef;
                    int             cmp_val = 0;
                    p_pipe_info = p_admin_info->admin_pipe_info;
                    cmp_val = phOsalNfc_MemCompare(p_hw_config->session_id , 
                                 p_hw_ref->session_id , 
                                         sizeof(p_hw_ref->session_id));
                    if((cmp_val == 0) 
                        && ( HCI_SESSION == psHciContext->init_mode)
                        )
                    {
                        psHciContext->hci_mode = hciMode_Session;
                        status = phHciNfc_Update_Pipe( psHciContext, pHwRef,
                                                &p_admin_info->pipe_seq );
                        if((status == NFCSTATUS_SUCCESS) 
                            && (NULL != p_pipe_info))
                        {
                            
                            p_pipe_info->reg_index = MAX_PIPE_INDEX;
                            status = phHciNfc_Send_Generic_Cmd( psHciContext,  
                                    pHwRef, (uint8_t)HCI_ADMIN_PIPE_ID,
                                                    (uint8_t)ANY_GET_PARAMETER );
                            p_pipe_info->prev_status = status;
                            if(NFCSTATUS_PENDING == status )
                            {
                                p_admin_info->next_seq = ADMIN_PIPE_CLOSE;
                                status = NFCSTATUS_SUCCESS;
                            }
                        }
                        else
                        {
                            status = PHNFCSTVAL(CID_NFC_HCI, 
                                            NFCSTATUS_INVALID_HCI_SEQUENCE);
                        }
                        break;
                    }
                    else
                    {
                        /* To clear the pipe information*/
                        psHciContext->hci_mode = hciMode_Override;
                        p_admin_info->current_seq = ADMIN_CLEAR_PIPES;
                    }
                }
                /* fall through */
                case ADMIN_CLEAR_PIPES:
                {
                    p_pipe_info = p_admin_info->admin_pipe_info;
                    p_pipe_info->prev_status = 
                                    phHciNfc_Send_Admin_Cmd( psHciContext,
                                        pHwRef, ADM_CLEAR_ALL_PIPE,
                                            length, p_pipe_info);
                    status = ((p_pipe_info->prev_status == NFCSTATUS_PENDING)?
                                            NFCSTATUS_SUCCESS : 
                                                p_pipe_info->prev_status);
                    if(status == NFCSTATUS_SUCCESS) 
                    {
                        p_admin_info->next_seq = ADMIN_PIPE_REOPEN;
                        status = NFCSTATUS_PENDING;
                    }
                    break;
                }
                /* Admin pipe Re-Open sequence , Re-Open the Admin Pipe */
                case ADMIN_PIPE_REOPEN:
                {
                    p_pipe_info = p_admin_info->admin_pipe_info;
                    status = phHciNfc_Open_Pipe( psHciContext,
                                                        pHwRef,p_pipe_info );
                    if(status == NFCSTATUS_SUCCESS)
                    {
                        p_admin_info->next_seq = ADMIN_CREATE_PIPES;
                        status = NFCSTATUS_PENDING;
                    }
                    break;
                }
                case ADMIN_CREATE_PIPES:
                {
                    status = phHciNfc_Create_All_Pipes( psHciContext, pHwRef,
                                                        &p_admin_info->pipe_seq );
                    if(status == NFCSTATUS_SUCCESS) 
                    {
                        p_admin_info->next_seq = ADMIN_GET_WHITE_LIST;
                        status = NFCSTATUS_PENDING;
                    }
                    break;
                }
                case ADMIN_GET_WHITE_LIST:
                {
                    p_pipe_info = p_admin_info->admin_pipe_info;
                    if(NULL == p_pipe_info )
                    {
                        status = PHNFCSTVAL(CID_NFC_HCI, 
                                        NFCSTATUS_INVALID_HCI_SEQUENCE);
                    }
                    else
                    {
                        p_pipe_info->reg_index = WHITELIST_INDEX;
                        status = phHciNfc_Send_Generic_Cmd( psHciContext,  
                                pHwRef, (uint8_t)HCI_ADMIN_PIPE_ID,
                                                (uint8_t)ANY_GET_PARAMETER );
                        p_pipe_info->prev_status = status;
                        if(HCI_SELF_TEST == psHciContext->init_mode)
                        {
                            status = ((NFCSTATUS_PENDING == status )?
                                            NFCSTATUS_SUCCESS : status);
                        }
                        else 
                        {
                            if(NFCSTATUS_PENDING == status )
                            {
                                p_admin_info->next_seq = ADMIN_GET_HOST_LIST;
                                /* status = NFCSTATUS_SUCCESS; */
                            }
                        }
                    }
                    break;
                }
                case ADMIN_GET_HOST_LIST:
                {
                    p_pipe_info = p_admin_info->admin_pipe_info;
                    if(NULL == p_pipe_info )
                    {
                        status = PHNFCSTVAL(CID_NFC_HCI, 
                                        NFCSTATUS_INVALID_HCI_SEQUENCE);
                    }
                    else
                    {
                        p_pipe_info->reg_index = HOST_LIST_INDEX;
                        status = phHciNfc_Send_Generic_Cmd( psHciContext,  
                                pHwRef, (uint8_t)HCI_ADMIN_PIPE_ID,
                                                (uint8_t)ANY_GET_PARAMETER );
                        p_pipe_info->prev_status = status;
                        if(NFCSTATUS_PENDING == status )
                        {

#if defined(HOST_WHITELIST)
                            p_admin_info->next_seq = ADMIN_SET_WHITE_LIST;
#else
                            p_admin_info->next_seq = ADMIN_SET_SESSION;
                            status = NFCSTATUS_SUCCESS;
#endif
                        }
                    }
                    break;
                }
                case ADMIN_SET_WHITE_LIST:
                {
                    p_pipe_info = p_admin_info->admin_pipe_info;
                    if(NULL == p_pipe_info )
                    {
                        status = PHNFCSTVAL(CID_NFC_HCI, 
                                        NFCSTATUS_INVALID_HCI_SEQUENCE);
                    }
                    else
                    {
                        uint8_t             i = 0;

                        for (i = 0; i < WHITELIST_MAX_LEN - 2; i++ )
                        {
                            p_admin_info->whitelist[i] = i + 2;
                        }
                        status = phHciNfc_Set_Param(psHciContext, pHwRef,
                                      p_pipe_info, WHITELIST_INDEX, 
                                        (uint8_t *)p_admin_info->whitelist, i );
                        if(NFCSTATUS_PENDING == status )
                        {
                            p_admin_info->next_seq = ADMIN_SET_SESSION;
                            status = NFCSTATUS_SUCCESS;
                        }
                    }
                    break;
                }
                case ADMIN_SET_SESSION:
                {
                    phHal_sHwConfig_t *p_hw_config = 
                             (phHal_sHwConfig_t *) psHciContext->p_config_params;
                    p_pipe_info = p_admin_info->admin_pipe_info;
                    status = phHciNfc_Set_Param(psHciContext, pHwRef, p_pipe_info,
                        SESSION_INDEX, (uint8_t *)(p_hw_config->session_id),
                            sizeof(p_hw_config->session_id));
                    if(NFCSTATUS_PENDING == p_pipe_info->prev_status )
                    {
                        p_admin_info->next_seq = ADMIN_PIPE_CLOSE;
                        status = NFCSTATUS_SUCCESS;
                    }
                    break;
                }
                default:
                {
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_SEQUENCE);
                    break;
                }

            }/* End of the Sequence Switch */

        }/* End of the Admin Info Memory Check */

    }/* End of Null context Check */

    return status;
}

#ifdef HOST_EMULATION

/*!
 * \brief Creates the Card Emulation Gate Pipes .
 *
 * This function Creates the Card Emulation Gate.
 */

NFCSTATUS
phHciNfc_Admin_CE_Init(
                                phHciNfc_sContext_t     *psHciContext,
                                void                    *pHwRef,
                                phHciNfc_GateID_t       ce_gate

                             )
{
    NFCSTATUS                           status = NFCSTATUS_SUCCESS;
    /* phHciNfc_Pipe_Info_t             *pipe_info = NULL; */
    phHciNfc_AdminGate_Info_t           *p_admin_info=NULL;

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

            switch(ce_gate)
            {
                /* Card Emulation A Gate Pipe Creation */
                case phHciNfc_CETypeAGate:
                {
                    p_admin_info->pipe_seq = PIPE_CARD_A_CREATE;
                    break;
                }
                /* Card Emulation B Gate Pipe Creation */
                case phHciNfc_CETypeBGate:
                {
                    p_admin_info->pipe_seq = PIPE_CARD_B_CREATE;
                    break;
                }
                default:
                {
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_HCI_GATE_NOT_SUPPORTED);
                    break;
                }
            } /* End of CE Gate Switch */

            if (NFCSTATUS_SUCCESS == status)
            {
                status = phHciNfc_CE_Pipes_OP( psHciContext,
                                        pHwRef, &p_admin_info->pipe_seq );
                if(status == NFCSTATUS_SUCCESS)
                {
                    p_admin_info->next_seq = ADMIN_END_SEQUENCE;
                    /* status = NFCSTATUS_PENDING; */
                }
            }

        }/* End of NULL Check for the Admin_Info */
    } /* End of Null Check for the Context */
    return status;
}

#endif

/*!
 * \brief Releases the resources allocated the Admin Management.
 *
 * This function Releases the resources allocated the Admin Management
 * and resets the hardware to the reset state.
 */

NFCSTATUS
phHciNfc_Admin_Release(
                                phHciNfc_sContext_t     *psHciContext,
                                void                    *pHwRef,
                                phHciNfc_HostID_t        host_type
                             )
{
    NFCSTATUS                           status = NFCSTATUS_SUCCESS;
    phHciNfc_Pipe_Info_t                *p_pipe_info = NULL;

    if( (NULL == psHciContext) || (NULL == pHwRef) )
    {
      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        if( NULL != psHciContext->p_admin_info )
        {
            if(phHciNfc_UICCHostID != host_type)
            {
                p_pipe_info = psHciContext->p_pipe_list[PIPETYPE_STATIC_ADMIN];

                status = phHciNfc_Close_Pipe( psHciContext,
                                                    pHwRef, p_pipe_info );
            }

        }/* End of NULL Check for the Admin_Info */
    } /* End of Null Check for the Context */
    return status;
}


/*!
 * \brief Sends the HCI Admin Event to the corresponding peripheral device.
 *
 * This function sends the HCI Admin Events to the connected NFC Pheripheral
 * device
 */

 NFCSTATUS
 phHciNfc_Send_Admin_Event (
                      phHciNfc_sContext_t   *psHciContext,
                      void                  *pHwRef,
                      uint8_t               event,
                      uint8_t               length,
                      void                  *params
                     )
{
    phHciNfc_HCP_Packet_t       *hcp_packet = NULL;
    phHciNfc_AdminGate_Info_t   *p_admin_info=NULL;
    NFCSTATUS                   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciContext) 
        || (NULL == pHwRef) 
      )
    {
      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        psHciContext->tx_total = 0 ;
        length +=  HCP_HEADER_LEN ;
        p_admin_info = psHciContext->p_admin_info;

        if( EVT_HOT_PLUG ==   event )
        {

            /* Use the HCP Packet Structure to Construct the send HCP
                * Packet data.
                */
            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_EVENT, event);
        }
        else
        {
            status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INSTRUCTION);
        }

        if( NFCSTATUS_SUCCESS == status )
        {
            p_admin_info->admin_pipe_info->sent_msg_type = HCP_MSG_TYPE_EVENT;
            p_admin_info->admin_pipe_info->prev_msg = event ;
            p_admin_info->admin_pipe_info->param_info = params ;
            psHciContext->tx_total = length;
            psHciContext->response_pending = FALSE ;
            status = phHciNfc_Send_HCP( (void *)psHciContext, (void *)pHwRef );
            p_admin_info->admin_pipe_info->prev_status = NFCSTATUS_PENDING;
        }
    }

    return status;
}


/*!
 * \brief Sends the HCI Admin Commands to the corresponding peripheral device.
 *
 * This function sends the HCI Admin Commands to the connected NFC Pheripheral
 * device
 */

 NFCSTATUS
 phHciNfc_Send_Admin_Cmd (
                      phHciNfc_sContext_t   *psHciContext,
                      void                  *pHwRef,
                      uint8_t               cmd,
                      uint8_t               length,
                      void                  *params
                     )
{
    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                     i=0;
    NFCSTATUS                   status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciContext) 
        || (NULL == pHwRef) 
        || (NULL == params)
      )
    {
      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        p_pipe_info = (phHciNfc_Pipe_Info_t *)  params;
        psHciContext->tx_total = 0 ;
        length +=  HCP_HEADER_LEN ;
        p_admin_info = psHciContext->p_admin_info;
        switch(  cmd )
        {
            case ADM_CREATE_PIPE:
            {
                hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
                /* Use the HCP Packet Structure to Construct the send HCP
                * Packet data.
                */
                phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
                                        (uint8_t) HCI_ADMIN_PIPE_ID,
                                        HCP_MSG_TYPE_COMMAND, cmd);
                hcp_message = &(hcp_packet->msg.message);

                /* Source HOST ID Parameter is not passed as a 
                 * parameter in the HCI SPEC */

                /* hcp_message->payload[i++] = p_pipe_info->pipe.source.host_id; */
                hcp_message->payload[i++] = p_pipe_info->pipe.source.gate_id;
                hcp_message->payload[i++] = p_pipe_info->pipe.dest.host_id;
                hcp_message->payload[i++] = p_pipe_info->pipe.dest.gate_id;
                break;
            }
            case ADM_DELETE_PIPE:
            {
                uint8_t     pipe_id = (uint8_t) HCI_UNKNOWN_PIPE_ID;

                pipe_id = p_pipe_info->pipe.pipe_id;
                if( pipe_id < PIPETYPE_DYNAMIC )
                {
                    /* The Static Pipes cannot be Deleted */
                    status = PHNFCSTVAL(CID_NFC_HCI,
                                    NFCSTATUS_INVALID_PARAMETER );
                    HCI_DEBUG("phHciNfc_Send_Admin_Cmd: Static Pipe %u "
                                                "Cannot be Deleted \n",pipe_id);
                }
                else
                {

                    /* Use the HCP Packet Structure to Construct the send HCP
                     * Packet data.
                     */
                    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_COMMAND, cmd);
                    hcp_message = &(hcp_packet->msg.message);
                    hcp_message->payload[i++] = pipe_id ;
                }
                break;
            }
            case ADM_CLEAR_ALL_PIPE:
            {

                /* Use the HCP Packet Structure to Construct the send HCP
                 * Packet data.
                 */
                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_COMMAND, cmd);
                hcp_message = &(hcp_packet->msg.message);
                break;
            }
            /* These are notifications and can not be sent by the Host */
            /* case ADM_NOTIFY_PIPE_CREATED: */
            /* case ADM_NOTIFY_PIPE_DELETED: */
            /* case ADM_NOTIFY_ALL_PIPE_CLEARED: */
            default:
                status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_COMMAND);
                break;
        }
        if( NFCSTATUS_SUCCESS == status )
        {
            p_admin_info->admin_pipe_info->sent_msg_type = HCP_MSG_TYPE_COMMAND;
            p_admin_info->admin_pipe_info->prev_msg = cmd;
            p_admin_info->admin_pipe_info->param_info = p_pipe_info;
            psHciContext->tx_total = length;
            psHciContext->response_pending = TRUE;
            status = phHciNfc_Send_HCP( (void *)psHciContext, (void *)pHwRef );
            p_admin_info->admin_pipe_info->prev_status = NFCSTATUS_PENDING;
        }
    }

    return status;
}


/*!
 * \brief Receives the HCI Response from the corresponding peripheral device.
 *
 * This function receives the HCI Command Response from the connected NFC
 * Pheripheral device.
 */

static
NFCSTATUS
phHciNfc_Recv_Admin_Response(
                        void                *psContext,
                        void                *pHwRef,
                        uint8_t             *pResponse,
#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_Pipe_Info_t        *p_pipe_info = NULL;
    phHciNfc_AdminGate_Info_t   *p_admin_info = NULL;
    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
    uint8_t                     pipe_id = (uint8_t) HCI_UNKNOWN_PIPE_ID;
    uint8_t                     prev_cmd = 0;
    NFCSTATUS                   prev_status = NFCSTATUS_SUCCESS;

    if( (NULL == psHciContext) || (NULL == pHwRef) )
    {
      status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else if ( NULL == psHciContext->p_admin_info )
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION);
    }
    else
    {
        hcp_packet = (phHciNfc_HCP_Packet_t *)pResponse;
        hcp_message = &hcp_packet->msg.message;
        p_admin_info = psHciContext->p_admin_info;
        prev_cmd = p_admin_info->admin_pipe_info->prev_msg ;
        prev_status = p_admin_info->admin_pipe_info->prev_status ;
        if(prev_status == NFCSTATUS_PENDING)
        {
            switch(prev_cmd)
            {
                case ANY_SET_PARAMETER:
                {
                    break;
                }
                case ANY_GET_PARAMETER:
                {
                    status = phHciNfc_Admin_InfoUpdate(psHciContext,
                                (phHal_sHwReference_t *)pHwRef,
                                p_admin_info->admin_pipe_info->reg_index, 
                                    &pResponse[HCP_HEADER_LEN],
                                        (uint8_t)(length - HCP_HEADER_LEN));
                    break;
                }
                case ANY_OPEN_PIPE:
                {
                    break;
                }
                case ANY_CLOSE_PIPE:
                {
                    phOsalNfc_FreeMemory(p_admin_info->admin_pipe_info);
                    p_admin_info->admin_pipe_info = NULL;
                    psHciContext->p_pipe_list[PIPETYPE_STATIC_ADMIN] = NULL;
                    break;
                }
                case ADM_CREATE_PIPE:
                {
                    p_pipe_info = (phHciNfc_Pipe_Info_t *)
                                        p_admin_info->admin_pipe_info->param_info;
                    pipe_id = hcp_message->payload[RESPONSE_PIPEID_OFFSET];
                    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;
                        p_pipe_info->pipe.pipe_id = pipe_id;
                    }
                    break;
                }
                case ADM_DELETE_PIPE:
                {
                    p_pipe_info = (phHciNfc_Pipe_Info_t *)
                                    p_admin_info->admin_pipe_info->param_info;
                    if ( NULL != p_pipe_info )
                    {
                        pipe_id = p_pipe_info->pipe.pipe_id;
                        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;
                }
                case ADM_CLEAR_ALL_PIPE:
                {
                    break;
                }
                default:
                {
                    status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
                    HCI_DEBUG("%s: Default Statement Should Not Occur \n",
                                                    "phHciNfc_Recv_Admin_Response");
                    break;
                }
            }
        }
        if( NFCSTATUS_SUCCESS == status )
        {
            if( NULL != p_admin_info->admin_pipe_info)
            {
                p_admin_info->admin_pipe_info->prev_status = NFCSTATUS_SUCCESS;
            }
            p_admin_info->current_seq = p_admin_info->next_seq;
        }
    }
    return status;
}

/*!
 * \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;
}

/*!
 * \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_Admin_InfoUpdate(
                                phHciNfc_sContext_t     *psHciContext,
                                phHal_sHwReference_t    *pHwRef,
                                uint8_t                 index,
                                uint8_t                 *reg_value,
                                uint8_t             reg_length
                          )
{
    phHciNfc_AdminGate_Info_t   *p_admin_info=NULL;
    uint8_t                     i=0;
    NFCSTATUS                   status = NFCSTATUS_SUCCESS;
    if(NULL == reg_value)
    {
        status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
    }
    else
    {
        p_admin_info = psHciContext->p_admin_info ;
        HCI_PRINT_BUFFER("Admin Mgmt Info Buffer",reg_value,reg_length);
        switch(index)
        {
            case SESSION_INDEX :
            {
                for(i=0 ;(reg_length == SESSIONID_LEN)&&(i < reg_length); i++)
                {
                    p_admin_info->session_id[i] = reg_value[i];
                    pHwRef->session_id[i] = reg_value[i];
                }
                break;
            }
            case MAX_PIPE_INDEX :
            {
                p_admin_info->max_pipe = reg_value[i];
                break;
            }
            case WHITELIST_INDEX :
            {
                for(i=0 ;(reg_length <= WHITELIST_MAX_LEN)&&(i < reg_length); i++)
                {
                    p_admin_info->whitelist[i] = reg_value[i];
                }
                break;
            }
            case HOST_LIST_INDEX :
            {
                for(i=0 ;(reg_length <= HOST_LIST_MAX_LEN)&&(i < reg_length); i++)
                {
                    p_admin_info->host_list[i] = reg_value[i];
                }
                break;
            }
            default:
            {
                status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
                break;
            } /*End of the default Switch Case */

        } /*End of the Index Switch */

    } /* End of Context and the Identity information validity check */

    return status;
}

