/*
 * 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 <phNfcLlcpTypes.h>
#include <phOsalNfc_Timer.h>

#include <phFriNfc_Llcp.h>
#include <phFriNfc_LlcpUtils.h>

/**
 * \internal 
 * \name States of the LLC state machine.
 *
 */
/*@{*/
#define PHFRINFC_LLCP_STATE_RESET_INIT               0   /**< \internal Initial state.*/
#define PHFRINFC_LLCP_STATE_CHECKED                  1   /**< \internal The tag has been checked for LLCP compliance.*/
#define PHFRINFC_LLCP_STATE_ACTIVATION               2   /**< \internal The deactivation phase.*/
#define PHFRINFC_LLCP_STATE_PAX                      3   /**< \internal Parameter exchange phase.*/
#define PHFRINFC_LLCP_STATE_OPERATION_RECV           4   /**< \internal Normal operation phase (ready to receive).*/
#define PHFRINFC_LLCP_STATE_OPERATION_SEND           5   /**< \internal Normal operation phase (ready to send).*/
#define PHFRINFC_LLCP_STATE_DEACTIVATION             6   /**< \internal The deactivation phase.*/
/*@}*/

/**
 * \internal 
 * \name Masks used for VERSION parsing.
 *
 */
/*@{*/
#define PHFRINFC_LLCP_VERSION_MAJOR_MASK            0xF0    /**< \internal Mask to apply to get major version number.*/
#define PHFRINFC_LLCP_VERSION_MINOR_MASK            0x0F    /**< \internal Mask to apply to get major version number.*/
/*@}*/

/**
 * \internal 
 * \name Invalid values for parameters.
 *
 */
/*@{*/
#define PHFRINFC_LLCP_INVALID_VERSION              0x00   /**< \internal Invalid VERSION value.*/
/*@}*/

/**
 * \internal 
 * \name Internal constants.
 *
 */
/*@{*/
#define PHFRINFC_LLCP_MAX_PARAM_TLV_LENGTH \
   (( PHFRINFC_LLCP_TLV_LENGTH_HEADER + PHFRINFC_LLCP_TLV_LENGTH_VERSION ) + \
    ( PHFRINFC_LLCP_TLV_LENGTH_HEADER + PHFRINFC_LLCP_TLV_LENGTH_MIUX ) + \
    ( PHFRINFC_LLCP_TLV_LENGTH_HEADER + PHFRINFC_LLCP_TLV_LENGTH_WKS ) + \
    ( PHFRINFC_LLCP_TLV_LENGTH_HEADER + PHFRINFC_LLCP_TLV_LENGTH_LTO ) + \
    ( PHFRINFC_LLCP_TLV_LENGTH_HEADER + PHFRINFC_LLCP_TLV_LENGTH_OPT ))   /**< \internal Maximum size of link params TLV.*/
/*@}*/



/* --------------------------- Internal functions ------------------------------ */

static void phFriNfc_Llcp_Receive_CB( void               *pContext,
                                      NFCSTATUS          status,
                                      phNfc_sData_t      *psData);
static NFCSTATUS phFriNfc_Llcp_HandleIncomingPacket( phFriNfc_Llcp_t    *Llcp,
                                                     phNfc_sData_t      *psPacket );
static void phFriNfc_Llcp_ResetLTO( phFriNfc_Llcp_t *Llcp );
static NFCSTATUS phFriNfc_Llcp_InternalSend( phFriNfc_Llcp_t                    *Llcp,
                                             phFriNfc_Llcp_sPacketHeader_t      *psHeader,
                                             phFriNfc_Llcp_sPacketSequence_t    *psSequence,
                                             phNfc_sData_t                      *psInfo );
static bool_t phFriNfc_Llcp_HandlePendingSend ( phFriNfc_Llcp_t *Llcp );

static phNfc_sData_t * phFriNfc_Llcp_AllocateAndCopy(phNfc_sData_t * pOrig)
{
   phNfc_sData_t * pDest = NULL;

   if (pOrig == NULL)
   {
       return NULL;
   }

   pDest = phOsalNfc_GetMemory(sizeof(phNfc_sData_t));
   if (pDest == NULL)
   {
      goto error;
   }

   pDest->buffer = phOsalNfc_GetMemory(pOrig->length);
   if (pDest->buffer == NULL)
   {
      goto error;
   }

   memcpy(pDest->buffer, pOrig->buffer, pOrig->length);
   pDest->length = pOrig->length;

   return pDest;

error:
   if (pDest != NULL)
   {
      if (pDest->buffer != NULL)
      {
         phOsalNfc_FreeMemory(pDest->buffer);
      }
      phOsalNfc_FreeMemory(pDest);
   }
   return NULL;
}

static void phFriNfc_Llcp_Deallocate(phNfc_sData_t * pData)
{
   if (pData != NULL)
   {
      if (pData->buffer != NULL)
      {
         phOsalNfc_FreeMemory(pData->buffer);
      }
      else
      {
         LLCP_PRINT("Warning, deallocating empty buffer");
      }
      phOsalNfc_FreeMemory(pData);
   }
}

static NFCSTATUS phFriNfc_Llcp_InternalDeactivate( phFriNfc_Llcp_t *Llcp )
{
   phFriNfc_Llcp_Send_CB_t pfSendCB;
   void * pSendContext;
   if ((Llcp->state == PHFRINFC_LLCP_STATE_OPERATION_RECV) ||
       (Llcp->state == PHFRINFC_LLCP_STATE_OPERATION_SEND) ||
       (Llcp->state == PHFRINFC_LLCP_STATE_PAX)            ||
       (Llcp->state == PHFRINFC_LLCP_STATE_ACTIVATION))
   {
      /* Update state */
      Llcp->state = PHFRINFC_LLCP_STATE_DEACTIVATION;

      /* Stop timer */
      phOsalNfc_Timer_Stop(Llcp->hSymmTimer);

      /* Return delayed send operation in error, in any */
      if (Llcp->psSendInfo != NULL)
      {
         phFriNfc_Llcp_Deallocate(Llcp->psSendInfo);
         Llcp->psSendInfo = NULL;
         Llcp->psSendHeader = NULL;
         Llcp->psSendSequence = NULL;
      }
      if (Llcp->pfSendCB != NULL)
      {
         /* Get Callback params */
         pfSendCB = Llcp->pfSendCB;
         pSendContext = Llcp->pSendContext;
         /* Reset callback params */
         Llcp->pfSendCB = NULL;
         Llcp->pSendContext = NULL;
         /* Call the callback */
         (pfSendCB)(pSendContext, NFCSTATUS_FAILED);
      }

      /* Notify service layer */
      Llcp->pfLink_CB(Llcp->pLinkContext, phFriNfc_LlcpMac_eLinkDeactivated);

      /* Forward check request to MAC layer */
      return phFriNfc_LlcpMac_Deactivate(&Llcp->MAC);
   }

   return NFCSTATUS_SUCCESS;
}


static NFCSTATUS phFriNfc_Llcp_SendSymm( phFriNfc_Llcp_t *Llcp )
{
   phFriNfc_Llcp_sPacketHeader_t sHeader;

   sHeader.dsap  = PHFRINFC_LLCP_SAP_LINK;
   sHeader.ssap  = PHFRINFC_LLCP_SAP_LINK;
   sHeader.ptype = PHFRINFC_LLCP_PTYPE_SYMM;
   return phFriNfc_Llcp_InternalSend(Llcp, &sHeader, NULL, NULL);
}


static NFCSTATUS phFriNfc_Llcp_SendPax( phFriNfc_Llcp_t *Llcp, phFriNfc_Llcp_sLinkParameters_t *psLinkParams)
{
   uint8_t                       pTLVBuffer[PHFRINFC_LLCP_MAX_PARAM_TLV_LENGTH];
   phNfc_sData_t                 sParamsTLV;
   phFriNfc_Llcp_sPacketHeader_t sHeader;
   NFCSTATUS                     result;

   /* Prepare link parameters TLV */
   sParamsTLV.buffer = pTLVBuffer;
   sParamsTLV.length = PHFRINFC_LLCP_MAX_PARAM_TLV_LENGTH;
   result = phFriNfc_Llcp_EncodeLinkParams(&sParamsTLV, psLinkParams, PHFRINFC_LLCP_VERSION);
   if (result != NFCSTATUS_SUCCESS)
   {
      /* Error while encoding */
      return NFCSTATUS_FAILED;
   }

   /* Check if ready to send */
   if (Llcp->state != PHFRINFC_LLCP_STATE_OPERATION_SEND)
   {
      /* No send pending, send the PAX packet */
      sHeader.dsap  = PHFRINFC_LLCP_SAP_LINK;
      sHeader.ssap  = PHFRINFC_LLCP_SAP_LINK;
      sHeader.ptype = PHFRINFC_LLCP_PTYPE_PAX;
      return phFriNfc_Llcp_InternalSend(Llcp, &sHeader, NULL, &sParamsTLV);
   }
   else
   {
      /* Error: A send is already pending, cannot send PAX */
      /* NOTE: this should not happen since PAX are sent before any other packet ! */
      return NFCSTATUS_FAILED;
   }
}


static NFCSTATUS phFriNfc_Llcp_SendDisconnect( phFriNfc_Llcp_t *Llcp )
{
   phFriNfc_Llcp_sPacketHeader_t sHeader;

   /* Check if ready to send */
   if (Llcp->state != PHFRINFC_LLCP_STATE_OPERATION_SEND)
   {
      /* No send pending, send the DISC packet */
      sHeader.dsap  = PHFRINFC_LLCP_SAP_LINK;
      sHeader.ssap  = PHFRINFC_LLCP_SAP_LINK;
      sHeader.ptype = PHFRINFC_LLCP_PTYPE_DISC;
      return phFriNfc_Llcp_InternalSend(Llcp, &sHeader, NULL, NULL);
   }
   else
   {
      /* A send is already pending, raise a flag to send DISC as soon as possible */
      Llcp->bDiscPendingFlag = TRUE;
      return NFCSTATUS_PENDING;
   }
}


static void phFriNfc_Llcp_Timer_CB(uint32_t TimerId, void *pContext)
{
   phFriNfc_Llcp_t               *Llcp = (phFriNfc_Llcp_t*)pContext;

   PHNFC_UNUSED_VARIABLE(TimerId);

   /* Check current state */
   if (Llcp->state == PHFRINFC_LLCP_STATE_OPERATION_RECV)
   {
      /* No data is coming before LTO, disconnecting */
      phFriNfc_Llcp_InternalDeactivate(Llcp);
   }
   else if (Llcp->state == PHFRINFC_LLCP_STATE_OPERATION_SEND)
   {
      /* Send SYMM */
      phFriNfc_Llcp_SendSymm(Llcp);
   }
   else
   {
      /* Nothing to do if not in Normal Operation state */
   }
}


static NFCSTATUS phFriNfc_Llcp_HandleAggregatedPacket( phFriNfc_Llcp_t *Llcp,
                                                       phNfc_sData_t *psRawPacket )
{
   phNfc_sData_t  sInfo;
   phNfc_sData_t  sCurrentInfo;
   uint16_t       length;
   NFCSTATUS      status;

   /* Get info field */
   sInfo.buffer = psRawPacket->buffer + PHFRINFC_LLCP_PACKET_HEADER_SIZE;
   sInfo.length = psRawPacket->length - PHFRINFC_LLCP_PACKET_HEADER_SIZE;

   /* Check for empty info field */
   if (sInfo.length == 0)
   {
      return NFCSTATUS_FAILED;
   }

   /* Check consistency */
   while (sInfo.length != 0)
   {
      /* Check if enough room to read length */
      if (sInfo.length < sizeof(sInfo.length))
      {
         return NFCSTATUS_FAILED;
      }
      /* Read length */
      length = (sInfo.buffer[0] << 8) | sInfo.buffer[1];
      /* Update info buffer */
      sInfo.buffer += 2; /*Size of length field is 2*/
      sInfo.length -= 2; /*Size of length field is 2*/
      /* Check if declared length fits in remaining space */
      if (length > sInfo.length)
      {
         return NFCSTATUS_FAILED;
      }
      /* Update info buffer */
      sInfo.buffer += length;
      sInfo.length -= length;
   }

   /* Get info field */
   sInfo.buffer = psRawPacket->buffer + PHFRINFC_LLCP_PACKET_HEADER_SIZE;
   sInfo.length = psRawPacket->length - PHFRINFC_LLCP_PACKET_HEADER_SIZE;

   /* Handle aggregated packets */
   while (sInfo.length != 0)
   {
      /* Read length */
      length = (sInfo.buffer[0] << 8) | sInfo.buffer[1];
      /* Update info buffer */
      sInfo.buffer += 2;        /* Size of length field is 2 */
      sInfo.length -= 2;    /*Size of length field is 2*/
      /* Handle aggregated packet */
      sCurrentInfo.buffer=sInfo.buffer;
      sCurrentInfo.length=length;
      status = phFriNfc_Llcp_HandleIncomingPacket(Llcp, &sCurrentInfo);
      if ( (status != NFCSTATUS_SUCCESS) &&
           (status != NFCSTATUS_PENDING) )
      {
         /* TODO: Error: invalid frame */
      }
      /* Update info buffer */
      sInfo.buffer += length;
      sInfo.length -= length;
   }
   return NFCSTATUS_SUCCESS;
}


static NFCSTATUS phFriNfc_Llcp_ParseLinkParams( phNfc_sData_t                    *psParamsTLV,
                                                phFriNfc_Llcp_sLinkParameters_t  *psParsedParams,
                                                uint8_t                          *pnParsedVersion )
{
   NFCSTATUS                        status;
   uint8_t                          type;
   phFriNfc_Llcp_sLinkParameters_t  sParams;
   phNfc_sData_t                    sValueBuffer;
   uint32_t                         offset = 0;
   uint8_t                          version = PHFRINFC_LLCP_INVALID_VERSION;

   /* Check for NULL pointers */
   if ((psParamsTLV == NULL) || (psParsedParams == NULL) || (pnParsedVersion == NULL))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Prepare default param structure */
   sParams.miu    = PHFRINFC_LLCP_MIU_DEFAULT;
   sParams.wks    = PHFRINFC_LLCP_WKS_DEFAULT;
   sParams.lto    = PHFRINFC_LLCP_LTO_DEFAULT;
   sParams.option = PHFRINFC_LLCP_OPTION_DEFAULT;

   /* Decode TLV */
   while (offset < psParamsTLV->length)
   {
      status = phFriNfc_Llcp_DecodeTLV(psParamsTLV, &offset, &type, &sValueBuffer);
      if (status != NFCSTATUS_SUCCESS)
      {
         /* Error: Ill-formed TLV */
         return status;
      }
      switch(type)
      {
         case PHFRINFC_LLCP_TLV_TYPE_VERSION:
         {
            /* Check length */
            if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_VERSION)
            {
               /* Error : Ill-formed VERSION parameter TLV */
               break;
            }
            /* Get VERSION */
            version = sValueBuffer.buffer[0];
            break;
         }
         case PHFRINFC_LLCP_TLV_TYPE_MIUX:
         {
            /* Check length */
            if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_MIUX)
            {
               /* Error : Ill-formed MIUX parameter TLV */
               break;
            }
            /* Get MIU */
            sParams.miu = (PHFRINFC_LLCP_MIU_DEFAULT + ((sValueBuffer.buffer[0] << 8) | sValueBuffer.buffer[1])) & PHFRINFC_LLCP_TLV_MIUX_MASK;
            break;
         }
         case PHFRINFC_LLCP_TLV_TYPE_WKS:
         {
            /* Check length */
            if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_WKS)
            {
               /* Error : Ill-formed MIUX parameter TLV */
               break;
            }
            /* Get WKS */
            sParams.wks = (sValueBuffer.buffer[0] << 8) | sValueBuffer.buffer[1];
            /* Ignored bits must always be set */
            sParams.wks |= PHFRINFC_LLCP_TLV_WKS_MASK;
            break;
         }
         case PHFRINFC_LLCP_TLV_TYPE_LTO:
         {
            /* Check length */
            if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_LTO)
            {
               /* Error : Ill-formed LTO parameter TLV */
               break;
            }
            /* Get LTO */
            sParams.lto = sValueBuffer.buffer[0];
            break;
         }
         case PHFRINFC_LLCP_TLV_TYPE_OPT:
         {
            /* Check length */
            if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_OPT)
            {
               /* Error : Ill-formed OPT parameter TLV */
               break;;
            }
            /* Get OPT */
            sParams.option = sValueBuffer.buffer[0] & PHFRINFC_LLCP_TLV_OPT_MASK;
            break;
         }
         default:
         {
            /* Error : Unknown Type */
            break;
         }
      }
   }

   /* Check if a VERSION parameter has been provided */
   if (version == PHFRINFC_LLCP_INVALID_VERSION)
   {
      /* Error : Mandatory VERSION parameter not provided */
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Save response */
   *pnParsedVersion = version;
   memcpy(psParsedParams, &sParams, sizeof(phFriNfc_Llcp_sLinkParameters_t));

   return NFCSTATUS_SUCCESS;
}


static NFCSTATUS phFriNfc_Llcp_VersionAgreement( uint8_t localVersion,
                                                 uint8_t remoteVersion,
                                                 uint8_t *pNegociatedVersion )
{
   uint8_t     localMajor  = localVersion  & PHFRINFC_LLCP_VERSION_MAJOR_MASK;
   uint8_t     localMinor  = localVersion  & PHFRINFC_LLCP_VERSION_MINOR_MASK;
   uint8_t     remoteMajor = remoteVersion & PHFRINFC_LLCP_VERSION_MAJOR_MASK;
   uint8_t     remoteMinor = remoteVersion & PHFRINFC_LLCP_VERSION_MINOR_MASK;
   uint8_t     negociatedVersion;

   /* Check for NULL pointers */
   if (pNegociatedVersion == NULL)
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Compare Major numbers */
   if (localMajor == remoteMajor)
   {
      /* Version agreement succeed : use lowest version */
      negociatedVersion = localMajor | ((remoteMinor<localMinor)?remoteMinor:localMinor);
   }
   else if (localMajor > remoteMajor)
   {
      /* Decide if versions are compatible */
      /* Currently, there is no backward compatibility to handle */
      return NFCSTATUS_FAILED;
   }
   else /* if (localMajor < remoteMajor) */
   {
      /* It is up to the remote host to decide if versions are compatible */
      /* Set negociated version to our local version, the remote will
         deacivate the link if its own version agreement fails */
      negociatedVersion = localVersion;
   }

   /* Save response */
   *pNegociatedVersion = negociatedVersion;

   return NFCSTATUS_SUCCESS;
}


static NFCSTATUS phFriNfc_Llcp_InternalActivate( phFriNfc_Llcp_t *Llcp,
                                                 phNfc_sData_t   *psParamsTLV)
{
   NFCSTATUS                        status;
   phFriNfc_Llcp_sLinkParameters_t  sRemoteParams;
   uint8_t                          remoteVersion;
   uint8_t                          negociatedVersion;
   const uint16_t nMaxHeaderSize =  PHFRINFC_LLCP_PACKET_HEADER_SIZE +
                                    PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;

   /* Parse parameters  */
   status = phFriNfc_Llcp_ParseLinkParams(psParamsTLV, &sRemoteParams, &remoteVersion);
   if (status != NFCSTATUS_SUCCESS)
   {
      /* Error: invalid parameters TLV */
      status = NFCSTATUS_FAILED;
   }
   else
   {
      /* Version agreement procedure */
      status = phFriNfc_Llcp_VersionAgreement(PHFRINFC_LLCP_VERSION , remoteVersion, &negociatedVersion);
      if (status != NFCSTATUS_SUCCESS)
      {
         /* Error: version agreement failed */
         status = NFCSTATUS_FAILED;
      }
      else
      {
         /* Save parameters */
         Llcp->version = negociatedVersion;
         memcpy(&Llcp->sRemoteParams, &sRemoteParams, sizeof(phFriNfc_Llcp_sLinkParameters_t));

         /* Update remote MIU to match local Tx buffer size */
         if (Llcp->nTxBufferLength < (Llcp->sRemoteParams.miu + nMaxHeaderSize))
         {
            Llcp->sRemoteParams.miu = Llcp->nTxBufferLength - nMaxHeaderSize;
         }

         /* Initiate Symmetry procedure by resetting LTO timer */
         /* NOTE: this also updates current state */
         phFriNfc_Llcp_ResetLTO(Llcp);
      }
   }

   /* Notify upper layer, if Activation failed CB called by Deactivate */
   if (status == NFCSTATUS_SUCCESS)
   {
      /* Link activated ! */
      Llcp->pfLink_CB(Llcp->pLinkContext, phFriNfc_LlcpMac_eLinkActivated);
   }

   return status;
}


static NFCSTATUS phFriNfc_Llcp_HandleMACLinkActivated( phFriNfc_Llcp_t  *Llcp,
                                                       phNfc_sData_t    *psParamsTLV)
{
   NFCSTATUS                     status = NFCSTATUS_SUCCESS;

   /* Create the timer */
   Llcp->hSymmTimer = phOsalNfc_Timer_Create();
   if (Llcp->hSymmTimer == PH_OSALNFC_INVALID_TIMER_ID)
   {
      /* Error: unable to create timer */
      return NFCSTATUS_INSUFFICIENT_RESOURCES;
   }

   /* Check if params received from MAC activation procedure */
   if (psParamsTLV == NULL)
   {
      /* No params with selected MAC mapping, enter PAX mode for parameter exchange */
      Llcp->state = PHFRINFC_LLCP_STATE_PAX;
      /* Set default MIU for PAX exchange */
      Llcp->sRemoteParams.miu = PHFRINFC_LLCP_MIU_DEFAULT;
      /* If the local device is the initiator, it must initiate PAX exchange */
      if (Llcp->eRole == phFriNfc_LlcpMac_ePeerTypeInitiator)
      {
         /* Send PAX */
         status = phFriNfc_Llcp_SendPax(Llcp, &Llcp->sLocalParams);
      }
   }
   else
   {
      /* Params exchanged during MAX activation, try LLC activation */
      status = phFriNfc_Llcp_InternalActivate(Llcp, psParamsTLV);
   }

   if (status == NFCSTATUS_SUCCESS)
   {
      /* Start listening for incoming packets */
      Llcp->sRxBuffer.length = Llcp->nRxBufferLength;
      phFriNfc_LlcpMac_Receive(&Llcp->MAC, &Llcp->sRxBuffer, phFriNfc_Llcp_Receive_CB, Llcp);
   }

   return status;
}


static void phFriNfc_Llcp_HandleMACLinkDeactivated( phFriNfc_Llcp_t  *Llcp )
{
   uint8_t state = Llcp->state;

   /* Delete the timer */
   if (Llcp->hSymmTimer != PH_OSALNFC_INVALID_TIMER_ID)
   {
      phOsalNfc_Timer_Delete(Llcp->hSymmTimer);
   }

   /* Reset state */
   Llcp->state = PHFRINFC_LLCP_STATE_DEACTIVATION;

   switch (state)
   {
      case PHFRINFC_LLCP_STATE_DEACTIVATION:
      {
         /* The service layer has already been notified, nothing more to do */
         break;
      }
      default:
      {
         /* Notify service layer of link failure */
         Llcp->pfLink_CB(Llcp->pLinkContext, phFriNfc_LlcpMac_eLinkDeactivated);
         break;
      }
   }
}


static void phFriNfc_Llcp_ChkLlcp_CB( void       *pContext,
                                      NFCSTATUS  status )
{
   /* Get monitor from context */
   phFriNfc_Llcp_t *Llcp = (phFriNfc_Llcp_t*)pContext;

   /* Update state */
   Llcp->state = PHFRINFC_LLCP_STATE_CHECKED;

   /* Invoke callback */
   Llcp->pfChk_CB(Llcp->pChkContext, status);
}

static void phFriNfc_Llcp_LinkStatus_CB( void                              *pContext,
                                         phFriNfc_LlcpMac_eLinkStatus_t    eLinkStatus,
                                         phNfc_sData_t                     *psParamsTLV,
                                         phFriNfc_LlcpMac_ePeerType_t      PeerRemoteDevType)
{
   NFCSTATUS status;

   /* Get monitor from context */
   phFriNfc_Llcp_t *Llcp = (phFriNfc_Llcp_t*)pContext;

   /* Save the local peer role (initiator/target) */
   Llcp->eRole = PeerRemoteDevType;

   /* Check new link status */
   switch(eLinkStatus)
   {
      case phFriNfc_LlcpMac_eLinkActivated:
      {
         /* Handle MAC link activation */
         status = phFriNfc_Llcp_HandleMACLinkActivated(Llcp, psParamsTLV);
         if (status != NFCSTATUS_SUCCESS)
         {
            /* Error: LLC link activation procedure failed, deactivate MAC link */
            status = phFriNfc_Llcp_InternalDeactivate(Llcp);
         }
         break;
      }
      case phFriNfc_LlcpMac_eLinkDeactivated:
      {
         /* Handle MAC link deactivation (cannot fail) */
         phFriNfc_Llcp_HandleMACLinkDeactivated(Llcp);
         break;
      }
      default:
      {
         /* Warning: Unknown link status, should not happen */
      }
   }
}


static void phFriNfc_Llcp_ResetLTO( phFriNfc_Llcp_t *Llcp )
{
   uint32_t nDuration;

   /* Stop timer */
   phOsalNfc_Timer_Stop(Llcp->hSymmTimer);


   /* Update state */
   if (Llcp->state == PHFRINFC_LLCP_STATE_OPERATION_RECV)
   {
      Llcp->state = PHFRINFC_LLCP_STATE_OPERATION_SEND;
   }
   else if (Llcp->state == PHFRINFC_LLCP_STATE_OPERATION_SEND)
   {
      Llcp->state = PHFRINFC_LLCP_STATE_OPERATION_RECV;
   }
   else if (Llcp->state != PHFRINFC_LLCP_STATE_DEACTIVATION)
   {
      /* Not yet in OPERATION state, perform first reset */
      if (Llcp->eRole == phFriNfc_LlcpMac_ePeerTypeInitiator)
      {
         Llcp->state = PHFRINFC_LLCP_STATE_OPERATION_SEND;
      }
      else
      {
         Llcp->state = PHFRINFC_LLCP_STATE_OPERATION_RECV;
      }
   }

   /* Calculate timer duration */
   /* NOTE: nDuration is in 1/100s, and timer system takes values in 1/1000s */
   if (Llcp->state == PHFRINFC_LLCP_STATE_OPERATION_RECV)
   {
      /* Response must be received before LTO announced by remote peer */
      nDuration = Llcp->sRemoteParams.lto * 10;
   }
   else
   {
      /* Must answer before the local announced LTO */
      /* NOTE: to ensure the answer is completely sent before LTO, the
               timer is triggered _before_ LTO expiration */
      /* TODO: make sure time scope is enough, and avoid use of magic number */
      nDuration = (Llcp->sLocalParams.lto * 10) / 2;
   }

   LLCP_DEBUG("Starting LLCP timer with duration %d", nDuration);

   /* Restart timer */
   phOsalNfc_Timer_Start(
      Llcp->hSymmTimer,
      nDuration,
      phFriNfc_Llcp_Timer_CB,
      Llcp);
}


static NFCSTATUS phFriNfc_Llcp_HandleLinkPacket( phFriNfc_Llcp_t    *Llcp,
                                                 phNfc_sData_t      *psPacket )
{
   NFCSTATUS                        result;
   phFriNfc_Llcp_sPacketHeader_t    sHeader;

   /* Parse header */
   phFriNfc_Llcp_Buffer2Header(psPacket->buffer, 0, &sHeader);

   /* Check packet type */
   switch (sHeader.ptype)
   {
      case PHFRINFC_LLCP_PTYPE_SYMM:
      {
         /* Nothing to do, the LTO is handled upon all packet reception */
         result = NFCSTATUS_SUCCESS;
         break;
      }
      
      case PHFRINFC_LLCP_PTYPE_AGF:
      {
         /* Handle the aggregated packet */
         result = phFriNfc_Llcp_HandleAggregatedPacket(Llcp, psPacket);
         if (result != NFCSTATUS_SUCCESS)
         {
            /* Error: invalid info field, dropping frame */
         }
         break;
      }
      
      case PHFRINFC_LLCP_PTYPE_DISC:
      {
         /* Handle link disconnection request */
         result = phFriNfc_Llcp_InternalDeactivate(Llcp);
         break;
      }
      
     
      case PHFRINFC_LLCP_PTYPE_FRMR:
      {
         /* TODO: what to do upon reception of FRMR on Link SAP ? */
         result = NFCSTATUS_SUCCESS;
         break;
      }

      case PHFRINFC_LLCP_PTYPE_PAX:
      {
         /* Ignore PAX when in Normal Operation */
         result = NFCSTATUS_SUCCESS;
         break;
      }

      default:
      {
         /* Error: invalid ptype field, dropping packet */
         break;
      }
   }

   return result;
}


static NFCSTATUS phFriNfc_Llcp_HandleTransportPacket( phFriNfc_Llcp_t    *Llcp,
                                                      phNfc_sData_t      *psPacket )
{
   phFriNfc_Llcp_Recv_CB_t          pfRecvCB;
   void                             *pContext;
   NFCSTATUS                        result = NFCSTATUS_SUCCESS;
   phFriNfc_Llcp_sPacketHeader_t    sHeader;

   /* Forward to upper layer */
   if (Llcp->pfRecvCB != NULL)
   {
      /* Get callback details */
      pfRecvCB = Llcp->pfRecvCB;
      pContext = Llcp->pRecvContext;
      /* Reset callback details */
      Llcp->pfRecvCB = NULL;
      Llcp->pRecvContext = NULL;
      /* Call the callback */
      (pfRecvCB)(pContext, psPacket, NFCSTATUS_SUCCESS);
   }

   return result;
}


static bool_t phFriNfc_Llcp_HandlePendingSend ( phFriNfc_Llcp_t *Llcp )
{
   phFriNfc_Llcp_sPacketHeader_t    sHeader;
   phNfc_sData_t                    sInfoBuffer;
   phFriNfc_Llcp_sPacketHeader_t    *psSendHeader = NULL;
   phFriNfc_Llcp_sPacketSequence_t  *psSendSequence = NULL;
   phNfc_sData_t                    *psSendInfo = NULL;
   NFCSTATUS                        result;
   uint8_t                          bDeallocate = FALSE;
   uint8_t                          return_value = FALSE;

   /* Handle pending disconnection request */
   if (Llcp->bDiscPendingFlag == TRUE)
   {
      /* Last send si acheived, send the pending DISC packet */
      sHeader.dsap  = PHFRINFC_LLCP_SAP_LINK;
      sHeader.ssap  = PHFRINFC_LLCP_SAP_LINK;
      sHeader.ptype = PHFRINFC_LLCP_PTYPE_DISC;
      /* Set send params */
      psSendHeader = &sHeader;
      /* Reset flag */
      Llcp->bDiscPendingFlag = FALSE;
   }
   /* Handle pending frame reject request */
   else if (Llcp->bFrmrPendingFlag == TRUE)
   {
      /* Last send si acheived, send the pending FRMR packet */
      sInfoBuffer.buffer = Llcp->pFrmrInfo;
      sInfoBuffer.length = sizeof(Llcp->pFrmrInfo);
      /* Set send params */
      psSendHeader = &Llcp->sFrmrHeader;
      psSendInfo   = &sInfoBuffer;
      /* Reset flag */
      Llcp->bFrmrPendingFlag = FALSE;
   }
   /* Handle pending service frame */
   else if (Llcp->pfSendCB != NULL)
   {
      /* Set send params */
      psSendHeader = Llcp->psSendHeader;
      psSendSequence = Llcp->psSendSequence;
      psSendInfo = Llcp->psSendInfo;
      /* Reset pending send infos */
      Llcp->psSendHeader = NULL;
      Llcp->psSendSequence = NULL;
      Llcp->psSendInfo = NULL;
      bDeallocate = TRUE;
   }

   /* Perform send, if needed */
   if (psSendHeader != NULL)
   {
      result = phFriNfc_Llcp_InternalSend(Llcp, psSendHeader, psSendSequence, psSendInfo);
      if ((result != NFCSTATUS_SUCCESS) && (result != NFCSTATUS_PENDING))
      {
         /* Error: send failed, impossible to recover */
         phFriNfc_Llcp_InternalDeactivate(Llcp);
      }
      return_value = TRUE;
   } else if (Llcp->pfSendCB == NULL) {
      // Nothing to send, send SYMM instead to allow peer to send something
      // if it wants.
      phFriNfc_Llcp_SendSymm(Llcp);
      return_value = TRUE;
   }

clean_and_return:
   if (bDeallocate)
   {
       phFriNfc_Llcp_Deallocate(psSendInfo);
   }

   return return_value;
}

static NFCSTATUS phFriNfc_Llcp_HandleIncomingPacket( phFriNfc_Llcp_t    *Llcp,
                                                     phNfc_sData_t      *psPacket )
{
   NFCSTATUS                        status = NFCSTATUS_SUCCESS;
   phFriNfc_Llcp_sPacketHeader_t    sHeader;

   /* Parse header */
   phFriNfc_Llcp_Buffer2Header(psPacket->buffer, 0, &sHeader);

   /* Check destination */
   if (sHeader.dsap == PHFRINFC_LLCP_SAP_LINK)
   {
      /* Handle packet as destinated to the Link SAP */
      status = phFriNfc_Llcp_HandleLinkPacket(Llcp, psPacket);
   }
   else if (sHeader.dsap >= PHFRINFC_LLCP_SAP_NUMBER)
   {
     /* NOTE: this cannot happen since "psHeader->dsap" is only 6-bit wide */
     status = NFCSTATUS_FAILED;
   }
   else
   {
      /* Handle packet as destinated to the SDP and transport SAPs */
      status = phFriNfc_Llcp_HandleTransportPacket(Llcp, psPacket);
   }
   return status;
}


static void phFriNfc_Llcp_Receive_CB( void               *pContext,
                                      NFCSTATUS          status,
                                      phNfc_sData_t      *psData)
{
   /* Get monitor from context */
   phFriNfc_Llcp_t               *Llcp = (phFriNfc_Llcp_t*)pContext;
   NFCSTATUS                     result = NFCSTATUS_SUCCESS;
   phFriNfc_Llcp_sPacketHeader_t sPacketHeader;

   /* Check reception status and for pending disconnection */
   if ((status != NFCSTATUS_SUCCESS) || (Llcp->bDiscPendingFlag == TRUE))
   {
	  LLCP_DEBUG("\nReceived LLCP packet error - status = 0x%04x", status);
      /* Reset disconnection operation */
      Llcp->bDiscPendingFlag = FALSE;
      /* Deactivate the link */
      phFriNfc_Llcp_InternalDeactivate(Llcp);
      return;
   }

   /* Parse header */
   phFriNfc_Llcp_Buffer2Header(psData->buffer, 0, &sPacketHeader);

   if (sPacketHeader.ptype != PHFRINFC_LLCP_PTYPE_SYMM)
   {
      LLCP_PRINT_BUFFER("\nReceived LLCP packet :", psData->buffer, psData->length);
   }
   else
   {
      LLCP_PRINT("?");
   }


   /* Check new link status */
   switch(Llcp->state)
   {
      /* Handle packets in PAX-waiting state */
      case PHFRINFC_LLCP_STATE_PAX:
      {
         /* Check packet type */
         if (sPacketHeader.ptype == PHFRINFC_LLCP_PTYPE_PAX)
         {
            /* Params exchanged during MAC activation, try LLC activation */
            result = phFriNfc_Llcp_InternalActivate(Llcp, psData+PHFRINFC_LLCP_PACKET_HEADER_SIZE);
            /* If the local LLC is the target, it must answer the PAX */
            if (Llcp->eRole == phFriNfc_LlcpMac_ePeerTypeTarget)
            {
               /* Send PAX */
               result = phFriNfc_Llcp_SendPax(Llcp, &Llcp->sLocalParams);
            }
         }
         else
         {
            /* Warning: Received packet with unhandled type in PAX-waiting state, drop it */
         }
         break;
      }

      /* Handle normal operation packets */
      case PHFRINFC_LLCP_STATE_OPERATION_RECV:
      case PHFRINFC_LLCP_STATE_OPERATION_SEND:
      {
         /* Handle Symmetry procedure by resetting LTO timer */
         phFriNfc_Llcp_ResetLTO(Llcp);
         /* Handle packet */
         result = phFriNfc_Llcp_HandleIncomingPacket(Llcp, psData);
         if ( (result != NFCSTATUS_SUCCESS) &&
              (result != NFCSTATUS_PENDING) )
         {
            /* TODO: Error: invalid frame */
         }
         /* Perform pending send request, if any */
         phFriNfc_Llcp_HandlePendingSend(Llcp);
         break;
      }

      default:
      {
         /* Warning: Should not receive packets in other states, drop them */
      }
   }

   /* Restart reception */
   Llcp->sRxBuffer.length = Llcp->nRxBufferLength;
   phFriNfc_LlcpMac_Receive(&Llcp->MAC, &Llcp->sRxBuffer, phFriNfc_Llcp_Receive_CB, Llcp);
}


static void phFriNfc_Llcp_Send_CB( void               *pContext,
                                   NFCSTATUS          status )
{
   /* Get monitor from context */
   phFriNfc_Llcp_t                  *Llcp = (phFriNfc_Llcp_t*)pContext;
   phFriNfc_Llcp_Send_CB_t          pfSendCB;
   void                             *pSendContext;

   /* Call the upper layer callback if last packet sent was  */
   /* NOTE: if Llcp->psSendHeader is not NULL, this means that the send operation is still not initiated */
   if (Llcp->psSendHeader == NULL)
   {
      if (Llcp->pfSendCB != NULL)
      {
         /* Get Callback params */
         pfSendCB = Llcp->pfSendCB;
         pSendContext = Llcp->pSendContext;
         /* Reset callback params */
         Llcp->pfSendCB = NULL;
         Llcp->pSendContext = NULL;
         /* Call the callback */
         (pfSendCB)(pSendContext, status);
      }
   }

   /* Check reception status */
   if (status != NFCSTATUS_SUCCESS)
   {
       /* Error: Reception failed, link must be down */
       phFriNfc_Llcp_InternalDeactivate(Llcp);
   }
}


static NFCSTATUS phFriNfc_Llcp_InternalSend( phFriNfc_Llcp_t                    *Llcp,
                                             phFriNfc_Llcp_sPacketHeader_t      *psHeader,
                                             phFriNfc_Llcp_sPacketSequence_t    *psSequence,
                                             phNfc_sData_t                      *psInfo )
{
   NFCSTATUS status;
   phNfc_sData_t  *psRawPacket = &Llcp->sTxBuffer; /* Use internal Tx buffer */

   /* Handle Symmetry procedure */
   phFriNfc_Llcp_ResetLTO(Llcp);

   /* Generate raw packet to send (aggregate header + sequence + info fields) */
   psRawPacket->length = 0;
   psRawPacket->length += phFriNfc_Llcp_Header2Buffer(psHeader, psRawPacket->buffer, psRawPacket->length);
   if (psSequence != NULL)
   {
      psRawPacket->length += phFriNfc_Llcp_Sequence2Buffer(psSequence, psRawPacket->buffer, psRawPacket->length);
   }
   if (psInfo != NULL)
   {
      memcpy(psRawPacket->buffer + psRawPacket->length, psInfo->buffer, psInfo->length);
      psRawPacket->length += psInfo->length;
   }

   if (psHeader->ptype != PHFRINFC_LLCP_PTYPE_SYMM)
   {
      LLCP_PRINT_BUFFER("\nSending LLCP packet :", psRawPacket->buffer, psRawPacket->length);
   }
   else
   {
      LLCP_PRINT("!");
   }

   /* Send raw packet */
   status = phFriNfc_LlcpMac_Send (
               &Llcp->MAC,
               psRawPacket,
               phFriNfc_Llcp_Send_CB,
               Llcp );

   return status;
}

/* ---------------------------- Public functions ------------------------------- */

NFCSTATUS phFriNfc_Llcp_EncodeLinkParams( phNfc_sData_t                   *psRawBuffer,
                                          phFriNfc_Llcp_sLinkParameters_t *psLinkParams,
                                          uint8_t                         nVersion )
{
   uint32_t    nOffset = 0;
   uint16_t    miux;
   uint16_t    wks;
   uint8_t     pValue[2];
   NFCSTATUS   result = NFCSTATUS_SUCCESS;

   /* Check parameters */
   if ((psRawBuffer == NULL) || (psLinkParams == NULL))
   {
      return NFCSTATUS_INVALID_PARAMETER;
   }

   /* Encode mandatory VERSION field */
   if (result == NFCSTATUS_SUCCESS)
   {
      result = phFriNfc_Llcp_EncodeTLV(
                  psRawBuffer,
                  &nOffset,
                  PHFRINFC_LLCP_TLV_TYPE_VERSION,
                  PHFRINFC_LLCP_TLV_LENGTH_VERSION,
                  &nVersion);
   }

   /* Encode mandatory VERSION field */
   if (result == NFCSTATUS_SUCCESS)
   {
      /* Encode MIUX field, if needed */
      if (psLinkParams->miu != PHFRINFC_LLCP_MIU_DEFAULT)
      {
         miux = (psLinkParams->miu - PHFRINFC_LLCP_MIU_DEFAULT) & PHFRINFC_LLCP_TLV_MIUX_MASK;
         pValue[0] = (miux >> 8) & 0xFF;
         pValue[1] =  miux       & 0xFF;
         result = phFriNfc_Llcp_EncodeTLV(
                     psRawBuffer,
                     &nOffset,
                     PHFRINFC_LLCP_TLV_TYPE_MIUX,
                     PHFRINFC_LLCP_TLV_LENGTH_MIUX,
                     pValue);
      }
   }

   /* Encode WKS field */
   if (result == NFCSTATUS_SUCCESS)
   {
      wks = psLinkParams->wks | PHFRINFC_LLCP_TLV_WKS_MASK;
      pValue[0] = (wks >> 8) & 0xFF;
      pValue[1] =  wks       & 0xFF;
      result = phFriNfc_Llcp_EncodeTLV(
                  psRawBuffer,
                  &nOffset,
                  PHFRINFC_LLCP_TLV_TYPE_WKS,
                  PHFRINFC_LLCP_TLV_LENGTH_WKS,
                  pValue);
   }

   /* Encode LTO field, if needed */
   if (result == NFCSTATUS_SUCCESS)
   {
      if (psLinkParams->lto != PHFRINFC_LLCP_LTO_DEFAULT)
      {
         result = phFriNfc_Llcp_EncodeTLV(
                     psRawBuffer,
                     &nOffset,
                     PHFRINFC_LLCP_TLV_TYPE_LTO,
                     PHFRINFC_LLCP_TLV_LENGTH_LTO,
                     &psLinkParams->lto);
      }
   }

   /* Encode OPT field, if needed */
   if (result == NFCSTATUS_SUCCESS)
   {
      if (psLinkParams->option != PHFRINFC_LLCP_OPTION_DEFAULT)
      {
         result = phFriNfc_Llcp_EncodeTLV(
                     psRawBuffer,
                     &nOffset,
                     PHFRINFC_LLCP_TLV_TYPE_OPT,
                     PHFRINFC_LLCP_TLV_LENGTH_OPT,
                     &psLinkParams->option);
      }
   }

   if (result != NFCSTATUS_SUCCESS)
   {
      /* Error: failed to encode TLV */
      return NFCSTATUS_FAILED;
   }

   /* Save new buffer size */
   psRawBuffer->length = nOffset;

   return result;
}


NFCSTATUS phFriNfc_Llcp_Reset( phFriNfc_Llcp_t                 *Llcp,
                               void                            *LowerDevice,
                               phFriNfc_Llcp_sLinkParameters_t *psLinkParams,
                               void                            *pRxBuffer,
                               uint16_t                        nRxBufferLength,
                               void                            *pTxBuffer,
                               uint16_t                        nTxBufferLength,
                               phFriNfc_Llcp_LinkStatus_CB_t   pfLink_CB,
                               void                            *pContext )
{
   const uint16_t nMaxHeaderSize =  PHFRINFC_LLCP_PACKET_HEADER_SIZE +
                                    PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;
   NFCSTATUS result;

   /* Check parameters presence */
   if ((Llcp == NULL) || (LowerDevice == NULL) || (pfLink_CB == NULL) ||
       (pRxBuffer == NULL) || (pTxBuffer == NULL) )
   {
      return NFCSTATUS_INVALID_PARAMETER;
   }

   /* Check parameters value */
   if (psLinkParams->miu < PHFRINFC_LLCP_MIU_DEFAULT)
   {
      return NFCSTATUS_INVALID_PARAMETER;
   }

   /* Check if buffers are large enough to support minimal MIU */
   if ((nRxBufferLength < (nMaxHeaderSize + PHFRINFC_LLCP_MIU_DEFAULT)) ||
       (nTxBufferLength < (nMaxHeaderSize + PHFRINFC_LLCP_MIU_DEFAULT)) )
   {
      return NFCSTATUS_BUFFER_TOO_SMALL;
   }

   /* Check compatibility between reception buffer size and announced MIU */
   if (nRxBufferLength < (nMaxHeaderSize + psLinkParams->miu))
   {
      return NFCSTATUS_BUFFER_TOO_SMALL;
   }

   /* Start with a zero-filled monitor */
   memset(Llcp, 0x00, sizeof(phFriNfc_Llcp_t));

   /* Reset the MAC Mapping layer */
   result = phFriNfc_LlcpMac_Reset(&Llcp->MAC, LowerDevice, phFriNfc_Llcp_LinkStatus_CB, Llcp);
   if (result != NFCSTATUS_SUCCESS) {
      return result;
   }

   /* Save the working buffers */
   Llcp->sRxBuffer.buffer = pRxBuffer;
   Llcp->sRxBuffer.length = nRxBufferLength;
   Llcp->nRxBufferLength = nRxBufferLength;
   Llcp->sTxBuffer.buffer = pTxBuffer;
   Llcp->sTxBuffer.length = nTxBufferLength;
   Llcp->nTxBufferLength = nTxBufferLength;

   /* Save the link status callback references */
   Llcp->pfLink_CB = pfLink_CB;
   Llcp->pLinkContext = pContext;

   /* Save the local link parameters */
   memcpy(&Llcp->sLocalParams, psLinkParams, sizeof(phFriNfc_Llcp_sLinkParameters_t));

   return NFCSTATUS_SUCCESS;
}


NFCSTATUS phFriNfc_Llcp_ChkLlcp( phFriNfc_Llcp_t               *Llcp,
                                 phHal_sRemoteDevInformation_t *psRemoteDevInfo,
                                 phFriNfc_Llcp_Check_CB_t      pfCheck_CB,
                                 void                          *pContext )
{
   /* Check parameters */
   if ( (Llcp == NULL) || (psRemoteDevInfo == NULL) || (pfCheck_CB == NULL) )
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Check current state */
   if( Llcp->state != PHFRINFC_LLCP_STATE_RESET_INIT ) {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_STATE);
   }

   /* Save the compliance check callback */
   Llcp->pfChk_CB = pfCheck_CB;
   Llcp->pChkContext = pContext;

   /* Forward check request to MAC layer */
   return phFriNfc_LlcpMac_ChkLlcp(&Llcp->MAC, psRemoteDevInfo, phFriNfc_Llcp_ChkLlcp_CB, (void*)Llcp);
}


NFCSTATUS phFriNfc_Llcp_Activate( phFriNfc_Llcp_t *Llcp )
{
   /* Check parameters */
   if (Llcp == NULL)
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Check current state */
   if( Llcp->state != PHFRINFC_LLCP_STATE_CHECKED ) {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_STATE);
   }

   /* Update state */
   Llcp->state = PHFRINFC_LLCP_STATE_ACTIVATION;

   /* Forward check request to MAC layer */
   return phFriNfc_LlcpMac_Activate(&Llcp->MAC);
}


NFCSTATUS phFriNfc_Llcp_Deactivate( phFriNfc_Llcp_t *Llcp )
{
   NFCSTATUS status;

   /* Check parameters */
   if (Llcp == NULL)
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Check current state */
   if( (Llcp->state != PHFRINFC_LLCP_STATE_OPERATION_RECV) &&
       (Llcp->state != PHFRINFC_LLCP_STATE_OPERATION_SEND) ) {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_STATE);
   }

   /* Send DISC packet */
   status = phFriNfc_Llcp_SendDisconnect(Llcp);
   if (status == NFCSTATUS_PENDING)
   {
      /* Wait for packet to be sent before deactivate link */
      return status;
   }

   /* Perform actual deactivation */
   return phFriNfc_Llcp_InternalDeactivate(Llcp);
}


NFCSTATUS phFriNfc_Llcp_GetLocalInfo( phFriNfc_Llcp_t                   *Llcp,
                                      phFriNfc_Llcp_sLinkParameters_t   *pParams )
{
   /* Check parameters */
   if ((Llcp == NULL) || (pParams == NULL))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Copy response */
   memcpy(pParams, &Llcp->sLocalParams, sizeof(phFriNfc_Llcp_sLinkParameters_t));

   return NFCSTATUS_SUCCESS;
}


NFCSTATUS phFriNfc_Llcp_GetRemoteInfo( phFriNfc_Llcp_t                  *Llcp,
                                       phFriNfc_Llcp_sLinkParameters_t  *pParams )
{
   /* Check parameters */
   if ((Llcp == NULL) || (pParams == NULL))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Copy response */
   memcpy(pParams, &Llcp->sRemoteParams, sizeof(phFriNfc_Llcp_sLinkParameters_t));

   return NFCSTATUS_SUCCESS;
}


NFCSTATUS phFriNfc_Llcp_Send( phFriNfc_Llcp_t                  *Llcp,
                              phFriNfc_Llcp_sPacketHeader_t    *psHeader,
                              phFriNfc_Llcp_sPacketSequence_t  *psSequence,
                              phNfc_sData_t                    *psInfo,
                              phFriNfc_Llcp_Send_CB_t          pfSend_CB,
                              void                             *pContext )
{
   NFCSTATUS result;

   /* Check parameters */
   if ((Llcp == NULL) || (psHeader == NULL) || (pfSend_CB == NULL))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Check if previous phFriNfc_Llcp_Send() has finished */
   if (Llcp->pfSendCB != NULL)
   {
      /* Error: a send operation is already running */
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_REJECTED);
   }

   /* Save the callback parameters */
   Llcp->pfSendCB = pfSend_CB;
   Llcp->pSendContext = pContext;

   if (Llcp->state == PHFRINFC_LLCP_STATE_OPERATION_SEND)
   {
      /* Ready to send */
      result = phFriNfc_Llcp_InternalSend(Llcp, psHeader, psSequence, psInfo);
   }
   else if (Llcp->state == PHFRINFC_LLCP_STATE_OPERATION_RECV)
   {
      /* Not ready to send, save send params for later use */
      Llcp->psSendHeader = psHeader;
      Llcp->psSendSequence = psSequence;
      Llcp->psSendInfo = phFriNfc_Llcp_AllocateAndCopy(psInfo);
      result = NFCSTATUS_PENDING;
   }
   else
   {
      /* Incorrect state for sending ! */
      result = PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_STATE);;
   }

   if (result != NFCSTATUS_PENDING) {
       Llcp->pfSendCB = NULL;
   }
   return result;
}


NFCSTATUS phFriNfc_Llcp_Recv( phFriNfc_Llcp_t            *Llcp,
                              phFriNfc_Llcp_Recv_CB_t    pfRecv_CB,
                              void                       *pContext )
{
   NFCSTATUS result = NFCSTATUS_SUCCESS;

   /* Check parameters */
   if ((Llcp == NULL) || (pfRecv_CB == NULL))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Check if previous phFriNfc_Llcp_Recv() has finished */
   if (Llcp->pfRecvCB != NULL)
   {
      /* Error: a send operation is already running */
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_REJECTED);
   }

   /* Save the callback parameters */
   Llcp->pfRecvCB = pfRecv_CB;
   Llcp->pRecvContext = pContext;

   /* NOTE: nothing more to do, the receive function is called in background */

   return result;
}
