summaryrefslogtreecommitdiffstats
path: root/src/phHal4Nfc_Reader.c
diff options
context:
space:
mode:
authorNick Pelly <npelly@google.com>2010-09-23 12:47:58 -0700
committerNick Pelly <npelly@google.com>2010-09-23 13:53:18 -0700
commit5d9927ba30ba449badb9f6df0fbeb4d6aedc6e2a (patch)
tree190f9251c6db03d3550ec7f30b51a2561c01d9cf /src/phHal4Nfc_Reader.c
parent4ff7c86a2c706b150078274455406f1b04966e1a (diff)
downloadexternal_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.c1282
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;
+}