| /* |
| * 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 phLibNfc_Target.c |
| |
| * Project: NFC FRI 1.1 |
| * |
| * $Date: Thu Oct 15 15:24:43 2009 $ |
| * $Author: ing07299 $ |
| * $Revision: 1.12 $ |
| * $Aliases: NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK944_SDK,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK949_SDK_INT,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK1003_SDK,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1008_SDK,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1007_SDK,NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $ |
| * |
| */ |
| |
| /* |
| ************************* Header Files *************************************** |
| */ |
| |
| #include <phLibNfcStatus.h> |
| #include <phLibNfc.h> |
| #include <phHal4Nfc.h> |
| #include <phOsalNfc.h> |
| #include <phLibNfc_Internal.h> |
| #include <phLibNfc_ndef_raw.h> |
| #include <phLibNfc_initiator.h> |
| #include <phLibNfc_discovery.h> |
| |
| /* |
| *************************** Macro's **************************************** |
| */ |
| |
| #ifndef STATIC_DISABLE |
| #define STATIC static |
| #else |
| //#undef STATIC |
| #define STATIC |
| #endif |
| /* |
| *************************** Global Variables ********************************** |
| */ |
| |
| /* |
| *************************** Static Function Declaration *********************** |
| */ |
| |
| /* Remote device receive callback */ |
| STATIC void phLibNfc_RemoteDev_Receive_Cb( |
| void *context, |
| phNfc_sData_t *rec_rsp_data, |
| NFCSTATUS status |
| ); |
| |
| /* Remote device Send callback */ |
| STATIC void phLibNfc_RemoteDev_Send_Cb( |
| void *Context, |
| NFCSTATUS status |
| ); |
| |
| /* |
| *************************** Function Definitions ****************************** |
| */ |
| |
| /** |
| * Interface used to receive data from initiator at target side during P2P |
| * communication. |
| */ |
| NFCSTATUS phLibNfc_RemoteDev_Receive(phLibNfc_Handle hRemoteDevice, |
| pphLibNfc_Receive_RspCb_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) |
| || (0 == hRemoteDevice)) |
| { |
| 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) |
| ||(phHal_eNfcIP1_Target== |
| ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType)) |
| { |
| /*Previous callback is pending or if initiator uses this api */ |
| RetVal = NFCSTATUS_REJECTED; |
| }/*check for Discovered initiator handle and handle sent by application */ |
| else if(gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle != hRemoteDevice) |
| { |
| RetVal= NFCSTATUS_INVALID_DEVICE; |
| } |
| #ifdef LLCP_TRANSACT_CHANGES |
| else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state) |
| && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state)) |
| { |
| RetVal = NFCSTATUS_BUSY; |
| } |
| #endif /* #ifdef LLCP_TRANSACT_CHANGES */ |
| 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:P2P Receive In Progress"); |
| RetVal =phHal4Nfc_Receive( |
| gpphLibContext->psHwReference, |
| (phHal4Nfc_TransactInfo_t*)gpphLibContext->psTransInfo, |
| (pphLibNfc_Receive_RspCb_t) |
| phLibNfc_RemoteDev_Receive_Cb, |
| (void *)gpphLibContext |
| ); |
| } |
| if(NFCSTATUS_PENDING == RetVal) |
| { |
| /*Update the Next state as Transaction*/ |
| gpphLibContext->sNfcIp_Context.pClientNfcIpRxCb= 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_Receive_Cb( |
| void *context, |
| phNfc_sData_t *rec_rsp_data, |
| NFCSTATUS status |
| ) |
| { |
| pphLibNfc_Receive_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 |
| { |
| pClientCb = 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 p2p 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, rec_rsp_data, status); |
| } |
| } |
| return; |
| } |
| |
| /** |
| * Interface used to send data from target to initiator during P2P communication |
| */ |
| NFCSTATUS |
| phLibNfc_RemoteDev_Send( |
| phLibNfc_Handle hRemoteDevice, |
| 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) |
| || (0 == hRemoteDevice)) |
| { |
| 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) |
| ||(phHal_eNfcIP1_Target== |
| ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType)) |
| { |
| /*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(gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle != hRemoteDevice) |
| { |
| RetVal= NFCSTATUS_INVALID_DEVICE; |
| } |
| else if((NULL!=gpphLibContext->sNfcIp_Context.pClientNfcIpTxCb)) |
| { |
| RetVal =NFCSTATUS_BUSY ; |
| } |
| #ifdef LLCP_TRANSACT_CHANGES |
| else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state) |
| && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state)) |
| { |
| RetVal= NFCSTATUS_BUSY; |
| } |
| #endif /* #ifdef LLCP_TRANSACT_CHANGES */ |
| 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; |
| |
| /* Copy remote device type */ |
| gpphLibContext->sNfcIp_Context.TransactInfoRole.remotePCDType = |
| ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType; |
| /*Call Hal4 Send API and register callback with it*/ |
| PHDBG_INFO("LibNfc:P2P send In Progress"); |
| RetVal= phHal4Nfc_Send( |
| gpphLibContext->psHwReference, |
| &(gpphLibContext->sNfcIp_Context.TransactInfoRole), |
| gpphLibContext->psTransInfo->sSendData, |
| (pphLibNfc_RspCb_t) |
| phLibNfc_RemoteDev_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_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; |
| } |
| |
| |
| |
| |