blob: a7918d8eb260e676917381ce4ecc3cb671b3b105 [file] [log] [blame]
/*
*
* Copyright 2016-2018,2020 NXP
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @par Description
* This file implements the SmCom T1oI2C communication layer.
*
*****************************************************************************/
#ifdef T1oI2C
#include <assert.h>
#include "smComT1oI2C.h"
#include "phNxpEse_Api.h"
#include "phNxpEseProto7816_3.h"
#include "i2c_a7.h"
#include "sm_printf.h"
#include "phEseStatus.h"
#include "sm_apdu.h"
#ifdef FLOW_VERBOSE
#define NX_LOG_ENABLE_SMCOM_DEBUG 1
#else
//#define NX_LOG_ENABLE_SMCOM_DEBUG 1
#endif
#include "nxLog_smCom.h"
#include "nxEnsure.h"
static U32 smComT1oI2C_Transceive(void* conn_ctx, apdu_t * pApdu);
static U32 smComT1oI2C_TransceiveRaw(void* conn_ctx, U8 * pTx, U16 txLen, U8 * pRx, U32 * pRxLen);
U16 smComT1oI2C_AnswerToReset(void* conn_ctx, U8 *T1oI2Catr, U16 *T1oI2CatrLen);
U16 smComT1oI2C_Close(void *conn_ctx, U8 mode)
{
ESESTATUS status;
if (conn_ctx) {
status=phNxpEse_EndOfApdu(conn_ctx);
//status=phNxpEse_chipReset();
if(status ==ESESTATUS_SUCCESS)
{
status=phNxpEse_close(conn_ctx);
}
else
{
LOG_E("Failed to close session ");
return SMCOM_COM_FAILED;
}
}
else {
LOG_W("Invalid conn_ctx");
}
return SMCOM_OK;
}
U16 smComT1oI2C_Init(void **conn_ctx, const char *pConnString)
{
ESESTATUS ret;
phNxpEse_initParams initParams;
initParams.initMode = ESE_MODE_NORMAL;
if(conn_ctx != NULL) {
*conn_ctx = NULL;
}
ret = phNxpEse_open(conn_ctx, initParams, pConnString);
if (ret != ESESTATUS_SUCCESS)
{
LOG_E(" Failed to create physical connection with ESE ");
return SMCOM_COM_FAILED;
}
return SMCOM_OK;
}
U16 smComT1oI2C_Open(void *conn_ctx, U8 mode, U8 seqCnt, U8 *T1oI2Catr, U16 *T1oI2CatrLen)
{
ESESTATUS ret;
phNxpEse_data AtrRsp;
phNxpEse_initParams initParams;
initParams.initMode = ESE_MODE_NORMAL;
AtrRsp.len = *T1oI2CatrLen;
AtrRsp.p_data = T1oI2Catr;
if (conn_ctx == NULL) {
// Connection context is stored in global variable contained in phNxpEse_Api.c
smComT1oI2C_Init(NULL, NULL);
}
ret=phNxpEse_init(conn_ctx, initParams, &AtrRsp);
if (ret != ESESTATUS_SUCCESS)
{
*T1oI2CatrLen=0;
LOG_E(" Failed to Open session ");
return SMCOM_COM_FAILED;
}
else
{
*T1oI2CatrLen = AtrRsp.len ; /*Retrive INF FIELD*/
}
return smCom_Init(&smComT1oI2C_Transceive, &smComT1oI2C_TransceiveRaw);
}
static U32 smComT1oI2C_Transceive(void* conn_ctx, apdu_t * pApdu)
{
U32 respLen= MAX_APDU_BUF_LENGTH;
U32 retCode = SMCOM_COM_FAILED;
ENSURE_OR_GO_EXIT(pApdu != NULL);
retCode = smComT1oI2C_TransceiveRaw(conn_ctx, (U8 *)pApdu->pBuf, pApdu->buflen, pApdu->pBuf, &respLen);
pApdu->rxlen = (U16)respLen;
exit:
return retCode;
}
static U32 smComT1oI2C_TransceiveRaw(void* conn_ctx, U8 * pTx, U16 txLen, U8 * pRx, U32 * pRxLen)
{
phNxpEse_data pCmdTrans;
phNxpEse_data pRspTrans={0};
ESESTATUS txnStatus;
pCmdTrans.len = txLen;
pCmdTrans.p_data = pTx;
pRspTrans.len = *pRxLen;
pRspTrans.p_data = pRx;
LOG_MAU8_D("APDU Tx>", pTx, txLen);
txnStatus = phNxpEse_Transceive(conn_ctx, &pCmdTrans, &pRspTrans);
if ( txnStatus == ESESTATUS_SUCCESS )
{
*pRxLen = pRspTrans.len;
LOG_MAU8_D("APDU Rx<", pRx, pRspTrans.len);
}
else
{
*pRxLen = 0;
LOG_E(" Transcive Failed ");
return SMCOM_SND_FAILED;
}
return SMCOM_OK;
}
U16 smComT1oI2C_AnswerToReset(void* conn_ctx, U8 *T1oI2Catr, U16 *T1oI2CatrLen)
{
phNxpEse_data pRsp= {0};
ESESTATUS txnStatus;
U16 status = SMCOM_NO_ATR;
ENSURE_OR_GO_EXIT(T1oI2Catr != NULL);
ENSURE_OR_GO_EXIT(T1oI2CatrLen != NULL);
#if defined(T1oI2C_UM11225)
txnStatus= phNxpEse_getAtr(conn_ctx, &pRsp);
#elif defined(T1oI2C_GP1_0)
txnStatus= phNxpEse_getCip(conn_ctx, &pRsp);
#endif
if(txnStatus == ESESTATUS_SUCCESS)
{
*T1oI2CatrLen = pRsp.len;
if (pRsp.len > 0) {
memcpy(T1oI2Catr, pRsp.p_data, pRsp.len);
status = SMCOM_OK;
}
else {
LOG_E(" ATR/CIP Length is improper!!!");
}
}
else
{
*T1oI2CatrLen = 0;
LOG_E(" Failed to Retrieve ATR/CIP status ");
}
exit:
return status;
}
U16 smComT1oI2C_ComReset(void* conn_ctx)
{
ESESTATUS status = ESESTATUS_SUCCESS;
status = phNxpEse_deInit(conn_ctx);
if(status !=ESESTATUS_SUCCESS)
{
LOG_E("Failed to Reset 7816 protocol instance ");
return SMCOM_COM_FAILED;
}
return SMCOM_OK;
}
#endif /* T1oI2C */