diff options
Diffstat (limited to 'src/phHciNfc_CE_B.c')
-rwxr-xr-x[-rw-r--r--] | src/phHciNfc_CE_B.c | 1256 |
1 files changed, 1177 insertions, 79 deletions
diff --git a/src/phHciNfc_CE_B.c b/src/phHciNfc_CE_B.c index 4b985a3..6583160 100644..100755 --- a/src/phHciNfc_CE_B.c +++ b/src/phHciNfc_CE_B.c @@ -40,10 +40,16 @@ #include <phHciNfc_Pipe.h> #include <phHciNfc_Emulation.h> #include <phOsalNfc.h> +#include <phLibNfc.h> +#include <phLibNfc_Internal.h> +#include <phHal4Nfc_Internal.h> +#include <phHciNfc_NfcIPMgmt.h> +#include <phHciNfc_Sequence.h> /* ****************************** Macro Definitions ******************************* */ #if defined (HOST_EMULATION) +#include <phHciNfc_CE.h> #include <phHciNfc_CE_B.h> #define CE_B_EVT_NFC_SEND_DATA 0x10U @@ -87,16 +93,34 @@ phHciNfc_Recv_CE_B_Response( #endif ); -#if defined (SEND_DATA_EVENT) -static -NFCSTATUS -phHciNfc_CE_B_ProcessData( - phHciNfc_sContext_t *psHciContext, - void *pHwRef, - uint8_t *pData, - uint8_t length - ); -#endif /* #if defined (SEND_DATA_EVENT) */ +/*Set CE config paramater response callback*/ +static + void phLibNfc_Mgt_SetCE_B_14443_4_ConfigParams_Cb( + void *context, + NFCSTATUS status + ); + + +/* Response callback for Remote Device Receive.*/ +static void phLibNfc_RemoteDev_CE_B_Receive_Cb( + void *context, + phHal_sRemoteDevInformation_t *ConnectedDevice, + phNfc_sData_t *rec_rsp_data, + NFCSTATUS status + ); + +/*Response callback for Remote Device Send.*/ +static void phLibNfc_RemoteDev_CE_B_Send_Cb( + void *Context, + NFCSTATUS status + ); + +static NFCSTATUS +phHciNfc_CE_B_SendData ( + phHciNfc_sContext_t *psHciContext, + void *pHwRef, + phHciNfc_XchgInfo_t *sData + ); /* *************************** Function Definitions *************************** @@ -129,7 +153,7 @@ phHciNfc_CE_B_Init_Resources( { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES); } - + } return status; } @@ -161,7 +185,7 @@ phHciNfc_CE_B_Initialise( ps_pipe_info = ps_ce_b_info->p_pipe_info; if(NULL == ps_pipe_info ) { - status = PHNFCSTVAL(CID_NFC_HCI, + status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else @@ -169,14 +193,14 @@ phHciNfc_CE_B_Initialise( switch(ps_ce_b_info->current_seq) { case HOST_CE_B_PIPE_OPEN: - { + { status = phHciNfc_Open_Pipe( psHciContext, pHwRef, ps_pipe_info ); if(status == NFCSTATUS_SUCCESS) { #if defined (CE_B_CONTINUE_SEQ) ps_ce_b_info->next_seq = HOST_CE_B_PUPI_SEQ; -#else +#else ps_ce_b_info->next_seq = HOST_CE_B_ENABLE_SEQ; #endif /* #if defined (CE_CONTINUE_SEQ) */ status = NFCSTATUS_PENDING; @@ -184,13 +208,13 @@ phHciNfc_CE_B_Initialise( break; } case HOST_CE_B_PUPI_SEQ: - { + { /* HOST Card Emulation B PUPI Configuration */ ps_pipe_info->reg_index = HOST_CE_B_ATQB_INDEX; - + ps_pipe_info->param_info =(void*)&pupi ; ps_pipe_info->param_length = sizeof(pupi) ; - status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef, + status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef, ps_pipe_info->pipe.pipe_id, (uint8_t)ANY_SET_PARAMETER); if(status == NFCSTATUS_PENDING) @@ -206,7 +230,7 @@ phHciNfc_CE_B_Initialise( /* Configure the ATQA of Host Card Emulation B */ ps_pipe_info->param_info = (void*)atqb_info ; ps_pipe_info->param_length = sizeof(atqb_info) ; - status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef, + status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef, ps_pipe_info->pipe.pipe_id, (uint8_t)ANY_SET_PARAMETER); if(status == NFCSTATUS_PENDING) @@ -261,7 +285,7 @@ phHciNfc_CE_B_Release( ps_pipe_info = ps_ce_b_info->p_pipe_info; if(NULL == ps_pipe_info ) { - status = PHNFCSTVAL(CID_NFC_HCI, + status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION); } else @@ -285,8 +309,9 @@ phHciNfc_CE_B_Release( pHwRef, ps_pipe_info ); if(status == NFCSTATUS_SUCCESS) { - ps_ce_b_info->next_seq = HOST_CE_B_PIPE_DELETE; - status = NFCSTATUS_PENDING; +// ps_ce_b_info->next_seq = HOST_CE_B_PIPE_DELETE; +// status = NFCSTATUS_PENDING; + ps_ce_b_info->next_seq = HOST_CE_B_PIPE_OPEN; } break; } @@ -347,11 +372,11 @@ phHciNfc_CE_B_Mode( if (NULL != ps_pipe_info) { ps_pipe_info->reg_index = HOST_CE_B_MODE_INDEX; - /* Enable/Disable Host Card Emulation A */ + /* Enable/Disable Host Card Emulation B */ param = (uint8_t)enable_type; ps_pipe_info->param_info =(void*)¶m ; ps_pipe_info->param_length = sizeof(param) ; - status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef, + status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef, ps_ce_b_info->pipe_id,(uint8_t)ANY_SET_PARAMETER); } else @@ -374,7 +399,7 @@ phHciNfc_CE_B_Get_PipeID( if( (NULL != psHciContext) && ( NULL != ppipe_id ) - && ( NULL != psHciContext->p_ce_b_info ) + && ( NULL != psHciContext->p_ce_b_info ) ) { phHciNfc_CE_B_Info_t *ps_ce_b_info=NULL; @@ -382,7 +407,7 @@ phHciNfc_CE_B_Get_PipeID( psHciContext->p_ce_b_info ; *ppipe_id = ps_ce_b_info->pipe_id ; } - else + else { status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); } @@ -422,7 +447,7 @@ phHciNfc_CE_B_Update_PipeInfo( ps_ce_b_info->p_pipe_info = pPipeInfo; if (NULL != pPipeInfo) { - /* Update the Response Receive routine of the card + /* Update the Response Receive routine of the card emulation A Gate */ pPipeInfo->recv_resp = &phHciNfc_Recv_CE_B_Response; /* Update the event Receive routine of the card emulation A Gate */ @@ -438,22 +463,6 @@ phHciNfc_CE_B_Update_PipeInfo( return status; } -#ifdef CE_B_SEND_EVENT -NFCSTATUS -phHciNfc_CE_B_SendData_Event( - void *psContext, - void *pHwRef, - uint8_t *pEvent, - uint8_t length - ) -{ - NFCSTATUS status = NFCSTATUS_SUCCESS; - phHciNfc_sContext_t *psHciContext = - (phHciNfc_sContext_t *)psContext ; - return status; -} -#endif /* #ifdef CE_B_SEND_EVENT */ - static NFCSTATUS phHciNfc_Recv_CE_B_Response( @@ -468,7 +477,7 @@ phHciNfc_Recv_CE_B_Response( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - phHciNfc_sContext_t *psHciContext = + phHciNfc_sContext_t *psHciContext = (phHciNfc_sContext_t *)psContext ; if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse) || (length == 0)) @@ -487,7 +496,7 @@ phHciNfc_Recv_CE_B_Response( psHciContext->p_ce_b_info ; if( NULL == ps_ce_b_info->p_pipe_info) { - status = PHNFCSTVAL(CID_NFC_HCI, + status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_SEQUENCE); } else @@ -499,7 +508,7 @@ phHciNfc_Recv_CE_B_Response( { #if 0 status = phHciNfc_CE_B_InfoUpdate(psHciContext, - ps_ce_b_info->p_pipe_info->reg_index, + ps_ce_b_info->p_pipe_info->reg_index, &pResponse[HCP_HEADER_LEN], (length - HCP_HEADER_LEN)); #endif /* #if 0 */ @@ -517,19 +526,19 @@ phHciNfc_Recv_CE_B_Response( } case ANY_CLOSE_PIPE: { - HCI_PRINT("CE B close pipe complete\n"); + HCI_PRINT("CE B close pipe complete\n"); break; } default: { - status = PHNFCSTVAL(CID_NFC_HCI, + status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); break; } } if( NFCSTATUS_SUCCESS == status ) { - status = phHciNfc_CE_B_Update_Seq(psHciContext, + status = phHciNfc_CE_B_Update_Seq(psHciContext, UPDATE_SEQ); ps_ce_b_info->p_pipe_info->prev_status = NFCSTATUS_SUCCESS; } @@ -553,7 +562,7 @@ phHciNfc_CE_B_Update_Seq( } else if( NULL == psHciContext->p_ce_b_info ) { - status = PHNFCSTVAL(CID_NFC_HCI, + status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); } else @@ -594,7 +603,7 @@ phHciNfc_CE_B_Update_Seq( } -static +static NFCSTATUS phHciNfc_Recv_CE_B_Event( void *psContext, @@ -608,7 +617,7 @@ phHciNfc_Recv_CE_B_Event( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - phHciNfc_sContext_t *psHciContext = + phHciNfc_sContext_t *psHciContext = (phHciNfc_sContext_t *)psContext ; if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent) || (length == 0)) @@ -621,10 +630,15 @@ phHciNfc_Recv_CE_B_Event( } else { + phHciNfc_NfcIP_Info_t *p_nfcipinfo= (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; + p_nfcipinfo->rem_nfcip_tgt_info.RemDevType = phHal_eISO14443_B_PCD; phHciNfc_HCP_Packet_t *p_packet = NULL; phHciNfc_CE_B_Info_t *ps_ce_b_info=NULL; phHciNfc_HCP_Message_t *message = NULL; static phHal_sEventInfo_t event_info; + static phNfc_sTransactionInfo_t trans_info; + void * pInfo = &event_info; + uint8_t evt = NFC_NOTIFY_EVENT; uint8_t instruction=0; ps_ce_b_info = (phHciNfc_CE_B_Info_t *) @@ -637,15 +651,18 @@ phHciNfc_Recv_CE_B_Event( 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_OFFSET, HCP_MSG_INSTRUCTION_LEN); psHciContext->host_rf_type = phHal_eISO14443_B_PICC; event_info.eventHost = phHal_eHostController; event_info.eventSource = phHal_eISO14443_B_PICC; + event_info.eventInfo.pRemoteDevInfo = &(p_nfcipinfo->rem_nfcip_tgt_info); switch(instruction) - { + { case CE_B_EVT_NFC_ACTIVATED: { + psHciContext->hci_state.cur_state = hciState_Listen; + psHciContext->hci_state.next_state = hciState_Unknown; event_info.eventType = NFC_EVT_ACTIVATED; /* Notify to the HCI Generic layer To Update the FSM */ break; @@ -658,27 +675,29 @@ phHciNfc_Recv_CE_B_Event( } case CE_B_EVT_NFC_SEND_DATA: { -#if defined (SEND_DATA_EVENT) HCI_PRINT("CE B data is received from the PN544\n"); if(length > HCP_HEADER_LEN) { - status = phHciNfc_CE_B_ProcessData( - psHciContext, pHwRef, - &pEvent[HCP_HEADER_LEN], - (length - HCP_HEADER_LEN)); + event_info.eventType = NFC_EVT_APDU_RECEIVED; + trans_info.status = status; + trans_info.type = NFC_NOTIFY_CE_B_RECV_EVENT; + trans_info.length = length - HCP_HEADER_LEN - 1; + trans_info.buffer = &pEvent[HCP_HEADER_LEN]; + trans_info.info = &event_info; + pInfo = &trans_info; + evt = NFC_NOTIFY_CE_B_RECV_EVENT; } else { - status = PHNFCSTVAL(CID_NFC_HCI, + status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE); } -#endif /* #if defined (SEND_DATA_EVENT) */ break; } case CE_B_EVT_NFC_FIELD_ON: { HCI_PRINT("CE B field on\n"); - event_info.eventType = NFC_EVT_FIELD_ON; + event_info.eventType = NFC_EVT_FIELD_ON; break; } case CE_B_EVT_NFC_FIELD_OFF: @@ -689,41 +708,1120 @@ phHciNfc_Recv_CE_B_Event( } default: { - status = PHNFCSTVAL(CID_NFC_HCI, + status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INSTRUCTION); break; } } if(NFCSTATUS_SUCCESS == status) { - phHciNfc_Notify_Event(psHciContext, pHwRef, - NFC_NOTIFY_EVENT, - &event_info); + phHciNfc_Notify_Event(psHciContext, pHwRef, + evt, + pInfo); } } return status; } -#if defined (SEND_DATA_EVENT) -static NFCSTATUS -phHciNfc_CE_B_ProcessData( - phHciNfc_sContext_t *psHciContext, - void *pHwRef, - uint8_t *pData, - uint8_t length - ) +phHciNfc_CE_B_SendData ( + phHciNfc_sContext_t *psHciContext, + void *pHwRef, + phHciNfc_XchgInfo_t *sData + ) { - NFCSTATUS status = NFCSTATUS_SUCCESS; + NFCSTATUS status = NFCSTATUS_SUCCESS; - static uint8_t send_data[] = {0x6D, 0x80}; - status = phHciNfc_CE_B_SendData_Event( - (void *)psHciContext, pHwRef, - send_data, sizeof(send_data)); + if( (NULL == psHciContext) || (NULL == pHwRef) || + (NULL == sData) || (0 == sData->tx_length) || (CE_MAX_SEND_BUFFER_LEN < sData->tx_length)) + { + status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER); + } + else if(NULL == psHciContext->p_ce_b_info) + { + status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED); + } + else + { + phHciNfc_CE_B_Info_t *ps_ce_b_info = (phHciNfc_CE_B_Info_t *) + psHciContext->p_ce_b_info ; + phHciNfc_Pipe_Info_t *p_pipe_info = ps_ce_b_info->p_pipe_info; + + if(NULL == p_pipe_info ) + { + status = PHNFCSTVAL(CID_NFC_HCI, + NFCSTATUS_INVALID_HCI_INFORMATION); + } + else + { + if (NFCSTATUS_SUCCESS == status) + { + 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 CE 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); + + /* Construct the HCP Frame */ + phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT, + (uint8_t) pipeid, (uint8_t)HCP_MSG_TYPE_EVENT, + (uint8_t)CE_B_EVT_NFC_SEND_DATA); + + phHciNfc_Append_HCPFrame((uint8_t *)hcp_message->payload, + i, sData->tx_buffer, + 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 = CE_B_EVT_NFC_SEND_DATA; + psHciContext->tx_total = length; + /* Send the Constructed HCP packet to the lower layer */ + status = phHciNfc_Send_HCP( psHciContext, pHwRef); + p_pipe_info->prev_status = status; + } + } + } return status; } -#endif /* #if defined (SEND_DATA_EVENT) */ +/**Receive complete handler*/ +void phHal4Nfc_CE_B_RecvCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo) +{ + pphHal4Nfc_TransceiveCallback_t pUpperRecvCb = NULL; + NFCSTATUS RecvStatus = ((phNfc_sTransactionInfo_t *)pInfo)->status; + /*allocate TrcvContext if not already allocated.Required since + Receive complete can occur before any other send /receive calls.*/ + if(NULL == Hal4Ctxt->psTrcvCtxtInfo) + { + Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t) + phOsalNfc_GetMemory((uint32_t) + (sizeof(phHal4Nfc_TrcvCtxtInfo_t))); + if(NULL != Hal4Ctxt->psTrcvCtxtInfo) + { + (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0, + sizeof(phHal4Nfc_TrcvCtxtInfo_t)); + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + = PH_OSALNFC_INVALID_TIMER_ID; + Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus + = NFCSTATUS_PENDING; + } + } + if(NULL == Hal4Ctxt->psTrcvCtxtInfo) + { + phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); + RecvStatus = PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_INSUFFICIENT_RESOURCES); + } + else + { + /*Allocate 4K buffer to copy the received data into*/ + if(NULL == Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) + { + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer + = (uint8_t *)phOsalNfc_GetMemory( + PH_HAL4NFC_MAX_RECEIVE_BUFFER + ); + if(NULL == Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) + { + phOsalNfc_RaiseException(phOsalNfc_e_NoMemory, + 0); + RecvStatus = NFCSTATUS_INSUFFICIENT_RESOURCES; + } + else /*memset*/ + { + (void)memset( + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer, + 0, + PH_HAL4NFC_MAX_RECEIVE_BUFFER + ); + } + } + + if(RecvStatus != NFCSTATUS_INSUFFICIENT_RESOURCES) + { + /*Copy the data*/ + (void)memcpy( + (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer + + Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength), + ((phNfc_sTransactionInfo_t *)pInfo)->buffer, + ((phNfc_sTransactionInfo_t *)pInfo)->length + ); + /*Update P2PRecvLength,this also acts as the offset to append more + received bytes*/ + Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength + += ((phNfc_sTransactionInfo_t *)pInfo)->length; + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length + = Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength; + } + + if(RecvStatus != NFCSTATUS_MORE_INFORMATION) + { + Hal4Ctxt->psTrcvCtxtInfo->P2PRecvLength = 0; + Hal4Ctxt->Hal4NextState = (eHal4StateTransaction + == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState); + if(NFCSTATUS_PENDING == Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus) + { + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb) + { + pUpperRecvCb = (pphHal4Nfc_TransceiveCallback_t)Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb; + Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL; + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData + = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData); + (*pUpperRecvCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, + RecvStatus + ); + } + else + { + /*Receive data buffer is complete with data & P2P receive has + not yet been called*/ + Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus + = NFCSTATUS_SUCCESS; + } + } + } + } + return; +} + +/** +* unblock any pending callback functions. +*/ +NFCSTATUS +phLibNfc_Mgt_Unblock_Cb_CE_B_14443_4( ) +{ + NFCSTATUS RetVal = NFCSTATUS_NOT_INITIALISED; + if(gpphLibContext!=NULL && (gpphLibContext->psHwReference)!=NULL && (gpphLibContext->psHwReference->hal_context)!=NULL) + { + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + Hal4Ctxt = gpphLibContext->psHwReference->hal_context; + if(Hal4Ctxt->rem_dev_list[0]!=NULL && + Hal4Ctxt->rem_dev_list[0]->SessionOpened==TRUE && + Hal4Ctxt->rem_dev_list[0]->RemDevType == phNfc_eISO14443_B_PCD + ) + { + phHciNfc_sContext_t *psHciContext = ((phHciNfc_sContext_t *)(Hal4Ctxt->psHciHandle)); + phHciNfc_NfcIP_Info_t *p_nfcipinfo= (phHciNfc_NfcIP_Info_t *) psHciContext->p_nfcip_info ; + p_nfcipinfo->rem_nfcip_tgt_info.RemDevType = phHal_eISO14443_B_PCD; + phHciNfc_CE_B_Info_t *ps_ce_b_info=NULL; + static phHal_sEventInfo_t event_info; + void * pInfo = &event_info; + + ps_ce_b_info = (phHciNfc_CE_B_Info_t *)psHciContext->p_ce_b_info ; + + /* Variable was set but never used (ARM warning) */ + PHNFC_UNUSED_VARIABLE(ps_ce_b_info); + + psHciContext->host_rf_type = phHal_eISO14443_B_PICC; + event_info.eventHost = phHal_eHostController; + event_info.eventSource = phHal_eISO14443_B_PICC; + event_info.eventInfo.pRemoteDevInfo = &(p_nfcipinfo->rem_nfcip_tgt_info); + event_info.eventType = NFC_EVT_DEACTIVATED; + phHciNfc_Notify_Event(psHciContext, gpphLibContext->psHwReference, + NFC_NOTIFY_EVENT, + pInfo); + RetVal = NFCSTATUS_SUCCESS; + } + } + return RetVal; +} + + +/** +* Interface to configure Card Emulation configurations. +*/ +NFCSTATUS +phLibNfc_Mgt_SetCE_B_14443_4_ConfigParams( + uint8_t emulate, + pphLibNfc_RspCb_t pConfigRspCb, + void* pContext + ) +{ + NFCSTATUS RetVal = NFCSTATUS_FAILED; + /* LibNfc Initialized or not */ + if((NULL == gpphLibContext)|| + (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) + { + RetVal = NFCSTATUS_NOT_INITIALISED; + }/* Check for valid parameters */ + else if((NULL == pConfigRspCb) + || (NULL == pContext)) + { + RetVal= NFCSTATUS_INVALID_PARAMETER; + } + else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) + { + RetVal = NFCSTATUS_SHUTDOWN; + } + else if(TRUE == gpphLibContext->status.GenCb_pending_status) + { /*Previous callback is pending */ + RetVal = NFCSTATUS_BUSY; + } + else + { + if(eLibNfcHalStatePresenceChk != + gpphLibContext->LibNfcState.next_state) + { + phHal_uConfig_t uConfig; + uConfig.emuConfig.emuType = NFC_HOST_CE_B_EMULATION; + uConfig.emuConfig.config.hostEmuCfg_B.enableEmulation = emulate; + if(emulate==FALSE) + { + //de-activate any pending commands + phLibNfc_Mgt_Unblock_Cb_CE_B_14443_4(); + } + RetVal = phHal4Nfc_ConfigParameters( + gpphLibContext->psHwReference, + NFC_EMULATION_CONFIG, + &uConfig, + phLibNfc_Mgt_SetCE_B_14443_4_ConfigParams_Cb, + (void *)gpphLibContext + ); + } + else + { + gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb= NULL; + RetVal = NFCSTATUS_PENDING; + } + if(NFCSTATUS_PENDING == RetVal) + { + /* save the context and callback for later use */ + gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = pConfigRspCb; + gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = pContext; + gpphLibContext->status.GenCb_pending_status=TRUE; + /* Next state is configured */ + gpphLibContext->LibNfcState.next_state =eLibNfcHalStateConfigReady; + } + else + { + RetVal = NFCSTATUS_FAILED; + } + } + return RetVal; +} +/** +* Response callback for CE configurations. +*/ +static void phLibNfc_Mgt_SetCE_B_14443_4_ConfigParams_Cb(void *context, + NFCSTATUS status) +{ + pphLibNfc_RspCb_t pClientCb=NULL; + void *pUpperLayerContext=NULL; + /* Check for the context returned by below layer */ + if((phLibNfc_LibContext_t *)context != gpphLibContext) + { /*wrong context returned*/ + phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); + } + else + { + if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) + { /*shutdown called before completion of this api allow + shutdown to happen */ + phLibNfc_Pending_Shutdown(); + status = NFCSTATUS_SHUTDOWN; + } + else + { + gpphLibContext->status.GenCb_pending_status = FALSE; + if(NFCSTATUS_SUCCESS != status) + { + status = NFCSTATUS_FAILED; + } + else + { + status = NFCSTATUS_SUCCESS; + } + } + /*update the current state */ + phLibNfc_UpdateCurState(status,gpphLibContext); + + pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb; + pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx; + + gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = NULL; + gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = NULL; + if (NULL != pClientCb) + { + /* Notify to upper layer status of configure operation */ + pClientCb(pUpperLayerContext, status); + } + } + return; +} + + +/* Transfer the user data to the another NfcIP device from the host. + * pTransferCallback is called, when all steps in the transfer sequence are + * completed.*/ +NFCSTATUS +phHal4Nfc_CE_B_Receive( + phHal_sHwReference_t *psHwReference, + phHal4Nfc_TransactInfo_t *psRecvInfo, + pphHal4Nfc_TransceiveCallback_t pReceiveCallback, + void *pContext + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_PENDING; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + /*NULL checks*/ + if((NULL == psHwReference) + ||( NULL == pReceiveCallback) + ||( NULL == psRecvInfo)) + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER); + } + /*Check initialised state*/ + else if((NULL == psHwReference->hal_context) + || (((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->Hal4CurrentState + < eHal4StateOpenAndReady) + || (((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->Hal4NextState + == eHal4StateClosed)) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED); + } + else + { + Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; + if(NFC_EVT_ACTIVATED == Hal4Ctxt->sTgtConnectInfo.EmulationState) + { + /*Following condition gets satisfied only on target side,if receive + is not already called*/ + if(NULL == Hal4Ctxt->psTrcvCtxtInfo) + { + Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t) + phOsalNfc_GetMemory((uint32_t) + (sizeof(phHal4Nfc_TrcvCtxtInfo_t))); + if(NULL != Hal4Ctxt->psTrcvCtxtInfo) + { + (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0, + sizeof(phHal4Nfc_TrcvCtxtInfo_t)); + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + = PH_OSALNFC_INVALID_TIMER_ID; + Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus = NFCSTATUS_PENDING; + } + } + if(NULL == Hal4Ctxt->psTrcvCtxtInfo) + { + phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); + RetStatus= PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_INSUFFICIENT_RESOURCES); + } + else /*Store callback & Return status pending*/ + { + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; + /*Register upper layer callback*/ + Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; + Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = (pphHal4Nfc_ReceiveCallback_t)pReceiveCallback; + if(NFCSTATUS_PENDING != + Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus) + { + /**Create a timer to send received data in the callback*/ + if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + == PH_OSALNFC_INVALID_TIMER_ID) + { + PHDBG_INFO("HAL4: Transaction Timer Create for Receive"); + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + = phOsalNfc_Timer_Create(); + } + if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + == PH_OSALNFC_INVALID_TIMER_ID) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_INSUFFICIENT_RESOURCES); + } + else/*start the timer*/ + { + phOsalNfc_Timer_Start( + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId, + PH_HAL4NFC_CE_RECV_CB_TIMEOUT, + phHal4Nfc_CE_RecvTimerCb, + NULL + ); + } + } + } + } + else/*deactivated*/ + { + RetStatus= PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_DESELECTED); + } + } + return RetStatus; +} + +/** +* Interface used to transceive data from target to reader during CE communication +*/ +NFCSTATUS +phLibNfc_RemoteDev_CE_B_Transceive( + phNfc_sData_t * pTransferData, + pphLibNfc_TransceiveCallback_t pTransceive_RspCb, + void *pContext + ) +{ + NFCSTATUS RetVal = NFCSTATUS_FAILED; + /*Check Lib Nfc stack is initilized*/ + if((NULL == gpphLibContext)|| + (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) + { + RetVal = NFCSTATUS_NOT_INITIALISED; + } + else if (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateRelease) + { + RetVal = NFCSTATUS_DESELECTED; + } + /*Check application has sent the valid parameters*/ + else if((NULL == pTransferData) + || (NULL == pTransceive_RspCb) + || (NULL == pTransferData->buffer) + || (0 == pTransferData->length) + || (NULL == pContext)) + { + RetVal= NFCSTATUS_INVALID_PARAMETER; + } + else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) + { + RetVal = NFCSTATUS_SHUTDOWN; + } + else if((TRUE == gpphLibContext->status.GenCb_pending_status) + ||(NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb)) + { + /*Previous callback is pending or local device is Initiator + then don't allow */ + RetVal = NFCSTATUS_REJECTED; + } + else if((NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb)) + { + RetVal =NFCSTATUS_BUSY ; + } + else + { + if(eLibNfcHalStatePresenceChk == + gpphLibContext->LibNfcState.next_state) + { + gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL; + RetVal = NFCSTATUS_PENDING; + } + else + { + if(gpphLibContext->psTransInfo!=NULL) + { + (void)memset(gpphLibContext->psTransInfo, + 0, + sizeof(phLibNfc_sTransceiveInfo_t)); + + gpphLibContext->psTransInfo->addr =UNKNOWN_BLOCK_ADDRESS; + /*pointer to send data */ + gpphLibContext->psTransInfo->sSendData.buffer = + pTransferData->buffer; + /*size of send data*/ + gpphLibContext->psTransInfo->sSendData.length = + pTransferData->length; + + /*Call Hal4 Send API and register callback with it*/ + PHDBG_INFO("LibNfc:CE send In Progress"); + RetVal= phHal4Nfc_CE_B_Transceive( + gpphLibContext->psHwReference, + &(gpphLibContext->sNfcIp_Context.TransactInfoRole), + gpphLibContext->psTransInfo->sSendData, + (pphHal4Nfc_TransceiveCallback_t) phLibNfc_RemoteDev_CE_B_Receive_Cb, + (void *)gpphLibContext + ); + } + } + if(NFCSTATUS_PENDING == RetVal) + { + /* Update next state to transaction */ + gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb= (pphLibNfc_Receive_RspCb_t) pTransceive_RspCb; + gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb= NULL; + gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = pContext; + gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = pContext; + gpphLibContext->status.GenCb_pending_status=TRUE; + gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; + } + else + { + RetVal = NFCSTATUS_FAILED; + } + } + return RetVal; +} + +/* Transfer the user data to reader device from the host. + * pTransferCallback is called, when all steps in the transfer sequence are + * completed.*/ +NFCSTATUS +phHal4Nfc_CE_B_Transceive( + phHal_sHwReference_t *psHwReference, + phHal4Nfc_TransactInfo_t *psTransferInfo, + phNfc_sData_t sTransferData, + pphHal4Nfc_TransceiveCallback_t pTransceiveCallback, + void *pContext + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_PENDING; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + /*NULL checks*/ + if((NULL == psHwReference) + ||( NULL == pTransceiveCallback ) + || (NULL == psTransferInfo) + ) + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER); + } + /*Check initialised state*/ + else if((NULL == psHwReference->hal_context) + || (((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->Hal4CurrentState + < eHal4StateOpenAndReady) + || (((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->Hal4NextState + == eHal4StateClosed)) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED); + } + else + { + Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; + if(NULL == Hal4Ctxt->psTrcvCtxtInfo) + { + RetStatus= PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED); + } + /*Check Activated*/ + else if(NFC_EVT_ACTIVATED == Hal4Ctxt->sTgtConnectInfo.EmulationState) + { + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; + /*Register upper layer callback*/ + Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; + Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = (pphHal4Nfc_ReceiveCallback_t)pTransceiveCallback; + PHDBG_INFO("NfcIP1 Send"); + /*allocate buffer to store senddata received from upper layer*/ + if (NULL == Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData) + { + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData = (phNfc_sData_t *) + phOsalNfc_GetMemory(sizeof(phNfc_sData_t)); + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData) + { + (void)memset(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData, 0, + sizeof(phNfc_sData_t)); + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + = PH_OSALNFC_INVALID_TIMER_ID; + } + } + + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer + = sTransferData.buffer; + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length + = sTransferData.length; + /*If data size is less than MAX_SEND_LEN ,no chaining is required*/ + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.nfc_info.more_info = FALSE; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length + = (uint8_t)sTransferData.length; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer + = sTransferData.buffer; + + PHDBG_INFO("HAL4:Calling Hci_Send_data()"); + + RetStatus = phHciNfc_CE_B_SendData ( + (phHciNfc_sContext_t *)Hal4Ctxt->psHciHandle, + psHwReference, + &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) + ); + + /*check return status*/ + if (NFCSTATUS_PENDING == RetStatus) + { + /*Set P2P_Send_In_Progress to defer any disconnect call until + Send complete occurs*/ + Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE; + Hal4Ctxt->Hal4NextState = eHal4StateTransaction; + /*No of bytes remaining for next send*/ + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length + -= Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length; + } + } + else/*Deactivated*/ + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_DESELECTED); + } + } + return RetStatus; +} + +/** +* Interface used to receive data from initiator at target side during P2P +* communication. +*/ +NFCSTATUS phLibNfc_RemoteDev_CE_B_Receive( + pphLibNfc_TransceiveCallback_t pReceiveRspCb, + void *pContext + ) +{ + NFCSTATUS RetVal = NFCSTATUS_FAILED; + /*Check Lib Nfc is initialized*/ + if((NULL == gpphLibContext)|| + (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) + { + RetVal = NFCSTATUS_NOT_INITIALISED; + }/*Check application has sent valid parameters*/ + else if (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateRelease) + { + RetVal = NFCSTATUS_DESELECTED; + } + else if((NULL == pReceiveRspCb) + || (NULL == pContext)) + { + RetVal= NFCSTATUS_INVALID_PARAMETER; + } + else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) + { + RetVal = NFCSTATUS_SHUTDOWN; + } + else if((TRUE == gpphLibContext->status.GenCb_pending_status) + ||(NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb)) + { + /*Previous callback is pending or if initiator uses this api */ + RetVal = NFCSTATUS_REJECTED; + } + else + { + if(eLibNfcHalStatePresenceChk == + gpphLibContext->LibNfcState.next_state) + { + gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL; + RetVal = NFCSTATUS_PENDING; + } + else + { + /*Call below layer receive and register the callback with it*/ + PHDBG_INFO("LibNfc:CE Receive In Progress"); + RetVal =phHal4Nfc_CE_B_Receive( + gpphLibContext->psHwReference, + (phHal4Nfc_TransactInfo_t*)gpphLibContext->psTransInfo, + (pphHal4Nfc_TransceiveCallback_t)phLibNfc_RemoteDev_CE_B_Receive_Cb, + (void *)gpphLibContext + ); + } + + if(NFCSTATUS_PENDING == RetVal) + { + /*Update the Next state as Transaction*/ + gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb= (pphHal4Nfc_ReceiveCallback_t) pReceiveRspCb; + gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = pContext; + gpphLibContext->status.GenCb_pending_status=TRUE; + gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; + } + else + { + RetVal = NFCSTATUS_FAILED; + } + } + return RetVal; +} + +/** +* Response callback for Remote Device Receive. +*/ +static void phLibNfc_RemoteDev_CE_B_Receive_Cb( + void *context, + phHal_sRemoteDevInformation_t *ConnectedDevice, + phNfc_sData_t *rec_rsp_data, + NFCSTATUS status + ) +{ + pphLibNfc_TransceiveCallback_t pClientCb=NULL; + + phLibNfc_LibContext_t *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)context; + void *pUpperLayerContext=NULL; + + /* Check for the context returned by below layer */ + if(pLibNfc_Ctxt != gpphLibContext) + { /*wrong context returned*/ + phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); + } + else + { + pClientCb = (pphLibNfc_TransceiveCallback_t) gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb; + pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx; + + gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb = NULL; + gpphLibContext->sNfcIp_Context.pClientNfcIpRxCntx = NULL; + gpphLibContext->status.GenCb_pending_status = FALSE; + if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) + { /*shutdown called before completion of P2P receive allow + shutdown to happen */ + phLibNfc_Pending_Shutdown(); + status = NFCSTATUS_SHUTDOWN; + } + else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state) + { + status = NFCSTATUS_ABORTED; + } + else + { + if((NFCSTATUS_SUCCESS != status) && + (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION ) ) + { + /*During CE receive operation initiator was removed + from RF field of target*/ + status = NFCSTATUS_DESELECTED; + } + else + { + status = NFCSTATUS_SUCCESS; + } + } + /* Update current state */ + phLibNfc_UpdateCurState(status,gpphLibContext); + + if (NULL != pClientCb) + { + /*Notify to upper layer status and No. of bytes + actually received */ + pClientCb(pUpperLayerContext, (uint32_t)ConnectedDevice, rec_rsp_data, status); + } + } + return; +} + + +/* Transfer the user data to a reader device from the host. + * pTransferCallback is called, when all steps in the transfer sequence are + * completed.*/ +NFCSTATUS +phHal4Nfc_CE_B_Send( + phHal_sHwReference_t *psHwReference, + phHal4Nfc_TransactInfo_t *psTransferInfo, + phNfc_sData_t sTransferData, + pphHal4Nfc_SendCallback_t pSendCallback, + void *pContext + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_PENDING; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + /*NULL checks*/ + if((NULL == psHwReference) + ||( NULL == pSendCallback ) + || (NULL == psTransferInfo) + ) + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER); + } + /*Check initialised state*/ + else if((NULL == psHwReference->hal_context) + || (((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->Hal4CurrentState + < eHal4StateOpenAndReady) + || (((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->Hal4NextState + == eHal4StateClosed)) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED); + } + else + { + Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; + if(NULL == Hal4Ctxt->psTrcvCtxtInfo) + { + RetStatus= PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED); + } + /*Check Activated*/ + else if(NFC_EVT_ACTIVATED == Hal4Ctxt->sTgtConnectInfo.EmulationState) + { + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; + /*Register upper layer callback*/ + Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb = pSendCallback; + PHDBG_INFO("NfcIP1 Send"); + /*allocate buffer to store senddata received from upper layer*/ + if (NULL == Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData) + { + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData = (phNfc_sData_t *) + phOsalNfc_GetMemory(sizeof(phNfc_sData_t)); + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData) + { + (void)memset(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData, 0, + sizeof(phNfc_sData_t)); + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + = PH_OSALNFC_INVALID_TIMER_ID; + } + } + + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer + = sTransferData.buffer; + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length + = sTransferData.length; + /*If data size is less than MAX_SEND_LEN ,no chaining is required*/ + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.nfc_info.more_info = FALSE; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length + = (uint8_t)sTransferData.length; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer + = sTransferData.buffer; + + PHDBG_INFO("HAL4:Calling Hci_Send_data()"); + + RetStatus = phHciNfc_CE_B_SendData ( + (phHciNfc_sContext_t *)Hal4Ctxt->psHciHandle, + psHwReference, + &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) + ); + + /*check return status*/ + if (NFCSTATUS_PENDING == RetStatus) + { + /*Set P2P_Send_In_Progress to defer any disconnect call until + Send complete occurs*/ + Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE; + Hal4Ctxt->Hal4NextState = eHal4StateTransaction; + /*No of bytes remaining for next send*/ + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length + -= Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length; + } + } + else/*Deactivated*/ + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_DESELECTED); + } + } + return RetStatus; +} + +/** +* Interface used to send data from target to reader during CE communication +*/ +NFCSTATUS +phLibNfc_RemoteDev_CE_B_Send( + phNfc_sData_t * pTransferData, + pphLibNfc_RspCb_t pSendRspCb, + void *pContext + ) +{ + NFCSTATUS RetVal = NFCSTATUS_FAILED; + /*Check Lib Nfc stack is initilized*/ + if((NULL == gpphLibContext)|| + (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown)) + { + RetVal = NFCSTATUS_NOT_INITIALISED; + } + else if (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateRelease) + { + RetVal = NFCSTATUS_DESELECTED; + } + /*Check application has sent the valid parameters*/ + else if((NULL == pTransferData) + || (NULL == pSendRspCb) + || (NULL == pTransferData->buffer) + || (0 == pTransferData->length) + || (NULL == pContext)) + { + RetVal= NFCSTATUS_INVALID_PARAMETER; + } + else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown) + { + RetVal = NFCSTATUS_SHUTDOWN; + } + else if((TRUE == gpphLibContext->status.GenCb_pending_status) + ||(NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb)) + { + /*Previous callback is pending or local device is Initiator + then don't allow */ + RetVal = NFCSTATUS_REJECTED; + }/*Check for Discovered initiator handle and handle sent by application */ + else if((NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb)) + { + RetVal =NFCSTATUS_BUSY ; + } + else + { + if(eLibNfcHalStatePresenceChk == + gpphLibContext->LibNfcState.next_state) + { + gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL; + RetVal = NFCSTATUS_PENDING; + } + else + { + if(gpphLibContext->psTransInfo!=NULL) + { + (void)memset(gpphLibContext->psTransInfo, + 0, + sizeof(phLibNfc_sTransceiveInfo_t)); + + gpphLibContext->psTransInfo->addr =UNKNOWN_BLOCK_ADDRESS; + /*pointer to send data */ + gpphLibContext->psTransInfo->sSendData.buffer = + pTransferData->buffer; + /*size of send data*/ + gpphLibContext->psTransInfo->sSendData.length = + pTransferData->length; + + /*Call Hal4 Send API and register callback with it*/ + PHDBG_INFO("LibNfc:CE send In Progress"); + RetVal= phHal4Nfc_CE_B_Send( + gpphLibContext->psHwReference, + &(gpphLibContext->sNfcIp_Context.TransactInfoRole), + gpphLibContext->psTransInfo->sSendData, + (pphLibNfc_RspCb_t) + phLibNfc_RemoteDev_CE_B_Send_Cb, + (void *)gpphLibContext + ); + } + } + if(NFCSTATUS_PENDING == RetVal) + { + /* Update next state to transaction */ + gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb= pSendRspCb; + gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = pContext; + gpphLibContext->status.GenCb_pending_status=TRUE; + gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction; + } + else + { + RetVal = NFCSTATUS_FAILED; + } + } + return RetVal; +} + +/* +* Response callback for Remote Device Send. +*/ +static void phLibNfc_RemoteDev_CE_B_Send_Cb( + void *Context, + NFCSTATUS status + ) +{ + pphLibNfc_RspCb_t pClientCb=NULL; + phLibNfc_LibContext_t *pLibNfc_Ctxt = (phLibNfc_LibContext_t *)Context; + void *pUpperLayerContext=NULL; + + /* Check for the context returned by below layer */ + if(pLibNfc_Ctxt != gpphLibContext) + { /*wrong context returned*/ + phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); + } + else + { + if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state) + { /*shutdown called before completion p2p send allow + shutdown to happen */ + phLibNfc_Pending_Shutdown(); + status = NFCSTATUS_SHUTDOWN; + } + else if(eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state) + { + status = NFCSTATUS_ABORTED; + } + else + { + gpphLibContext->status.GenCb_pending_status = FALSE; + if((NFCSTATUS_SUCCESS != status) && + (PHNFCSTATUS(status) != NFCSTATUS_MORE_INFORMATION ) ) + { + /*During p2p send operation initator was not present in RF + field of target*/ + status = NFCSTATUS_DESELECTED; + } + else + { + status = NFCSTATUS_SUCCESS; + } + } + /* Update current state */ + phLibNfc_UpdateCurState(status,gpphLibContext); + + pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb; + pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx; + + gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb = NULL; + gpphLibContext->sNfcIp_Context.pClientNfcIpTxCntx = NULL; + if (NULL != pClientCb) + { + /* Notify to upper layer status and No. of bytes + actually written or send to initiator */ + pClientCb(pUpperLayerContext, status); + } + } + return; +} + +/**Send complete handler*/ +void phHal4Nfc_CE_B_SendCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo) +{ + pphHal4Nfc_SendCallback_t pUpperSendCb = NULL; + NFCSTATUS SendStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; + pphHal4Nfc_DiscntCallback_t pUpperDisconnectCb = NULL; + Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = FALSE; + + /*Send status Success or Pending disconnect in HAl4*/ + if((SendStatus != NFCSTATUS_SUCCESS) + ||(NFC_INVALID_RELEASE_TYPE != Hal4Ctxt->sTgtConnectInfo.ReleaseType)) + { + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + /*Update Status*/ + SendStatus = (NFCSTATUS)(NFC_INVALID_RELEASE_TYPE != + Hal4Ctxt->sTgtConnectInfo.ReleaseType?NFCSTATUS_RELEASED:SendStatus); + /*Callback For Target Send*/ + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb) + { + pUpperSendCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb; + Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb = NULL; + (*pUpperSendCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + SendStatus + ); + } + /*Issue Pending disconnect from HAl4*/ + if(NFC_INVALID_RELEASE_TYPE != Hal4Ctxt->sTgtConnectInfo.ReleaseType) + { + SendStatus = phHal4Nfc_Disconnect_Execute(gpphHal4Nfc_Hwref); + if((NFCSTATUS_PENDING != SendStatus) && + (NULL != Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb)) + { + pUpperDisconnectCb = + Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb; + Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb = NULL; + (*pUpperDisconnectCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerDisconnectCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + SendStatus + );/*Notify disconnect failed to upper layer*/ + } + } + } + else + { + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent = 0; + /*Callback For Target Send*/ + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb) + { + pUpperSendCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb; + Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb = NULL; + (*pUpperSendCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + SendStatus + ); + } + } + return; +} #endif /* #if defined (HOST_EMULATION) */ |