/*
 * Copyright (C) 2010 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.
 */

/**
 * \file phDalNfc_i2c.c
 * \brief DAL I2C port implementation for linux
 *
 * Project: Trusted NFC Linux
 *
 */

#define LOG_TAG "NFC_i2c"
#include <cutils/log.h>
#include <hardware/nfc.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <errno.h>

#include <phDal4Nfc_debug.h>
#include <phDal4Nfc_i2c.h>
#include <phOsalNfc.h>
#include <phNfcStatus.h>
#if defined(ANDROID)
#include <string.h>
#endif

typedef struct
{
   int  nHandle;
   char nOpened;

} phDal4Nfc_I2cPortContext_t;


/*-----------------------------------------------------------------------------------
                                      VARIABLES
------------------------------------------------------------------------------------*/
static phDal4Nfc_I2cPortContext_t gI2cPortContext;



/*-----------------------------------------------------------------------------

FUNCTION: phDal4Nfc_i2c_set_open_from_handle

PURPOSE:  Initialize internal variables

-----------------------------------------------------------------------------*/

void phDal4Nfc_i2c_initialize(void)
{
   memset(&gI2cPortContext, 0, sizeof(phDal4Nfc_I2cPortContext_t));
}


/*-----------------------------------------------------------------------------

FUNCTION: phDal4Nfc_i2c_set_open_from_handle

PURPOSE:  The application could have opened the link itself. So we just need
          to get the handle and consider that the open operation has already
          been done.

-----------------------------------------------------------------------------*/

void phDal4Nfc_i2c_set_open_from_handle(phHal_sHwReference_t * pDalHwContext)
{
   gI2cPortContext.nHandle = (int)(intptr_t) pDalHwContext->p_board_driver;
   DAL_ASSERT_STR(gI2cPortContext.nHandle >= 0, "Bad passed com port handle");
   gI2cPortContext.nOpened = 1;
}

/*-----------------------------------------------------------------------------

FUNCTION: phDal4Nfc_i2c_is_opened

PURPOSE:  Returns if the link is opened or not. (0 = not opened; 1 = opened)

-----------------------------------------------------------------------------*/

int phDal4Nfc_i2c_is_opened(void)
{
   return gI2cPortContext.nOpened;
}

/*-----------------------------------------------------------------------------

FUNCTION: phDal4Nfc_i2c_flush

PURPOSE:  Flushes the link ; clears the link buffers

-----------------------------------------------------------------------------*/

void phDal4Nfc_i2c_flush(void)
{
   /* Nothing to do (driver has no internal buffers) */
}

/*-----------------------------------------------------------------------------

FUNCTION: phDal4Nfc_i2c_close

PURPOSE:  Closes the link

-----------------------------------------------------------------------------*/

void phDal4Nfc_i2c_close(void)
{
   DAL_PRINT("Closing port\n");
   if (gI2cPortContext.nOpened == 1)
   {
      close(gI2cPortContext.nHandle);
      gI2cPortContext.nHandle = 0;
      gI2cPortContext.nOpened = 0;
   }
}

/*-----------------------------------------------------------------------------

FUNCTION: phDal4Nfc_i2c_open_and_configure

PURPOSE:  Closes the link

-----------------------------------------------------------------------------*/

NFCSTATUS phDal4Nfc_i2c_open_and_configure(pphDal4Nfc_sConfig_t pConfig, void ** pLinkHandle)
{
   DAL_ASSERT_STR(gI2cPortContext.nOpened==0, "Trying to open but already done!");

   DAL_DEBUG("Opening port=%s\n", pConfig->deviceNode);

   /* open port */
   gI2cPortContext.nHandle = open(pConfig->deviceNode, O_RDWR | O_NOCTTY);
   if (gI2cPortContext.nHandle < 0)
   {
       DAL_DEBUG("Open failed: open() returned %d\n", gI2cPortContext.nHandle);
      *pLinkHandle = NULL;
      return PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_INVALID_DEVICE);
   }

   gI2cPortContext.nOpened = 1;
   *pLinkHandle = (void*)(intptr_t)gI2cPortContext.nHandle;

   DAL_PRINT("Open succeed\n");

   return NFCSTATUS_SUCCESS;
}


/*-----------------------------------------------------------------------------

FUNCTION: phDal4Nfc_i2c_read

PURPOSE:  Reads nNbBytesToRead bytes and writes them in pBuffer.
          Returns the number of bytes really read or -1 in case of error.

-----------------------------------------------------------------------------*/

int phDal4Nfc_i2c_read(uint8_t * pBuffer, int nNbBytesToRead)
{
    int ret;
    int numRead = 0;
    struct timeval tv;
    fd_set rfds;

    DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "read called but not opened!");
    DAL_DEBUG("_i2c_read() called to read %d bytes", nNbBytesToRead);

    // Read with 2 second timeout, so that the read thread can be aborted
    // when the pn544 does not respond and we need to switch to FW download
    // mode. This should be done via a control socket instead.
    while (numRead < nNbBytesToRead) {
        FD_ZERO(&rfds);
        FD_SET(gI2cPortContext.nHandle, &rfds);
        tv.tv_sec = 2;
        tv.tv_usec = 0;
        ret = select(gI2cPortContext.nHandle + 1, &rfds, NULL, NULL, &tv);
        if (ret < 0) {
            DAL_DEBUG("select() errno=%d", errno);
            if (errno == EINTR || errno == EAGAIN) {
                continue;
            }
            return -1;
        } else if (ret == 0) {
            DAL_PRINT("timeout!");
            return -1;
        }
        ret = read(gI2cPortContext.nHandle, pBuffer + numRead, nNbBytesToRead - numRead);
        if (ret > 0) {
            DAL_DEBUG("read %d bytes", ret);
            numRead += ret;
        } else if (ret == 0) {
            DAL_PRINT("_i2c_read() EOF");
            return -1;
        } else {
            DAL_DEBUG("_i2c_read() errno=%d", errno);
            if (errno == EINTR || errno == EAGAIN) {
                continue;
            }
            return -1;
        }
    }
    return numRead;
}

/*-----------------------------------------------------------------------------

FUNCTION: phDal4Nfc_i2c_write

PURPOSE:  Writes nNbBytesToWrite bytes from pBuffer to the link
          Returns the number of bytes that have been wrote to the interface or -1 in case of error.

-----------------------------------------------------------------------------*/

int phDal4Nfc_i2c_write(uint8_t * pBuffer, int nNbBytesToWrite)
{
    int ret;
    int numWrote = 0;

    DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "write called but not opened!");
    DAL_DEBUG("_i2c_write() called to write %d bytes\n", nNbBytesToWrite);

    while (numWrote < nNbBytesToWrite) {
        ret = write(gI2cPortContext.nHandle, pBuffer + numWrote, nNbBytesToWrite - numWrote);
        if (ret > 0) {
            DAL_DEBUG("wrote %d bytes", ret);
            numWrote += ret;
        } else if (ret == 0) {
            DAL_PRINT("_i2c_write() EOF");
            return -1;
        } else {
            DAL_DEBUG("_i2c_write() errno=%d", errno);
            if (errno == EINTR || errno == EAGAIN) {
                continue;
            }
            return -1;
        }
    }

    return numWrote;
}

/*-----------------------------------------------------------------------------

FUNCTION: phDal4Nfc_i2c_reset

PURPOSE:  Reset the PN544, using the VEN pin

-----------------------------------------------------------------------------*/
#define PN544_SET_PWR _IOW(0xe9, 0x01, unsigned int)
int phDal4Nfc_i2c_reset(long level)
{
    DAL_DEBUG("phDal4Nfc_i2c_reset, VEN level = %ld", level);

    return ioctl(gI2cPortContext.nHandle, PN544_SET_PWR, level);
}
