/*
* 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 */
if (OvrHal->TranceiveInfo.sRecvData.buffer != pRecvdata->buffer)
{
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;
}
}
}