diff options
author | Nick Pelly <npelly@google.com> | 2010-09-23 12:47:58 -0700 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2010-09-23 13:53:18 -0700 |
commit | 5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a (patch) | |
tree | 190f9251c6db03d3550ec7f30b51a2561c01d9cf /src/phHal4Nfc_P2P.c | |
parent | 4ff7c86a2c706b150078274455406f1b04966e1a (diff) | |
download | external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.zip external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.gz external_libnfc-nxp-5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a.tar.bz2 |
Initial libnfc checkin
Source: Trusted_NFC_Device_Host_AA03.01e02_google.zip code drop (23-Sep-2010)
Change-Id: Ie47f18423f949a8d3e0815d13f55c814312add24
Signed-off-by: Nick Pelly <npelly@google.com>
Diffstat (limited to 'src/phHal4Nfc_P2P.c')
-rw-r--r-- | src/phHal4Nfc_P2P.c | 750 |
1 files changed, 750 insertions, 0 deletions
diff --git a/src/phHal4Nfc_P2P.c b/src/phHal4Nfc_P2P.c new file mode 100644 index 0000000..2397812 --- /dev/null +++ b/src/phHal4Nfc_P2P.c @@ -0,0 +1,750 @@ +/* + * 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 phHal4Nfc_P2P.c + * \brief Hal4Nfc_P2P source. + * + * Project: NFC-FRI 1.1 + * + * $Date: Mon May 31 11:43:43 2010 $ + * $Author: ing07385 $ + * $Revision: 1.56 $ + * $Aliases: NFC_FRI1.1_WK1023_R35_1 $ + * + */ + +/* ---------------------------Include files ------------------------------------*/ +#include <phHal4Nfc.h> +#include <phHal4Nfc_Internal.h> +#include <phOsalNfc.h> +#include <phOsalNfc_Timer.h> +#include <phHciNfc.h> +#include <phNfcConfig.h> +/* ------------------------------- Macros ------------------------------------*/ + +#ifdef _WIN32 +/*Timeout value for recv data timer for P2P.This timer is used for creating + Asynchronous behavior in the scenario where the data is received even before + the upper layer calls the phHal4Nfc_receive().*/ +#define PH_HAL4NFC_RECV_CB_TIMEOUT 100U +#else +#define PH_HAL4NFC_RECV_CB_TIMEOUT 0x00U +#endif/*#ifdef _WIN32*/ + + +/* --------------------Structures and enumerations --------------------------*/ + +/*timer callback to send already buffered receive data to upper layer*/ +static void phHal4Nfc_P2PRecvTimerCb(uint32_t P2PRecvTimerId, void *pContext); + +/* ---------------------- Function definitions ------------------------------*/ + +/* Transfer the user data to another NfcIP device from the host. + * pTransferCallback is called, when all steps in the transfer sequence are + * completed.*/ +NFCSTATUS +phHal4Nfc_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); + } + /*Only NfcIp1 Target can call this API*/ + else if(phHal_eNfcIP1_Initiator != psTransferInfo->remotePCDType) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_DEVICE); + } + 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*/ + if(PH_HAL4NFC_MAX_SEND_LEN >= sTransferData.length) + { + 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; + } + else/*set more_info to true,to indicate more data pending to be sent*/ + { + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.nfc_info.more_info = TRUE; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length + = PH_HAL4NFC_MAX_SEND_LEN; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer + = sTransferData.buffer; + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent + += PH_HAL4NFC_MAX_SEND_LEN; + } + PHDBG_INFO("HAL4:Calling Hci_Send_data()"); + RetStatus = phHciNfc_Send_Data ( + Hal4Ctxt->psHciHandle, + psHwReference, + NULL, + &(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; +} + + +/* 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_Receive( + phHal_sHwReference_t *psHwReference, + phHal4Nfc_TransactInfo_t *psRecvInfo, + pphHal4Nfc_ReceiveCallback_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 = 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_RECV_CB_TIMEOUT, + phHal4Nfc_P2PRecvTimerCb, + NULL + ); + } + } + } + } + else/*deactivated*/ + { + RetStatus= PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_DESELECTED); + } + } + return RetStatus; +} + +/*Timer callback for recv data timer for P2P.This timer is used for creating + Asynchronous behavior in the scenario where the data is received even before + the upper layer calls the phHal4Nfc_receive().*/ +static void phHal4Nfc_P2PRecvTimerCb(uint32_t P2PRecvTimerId, void *pContext) +{ + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)( + gpphHal4Nfc_Hwref->hal_context); + pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL; + NFCSTATUS RecvDataBufferStatus = NFCSTATUS_PENDING; + PHNFC_UNUSED_VARIABLE(pContext); + + phOsalNfc_Timer_Stop(P2PRecvTimerId); + phOsalNfc_Timer_Delete(P2PRecvTimerId); + if(NULL != Hal4Ctxt->psTrcvCtxtInfo) + { + RecvDataBufferStatus = Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus; + Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus = NFCSTATUS_PENDING; + + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + = PH_OSALNFC_INVALID_TIMER_ID; + /*Update state*/ + Hal4Ctxt->Hal4NextState = (eHal4StateTransaction + == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState); + /*Provide address of received data to upper layer data pointer*/ + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData + = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData); + /*Chk NULL and call recv callback*/ + if(Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb != NULL) + { + pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb; + Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL; + (*pUpperRecvCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, + RecvDataBufferStatus + ); + } + } + return; +} + +/**Send complete handler*/ +void phHal4Nfc_SendCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo) +{ + pphHal4Nfc_SendCallback_t pUpperSendCb = NULL; + pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = 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 + ); + } + else/*Callback For Initiator Send*/ + { + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb) + { + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0; + pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; + Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; + (*pUpperTrcvCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, + 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.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + SendStatus + );/*Notify disconnect failed to upper layer*/ + } + } + } + else + { + /*More info remaining in send buffer.continue with sending remaining + bytes*/ + if(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length + > PH_HAL4NFC_MAX_SEND_LEN) + { + /*Set more info*/ + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.nfc_info.more_info = TRUE; + /*copy to tx_buffer ,remaining bytes.NumberOfBytesSent is the + number of bytes already sent from current send buffer.*/ + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer + = (Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer + + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent); + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length + = PH_HAL4NFC_MAX_SEND_LEN; + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent + += PH_HAL4NFC_MAX_SEND_LEN; + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length + -= PH_HAL4NFC_MAX_SEND_LEN; + PHDBG_INFO("Hal4:Calling Hci_senddata() from sendcompletehandler1"); + SendStatus = phHciNfc_Send_Data ( + Hal4Ctxt->psHciHandle, + gpphHal4Nfc_Hwref, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) + ); + if(NFCSTATUS_PENDING == SendStatus) + { + Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE; + } + } + /*Remaining bytes is less than PH_HAL4NFC_MAX_SEND_LEN*/ + else if(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length > 0) + { + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.nfc_info.more_info = FALSE; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length + = (uint8_t)Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer + = (Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer + + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent); + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent = 0; + /*No of bytes remaining for next send*/ + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length = 0; + PHDBG_INFO("Hal4:Calling Hci_senddata() from sendcompletehandler2"); + SendStatus = phHciNfc_Send_Data ( + Hal4Ctxt->psHciHandle, + gpphHal4Nfc_Hwref, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) + ); + } + else/*No more Bytes left.Send complete*/ + { + 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 + ); + } + else + { + /**Start timer to keep track of transceive timeout*/ +#ifdef TRANSACTION_TIMER + phOsalNfc_Timer_Start( + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId, + PH_HAL4NFC_TRANSCEIVE_TIMEOUT, + phHal4Nfc_TrcvTimeoutHandler + ); +#endif /*TRANSACTION_TIMER*/ + } + } + } + return; +} + +/**Receive complete handler*/ +void phHal4Nfc_RecvCompleteHandler(phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt,void *pInfo) +{ + pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL; + pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = 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_MORE_INFORMATION; + } + } + 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) + { + /*Initiator case*/ + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb) + { + RecvStatus =(NFCSTATUS_RF_TIMEOUT == RecvStatus? + NFCSTATUS_DESELECTED:RecvStatus); + pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; + Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData + = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData); + (*pUpperTrcvCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, + RecvStatus + ); + } + /*P2P target*/ + else if(NULL != Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb) + { + pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb; + Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL; + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData + = &(Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData); + (*pUpperRecvCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + 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; +} + +/*Activation complete handler*/ +void phHal4Nfc_P2PActivateComplete( + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, + void *pInfo + ) +{ + phHal_sEventInfo_t *psEventInfo = (phHal_sEventInfo_t *)pInfo; + NFCSTATUS Status = NFCSTATUS_SUCCESS; + static phHal4Nfc_DiscoveryInfo_t sDiscoveryInfo; + /*Copy notification info to provide to upper layer*/ + phHal4Nfc_NotificationInfo_t uNotificationInfo = {&sDiscoveryInfo}; + Hal4Ctxt->sTgtConnectInfo.EmulationState = NFC_EVT_ACTIVATED; + /*if P2p notification is registered*/ + if( NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) + { + /*Allocate remote device Info for P2P target*/ + uNotificationInfo.psDiscoveryInfo->NumberOfDevices = 1; + if(NULL == Hal4Ctxt->rem_dev_list[0]) + { + Hal4Ctxt->rem_dev_list[0] + = (phHal_sRemoteDevInformation_t *) + phOsalNfc_GetMemory( + sizeof(phHal_sRemoteDevInformation_t) + ); + } + if(NULL == Hal4Ctxt->rem_dev_list[0]) + { + phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); + Status = PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_INSUFFICIENT_RESOURCES); + } + else + { + (void)memset((void *)Hal4Ctxt->rem_dev_list[0], + 0,sizeof(phHal_sRemoteDevInformation_t)); + /*Copy device info*/ + (void)memcpy(Hal4Ctxt->rem_dev_list[0], + psEventInfo->eventInfo.pRemoteDevInfo, + sizeof(phHal_sRemoteDevInformation_t) + ); + /*Allocate Trcv context info*/ + 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->RecvDataBufferStatus + = NFCSTATUS_PENDING; + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + = PH_OSALNFC_INVALID_TIMER_ID; + } + } + if(NULL == Hal4Ctxt->psTrcvCtxtInfo) + { + phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); + Status= PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_INSUFFICIENT_RESOURCES); + } + else + { + /*Update state*/ + Hal4Ctxt->Hal4CurrentState = eHal4StateEmulation; + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + uNotificationInfo.psDiscoveryInfo->ppRemoteDevInfo + = Hal4Ctxt->rem_dev_list; + /*set session Opened ,this will keep track of whether the session + is alive.will be reset if a Event DEACTIVATED is received*/ + Hal4Ctxt->rem_dev_list[0]->SessionOpened = TRUE; + (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)( + Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt, + NFC_DISCOVERY_NOTIFICATION, + uNotificationInfo, + Status + ); + } + } + } + return; +} + +/*Deactivation complete handler*/ +void phHal4Nfc_HandleP2PDeActivate( + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, + void *pInfo + ) +{ + pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL; + pphHal4Nfc_SendCallback_t pUpperSendCb = NULL; + phHal4Nfc_NotificationInfo_t uNotificationInfo; + uNotificationInfo.psEventInfo = (phHal_sEventInfo_t *)pInfo; + /*session is closed*/ + if(NULL != Hal4Ctxt->rem_dev_list[0]) + { + Hal4Ctxt->rem_dev_list[0]->SessionOpened = FALSE; + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0; + } + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL; + /*Update state*/ + Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady; + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + Hal4Ctxt->sTgtConnectInfo.EmulationState = NFC_EVT_DEACTIVATED; + /*If Trcv ctxt info is allocated ,free it here*/ + if(NULL != Hal4Ctxt->psTrcvCtxtInfo) + { + if(PH_OSALNFC_INVALID_TIMER_ID != + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId) + { + phOsalNfc_Timer_Stop(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId); + phOsalNfc_Timer_Delete(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId); + } + pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb; + pUpperSendCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PSendCb; + /*Free Hal4 resources used by Target*/ + if (NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) + { + phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo-> + sLowerRecvData.buffer); + } + if((NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) + && (NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData)) + { + phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData); + } + phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo); + Hal4Ctxt->psTrcvCtxtInfo = NULL; + } + /*if recv callback is pending*/ + if(NULL != pUpperRecvCb) + { + (*pUpperRecvCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + NULL, + NFCSTATUS_DESELECTED + ); + } + /*if send callback is pending*/ + else if(NULL != pUpperSendCb) + { + (*pUpperSendCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + NFCSTATUS_DESELECTED + ); + } + /*if pP2PNotification is registered*/ + else if(NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification) + { + (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)( + Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt, + NFC_EVENT_NOTIFICATION, + uNotificationInfo, + NFCSTATUS_DESELECTED + ); + } + else/*Call Default event handler*/ + { + if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler) + { + Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler( + Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt, + NFC_EVENT_NOTIFICATION, + uNotificationInfo, + NFCSTATUS_DESELECTED + ); + } + } +} |