/*
 * Copyright (C) 2010-2014 NXP Semiconductors
 *
 * 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.
 */

/*
 * DAL spi port implementation for linux
 *
 * Project: Trusted ESE Linux
 *
 */
#include <stdint.h>
#include <phNxpLog.h>
#include <phNxpEsePal_spi.h>
#include <phEseStatus.h>

#include "tz_debug.h"
#include "tz_utils.h"

enum
{
    LEN_TAIL = 1,
    HEX_MULTIPLIER = 2,
    LEN_MULTIPLIER = 3,
    HEX_LEN = 3,
};

/*!
 * \brief Normal mode header length
 */
#define NORMAL_MODE_HEADER_LEN      3
/*!
 * \brief Normal mode header offset
 */
#define NORMAL_MODE_LEN_OFFSET      2
/*!
 * \brief Start of frame marker
 */
#define SEND_PACKET_SOF             0x5A

/*******************************************************************************
**
** Function         phPalEse_read
**
** Description     Reads requested number of bytes from pn547 device into given buffer
**
** Parameters
**                      pBuffer                 - buffer for read data
**                      nNbBytesToRead  - number of bytes requested to be read
**
** Returns          numRead             - number of successfully read bytes
**                      -1                        - read operation failure
**
*******************************************************************************/
int phPalEse_read(uint8_t * pBuffer, int nNbBytesToRead)
{
    int ret = -1;
    ret = phPalEse_spi_read(pBuffer, nNbBytesToRead);
    return ret;
}

/*******************************************************************************
**
** Function         phPalEse_write
**
** Description     Writes requested number of bytes from given buffer into pn547 device
**
** Parameters
**                      pBuffer                  - buffer for read data
**                      nNbBytesToWrite   - number of bytes requested to be written
**
** Returns          numWrote            - number of successfully written bytes
**                      -1                        - write operation failure
**
*******************************************************************************/
int phPalEse_write(uint8_t * pBuffer, int nNbBytesToWrite)
{
    int numWrote = 0;
    numWrote = phPalEse_spi_write(pBuffer, nNbBytesToWrite);
    return numWrote;
}

/*******************************************************************************
**
** Function         phPalEse_print_packet
**
** Description      Print packet
**
** Returns          None
**
*******************************************************************************/
void phPalEse_print_packet(const char *pString, const uint8_t *p_data, uint16_t len)
{

    uint32_t i;
    char* print_buffer = NULL;
    uint32_t size_buffer = 0;

    uint32_t possible_max_len = (UINT32_MAX / LEN_MULTIPLIER) - LEN_TAIL;
    if( len > possible_max_len )
    {
        LOGE( "length exceeded");
        return;
    }

    size_buffer = (len * LEN_MULTIPLIER) + LEN_TAIL;

    print_buffer = phPalEse_memalloc( size_buffer );
    if( NULL == print_buffer )
    {
        LOGE("memory is not allocated");
        return;
    }

    memset ( print_buffer, 0, size_buffer );

    for( i = 0; i < len; i++ )
    {
        snprintf( &print_buffer[i * HEX_MULTIPLIER], HEX_LEN, "%02X", p_data[i]);
    }

    if( 0 == memcmp(pString, "SEND", 0x04) )
    {
        NXPLOG_SPIX_D( "SEND : len = %3d > %s", len, print_buffer );
    }
    else if( 0 == memcmp(pString, "RECV", 0x04))
    {
        NXPLOG_SPIR_D( "RECV : len = %3d > %s", len, print_buffer );
    }

    phPalEse_free( print_buffer );
}

/*******************************************************************************
**
** Function         phPalEse_sleep
**
** Description      This function  suspends execution of the calling thread for
**                  (at least) usec microseconds
**
** Returns          None
**
*******************************************************************************/
void phPalEse_sleep(uint32_t usec)
{
    int sleepms = (usec+1000)/1000;
    sleepProcess(sleepms);
}

/**
 * \ingroup eSe_PAL
 * \brief This function updates destination buffer with val
 *                 data in len size
 *
 * \param[in]    buff                - Array to be udpated
 * \param[in]    val                 - value to be updated
 * \param[in]    len                 - length of array to be updated
 *
 * \retval   void
 *
 */
void* phPalEse_memset(void *buff, int val, size_t len)
{
    return memset(buff, val, len);
}

/**
 * \ingroup eSe_PAL
 * \brief This function copies source buffer to  destination buffer
 *                 data in len size
 *
 * \param[in]    dest                - Destination array to be updated
 * \param[in]    src                 - Source array to be updated
 * \param[in]    len                 - length of array to be updated
 *
 * \retval   void
 *
 */
void* phPalEse_memcpy(void *dest, const void *src, size_t len)
{
    return memcpy(dest, src, len);
}

/**
 * \ingroup eSe_PAL
 * \brief This is utility function for runtime heap memory allocation
 *
 * \param[in]    size                 - number of bytes to be allocated
 *
 * \retval   void
 *
 */
void *phPalEse_memalloc(uint32_t size)
{
    uint8_t *pbuff = NULL;
    pbuff = (uint8_t *)tz_malloc(size);
    return pbuff;
}

/**
 * \ingroup eSe_PAL
 * \brief This is utility function for freeeing heap memory allocated
 *
 * \param[in]    ptr                 - Address pointer to previous allocation
 *
 * \retval   void
 *
 */
void phPalEse_free(void* ptr)
{
    tz_free(ptr);
}

