/* Copyright 2020 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include <stdio.h> #include "smComNxpNfcRdLib.h" #include "nxLog_smCom.h" #include "nxEnsure.h" /* ------------------------------------------------------------------------- */ NPNxpNfcRdLibCtx_t gsmComRdLibCtx; static phStatus_t AppMain(const char *com_port, const char *front_end); static phStatus_t np_TypeA_Init(NPNxpNfcRdLibCtx_t *pRdCtx); static phStatus_t np_TypeA_Demo(NPNxpNfcRdLibCtx_t *pRdCtx); U32 smComNxpNfcRdLib_Transceive(void* conn_ctx, apdu_t *pApdu); U32 smComNxpNfcRdLib_TransceiveRaw(void* conn_ctx, U8 *pTx, U16 txLen, U8 *pRx, U32 *pRxLen); /** TODO */ U16 smComNxpNfcRdLib_OpenVCOM(void **conn_ctx, const char * vPortName) { phStatus_t ret = AppMain(vPortName, "RC663"); if (ret == PH_ERR_SUCCESS) { smCom_Init(&smComNxpNfcRdLib_Transceive, &smComNxpNfcRdLib_TransceiveRaw); } return (U16)ret; } void smComNxpNfcRdLib_Close(void) { phbalReg_ClosePort(gsmComRdLibCtx.pBal); } U32 smComNxpNfcRdLib_Transceive(void* conn_ctx, apdu_t *pApdu) { U32 respLen = 256; U32 retCode = SMCOM_COM_FAILED; ENSURE_OR_GO_EXIT(pApdu != NULL); retCode = smComNxpNfcRdLib_TransceiveRaw(conn_ctx, (U8 *)pApdu->pBuf, pApdu->buflen, pApdu->pBuf, &respLen); pApdu->rxlen = (U16)respLen; exit: return retCode; } U32 smComNxpNfcRdLib_TransceiveRaw(void * conn_ctx, U8 *pTx, U16 txLen, U8 *pRx, U32 *pRxLen) { uint16_t u16RxLen = 0; //*pRxLen; phStatus_t status; uint8_t *ppRx = NULL; LOG_MAU8_I("L4 Command:", pTx, txLen); status = phpalI14443p4_Exchange(&gsmComRdLibCtx.sType4Pal, PH_EXCHANGE_DEFAULT, pTx, txLen, &ppRx, &u16RxLen); if (status == PH_ERR_SUCCESS) { *pRxLen = u16RxLen; memcpy(pRx, ppRx, u16RxLen); LOG_MAU8_I("L4 Reponse:", pRx, u16RxLen); return SMCOM_OK; } else { LOG_W("TX Failed with status %04X", status); return SMCOM_SND_FAILED; } } static phStatus_t AppMain(const char *com_port, const char *front_end) { phStatus_t status = PH_ERR_SUCCESS; PH_CHECK_SUCCESS_FCT(status, np_NxpNfcRdLib_CheckComPortName(com_port, &gsmComRdLibCtx.sBalCtx)); PH_CHECK_SUCCESS_FCT(status, np_NxpNfcRdLib_CheckFrontEndName(front_end, &gsmComRdLibCtx)); PH_CHECK_SUCCESS_FCT(status, np_NxpNfcRdLib_Init(&gsmComRdLibCtx)); PH_CHECK_SUCCESS_FCT(status, np_TypeA_Init(&gsmComRdLibCtx)); //// Example Starts ///// { int count = 0; LOG_I("Performing filed on-off.\n"); while (count++ < 2) { PH_CHECK_SUCCESS_FCT(status, phhalHw_FieldOn(gsmComRdLibCtx.pHal)); Sleep(50); PH_CHECK_SUCCESS_FCT(status, phhalHw_FieldOff(gsmComRdLibCtx.pHal)); Sleep(100); } status = np_TypeA_Demo(&gsmComRdLibCtx); } //// Example Ends ///// return status; } static phStatus_t np_TypeA_Init(NPNxpNfcRdLibCtx_t *pRdCtx) { phStatus_t status; PH_CHECK_SUCCESS_FCT(status, phpalI14443p3a_Sw_Init(&pRdCtx->sType3APal, sizeof(pRdCtx->sType3APal), pRdCtx->pHal)); PH_CHECK_SUCCESS_FCT(status, phpalI14443p4a_Sw_Init(&pRdCtx->sType4APal, sizeof(pRdCtx->sType4APal), pRdCtx->pHal)); PH_CHECK_SUCCESS_FCT(status, phpalI14443p4_Sw_Init(&pRdCtx->sType4Pal, sizeof(pRdCtx->sType4Pal), pRdCtx->pHal)); return status; } phStatus_t np_TypeA_Demo(NPNxpNfcRdLibCtx_t *pRdCtx) { phStatus_t status = PH_ERR_CUSTOM_BEGIN; uint8_t aUid[10] = {0}; uint8_t uidLen = 0; uint8_t bSak; uint8_t bMoreCardsAvailable; int retryCount = 1000; while (status != PH_ERR_SUCCESS && retryCount-- >= 0) { PH_CHECK_SUCCESS_FCT(status, phhalHw_FieldReset(pRdCtx->pHal)); status = phpalI14443p3a_ActivateCard(&pRdCtx->sType3APal, NULL, 0, aUid, &uidLen, &bSak, &bMoreCardsAvailable); if (status != PH_ERR_SUCCESS) { printf("%c\r", "/-\\+"[retryCount % 4]); } } if (status != PH_ERR_SUCCESS) { LOG_E("Could not detect any TYPE A Card.\n"); return status; } LOG_MAU8_I("UID after L3 Activation", aUid, sizeof(aUid)); if (bSak == 0x20 || bSak == 0x28) // DESFIre { uint8_t pAts[256] = {0}; uint8_t PH_MEMLOC_REM bCidEnabled; uint8_t PH_MEMLOC_REM bCid; uint8_t PH_MEMLOC_REM bNadSupported; uint8_t PH_MEMLOC_REM bFwi; uint8_t PH_MEMLOC_REM bFsdi; uint8_t PH_MEMLOC_REM bFsci; // activate till level 4 PH_CHECK_SUCCESS_FCT(status, phpalI14443p4a_ActivateCard(&pRdCtx->sType4APal, 0x08, 0, // CID = 0 (uint8_t)PHHAL_HW_RF_DATARATE_106, (uint8_t)PHHAL_HW_RF_DATARATE_106, pAts)); LOG_MAU8_I("ATS after L4 Activation", pAts, pAts[0]); PH_CHECK_SUCCESS_FCT(status, phpalI14443p4a_GetProtocolParams( &pRdCtx->sType4APal, &bCidEnabled, &bCid, &bNadSupported, &bFwi, &bFsdi, &bFsci)); PH_CHECK_SUCCESS_FCT(status, phpalI14443p4_SetProtocol( &pRdCtx->sType4Pal, bCidEnabled, bCid, bNadSupported, pRdCtx->sType4Pal.bNad, bFwi, bFsdi, bFsci)); } else if (bSak == 0x00) // Mifare Ultralight { status = PH_ERR_UNSUPPORTED_COMMAND; LOG_W("Do not support SAK==0"); } else { LOG_E("SAK=0x%02X is not processed by this example", bSak); status = PH_ERR_UNSUPPORTED_COMMAND; } return status; }