| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * 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. |
| */ |
| #define LOG_TAG "pn54x" |
| |
| #include <log/log.h> |
| |
| #include <nfc_api.h> |
| #include <rw_api.h> |
| #include <phNfcCompId.h> |
| #include <phNxpLog.h> |
| #include <phNxpExtns_MifareStd.h> |
| |
| phNxpExtns_Context_t gphNxpExtns_Context; |
| phNciNfc_TransceiveInfo_t tNciTranscvInfo; |
| phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = NULL; |
| phFriNfc_NdefMap_t *NdefMap = NULL; |
| phLibNfc_NdefInfo_t NdefInfo; |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_t SharedDataMutex = PTHREAD_MUTEX_INITIALIZER; |
| #endif |
| uint8_t current_key[6]={0}; |
| phNci_mfc_auth_cmd_t gAuthCmdBuf; |
| STATIC NFCSTATUS phNciNfc_SendMfReq(phNciNfc_TransceiveInfo_t tTranscvInfo, |
| uint8_t *buff, uint16_t *buffSz); |
| STATIC NFCSTATUS phLibNfc_SendRawCmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf); |
| STATIC NFCSTATUS phLibNfc_SendWrt16Cmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf); |
| STATIC NFCSTATUS phLibNfc_SendAuthCmd(phNfc_sTransceiveInfo_t *pTransceiveInfo, |
| phNciNfc_TransceiveInfo_t *tNciTranscvInfo) __attribute__((unused)); |
| STATIC NFCSTATUS phLibNfc_MapCmds(phNciNfc_RFDevType_t RemDevType, |
| phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf); |
| STATIC NFCSTATUS phLibNfc_MifareMap(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf); |
| STATIC NFCSTATUS phLibNfc_ChkAuthCmdMFC(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| uint8_t *bKey); |
| STATIC NFCSTATUS phLibNfc_GetKeyNumberMFC(uint8_t *buffer,uint8_t *bKey); |
| STATIC void phLibNfc_CalSectorAddress(uint8_t *Sector_Address); |
| STATIC NFCSTATUS phNciNfc_MfCreateAuthCmdHdr(phNciNfc_TransceiveInfo_t tTranscvInfo, |
| uint8_t bBlockAddr, |
| uint8_t *buff, |
| uint16_t *buffSz); |
| STATIC NFCSTATUS phNciNfc_MfCreateXchgDataHdr(phNciNfc_TransceiveInfo_t tTranscvInfo, |
| uint8_t *buff, uint16_t *buffSz); |
| STATIC NFCSTATUS phLibNfc_SendWrt16CmdPayload(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf); |
| STATIC NFCSTATUS phNciNfc_RecvMfResp(phNciNfc_Buff_t* RspBuffInfo, NFCSTATUS wStatus); |
| STATIC NFCSTATUS nativeNfcExtns_doTransceive(uint8_t *buff, uint16_t buffSz); |
| STATIC NFCSTATUS phFriNfc_NdefSmtCrd_Reset__(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, |
| uint8_t *SendRecvBuffer, |
| uint16_t *SendRecvBuffLen); |
| STATIC NFCSTATUS phFriNfc_ValidateParams(uint8_t *PacketData, |
| uint32_t *PacketDataLength, |
| uint8_t Offset, |
| phFriNfc_NdefMap_t *pNdefMap, |
| uint8_t bNdefReq); |
| STATIC void Mfc_FormatNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status); |
| STATIC void Mfc_WriteNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status); |
| STATIC void Mfc_ReadNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status); |
| STATIC void Mfc_CheckNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status); |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpExtns_MfcModuleDeInit |
| ** |
| ** Description It Deinitializes the Mifare module. |
| ** |
| ** Frees all the memory occupied by Mifare module |
| ** |
| ** Returns: |
| ** NFCSTATUS_SUCCESS - if successfully deinitialize |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS phNxpExtns_MfcModuleDeInit(void) |
| { |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| |
| if(NdefMap != NULL) |
| { |
| if( NdefMap->psRemoteDevInfo != NULL ) |
| { |
| free(NdefMap->psRemoteDevInfo); |
| NdefMap->psRemoteDevInfo = NULL; |
| } |
| if( NdefMap->SendRecvBuf != NULL ) |
| { |
| free(NdefMap->SendRecvBuf); |
| NdefMap->SendRecvBuf = NULL; |
| } |
| if( NdefMap->SendRecvLength != NULL ) |
| { |
| free(NdefMap->SendRecvLength); |
| NdefMap->SendRecvLength = NULL; |
| } |
| if( NdefMap->DataCount != NULL ) |
| { |
| free(NdefMap->DataCount); |
| NdefMap->DataCount = NULL; |
| } |
| if( NdefMap->pTransceiveInfo != NULL ) |
| { |
| if( NdefMap->pTransceiveInfo->sSendData.buffer != NULL ) |
| { |
| free(NdefMap->pTransceiveInfo->sSendData.buffer); |
| NdefMap->pTransceiveInfo->sSendData.buffer = NULL; |
| } |
| if( NdefMap->pTransceiveInfo->sRecvData.buffer != NULL ) |
| { |
| free(NdefMap->pTransceiveInfo->sRecvData.buffer); |
| NdefMap->pTransceiveInfo->sRecvData.buffer = NULL; |
| } |
| free(NdefMap->pTransceiveInfo); |
| NdefMap->pTransceiveInfo = NULL; |
| } |
| |
| free(NdefMap); |
| NdefMap = NULL; |
| } |
| |
| if( tNciTranscvInfo.tSendData.pBuff != NULL ) |
| { |
| free(tNciTranscvInfo.tSendData.pBuff); |
| tNciTranscvInfo.tSendData.pBuff = NULL; |
| } |
| |
| if( NdefSmtCrdFmt != NULL ) |
| { |
| free(NdefSmtCrdFmt); |
| NdefSmtCrdFmt = NULL; |
| } |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_lock(&SharedDataMutex); |
| #endif |
| if ( NULL != NdefInfo.psUpperNdefMsg ) |
| { |
| if ( NdefInfo.psUpperNdefMsg->buffer != NULL ) |
| { |
| free(NdefInfo.psUpperNdefMsg->buffer); |
| NdefInfo.psUpperNdefMsg->buffer = NULL; |
| } |
| free(NdefInfo.psUpperNdefMsg); |
| NdefInfo.psUpperNdefMsg = NULL; |
| } |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_unlock(&SharedDataMutex); |
| #endif |
| if (NULL != gAuthCmdBuf.pauth_cmd) |
| { |
| if (NULL != gAuthCmdBuf.pauth_cmd->buffer) |
| { |
| free(gAuthCmdBuf.pauth_cmd->buffer); |
| gAuthCmdBuf.pauth_cmd->buffer = NULL; |
| } |
| free(gAuthCmdBuf.pauth_cmd); |
| gAuthCmdBuf.pauth_cmd = NULL; |
| } |
| status = NFCSTATUS_SUCCESS; |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxpExtns_MfcModuleInit |
| ** |
| ** Description It Initializes the memroy and global variables related |
| ** to Mifare module. |
| ** |
| ** Reset all the global variables and allocate memory for Mifare module |
| ** |
| ** Returns: |
| ** NFCSTATUS_SUCCESS - if successfully deinitialize |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS phNxpExtns_MfcModuleInit(void) |
| { |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| gphNxpExtns_Context.writecmdFlag = false; |
| gphNxpExtns_Context.RawWriteCallBack = false; |
| gphNxpExtns_Context.CallBackCtxt = NULL; |
| gphNxpExtns_Context.CallBackMifare = NULL; |
| gphNxpExtns_Context.ExtnsConnect = false; |
| gphNxpExtns_Context.ExtnsDeactivate = false; |
| gphNxpExtns_Context.ExtnsCallBack = false; |
| |
| NdefMap = malloc(sizeof(phFriNfc_NdefMap_t)); |
| if( NULL == NdefMap ) |
| { |
| goto clean_and_return; |
| } |
| memset(NdefMap,0,sizeof(phFriNfc_NdefMap_t)); |
| |
| NdefMap->psRemoteDevInfo = malloc(sizeof(phLibNfc_sRemoteDevInformation_t)); |
| if( NULL == NdefMap->psRemoteDevInfo ) |
| { |
| goto clean_and_return; |
| } |
| memset(NdefMap->psRemoteDevInfo, 0, sizeof(phLibNfc_sRemoteDevInformation_t)); |
| |
| NdefMap->SendRecvBuf = malloc((uint32_t)(MAX_BUFF_SIZE * 2)); |
| if( NULL == NdefMap->SendRecvBuf ) |
| { |
| goto clean_and_return; |
| } |
| memset(NdefMap->SendRecvBuf, 0, (MAX_BUFF_SIZE * 2)); |
| |
| NdefMap->SendRecvLength = malloc(sizeof(uint16_t)); |
| if( NULL == NdefMap->SendRecvLength ) |
| { |
| goto clean_and_return; |
| } |
| memset(NdefMap->SendRecvLength, 0, sizeof(uint16_t)); |
| |
| NdefMap->DataCount = malloc(sizeof(uint16_t)); |
| if( NULL == NdefMap->DataCount ) |
| { |
| goto clean_and_return; |
| } |
| memset(NdefMap->DataCount, 0, sizeof(uint16_t)); |
| |
| NdefMap->pTransceiveInfo = malloc(sizeof(phNfc_sTransceiveInfo_t)); |
| if(NULL == NdefMap->pTransceiveInfo) |
| { |
| goto clean_and_return; |
| } |
| memset(NdefMap->pTransceiveInfo, 0, sizeof(phNfc_sTransceiveInfo_t)); |
| |
| tNciTranscvInfo.tSendData.pBuff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); |
| if(NULL == tNciTranscvInfo.tSendData.pBuff) |
| { |
| goto clean_and_return; |
| } |
| memset(tNciTranscvInfo.tSendData.pBuff, 0, MAX_BUFF_SIZE); |
| |
| NdefMap->pTransceiveInfo->sSendData.buffer = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); |
| if( NdefMap->pTransceiveInfo->sSendData.buffer == NULL ) |
| { |
| goto clean_and_return; |
| } |
| memset( NdefMap->pTransceiveInfo->sSendData.buffer, 0, MAX_BUFF_SIZE ); |
| NdefMap->pTransceiveInfo->sSendData.length = MAX_BUFF_SIZE; |
| |
| NdefMap->pTransceiveInfo->sRecvData.buffer = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); /* size should be same as sRecvData */ |
| if( NdefMap->pTransceiveInfo->sRecvData.buffer == NULL ) |
| { |
| goto clean_and_return; |
| } |
| memset( NdefMap->pTransceiveInfo->sRecvData.buffer, 0, MAX_BUFF_SIZE ); |
| NdefMap->pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; |
| |
| NdefSmtCrdFmt = malloc( sizeof(phFriNfc_sNdefSmtCrdFmt_t) ); |
| if( NdefSmtCrdFmt == NULL ) |
| { |
| goto clean_and_return; |
| } |
| memset( NdefSmtCrdFmt , 0, sizeof(phFriNfc_sNdefSmtCrdFmt_t) ); |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_lock(&SharedDataMutex); |
| #endif |
| NdefInfo.psUpperNdefMsg = malloc(sizeof(phNfc_sData_t)); |
| if ( NULL == NdefInfo.psUpperNdefMsg ) |
| { |
| goto clean_and_return; |
| } |
| memset( NdefInfo.psUpperNdefMsg, 0, sizeof(phNfc_sData_t) ); |
| memset (&gAuthCmdBuf, 0, sizeof(phNci_mfc_auth_cmd_t)); |
| gAuthCmdBuf.pauth_cmd = malloc(sizeof(phNfc_sData_t)); |
| if (NULL == gAuthCmdBuf.pauth_cmd) |
| { |
| goto clean_and_return; |
| } |
| gAuthCmdBuf.pauth_cmd->buffer = malloc((uint32_t)NCI_MAX_DATA_LEN); |
| if (NULL == gAuthCmdBuf.pauth_cmd->buffer) |
| { |
| goto clean_and_return; |
| } |
| status = NFCSTATUS_SUCCESS; |
| |
| clean_and_return: |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_unlock(&SharedDataMutex); |
| #endif |
| if(status != NFCSTATUS_SUCCESS) |
| { |
| NXPLOG_EXTNS_E("CRIT: Memory Allocation failed for MFC!"); |
| phNxpExtns_MfcModuleDeInit(); |
| } |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_CheckNdef |
| ** |
| ** Description It triggers NDEF detection for Mifare Classic Tag. |
| ** |
| ** |
| ** Returns NFCSTATUS_SUCCESS - if successfully initiated |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS Mfc_CheckNdef(void) |
| { |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| |
| EXTNS_SetCallBackFlag(false); |
| /* Set Completion Routine for CheckNdef */ |
| NdefMap->CompletionRoutine[0].CompletionRoutine = Mfc_CheckNdef_Completion_Routine; |
| |
| gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process; |
| gphNxpExtns_Context.CallBackCtxt = NdefMap; |
| status = phFriNfc_MifareStdMap_H_Reset(NdefMap); |
| if ( NFCSTATUS_SUCCESS == status) |
| { |
| status = phFriNfc_MifareStdMap_ChkNdef(NdefMap); |
| if ( status == NFCSTATUS_PENDING ) |
| { |
| status = NFCSTATUS_SUCCESS; |
| } |
| } |
| if( status != NFCSTATUS_SUCCESS ) |
| { |
| status = NFCSTATUS_FAILED; |
| } |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_CheckNdef_Completion_Routine |
| ** |
| ** Description Notify NDEF detection for Mifare Classic Tag to JNI |
| ** |
| ** Upon completion of NDEF detection, a |
| ** NFA_NDEF_DETECT_EVT will be sent, to notify the application |
| ** of the NDEF attributes (NDEF total memory size, current |
| ** size, etc.). |
| ** |
| ** Returns: void |
| ** |
| *******************************************************************************/ |
| STATIC void Mfc_CheckNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status) |
| { |
| (void)NdefCtxt; |
| tNFA_CONN_EVT_DATA conn_evt_data; |
| |
| conn_evt_data.ndef_detect.status = status; |
| if(NFCSTATUS_SUCCESS == status) |
| { |
| /* NDef Tag Detected */ |
| conn_evt_data.ndef_detect.protocol = NFA_PROTOCOL_MIFARE; |
| phFrinfc_MifareClassic_GetContainerSize(NdefMap, |
| (uint32_t *)&(conn_evt_data.ndef_detect.max_size), |
| (uint32_t *)&(conn_evt_data.ndef_detect.cur_size)); |
| NdefInfo.NdefLength = conn_evt_data.ndef_detect.max_size; |
| /* update local flags */ |
| NdefInfo.is_ndef = 1; |
| NdefInfo.NdefActualSize = conn_evt_data.ndef_detect.cur_size; |
| if ( PH_NDEFMAP_CARD_STATE_READ_ONLY == NdefMap->CardState ) |
| { |
| NXPLOG_EXTNS_D("Mfc_CheckNdef_Completion_Routine : READ_ONLY_CARD"); |
| conn_evt_data.ndef_detect.flags = RW_NDEF_FL_READ_ONLY; |
| } |
| else |
| { |
| conn_evt_data.ndef_detect.flags = RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED; |
| } |
| } |
| else |
| { |
| /* NDEF Detection failed for other reasons */ |
| conn_evt_data.ndef_detect.cur_size = 0; |
| conn_evt_data.ndef_detect.max_size = 0; |
| conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN; |
| |
| /* update local flags */ |
| NdefInfo.is_ndef = 0; |
| NdefInfo.NdefActualSize = conn_evt_data.ndef_detect.cur_size; |
| } |
| (*gphNxpExtns_Context.p_conn_cback) (NFA_NDEF_DETECT_EVT, &conn_evt_data); |
| |
| return; |
| } |
| /******************************************************************************* |
| ** |
| ** Function Mfc_ReadNdef_Completion_Routine |
| ** |
| ** Description Notify NDEF read completion for Mifare Classic Tag to JNI |
| ** |
| ** Upon completion of NDEF read, a |
| ** NFA_READ_CPLT_EVT will be sent, to notify the application |
| ** with the NDEF data and status |
| ** |
| ** Returns: void |
| ** |
| *******************************************************************************/ |
| STATIC void Mfc_ReadNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status) |
| { |
| (void)NdefCtxt; |
| tNFA_CONN_EVT_DATA conn_evt_data; |
| tNFA_NDEF_EVT_DATA p_data; |
| |
| conn_evt_data.status = status; |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_lock(&SharedDataMutex); |
| #endif |
| if(NFCSTATUS_SUCCESS == status) |
| { |
| p_data.ndef_data.len = NdefInfo.psUpperNdefMsg->length; |
| p_data.ndef_data.p_data = NdefInfo.psUpperNdefMsg->buffer; |
| (*gphNxpExtns_Context.p_ndef_cback) (NFA_NDEF_DATA_EVT, &p_data); |
| } |
| else |
| { |
| } |
| |
| (*gphNxpExtns_Context.p_conn_cback) (NFA_READ_CPLT_EVT, &conn_evt_data); |
| |
| if( NdefInfo.psUpperNdefMsg->buffer != NULL) |
| { |
| free (NdefInfo.psUpperNdefMsg->buffer); |
| NdefInfo.psUpperNdefMsg->buffer = NULL; |
| } |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_unlock(&SharedDataMutex); |
| #endif |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_WriteNdef_Completion_Routine |
| ** |
| ** Description Notify NDEF write completion for Mifare Classic Tag to JNI |
| ** |
| ** Upon completion of NDEF write, a |
| ** NFA_WRITE_CPLT_EVT will be sent along with status |
| ** |
| ** Returns: void |
| ** |
| *******************************************************************************/ |
| STATIC void Mfc_WriteNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status) |
| { |
| (void)NdefCtxt; |
| tNFA_CONN_EVT_DATA conn_evt_data; |
| |
| conn_evt_data.status = status; |
| (*gphNxpExtns_Context.p_conn_cback) (NFA_WRITE_CPLT_EVT, &conn_evt_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_FormatNdef_Completion_Routine |
| ** |
| ** Description Notify NDEF format completion for Mifare Classic Tag to JNI |
| ** |
| ** Upon completion of NDEF format, a |
| ** NFA_FORMAT_CPLT_EVT will be sent along with status |
| ** |
| ** Returns: void |
| ** |
| *******************************************************************************/ |
| STATIC void Mfc_FormatNdef_Completion_Routine(void *NdefCtxt, NFCSTATUS status) |
| { |
| (void)NdefCtxt; |
| tNFA_CONN_EVT_DATA conn_evt_data; |
| |
| conn_evt_data.status = status; |
| (*gphNxpExtns_Context.p_conn_cback) (NFA_FORMAT_CPLT_EVT, &conn_evt_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phFriNfc_ValidateParams |
| ** |
| ** Description This function is a common function which validates NdefRd |
| ** and NdefWr parameters. |
| ** |
| ** Returns NFCSTATUS_SUCCESS - All the params are valid |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phFriNfc_ValidateParams(uint8_t *PacketData, |
| uint32_t *PacketDataLength, |
| uint8_t Offset, |
| phFriNfc_NdefMap_t *pNdefMap, |
| uint8_t bNdefReq) |
| { |
| |
| if( (pNdefMap == NULL) || (PacketData == NULL) |
| || (PacketDataLength == NULL) ) |
| { |
| return NFCSTATUS_FAILED; |
| } |
| |
| if( pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID ) |
| { |
| return NFCSTATUS_FAILED; |
| } |
| |
| if( bNdefReq == PH_FRINFC_NDEF_READ_REQ ) |
| { |
| if( (Offset != PH_FRINFC_NDEFMAP_SEEK_CUR) && (Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) ) |
| { |
| return NFCSTATUS_FAILED; |
| } |
| if( pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_INITIALIZED ) |
| { |
| pNdefMap->NumOfBytesRead = PacketDataLength; |
| *pNdefMap->NumOfBytesRead = 0; |
| return NFCSTATUS_EOF_NDEF_CONTAINER_REACHED; |
| } |
| if( (pNdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE) && |
| (Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN) ) |
| { |
| return NFCSTATUS_FAILED; /* return INVALID_DEVICE_REQUEST */ |
| } |
| if( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN ) |
| { |
| pNdefMap->ApduBuffIndex = 0; |
| *pNdefMap->DataCount = 0; |
| } |
| else if ( (pNdefMap->bPrevReadMode == PH_FRINFC_NDEFMAP_SEEK_BEGIN) || |
| (pNdefMap->bPrevReadMode == PH_FRINFC_NDEFMAP_SEEK_CUR) ) |
| { |
| |
| } |
| else |
| { |
| return NFCSTATUS_FAILED; |
| } |
| } |
| else if( bNdefReq == PH_FRINFC_NDEF_WRITE_REQ ) |
| { |
| if( pNdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY ) |
| { |
| pNdefMap->WrNdefPacketLength = PacketDataLength; |
| *pNdefMap->WrNdefPacketLength = 0x00; |
| return NFCSTATUS_NOT_ALLOWED; |
| } |
| } |
| |
| return NFCSTATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_SetRdOnly_Completion_Routine |
| ** |
| ** Description Notify NDEF read only completion for Mifare Classic Tag to JNI |
| ** |
| ** Upon completion of NDEF format, a |
| ** NFA_SET_TAG_RO_EVT will be sent along with status |
| ** |
| ** Returns: void |
| ** |
| *******************************************************************************/ |
| STATIC void Mfc_SetRdOnly_Completion_Routine(void *NdefCtxt, NFCSTATUS status) |
| { |
| (void)NdefCtxt; |
| tNFA_CONN_EVT_DATA conn_evt_data; |
| ALOGE("%s status = 0x%x", __func__, status); |
| conn_evt_data.status = status; |
| (*gphNxpExtns_Context.p_conn_cback) (NFA_SET_TAG_RO_EVT, &conn_evt_data); |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_SetReadOnly |
| ** |
| ** |
| ** Description: It triggers ConvertToReadOnly for Mifare Classic Tag. |
| ** |
| ** Returns: |
| ** NFCSTATUS_SUCCESS if successfully initiated |
| ** NFCSTATUS_FAILED otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS Mfc_SetReadOnly(uint8_t *secrtkey, uint8_t len) |
| { |
| NXPLOG_EXTNS_D("%s Entering ", __func__); |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| uint8_t mif_secrete_key[6] = {0}; |
| uint8_t id = 0; |
| EXTNS_SetCallBackFlag(false); |
| memcpy(mif_secrete_key,secrtkey,len); |
| gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process; |
| gphNxpExtns_Context.CallBackCtxt = NdefMap; |
| for (id = 0; id < len; id++) |
| { |
| ALOGV("secrtkey[%d] = 0x%x", id, secrtkey[id]); |
| ALOGV("mif_secrete_key[%d] = 0x%x", id, mif_secrete_key[id]); |
| } |
| /* Set Completion Routine for ReadNdef */ |
| NdefMap->CompletionRoutine[0].CompletionRoutine = Mfc_SetRdOnly_Completion_Routine; |
| if(NdefInfo.is_ndef == 0) |
| { |
| status = NFCSTATUS_NON_NDEF_COMPLIANT; |
| goto Mfc_SetRdOnly; |
| } |
| else if( (NdefInfo.is_ndef == 1) && (NdefInfo.NdefActualSize == 0) ) |
| { |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_lock(&SharedDataMutex); |
| #endif |
| NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize; |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_unlock(&SharedDataMutex); |
| #endif |
| status = NFCSTATUS_SUCCESS; |
| goto Mfc_SetRdOnly; |
| } |
| else |
| { |
| status = phFriNfc_MifareStdMap_ConvertToReadOnly(NdefMap, mif_secrete_key); |
| } |
| if ( NFCSTATUS_PENDING == status ) |
| { |
| status = NFCSTATUS_SUCCESS; |
| } |
| |
| Mfc_SetRdOnly: |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_ReadNdef |
| ** |
| ** Description It triggers receiving of the NDEF message from Mifare Classic Tag. |
| ** |
| ** |
| ** Returns: |
| ** NFCSTATUS_SUCCESS - if successfully initiated |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS Mfc_ReadNdef(void) |
| { |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| uint8_t *PacketData = NULL; |
| uint32_t *PacketDataLength = NULL; |
| phLibNfc_Ndef_EOffset_t Offset; |
| |
| EXTNS_SetCallBackFlag(false); |
| |
| Offset = phLibNfc_Ndef_EBegin; |
| |
| gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process; |
| gphNxpExtns_Context.CallBackCtxt = NdefMap; |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_lock(&SharedDataMutex); |
| #endif |
| if(NdefInfo.is_ndef == 0) |
| { |
| status = NFCSTATUS_NON_NDEF_COMPLIANT; |
| goto Mfc_RdNdefEnd; |
| } |
| else if( (NdefInfo.is_ndef == 1) && (NdefInfo.NdefActualSize == 0) ) |
| { |
| NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize; |
| status = NFCSTATUS_SUCCESS; |
| goto Mfc_RdNdefEnd; |
| } |
| else |
| { |
| NdefInfo.psUpperNdefMsg->buffer = malloc(NdefInfo.NdefActualSize); |
| if ( NULL == NdefInfo.psUpperNdefMsg->buffer) |
| { |
| goto Mfc_RdNdefEnd; |
| } |
| NdefInfo.psUpperNdefMsg->length = NdefInfo.NdefActualSize; |
| |
| /* Set Completion Routine for ReadNdef */ |
| NdefMap->CompletionRoutine[1].CompletionRoutine = Mfc_ReadNdef_Completion_Routine; |
| NdefInfo.NdefContinueRead = (uint8_t) ((phLibNfc_Ndef_EBegin==Offset) ? |
| PH_FRINFC_NDEFMAP_SEEK_BEGIN : |
| PH_FRINFC_NDEFMAP_SEEK_CUR); |
| } |
| |
| PacketData = NdefInfo.psUpperNdefMsg->buffer; |
| PacketDataLength = (uint32_t*)&(NdefInfo.psUpperNdefMsg->length); |
| NdefMap->bCurrReadMode = Offset; |
| status = phFriNfc_ValidateParams (PacketData, PacketDataLength, Offset, NdefMap, PH_FRINFC_NDEF_READ_REQ); |
| if( status != NFCSTATUS_SUCCESS ) |
| { |
| goto Mfc_RdNdefEnd; |
| } |
| |
| status = phFriNfc_MifareStdMap_RdNdef(NdefMap, PacketData, PacketDataLength, Offset); |
| |
| if(NFCSTATUS_INSUFFICIENT_STORAGE == status) |
| { |
| NdefInfo.psUpperNdefMsg->length = 0x00; |
| status = NFCSTATUS_SUCCESS; |
| } |
| |
| if ( NFCSTATUS_PENDING == status ) |
| { |
| status = NFCSTATUS_SUCCESS; |
| } |
| |
| Mfc_RdNdefEnd: |
| if( status != NFCSTATUS_SUCCESS ) |
| { |
| if ( NULL != NdefInfo.psUpperNdefMsg->buffer ) |
| { |
| free(NdefInfo.psUpperNdefMsg->buffer); |
| NdefInfo.psUpperNdefMsg->buffer = NULL; |
| } |
| status = NFCSTATUS_FAILED; |
| } |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_unlock(&SharedDataMutex); |
| #endif |
| return status; |
| |
| } |
| /******************************************************************************* |
| ** |
| ** Function Mfc_PresenceCheck |
| ** |
| ** Description It triggers receiving of the NDEF message from Mifare Classic Tag. |
| ** |
| ** |
| ** Returns: |
| ** NFCSTATUS_SUCCESS - if successfully initiated |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS Mfc_PresenceCheck(void) |
| { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| |
| if (gAuthCmdBuf.auth_status == true) |
| { |
| EXTNS_SetCallBackFlag(false); |
| status = nativeNfcExtns_doTransceive(gAuthCmdBuf.pauth_cmd->buffer, |
| gAuthCmdBuf.pauth_cmd->length); |
| if (status != NFCSTATUS_PENDING) |
| { |
| gAuthCmdBuf.auth_sent = false; |
| status = NFCSTATUS_FAILED; |
| } |
| else |
| { |
| gAuthCmdBuf.auth_sent = true; |
| status = NFCSTATUS_SUCCESS; |
| } |
| } |
| else |
| { |
| status = NFCSTATUS_NOT_ALLOWED; |
| } |
| NXPLOG_EXTNS_D("%s status = 0x%x", __func__, status); |
| return status; |
| } |
| /******************************************************************************* |
| ** |
| ** Function Mfc_WriteNdef |
| ** |
| ** Description It triggers the NDEF data write to Mifare Classic Tag. |
| ** |
| ** |
| ** Returns: |
| ** NFCSTATUS_SUCCESS - if successfully initiated |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS Mfc_WriteNdef(uint8_t *p_data, uint32_t len) |
| { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| uint8_t *PacketData = NULL; |
| uint32_t *PacketDataLength = NULL; |
| |
| if( p_data == NULL || len == 0 ) |
| { |
| NXPLOG_EXTNS_E("MFC Error: Invalid Parameters to Ndef Write"); |
| status = NFCSTATUS_FAILED; |
| goto Mfc_WrNdefEnd; |
| } |
| |
| EXTNS_SetCallBackFlag(false); |
| gphNxpExtns_Context.CallBackMifare = phFriNfc_MifareStdMap_Process; |
| gphNxpExtns_Context.CallBackCtxt = NdefMap; |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_lock(&SharedDataMutex); |
| #endif |
| if( NdefInfo.is_ndef == PH_LIBNFC_INTERNAL_CHK_NDEF_NOT_DONE ) |
| { |
| status = NFCSTATUS_REJECTED; |
| goto Mfc_WrNdefEnd; |
| } |
| else if( NdefInfo.is_ndef == 0 ) |
| { |
| status = NFCSTATUS_NON_NDEF_COMPLIANT; |
| goto Mfc_WrNdefEnd; |
| } |
| else if( len > NdefInfo.NdefLength ) |
| { |
| status = NFCSTATUS_NOT_ENOUGH_MEMORY; |
| goto Mfc_WrNdefEnd; |
| } |
| else |
| { |
| NdefInfo.psUpperNdefMsg->buffer = p_data; |
| NdefInfo.psUpperNdefMsg->length = len; |
| |
| NdefInfo.AppWrLength = len; |
| NdefMap->CompletionRoutine[2].CompletionRoutine = Mfc_WriteNdef_Completion_Routine; |
| if( 0 == len ) |
| { |
| /* TODO: Erase the Tag */ |
| } |
| else |
| { |
| NdefMap->ApduBuffIndex = 0x00; |
| *NdefMap->DataCount = 0x00; |
| PacketData = NdefInfo.psUpperNdefMsg->buffer; |
| PacketDataLength = &(NdefInfo.dwWrLength); |
| NdefMap->WrNdefPacketLength = PacketDataLength; |
| NdefInfo.dwWrLength = len; |
| |
| status = phFriNfc_ValidateParams (PacketData, PacketDataLength, 0, NdefMap, PH_FRINFC_NDEF_WRITE_REQ); |
| if( status != NFCSTATUS_SUCCESS ) |
| { |
| goto Mfc_WrNdefEnd; |
| } |
| |
| status = phFriNfc_MifareStdMap_WrNdef(NdefMap, PacketData, PacketDataLength, PH_FRINFC_NDEFMAP_SEEK_BEGIN); |
| |
| if ( status == NFCSTATUS_PENDING ) |
| { |
| status = NFCSTATUS_SUCCESS; |
| } |
| } |
| } |
| |
| Mfc_WrNdefEnd: |
| #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) |
| pthread_mutex_unlock(&SharedDataMutex); |
| #endif |
| if( status != NFCSTATUS_SUCCESS ) |
| { |
| status = NFCSTATUS_FAILED; |
| } |
| return status; |
| } |
| /******************************************************************************* |
| ** |
| ** Function phFriNfc_NdefSmtCrd_Reset__ |
| ** |
| ** Description This function Resets the component instance to the initial |
| ** state and initializes the internal variables. |
| ** |
| ** Returns NFCSTATUS_SUCCESS |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phFriNfc_NdefSmtCrd_Reset__(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, |
| uint8_t *SendRecvBuffer, |
| uint16_t *SendRecvBuffLen) |
| { |
| // NFCSTATUS status = NFCSTATUS_FAILED; /*commented to eliminate unused variable warning*/ |
| uint8_t index; |
| |
| /* Initialize the state to Init */ |
| NdefSmtCrdFmt->State = PH_FRINFC_SMTCRDFMT_STATE_RESET_INIT; |
| |
| for(index = 0;index<PH_FRINFC_SMTCRDFMT_CR;index++) |
| { |
| /* Initialize the NdefMap Completion Routine to Null */ |
| NdefSmtCrdFmt->CompletionRoutine[index].CompletionRoutine = NULL; |
| /* Initialize the NdefMap Completion Routine context to Null */ |
| NdefSmtCrdFmt->CompletionRoutine[index].Context = NULL; |
| } |
| |
| /* Trx Buffer registered */ |
| NdefSmtCrdFmt->SendRecvBuf = SendRecvBuffer; |
| |
| /* Trx Buffer Size */ |
| NdefSmtCrdFmt->SendRecvLength = SendRecvBuffLen; |
| |
| /* Register Transfer Buffer Length */ |
| NdefSmtCrdFmt->SendLength = 0; |
| |
| /* Initialize the Format status flag*/ |
| NdefSmtCrdFmt->FmtProcStatus = 0; |
| |
| /* Reset the Card Type */ |
| NdefSmtCrdFmt->CardType = 0; |
| |
| /* Reset MapCompletion Info*/ |
| NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = NULL; |
| NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NULL; |
| |
| phFriNfc_MfStd_Reset(NdefSmtCrdFmt); |
| |
| return NFCSTATUS_SUCCESS; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_FormatNdef |
| ** |
| ** Description It triggers the NDEF format of Mifare Classic Tag. |
| ** |
| ** |
| ** Returns: |
| ** NFCSTATUS_SUCCESS - if successfully initiated |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS Mfc_FormatNdef(uint8_t *secretkey, uint8_t len) |
| { |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| uint8_t mif_std_key[6] = {0}; |
| // static uint8_t Index; /*commented to eliminate unused variable warning*/ |
| uint8_t sak = 0; |
| |
| EXTNS_SetCallBackFlag(false); |
| |
| memcpy(mif_std_key,secretkey,len); |
| memcpy(current_key,secretkey,len); |
| |
| if( NULL == NdefSmtCrdFmt || |
| NULL == NdefMap || NULL == NdefMap->SendRecvBuf ) |
| { |
| goto Mfc_FormatEnd; |
| } |
| NdefSmtCrdFmt->pTransceiveInfo = NdefMap->pTransceiveInfo; |
| |
| gphNxpExtns_Context.CallBackMifare = phFriNfc_MfStd_Process; |
| gphNxpExtns_Context.CallBackCtxt = NdefSmtCrdFmt; |
| |
| NdefInfo.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN; |
| phFriNfc_NdefSmtCrd_Reset__(NdefSmtCrdFmt, NdefMap->SendRecvBuf, &(NdefInfo.NdefSendRecvLen)); |
| |
| /* Register Callbacks */ |
| NdefSmtCrdFmt->CompletionRoutine[0].CompletionRoutine = Mfc_FormatNdef_Completion_Routine; |
| NdefSmtCrdFmt->CompletionRoutine[1].CompletionRoutine = Mfc_FormatNdef_Completion_Routine; |
| NdefSmtCrdFmt->psRemoteDevInfo = NdefMap->psRemoteDevInfo; |
| sak = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; |
| |
| if((0x08 == (sak & 0x18)) || (0x18 == (sak & 0x18)) || |
| (0x01 == sak)) |
| { |
| NdefSmtCrdFmt->CardType = (uint8_t) (((sak & 0x18) == 0x08)? |
| PH_FRINFC_SMTCRDFMT_MFSTD_1K_CRD:(((sak & 0x19) == 0x19)? |
| PH_FRINFC_SMTCRDFMT_MFSTD_2K_CRD: |
| PH_FRINFC_SMTCRDFMT_MFSTD_4K_CRD)); |
| status = phFriNfc_MfStd_Format( NdefSmtCrdFmt, mif_std_key); |
| } |
| |
| if( NFCSTATUS_PENDING == status ) |
| { |
| status = NFCSTATUS_SUCCESS; |
| } |
| |
| Mfc_FormatEnd: |
| if( status != NFCSTATUS_SUCCESS ) |
| { |
| status = NFCSTATUS_FAILED; |
| } |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNxNciExtns_MifareStd_Reconnect |
| ** |
| ** Description This function sends the deactivate command to NFCC for Mifare |
| ** |
| ** |
| ** Returns: |
| ** NFCSTATUS_PENDING - if successfully initiated |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS phNxNciExtns_MifareStd_Reconnect(void) |
| { |
| tNFA_STATUS status; |
| |
| EXTNS_SetDeactivateFlag(true); |
| if (NFA_STATUS_OK != (status = NFA_Deactivate (true))) /* deactivate to sleep state */ |
| { |
| NXPLOG_EXTNS_E ("%s: deactivate failed, status = %d", __func__, status); |
| return NFCSTATUS_FAILED; |
| } |
| |
| return NFCSTATUS_PENDING; |
| |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_DeactivateCbackSelect |
| ** |
| ** Description This function select the Mifare tag |
| ** |
| ** |
| ** Returns: void |
| ** |
| *******************************************************************************/ |
| void Mfc_DeactivateCbackSelect(void) |
| { |
| tNFA_STATUS status; |
| |
| EXTNS_SetConnectFlag(true); |
| if (NFA_STATUS_OK != (status = NFA_Select (0x01, phNciNfc_e_RfProtocolsMifCProtocol, |
| phNciNfc_e_RfInterfacesTagCmd_RF))) |
| { |
| NXPLOG_EXTNS_E ("%s: NFA_Select failed, status = %d", __func__, status); |
| } |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_ActivateCback |
| ** |
| ** Description This function invoke the callback when receive the response |
| ** |
| ** |
| ** Returns: void |
| ** |
| ** |
| *******************************************************************************/ |
| void Mfc_ActivateCback(void) |
| { |
| gphNxpExtns_Context.CallBackMifare(gphNxpExtns_Context.CallBackCtxt, NFCSTATUS_SUCCESS); |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_Transceive |
| ** |
| ** Description Sends raw frame to Mifare Classic Tag. |
| ** |
| ** Returns NFCSTATUS_SUCCESS - if successfully initiated |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS Mfc_Transceive(uint8_t *p_data, uint32_t len) |
| { |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| uint8_t i = 0x00; |
| |
| gphNxpExtns_Context.RawWriteCallBack = false; |
| gphNxpExtns_Context.CallBackMifare = NULL; |
| gphNxpExtns_Context.CallBackCtxt = NdefMap; |
| |
| EXTNS_SetCallBackFlag(true); |
| if( p_data[0] == 0x60 || p_data[0] == 0x61 ) |
| { |
| |
| NdefMap->Cmd.MfCmd = p_data[0]; |
| |
| NdefMap->SendRecvBuf[i++] = p_data[1]; |
| |
| NdefMap->SendRecvBuf[i++] = p_data[6]; /* TODO, handle 7 byte UID */ |
| NdefMap->SendRecvBuf[i++] = p_data[7]; |
| NdefMap->SendRecvBuf[i++] = p_data[8]; |
| NdefMap->SendRecvBuf[i++] = p_data[9]; |
| NdefMap->SendRecvBuf[i++] = p_data[10]; |
| NdefMap->SendRecvBuf[i++] = p_data[11]; |
| |
| status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, |
| NdefMap->Cmd, |
| NdefMap->SendRecvBuf, |
| NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| } |
| else if( p_data[0] == 0xA0 ) |
| { |
| EXTNS_SetCallBackFlag(false); |
| NdefMap->Cmd.MfCmd = phNfc_eMifareWrite16; |
| gphNxpExtns_Context.RawWriteCallBack = true; |
| |
| memcpy(NdefMap->SendRecvBuf, &p_data[1], len-1); |
| NdefMap->SendLength = len-1; |
| status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, |
| NdefMap->Cmd, |
| NdefMap->SendRecvBuf, |
| NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| } |
| else if( (p_data[0] == phNfc_eMifareInc) || (p_data[0] == phNfc_eMifareDec) ) |
| { |
| |
| EXTNS_SetCallBackFlag(false); |
| NdefMap->Cmd.MfCmd = p_data[0]; |
| gphNxpExtns_Context.RawWriteCallBack = true; |
| |
| memcpy(NdefMap->SendRecvBuf, &p_data[1], len-1); |
| NdefMap->SendLength = len - 1; |
| status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, |
| NdefMap->Cmd, |
| NdefMap->SendRecvBuf, |
| NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| } |
| else if( ((p_data[0] == phNfc_eMifareTransfer) || (p_data[0] == phNfc_eMifareRestore)) && (len == 2) ) |
| { |
| NdefMap->Cmd.MfCmd = p_data[0]; |
| if (p_data[0] == phNfc_eMifareRestore) |
| { |
| EXTNS_SetCallBackFlag(false); |
| gphNxpExtns_Context.RawWriteCallBack = true; |
| memcpy(NdefMap->SendRecvBuf, &p_data[1], len -1); |
| NdefMap->SendLength = len - 1; |
| } |
| else |
| { |
| memcpy(NdefMap->SendRecvBuf, p_data, len); |
| NdefMap->SendLength = len; |
| } |
| status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, |
| NdefMap->Cmd, |
| NdefMap->SendRecvBuf, |
| NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| |
| } |
| else |
| { |
| NdefMap->Cmd.MfCmd = phNfc_eMifareRaw; |
| |
| memcpy(NdefMap->SendRecvBuf, p_data, len); |
| NdefMap->SendLength = len; |
| status = phFriNfc_ExtnsTransceive(NdefMap->pTransceiveInfo, |
| NdefMap->Cmd, |
| NdefMap->SendRecvBuf, |
| NdefMap->SendLength, |
| NdefMap->SendRecvLength); |
| } |
| if (NFCSTATUS_PENDING == status) |
| { |
| status = NFCSTATUS_SUCCESS; |
| } |
| else |
| { |
| NXPLOG_EXTNS_E("ERROR: Mfc_Transceive = 0x%x", status); |
| } |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function nativeNfcExtns_doTransceive |
| ** |
| ** Description Sends raw frame to BCM stack. |
| ** |
| ** Returns NFCSTATUS_PENDING - if successfully initiated |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS nativeNfcExtns_doTransceive(uint8_t *buff, uint16_t buffSz) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_PENDING; |
| tNFA_STATUS status = NFA_SendRawFrame (buff, buffSz, NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY); |
| |
| if (status != NFA_STATUS_OK) |
| { |
| NXPLOG_EXTNS_E ("%s: fail send; error=%d", __func__, status); |
| wStatus = NFCSTATUS_FAILED; |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNciNfc_RecvMfResp |
| ** |
| ** Description This function shall be invoked as part of ReaderMgmt data |
| ** exchange sequence handler on receiving response/data from NFCC |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Data Reception is successful |
| ** NFCSTATUS_FAILED - Data Reception failed |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS |
| phNciNfc_RecvMfResp(phNciNfc_Buff_t* RspBuffInfo, |
| NFCSTATUS wStatus |
| ) |
| { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| uint16_t wPldDataSize = 0; |
| phNciNfc_ExtnRespId_t RecvdExtnRspId = phNciNfc_e_InvalidRsp; |
| uint16_t wRecvDataSz = 0; |
| |
| if(NULL == RspBuffInfo) |
| { |
| status = NFCSTATUS_FAILED; |
| } |
| else |
| { |
| if((0 == (RspBuffInfo->wLen)) |
| || (PH_NCINFC_STATUS_OK != wStatus) |
| || (NULL == (RspBuffInfo->pBuff)) |
| ) |
| { |
| status = NFCSTATUS_FAILED; |
| } |
| else |
| { |
| RecvdExtnRspId = (phNciNfc_ExtnRespId_t)RspBuffInfo->pBuff[0]; |
| |
| switch(RecvdExtnRspId) |
| { |
| case phNciNfc_e_MfXchgDataRsp: |
| { |
| /* check the status byte */ |
| if( PH_NCINFC_STATUS_OK == RspBuffInfo->pBuff[RspBuffInfo->wLen-1] ) |
| { |
| status = NFCSTATUS_SUCCESS; |
| |
| /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */ |
| wPldDataSize = ((RspBuffInfo->wLen) - |
| (PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE)); |
| wRecvDataSz = NCI_MAX_DATA_LEN; |
| |
| /* wPldDataSize = wPldDataSize-1; ==> ignoring the last status byte appended with data */ |
| if((wPldDataSize) <= wRecvDataSz) |
| { |
| /* Extract the data part from pBuff[2] & fill it to be sent to upper layer */ |
| memcpy(NdefMap->SendRecvBuf, &(RspBuffInfo->pBuff[1]),(wPldDataSize)); |
| /* update the number of bytes received from lower layer,excluding the status byte */ |
| *(NdefMap->SendRecvLength) = wPldDataSize; |
| } |
| else |
| { |
| //TODO:- Map some status for remaining extra data received to be sent back to caller?? |
| status = NFCSTATUS_FAILED; |
| } |
| } |
| else |
| { |
| status = NFCSTATUS_FAILED; |
| } |
| } |
| break; |
| |
| case phNciNfc_e_MfcAuthRsp: |
| { |
| /* check the status byte */ |
| if(PH_NCINFC_STATUS_OK == RspBuffInfo->pBuff[1]) |
| { |
| if (gAuthCmdBuf.auth_sent == true) |
| { |
| MfcPresenceCheckResult(NFCSTATUS_SUCCESS); |
| return NFCSTATUS_SUCCESS; |
| } |
| gAuthCmdBuf.auth_status = true; |
| status = NFCSTATUS_SUCCESS; |
| |
| /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */ |
| wPldDataSize = ((RspBuffInfo->wLen) - |
| (PHNCINFC_EXTNID_SIZE + PHNCINFC_EXTNSTATUS_SIZE)); |
| |
| /* Extract the data part from pBuff[2] & fill it to be sent to upper layer */ |
| memcpy(NdefMap->SendRecvBuf, &(RspBuffInfo->pBuff[2]),wPldDataSize); |
| /* update the number of bytes received from lower layer,excluding the status byte */ |
| *(NdefMap->SendRecvLength) = wPldDataSize; |
| } |
| else |
| { |
| if (gAuthCmdBuf.auth_sent == true) |
| { |
| gAuthCmdBuf.auth_status = false; |
| MfcPresenceCheckResult(NFCSTATUS_FAILED); |
| return NFCSTATUS_SUCCESS; |
| } |
| else |
| { |
| /* Reset the stored auth command buffer */ |
| memset(gAuthCmdBuf.pauth_cmd->buffer, 0 , NCI_MAX_DATA_LEN); |
| gAuthCmdBuf.pauth_cmd->length = 0; |
| gAuthCmdBuf.auth_status = false; |
| } |
| status = NFCSTATUS_FAILED; |
| } |
| } |
| break; |
| |
| default: |
| { |
| status = NFCSTATUS_FAILED; |
| } |
| break; |
| } |
| } |
| } |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_SendWrt16CmdPayload |
| ** |
| ** Description This function map the raw write cmd |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Command framing done |
| ** NFCSTATUS_INVALID_PARAMETER - Otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_SendWrt16CmdPayload(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| |
| if( (NULL != pTransceiveInfo->sSendData.buffer) && |
| (0 != (pTransceiveInfo->sSendData.length))) |
| { |
| memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer, |
| (pTransceiveInfo->sSendData.length)); |
| pMappedTranscvIf->tSendData.wLen = pTransceiveInfo->sSendData.length; |
| pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; |
| } |
| else |
| { |
| wStatus = NFCSTATUS_INVALID_PARAMETER; |
| } |
| |
| if ( gphNxpExtns_Context.RawWriteCallBack == true ) |
| { |
| EXTNS_SetCallBackFlag(true); |
| gphNxpExtns_Context.RawWriteCallBack = false; |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_SendIncDecCmdPayload |
| ** |
| ** Description This function prepares the Increment/Decrement Value to be |
| ** sent. This is called after sending the Increment/Decrement |
| ** command is already sent and successfull |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Payload framing done |
| ** NFCSTATUS_INVALID_PARAMETER - Otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_SendIncDecCmdPayload(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| |
| if( (NULL != pTransceiveInfo->sSendData.buffer) && |
| (0 != (pTransceiveInfo->sSendData.length))) |
| { |
| memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer, |
| (pTransceiveInfo->sSendData.length)); |
| pMappedTranscvIf->tSendData.wLen = pTransceiveInfo->sSendData.length; |
| pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; |
| } |
| else |
| { |
| wStatus = NFCSTATUS_INVALID_PARAMETER; |
| } |
| |
| if ( gphNxpExtns_Context.RawWriteCallBack == true ) |
| { |
| EXTNS_SetCallBackFlag(true); |
| gphNxpExtns_Context.RawWriteCallBack = false; |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function Mfc_RecvPacket |
| ** |
| ** Description Decodes Mifare Classic Tag Response |
| ** This is called from NFA_SendRaw Callback |
| ** |
| ** Returns: |
| ** NFCSTATUS_SUCCESS - if successfully initiated |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS Mfc_RecvPacket(uint8_t *buff, uint8_t buffSz) |
| { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| phNciNfc_Buff_t RspBuff; |
| uint8_t *pcmd_buff; |
| uint16_t buffSize; |
| |
| RspBuff.pBuff = buff; |
| RspBuff.wLen = buffSz; |
| status = phNciNfc_RecvMfResp(&RspBuff, status); |
| if (true == gAuthCmdBuf.auth_sent) |
| { |
| ALOGV("%s Mfc Check Presence in progress", __func__); |
| gAuthCmdBuf.auth_sent = false; |
| return status; |
| } |
| if(true == gphNxpExtns_Context.writecmdFlag && (NFCSTATUS_SUCCESS == status )) |
| { |
| pcmd_buff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); |
| if( NULL == pcmd_buff ) |
| { |
| return NFCSTATUS_FAILED; |
| } |
| buffSize = MAX_BUFF_SIZE; |
| gphNxpExtns_Context.writecmdFlag = false; |
| phLibNfc_SendWrt16CmdPayload(NdefMap->pTransceiveInfo, &tNciTranscvInfo); |
| status = phNciNfc_SendMfReq(tNciTranscvInfo, pcmd_buff, &buffSize); |
| if ( NFCSTATUS_PENDING != status ) |
| { |
| NXPLOG_EXTNS_E("ERROR : Mfc_RecvPacket: 0x%x", status); |
| } |
| else |
| { |
| status = NFCSTATUS_SUCCESS; |
| } |
| if( pcmd_buff != NULL ) |
| { |
| free(pcmd_buff); |
| pcmd_buff = NULL; |
| } |
| } |
| else if(true == gphNxpExtns_Context.incrdecflag && (NFCSTATUS_SUCCESS == status )) |
| { |
| pcmd_buff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); |
| if( NULL == pcmd_buff ) |
| { |
| return NFCSTATUS_FAILED; |
| } |
| buffSize = MAX_BUFF_SIZE; |
| gphNxpExtns_Context.incrdecflag = false; |
| phLibNfc_SendIncDecCmdPayload(NdefMap->pTransceiveInfo, &tNciTranscvInfo); |
| status = phNciNfc_SendMfReq(tNciTranscvInfo, pcmd_buff, &buffSize); |
| if ( NFCSTATUS_PENDING != status ) |
| { |
| NXPLOG_EXTNS_E("ERROR : Mfc_RecvPacket: 0x%x", status); |
| } |
| else |
| { |
| status = NFCSTATUS_SUCCESS; |
| } |
| gphNxpExtns_Context.incrdecstatusflag = true; |
| if( pcmd_buff != NULL ) |
| { |
| free(pcmd_buff); |
| pcmd_buff = NULL; |
| } |
| |
| } |
| else |
| { |
| if( gphNxpExtns_Context.CallBackMifare != NULL ) |
| { |
| if( (gphNxpExtns_Context.incrdecstatusflag == true) && status == 0xB2 ) |
| { |
| gphNxpExtns_Context.incrdecstatusflag = false; |
| status = NFCSTATUS_SUCCESS; |
| } |
| gphNxpExtns_Context.CallBackMifare(gphNxpExtns_Context.CallBackCtxt, status); |
| } |
| } |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNciNfc_MfCreateXchgDataHdr |
| ** |
| ** Description This function builds the payload header for mifare XchgData |
| ** request to be sent to NFCC. |
| ** |
| ** Returns NFCSTATUS_PENDING - Command framing done |
| ** NFCSTATUS_FAILED - Otherwise |
| ** |
| *******************************************************************************/ |
| STATIC |
| NFCSTATUS |
| phNciNfc_MfCreateXchgDataHdr(phNciNfc_TransceiveInfo_t tTranscvInfo, |
| uint8_t *buff, uint16_t *buffSz) |
| |
| { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| uint8_t i = 0; |
| |
| buff[i++] = phNciNfc_e_MfRawDataXchgHdr; |
| memcpy(&buff[i],tTranscvInfo.tSendData.pBuff,tTranscvInfo.tSendData.wLen); |
| *buffSz = i + tTranscvInfo.tSendData.wLen; |
| |
| status = nativeNfcExtns_doTransceive(buff, (uint16_t) *buffSz); |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNciNfc_MfCreateAuthCmdHdr |
| ** |
| ** Description This function builds the payload header for mifare |
| ** classic Authenticate command to be sent to NFCC. |
| ** |
| ** Returns NFCSTATUS_PENDING - Command framing done |
| ** NFCSTATUS_FAILED - Otherwise |
| ** |
| *******************************************************************************/ |
| STATIC |
| NFCSTATUS |
| phNciNfc_MfCreateAuthCmdHdr(phNciNfc_TransceiveInfo_t tTranscvInfo, |
| uint8_t bBlockAddr, |
| uint8_t *buff, |
| uint16_t *buffSz) |
| { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| // pphNciNfc_RemoteDevInformation_t pActivDev = NULL; /*commented to eliminate unused variable warning*/ |
| uint8_t bKey = 0x00; |
| |
| /*No need to check range of block address*/ |
| /*To check for Authenticate A or Authenticate B type command*/ |
| if(PHNCINFC_AUTHENTICATION_KEYB == |
| tTranscvInfo.tSendData.pBuff[0] ) |
| { |
| bKey = bKey | PHNCINFC_ENABLE_KEY_B; |
| } |
| |
| /*TO Do last 4 bits of Key to be set based of firmware implementation*/ |
| /*this value is hardcoded but based on firmware implementation change this value*/ |
| bKey = (bKey | PHNCINFC_AUTHENTICATION_KEY); |
| |
| bKey |= tTranscvInfo.tSendData.pBuff[2]; |
| |
| /*For authentication extension no need to copy tSendData buffer of tTranscvInfo */ |
| tTranscvInfo.tSendData.wLen = 0x00; |
| |
| buff[0] = phNciNfc_e_MfcAuthReq; |
| buff[1] = bBlockAddr; |
| buff[2] = bKey; |
| |
| *buffSz = 0x03; |
| if (bKey & PH_NCINFC_MIFARECLASSIC_EMBEDDED_KEY) |
| { |
| memcpy(&buff[3],&tTranscvInfo.tSendData.pBuff[3], PHLIBNFC_MFC_AUTHKEYLEN); |
| *buffSz += PHLIBNFC_MFC_AUTHKEYLEN; |
| } |
| /* Store the auth command buffer to use further for presence check */ |
| if (gAuthCmdBuf.pauth_cmd != NULL) |
| { |
| memset(gAuthCmdBuf.pauth_cmd->buffer, 0, NCI_MAX_DATA_LEN); |
| gAuthCmdBuf.pauth_cmd->length = *buffSz; |
| memcpy(gAuthCmdBuf.pauth_cmd->buffer, buff, *buffSz); |
| } |
| status = nativeNfcExtns_doTransceive(buff,(uint16_t) *buffSz); |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phNciNfc_SendMfReq |
| ** |
| ** Description This function shall be invoked as part of ReaderMgmt data |
| ** exchange sequence handler. |
| ** It shall send the request packet to NFCC. |
| ** |
| ** Returns NFCSTATUS_PENDING - Send request is Pending |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS |
| phNciNfc_SendMfReq(phNciNfc_TransceiveInfo_t tTranscvInfo, uint8_t *buff, uint16_t *buffSz) |
| { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| |
| switch(tTranscvInfo.uCmd.T2TCmd) |
| { |
| case phNciNfc_eT2TRaw: |
| { |
| status = phNciNfc_MfCreateXchgDataHdr(tTranscvInfo, buff, buffSz); |
| } |
| break; |
| case phNciNfc_eT2TAuth: |
| { |
| status = phNciNfc_MfCreateAuthCmdHdr(tTranscvInfo, |
| (tTranscvInfo.bAddr), buff, buffSz); |
| } |
| break; |
| default: |
| { |
| status = NFCSTATUS_FAILED; |
| break; |
| } |
| } |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_CalSectorAddress |
| ** |
| ** Description This function update the sector address for Mifare classic |
| ** |
| ** Returns none |
| ** |
| *******************************************************************************/ |
| STATIC void phLibNfc_CalSectorAddress(uint8_t *Sector_Address) |
| { |
| uint8_t BlockNumber = 0x00; |
| |
| if(NULL != Sector_Address) |
| { |
| BlockNumber = *Sector_Address; |
| if(BlockNumber >= PHLIBNFC_MIFARESTD4K_BLK128) |
| { |
| *Sector_Address = (uint8_t)(PHLIBNFC_MIFARESTD_SECTOR_NO32 + |
| ((BlockNumber - PHLIBNFC_MIFARESTD4K_BLK128)/ |
| PHLIBNFC_MIFARESTD_BLOCK_BYTES)); |
| } |
| else |
| { |
| *Sector_Address = BlockNumber/PHLIBNFC_NO_OF_BLKPERSECTOR; |
| } |
| } |
| else |
| { |
| } |
| |
| return; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_GetKeyNumberMFC |
| ** |
| ** Description This function find key number based on authentication command |
| ** |
| ** Returns NFCSTATUS_SUCCESS - If found the key number |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_GetKeyNumberMFC(uint8_t *buffer,uint8_t *bKey) |
| { |
| int32_t sdwStat = 0X00; |
| NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER; |
| |
| /*Key Configuration |
| uint8_t NdefKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xD3,0XF7,0xD3,0XF7,0xD3,0XF7}; |
| uint8_t RawKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xFF,0XFF,0xFF,0XFF,0xFF,0XFF}; |
| uint8_t MadKey[PHLIBNFC_MFC_AUTHKEYLEN] = {0xA0,0XA1,0xA2,0XA3,0xA4,0XA5}; |
| uint8_t Key[PHLIBNFC_MFC_AUTHKEYLEN] = {0x00,0x00,0x00,0x00,0x00,0x00}; */ /*Key used during ndef format*/ |
| |
| uint8_t bIndex = 0x00; |
| uint8_t bNoOfKeys = 0x00; |
| |
| #if PHLIBNFC_NXPETENSION_CONFIGURE_MFKEYS |
| uint8_t aMfc_keys[NXP_NUMBER_OF_MFC_KEYS][NXP_MFC_KEY_SIZE] = NXP_MFC_KEYS; |
| #else |
| uint8_t aMfc_keys[1][1] = {{0x00}}; |
| #endif |
| |
| if(NULL != bKey && |
| NULL != buffer ) |
| { |
| bNoOfKeys = sizeof(aMfc_keys)/NXP_MFC_KEY_SIZE; |
| /* Traverse through the keys stored to determine whether keys is preloaded key */ |
| for(bIndex = 0; bIndex < bNoOfKeys; bIndex++) |
| { |
| /* Check passed key is NDEF key */ |
| sdwStat = memcmp(&buffer[PHLIBNFC_MFCUIDLEN_INAUTHCMD], |
| aMfc_keys[bIndex], PHLIBNFC_MFC_AUTHKEYLEN); |
| if(!sdwStat) |
| { |
| NXPLOG_EXTNS_E("Mifare : phLibNfc_GetKeyNumberMFC Key found"); |
| *bKey = bIndex; |
| wStatus = NFCSTATUS_SUCCESS; |
| break; |
| } |
| } |
| NXPLOG_EXTNS_E("Mifare : phLibNfc_GetKeyNumberMFC returning = 0x%x Key = 0x%x", wStatus, *bKey); |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| NXPLOG_EXTNS_E("Mifare : phLibNfc_GetKeyNumberMFC returning = 0x%x", wStatus); |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_ChkAuthCmdMFC |
| ** |
| ** Description This function Check Authentication command send is proper or not |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Authenticate command is proper |
| ** NFCSTATUS_FAILED - otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_ChkAuthCmdMFC(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| uint8_t *bKey) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| |
| if(NULL != pTransceiveInfo && |
| NULL != pTransceiveInfo->sSendData.buffer && |
| 0 != pTransceiveInfo->sSendData.length && |
| NULL != bKey) |
| { |
| if((pTransceiveInfo->cmd.MfCmd == phNfc_eMifareAuthentA || |
| pTransceiveInfo->cmd.MfCmd == phNfc_eMifareAuthentB )) |
| { |
| wStatus = phLibNfc_GetKeyNumberMFC(pTransceiveInfo->sSendData.buffer,bKey); |
| } |
| else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| } |
| }else |
| { |
| wStatus = NFCSTATUS_FAILED; |
| } |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_MifareMap |
| ** |
| ** Description Mifare Mapping Utility function |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Mapping is proper |
| ** NFCSTATUS_INVALID_PARAMETER - otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_MifareMap(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf) |
| { |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| uint8_t bBuffIdx = 0; |
| uint8_t bSectorNumber; |
| uint8_t bKey = 0; |
| |
| switch(pTransceiveInfo->cmd.MfCmd) |
| { |
| case phNfc_eMifareRead16: |
| { |
| if( (NULL != pTransceiveInfo->sRecvData.buffer) && |
| (0 != (pTransceiveInfo->sRecvData.length))) |
| { |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareRead16; |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr; |
| pMappedTranscvIf->tSendData.wLen = bBuffIdx; |
| pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; |
| } |
| else |
| { |
| status = NFCSTATUS_INVALID_PARAMETER; |
| } |
| } |
| break; |
| |
| case phNfc_eMifareWrite16: |
| { |
| if( (NULL != pTransceiveInfo->sSendData.buffer) && |
| (0 != (pTransceiveInfo->sSendData.length))) |
| { |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareWrite16; |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr; |
| memcpy(&(pMappedTranscvIf->tSendData.pBuff[bBuffIdx]),pTransceiveInfo->sSendData.buffer, |
| (pTransceiveInfo->sSendData.length)); |
| pMappedTranscvIf->tSendData.wLen = bBuffIdx + pTransceiveInfo->sSendData.length; |
| pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; |
| } |
| else |
| { |
| status = NFCSTATUS_INVALID_PARAMETER; |
| } |
| } |
| break; |
| |
| case phNfc_eMifareAuthentA: |
| case phNfc_eMifareAuthentB: |
| { |
| if( (NULL != pTransceiveInfo->sSendData.buffer) && |
| (0 != (pTransceiveInfo->sSendData.length)) && |
| (NULL != pTransceiveInfo->sRecvData.buffer) && |
| (0 != (pTransceiveInfo->sRecvData.length)) |
| ) |
| { |
| status = phLibNfc_ChkAuthCmdMFC(pTransceiveInfo, &bKey); |
| if(NFCSTATUS_FAILED != status ) |
| { |
| bSectorNumber = pTransceiveInfo->addr; |
| phLibNfc_CalSectorAddress(&bSectorNumber); |
| /*For creating extension command header pTransceiveInfo's MfCmd get used*/ |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->cmd.MfCmd; |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bSectorNumber; |
| pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TAuth; |
| pMappedTranscvIf->bAddr = bSectorNumber; |
| pMappedTranscvIf->bNumBlock = pTransceiveInfo->NumBlock; |
| if(NFCSTATUS_SUCCESS == status) |
| { |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bKey; |
| (pMappedTranscvIf->tSendData.wLen) = (uint16_t)(bBuffIdx); |
| |
| } |
| else if(NFCSTATUS_INVALID_PARAMETER == status) |
| { |
| bKey = bKey | PH_NCINFC_MIFARECLASSIC_EMBEDDED_KEY; |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = bKey; |
| memcpy(&pMappedTranscvIf->tSendData.pBuff[bBuffIdx], |
| &pTransceiveInfo->sSendData.buffer[PHLIBNFC_MFCUIDLEN_INAUTHCMD], PHLIBNFC_MFC_AUTHKEYLEN); |
| |
| (pMappedTranscvIf->tSendData.wLen) = (uint16_t)(bBuffIdx + PHLIBNFC_MFC_AUTHKEYLEN); |
| status = NFCSTATUS_SUCCESS; |
| } |
| else |
| { |
| /* do nothing */ |
| } |
| } |
| } |
| else |
| { |
| status = NFCSTATUS_INVALID_PARAMETER; |
| } |
| } |
| break; |
| |
| case phNfc_eMifareRaw: |
| { |
| |
| } |
| break; |
| |
| default: |
| { |
| status = NFCSTATUS_INVALID_PARAMETER; |
| break; |
| } |
| } |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_MapCmds |
| ** |
| ** Description This function maps the command request from libnfc level to nci level |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Mapping of command is successful |
| ** NFCSTATUS_INVALID_PARAMETER - One or more of the supplied |
| ** parameters could not be interpreted properly |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_MapCmds(phNciNfc_RFDevType_t RemDevType, |
| phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf) |
| { |
| |
| NFCSTATUS status = NFCSTATUS_SUCCESS; |
| |
| if((NULL == pTransceiveInfo) || (NULL == pMappedTranscvIf)) |
| { |
| return NFCSTATUS_FAILED; |
| } |
| switch(RemDevType) |
| { |
| case phNciNfc_eMifare1k_PICC: |
| case phNciNfc_eMifare4k_PICC: |
| { |
| status = phLibNfc_MifareMap(pTransceiveInfo,pMappedTranscvIf); |
| break; |
| } |
| default: |
| { |
| break; |
| } |
| } |
| |
| return status; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_SendAuthCmd |
| ** |
| ** Description This function Send authentication command to NFCC |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Parameters are proper |
| ** NFCSTATUS_INVALID_PARAMETER - Otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_SendAuthCmd(phNfc_sTransceiveInfo_t *pTransceiveInfo, |
| phNciNfc_TransceiveInfo_t *tNciTranscvInfo) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| |
| wStatus = phLibNfc_MapCmds(phNciNfc_eMifare1k_PICC, pTransceiveInfo, tNciTranscvInfo); |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_SendWrt16Cmd |
| ** |
| ** Description This function maps Mifarewirte16 commands |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Parameters are mapped |
| ** NFCSTATUS_INVALID_PARAMETER - Otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_SendWrt16Cmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| uint8_t bBuffIdx = 0x00; |
| |
| if( (NULL != pTransceiveInfo->sSendData.buffer) && |
| (0 != (pTransceiveInfo->sSendData.length))) |
| { |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = phNfc_eMifareWrite16; |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr; |
| pMappedTranscvIf->tSendData.wLen = bBuffIdx; |
| pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; |
| } |
| else |
| { |
| wStatus = NFCSTATUS_INVALID_PARAMETER; |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_SendIncDecCmd |
| ** |
| ** Description This function prepares the Increment/Decrement command |
| ** to be sent, increment/decrement value is sent separately |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Params are mapped |
| ** NFCSTATUS_INVALID_PARAMETER - Otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_SendIncDecCmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf, |
| uint8_t IncDecCmd) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| uint8_t bBuffIdx = 0x00; |
| |
| if( (NULL != pTransceiveInfo->sSendData.buffer) && |
| (0 != (pTransceiveInfo->sSendData.length))) |
| { |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = IncDecCmd; |
| pMappedTranscvIf->tSendData.pBuff[bBuffIdx++] = pTransceiveInfo->addr; |
| pMappedTranscvIf->tSendData.wLen = bBuffIdx; |
| pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; |
| } |
| else |
| { |
| wStatus = NFCSTATUS_INVALID_PARAMETER; |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phLibNfc_SendRawCmd |
| ** |
| ** Description This function maps Mifare raw command |
| ** |
| ** Returns NFCSTATUS_SUCCESS - Parameters are mapped |
| ** NFCSTATUS_INVALID_PARAMETER - Otherwise |
| ** |
| *******************************************************************************/ |
| STATIC NFCSTATUS phLibNfc_SendRawCmd(phNfc_sTransceiveInfo_t* pTransceiveInfo, |
| pphNciNfc_TransceiveInfo_t pMappedTranscvIf) |
| { |
| NFCSTATUS wStatus = NFCSTATUS_SUCCESS; |
| // uint8_t bBuffIdx = 0x00; /*commented to eliminate unused variable warning*/ |
| |
| if( (NULL != pTransceiveInfo->sSendData.buffer) && |
| (0 != (pTransceiveInfo->sSendData.length))) |
| { |
| memcpy(pMappedTranscvIf->tSendData.pBuff, pTransceiveInfo->sSendData.buffer, |
| (pTransceiveInfo->sSendData.length)); |
| pMappedTranscvIf->tSendData.wLen = pTransceiveInfo->sSendData.length; |
| pMappedTranscvIf->uCmd.T2TCmd = phNciNfc_eT2TRaw; |
| } |
| else |
| { |
| wStatus = NFCSTATUS_INVALID_PARAMETER; |
| } |
| |
| return wStatus; |
| } |
| |
| /******************************************************************************* |
| ** |
| ** Function phFriNfc_ExtnsTransceive |
| ** |
| ** Description This function maps Mifare raw command and send it to NFCC |
| ** |
| ** Returns NFCSTATUS_PENDING - Operation successful |
| ** NFCSTATUS_INVALID_PARAMETER - Otherwise |
| ** |
| *******************************************************************************/ |
| NFCSTATUS phFriNfc_ExtnsTransceive(phNfc_sTransceiveInfo_t *pTransceiveInfo, |
| phNfc_uCmdList_t Cmd, |
| uint8_t *SendRecvBuf, |
| uint16_t SendLength, |
| uint16_t *SendRecvLength) |
| { |
| (void)SendRecvLength; |
| NFCSTATUS status = NFCSTATUS_FAILED; |
| uint8_t *buff=NULL; |
| uint16_t buffSz=0; |
| uint8_t i = 0; |
| uint32_t length = SendLength; |
| uint8_t restore_payload[]={0x00, 0x00, 0x00, 0x00,}; |
| |
| if( SendLength == 0 ) |
| { |
| android_errorWriteLog(0x534e4554, "132083376"); |
| return status; |
| } |
| |
| buff = (uint8_t *)malloc((uint32_t)MAX_BUFF_SIZE); |
| if( NULL == buff ) |
| { |
| return status; |
| } |
| |
| pTransceiveInfo->cmd = Cmd; |
| |
| if( (Cmd.MfCmd == phNfc_eMifareAuthentA) || |
| (Cmd.MfCmd == phNfc_eMifareAuthentB) ) |
| { |
| pTransceiveInfo->addr = SendRecvBuf[i++]; |
| pTransceiveInfo->sSendData.buffer[4] = SendRecvBuf[i++]; |
| pTransceiveInfo->sSendData.buffer[5] = SendRecvBuf[i++]; |
| pTransceiveInfo->sSendData.buffer[6] = SendRecvBuf[i++]; |
| pTransceiveInfo->sSendData.buffer[7] = SendRecvBuf[i++]; |
| pTransceiveInfo->sSendData.buffer[8] = SendRecvBuf[i++]; |
| pTransceiveInfo->sSendData.buffer[9] = SendRecvBuf[i++]; |
| |
| pTransceiveInfo->cmd.MfCmd = Cmd.MfCmd; |
| |
| pTransceiveInfo->sSendData.length = length; |
| pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; |
| status = phLibNfc_MifareMap(pTransceiveInfo, &tNciTranscvInfo); |
| } |
| else if( Cmd.MfCmd == phNfc_eMifareWrite16 ) |
| { |
| pTransceiveInfo->addr = SendRecvBuf[i++]; |
| length = SendLength - i; |
| memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length); |
| pTransceiveInfo->sSendData.length = length; |
| pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; |
| |
| gphNxpExtns_Context.writecmdFlag = true; |
| |
| status = phLibNfc_SendWrt16Cmd(pTransceiveInfo, &tNciTranscvInfo); |
| } |
| else if( (Cmd.MfCmd == phNfc_eMifareInc) || (Cmd.MfCmd == phNfc_eMifareDec) ) |
| { |
| pTransceiveInfo->addr = SendRecvBuf[i++]; |
| length = SendLength - i; |
| memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length); |
| pTransceiveInfo->sSendData.length = length; |
| pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; |
| |
| gphNxpExtns_Context.incrdecflag = true; |
| |
| status = phLibNfc_SendIncDecCmd(pTransceiveInfo, &tNciTranscvInfo, Cmd.MfCmd); |
| |
| } |
| else if(Cmd.MfCmd == phNfc_eMifareRestore) |
| { |
| pTransceiveInfo->addr = SendRecvBuf[i++]; |
| length = SendLength - i; |
| memcpy(pTransceiveInfo->sSendData.buffer, &restore_payload[0], sizeof(restore_payload)); |
| pTransceiveInfo->sSendData.length = length + sizeof(restore_payload); |
| pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; |
| |
| gphNxpExtns_Context.incrdecflag = true; |
| |
| status = phLibNfc_SendIncDecCmd(pTransceiveInfo, &tNciTranscvInfo, Cmd.MfCmd); |
| |
| } |
| else if ((Cmd.MfCmd == phNfc_eMifareRaw) || (Cmd.MfCmd == phNfc_eMifareTransfer )) |
| { |
| pTransceiveInfo->cmd.MfCmd = (phNfc_eMifareCmdList_t) phNciNfc_eT2TRaw; |
| memcpy(pTransceiveInfo->sSendData.buffer, SendRecvBuf, length); |
| pTransceiveInfo->sSendData.length = length; |
| pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; |
| status = phLibNfc_SendRawCmd(pTransceiveInfo, &tNciTranscvInfo); |
| } |
| else |
| { |
| pTransceiveInfo->addr = SendRecvBuf[i++]; |
| length = SendLength - i; |
| memcpy(pTransceiveInfo->sSendData.buffer, &SendRecvBuf[i], length); |
| pTransceiveInfo->sSendData.length = length; |
| pTransceiveInfo->sRecvData.length = MAX_BUFF_SIZE; |
| status = phLibNfc_MifareMap(pTransceiveInfo, &tNciTranscvInfo); |
| } |
| |
| if (NFCSTATUS_SUCCESS == status ) |
| { |
| status = phNciNfc_SendMfReq(tNciTranscvInfo, buff, &buffSz); |
| if (NFCSTATUS_PENDING != status) |
| { |
| NXPLOG_EXTNS_E("ERROR : phNciNfc_SendMfReq()"); |
| } |
| } |
| else |
| { |
| NXPLOG_EXTNS_E (" ERROR : Sending phNciNfc_SendMfReq"); |
| } |
| if( buff != NULL ) |
| { |
| free(buff); |
| buff = NULL; |
| } |
| |
| return status; |
| } |