/* * 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 phFriNfc_OvrHal.c * \brief Overlapped HAL * * Project: NFC-FRI * Creator: Gerald Kersch * * $Date: Wed May 5 10:47:27 2010 $ * Changed by: $Author: ing02260 $ * $Revision: 1.37 $ * $Aliases: NFC_FRI1.1_WK1017_R34_3,NFC_FRI1.1_WK1023_R35_1 $ * */ #include <phFriNfc_OvrHal.h> #include <phOsalNfc.h> #include <phFriNfc_NdefMap.h> #include <phFriNfc_SmtCrdFmt.h> #ifdef PHFRINFC_OVRHAL_MOCKUP /* */ //#include <phLibNfc_Gen.h> #endif /* PHFRINFC_OVRHAL_MOCKUP */ /* * */ #define MAX_MIF_PACKET_LEN 0x0FU #define MIFARE_PLUS_UID_INDEX_TO_COPY 0x03U #define MIFARE_PLUS_UID_LENGTH 0x07U #define MIFARE_CLASSIC_UID_LENGTH 0x04U #define MIFARE_UID_LEN_TO_COPY 0x04U static void phFriNfc_OvrHal_CB_Send(void *context, NFCSTATUS status); static void phFriNfc_OvrHal_CB_Receive(void *context, phNfc_sData_t *pDataInfo, NFCSTATUS status); static void phFriNfc_OvrHal_CB_Transceive(void *context, phHal_sRemoteDevInformation_t *RemoteDevHandle, phNfc_sData_t *pRecvdata, NFCSTATUS status ); static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context, phHal_sRemoteDevInformation_t *RemoteDevHandle, NFCSTATUS status ); static void phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal, phFriNfc_CplRt_t *CompletionInfo, uint8_t Operation); NFCSTATUS phFriNfc_OvrHal_Transceive(phFriNfc_OvrHal_t *OvrHal, phFriNfc_CplRt_t *CompletionInfo, phHal_sRemoteDevInformation_t *RemoteDevInfo, phHal_uCmdList_t Cmd, phHal_sDepAdditionalInfo_t *DepAdditionalInfo, uint8_t *SendBuf, uint16_t SendLength, uint8_t *RecvBuf, uint16_t *RecvLength) { NFCSTATUS status = NFCSTATUS_PENDING; uint8_t i = 0; uint32_t length = SendLength; /* To remove "warning (VS C4100) : unreferenced formal parameter" */ PHNFC_UNUSED_VARIABLE(DepAdditionalInfo); /* Check the Input Parameters */ if ((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo) || (NULL == (void*)SendBuf) || (NULL == RecvBuf) || (NULL == RecvLength) || ((phHal_eJewel_PICC != RemoteDevInfo->RemDevType) && (0 == SendLength))) { status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL, NFCSTATUS_INVALID_PARAMETER); } else { /* 16 is the maximum data, that can be sent to the mifare standard */ static uint8_t mif_send_buf[MAX_MIF_PACKET_LEN] = {0}; /* Populate the Transfer info structure */ OvrHal->TranceiveInfo.cmd = Cmd; /* Populate the Send Buffer Info */ if((phHal_eMifare_PICC == RemoteDevInfo->RemDevType) || (phHal_eISO14443_3A_PICC == RemoteDevInfo->RemDevType)) { OvrHal->TranceiveInfo.addr = SendBuf[i++]; length = (SendLength - i); if ((phHal_eMifareAuthentA == Cmd.MfCmd) || (phHal_eMifareAuthentB == Cmd.MfCmd)) { uint8_t uid_index = 0; /* Authentication requires UID in the send buffer */ uint8_t uid_len = RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength; OvrHal->TranceiveInfo.sSendData.buffer = mif_send_buf; switch (uid_len) { case MIFARE_PLUS_UID_LENGTH: { uid_index = MIFARE_PLUS_UID_INDEX_TO_COPY; uid_len = MIFARE_UID_LEN_TO_COPY; break; } case MIFARE_CLASSIC_UID_LENGTH: { uid_index = 0; break; } default: { status = PHNFCSTVAL (CID_FRI_NFC_OVR_HAL, NFCSTATUS_READ_FAILED); break; } } if (NFCSTATUS_PENDING == status) { /* copy uid to the send buffer for the authentication */ (void)memcpy ((void *)mif_send_buf, (void *)&RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[uid_index], uid_len); (void)memcpy((mif_send_buf + uid_len), &(SendBuf[i]), length); length += uid_len; } } else { OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++]; } OvrHal->TranceiveInfo.sSendData.length = length; } else { OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++]; OvrHal->TranceiveInfo.sSendData.length = length; } if (NFCSTATUS_PENDING == status) { /* Populate the Receive buffer */ OvrHal->TranceiveInfo.sRecvData.buffer = RecvBuf; OvrHal->TranceiveInfo.sRecvData.length = *RecvLength; OvrHal->pndef_recv_length = RecvLength; phFriNfc_OvrHal_SetComplInfo(OvrHal,CompletionInfo, PH_FRINFC_OVRHAL_TRX); /* Call the HAL 4.0 Transceive Function */ status = phHal4Nfc_Transceive (OvrHal->psHwReference, &OvrHal->TranceiveInfo, RemoteDevInfo, phFriNfc_OvrHal_CB_Transceive, (void *)OvrHal); } } return status; } NFCSTATUS phFriNfc_OvrHal_Receive(phFriNfc_OvrHal_t *OvrHal, phFriNfc_CplRt_t *CompletionInfo, phHal_sRemoteDevInformation_t *RemoteDevInfo, uint8_t *RecvBuf, uint16_t *RecvLength) { NFCSTATUS status = NFCSTATUS_PENDING; /* Check the Input Parameters */ if( (NULL==OvrHal) || (NULL==CompletionInfo) || (NULL==RemoteDevInfo) || (NULL==RecvBuf) || (NULL==RecvLength) ) { status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER); } else { /* Get the remote dev type */ OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType; /* Save the receive buffer for use in callback */ OvrHal->sReceiveData.buffer = RecvBuf; OvrHal->sReceiveData.length = *RecvLength; OvrHal->pndef_recv_length = RecvLength; /* Set the callback */ phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_RCV); /* Call the HAL 4.0 Receive Function */ status = phHal4Nfc_Receive( OvrHal->psHwReference, &OvrHal->TransactInfo, phFriNfc_OvrHal_CB_Receive, (void *)OvrHal); } return status; } NFCSTATUS phFriNfc_OvrHal_Send(phFriNfc_OvrHal_t *OvrHal, phFriNfc_CplRt_t *CompletionInfo, phHal_sRemoteDevInformation_t *RemoteDevInfo, uint8_t *SendBuf, uint16_t SendLength) { NFCSTATUS status = NFCSTATUS_PENDING; /* Check the Input Parameters */ if( (NULL==OvrHal) || (NULL==CompletionInfo) || (NULL==RemoteDevInfo) || (NULL==SendBuf) ) { status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER); } else { /* Get the remote dev type */ OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType; /* Save the receive buffer for use in callback */ OvrHal->sSendData.buffer = SendBuf; OvrHal->sSendData.length = SendLength; /* Set the callback */ phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_SND); /* Call the HAL 4.0 Receive Function */ status = phHal4Nfc_Send( OvrHal->psHwReference, &OvrHal->TransactInfo, OvrHal->sSendData, phFriNfc_OvrHal_CB_Send, (void *)OvrHal); } return status; } #ifndef PH_FRINFC_MAP_MIFARESTD_DISABLED NFCSTATUS phFriNfc_OvrHal_Reconnect(phFriNfc_OvrHal_t *OvrHal, phFriNfc_CplRt_t *CompletionInfo, phHal_sRemoteDevInformation_t *RemoteDevInfo) { NFCSTATUS status = NFCSTATUS_PENDING; /* Check the Input Parameters */ if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo)) { status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER); } else { phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_DIS); status = phHal4Nfc_Connect( OvrHal->psHwReference, RemoteDevInfo, phFriNfc_OvrHal_CB_ConnectDisconnect, (void *)OvrHal); } return status; } NFCSTATUS phFriNfc_OvrHal_Connect(phFriNfc_OvrHal_t *OvrHal, phFriNfc_CplRt_t *CompletionInfo, phHal_sRemoteDevInformation_t *RemoteDevInfo, phHal_sDevInputParam_t *DevInputParam) { NFCSTATUS status = NFCSTATUS_PENDING; /* Check the Input Parameters */ if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo) || (NULL == DevInputParam)) { status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER); } else { phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_CON); status = phHal4Nfc_Connect( OvrHal->psHwReference, RemoteDevInfo, phFriNfc_OvrHal_CB_ConnectDisconnect, (void *)OvrHal ); } return status; } #endif static void phFriNfc_OvrHal_CB_Transceive(void *context, phHal_sRemoteDevInformation_t *RemoteDevHandle, phNfc_sData_t *pRecvdata, NFCSTATUS status ) { phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context; if (NULL != OvrHal) { if(NULL != pRecvdata && OvrHal->TranceiveInfo.sRecvData.buffer != NULL && pRecvdata->buffer != NULL) { /* Work-around for the NFCIP Tranceive API */ memcpy(OvrHal->TranceiveInfo.sRecvData.buffer, pRecvdata->buffer, pRecvdata->length); if (OvrHal->pndef_recv_length != NULL) { *OvrHal->pndef_recv_length = (uint16_t) pRecvdata->length; } } if(NULL != RemoteDevHandle) { /* Fix for Warning 4100 */ RemoteDevHandle=RemoteDevHandle; } if (NULL != OvrHal->TemporaryCompletionInfo.CompletionRoutine) { OvrHal->TemporaryCompletionInfo.CompletionRoutine( OvrHal->TemporaryCompletionInfo.Context, status); } } } static void phFriNfc_OvrHal_CB_Send(void *context, NFCSTATUS status) { phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context; if (NULL != OvrHal) { if (NULL != OvrHal->TemporarySndCompletionInfo.CompletionRoutine) { OvrHal->TemporarySndCompletionInfo.CompletionRoutine( OvrHal->TemporarySndCompletionInfo.Context, status); } } } static void phFriNfc_OvrHal_CB_Receive(void *context, phNfc_sData_t *pDataInfo, NFCSTATUS status) { phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context; if (NULL != OvrHal) { /* Copy the received buffer */ if(NULL != pDataInfo && OvrHal->sReceiveData.buffer != NULL && pDataInfo->buffer != NULL) { memcpy(OvrHal->sReceiveData.buffer, pDataInfo->buffer, pDataInfo->length); *OvrHal->pndef_recv_length = (uint16_t) pDataInfo->length; } if (NULL != OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine) { OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine( OvrHal->TemporaryRcvCompletionInfo.Context, status); } } } static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context, phHal_sRemoteDevInformation_t *RemoteDevHandle, NFCSTATUS status ) { phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context; if (NULL != OvrHal) { if (RemoteDevHandle != NULL) { /* Fix for Warning 4100 */ RemoteDevHandle = RemoteDevHandle; } else { status = NFCSTATUS_FAILED; } OvrHal->TemporaryCompletionInfo.CompletionRoutine( OvrHal->TemporaryCompletionInfo.Context, status); } } static void phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal, phFriNfc_CplRt_t *CompletionInfo, uint8_t Operation) { OvrHal->Operation = Operation; switch(Operation) { case PH_FRINFC_OVRHAL_RCV: { OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine; OvrHal->TemporaryRcvCompletionInfo.Context = CompletionInfo->Context; break; } case PH_FRINFC_OVRHAL_SND: { OvrHal->TemporarySndCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine; OvrHal->TemporarySndCompletionInfo.Context = CompletionInfo->Context; break; } default: { OvrHal->TemporaryCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine; OvrHal->TemporaryCompletionInfo.Context = CompletionInfo->Context; break; } } }