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