/*
 *
 * Copyright 2019-2020 NXP
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 *
 * @par Description
 * This file implements the high-level APDU handling of the SM module.
 * @par History
 * 1.0   31-march-2014 : Initial version
 * 1.1   10-april-2019 : Removed compile time choice 'USE_MALLOC_FOR_APDU_BUFFER'
 *
 *****************************************************************************/
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>


#if defined(SSS_USE_FTR_FILE)
#include "fsl_sss_ftr.h"
#else
#include "fsl_sss_ftr_default.h"
#endif

#include "sm_apdu.h"
// #include "ax_api.h"
#include "scp.h"
#include "nxLog_hostLib.h"
#include "nxEnsure.h"

static void ReserveLc(apdu_t * pApdu);
static void SetLc(apdu_t * pApdu, U16 lc);
static void AddLe(apdu_t * pApdu, U16 le);

#if SSS_HAVE_A71CH_SIM
/* Send session ID in trans-receive */
static U8 session_Tlv[7];
static U8 gEnableEnc = 0;
#endif

static U8 sharedApduBuffer[MAX_APDU_BUF_LENGTH];

#ifdef TGT_A71CH
#if ( (APDU_HEADER_LENGTH + APDU_STD_MAX_DATA + 1) >= MAX_APDU_BUF_LENGTH )
#error "Ensure MAX_APDU_BUF_LENGTH is big enough"
#endif
#endif // TGT_A71CH

/**
 * Associates a memory buffer with the APDU buffer.
 *
 * By default (determined at compile time) the buffer is not allocated with each call, but a reference
 * is made to a static data structure.
 *
 * \param[in,out] pApdu         APDU buffer
 * \returns always returns 0
 */
U8 AllocateAPDUBuffer(apdu_t *pApdu)
{
    ENSURE_OR_GO_EXIT(pApdu != NULL);
    // In case of e.g. TGT_A7, pApdu is pointing to a structure defined on the stack
    // so pApdu->pBuf contains random data
    pApdu->pBuf = sharedApduBuffer;

exit:
    return 0;
}

/**
 * Clears the previously referenced APDU buffer.
 *
 * In case the buffer was effectively malloc'd by ::AllocateAPDUBuffer it will also be freed.
 *
 * \param[in,out] pApdu              APDU buffer
 * \return Always returns 0
 */
U8 FreeAPDUBuffer(apdu_t * pApdu)
{
    ENSURE_OR_GO_EXIT(pApdu != NULL);

    if (pApdu->pBuf)
    {
        U16 nClear = (pApdu->rxlen > MAX_APDU_BUF_LENGTH) ? MAX_APDU_BUF_LENGTH : pApdu->rxlen;
        memset(pApdu->pBuf, 0, nClear);
        pApdu->pBuf = 0;
    }

exit:
    return 0;
}

/**
 * Sets up the command APDU header.
 * \param[in,out] pApdu      APDU buffer
 * \param[in] extendedLength Indicates if command/response have extended length. Either ::USE_STANDARD_APDU_LEN or ::USE_EXTENDED_APDU_LEN
 * \return                   offset in APDU buffer after the header
 */
U8 SetApduHeader(apdu_t * pApdu, U8 extendedLength)
{
    U8 ret = 0;
    //    pApdu->edc = eEdc_NoErrorDetection;
    ENSURE_OR_GO_EXIT(pApdu != NULL);

    pApdu->pBuf[0] = pApdu->cla;
    pApdu->pBuf[1] = pApdu->ins;
    pApdu->pBuf[2] = pApdu->p1;
    pApdu->pBuf[3] = pApdu->p2;

    pApdu->extendedLength = extendedLength;
    pApdu->hasData = false;
    pApdu->lcLength = 0;
    pApdu->lc = 0;
    pApdu->hasLe = false;

    // No LC yet
    pApdu->offset = APDU_OFFSET_LC;

    // adapt length
    pApdu->buflen = pApdu->offset;

    // Set rxlen to default value
    pApdu->rxlen = 0;

    ret = (U8)(pApdu->offset);
exit:
    return ret;
}

#if SSS_HAVE_A71CH_SIM
/**
 * Creates session TLV from session ID. Session ID is retrieved as response to auth command.
 * \param[in] sessionId
 */
void set_SessionId_Tlv(U32 sessionId)
{
    session_Tlv[0] = 0xBE;
    session_Tlv[1] = 0xBE;
    session_Tlv[2] = 0x04;
    session_Tlv[3] = (U8)(sessionId >> 24);
    session_Tlv[4] = (U8)(sessionId >> 16);
    session_Tlv[5] = (U8)(sessionId >> 8);
    session_Tlv[6] = (U8)(sessionId >> 0);
    gEnableEnc = sessionId !=0 ? 1:0;
}
#endif

/**
 * In the final stage before sending the APDU cmd one needs to update the values of lc (and le).
 * \param[in,out] pApdu        APDU buffer
 * \param[in] lc
 */
void smApduAdaptLc(apdu_t *pApdu, U16 lc)
{
    SetLc(pApdu, lc);
}

/**
 * In the final stage before sending the APDU cmd one needs to update the values of le (and lc).
 * \param[in,out] pApdu        APDU buffer
 * \param[in] le
 */
void smApduAdaptLe(apdu_t *pApdu, U16 le)
{
    AddLe(pApdu, le);
}

/**
 * In the final stage before sending the APDU cmd one needs to update the values of lc and le.
 * \param[in,out] pApdu        APDU buffer
 * \param[in] lc
 * \param[in] le
 */
void smApduAdaptLcLe(apdu_t *pApdu, U16 lc, U16 le)
{
    SetLc(pApdu, lc);
    AddLe(pApdu, le);
}

/**
 * Reserves bytes for the LC in the command APDU and updated the pApdu data structure to match.
 * Must be called once in case the APDU cmd has a command data section.
 * \pre pApdu->hasData has been set.
 * \param[in,out] pApdu        APDU buffer
 */
static void ReserveLc(apdu_t * pApdu)
{
    ENSURE_OR_GO_EXIT(pApdu != NULL);

    pApdu->lcLength = 0;

    ENSURE_OR_GO_EXIT(pApdu->hasData != 0);

    if (pApdu->extendedLength) {
        pApdu->lcLength = 3;
    }
    else {
        pApdu->lcLength = 1;
    }

    pApdu->offset += pApdu->lcLength;
    pApdu->buflen += pApdu->lcLength;
exit:
    return;
}

/**
 * Sets the LC value in the command APDU.
 * @pre ReserveLc(...) has been called or there is no command data section
 * @param[in,out] pApdu APDU buffer
 * @param[in]     lc    LC value to be set
 */
static void SetLc(apdu_t * pApdu, U16 lc)
{
    ENSURE_OR_GO_EXIT(pApdu != NULL);
    ENSURE_OR_GO_EXIT((pApdu->lcLength != 0) || (pApdu->hasData == 0));

    // NOTE:
    // pApdu->lcLength was set to its proper value in a call to ReserveLc(...)

    if (pApdu->hasData) {
        if (pApdu->extendedLength) {
            pApdu->lc = lc;
            // pApdu->lcLength = 3;
            pApdu->pBuf[APDU_OFFSET_LC] = 0x00;
            pApdu->pBuf[APDU_OFFSET_LC + 1] = (U8)(lc >> 8);
            pApdu->pBuf[APDU_OFFSET_LC + 2] = (U8)(lc & 0xFF);
        }
        else {
            pApdu->lc = lc;
            // pApdu->lcLength = 1;
            pApdu->pBuf[APDU_OFFSET_LC] = (U8)(lc & 0xFF);
        }
    }
    else {
        pApdu->lcLength = 0;
    }
exit:
    return;
}

/**
 * Adds the LE value to the command APDU.
 * @param pApdu              [IN/OUT] APDU buffer
 * @param le                 [IN] LE
 * @return
 */
static void AddLe(apdu_t * pApdu, U16 le)
{
    ENSURE_OR_GO_EXIT(pApdu != NULL);

    pApdu->hasLe = true;
    pApdu->le = le;

    if (pApdu->extendedLength) {
        if (pApdu->hasData) {
            pApdu->pBuf[pApdu->offset] = (U8)(le >> 8);
            pApdu->pBuf[pApdu->offset + 1] = (U8)(le & 0xFF);
            pApdu->leLength = 2;
        }
        else {
            pApdu->pBuf[pApdu->offset] = 0x00;
            pApdu->pBuf[pApdu->offset + 1] = (U8)(le >> 8);
            pApdu->pBuf[pApdu->offset + 2] = (U8)(le & 0xFF);
            pApdu->leLength = 3;
        }
    }
    else {
        // regular length
        pApdu->pBuf[pApdu->offset] = (U8)(le & 0xFF);
        pApdu->leLength = 1;
    }

    pApdu->offset += pApdu->leLength;
    pApdu->buflen += pApdu->leLength;
exit:
    return;
}


#if 0
/**
 * @function             AddTlvItem
 * @description          Adds a Tag-Length-Value structure to the command APDU.
 * @param pApdu          [IN/OUT] APDU buffer.
 * @param tag            [IN] tag; either a 1-byte tag or a 2-byte tag
 * @param dataLength     [IN] length of the Value
 * @param pValue         [IN] Value
 * @return               SW_OK or ERR_BUF_TOO_SMALL
 */
U16 AddTlvItem(apdu_t * pApdu, U16 tag, U16 dataLength, const U8 *pValue)
{
    U8 msbTag = tag >> 8;
    U8 lsbTag = tag & 0xff;

    // If this is the first tag added to the buffer, we needs to ensure
    // the correct offset is used writing the data. This depends on
    // whether the APDU is a standard or an extended APDU.
    if (pApdu->hasData == 0)
    {
        pApdu->hasData = 1;
        ReserveLc(pApdu);
    }

    // Ensure no buffer overflow will occur before writing any data to buffer
    {
        U32 xtraData = 0;
        U32 u32_Offset = (U32)(pApdu->offset);

        xtraData = 1;
        // Tag
        if (msbTag != 0x00)
        {
            // 2-byte tag
            xtraData++;
        }

        // Length
        if (dataLength <= 0x7f)
        {
            // 1-byte length
            xtraData++;
        }
        else if (dataLength <= 0xff)
        {
            // 2-byte length
            xtraData += 2;
        }
        else
        {
            // 3-byte length
            xtraData += 3;
        }
        xtraData += dataLength;

        // Can we still add 'xtraData' to internal buffer without buffer overwrite?
        if ( (u32_Offset + xtraData) > MAX_APDU_BUF_LENGTH)
        {
            // Bufferflow would occur
            return ERR_BUF_TOO_SMALL;
        }
    }

    // Tag
    if (msbTag != 0x00)
    {
        // 2-byte tag
        pApdu->pBuf[pApdu->offset++] = msbTag;
    }
    pApdu->pBuf[pApdu->offset++] = lsbTag;

    // Length
    if (dataLength <= 0x7f)
    {
        // 1-byte length
        pApdu->pBuf[pApdu->offset++] = (U8) dataLength;
        pApdu->lc += 2 + dataLength;
    }
    else if (dataLength <= 0xff)
    {
        // 2-byte length
        pApdu->pBuf[pApdu->offset++] = 0x81;
        pApdu->pBuf[pApdu->offset++] = (U8) dataLength;
        pApdu->lc += 3 + dataLength;
    }
    else
    {
        // 3-byte length
        pApdu->pBuf[pApdu->offset++] = 0x82;
        pApdu->pBuf[pApdu->offset++] = dataLength >> 8;
        pApdu->pBuf[pApdu->offset++] = dataLength & 0xff;
        pApdu->lc += 4 + dataLength;
    }

    // Value
    memcpy(&pApdu->pBuf[pApdu->offset], pValue, dataLength);
    pApdu->offset += dataLength;

    // adapt length
    pApdu->buflen = pApdu->offset;

    return SW_OK;
}

/**
 * AddStdCmdData
 * \deprecated Use ::smApduAppendCmdData instead
 */
U16 AddStdCmdData(apdu_t * pApdu, U16 dataLen, const U8 *data)
{

    pApdu->hasData = 1;
    ReserveLc(pApdu);

    pApdu->lc += dataLen;

    // Value
    memcpy(&pApdu->pBuf[pApdu->offset], data, dataLen);
    pApdu->offset += dataLen;

    // adapt length
    pApdu->buflen = pApdu->offset;

    return pApdu->offset;
}

/**
 * @function                 ParseResponse
 * @description              Parses a received Tag-Length-Value structure (response APDU).
 * @param pApdu              [IN] APDU buffer
 * @param expectedTag        [IN] expected tag; either a 1-byte tag or a 2-byte tag
 * @param pLen               [IN,OUT] IN: size of buffer provided; OUT: length of the received Value
 * @param pValue             [OUT] received Value
 * @return status
 */
U16 ParseResponse(apdu_t *pApdu, U16 expectedTag, U16 *pLen, U8 *pValue)
{
    U16 tag = 0;
    U16 rv = ERR_GENERAL_ERROR;
    int foundTag = 0;
    U16 bufferLen = *pLen;

    *pLen = 0;

    if (pApdu->rxlen < 2) /* minimum: 2 byte for response */
    {
        return ERR_GENERAL_ERROR;
    }
    else
    {
        /* check status returned is okay */
        if ((pApdu->pBuf[pApdu->rxlen - 2] != 0x90) || (pApdu->pBuf[pApdu->rxlen - 1] != 0x00))
        {
            return ERR_GENERAL_ERROR;
        }
        else // response okay
        {
            pApdu->offset = 0;

            do
            {
                U16 len = 0;

                // Ensure we don't parse beyond the APDU Response Data
                if (pApdu->offset >= (pApdu->rxlen -2)) { break; }

                /* get the tag (see ISO 7816-4 annex D); limited to max 2 bytes */
                if ((pApdu->pBuf[pApdu->offset] & 0x1F) != 0x1F) /* 1 byte tag only */
                {
                    tag = (pApdu->pBuf[pApdu->offset] & 0x00FF);
                    pApdu->offset += 1;
                }
                else /* tag consists out of 2 bytes */
                {
                    tag = (pApdu->pBuf[pApdu->offset] << 8) + pApdu->pBuf[pApdu->offset + 1];
                    pApdu->offset += 2;
                }

                // Ensure we don't parse beyond the APDU Response Data
                if (pApdu->offset >= (pApdu->rxlen -2)) { break; }

                // tag is OK
                /* get the length (see ISO 7816-4 annex D) */
                if ((pApdu->pBuf[pApdu->offset] & 0x80) != 0x80)
                {
                    /* 1 byte length */
                    len = (pApdu->pBuf[pApdu->offset++] & 0x00FF);
                }
                else
                {
                    /* length consists of 2 or 3 bytes */

                    U8 additionalBytesForLength = (pApdu->pBuf[pApdu->offset++] & 0x7F);

                    if (additionalBytesForLength == 1)
                    {
                        len = pApdu->pBuf[pApdu->offset];
                        pApdu->offset += 1;
                    }
                    else if (additionalBytesForLength == 2)
                    {
                        len = (pApdu->pBuf[pApdu->offset] << 8) + pApdu->pBuf[pApdu->offset + 1];
                        pApdu->offset += 2;
                    }
                    else
                    {
                        return ERR_GENERAL_ERROR;
                    }
                }

                // Ensure we don't parse beyond the APDU Response Data
                if (pApdu->offset >= (pApdu->rxlen -2)) { break; }

                if (tag == expectedTag)
                {
                    // copy the value
                    if ( (len > 0) && (bufferLen >= len) )
                    {
                        *pLen = len;
                        memcpy(pValue, &pApdu->pBuf[pApdu->offset], *pLen);
                        rv = SW_OK;
                        foundTag = 1;
                        break;
                    }
                    else
                    {
                        rv = ERR_BUF_TOO_SMALL;
                        break;
                    }
                }

                // update the offset
                pApdu->offset += len;
            } while (!foundTag);
        }
    }

    return rv;
}

#endif // TGT_A71CH

/**
 * Add or append data to the body of a command APDU.
 * WARNING:
 * - Bufferoverflow fix not applied for SSS_HAVE_A71CH_SIM
 * WARNING for non-TGT_A71CH cases :
 * - TGT_A71CL: This function must only be called once in case pApdu->txHasChkSum is set
 */
U16 smApduAppendCmdData(apdu_t *pApdu, const U8 *data, U16 dataLen)
{
    U16 rv = ERR_GENERAL_ERROR;
    ENSURE_OR_GO_EXIT(pApdu != NULL);
    ENSURE_OR_GO_EXIT(data != NULL);
#ifdef TGT_A71CH
    // The maximum amount of data payload depends on (whichever is smaller)
    //   - STD-APDU (MAX=255 byte) / EXTENDED-APDU (MAX=65536 byte)
    //   - size of pApdu->pBuf (MAX_APDU_BUF_LENGTH)
    // Standard Length APDU's:
    //   There is a pre-processor macro in place that ensures 'pApdu->pBuf' is of sufficient size
    // Extended Length APDU's (not used by A71CH):
    //   APDU payload restricted by buffersize of 'pApdu->pBuf'
    U16 maxPayload_noLe;

    if (pApdu->extendedLength) {
        maxPayload_noLe = MAX_APDU_BUF_LENGTH - EXT_CASE4_APDU_OVERHEAD;
    }
    else {
        maxPayload_noLe = APDU_HEADER_LENGTH + APDU_STD_MAX_DATA;
    }
#endif // TGT_A71CH

#ifdef TGT_A71CL
    U16 maxPayload_noLe;

    maxPayload_noLe = MAX_APDU_BUF_LENGTH - EXT_CASE4_APDU_OVERHEAD;
    if (pApdu->txHasChkSum == 1) {
        maxPayload_noLe -= pApdu->txChkSumLength;
    }
#endif // TGT_A71CL

    // If this is the first commmand data section added to the buffer, we needs to ensure
    // the correct offset is used writing the data. This depends on
    // whether the APDU is a standard or an extended APDU.
    if (pApdu->hasData == 0)
    {
        pApdu->hasData = 1;
        ReserveLc(pApdu);
    }

#if SSS_HAVE_A71CH_SIM
    if (gEnableEnc)
    {
        pApdu->lc += (dataLen + sizeof(session_Tlv));
        //add SessionId_Tlv
        memcpy(&pApdu->pBuf[pApdu->offset], session_Tlv, sizeof(session_Tlv));
        pApdu->offset += sizeof(session_Tlv);
    }
    else
#endif // SSS_HAVE_A71CH_SIM
    {
        pApdu->lc += dataLen;
    }

#ifdef TGT_A71CL
    /* add for cl */
    if (pApdu->txHasChkSum == 1) {
        pApdu->lc += pApdu->txChkSumLength;
        pApdu->pBuf[pApdu->offset - 1] = (U8)pApdu->lc;
    }
#endif // TGT_A71CL

    // Value
#if defined(TGT_A71CH) || defined(TGT_A71CL)
    if (dataLen <= (maxPayload_noLe - pApdu->offset))
    {
        memcpy(&pApdu->pBuf[pApdu->offset], data, dataLen);
        pApdu->offset += dataLen;
    }
    else
    {
        return ERR_INTERNAL_BUF_TOO_SMALL;
    }
#else // defined(TGT_A71CH) || defined(TGT_A71CL)
    memcpy(&pApdu->pBuf[pApdu->offset], data, dataLen);
    pApdu->offset += dataLen;
#endif // defined(TGT_A71CH) || defined(TGT_A71CL)

    // adapt length
    pApdu->buflen = pApdu->offset;

    rv = pApdu->offset;
exit:
    return rv;
}

/**
 * Gets the Status Word from the APDU.
 * @param[in]      pApdu Pointer to the APDU.
 * @param[in,out]  pIsOk IN: Pointer to the error indicator, allowed to be NULL; OUT: Points to '1' in case SW is 0x9000
 * @return      Status Word or ::ERR_COMM_ERROR
 */
U16 smGetSw(apdu_t *pApdu, U8 *pIsOk)
{
    U16 sw = ERR_API_ERROR;
    U16 offset;
    ENSURE_OR_GO_EXIT(pApdu != NULL);
    ENSURE_OR_GO_EXIT(pIsOk != NULL);

    if (pApdu->rxlen >= 2)
    {
        offset = pApdu->rxlen - 2;
        sw = (pApdu->pBuf[offset] << 8) + pApdu->pBuf[offset + 1];

        if (sw == SW_OK)
        {
            *pIsOk = 1;
        }
        else
        {
            *pIsOk = 0;
        }
    }
    else
    {
        sw = ERR_COMM_ERROR;
        *pIsOk = 0;

    }
exit:
    return sw;
}

/**
 * verify crc checksum.
 * \param[in] pApdu      APDU buffer
 * \param[in] dataLen    data length to be use for crc caluate
 * \return               offset in APDU buffer after the header
 */
#if defined(TGT_A71CL)
static U8 smVerifyCrc(apdu_t *pApdu, U16 dataLen)
{
    U16 crc = 0;
    U16 recvCrc = 0;

    ENSURE_OR_GO_EXIT(pApdu != NULL);
    //FIXME: Where is the definition for below function?
    //crc = CL_CalCRC(&pApdu->pBuf[pApdu->offset], (U32)dataLen, 0xFFFF);
    recvCrc = *(U16*)&pApdu->pBuf[pApdu->offset + dataLen];
    if (crc != recvCrc) {
        return 0;
    } else {
        return 1;
    }
exit:
    return 0;
}
#endif
/**
 * Retrieve the response data of the APDU response, in case the status word matches ::SW_OK
 */
U16 smApduGetResponseBody(apdu_t *pApdu, U8 *buf, U16 *bufLen)
{
    U16 tailInfoLen = 2;
    U16 rv = ERR_GENERAL_ERROR;

    ENSURE_OR_GO_EXIT(pApdu != NULL);
    if (pApdu->rxlen < 2) /* minimum: 2 byte for response */
    {
        *bufLen = 0;
        return ERR_GENERAL_ERROR;
    }
    else
    {
        /* check status returned is okay */
        if (((pApdu->pBuf[pApdu->rxlen - 2] != 0x90) || (pApdu->pBuf[pApdu->rxlen - 1] != 0x00)) &&
            (pApdu->pBuf[pApdu->rxlen -2] != 0x63) &&
            (pApdu->pBuf[pApdu->rxlen - 2] != 0x95)) {
            *bufLen = 0;
            return ERR_GENERAL_ERROR;
        }
        else // response okay
        {
            pApdu->offset = 0;
#if defined(TGT_A71CL)
            if (pApdu->rxHasChkSum == 1) {
                tailInfoLen += pApdu->rxChkSumLength;
            }
#endif
            if ((pApdu->rxlen - tailInfoLen) > *bufLen)
            {
                *bufLen = 0;
                return ERR_BUF_TOO_SMALL;
            }
            else
            {
                *bufLen = pApdu->rxlen - tailInfoLen;
#if defined(TGT_A71CL)
                if (pApdu->rxHasChkSum == 1) {
                    if (smVerifyCrc(pApdu, *bufLen)) {
                        memcpy(buf, &(pApdu->pBuf[pApdu->offset]), *bufLen);
                    } else {
                        return ERR_CRC_CHKSUM_VERIFY;
                    }
                }
                else
#endif
                {
                    if (*bufLen) {
                        memcpy(buf, &(pApdu->pBuf[pApdu->offset]), *bufLen);
                    }
                }
            }
        }
    }

    rv = SW_OK;
exit:
    return rv;
}

#ifdef TGT_A71CL

/**
 * In the final stage before sending the APDU cmd one needs to update checksum value.
 * \param[in,out] pApdu        APDU buffer
 * \param[in] chksum
 */
U16 smApduAdaptChkSum(apdu_t *pApdu, U16 chkSum)
{
    U16 rv = ERR_GENERAL_ERROR;
    // assert(pApdu->txHasChkSum == 1);
    // U16 tmpchkSum = (chkSum >> 8)|(chkSum << 8);

    ENSURE_OR_GO_EXIT(pApdu != NULL);
    if (pApdu->txHasChkSum) {
        memcpy(&pApdu->pBuf[pApdu->offset], &chkSum, pApdu->txChkSumLength);
    }
    pApdu->buflen += pApdu->txChkSumLength;
    pApdu->offset += pApdu->txChkSumLength;

    rv = pApdu->offset;
exit:
    return rv;
}
#endif

bool smApduGetArrayBytes(char *str, size_t *len, uint8_t *buffer, size_t buffer_len)
{
    if ((strlen(str) % 2) != 0) {
        LOG_E("Invalid length");
        return false;
    }

    *len = strlen(str) / 2;
    if (buffer_len < *len)
    {
        LOG_E("Insufficient buffer size\n");
        *len = 0;
        return false;
    }
    char *pos = str;
    for (size_t count = 0; count < *len; count++) {
        if (sscanf(pos, "%2hhx", &buffer[count]) < 1) {
            *len = 0;
            return false;
        }
        pos += 2;
    }
    return true;
}

bool smApduGetTxRxCase(uint8_t *apdu, size_t apduLen, size_t* data_offset, size_t *dataLen, apduTxRx_case_t *apdu_case)
{
    *data_offset = 0;
    *dataLen = 0;
    *apdu_case = APDU_TXRX_CASE_INVALID;
    //Invalid apdu
    if (apduLen < 4)
    {
        LOG_E("Wrong APDU format\n");
        return false;
    }

    //Case 1
    if (apduLen == 4)
    {
        *apdu_case = APDU_TXRX_CASE_1;
        return true;
    }
    //Case 2S
    else if (apduLen == 5)
    {
        *apdu_case = APDU_TXRX_CASE_2;
        return true;
    }
    else
    {
        size_t byte5 = apdu[4] & 0xFF;
        if (byte5 != 0x0)
        {
            if (apduLen == 5 + byte5)
            {
                //case 3S
                *apdu_case = APDU_TXRX_CASE_3;
                *data_offset = 5;
                *dataLen = byte5;
            }
            else if (apduLen == 6 + byte5)
            {
                //case 4S
                *apdu_case = APDU_TXRX_CASE_4;
                *data_offset = 5;
                *dataLen = byte5;
            }
            else
            {
                LOG_E("Wrong APDU format\n");
                return false;
            }
        }
        else if (apduLen == 7)
        {
            //case 2E
            *apdu_case = APDU_TXRX_CASE_2E;
        }
        else if (apduLen < 7)
        {
            LOG_E("Wrong APDU format\n");
            return false;
        }
        else
        {
            size_t len = ((apdu[5] & 0xFF) << 8) | (apdu[6] & 0xFF);
            if (apduLen == 7 + len) {
                //case 3E
                *apdu_case = APDU_TXRX_CASE_3E;
                *data_offset = 7;
                *dataLen = len;
            }
            else if (apduLen == 9 + len) {
                //Case 4E
                *apdu_case = APDU_TXRX_CASE_4E;
                *data_offset = 7;
                *dataLen = len;
            }
            else
            {
                LOG_E("Wrong APDU format\n");
                return false;
            }
        }
    }
    return true;
}
