/*
 * 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  phFriNfc_Llcp.c
 * \brief NFC LLCP core
 *
 * Project: NFC-FRI
 *
 */

/*include files*/
#include <phNfcTypes.h>
#include <phNfcHalTypes.h>
#include <phLibNfcStatus.h>
#include <phFriNfc_LlcpUtils.h>
#include <phFriNfc_Llcp.h>

NFCSTATUS phFriNfc_Llcp_DecodeTLV( phNfc_sData_t  *psRawData,
                                   uint32_t       *pOffset,
                                   uint8_t        *pType,
                                   phNfc_sData_t  *psValueBuffer )
{
   uint8_t type;
   uint8_t length;
   uint32_t offset = *pOffset;

   /* Check for NULL pointers */
   if ((psRawData == NULL) || (pOffset == NULL) || (pType == NULL) || (psValueBuffer == NULL))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Check offset */
   if (offset > psRawData->length)
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Check if enough room for Type and Length (with overflow check) */
   if ((offset+2 > psRawData->length) && (offset+2 > offset))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Get Type and Length from current TLV, and update offset */
   type = psRawData->buffer[offset];
   length = psRawData->buffer[offset+1];
   offset += 2;

   /* Check if enough room for Value with announced Length (with overflow check) */
   if ((offset+length > psRawData->length) && (offset+length > offset))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Save response, and update offset */
   *pType = type;
   psValueBuffer->buffer = psRawData->buffer + offset;
   psValueBuffer->length = length;
   offset += length;

   /* Save updated offset */
   *pOffset = offset;

   return NFCSTATUS_SUCCESS;
}

NFCSTATUS phFriNfc_Llcp_EncodeTLV( phNfc_sData_t  *psValueBuffer,
                                   uint32_t       *pOffset,
                                   uint8_t        type,
                                   uint8_t        length,
                                   uint8_t        *pValue)
{
   uint32_t offset = *pOffset;
   uint8_t i;

   /* Check for NULL pointers */
   if ((psValueBuffer == NULL) || (pOffset == NULL) || (pValue == NULL))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Check offset */
   if (offset > psValueBuffer->length)
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Check if enough room for Type and Length (with overflow check) */
   if ((offset+2 > psValueBuffer->length) && (offset+2 > offset))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Set the TYPE */
   psValueBuffer->buffer[offset] = type;
   offset += 1;

   /* Set the LENGTH */
   psValueBuffer->buffer[offset] = length;
   offset += 1;

   /* Set the VALUE */
   for(i=0;i<length;i++,offset++)
   {
      psValueBuffer->buffer[offset]  = pValue[i];
   }

   /* Save updated offset */
   *pOffset = offset;

   return NFCSTATUS_SUCCESS;
}

/* TODO: comment function EncodeMIUX */
void phFriNfc_Llcp_EncodeMIUX(uint16_t miux,
                              uint8_t* pMiuxEncoded)
{
   /* MASK */
   miux = miux & PHFRINFC_LLCP_TLV_MIUX_MASK;

   pMiuxEncoded[0] = miux >> 8;
   pMiuxEncoded[1] = miux & 0xff;
}

/* TODO: comment function EncodeRW */
void phFriNfc_Llcp_EncodeRW(uint8_t *pRw)
{
   /* MASK */
   *pRw = *pRw & PHFRINFC_LLCP_TLV_RW_MASK;
}

/**
 * Initializes a Fifo Cyclic Buffer to point to some allocated memory.
 */
void phFriNfc_Llcp_CyclicFifoInit(P_UTIL_FIFO_BUFFER   pUtilFifo,
                                  const uint8_t        *pBuffStart,
                                  uint32_t             buffLength)
{
   pUtilFifo->pBuffStart = (uint8_t *)pBuffStart;
   pUtilFifo->pBuffEnd   = (uint8_t *)pBuffStart + buffLength-1;
   pUtilFifo->pIn        = (uint8_t *)pBuffStart;
   pUtilFifo->pOut       = (uint8_t *)pBuffStart;
   pUtilFifo->bFull      = FALSE;
}

/**
 * Clears the Fifo Cyclic Buffer - loosing any data that was in it.
 */
void phFriNfc_Llcp_CyclicFifoClear(P_UTIL_FIFO_BUFFER pUtilFifo)
{
   pUtilFifo->pIn = pUtilFifo->pBuffStart;
   pUtilFifo->pOut = pUtilFifo->pBuffStart;
   pUtilFifo->bFull      = FALSE;
}

/**
 * Attempts to write dataLength bytes to the specified Fifo Cyclic Buffer.
 */
uint32_t phFriNfc_Llcp_CyclicFifoWrite(P_UTIL_FIFO_BUFFER   pUtilFifo,
                                       uint8_t              *pData,
                                       uint32_t             dataLength)
{
   uint32_t dataLengthWritten = 0;
   uint8_t * pNext;

   while(dataLengthWritten < dataLength)
   {
      pNext = (uint8_t*)pUtilFifo->pIn+1;

      if(pNext > pUtilFifo->pBuffEnd)
      {
         //Wrap around
         pNext = pUtilFifo->pBuffStart;
      }

      if(pUtilFifo->bFull)
      {
         //Full
         break;
      }

      if(pNext == pUtilFifo->pOut)
      {
         // Trigger Full flag
         pUtilFifo->bFull = TRUE;
      }

      dataLengthWritten++;
      *pNext = *pData++;
      pUtilFifo->pIn = pNext;
   }

   return dataLengthWritten;
}

/**
 * Attempts to read dataLength bytes from the specified  Fifo Cyclic Buffer.
 */
uint32_t phFriNfc_Llcp_CyclicFifoFifoRead(P_UTIL_FIFO_BUFFER   pUtilFifo,
                                          uint8_t              *pBuffer,
                                          uint32_t             dataLength)
{
   uint32_t  dataLengthRead = 0;
   uint8_t * pNext;

   while(dataLengthRead < dataLength)
   {
      if((pUtilFifo->pOut == pUtilFifo->pIn) && (pUtilFifo->bFull == FALSE))
      {
         //No more bytes in buffer
         break;
      }
      else
      {
         dataLengthRead++;

         if(pUtilFifo->pOut == pUtilFifo->pBuffEnd)
         {
            /* Wrap around */
            pNext = pUtilFifo->pBuffStart;
         }
         else
         {
            pNext = (uint8_t*)pUtilFifo->pOut + 1;
         }

         *pBuffer++ = *pNext;

         pUtilFifo->pOut = pNext;

         pUtilFifo->bFull = FALSE;
      }
   }

   return dataLengthRead;
}

/**
 * Returns the number of bytes currently stored in Fifo Cyclic Buffer.
 */
uint32_t phFriNfc_Llcp_CyclicFifoUsage(P_UTIL_FIFO_BUFFER pUtilFifo)
{
   uint32_t dataLength;
   uint8_t * pIn        = (uint8_t *)pUtilFifo->pIn;
   uint8_t * pOut       = (uint8_t *)pUtilFifo->pOut;

   if (pUtilFifo->bFull)
   {
      dataLength = pUtilFifo->pBuffEnd - pUtilFifo->pBuffStart + 1;
   }
   else
   {
      if(pIn >= pOut)
      {
         dataLength = pIn - pOut;
      }
      else
      {
         dataLength = pUtilFifo->pBuffEnd - pOut;
         dataLength += (pIn+1) - pUtilFifo->pBuffStart;
      }
   }

   return dataLength;
}


/**
 * Returns the available room for writing in Fifo Cyclic Buffer.
 */
uint32_t phFriNfc_Llcp_CyclicFifoAvailable(P_UTIL_FIFO_BUFFER pUtilFifo)
{
   uint32_t dataLength;
   uint32_t  size;
   uint8_t * pIn         = (uint8_t *)pUtilFifo->pIn;
   uint8_t * pOut        = (uint8_t *)pUtilFifo->pOut;

   if (pUtilFifo->bFull)
   {
      dataLength = 0;
   }
   else
   {
      if(pIn >= pOut)
      {
         size = pUtilFifo->pBuffEnd - pUtilFifo->pBuffStart + 1;
         dataLength = size - (pIn - pOut);
      }
      else
      {
         dataLength = pOut - pIn;
      }
   }

   return dataLength;
}



uint32_t phFriNfc_Llcp_Header2Buffer( phFriNfc_Llcp_sPacketHeader_t *psHeader, uint8_t *pBuffer, uint32_t nOffset )
{
   uint32_t nOriginalOffset = nOffset;
   pBuffer[nOffset++] = (uint8_t)((psHeader->dsap << 2)  | (psHeader->ptype >> 2));
   pBuffer[nOffset++] = (uint8_t)((psHeader->ptype << 6) | psHeader->ssap);
   return nOffset - nOriginalOffset;
}

uint32_t phFriNfc_Llcp_Sequence2Buffer( phFriNfc_Llcp_sPacketSequence_t *psSequence, uint8_t *pBuffer, uint32_t nOffset )
{
   uint32_t nOriginalOffset = nOffset;
   pBuffer[nOffset++] = (uint8_t)((psSequence->ns << 4) | (psSequence->nr));
   return nOffset - nOriginalOffset;
}

uint32_t phFriNfc_Llcp_Buffer2Header( uint8_t *pBuffer, uint32_t nOffset, phFriNfc_Llcp_sPacketHeader_t *psHeader )
{
   psHeader->dsap  = (pBuffer[nOffset] & 0xFC) >> 2;
   psHeader->ptype = ((pBuffer[nOffset]  & 0x03) << 2) | ((pBuffer[nOffset+1] & 0xC0) >> 6);
   psHeader->ssap  = pBuffer[nOffset+1] & 0x3F;
   return PHFRINFC_LLCP_PACKET_HEADER_SIZE;
}

uint32_t phFriNfc_Llcp_Buffer2Sequence( uint8_t *pBuffer, uint32_t nOffset, phFriNfc_Llcp_sPacketSequence_t *psSequence )
{
   psSequence->ns = pBuffer[nOffset] >> 4;
   psSequence->nr = pBuffer[nOffset] & 0x0F;
   return PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;
}


