/*! * \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; }
NFCSTATUS phHciNfc_Update_Pipe( phHciNfc_sContext_t *psHciContext, void *pHwRef, phHciNfc_PipeMgmt_Seq_t *p_pipe_seq ) { static uint8_t pipe_index = HCI_DYNAMIC_PIPE_ID; phHciNfc_Pipe_Info_t *p_pipe_info = NULL; NFCSTATUS status = NFCSTATUS_SUCCESS; for (pipe_index = 0; (pipe_index + HCI_DYNAMIC_PIPE_ID) <= (uint8_t)(sizeof(host_gate_list)/sizeof(phHciNfc_GateID_t) ); pipe_index++) { status = phHciNfc_Allocate_Resource((void **)&p_pipe_info, sizeof(phHciNfc_Pipe_Info_t)); if( (NFCSTATUS_SUCCESS == status) && (NULL != p_pipe_info)) { /* The Source Host is the Terminal Host */ p_pipe_info->pipe.source.host_id = (uint8_t) phHciNfc_TerminalHostID; /* The Source Gate is same as the Destination Gate */ p_pipe_info->pipe.source.gate_id = host_gate_list[pipe_index]; p_pipe_info->pipe.dest.host_id = phHciNfc_HostControllerID; p_pipe_info->pipe.dest.gate_id = host_gate_list[pipe_index]; /* The Pipe ID is unknown until it is assigned */ p_pipe_info->pipe.pipe_id = (uint8_t) HCI_UNKNOWN_PIPE_ID; /* Initialise the Resources for the particular Gate */ status = phHciNfc_Create_All_Pipes(psHciContext, pHwRef, p_pipe_seq ); if( NFCSTATUS_SUCCESS == status ) { uint8_t pipe_id = (uint8_t)(pipe_index + HCI_DYNAMIC_PIPE_ID); status = phHciNfc_Update_PipeInfo( psHciContext, p_pipe_seq , pipe_id, p_pipe_info ); if( NFCSTATUS_SUCCESS == status ) { p_pipe_info->pipe.pipe_id = pipe_id; psHciContext->p_pipe_list[pipe_id] = p_pipe_info; } else { phOsalNfc_FreeMemory(p_pipe_info); } p_pipe_info = NULL; } else { phOsalNfc_FreeMemory(p_pipe_info); p_pipe_info = NULL; } } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES); } } if( NFCSTATUS_SUCCESS == status ) { status = phHciNfc_LinkMgmt_Initialise( psHciContext,pHwRef ); if(NFCSTATUS_SUCCESS == status) { status = phHciNfc_ReaderMgmt_Initialise( psHciContext,pHwRef ); } if(NFCSTATUS_SUCCESS == status) { status = phHciNfc_EmuMgmt_Initialise( psHciContext,pHwRef ); } } return status; }
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; }