| /* |
| * 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; |
| } |
| } |
| } |