blob: ec064718d99a3bc0b578f8b89adb225c86cbc4b7 [file] [log] [blame]
/**
* @file smComSCI2c.c
* @author NXP Semiconductors
* @version 1.0
* @par License
*
* Copyright 2016,2020 NXP
* SPDX-License-Identifier: Apache-2.0
*
* @par Description
* This file implements the SmCom JRCP-V2 communication layer.
*
*****************************************************************************/
#include <assert.h>
#include <stdio.h>
#include "smComJRCP.h"
#include "sm_printf.h"
#include "sm_apdu.h"
#include <string.h>
#include "ex_sss_ports.h"
#ifdef FLOW_VERBOSE
# define NX_LOG_ENABLE_SMCOM_DEBUG 1
#endif
// #define NX_LOG_ENABLE_SMCOM_DEBUG 1
#include <nxLog_smCom.h>
#include "nxEnsure.h"
#if defined(SMCOM_JRCP_V2)
#include <jrcplib/networking/tcpclient.h>
static U32 smComJRCP_Transceive(void* conn_ctx, apdu_t * pApdu);
static U32 smComJRCP_TransceiveRaw(void* conn_ctx, U8 * pTx, U16 txLen, U8 * pRx, U32 * pRxLen);
static jrcplib_tcpclient_ctx_t* gctx = NULL;
U16 smComJRCP_Close(void* conn_ctx, U8 mode)
{
jrcplib_tcpclient_ctx_t* ctx = (conn_ctx == NULL) ? gctx : (jrcplib_tcpclient_ctx_t*)conn_ctx;
if (ctx != NULL)
{
if (gctx == ctx) {
gctx = NULL;
}
jrcplib_tcpclient_disconnect(ctx);
jrcplib_tcpclient_free(ctx);
ctx = NULL;
}
return SW_OK;
}
//
// smComSCI2C_Init is deprecated, please use smComSCI2C_Open
//
#ifndef TGT_A71CH
void smComJRCP_Init()
{
smCom_Init(&smComJRCP_Transceive, &smComJRCP_TransceiveRaw);
}
#endif
U16 smComJRCP_Open(void** conn_ctx, const char *hostname_in, unsigned int portnum_in)
{
int32_t ret = 0;
const char *hostname_env;
const char *hostname_selected;
char szHostname[70] = {0};
unsigned int portnum = 0;
const char *hostname_default = EX_SSS_BOOT_SSS_SOCKET_HOSTNAME_DEFAULT;
const unsigned int portnum_default = EX_SSS_BOOT_SSS_SOCKET_PORTNUMBER_DEFAULT;
jrcplib_tcpclient_ctx_t* ctx = NULL;
/* First priority Environment variable */
hostname_env = getenv("JRCP_HOSTNAME");
if (NULL == hostname_env) {
/* No ENV */
if (hostname_in == NULL) {
/* No value from CLI : use default */
hostname_selected = hostname_default;
LOG_I("Hostname taken from default '%s'. Set 'JRCP_HOSTNAME' to override.", hostname_default);
}
else {
/* Take from CLI */
hostname_selected = hostname_in;
}
}
else
{
strncpy(szHostname, hostname_env, sizeof(szHostname) - 1);
hostname_selected = szHostname;
}
/* First priority Environment variable */
const char *portnum_str_env = getenv("JRCP_PORT");
if (portnum_str_env != NULL) {
/* ENV has it, use that*/
portnum = strtol(portnum_str_env, NULL, 10);
}
if (0 == portnum) {
/* No ENV */
if (0 == portnum_in) {
/* CLI didn't have it, env didn't have it, use default*/
portnum = portnum_default;
LOG_I("Port number taken from default. Set 'JRCP_PORT' to override.");
}
else {
portnum = portnum_in;
}
}
LOG_I("Opening connection to JRCP server on %s:%d", hostname_selected, portnum);
ret = jrcplib_tcpclient_init(&ctx);
if (ret < 0) {
LOG_E("%s", jrcplib_get_error_string(ret));
smComJRCP_Close(ctx, 0);
return SMCOM_COM_FAILED;
}
ret = jrcplib_tcpclient_connect_to_default_node(ctx, hostname_selected, (uint16_t)portnum);
if (ret < 0) {
LOG_E("%s", jrcplib_get_error_string(ret));
smComJRCP_Close(ctx, 0);
return SMCOM_COM_FAILED;
}
uint32_t nodes_count;
jrcplib_nad_t *nodes = NULL;
ret = jrcplib_tcpclient_list_nodes(ctx, &nodes_count, &nodes);
if (ret < 0) {
LOG_E("%s", jrcplib_get_error_string(ret));
smComJRCP_Close(ctx, 0);
return SMCOM_COM_FAILED;
}
/*int i = 0;
for (; i < nodes_count; i++) {
printf("Node: NAD: %d, Name: %s\n", nodes[i].nad, nodes[i].description);
}*/
ret = jrcplib_tcpclient_list_nodes_cleanup(nodes_count, nodes);
if (ret < 0) {
LOG_E("%s", jrcplib_get_error_string(ret));
smComJRCP_Close(ctx, 0);
return SMCOM_COM_FAILED;
}
ret = jrcplib_tcpclient_reset(ctx, ColdReset);
if (ret < 0) {
LOG_E("%s", jrcplib_get_error_string(ret));
smComJRCP_Close(ctx, 0);
return SMCOM_COM_FAILED;
}
LOG_D("Opening connection to JRCP successful");
if (conn_ctx == NULL) {
gctx = ctx;
}
else {
gctx = ctx;
*conn_ctx = ctx;
}
return smCom_Init(&smComJRCP_Transceive, &smComJRCP_TransceiveRaw);
}
U16 smComJRCP_Reset(void* conn_ctx, uint32_t instruction_bytes)
{
int32_t ret = 0;
jrcplib_tcpclient_ctx_t* ctx = (conn_ctx == NULL) ? gctx : (jrcplib_tcpclient_ctx_t*)conn_ctx;
ret = jrcplib_tcpclient_prepare_reset(ctx, ColdReset, instruction_bytes);
if (ret < 0) {
LOG_E("%s", jrcplib_get_error_string(ret));
smComJRCP_Close(ctx, 0);
return SMCOM_COM_FAILED;
}
LOG_D("Resetting JRCP successful");
return SMCOM_OK;
}
static U32 smComJRCP_Transceive(void* conn_ctx, apdu_t * pApdu)
{
U32 respLen = MAX_APDU_BUF_LENGTH;
U32 retCode = SMCOM_COM_FAILED;
jrcplib_tcpclient_ctx_t* ctx = (conn_ctx == NULL) ? gctx : (jrcplib_tcpclient_ctx_t*)conn_ctx;
ENSURE_OR_GO_EXIT(pApdu != NULL);
retCode = smComJRCP_TransceiveRaw(ctx, (U8 *)pApdu->pBuf, pApdu->buflen, pApdu->pBuf, &respLen);
pApdu->rxlen = (U16)respLen;
exit:
return retCode;
}
static U32 smComJRCP_TransceiveRaw(void* conn_ctx, U8 * pTx, U16 txLen, U8 * pRx, U32 * pRxLen)
{
size_t resp_len = *pRxLen;
jrcplib_tcpclient_ctx_t* ctx = (conn_ctx == NULL) ? gctx : (jrcplib_tcpclient_ctx_t*)conn_ctx;
if (ctx == NULL) {
LOG_W("ctx==NULL");
return SMCOM_COM_FAILED;
}
LOG_MAU8_D("Tx>", pTx, txLen);
int32_t ret = jrcplib_tcpclient_dataexchange(ctx, txLen, pTx, *pRxLen, pRx, &resp_len);
*pRxLen = (U32)resp_len;
if (ret < 0) {
LOG_E("%s", jrcplib_get_error_string(ret));
return SMCOM_RCV_FAILED;
}
LOG_MAU8_D("<Rx", pRx, resp_len);
return SMCOM_OK;
}
void smComJRCP_Echo(void* conn_ctx, const char *comp, const char *level, const char *buffer)
{
char print_buffer[1024];
jrcplib_tcpclient_ctx_t* ctx = (conn_ctx == NULL) ? gctx : (jrcplib_tcpclient_ctx_t*)conn_ctx;
if (ctx == NULL) {
return;
}
snprintf(print_buffer, sizeof(print_buffer) / sizeof(print_buffer[0]) - 1, "%s:%s:%s", comp, level, buffer);
jrcplib_tcpclient_echo(ctx, print_buffer);
}
U32 smComJRCP_NvmCount(void* conn_ctx, U32 * pCount)
{
size_t resp_len = 0;
uint8_t rxBuf[MAX_APDU_BUF_LENGTH];
jrcplib_tcpclient_ctx_t* ctx = (conn_ctx == NULL) ? gctx : (jrcplib_tcpclient_ctx_t*)conn_ctx;
if(pCount == NULL){
LOG_W("pCount==NULL");
return SMCOM_RCV_FAILED;
}
if (ctx == NULL) {
LOG_W("ctx==NULL");
return SMCOM_COM_FAILED;
}
memset(rxBuf, 0x00, sizeof(rxBuf));
int32_t ret = jrcplib_tcpclient_nvmCount(ctx, &resp_len, rxBuf);
if (ret < 0) {
LOG_E("%s", jrcplib_get_error_string(ret));
return SMCOM_RCV_FAILED;
}
*pCount = ((rxBuf[resp_len - 4] << 8 * 3) | (rxBuf[resp_len - 3] << 8 * 2) | (rxBuf[resp_len - 2] << 8 * 1)
| (rxBuf[resp_len - 1]));
LOG_MAU8_D("<Rx", rxBuf, resp_len);
return SMCOM_OK;
}
#endif // defined(SMCOM_JRCP_V2)