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_Reader.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_Reader.c')
-rw-r--r-- | src/phHal4Nfc_Reader.c | 1282 |
1 files changed, 1282 insertions, 0 deletions
diff --git a/src/phHal4Nfc_Reader.c b/src/phHal4Nfc_Reader.c new file mode 100644 index 0000000..acb4060 --- /dev/null +++ b/src/phHal4Nfc_Reader.c @@ -0,0 +1,1282 @@ +/* + * 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_Reader.c +* \brief Hal4Nfc Reader source. +* +* Project: NFC-FRI 1.1 +* +* $Date: Mon May 31 11:43:43 2010 $ +* $Author: ing07385 $ +* $Revision: 1.120 $ +* $Aliases: NFC_FRI1.1_WK1023_R35_1 $ +* +*/ + +/* ---------------------------Include files ------------------------------------*/ +#include <phHal4Nfc.h> +#include <phHal4Nfc_Internal.h> +#include <phOsalNfc.h> +#include <phHciNfc.h> +#include <phOsalNfc_Timer.h> +#include <phNfcConfig.h> + + +/* ------------------------------- Macros ------------------------------------*/ +#define PH_HAL4NFC_CMD_LENGTH PHHAL_MAX_DATASIZE+12/**< Cmd length used + for Transceive*/ +#define PH_HAL4NFC_MAX_TRCV_LEN 4096 /**<Only a max of 1KB + can be sent at + a time*/ +#define PH_HAL4NFC_FLAG_0 0 + +#define PH_HAL4NFC_FLAG_1 1 + +#define PH_HAL4NFC_SEL_SECTOR1_BYTE0 0xC2 +#define PH_HAL4NFC_SEL_SECTOR1_BYTE1 0xFF + +#define PH_HAL4NFC_SEL_SECTOR2_BYTE0 0x02 +#define PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED 0x00 + + +/* --------------------Structures and enumerations --------------------------*/ + +static void phHal4Nfc_Iso_3A_Transceive( + phHal_sTransceiveInfo_t *psTransceiveInfo, + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt + ); + +static void phHal4Nfc_MifareTransceive( + phHal_sTransceiveInfo_t *psTransceiveInfo, + phHal_sRemoteDevInformation_t *psRemoteDevInfo, + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt + ); + +/*Allows to connect to a single, specific, already known Remote Device.*/ +NFCSTATUS phHal4Nfc_Connect( + phHal_sHwReference_t *psHwReference, + phHal_sRemoteDevInformation_t *psRemoteDevInfo, + pphHal4Nfc_ConnectCallback_t pNotifyConnectCb, + void *pContext + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_SUCCESS; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + uint8_t RemoteDevCount = 0; + int32_t MemCmpRet = 0; + /*NULL chks*/ + if(NULL == psHwReference + || NULL == pNotifyConnectCb + || NULL == psRemoteDevInfo) + { + 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 if ((psRemoteDevInfo == + ((phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context)-> + sTgtConnectInfo.psConnectedDevice) + &&((phHal_eNfcIP1_Target == psRemoteDevInfo->RemDevType) + ||(phHal_eJewel_PICC == psRemoteDevInfo->RemDevType))) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FEATURE_NOT_SUPPORTED); + } + else + { + /*Get Hal ctxt from hardware reference*/ + Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; + /*Register upper layer context*/ + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; + /*Register upper layer callback*/ + Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = pNotifyConnectCb; + /*Allow Connect only if no other remote device is connected*/ + if((eHal4StateTargetDiscovered == Hal4Ctxt->Hal4CurrentState) + && (NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)) + { + RemoteDevCount = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices; + while(0 != RemoteDevCount) + { + RemoteDevCount--; + /*Check if handle provided by upper layer matches with any + remote device in the list*/ + if(psRemoteDevInfo + == (Hal4Ctxt->rem_dev_list[RemoteDevCount])) + { + + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice + = Hal4Ctxt->rem_dev_list[RemoteDevCount]; + break; + } + }/*End of while*/ + + if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) + { + /*No matching device handle in list*/ + RetStatus = PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_INVALID_REMOTE_DEVICE); + } + else + { + MemCmpRet = phOsalNfc_MemCompare( + (void *)&(psRemoteDevInfo->RemoteDevInfo), + (void *)&(Hal4Ctxt->rem_dev_list[Hal4Ctxt + ->psADDCtxtInfo->nbr_of_devices - 1]->RemoteDevInfo), + sizeof(phHal_uRemoteDevInfo_t)); + + /*If device is already selected issue connect from here*/ + if(0 == MemCmpRet) + { + RetStatus = phHciNfc_Connect(Hal4Ctxt->psHciHandle, + (void *)psHwReference, + Hal4Ctxt->rem_dev_list[RemoteDevCount]); + if(NFCSTATUS_PENDING == RetStatus) + { + Hal4Ctxt->Hal4NextState = eHal4StateTargetConnected; + } + + } + else/*Select the matching device to connect to*/ + { + RetStatus = phHciNfc_Reactivate ( + Hal4Ctxt->psHciHandle, + (void *)psHwReference, + Hal4Ctxt->rem_dev_list[RemoteDevCount] + ); + Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate; + } + if(NFCSTATUS_PENDING != RetStatus) + { + /*Rollback state*/ + Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady; + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL; + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = NULL; + Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; + } + } + } + /*Issue Reconnect*/ + else if(psRemoteDevInfo == + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) + { + RetStatus = phHciNfc_Reactivate ( + Hal4Ctxt->psHciHandle, + (void *)psHwReference, + psRemoteDevInfo + ); + Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate; + } + else if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) + { + /*Wrong state to issue connect*/ + RetStatus = PHNFCSTVAL(CID_NFC_HAL, + NFCSTATUS_INVALID_REMOTE_DEVICE); + } + else/*No Target or already connected to device*/ + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED); + } + + } + return RetStatus; +} + +/*For Ordering Transceive Info for ISO_3A type tags*/ +static void phHal4Nfc_Iso_3A_Transceive( + phHal_sTransceiveInfo_t *psTransceiveInfo, + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt + ) +{ + uint16_t i; + uint16_t counter= 0; + /* Mifare UL, Keep MIFARE RAW command as it is */ + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type + = (uint8_t)psTransceiveInfo->cmd.MfCmd; + /* Set flags for Select Sector */ + if (psTransceiveInfo->sSendData.buffer[0] != phHal_eMifareWrite4) + { + if (Hal4Ctxt->SelectSectorFlag == PH_HAL4NFC_FLAG_0) + { + /* First Select Sector command */ + if ((psTransceiveInfo->sSendData.buffer[1] == PH_HAL4NFC_SEL_SECTOR1_BYTE0) && + (psTransceiveInfo->sSendData.buffer[2] == PH_HAL4NFC_SEL_SECTOR1_BYTE1)) + { + Hal4Ctxt->SelectSectorFlag++; + PHDBG_INFO("Inside 3ATrancv,first cmd, SelectSectorFlag is 1"); + for (i = 1; i < psTransceiveInfo->sSendData.length; i++) + { + psTransceiveInfo->sSendData.buffer[i - 1] = + psTransceiveInfo->sSendData.buffer[i]; + } + + psTransceiveInfo->sSendData.length--; + } + else + { + PHDBG_INFO("Inside 3ATrancv,first cmd,setting SelectSectorFlag 0"); + Hal4Ctxt->SelectSectorFlag = 0; + } + } + else if (Hal4Ctxt->SelectSectorFlag == PH_HAL4NFC_FLAG_1) + { + if ((psTransceiveInfo->sSendData.buffer[1] < PH_HAL4NFC_SEL_SECTOR2_BYTE0) && + (psTransceiveInfo->sSendData.buffer[2] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED) && + (psTransceiveInfo->sSendData.buffer[3] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED) && + (psTransceiveInfo->sSendData.buffer[4] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED)) + { + Hal4Ctxt->SelectSectorFlag++; + PHDBG_INFO("Inside 3ATrancv,2nd cmd, SelectSectorFlag set to 2"); + for (i = 1; i < psTransceiveInfo->sSendData.length; i++) + { + psTransceiveInfo->sSendData.buffer[i - 1] = + psTransceiveInfo->sSendData.buffer[i]; + } + + psTransceiveInfo->sSendData.length--; + } + else + { + PHDBG_INFO("Inside 3ATrancv,2nd cmd, SelectSectorFlag set to 0"); + Hal4Ctxt->SelectSectorFlag = 0; + } + } + else + { + Hal4Ctxt->SelectSectorFlag = 0; + } + } + else + { + PHDBG_INFO("Inside 3ATrancv,Mifarewrite4"); + /* Convert MIFARE RAW to MIFARE CMD */ + if (psTransceiveInfo->cmd.MfCmd == phHal_eMifareRaw) + { + psTransceiveInfo->cmd.MfCmd = + (phHal_eMifareCmdList_t)psTransceiveInfo->sSendData.buffer[0]; + + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type = + (uint8_t)psTransceiveInfo->cmd.MfCmd; + + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr = + psTransceiveInfo->addr = + psTransceiveInfo->sSendData.buffer[1]; + + for (counter = 2; counter < psTransceiveInfo->sSendData.length; + counter++) + { + psTransceiveInfo->sSendData.buffer[counter - 2] = + psTransceiveInfo->sSendData.buffer[counter]; + } + PHDBG_INFO("Hal4:Inside 3A_Trcv() ,minus length by 4"); + psTransceiveInfo->sSendData.length = + psTransceiveInfo->sSendData.length - 4; + } + else + { + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type + = (uint8_t)psTransceiveInfo->cmd.MfCmd; + } + } + return; +} + +/*For Ordering Transceive Info for Mifare tags*/ +static void phHal4Nfc_MifareTransceive( + phHal_sTransceiveInfo_t *psTransceiveInfo, + phHal_sRemoteDevInformation_t *psRemoteDevInfo, + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt + ) +{ + uint16_t counter; + if ((psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak == 0x00) +#ifndef DISABLE_MIFARE_UL_WRITE_WORKAROUND + &&(phHal_eMifareWrite4 != psTransceiveInfo->sSendData.buffer[0]) +#endif/*#ifndef DISABLE_MIFARE_UL_WRITE_WORKAROUND*/ + ) + + { + /* Mifare UL, Keep MIFARE RAW command as it is */ + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type + = (uint8_t)psTransceiveInfo->cmd.MfCmd; + + } + else + { + /* Convert MIFARE RAW to MIFARE CMD */ + if (psTransceiveInfo->cmd.MfCmd == phHal_eMifareRaw) + { + psTransceiveInfo->cmd.MfCmd = + (phHal_eMifareCmdList_t)psTransceiveInfo->sSendData.buffer[0]; + + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type = + (uint8_t)psTransceiveInfo->cmd.MfCmd; + + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr = + psTransceiveInfo->addr = + psTransceiveInfo->sSendData.buffer[1]; + + for (counter = 2; counter < psTransceiveInfo->sSendData.length; + counter++) + { + psTransceiveInfo->sSendData.buffer[counter - 2] = + psTransceiveInfo->sSendData.buffer[counter]; + } + PHDBG_INFO("Hal4:Inside MifareTrcv() ,minus length by 4"); + psTransceiveInfo->sSendData.length = + psTransceiveInfo->sSendData.length - 4; + + } + else + { + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type + = (uint8_t)psTransceiveInfo->cmd.MfCmd; + } + } + return; +} + +/* The phHal4Nfc_Transceive function allows the Initiator to send and receive + * data to and from the Remote Device selected by the caller.*/ +NFCSTATUS phHal4Nfc_Transceive( + phHal_sHwReference_t *psHwReference, + phHal_sTransceiveInfo_t *psTransceiveInfo, + phHal_sRemoteDevInformation_t *psRemoteDevInfo, + pphHal4Nfc_TransceiveCallback_t pTrcvCallback, + void *pContext + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_PENDING; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext; + + /*NULL checks*/ + if((NULL == psHwReference) + ||( NULL == pTrcvCallback ) + || (NULL == psRemoteDevInfo) + || (NULL == psTransceiveInfo) + || (NULL == psTransceiveInfo->sRecvData.buffer) + || (NULL == psTransceiveInfo->sSendData.buffer) + ) + { + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER); + } +#ifdef HAL_TRCV_LIMIT + else if(PH_HAL4NFC_MAX_TRCV_LEN < psTransceiveInfo->sSendData.length) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_ALLOWED); + } +#endif/*#ifdef HAL_TRCV_LIMIT*/ + /*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; + gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)psHwReference; + if((eHal4StateTargetConnected != Hal4Ctxt->Hal4CurrentState) + ||(eHal4StateInvalid != Hal4Ctxt->Hal4NextState)) + { + /*Hal4 state Busy*/ + RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_BUSY); + PHDBG_INFO("HAL4:Trcv Failed.Returning Busy"); + } + else if(psRemoteDevInfo != Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) + { + /*No such Target connected*/ + RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_REMOTE_DEVICE); + } + else + { + /*allocate Trcv context*/ + 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); + RetStatus= PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_INSUFFICIENT_RESOURCES); + } + else + { + /*Process transceive based on Remote device type*/ + switch(Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType) + { + case phHal_eISO14443_3A_PICC: + phHal4Nfc_Iso_3A_Transceive( + psTransceiveInfo, + Hal4Ctxt + ); + break; + case phHal_eMifare_PICC: + PHDBG_INFO("Mifare Cmd received"); + phHal4Nfc_MifareTransceive( + psTransceiveInfo, + psRemoteDevInfo, + Hal4Ctxt + ); + +#if 0 + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.tag_info.cmd_type + = (uint8_t)psTransceiveInfo->cmd.MfCmd; +#endif + break; + case phHal_eISO14443_A_PICC: + case phHal_eISO14443_B_PICC: + PHDBG_INFO("ISO14443 Cmd received"); + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.tag_info.cmd_type + = (uint8_t)psTransceiveInfo->cmd.Iso144434Cmd; + break; + case phHal_eISO15693_PICC: + PHDBG_INFO("ISO15693 Cmd received"); + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.tag_info.cmd_type + = (uint8_t)psTransceiveInfo->cmd.Iso15693Cmd; + break; + case phHal_eNfcIP1_Target: + { + PHDBG_INFO("NfcIP1 Transceive"); + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData + = &(psTransceiveInfo->sSendData); + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData = + &(psTransceiveInfo->sRecvData); + } + break; + case phHal_eFelica_PICC: + PHDBG_INFO("Felica Cmd received"); + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.tag_info.cmd_type + = (uint8_t)psTransceiveInfo->cmd.FelCmd; + break; + case phHal_eJewel_PICC: + PHDBG_INFO("Jewel Cmd received"); + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.tag_info.cmd_type + = (uint8_t)psTransceiveInfo->cmd.JewelCmd; + break; + case phHal_eISO14443_BPrime_PICC: + RetStatus = PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_FEATURE_NOT_SUPPORTED); + break; + default: + PHDBG_WARNING("Invalid Device type received"); + RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED); + break; + + } + } + } + /*If status is anything other than NFCSTATUS_PENDING ,an error has + already occured, so dont process any further and return*/ + if(RetStatus == NFCSTATUS_PENDING) + { + if(phHal_eNfcIP1_Target == + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType) + { + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; + /*Register upper layer callback*/ + Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = pTrcvCallback; + if(PH_HAL4NFC_MAX_SEND_LEN + >= psTransceiveInfo->sSendData.length) + { + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.nfc_info.more_info = FALSE; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length + = (uint8_t)psTransceiveInfo->sSendData.length; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer + = psTransceiveInfo->sSendData.buffer; + /*Number of bytes remaining for next send*/ + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length = 0; + } + else + { + Hal4Ctxt->psTrcvCtxtInfo-> + XchangeInfo.params.nfc_info.more_info = TRUE; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer + = Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length + = PH_HAL4NFC_MAX_SEND_LEN; +#if 0 + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer + += PH_HAL4NFC_MAX_SEND_LEN; +#else + Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent + += PH_HAL4NFC_MAX_SEND_LEN; +#endif + /*Number of bytes remaining for next send*/ + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length + -= PH_HAL4NFC_MAX_SEND_LEN; + } + Hal4Ctxt->Hal4NextState = eHal4StateTransaction; +#ifdef TRANSACTION_TIMER + /**Create a timer to keep track of transceive timeout*/ + if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + == PH_OSALNFC_INVALID_TIMER_ID) + { + PHDBG_INFO("HAL4: Transaction Timer Create for transceive"); + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + = phOsalNfc_Timer_Create(); + } + if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + == PH_OSALNFC_INVALID_TIMER_ID) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_INSUFFICIENT_RESOURCES); + } + else +#endif/*TRANSACTION_TIMER*/ + { + PHDBG_INFO("Hal4:Calling phHciNfc_Send_Data from Hal4_Transceive()"); + RetStatus = phHciNfc_Send_Data ( + Hal4Ctxt->psHciHandle, + psHwReference, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) + ); + if(NFCSTATUS_PENDING == RetStatus) + { + Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE; + } + } + } + else if(psTransceiveInfo->sSendData.length > PH_HAL4NFC_CMD_LENGTH) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_PARAMETER); + } + else if((psTransceiveInfo->sSendData.length == 0) + && (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length != 0)) + { + PHDBG_INFO("Hal4:Read remaining bytes"); + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData + = &(psTransceiveInfo->sRecvData); + /*Number of read bytes left is greater than bytes requested + by upper layer*/ + if(Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length + < Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length) + { + (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo + ->psUpperRecvData->buffer, + (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer + + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset) + ,Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length); + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length -= + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length; + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset + += Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length; + RetStatus = PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_MORE_INFORMATION); + } + else/*Number of read bytes left is smaller.Copy all bytes + and free Hal's buffer*/ + { + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length + = Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length; + (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo + ->psUpperRecvData + ->buffer, + (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer + + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset) + ,Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length); + phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo + ->sLowerRecvData.buffer); + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer = NULL; + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length = 0; + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset = 0; + RetStatus = NFCSTATUS_SUCCESS; + } + } + else/*No more bytes remaining in Hal.Read from device*/ + { + /*Register upper layer context*/ + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; + /*Register upper layer callback*/ + Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = pTrcvCallback; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr + = psTransceiveInfo->addr; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length + = (uint8_t)psTransceiveInfo->sSendData.length; + Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer + = psTransceiveInfo->sSendData.buffer; + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData + = &(psTransceiveInfo->sRecvData); +#ifdef TRANSACTION_TIMER + /**Create a timer to keep track of transceive timeout*/ + if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + == PH_OSALNFC_INVALID_TIMER_ID) + { + PHDBG_INFO("HAL4: Transaction Timer Create for transceive"); + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + = phOsalNfc_Timer_Create(); + } + if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId + == PH_OSALNFC_INVALID_TIMER_ID) + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL , + NFCSTATUS_INSUFFICIENT_RESOURCES); + } + else +#endif /*TRANSACTION_TIMER*/ + { + PHDBG_INFO("Calling phHciNfc_Exchange_Data"); + RetStatus = phHciNfc_Exchange_Data( + Hal4Ctxt->psHciHandle, + psHwReference, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo) + ); + + if(NFCSTATUS_PENDING == RetStatus) + { + Hal4Ctxt->Hal4NextState = eHal4StateTransaction; +#ifdef TRANSACTION_TIMER + /**Start timer to keep track of transceive timeout*/ + phOsalNfc_Timer_Start( + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId, + PH_HAL4NFC_TRANSCEIVE_TIMEOUT, + phHal4Nfc_TrcvTimeoutHandler + ); +#endif/*#ifdef TRANSACTION_TIMER*/ + } + else + { + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + } + } + } + } + } + return RetStatus; +} + +#ifdef TRANSACTION_TIMER +/**Handle transceive timeout*/ +void phHal4Nfc_TrcvTimeoutHandler(uint32_t TrcvTimerId) +{ + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = gpphHal4Nfc_Hwref->hal_context; + pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL; + pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL; + phOsalNfc_Timer_Stop(TrcvTimerId); + phOsalNfc_Timer_Delete(TrcvTimerId); + Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId = PH_OSALNFC_INVALID_TIMER_ID; + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + /*For a P2P target*/ + if(Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb != NULL) + { + pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb; + Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL; + (*pUpperRecvCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + NULL, + NFCSTATUS_RF_TIMEOUT + ); + } + else + { + /*For a P2P Initiator and tags*/ + if(Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb != NULL) + { + pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; + Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; + (*pUpperTrcvCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + NULL, + NFCSTATUS_RF_TIMEOUT + ); + } + } +} +#endif /*TRANSACTION_TIMER*/ + + +/**The function allows to disconnect from a specific Remote Device.*/ +NFCSTATUS phHal4Nfc_Disconnect( + phHal_sHwReference_t *psHwReference, + phHal_sRemoteDevInformation_t *psRemoteDevInfo, + phHal_eReleaseType_t ReleaseType, + pphHal4Nfc_DiscntCallback_t pDscntCallback, + void *pContext + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_PENDING; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + PHDBG_INFO("Hal4:Inside Hal4 disconnect"); + /*NULL checks*/ + if(NULL == psHwReference || NULL == pDscntCallback + || NULL == psRemoteDevInfo) + { + 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 if(((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->Hal4CurrentState + != eHal4StateTargetConnected) + { + PHDBG_INFO("Hal4:Current sate is not connect.Release returning failed"); + RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_FAILED); + } + else + { + Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; + if((Hal4Ctxt->sTgtConnectInfo.psConnectedDevice == NULL) + || (psRemoteDevInfo != Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)) + { + PHDBG_INFO("Hal4:disconnect returning INVALID_REMOTE_DEVICE"); + RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_REMOTE_DEVICE); + } + else + { + /*Register upper layer context*/ + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext; + /*Register upper layer callback*/ + Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb = pDscntCallback; + /*Register Release Type*/ + Hal4Ctxt->sTgtConnectInfo.ReleaseType = ReleaseType; + if((eHal4StateTransaction == Hal4Ctxt->Hal4NextState) + &&((phHal_eNfcIP1_Target != psRemoteDevInfo->RemDevType) + ||((NFC_DISCOVERY_CONTINUE != ReleaseType) + &&(NFC_DISCOVERY_RESTART != ReleaseType)))) + { + Hal4Ctxt->sTgtConnectInfo.ReleaseType + = NFC_INVALID_RELEASE_TYPE; + PHDBG_INFO("Hal4:disconnect returning NFCSTATUS_NOT_ALLOWED"); + RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_NOT_ALLOWED); + } + else if((eHal4StateTransaction == Hal4Ctxt->Hal4NextState) + &&(NULL != Hal4Ctxt->psTrcvCtxtInfo) + &&(TRUE == Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress)) + { + /*store the hardware reference for executing disconnect later*/ + gpphHal4Nfc_Hwref = psHwReference; + PHDBG_INFO("Hal4:disconnect deferred"); + } + else/*execute disconnect*/ + { + RetStatus = phHal4Nfc_Disconnect_Execute(psHwReference); + } + } + } + return RetStatus; +} + +/**Execute Hal4 Disconnect*/ +NFCSTATUS phHal4Nfc_Disconnect_Execute( + phHal_sHwReference_t *psHwReference + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_PENDING; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = + (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; + phHal_eSmartMX_Mode_t SmxMode = eSmartMx_Default; + PHDBG_INFO("Hal4:Inside Hal4 disconnect execute"); + switch(Hal4Ctxt->sTgtConnectInfo.ReleaseType) + { + /*Switch mode to Default*/ + case NFC_SMARTMX_RELEASE: + SmxMode = eSmartMx_Default; + RetStatus = phHciNfc_Switch_SmxMode ( + Hal4Ctxt->psHciHandle, + psHwReference, + SmxMode, + &(Hal4Ctxt->psADDCtxtInfo->sADDCfg) + ); + break; + /*Disconnect and continue polling wheel*/ + case NFC_DISCOVERY_CONTINUE: + { + RetStatus = phHciNfc_Disconnect ( + Hal4Ctxt->psHciHandle, + psHwReference, + FALSE + ); + if(NFCSTATUS_PENDING != RetStatus) + { + PHDBG_INFO("Hal4:Hci disconnect failed.Restarting discovery"); + RetStatus = phHciNfc_Restart_Discovery ( + (void *)Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref, + FALSE + ); + if(NFCSTATUS_PENDING != RetStatus) + { + PHDBG_INFO("Hal4:Hci Restart discovery also failed"); + } + } + break; + } + /*Disconnect and restart polling wheel*/ + case NFC_DISCOVERY_RESTART: + RetStatus = phHciNfc_Disconnect ( + Hal4Ctxt->psHciHandle, + psHwReference, + TRUE + ); + break; + default: + RetStatus = PHNFCSTVAL(CID_NFC_HAL, + NFCSTATUS_FEATURE_NOT_SUPPORTED); + break; + } + Hal4Ctxt->sTgtConnectInfo.ReleaseType = NFC_INVALID_RELEASE_TYPE; + /*Update or rollback next state*/ + Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus? + eHal4StateOpenAndReady:Hal4Ctxt->Hal4NextState); + return RetStatus; +} + +/*The function allows to check for presence in vicinity of connected remote + device.*/ +NFCSTATUS phHal4Nfc_PresenceCheck( + phHal_sHwReference_t *psHwReference, + pphHal4Nfc_GenCallback_t pPresenceChkCb, + void *context + ) +{ + NFCSTATUS RetStatus = NFCSTATUS_FAILED; + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL; + /*NULL checks*/ + if((NULL == pPresenceChkCb) || (NULL == psHwReference)) + { + 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)) + { + PHDBG_INFO("HAL4:Context not Open"); + RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_NOT_INITIALISED); + } + /*check connected state and session alive*/ + else if((((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->Hal4CurrentState + < eHal4StateTargetConnected)|| + (NULL == ((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->sTgtConnectInfo.psConnectedDevice)|| + (FALSE == ((phHal4Nfc_Hal4Ctxt_t *) + psHwReference->hal_context)->sTgtConnectInfo. + psConnectedDevice->SessionOpened)) + { + PHDBG_INFO("HAL4:No target connected"); + RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_RELEASED); + } + else + { + Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context; + /*allow only one Presence chk command at any point in time*/ + if (eHal4StatePresenceCheck != Hal4Ctxt->Hal4NextState) + { + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = context; + Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb = pPresenceChkCb; + RetStatus = phHciNfc_Presence_Check(Hal4Ctxt->psHciHandle, + psHwReference + ); + Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus? + eHal4StatePresenceCheck:Hal4Ctxt->Hal4NextState); + } + else/*Ongoing presence chk*/ + { + RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_BUSY); + } + } + return RetStatus; +} + +void phHal4Nfc_PresenceChkComplete( + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, + void *pInfo + ) +{ + NFCSTATUS RetStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + /*Notify to upper layer*/ + if(NULL != Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb) + { + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened + =(uint8_t)(NFCSTATUS_SUCCESS == RetStatus?TRUE:FALSE); + (*Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + RetStatus + ); + } + return; +} + +/*Callback for reactivate target and to select appropriate target incase + of multiple targets*/ +void phHal4Nfc_ReactivationComplete( + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, + void *pInfo + ) +{ + NFCSTATUS Status = ((phNfc_sCompletionInfo_t *)pInfo)->status; + /*A NFCSTATUS_SUCCESS status returned here means that the correct device + to connect to has now been selected.So issue connect from here to complete + activation*/ + if(NFCSTATUS_SUCCESS == Status) + { + Hal4Ctxt->Hal4NextState = eHal4StateTargetConnected; + Status = phHciNfc_Connect( + Hal4Ctxt->psHciHandle, + gpphHal4Nfc_Hwref, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice + ); + Status = (NFCSTATUS_PENDING == Status)? + NFCSTATUS_PENDING:NFCSTATUS_FAILED; + } + else/*Device unavailable, return error in connect Callback*/ + { + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + if(NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb) + { + (*Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + Status + ); + } + } + return; +} + + +void phHal4Nfc_ConnectComplete( + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, + void *pInfo + ) +{ + NFCSTATUS ConnectStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; + pphHal4Nfc_ConnectCallback_t pUpperConnectCb + = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb; + /*Flag to decide whether or not upper layer callback has to be called*/ + uint8_t CallConnectCb = TRUE; + /*Remote device Connect successful*/ + if((NFCSTATUS_SUCCESS == ConnectStatus) + ||(eHal4StateTargetConnected == Hal4Ctxt->Hal4CurrentState)) + { + PHDBG_INFO("Hal4:Connect status Success"); + Hal4Ctxt->Hal4CurrentState = eHal4StateTargetConnected; + Hal4Ctxt->Hal4NextState = eHal4StateInvalid; + /* Open the Session */ + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened = + (uint8_t)(NFCSTATUS_SUCCESS == ConnectStatus?TRUE:FALSE); + Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; + + } + else/*Remote device Connect failed*/ + { + Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady; + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened = FALSE; + /*For a NfcIp1 target and case where it is not a internal reconnect + from Hal4 ,notify callback to upper layer*/ + if((phHal_eNfcIP1_Target + == Hal4Ctxt->rem_dev_list[0]->RemDevType) + || (NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)) + { + Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; + } + else/*do not notify callback*/ + { + CallConnectCb = FALSE; + } + /*Free the remote device list*/ + do + { + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices--; + if(NULL != Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]) + { + phOsalNfc_FreeMemory((void *) + (Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])); + Hal4Ctxt->rem_dev_list[ + Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL; + } + }while(0 < Hal4Ctxt->psADDCtxtInfo->nbr_of_devices); + + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL; + } + if(TRUE == CallConnectCb) + { + PHDBG_INFO("Hal4:Calling Connect callback"); + /*Notify to the upper layer*/ + (*pUpperConnectCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + ConnectStatus + ); + } + else + { + PHDBG_INFO("Hal4:Connect failed ,Restarting discovery"); + /*Restart the Discovery wheel*/ + ConnectStatus = phHciNfc_Restart_Discovery ( + (void *)Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref, + FALSE + ); + Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == ConnectStatus? + eHal4StateConfiguring:eHal4StateInvalid); + } + return; +} + + + + +void phHal4Nfc_DisconnectComplete( + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, + void *pInfo + ) +{ + NFCSTATUS ConnectStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; + phHal_sRemoteDevInformation_t *psConnectedDevice = NULL; + pphHal4Nfc_DiscntCallback_t pUpperDisconnectCb = NULL; + pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL; + PHDBG_INFO("Hal4:Inside Hal4 disconnect callback"); + if(NULL == Hal4Ctxt) + { + phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1); + } + else if(NFCSTATUS_SUCCESS != ConnectStatus)/*Restart the Discovery wheel*/ + { + ConnectStatus = phHciNfc_Restart_Discovery ( + (void *)Hal4Ctxt->psHciHandle, + (void *)gpphHal4Nfc_Hwref, + FALSE + ); + Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == ConnectStatus? + eHal4StateConfiguring:eHal4StateInvalid); + } + else/*Remote device Disconnect successful*/ + { + psConnectedDevice = Hal4Ctxt->sTgtConnectInfo.psConnectedDevice; + pUpperDisconnectCb = Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb; + /*Deallocate psTrcvCtxtInfo*/ + if(NULL != Hal4Ctxt->psTrcvCtxtInfo) + { + if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice) + { + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData) + { + phOsalNfc_FreeMemory( + Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData); + } + } + else + { + if(phHal_eNfcIP1_Target + == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType) + { + pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0; + pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb; + Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL; + } + } + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) + { + phOsalNfc_FreeMemory( + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer); + } + + phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo); + Hal4Ctxt->psTrcvCtxtInfo = NULL; + } + /*Free the remote device list*/ + do + { + if(NULL != Hal4Ctxt->rem_dev_list[Hal4Ctxt-> + psADDCtxtInfo->nbr_of_devices-1]) + { + phOsalNfc_FreeMemory((void *) + (Hal4Ctxt->rem_dev_list[Hal4Ctxt-> + psADDCtxtInfo->nbr_of_devices-1])); + Hal4Ctxt->rem_dev_list[Hal4Ctxt-> + psADDCtxtInfo->nbr_of_devices-1] = NULL; + } + }while(--(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices)); + + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL; + /*Disconnect successful.Go to Ready state*/ + Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState; + Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb = NULL; + Hal4Ctxt->Hal4NextState = ( + eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState? + eHal4StateInvalid:Hal4Ctxt->Hal4NextState); + /*Issue any pending Trcv callback*/ + if(NULL != pUpperTrcvCb) + { + (*pUpperTrcvCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + psConnectedDevice, + NULL, + NFCSTATUS_FAILED + ); + } + /*Notify upper layer*/ + if(NULL != pUpperDisconnectCb) + { + PHDBG_INFO("Hal4:Calling Upper layer disconnect callback"); + (*pUpperDisconnectCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + psConnectedDevice, + ConnectStatus + ); + } + } + return; +} + + +/*Transceive complete handler function*/ +void phHal4Nfc_TransceiveComplete( + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, + void *pInfo + ) +{ + /*Copy status code*/ + NFCSTATUS TrcvStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status; + /*Update next state*/ + Hal4Ctxt->Hal4NextState = (eHal4StateTransaction + == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState); + /*Reset SelectSectorFlag for Mifare*/ + if (Hal4Ctxt->SelectSectorFlag == 2) + { + TrcvStatus = NFCSTATUS_SUCCESS; + PHDBG_INFO("Inside Hal4TrcvComplete SelectSectorFlag is 2"); + Hal4Ctxt->SelectSectorFlag = 0; + } + + if(NULL == Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData) + { + /*if recv buffer is Null*/ + phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1); + TrcvStatus = NFCSTATUS_FAILED; + } + else if(TrcvStatus == NFCSTATUS_SUCCESS) + { + /*Check if recvdata buffer given by upper layer is big enough to + receive all response bytes.If it is not big enough ,copy number + of bytes requested by upper layer to the buffer.Remaining + bytes are retained in Hal4 and upper layer has to issue another + transceive call to read the same.*/ + if(((phNfc_sTransactionInfo_t *)pInfo) + ->length > Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length ) + { + TrcvStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_MORE_INFORMATION); + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length + = ((phNfc_sTransactionInfo_t *)pInfo)->length + - Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length; + + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer + = (uint8_t *)phOsalNfc_GetMemory( + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length + ); + if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer) + { + (void)memcpy( + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer, + (((phNfc_sTransactionInfo_t *)pInfo)->buffer + + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData + ->length) + ,Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length + ); + } + else + { + TrcvStatus = PHNFCSTVAL(CID_NFC_HAL, + NFCSTATUS_INSUFFICIENT_RESOURCES); + phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0); + } + + } + else/*Buffer provided by upper layer is big enough to hold all read + bytes*/ + { + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length + = ((phNfc_sTransactionInfo_t *)pInfo)->length; + Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length = 0; + } + (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->buffer, + ((phNfc_sTransactionInfo_t *)pInfo)->buffer, + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length + ); + + } + else/*Error scenario.Set received bytes length to zero*/ + { + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0; + } + (void)memset((void *)&(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params), + 0, + sizeof(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params) + ); + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset = 0; + /*Issue transceive callback*/ + (*Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData, + TrcvStatus + ); + return; +} |