blob: 9f04c18bad01c76859b90333ae249d5dbd95f749 [file] [log] [blame]
/*
* 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.
*/
#include <android-base/stringprintf.h>
#include <base/logging.h>
#include <log/log.h>
#include <nfc_api.h>
#include <nfc_int.h>
#include <phNfcCompId.h>
#include <phNxpExtns_MifareStd.h>
#include <phNxpLog.h>
#include <rw_api.h>
using android::base::StringPrintf;
extern bool nfc_debug_enabled;
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 = (phFriNfc_NdefMap_t*)malloc(sizeof(phFriNfc_NdefMap_t));
if (NULL == NdefMap) {
goto clean_and_return;
}
memset(NdefMap, 0, sizeof(phFriNfc_NdefMap_t));
NdefMap->psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)malloc(
sizeof(phLibNfc_sRemoteDevInformation_t));
if (NULL == NdefMap->psRemoteDevInfo) {
goto clean_and_return;
}
memset(NdefMap->psRemoteDevInfo, 0, sizeof(phLibNfc_sRemoteDevInformation_t));
NdefMap->SendRecvBuf = (uint8_t*)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 = (uint16_t*)malloc(sizeof(uint16_t));
if (NULL == NdefMap->SendRecvLength) {
goto clean_and_return;
}
memset(NdefMap->SendRecvLength, 0, sizeof(uint16_t));
NdefMap->DataCount = (uint16_t*)malloc(sizeof(uint16_t));
if (NULL == NdefMap->DataCount) {
goto clean_and_return;
}
memset(NdefMap->DataCount, 0, sizeof(uint16_t));
NdefMap->pTransceiveInfo =
(phNfc_sTransceiveInfo_t*)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 =
(phFriNfc_sNdefSmtCrdFmt_t*)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 = (phNfc_sData_t*)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 = (phNfc_sData_t*)malloc(sizeof(phNfc_sData_t));
if (NULL == gAuthCmdBuf.pauth_cmd) {
goto clean_and_return;
}
gAuthCmdBuf.pauth_cmd->buffer = (uint8_t*)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) {
LOG(ERROR) << StringPrintf("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 = NFC_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) {
DLOG_IF(INFO, gLog_level.extns_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL)
<< StringPrintf("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;
LOG(ERROR) << StringPrintf("%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) {
DLOG_IF(INFO, gLog_level.extns_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL)
<< StringPrintf("%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++) {
DLOG_IF(INFO, nfc_debug_enabled)
<< StringPrintf("secrtkey[%d] = 0x%x", id, secrtkey[id]);
DLOG_IF(INFO, nfc_debug_enabled)
<< StringPrintf("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 = (uint8_t*)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;
}
DLOG_IF(INFO, gLog_level.extns_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL)
<< StringPrintf("%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) {
LOG(ERROR) << StringPrintf("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 */
{
LOG(ERROR) << StringPrintf("%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))) {
LOG(ERROR) << StringPrintf("%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;
if (len == 0) {
android_errorWriteLog(0x534e4554, "132082342");
return status;
}
gphNxpExtns_Context.RawWriteCallBack = false;
gphNxpExtns_Context.CallBackMifare = NULL;
gphNxpExtns_Context.CallBackCtxt = NdefMap;
EXTNS_SetCallBackFlag(true);
if (p_data[0] == 0x60 || p_data[0] == 0x61) {
if (len < 12) {
android_errorWriteLog(0x534e4554, "125900276");
return status;
}
NdefMap->Cmd.MfCmd = (phNfc_eMifareCmdList_t)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 = (phNfc_eMifareCmdList_t)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 = (phNfc_eMifareCmdList_t)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_eMifareCmdList_t)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 {
LOG(ERROR) << StringPrintf("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) {
LOG(ERROR) << StringPrintf("%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;
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: {
NFCSTATUS writeResponse = NFCSTATUS_SUCCESS;
/* check the status byte */
if (NFC_GetNCIVersion() == NCI_VERSION_2_0 &&
(NdefMap->State == PH_FRINFC_NDEFMAP_STATE_WR_TLV ||
NdefMap->State == PH_FRINFC_NDEFMAP_STATE_WRITE ||
NdefMap->State == PH_FRINFC_NDEFMAP_STATE_WR_NDEF_LEN ||
NdefMap->State == PH_FRINFC_NDEFMAP_STATE_INIT)) {
uint8_t rspAck = RspBuffInfo->pBuff[RspBuffInfo->wLen - 2];
uint8_t rspAckMask = ((RspBuffInfo->pBuff[RspBuffInfo->wLen - 1]) &
MAX_NUM_VALID_BITS_FOR_ACK);
NCI_CALCULATE_ACK(rspAck, rspAckMask);
writeResponse =
(rspAck == T2T_RSP_ACK) ? NFCSTATUS_SUCCESS : NFC_STATUS_FAILED;
} else {
writeResponse = RspBuffInfo->pBuff[RspBuffInfo->wLen - 1];
}
if (PH_NCINFC_STATUS_OK == writeResponse) {
status = NFCSTATUS_SUCCESS;
uint16_t wRecvDataSz = 0;
/* 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) {
DLOG_IF(INFO, nfc_debug_enabled)
<< StringPrintf("%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) {
LOG(ERROR) << StringPrintf("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) {
LOG(ERROR) << StringPrintf("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) {
LOG(ERROR) << StringPrintf(
"Mifare : phLibNfc_GetKeyNumberMFC Key found");
*bKey = bIndex;
wStatus = NFCSTATUS_SUCCESS;
break;
}
}
LOG(ERROR) << StringPrintf(
"Mifare : phLibNfc_GetKeyNumberMFC returning = 0x%x Key = 0x%x",
wStatus, *bKey);
} else {
wStatus = NFCSTATUS_FAILED;
LOG(ERROR) << StringPrintf(
"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) {
LOG(ERROR) << StringPrintf("ERROR : phNciNfc_SendMfReq()");
}
} else {
LOG(ERROR) << StringPrintf(" ERROR : Sending phNciNfc_SendMfReq");
}
if (buff != NULL) {
free(buff);
buff = NULL;
}
return status;
}