/* * Copyright (C) 2010 NXP Semiconductors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*! * =========================================================================== * * * * * * \file phHciNfc_NfcIPMgmt.c * * \brief HCI NFCIP-1 management routines. * * * * * * Project: NFC-FRI-1.1 * * * * $Date: Tue Jun 8 09:32:31 2010 $ * * $Author: ing04880 $ * * $Revision: 1.33 $ * * $Aliases: NFC_FRI1.1_WK1023_R35_1 $ * * * =========================================================================== * */ /* ***************************** Header File Inclusion **************************** */ #include #include #include #include #include #include #if defined (ENABLE_P2P) #include /* ****************************** Macro Definitions ******************************* */ /* RF Error */ #define NFCIP_RF_NO_ERROR 0x00U #define NFCIP_STATUS_MAX_VALUE 0x01U /* Read and write to the below registry for initiator and target */ #define NXP_NFCIP_MODE 0x01U #define NXP_NFCIP_ATR_REQ 0x02U #define NXP_NFCIP_ATR_RES 0x03U #define NXP_NFCIP_PSL1 0x04U #define NXP_NFCIP_PSL2 0x05U #define NXP_NFCIP_DID 0x06U #define NXP_NFCIP_NAD 0x07U #define NXP_NFCIP_OPTIONS 0x08U #define NXP_NFCIP_STATUS 0x09U #define NXP_NFCIP_NFCID3I 0x0AU #define NXP_NFCIP_NFCID3T 0x0BU #define NXP_NFCIP_PARAM 0x0CU #define NXP_NFCIP_MERGE 0x0DU /* command */ #define NXP_NFCIP_ATTREQUEST 0x12U #define NXP_NFCI_CONTINUE_ACTIVATION 0x13U /* Event */ #define NXP_EVT_NFC_SND_DATA 0x01U #define NXP_EVT_NFC_ACTIVATED 0x02U #define NXP_EVT_NFC_DEACTIVATED 0x03U #define NXP_EVT_NFC_RCV_DATA 0x04U #define NXP_EVT_NFC_CONTINUE_MI 0x05U #define NFCIP_DATE_RATE_FACTOR 0x40U #define NFCIP_DATE_RATE_SHIFT 0x06U #define NFCIP_DATA_RATE_CALC(val) \ ((((uint8_t)(val) >> NFCIP_DATE_RATE_SHIFT) + \ 0x01U) * NFCIP_DATE_RATE_FACTOR) #define NFCIP_COMM_INITIATOR_SHIFT 0x03 #define NFCIP_COMM_FACTOR 0x03 /* *************************** Structure and Enumeration *************************** */ /* *************************** Static Function Declaration ************************** */ static NFCSTATUS phHciNfc_NfcIP_InfoUpdate( phHciNfc_sContext_t *psHciContext, uint8_t index, uint8_t *reg_value, uint8_t reg_length ); static NFCSTATUS phHciNfc_NfcIP_RecvData( phHciNfc_sContext_t *psHciContext, void *pHwRef, uint8_t *pResponse, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ); static NFCSTATUS phHciNfc_Recv_NfcIP_Response( phHciNfc_sContext_t *psHciContext, phHciNfc_Pipe_Info_t *ppipe_info, uint8_t *pResponse, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ); static NFCSTATUS phHciNfc_Recv_NfcIP_Event( phHciNfc_sContext_t *psHciContext, void *pHwRef, uint8_t *pEvent, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ); static NFCSTATUS phHciNfc_Recv_Initiator_Event( void *psContext, void *pHwRef, uint8_t *pEvent, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ); static NFCSTATUS phHciNfc_Recv_Target_Event( void *psContext, void *pHwRef, uint8_t *pEvent, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ); static NFCSTATUS phHciNfc_Recv_Initiator_Response( void *psContext, void *pHwRef, uint8_t *pResponse, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ); static NFCSTATUS phHciNfc_Recv_Target_Response( void *psContext, void *pHwRef, uint8_t *pResponse, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ); /* *************************** Function Definitions *************************** */ NFCSTATUS phHciNfc_Initiator_Init_Resources( phHciNfc_sContext_t *psHciContext ) { NFCSTATUS status = NFCSTATUS_SUCCESS; phHciNfc_NfcIP_Info_t *p_init_info=NULL; if( NULL == psHciContext ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else { if (NULL != psHciContext->p_nfcip_info) { status = NFCSTATUS_SUCCESS; } else if(( NULL == psHciContext->p_nfcip_info ) && (phHciNfc_Allocate_Resource((void **)(&p_init_info), sizeof(phHciNfc_NfcIP_Info_t))== NFCSTATUS_SUCCESS) ) { psHciContext->p_nfcip_info = p_init_info; p_init_info->nfcip_type = NFCIP_INVALID; p_init_info->current_seq = NFCIP_INVALID_SEQUENCE; p_init_info->next_seq = NFCIP_INVALID_SEQUENCE; p_init_info->p_init_pipe_info = NULL; p_init_info->p_tgt_pipe_info = NULL; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES); } } return status; } NFCSTATUS phHciNfc_Initiator_Get_PipeID( phHciNfc_sContext_t *psHciContext, uint8_t *ppipe_id ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL != psHciContext) && ( NULL != ppipe_id ) && ( NULL != psHciContext->p_nfcip_info ) ) { phHciNfc_NfcIP_Info_t *p_init_info=NULL; p_init_info = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; *ppipe_id = p_init_info->p_init_pipe_info->pipe.pipe_id ; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } return status; } NFCSTATUS phHciNfc_Initiator_Update_PipeInfo( phHciNfc_sContext_t *psHciContext, uint8_t pipeID, phHciNfc_Pipe_Info_t *pPipeInfo ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( NULL == psHciContext ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_init_info=NULL; p_init_info = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; /* Update the pipe_id of the NFCIP-1 initiator Gate obtained from the HCI Response */ p_init_info->p_init_pipe_info = pPipeInfo; p_init_info->p_init_pipe_info->pipe.pipe_id = pipeID; /* Update the Response Receive routine of the NFCIP-1 initiator Gate */ pPipeInfo->recv_resp = &phHciNfc_Recv_Initiator_Response; /* Update the event Receive routine of the NFCIP-1 initiator Gate */ pPipeInfo->recv_event = &phHciNfc_Recv_Initiator_Event; } return status; } NFCSTATUS phHciNfc_NfcIP_Presence_Check( phHciNfc_sContext_t *psHciContext, void *pHwRef ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef) ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if((NULL == psHciContext->p_nfcip_info) || (NFCIP_INVALID == ((phHciNfc_NfcIP_Info_t *)(psHciContext->p_nfcip_info))->nfcip_type)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == p_nfcipinfo->nfcip_type)? p_nfcipinfo->p_init_pipe_info : p_nfcipinfo->p_tgt_pipe_info); if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { phHciNfc_HCP_Packet_t *hcp_packet = NULL; uint16_t length = HCP_HEADER_LEN; uint8_t pipeid = 0; pipeid = p_pipe_info->pipe.pipe_id; psHciContext->tx_total = 0 ; hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer; /* Construct the HCP Frame */ phHciNfc_Build_HCPFrame(hcp_packet,(uint8_t)HCP_CHAINBIT_DEFAULT, (uint8_t) pipeid, (uint8_t)HCP_MSG_TYPE_COMMAND, (uint8_t)NXP_NFCIP_ATTREQUEST); p_pipe_info->sent_msg_type = (uint8_t)HCP_MSG_TYPE_COMMAND; p_pipe_info->prev_msg = (uint8_t)NXP_NFCIP_ATTREQUEST; psHciContext->tx_total = length; psHciContext->response_pending = (uint8_t)TRUE; /* Send the Constructed HCP packet to the lower layer */ status = phHciNfc_Send_HCP( psHciContext, pHwRef); p_pipe_info->prev_status = status; } } return status; } static NFCSTATUS phHciNfc_Recv_Initiator_Response( void *pContext, void *pHwRef, uint8_t *pResponse, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ) { NFCSTATUS status = NFCSTATUS_SUCCESS; phHciNfc_sContext_t *psHciContext = (phHciNfc_sContext_t *)pContext ; if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse) || (0 == length)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcip_info=NULL; phHciNfc_Pipe_Info_t *p_pipe_info = NULL; p_nfcip_info = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = p_nfcip_info->p_init_pipe_info; if( NULL == p_pipe_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { status = phHciNfc_Recv_NfcIP_Response(psHciContext, p_pipe_info, pResponse, length); if (NFCSTATUS_SUCCESS == status) { status = phHciNfc_ReaderMgmt_Update_Sequence(psHciContext, UPDATE_SEQ); } } } return status; } static NFCSTATUS phHciNfc_Recv_Initiator_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) || (0 == length)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_HCP_Packet_t *p_packet = NULL; phHciNfc_NfcIP_Info_t *p_nfcip_info=NULL; phHciNfc_HCP_Message_t *message = NULL; uint8_t instruction=0; p_nfcip_info = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_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 (NXP_EVT_NFC_ACTIVATED == instruction) { p_nfcip_info->nfcip_type = NFCIP_INITIATOR; psHciContext->host_rf_type = phHal_eNfcIP1_Initiator; p_nfcip_info->rem_nfcip_tgt_info.RemDevType = phHal_eNfcIP1_Target; } status = phHciNfc_Recv_NfcIP_Event(psHciContext, pHwRef, pEvent, length); } return status; } NFCSTATUS phHciNfc_Target_Init_Resources( phHciNfc_sContext_t *psHciContext ) { NFCSTATUS status = NFCSTATUS_SUCCESS; phHciNfc_NfcIP_Info_t *p_target_info=NULL; if( NULL == psHciContext ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else { if (NULL != psHciContext->p_nfcip_info) { status = NFCSTATUS_SUCCESS; } else if( ( NULL == psHciContext->p_nfcip_info ) && (phHciNfc_Allocate_Resource((void **)(&p_target_info), sizeof(phHciNfc_NfcIP_Info_t))== NFCSTATUS_SUCCESS) ) { psHciContext->p_nfcip_info = p_target_info; p_target_info->nfcip_type = NFCIP_INVALID; p_target_info->current_seq = NFCIP_INVALID_SEQUENCE; p_target_info->next_seq = NFCIP_INVALID_SEQUENCE; p_target_info->p_tgt_pipe_info = NULL; p_target_info->p_tgt_pipe_info = NULL; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES); } } return status; } NFCSTATUS phHciNfc_Target_Get_PipeID( phHciNfc_sContext_t *psHciContext, uint8_t *ppipe_id ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL != psHciContext) && ( NULL != ppipe_id ) && ( NULL != psHciContext->p_nfcip_info ) ) { phHciNfc_NfcIP_Info_t *p_target_info=NULL; p_target_info = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; *ppipe_id = p_target_info->p_tgt_pipe_info->pipe.pipe_id; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } return status; } NFCSTATUS phHciNfc_Target_Update_PipeInfo( phHciNfc_sContext_t *psHciContext, uint8_t pipeID, phHciNfc_Pipe_Info_t *pPipeInfo ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( NULL == psHciContext ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_target_info=NULL; p_target_info = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; /* Update the pipe_id of the NFCIP-1 target Gate obtained from the HCI Response */ p_target_info->p_tgt_pipe_info = pPipeInfo; p_target_info->p_tgt_pipe_info->pipe.pipe_id = pipeID; /* Update the Response Receive routine of the NFCIP-1 target Gate */ pPipeInfo->recv_resp = &phHciNfc_Recv_Target_Response; /* Update the event Receive routine of the NFCIP-1 target Gate */ pPipeInfo->recv_event = &phHciNfc_Recv_Target_Event; } return status; } static NFCSTATUS phHciNfc_Recv_Target_Response( void *pContext, void *pHwRef, uint8_t *pResponse, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ) { NFCSTATUS status = NFCSTATUS_SUCCESS; phHciNfc_sContext_t *psHciContext = (phHciNfc_sContext_t *)pContext ; if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse) || (0 == length)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcip_info=NULL; phHciNfc_Pipe_Info_t *p_pipe_info = NULL; p_nfcip_info = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = p_nfcip_info->p_tgt_pipe_info; if( NULL == p_pipe_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { status = phHciNfc_Recv_NfcIP_Response(psHciContext, p_pipe_info, pResponse, length); if (NFCSTATUS_SUCCESS == status) { status = phHciNfc_EmuMgmt_Update_Seq(psHciContext, UPDATE_SEQ); } } } return status; } static NFCSTATUS phHciNfc_Recv_Target_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) || (0 == length)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_HCP_Packet_t *p_packet = NULL; phHciNfc_NfcIP_Info_t *p_nfcip_info=NULL; phHciNfc_HCP_Message_t *message = NULL; uint8_t instruction=0; p_nfcip_info = (phHciNfc_NfcIP_Info_t *)psHciContext->p_nfcip_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 (NXP_EVT_NFC_ACTIVATED == instruction) { p_nfcip_info->nfcip_type = NFCIP_TARGET; psHciContext->host_rf_type = phHal_eNfcIP1_Target; p_nfcip_info->rem_nfcip_tgt_info.RemDevType = phHal_eNfcIP1_Initiator; } status = phHciNfc_Recv_NfcIP_Event(psHciContext, pHwRef, pEvent, length); } return status; } static NFCSTATUS phHciNfc_Recv_NfcIP_Response( phHciNfc_sContext_t *psHciContext, phHciNfc_Pipe_Info_t *ppipe_info, uint8_t *pResponse, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ) { NFCSTATUS status = NFCSTATUS_SUCCESS; phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; uint8_t prev_cmd = ANY_GET_PARAMETER; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; prev_cmd = ppipe_info->prev_msg ; switch(prev_cmd) { case ANY_OPEN_PIPE: { HCI_PRINT("NFCIP-1 NFCIP open pipe complete\n"); p_nfcipinfo->next_seq = NFCIP_NFCID3I; break; } case ANY_CLOSE_PIPE: { HCI_PRINT("NFCIP-1 NFCIP close pipe complete\n"); p_nfcipinfo->next_seq = NFCIP_NFCID3I; break; } case ANY_GET_PARAMETER: { HCI_PRINT("NFCIP-1 NFCIP get parameter complete\n"); if (length >= HCP_HEADER_LEN) { status = phHciNfc_NfcIP_InfoUpdate(psHciContext, ppipe_info->reg_index, &pResponse[HCP_HEADER_LEN], (uint8_t)(length - HCP_HEADER_LEN)); } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case ANY_SET_PARAMETER: { HCI_PRINT("NFCIP-1 NFCIP Parameter Set \n"); p_nfcipinfo->next_seq = NFCIP_NFCID3I; break; } case NXP_NFCI_CONTINUE_ACTIVATION: case NXP_NFCIP_ATTREQUEST: { p_nfcipinfo->next_seq = NFCIP_NFCID3I; break; } default: { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); break; } } if( NFCSTATUS_SUCCESS == status ) { ppipe_info->prev_status = NFCSTATUS_SUCCESS; p_nfcipinfo->current_seq = p_nfcipinfo->next_seq; } return status; } static NFCSTATUS phHciNfc_Recv_NfcIP_Event( phHciNfc_sContext_t *psHciContext, void *pHwRef, uint8_t *pEvent, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ) { NFCSTATUS status = NFCSTATUS_SUCCESS; phHciNfc_HCP_Packet_t *p_packet = NULL; phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_HCP_Message_t *message = NULL; phNfc_sCompletionInfo_t pCompInfo; uint8_t instruction=0; uint8_t type = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_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); switch(instruction) { case NXP_EVT_NFC_ACTIVATED: { HCI_PRINT("NFCIP-1 device discovered\n"); if (NFCIP_INITIATOR == p_nfcipinfo->nfcip_type) { pCompInfo.info = &(p_nfcipinfo->rem_nfcip_tgt_info); type = NFC_NOTIFY_TARGET_DISCOVERED; } else { type = NFC_NOTIFY_DEVICE_ACTIVATED; } if(length > HCP_HEADER_LEN) { HCI_DEBUG("NfcIP-1 activation mode : %d\n", pEvent[HCP_HEADER_LEN]); /* Mode indicates in which mode the current activation as be done - 0x00: Passive mode - 0x01: Active */ p_nfcipinfo->activation_mode = pEvent[HCP_HEADER_LEN]; } pCompInfo.status = NFCSTATUS_SUCCESS; /* Notify to the HCI Generic layer To Update the FSM */ phHciNfc_Notify_Event(psHciContext, pHwRef, type, &pCompInfo); break; } case NXP_EVT_NFC_DEACTIVATED: { static phHal_sEventInfo_t event_info; event_info.eventHost = phHal_eHostController; event_info.eventType = NFC_EVT_DEACTIVATED; p_nfcipinfo->activation_mode = FALSE; if (NFCIP_INITIATOR == p_nfcipinfo->nfcip_type) { p_nfcipinfo->rem_nfcip_tgt_info.RemDevType = phHal_eNfcIP1_Target; event_info.eventSource = phHal_eNfcIP1_Initiator; } else { p_nfcipinfo->rem_nfcip_tgt_info.RemDevType = phHal_eNfcIP1_Initiator; event_info.eventSource = phHal_eNfcIP1_Target; } /* Reset the sequence */ p_nfcipinfo->current_seq = NFCIP_NFCID3I; p_nfcipinfo->next_seq = NFCIP_NFCID3I; HCI_PRINT("NFCIP-1 Target Deactivated\n"); phHciNfc_Notify_Event(psHciContext, pHwRef, NFC_NOTIFY_DEVICE_DEACTIVATED, &event_info); break; } case NXP_EVT_NFC_RCV_DATA: { status = phHciNfc_NfcIP_RecvData(psHciContext, pHwRef, &pEvent[HCP_HEADER_LEN], (length - HCP_HEADER_LEN)); break; } case NXP_EVT_NFC_CONTINUE_MI: { /* psHciContext->response_pending = FALSE; */ psHciContext->event_pending = FALSE; break; } default: { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); break; } } return status; } static NFCSTATUS phHciNfc_NfcIP_RecvData( phHciNfc_sContext_t *psHciContext, void *pHwRef, uint8_t *pResponse, #ifdef ONE_BYTE_LEN uint8_t length #else uint16_t length #endif ) { NFCSTATUS status = NFCSTATUS_SUCCESS; uint8_t index = 0; if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse) || (0 == length)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else { phNfc_sTransactionInfo_t transInfo; phHciNfc_NfcIP_Info_t *p_nfcipinfo = NULL; uint8_t type = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info; HCI_PRINT("NFCIP-1 received bytes :"); if (NFCIP_RF_NO_ERROR == pResponse[index]) { HCI_PRINT_BUFFER("device ", &pResponse[index], (length - index)); transInfo.status = NFCSTATUS_SUCCESS; index++; if (TRUE == pResponse[index]) { /* Update the more information bit to the upper layer */ transInfo.status = NFCSTATUS_MORE_INFORMATION; } index++; transInfo.buffer = &pResponse[index]; transInfo.length = (length - index); type = (uint8_t)NFC_NOTIFY_RECV_EVENT; } else { HCI_PRINT("NFCIP-1 receive RF ERROR "); p_nfcipinfo->activation_mode = FALSE; type = (uint8_t)NFC_NOTIFY_RECV_EVENT; transInfo.status = NFCSTATUS_RF_TIMEOUT; transInfo.buffer = NULL; transInfo.length = 0; } status = NFCSTATUS_PENDING; /* Event NXP_EVT_NFC_RCV_DATA: so give received data to the upper layer */ phHciNfc_Notify_Event(psHciContext, pHwRef, type, &transInfo ); } return status; } NFCSTATUS phHciNfc_NfcIP_Send_Data ( phHciNfc_sContext_t *psHciContext, void *pHwRef, phHciNfc_XchgInfo_t *sData ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == sData) || (NULL == sData->tx_buffer) || (0 == sData->tx_length)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if((NULL == psHciContext->p_nfcip_info) || (NFCIP_INVALID == ((phHciNfc_NfcIP_Info_t *)(psHciContext->p_nfcip_info))->nfcip_type)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == p_nfcipinfo->nfcip_type)? p_nfcipinfo->p_init_pipe_info : p_nfcipinfo->p_tgt_pipe_info); if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { phHciNfc_HCP_Packet_t *hcp_packet = NULL; phHciNfc_HCP_Message_t *hcp_message = NULL; uint16_t length = HCP_HEADER_LEN; uint8_t pipeid = 0, i = 0; HCI_PRINT_BUFFER("HCI NFCIP-1 Send Data: ", sData->tx_buffer, sData->tx_length); psHciContext->tx_total = 0 ; pipeid = p_pipe_info->pipe.pipe_id; hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer; hcp_message = &(hcp_packet->msg.message); hcp_message->payload[i] = sData->params.nfc_info.more_info; i++; /* Construct the HCP Frame */ phHciNfc_Build_HCPFrame(hcp_packet,(uint8_t)HCP_CHAINBIT_DEFAULT, (uint8_t) pipeid, (uint8_t)HCP_MSG_TYPE_EVENT, (uint8_t)NXP_EVT_NFC_SND_DATA); phHciNfc_Append_HCPFrame((uint8_t *)hcp_message->payload, i, (uint8_t *)sData->tx_buffer, (uint8_t)sData->tx_length); length =(uint16_t)(length + i + sData->tx_length); p_pipe_info->sent_msg_type = (uint8_t)HCP_MSG_TYPE_EVENT; p_pipe_info->prev_msg = NXP_EVT_NFC_SND_DATA; psHciContext->tx_total = length; /* Send the Constructed HCP packet to the lower layer */ status = phHciNfc_Send_HCP( psHciContext, pHwRef); #if !defined (ENABLE_CONTINUE_MI) if ((TRUE == sData->params.nfc_info.more_info) && (NFCSTATUS_PENDING == status)) { /* If more information bit is set, then wait for the event NXP_EVT_NFC_CONTINUE_MI */ /* psHciContext->response_pending = TRUE; */ psHciContext->event_pending = TRUE; } #endif /* #if defined (ENABLE_CONTINUE_MI) */ p_pipe_info->prev_status = status; } } return status; } NFCSTATUS phHciNfc_NfcIP_Info_Sequence ( phHciNfc_sContext_t *psHciContext, void *pHwRef #ifdef NOTIFY_REQD , uint8_t notify_reqd #endif /* #ifdef NOTIFY_REQD */ ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef) ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if((NULL == psHciContext->p_nfcip_info) || (NFCIP_INVALID == ((phHciNfc_NfcIP_Info_t *)(psHciContext->p_nfcip_info))-> nfcip_type)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == p_nfcipinfo->nfcip_type)? p_nfcipinfo->p_init_pipe_info: p_nfcipinfo->p_tgt_pipe_info); if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { switch(p_nfcipinfo->current_seq) { case NFCIP_NFCID3I: { p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_NFCID3I; /* Fill the data buffer and send the command to the device */ status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, p_pipe_info->pipe.pipe_id, ANY_GET_PARAMETER); if(NFCSTATUS_PENDING == status ) { p_nfcipinfo->next_seq = NFCIP_NFCID3T; } break; } case NFCIP_NFCID3T: { p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_NFCID3T; /* Fill the data buffer and send the command to the device */ status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, p_pipe_info->pipe.pipe_id, ANY_GET_PARAMETER); if(NFCSTATUS_PENDING == status ) { p_nfcipinfo->next_seq = NFCIP_PARAM; } break; } case NFCIP_PARAM: { p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_PARAM; /* Fill the data buffer and send the command to the device */ status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, p_pipe_info->pipe.pipe_id, ANY_GET_PARAMETER); if(NFCSTATUS_PENDING == status ) { p_nfcipinfo->next_seq = NFCIP_ATR_INFO; } break; } case NFCIP_ATR_INFO: { p_pipe_info->reg_index = (uint8_t)((NFCIP_INITIATOR == p_nfcipinfo->nfcip_type)? NXP_NFCIP_ATR_RES : NXP_NFCIP_ATR_REQ); status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, p_pipe_info->pipe.pipe_id, ANY_GET_PARAMETER); if(NFCSTATUS_PENDING == status ) { p_nfcipinfo->next_seq = NFCIP_STATUS; } break; } case NFCIP_STATUS: { p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_STATUS; /* Fill the data buffer and send the command to the device */ status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, p_pipe_info->pipe.pipe_id, ANY_GET_PARAMETER); if(NFCSTATUS_PENDING == status ) { #ifdef NOTIFY_REQD if(FALSE == notify_reqd) #else /* #ifdef NOTIFY_REQD */ if (NULL != psHciContext->p_target_info) #endif /* #ifdef NOTIFY_REQD */ { p_nfcipinfo->next_seq = NFCIP_NFCID3I; status = NFCSTATUS_SUCCESS; } else { p_nfcipinfo->next_seq = NFCIP_END_SEQUENCE; } } break; } case NFCIP_END_SEQUENCE: { phHal_uRemoteDevInfo_t *rem_nfcipinfo = NULL; if (NULL != psHciContext->p_target_info) { /* This is given to user */ rem_nfcipinfo = &(psHciContext->p_target_info->RemoteDevInfo); } else { rem_nfcipinfo = &(p_nfcipinfo->rem_nfcip_tgt_info.RemoteDevInfo); } /* Update maximum frame length */ rem_nfcipinfo->NfcIP_Info.MaxFrameLength = p_nfcipinfo->max_frame_len; p_nfcipinfo->current_seq = NFCIP_NFCID3I; p_nfcipinfo->next_seq = NFCIP_NFCID3I; rem_nfcipinfo->NfcIP_Info.Nfcip_Active = p_nfcipinfo->activation_mode; if (NFCIP_INITIATOR == p_nfcipinfo->nfcip_type) { phNfc_sCompletionInfo_t CompInfo; p_nfcipinfo->rem_nfcip_tgt_info.RemDevType = phHal_eNfcIP1_Target; /* Update initiator speed */ rem_nfcipinfo->NfcIP_Info.Nfcip_Datarate = (phHalNfc_eDataRate_t) (p_nfcipinfo->initiator_speed); /* Update ATR info */ rem_nfcipinfo->NfcIP_Info.ATRInfo_Length = p_nfcipinfo->atr_res_length; (void)memcpy( (void *)rem_nfcipinfo->NfcIP_Info.ATRInfo, (void *)p_nfcipinfo->atr_res_info, rem_nfcipinfo->NfcIP_Info.ATRInfo_Length); /* Update NFCID */ rem_nfcipinfo->NfcIP_Info.NFCID_Length = p_nfcipinfo->nfcid3i_length; (void)memcpy( (void *)rem_nfcipinfo->NfcIP_Info.NFCID, (void *)p_nfcipinfo->nfcid3i, rem_nfcipinfo->NfcIP_Info.NFCID_Length); CompInfo.status = status = NFCSTATUS_SUCCESS; if (NULL != psHciContext->p_target_info) { CompInfo.info = &(psHciContext->p_target_info); } else { CompInfo.info = &(p_nfcipinfo->rem_nfcip_tgt_info); } /* Notify to the upper layer */ phHciNfc_Tag_Notify(psHciContext, pHwRef, NFC_NOTIFY_TARGET_DISCOVERED, &CompInfo); } else { static phHal_sEventInfo_t event_info; p_nfcipinfo->rem_nfcip_tgt_info.RemDevType = phHal_eNfcIP1_Initiator; /* Update target speed */ rem_nfcipinfo->NfcIP_Info.Nfcip_Datarate = (phHalNfc_eDataRate_t) (p_nfcipinfo->target_speed); /* Update ATR info */ rem_nfcipinfo->NfcIP_Info.ATRInfo_Length = p_nfcipinfo->atr_req_length; (void)memcpy( (void *)rem_nfcipinfo->NfcIP_Info.ATRInfo, (void *)p_nfcipinfo->atr_req_info, rem_nfcipinfo->NfcIP_Info.ATRInfo_Length); /* Update NFCID */ rem_nfcipinfo->NfcIP_Info.NFCID_Length = p_nfcipinfo->nfcid3t_length; (void)memcpy( (void *)rem_nfcipinfo->NfcIP_Info.NFCID, (void *)p_nfcipinfo->nfcid3t, rem_nfcipinfo->NfcIP_Info.NFCID_Length); event_info.eventHost = phHal_eHostController; event_info.eventType = NFC_EVT_ACTIVATED; event_info.eventSource = phHal_eNfcIP1_Target; event_info.eventInfo.pRemoteDevInfo = &(p_nfcipinfo->rem_nfcip_tgt_info); phHciNfc_Target_Select_Notify((void *)psHciContext, pHwRef, NFC_NOTIFY_EVENT, &(event_info)); } break; } default: { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); break; } } } } return status; } static NFCSTATUS phHciNfc_NfcIP_InfoUpdate( phHciNfc_sContext_t *psHciContext, uint8_t index, uint8_t *reg_value, uint8_t reg_length ) { NFCSTATUS status = NFCSTATUS_SUCCESS; phHciNfc_NfcIP_Info_t *p_nfcipinfo = NULL; phHal_sNfcIPInfo_t *p_rem_nfcipinfo = NULL; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *)(psHciContext->p_nfcip_info ); p_rem_nfcipinfo = &(p_nfcipinfo->rem_nfcip_tgt_info.RemoteDevInfo.NfcIP_Info); switch(index) { case NXP_NFCIP_ATR_RES: { if (reg_length <= NFCIP_ATR_MAX_LENGTH) { /* Remote device info provided by the user */ HCI_PRINT_BUFFER("\tNFCIP ATR_RES", reg_value, reg_length); p_rem_nfcipinfo->ATRInfo_Length = p_nfcipinfo->atr_res_length = reg_length; (void)memcpy((void *)p_rem_nfcipinfo->ATRInfo, (void *)reg_value, p_rem_nfcipinfo->ATRInfo_Length); (void)memcpy((void *)p_nfcipinfo->atr_res_info, (void *)reg_value, p_nfcipinfo->atr_res_length); if (NULL != psHciContext->p_target_info) { phHal_sNfcIPInfo_t *p_remtgt_info = NULL; /* This is given to user */ p_remtgt_info = &(psHciContext->p_target_info->RemoteDevInfo.NfcIP_Info); p_remtgt_info->ATRInfo_Length = reg_length; (void)memcpy((void *)p_remtgt_info->ATRInfo, (void *)reg_value, p_remtgt_info->ATRInfo_Length); } } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_STATUS: { if (sizeof(*reg_value) == reg_length) #ifdef STATUS_BUFFER_CHECK && (*reg_value <= NFCIP_STATUS_MAX_VALUE)) #endif /* #ifdef STATUS_ERROR */ { HCI_PRINT_BUFFER("\tNFCIP STATUS", reg_value, reg_length); p_nfcipinfo->linkstatus = *reg_value; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_NFCID3I: { if (reg_length <= NFCIP_NFCID_LENGTH) { HCI_PRINT_BUFFER("\tNFCIP NFCID3I", reg_value, reg_length); p_nfcipinfo->nfcid3i_length = p_rem_nfcipinfo->NFCID_Length = reg_length; (void)memcpy((void *)p_rem_nfcipinfo->NFCID, (void *)reg_value, p_rem_nfcipinfo->NFCID_Length); (void)memcpy((void *)p_nfcipinfo->nfcid3i, (void *)reg_value, reg_length); if ((NULL != psHciContext->p_target_info) && (NFCIP_INITIATOR == p_nfcipinfo->nfcip_type)) { phHal_sNfcIPInfo_t *p_remtgt_info = NULL; /* This is given to user */ p_remtgt_info = &(psHciContext->p_target_info->RemoteDevInfo.NfcIP_Info); p_remtgt_info->NFCID_Length = reg_length; (void)memcpy((void *)p_remtgt_info->NFCID, (void *)reg_value, p_remtgt_info->NFCID_Length); } } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_NFCID3T: { if (reg_length <= NFCIP_NFCID_LENGTH) { HCI_PRINT_BUFFER("\tNFCIP NFCID3T", reg_value, reg_length); p_nfcipinfo->nfcid3t_length = p_rem_nfcipinfo->NFCID_Length = reg_length; (void)memcpy((void *)p_rem_nfcipinfo->NFCID, (void *)reg_value, p_rem_nfcipinfo->NFCID_Length); (void)memcpy((void *)p_nfcipinfo->nfcid3t, (void *)reg_value, reg_length); if ((NULL != psHciContext->p_target_info) && (NFCIP_TARGET == p_nfcipinfo->nfcip_type)) { phHal_sNfcIPInfo_t *p_remtgt_info = NULL; /* This is given to user */ p_remtgt_info = &(psHciContext->p_target_info->RemoteDevInfo.NfcIP_Info); p_remtgt_info->NFCID_Length = reg_length; (void)memcpy((void *)p_remtgt_info->NFCID, (void *)reg_value, p_remtgt_info->NFCID_Length); } } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_PARAM: { if (sizeof(*reg_value) == reg_length) { HCI_PRINT_BUFFER("\tNFCIP PARAMS", reg_value, reg_length); p_nfcipinfo->initiator_speed = (phHciNfc_eP2PSpeed_t) ((*reg_value >> NFCIP_COMM_INITIATOR_SHIFT) & NFCIP_COMM_FACTOR); if (p_nfcipinfo->nfcip_type == NFCIP_INITIATOR) { switch(p_nfcipinfo->initiator_speed) { case phNfc_eDataRate_106: ALOGI("I'm P2P %s Initiator @ 106 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); break; case phNfc_eDataRate_212: ALOGI("I'm P2P %s Initiator @ 212 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); break; case phNfc_eDataRate_424: ALOGI("I'm P2P %s Initiator @ 424 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); break; } } p_nfcipinfo->target_speed = (phHciNfc_eP2PSpeed_t) (*reg_value & NFCIP_COMM_FACTOR); if (p_nfcipinfo->nfcip_type == NFCIP_TARGET) { switch(p_nfcipinfo->target_speed) { case phNfc_eDataRate_106: ALOGI("I'm P2P %s Target @ 106 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); break; case phNfc_eDataRate_212: ALOGI("I'm P2P %s Target @ 212 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); break; case phNfc_eDataRate_424: ALOGI("I'm P2P %s Target @ 424 kb/s", p_nfcipinfo->activation_mode ? "Active" : "Passive"); break; } } p_nfcipinfo->max_frame_len = NFCIP_DATA_RATE_CALC(*reg_value); if (p_nfcipinfo->max_frame_len > NFCIP_MAX_DEP_REQ_HDR_LEN) { p_nfcipinfo->max_frame_len -= NFCIP_MAX_DEP_REQ_HDR_LEN; if (NULL != psHciContext->p_target_info) { phHal_sNfcIPInfo_t *p_remtgt_info = NULL; /* This is given to user */ p_remtgt_info = &(psHciContext->p_target_info->RemoteDevInfo.NfcIP_Info); p_remtgt_info->MaxFrameLength = p_nfcipinfo->max_frame_len; p_remtgt_info->Nfcip_Datarate = (phHalNfc_eDataRate_t) p_nfcipinfo->initiator_speed; } } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_MODE: { if (sizeof(*reg_value) == reg_length) { HCI_PRINT_BUFFER("\tNFCIP MODE", reg_value, reg_length); p_nfcipinfo->nfcip_mode = *reg_value; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_ATR_REQ: { if (reg_length <= NFCIP_ATR_MAX_LENGTH) { HCI_PRINT_BUFFER("\tNFCIP ATR_REQ", reg_value, reg_length); p_rem_nfcipinfo->ATRInfo_Length = p_nfcipinfo->atr_req_length = reg_length; (void)memcpy((void *)p_rem_nfcipinfo->ATRInfo, (void *)reg_value, p_rem_nfcipinfo->ATRInfo_Length); (void)memcpy((void *)p_nfcipinfo->atr_req_info, (void *)reg_value, p_nfcipinfo->atr_req_length); if (NULL != psHciContext->p_target_info) { phHal_sNfcIPInfo_t *p_remtgt_info = NULL; /* This is given to user */ p_remtgt_info = &(psHciContext->p_target_info->RemoteDevInfo.NfcIP_Info); p_remtgt_info->NFCID_Length = reg_length; (void)memcpy((void *)p_remtgt_info->ATRInfo, (void *)reg_value, p_remtgt_info->ATRInfo_Length); } } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_PSL1: { if (sizeof(*reg_value) == reg_length) { HCI_PRINT_BUFFER("\tNFCIP PSL1", reg_value, reg_length); p_nfcipinfo->psl1 = *reg_value; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_PSL2: { if (sizeof(*reg_value) == reg_length) { HCI_PRINT_BUFFER("\tNFCIP PSL2", reg_value, reg_length); p_nfcipinfo->psl2 = *reg_value; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_DID: { if (sizeof(*reg_value) == reg_length) { HCI_PRINT_BUFFER("\tNFCIP DID", reg_value, reg_length); p_nfcipinfo->did = *reg_value; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_NAD: { if (sizeof(*reg_value) == reg_length) { HCI_PRINT_BUFFER("\tNFCIP NAD", reg_value, reg_length); p_nfcipinfo->nad = *reg_value; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } case NXP_NFCIP_OPTIONS: { if (sizeof(*reg_value) == reg_length) { HCI_PRINT_BUFFER("\tNFCIP OPTIONS", reg_value, reg_length); p_nfcipinfo->options = *reg_value; } else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } break; } default: { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); break; } } return status; } NFCSTATUS phHciNfc_NfcIP_SetMode( phHciNfc_sContext_t *psHciContext, void *pHwRef, phHciNfc_eNfcIPType_t nfciptype, uint8_t nfcip_mode ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef) || (nfcip_mode > (uint8_t)NFCIP_MODE_ALL)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if (NFCIP_INVALID == nfciptype) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == nfciptype)? p_nfcipinfo->p_init_pipe_info: p_nfcipinfo->p_tgt_pipe_info); if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { pipeid = p_pipe_info->pipe.pipe_id ; p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_MODE; p_pipe_info->param_info = &nfcip_mode; p_pipe_info->param_length = sizeof(uint8_t); status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_SET_PARAMETER); } } return status; } NFCSTATUS phHciNfc_NfcIP_SetNAD( phHciNfc_sContext_t *psHciContext, void *pHwRef, phHciNfc_eNfcIPType_t nfciptype, uint8_t nad ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if (NFCIP_INVALID == nfciptype) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == nfciptype)? p_nfcipinfo->p_init_pipe_info: p_nfcipinfo->p_tgt_pipe_info); if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { pipeid = p_pipe_info->pipe.pipe_id ; p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_NAD; p_pipe_info->param_info = &nad; p_pipe_info->param_length = sizeof(uint8_t); status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_SET_PARAMETER); } } return status; } NFCSTATUS phHciNfc_NfcIP_SetDID( phHciNfc_sContext_t *psHciContext, void *pHwRef, uint8_t did ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = p_nfcipinfo->p_init_pipe_info; if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { pipeid = p_pipe_info->pipe.pipe_id ; p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_DID; p_pipe_info->param_info = &did; p_pipe_info->param_length = sizeof(uint8_t); status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_SET_PARAMETER); } } return status; } NFCSTATUS phHciNfc_NfcIP_SetOptions( phHciNfc_sContext_t *psHciContext, void *pHwRef, phHciNfc_eNfcIPType_t nfciptype, uint8_t nfcip_options ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if (NFCIP_INVALID == nfciptype) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == p_nfcipinfo->nfcip_type)? p_nfcipinfo->p_init_pipe_info: p_nfcipinfo->p_tgt_pipe_info); pipeid = p_pipe_info->pipe.pipe_id ; p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_OPTIONS; p_pipe_info->param_info = &nfcip_options; p_pipe_info->param_length = sizeof(uint8_t); status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_SET_PARAMETER); } return status; } NFCSTATUS phHciNfc_NfcIP_SetATRInfo( phHciNfc_sContext_t *psHciContext, void *pHwRef, phHciNfc_eNfcIPType_t nfciptype, phHal_sNfcIPCfg_t *atr_info ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == atr_info) || (atr_info->generalBytesLength > NFCIP_ATR_MAX_LENGTH)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if (NFCIP_INVALID == nfciptype) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == nfciptype)? p_nfcipinfo->p_init_pipe_info: p_nfcipinfo->p_tgt_pipe_info); if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { pipeid = p_pipe_info->pipe.pipe_id ; p_pipe_info->reg_index = (uint8_t)((NFCIP_INITIATOR == nfciptype)? NXP_NFCIP_ATR_REQ : NXP_NFCIP_ATR_RES); p_pipe_info->param_info = atr_info->generalBytes; p_pipe_info->param_length = (uint8_t) atr_info->generalBytesLength; status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_SET_PARAMETER); } } return status; } NFCSTATUS phHciNfc_NfcIP_SetPSL1( phHciNfc_sContext_t *psHciContext, void *pHwRef, uint8_t psl1 ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = p_nfcipinfo->p_init_pipe_info; if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { pipeid = p_pipe_info->pipe.pipe_id ; p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_PSL1; p_pipe_info->param_info = &psl1; p_pipe_info->param_length = sizeof(uint8_t); status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_SET_PARAMETER); } } return status; } NFCSTATUS phHciNfc_NfcIP_SetPSL2( phHciNfc_sContext_t *psHciContext, void *pHwRef, uint8_t psl2 ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = p_nfcipinfo->p_init_pipe_info; if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { pipeid = p_pipe_info->pipe.pipe_id ; p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_PSL2; p_pipe_info->param_info = &psl2; p_pipe_info->param_length = sizeof(uint8_t); status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_SET_PARAMETER); } } return status; } NFCSTATUS phHciNfc_NfcIP_GetStatus( phHciNfc_sContext_t *psHciContext, void *pHwRef, phHciNfc_eNfcIPType_t nfciptype ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if (NFCIP_INVALID == nfciptype) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == nfciptype)? p_nfcipinfo->p_init_pipe_info : p_nfcipinfo->p_tgt_pipe_info); if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { pipeid = p_pipe_info->pipe.pipe_id ; p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_STATUS; status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_GET_PARAMETER); } } return status; } NFCSTATUS phHciNfc_NfcIP_GetParam( phHciNfc_sContext_t *psHciContext, void *pHwRef, phHciNfc_eNfcIPType_t nfciptype ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if (NFCIP_INVALID == nfciptype) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == nfciptype)? p_nfcipinfo->p_init_pipe_info : p_nfcipinfo->p_tgt_pipe_info); if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { pipeid = p_pipe_info->pipe.pipe_id ; p_pipe_info->reg_index = (uint8_t)NXP_NFCIP_PARAM; status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_GET_PARAMETER); } } return status; } NFCSTATUS phHciNfc_Initiator_Cont_Activate ( phHciNfc_sContext_t *psHciContext, void *pHwRef ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef) ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo = NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_nfcipinfo->nfcip_type = NFCIP_INITIATOR; psHciContext->host_rf_type = phHal_eNfcIP1_Initiator; p_pipe_info = p_nfcipinfo->p_init_pipe_info; if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { phHciNfc_HCP_Packet_t *hcp_packet = NULL; uint16_t length = HCP_HEADER_LEN; uint8_t pipeid = 0; pipeid = p_pipe_info->pipe.pipe_id; psHciContext->tx_total = 0 ; hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer; /* Construct the HCP Frame */ phHciNfc_Build_HCPFrame(hcp_packet,(uint8_t)HCP_CHAINBIT_DEFAULT, (uint8_t) pipeid, (uint8_t)HCP_MSG_TYPE_COMMAND, (uint8_t)NXP_NFCI_CONTINUE_ACTIVATION); p_pipe_info->sent_msg_type = (uint8_t)HCP_MSG_TYPE_COMMAND; p_pipe_info->prev_msg = (uint8_t)NXP_NFCI_CONTINUE_ACTIVATION; psHciContext->tx_total = length; psHciContext->response_pending = (uint8_t)TRUE; /* Send the Constructed HCP packet to the lower layer */ status = phHciNfc_Send_HCP( psHciContext, pHwRef); p_pipe_info->prev_status = status; } } return status; } NFCSTATUS phHciNfc_NfcIP_GetATRInfo ( phHciNfc_sContext_t *psHciContext, void *pHwRef, phHciNfc_eNfcIPType_t nfciptype ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if (NFCIP_INVALID == nfciptype) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *p_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *p_pipe_info=NULL; uint8_t pipeid = 0; p_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; p_pipe_info = ((NFCIP_INITIATOR == nfciptype)? p_nfcipinfo->p_init_pipe_info : p_nfcipinfo->p_tgt_pipe_info); if(NULL == p_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { p_pipe_info->reg_index = (uint8_t)((NFCIP_INITIATOR == nfciptype)? NXP_NFCIP_ATR_RES : NXP_NFCIP_ATR_REQ); pipeid = p_pipe_info->pipe.pipe_id ; /* Fill the data buffer and send the command to the device */ status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_GET_PARAMETER); } } return status; } NFCSTATUS phHciNfc_NfcIP_SetMergeSak( phHciNfc_sContext_t *psHciContext, void *pHwRef, uint8_t sak_value ) { NFCSTATUS status = NFCSTATUS_SUCCESS; if( (NULL == psHciContext) || (NULL == pHwRef) || (sak_value > (uint8_t)TRUE)) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } else if(NULL == psHciContext->p_nfcip_info) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else { phHciNfc_NfcIP_Info_t *ps_nfcipinfo=NULL; phHciNfc_Pipe_Info_t *ps_pipe_info=NULL; uint8_t pipeid = 0; ps_nfcipinfo = (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; ps_pipe_info = ps_nfcipinfo->p_tgt_pipe_info; if(NULL == ps_pipe_info ) { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else { pipeid = ps_pipe_info->pipe.pipe_id ; ps_pipe_info->reg_index = (uint8_t)NXP_NFCIP_MERGE; ps_pipe_info->param_info = &sak_value; ps_pipe_info->param_length = sizeof(uint8_t); status = phHciNfc_Send_Generic_Cmd( psHciContext, pHwRef, pipeid, (uint8_t)ANY_SET_PARAMETER); } } return status; } #endif /* #if defined (ENABLE_P2P) */