/*
 * 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_LlcpTransport_Connection.c
 * \brief 
 *
 * Project: NFC-FRI
 *
 */
/*include files*/
#include <phOsalNfc.h>
#include <phLibNfcStatus.h>
#include <phLibNfc.h>
#include <phNfcLlcpTypes.h>
#include <phFriNfc_LlcpTransport.h>
#include <phFriNfc_LlcpTransport_Connection.h>
#include <phFriNfc_Llcp.h>
#include <phFriNfc_LlcpUtils.h>

/* Function definition */
static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_Socket_t*    pLlcpSocket);
static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket);

static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket);

/**********   End Function definition   ***********/

NFCSTATUS phFriNfc_LlcpConnTransport_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,
        phFriNfc_LlcpTransport_t*        psTransport ) {
    NFCSTATUS result = phFriNfc_Llcp_Send(Llcp, psHeader, psSequence, psInfo,
            pfSend_CB, psTransport);
    if (result == NFCSTATUS_PENDING) {
        psTransport->bSendPending = TRUE;
    }
    return result;
}

/* TODO: comment functionphFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB */
static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void*        pContext,
                                                                  NFCSTATUS    status)
{
   phFriNfc_LlcpTransport_t          *psTransport;
   phFriNfc_LlcpTransport_Socket_t    psTempLlcpSocket;
   phFriNfc_LlcpTransport_Socket_t   *psLocalLlcpSocket = NULL;
   phNfc_sData_t                     sFrmrBuffer;
   uint8_t                           index;
   uint8_t                           socketFound = FALSE;
   NFCSTATUS                         result;

   /* Get Send CB context */
   psTransport = (phFriNfc_LlcpTransport_t*)pContext;

   if(status == NFCSTATUS_SUCCESS)
   {
      /* Test the socket */
      switch(psTransport->pSocketTable[psTransport->socketIndex].eSocket_State)
      {
      case phFriNfc_LlcpTransportSocket_eSocketAccepted:
         {
            /* Set socket state to Connected */
            psTransport->pSocketTable[psTransport->socketIndex].eSocket_State  = phFriNfc_LlcpTransportSocket_eSocketConnected;
            /* Call the Accept Callback */
            psTransport->pSocketTable[psTransport->socketIndex].pfSocketAccept_Cb(psTransport->pSocketTable[psTransport->socketIndex].pAcceptContext,status);
            psTransport->pSocketTable[psTransport->socketIndex].pfSocketAccept_Cb = NULL;
            psTransport->pSocketTable[psTransport->socketIndex].pAcceptContext = NULL;
         }break;

      case phFriNfc_LlcpTransportSocket_eSocketRejected:
         {
            /* Store the Llcp socket in a local Llcp socket */
            psTempLlcpSocket = psTransport->pSocketTable[psTransport->socketIndex];

            /* Reset the socket  and set the socket state to default */
            result = phFriNfc_LlcpTransport_Close(&psTransport->pSocketTable[psTransport->socketIndex]);

            /* Call the Reject Callback */
            psTempLlcpSocket.pfSocketSend_Cb(psTempLlcpSocket.pRejectContext,status);
            psTempLlcpSocket.pfSocketSend_Cb = NULL;
         }break;

      case phFriNfc_LlcpTransportSocket_eSocketConnected:
         {
            if(!psTransport->pSocketTable[psTransport->socketIndex].bSocketSendPending && psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb != NULL)
            {
               psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb(psTransport->pSocketTable[psTransport->socketIndex].pSendContext,status);
               psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb = NULL;
            }
         }break;
      default:
         /* Nothing to do */
         break;
      }
   }
   else
   {
      /* Send CB error */
      if(!psTransport->pSocketTable[psTransport->socketIndex].bSocketSendPending && psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb != NULL)
      {
         psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb(psTransport->pSocketTable[psTransport->socketIndex].pSendContext,status);
         psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb = NULL;
      }
   }
}


NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_HandlePendingOperations(phFriNfc_LlcpTransport_Socket_t *pSocket)
{
   NFCSTATUS                  result = NFCSTATUS_FAILED;
   phFriNfc_LlcpTransport_t   *psTransport = pSocket->psTransport;

   /* I FRAME */
   if(pSocket->bSocketSendPending == TRUE)
   {
      /* Test the RW window */
      if(CHECK_SEND_RW(pSocket))
      {
         result = static_performSendInfo(pSocket);
      }
   }
   /* RR FRAME */
   else if(pSocket->bSocketRRPending == TRUE)
   {
      /* Reset RR pending */
      pSocket->bSocketRRPending = FALSE;

      /* Send RR Frame */
      result = phFriNfc_Llcp_Send_ReceiveReady_Frame(pSocket);
   }
   /* RNR Frame */
   else if(pSocket->bSocketRNRPending == TRUE)
   {
      /* Reset RNR pending */
      pSocket->bSocketRNRPending = FALSE;

      /* Send RNR Frame */
      result = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(pSocket);
   }
   /* CC Frame */
   else if(pSocket->bSocketAcceptPending == TRUE)
   {
      /* Reset Accept pending */
      pSocket->bSocketAcceptPending = FALSE;

      /* Fill the psLlcpHeader stuture with the DSAP,CC PTYPE and the SSAP */
      pSocket->sLlcpHeader.dsap  = pSocket->socket_dSap;
      pSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC;
      pSocket->sLlcpHeader.ssap  = pSocket->socket_sSap;

      /* Send Pending */
      pSocket->psTransport->bSendPending = TRUE;

      /* Set the socket state to accepted */
      pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketAccepted;

      /* Send a CC Frame */
      result =  phFriNfc_LlcpTransport_LinkSend(psTransport,
                                   &pSocket->sLlcpHeader,
                                   NULL,
                                   &pSocket->sSocketSendBuffer,
                                   phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
                                   psTransport);
   }
   /* CONNECT FRAME */
   else if(pSocket->bSocketConnectPending == TRUE)
   {
      /* Reset Accept pending */
      pSocket->bSocketConnectPending = FALSE;

      /* Send Pending */
      pSocket->psTransport->bSendPending = TRUE;

      /* Set the socket in connecting state */
      pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnecting;

      /* send CONNECT */
      result =  phFriNfc_LlcpTransport_LinkSend(psTransport,
                                 &pSocket->sLlcpHeader,
                                 NULL,
                                 &pSocket->sSocketSendBuffer,
                                 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
                                 psTransport);
   }
   /* DISC FRAME */
   else if(pSocket->bSocketDiscPending == TRUE)
   {
      /* Reset Disc Pending */
      pSocket->bSocketDiscPending = FALSE;

      /* Send Pending */
      pSocket->psTransport->bSendPending = TRUE;

      /* Set the socket in connecting state */
      pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;

      /* Send DISC */
      result =  phFriNfc_LlcpTransport_LinkSend(psTransport,
                                   &pSocket->sLlcpHeader,
                                   NULL,
                                   &pSocket->sSocketSendBuffer,
                                   phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
                                   psTransport);

      /* Call ErrCB due to a DISC */
      pSocket->pSocketErrCb(pSocket->pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
   }

   return result;
}

static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket)
{
   phFriNfc_LlcpTransport_t   *psTransport = psLlcpSocket->psTransport;
   NFCSTATUS                  status;

   /* Set transport send pending */
   psTransport->bSendPending = TRUE;

   /* Set the Header */
   psLlcpSocket->sLlcpHeader.dsap   = psLlcpSocket->socket_dSap;
   psLlcpSocket->sLlcpHeader.ptype  = PHFRINFC_LLCP_PTYPE_I;
   psLlcpSocket->sLlcpHeader.ssap   = psLlcpSocket->socket_sSap;

   /* Set Sequence Numbers */
   psLlcpSocket->sSequence.ns = psLlcpSocket->socket_VS;
   psLlcpSocket->sSequence.nr = psLlcpSocket->socket_VR;

   /* Update the VRA */
   psLlcpSocket->socket_VRA = psLlcpSocket->socket_VR;

   /* Store the index of the socket */
   psTransport->socketIndex = psLlcpSocket->index;

   /* Send I_PDU */
   status =  phFriNfc_LlcpTransport_LinkSend(psTransport,
                                &psLlcpSocket->sLlcpHeader,
                                &psLlcpSocket->sSequence,
                                &psLlcpSocket->sSocketSendBuffer,
                                phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
                                psLlcpSocket->psTransport);

   /* Update VS */
   psLlcpSocket->socket_VS = (psLlcpSocket->socket_VS+1)%16;

   /* Reset Send Pending */
   psLlcpSocket->bSocketSendPending = FALSE;

   return status;
}

static void phFriNfc_LlcpTransport_ConnectionOriented_Abort(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket)
{
   if (pLlcpSocket->pfSocketSend_Cb != NULL)
   {
      pLlcpSocket->pfSocketSend_Cb(pLlcpSocket->pSendContext, NFCSTATUS_ABORTED);
      pLlcpSocket->pfSocketSend_Cb = NULL;
   }
   pLlcpSocket->pSendContext = NULL;
   if (pLlcpSocket->pfSocketRecv_Cb != NULL)
   {
      pLlcpSocket->pfSocketRecv_Cb(pLlcpSocket->pRecvContext, NFCSTATUS_ABORTED);
      pLlcpSocket->pfSocketRecv_Cb = NULL;
   }
   pLlcpSocket->pRecvContext = NULL;
   if (pLlcpSocket->pfSocketAccept_Cb != NULL)
   {
      pLlcpSocket->pfSocketAccept_Cb(pLlcpSocket->pAcceptContext, NFCSTATUS_ABORTED);
      pLlcpSocket->pfSocketAccept_Cb = NULL;
   }
   pLlcpSocket->pAcceptContext = NULL;
   if (pLlcpSocket->pfSocketConnect_Cb != NULL)
   {
      pLlcpSocket->pfSocketConnect_Cb(pLlcpSocket->pConnectContext, 0, NFCSTATUS_ABORTED);
      pLlcpSocket->pfSocketConnect_Cb = NULL;
   }
   pLlcpSocket->pConnectContext = NULL;
   if (pLlcpSocket->pfSocketDisconnect_Cb != NULL)
   {
      pLlcpSocket->pfSocketDisconnect_Cb(pLlcpSocket->pDisonnectContext, NFCSTATUS_ABORTED);
      pLlcpSocket->pfSocketDisconnect_Cb = NULL;
   }
   pLlcpSocket->pDisonnectContext = NULL;

   pLlcpSocket->pfSocketRecvFrom_Cb = NULL;
   pLlcpSocket->pfSocketListen_Cb = NULL;
   pLlcpSocket->pListenContext = NULL;
}


static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_Socket_t*    pLlcpSocket)
{
   NFCSTATUS   status = NFCSTATUS_SUCCESS;

   /* Test if a send is pending */
   if(pLlcpSocket->psTransport->bSendPending == TRUE)
   {
      pLlcpSocket->bSocketRRPending = TRUE;
      status = NFCSTATUS_PENDING;
   }
   else
   {
      /* Set the header of the RR frame */
      pLlcpSocket->sLlcpHeader.dsap   = pLlcpSocket->socket_dSap;
      pLlcpSocket->sLlcpHeader.ptype  = PHFRINFC_LLCP_PTYPE_RR;
      pLlcpSocket->sLlcpHeader.ssap   = pLlcpSocket->socket_sSap;

      /* Set sequence number for RR Frame */
      pLlcpSocket->sSequence.ns = 0;
      pLlcpSocket->sSequence.nr = pLlcpSocket->socket_VR;

      /* Update VRA */
      pLlcpSocket->socket_VRA = (uint8_t)pLlcpSocket->sSequence.nr;

      /* Store the index of the socket */
      pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;

      /* Send RR frame */
      status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
                                   &pLlcpSocket->sLlcpHeader,
                                   &pLlcpSocket->sSequence,
                                   NULL,
                                   phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
                                   pLlcpSocket->psTransport);
   }

   return status;
}

static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket)
{
   NFCSTATUS   status = NFCSTATUS_SUCCESS;


   /* Test if a send is pending */
   if(pLlcpSocket->psTransport->bSendPending == TRUE)
   {
      pLlcpSocket->bSocketRNRPending = TRUE;
      status = NFCSTATUS_PENDING;
   }
   else
   {
      /* Set the header of the RNR frame */
      pLlcpSocket->sLlcpHeader.dsap   = pLlcpSocket->socket_dSap;
      pLlcpSocket->sLlcpHeader.ptype  = PHFRINFC_LLCP_PTYPE_RNR;
      pLlcpSocket->sLlcpHeader.ssap   = pLlcpSocket->socket_sSap;

      /* Set sequence number for RNR Frame */
      pLlcpSocket->sSequence.ns = 0x00;
      pLlcpSocket->sSequence.nr = pLlcpSocket->socket_VR;

      /* Update VRA */
      pLlcpSocket->socket_VRA = (uint8_t)pLlcpSocket->sSequence.nr;

      /* Store the index of the socket */
      pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;

      /* Send RNR frame */
      status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
                                   &pLlcpSocket->sLlcpHeader,
                                   &pLlcpSocket->sSequence,
                                   NULL,
                                   phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
                                   pLlcpSocket->psTransport);
   }
   return status;
}

static NFCSTATUS phFriNfc_Llcp_GetSocket_Params(phNfc_sData_t                    *psParamsTLV,
                                                phNfc_sData_t                    *psServiceName,
                                                uint8_t                          *pRemoteRW_Size,
                                                uint16_t                         *pRemoteMIU)
{
   NFCSTATUS         status = NFCSTATUS_SUCCESS;
   phNfc_sData_t     sValueBuffer;
   uint32_t          offset = 0;
   uint8_t           type;
   
   /* Check for NULL pointers */
   if ((psParamsTLV == NULL) || (pRemoteRW_Size == NULL) || (pRemoteMIU == NULL))
   {
      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      /* 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_SN:
            {
               /* Test if a SN is present in the TLV */
               if(sValueBuffer.length == 0)
               {
                  /* Error : Ill-formed SN parameter TLV */
                  break;
               }
               /* Get the Service Name */
               *psServiceName = sValueBuffer;
            }break;

            case PHFRINFC_LLCP_TLV_TYPE_RW:
            {
               /* Check length */
               if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_RW)
               {
                  /* Error : Ill-formed MIUX parameter TLV */
                  break;
               }
               *pRemoteRW_Size = 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;
               }
               *pRemoteMIU = PHFRINFC_LLCP_MIU_DEFAULT + (((sValueBuffer.buffer[0] << 8) | sValueBuffer.buffer[1]) & PHFRINFC_LLCP_TLV_MIUX_MASK);
            }break;

            default:
            {
               /* Error : Unknown type */
               break;
            }
         }
      }
   }
   return status;
}


/* TODO: comment function Handle_ConnectFrame */
static void Handle_ConnectionFrame(phFriNfc_LlcpTransport_t      *psTransport,
                                   phNfc_sData_t                 *psData,
                                   uint8_t                       dsap,
                                   uint8_t                       ssap)
{ 
   NFCSTATUS                         status = NFCSTATUS_SUCCESS;

   uint8_t                                   index;
   uint8_t                                   socketFound = FALSE;
   phFriNfc_LlcpTransport_Socket_t           *pLlcpSocket = NULL;
   phFriNfc_LlcpTransport_Socket_t           *psLocalLlcpSocket = NULL;
   pphFriNfc_LlcpTransportSocketListenCb_t   pListen_Cb = NULL;
   void                                      *pListenContext = NULL;

   phNfc_sData_t                             sServiceName;
   uint8_t                                   remoteRW  = PHFRINFC_LLCP_RW_DEFAULT;
   uint16_t                                  remoteMIU = PHFRINFC_LLCP_MIU_DEFAULT;

   status = phFriNfc_Llcp_GetSocket_Params(psData,
                                           &sServiceName,
                                           &remoteRW,
                                           &remoteMIU);

   if(status != NFCSTATUS_SUCCESS)
   {
      /* Incorrect TLV */
      /* send FRMR */ 
      status  = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
                                                       ssap,
                                                       PHFRINFC_LLCP_PTYPE_CONNECT,
                                                       dsap,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00);
   }
   else
   {
      if(dsap == PHFRINFC_LLCP_SAP_SDP)
      {
         /* Search a socket with the SN */
         for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
         {
            /* Test if the socket is in Listen state and if its SN is the good one */
            if(psTransport->pSocketTable[index].bSocketListenPending 
               &&  (sServiceName.length == psTransport->pSocketTable[index].sServiceName.length) 
               && !memcmp(sServiceName.buffer,psTransport->pSocketTable[index].sServiceName.buffer,sServiceName.length))
            {
               /* socket with the SN found */
               socketFound = TRUE;

               psLocalLlcpSocket = &psTransport->pSocketTable[index];

               /* Get the new ssap number, it is the ssap number of the socket found */
               dsap = psLocalLlcpSocket->socket_sSap;
               /* Get the ListenCB of the socket */
               pListen_Cb = psLocalLlcpSocket->pfSocketListen_Cb;
               pListenContext = psLocalLlcpSocket->pListenContext;
               break;
            }
         }
     } 
     else
     {
        /* Search a socket with the DSAP */
        for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
        {
           /* Test if the socket is in Listen state and if its port number is the good one */
           if(psTransport->pSocketTable[index].bSocketListenPending && psTransport->pSocketTable[index].socket_sSap == dsap)
           {
              /* socket with the SN found */
              socketFound = TRUE;

              psLocalLlcpSocket = &psTransport->pSocketTable[index];

              /* Get the Listen CB and the Context of the socket */
               pListen_Cb = psLocalLlcpSocket->pfSocketListen_Cb;
               pListenContext = psLocalLlcpSocket->pListenContext;
              break;
           }
        }
     }
   }

   /* Test if a socket has beeen found */
   if(socketFound)
   {
      /* Reset the FLAG socketFound*/
      socketFound = FALSE;

      /* Search a socket free and no socket connect on this DSAP*/
      for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
      {
         if(psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault && socketFound != TRUE)
         {
            socketFound = TRUE;

            psTransport->pSocketTable[index].index = index;
            psTransport->socketIndex = psTransport->pSocketTable[index].index;

            /* Create a communication socket */
            pLlcpSocket = &psTransport->pSocketTable[index];

            /* Set the communication option of the Remote Socket */
            pLlcpSocket->remoteMIU = remoteMIU;
            pLlcpSocket->remoteRW  = remoteRW;

            /* Set SSAP/DSAP of the new socket created for the communication with the remote */
            pLlcpSocket->socket_dSap = ssap;
            pLlcpSocket->socket_sSap = dsap;

            /* Set the state and the type of the new socket */
            pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
            pLlcpSocket->eSocket_Type  = phFriNfc_LlcpTransport_eConnectionOriented;
           
         }
         else if(((psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
                  || (psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketAccepted))
                  && ((psTransport->pSocketTable[index].socket_sSap == ssap)&&(psTransport->pSocketTable[index].socket_dSap == dsap)))
                  
         {
            socketFound = FALSE;
            
            if(pLlcpSocket != NULL)
            {
               /* Reset Socket Information */
               pLlcpSocket->remoteMIU = 0;
               pLlcpSocket->remoteRW  = 0;

               /* Set SSAP/DSAP of the new socket created for the communication with the remote */
               pLlcpSocket->socket_dSap = 0;
               pLlcpSocket->socket_sSap = 0;

               /* Set the state and the type of the new socket */
               pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDefault;
               pLlcpSocket->eSocket_Type  = phFriNfc_LlcpTransport_eDefaultType;
               break;
            }
         }
      }



      /* Test if a socket has been found */
      if(socketFound)
      {
         /* Call the Listen CB */
         pListen_Cb(pListenContext,pLlcpSocket);
      }
      else
      {
         /* No more socket are available */
         /* Send a DM (0x21) */
         status = phFriNfc_LlcpTransport_SendDisconnectMode (psTransport,
                                                             ssap,
                                                             dsap,
                                                             PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE);
      }
   }
   else
   {
      /* Service Name not found or Port number not found */
      /* Send a DM (0x02) */ 
      status = phFriNfc_LlcpTransport_SendDisconnectMode (psTransport,
                                                          ssap,
                                                          dsap,
                                                          PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND);
   }
}

/* TODO: comment function Handle_ConnectFrame */
static void Handle_ConnectionCompleteFrame(phFriNfc_LlcpTransport_t      *psTransport,
                                           phNfc_sData_t                 *psData,
                                           uint8_t                       dsap,
                                           uint8_t                       ssap)
{
   NFCSTATUS                          status = NFCSTATUS_SUCCESS;
   uint8_t                            index;
   uint8_t                            remoteRW  = PHFRINFC_LLCP_RW_DEFAULT;
   uint16_t                           remoteMIU = PHFRINFC_LLCP_MIU_DEFAULT;
   uint8_t                            socketFound = FALSE;
   phFriNfc_LlcpTransport_Socket_t*   psLocalLlcpSocket = NULL;

   status = phFriNfc_Llcp_GetSocket_Params(psData,
                                           NULL,
                                           &remoteRW,
                                           &remoteMIU);

   if(status != NFCSTATUS_SUCCESS)
   {
      /* Incorrect TLV */
      /* send FRMR */ 
      status  = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
                                                       ssap,
                                                       PHFRINFC_LLCP_PTYPE_CC,
                                                       dsap,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00);
   }
   else
   {
      /* Search a socket in connecting state and with the good SSAP */
      for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
      {
         /* Test if the socket is in Connecting state and if its SSAP number is the good one */
         if(psTransport->pSocketTable[index].eSocket_State  == phFriNfc_LlcpTransportSocket_eSocketConnecting 
            && psTransport->pSocketTable[index].socket_sSap == dsap)
         {
            /* socket with the SN found */
            socketFound = TRUE;

            /* Update the DSAP value with the incomming Socket sSap */
            psTransport->pSocketTable[index].socket_dSap = ssap;

            /* Store a pointer to the socket found */
            psLocalLlcpSocket = &psTransport->pSocketTable[index];
            break;
         }
      }
      /* Test if a socket has been found */
      if(socketFound)
      {
         /* Set the socket state to connected */
         psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnected;

         /* Reset the socket_VS,socket_VR,socket_VSA and socket_VRA variables */
         psLocalLlcpSocket->socket_VR  = 0;
         psLocalLlcpSocket->socket_VRA = 0;
         psLocalLlcpSocket->socket_VS  = 0;
         psLocalLlcpSocket->socket_VSA = 0;

         /* Store the Remote parameters (MIU,RW) */
         psLocalLlcpSocket->remoteMIU  = remoteMIU;
         psLocalLlcpSocket->remoteRW   = remoteRW;

         /* Call the Connect CB and reset callback info */
         psLocalLlcpSocket->pfSocketConnect_Cb(psLocalLlcpSocket->pConnectContext,0x00,NFCSTATUS_SUCCESS);
         psLocalLlcpSocket->pfSocketConnect_Cb = NULL;
         psLocalLlcpSocket->pConnectContext = NULL;
      }
      else
      {
         /* No socket Active */
         /* CC Frame not handled */
      }
   }
}

/* TODO: comment function Handle_DisconnectFrame */
static void Handle_DisconnectFrame(phFriNfc_LlcpTransport_t      *psTransport,
                                   uint8_t                       dsap,
                                   uint8_t                       ssap)
{
   NFCSTATUS   status = NFCSTATUS_SUCCESS;
   uint8_t     index;
   uint8_t     socketFound = FALSE;
   phFriNfc_LlcpTransport_Socket_t*   psLocalLlcpSocket = NULL;

   /* Search a socket in connected state and the good SSAP */
   for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
   {
      /* Test if the socket is in Connected state and if its SSAP number is the good one */
      if(psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected 
         && psTransport->pSocketTable[index].socket_sSap == dsap)
      {
         /* socket found */
         socketFound = TRUE;

         /* Store a pointer to the socket found */
         psLocalLlcpSocket = &psTransport->pSocketTable[index];
         break;
      }
   }

   /* Test if a socket has been found */
   if(socketFound)
   {
      /* Test if a send IFRAME is pending with this socket */
      if((psLocalLlcpSocket->bSocketSendPending == TRUE) || (psLocalLlcpSocket->bSocketRecvPending == TRUE))
      {
         /* Call the send CB, a disconnect abort the send request */
         if (psLocalLlcpSocket->pfSocketSend_Cb != NULL && psLocalLlcpSocket->bSocketSendPending == TRUE)
         {
            /* Copy CB + context in local variables */
            pphFriNfc_LlcpTransportSocketSendCb_t  pfSendCb = psLocalLlcpSocket->pfSocketSend_Cb;
            void*                                  pSendContext = psLocalLlcpSocket->pSendContext;
            /* Reset CB + context */
            psLocalLlcpSocket->pfSocketSend_Cb = NULL;
            psLocalLlcpSocket->pSendContext = NULL;
            /* Perform callback */
            pfSendCb(pSendContext, NFCSTATUS_FAILED);
         }
         /* Call the send CB, a disconnect abort the receive request */
         if (psLocalLlcpSocket->pfSocketRecv_Cb != NULL && psLocalLlcpSocket->bSocketRecvPending == TRUE)
         {
            /* Copy CB + context in local variables */
            pphFriNfc_LlcpTransportSocketRecvCb_t  pfRecvCb = psLocalLlcpSocket->pfSocketRecv_Cb;
            void*                                  pRecvContext = psLocalLlcpSocket->pRecvContext;
            /* Reset CB + context */
            psLocalLlcpSocket->pfSocketRecv_Cb = NULL;
            psLocalLlcpSocket->pRecvContext = NULL;
            /* Perform callback */
            pfRecvCb(pRecvContext, NFCSTATUS_FAILED);
         }
         psLocalLlcpSocket->bSocketRecvPending = FALSE;
         psLocalLlcpSocket->bSocketSendPending = FALSE;
      }

      /* Update the socket state */
      psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;

      /* Send a DM*/
      /* TODO: use a socket internal flag to save */
      status = phFriNfc_LlcpTransport_SendDisconnectMode(psTransport,
                                                         ssap,
                                                         dsap,
                                                         PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED);

      /* Call ErrCB due to a DISC */
      psTransport->pSocketTable[index].pSocketErrCb(psTransport->pSocketTable[index].pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
   }
   else
   {
      /* No socket Active */
      /* DISC Frame not handled */
   }
}

/* TODO: comment function Handle_ConnectFrame */
static void Handle_DisconnetModeFrame(phFriNfc_LlcpTransport_t      *psTransport,
                                      phNfc_sData_t                 *psData,
                                      uint8_t                       dsap,
                                      uint8_t                       ssap)
{
   NFCSTATUS                           status = NFCSTATUS_SUCCESS;
   uint8_t                             index;
   uint8_t                             socketFound = FALSE;
   uint8_t                             dmOpCode;
   phFriNfc_LlcpTransport_Socket_t     *psLocalLlcpSocket = NULL;

   /* Test if the DM buffer is correct */
   if(psData->length != PHFRINFC_LLCP_DM_LENGTH)
   {
      /* send FRMR */
      status  = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
                                                       ssap,
                                                       PHFRINFC_LLCP_PTYPE_DM,
                                                       dsap,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00,
                                                       0x00);
   }
   else
   {
      /* Search a socket waiting for a DM (Disconnecting State) */
      for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
      {
         /* Test if the socket is in Disconnecting  or connecting state and if its SSAP number is the good one */
         if((psTransport->pSocketTable[index].eSocket_State   == phFriNfc_LlcpTransportSocket_eSocketDisconnecting 
            || psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnecting)
            && psTransport->pSocketTable[index].socket_sSap   == dsap)
         {
            /* socket found */
            socketFound = TRUE;

            /* Store a pointer to the socket found */
            psLocalLlcpSocket = &psTransport->pSocketTable[index];
            break;
         }
      }

      /* Test if a socket has been found */
      if(socketFound)
      {
         /* Set dmOpcode */
         dmOpCode = psData->buffer[0];

         switch(dmOpCode)
         {
         case PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED:
            {
               /* Set the socket state to disconnected */
               psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;

               /* Call Disconnect CB */
               if (psLocalLlcpSocket->pfSocketDisconnect_Cb != NULL)
               {
                  psLocalLlcpSocket->pfSocketDisconnect_Cb(psLocalLlcpSocket->pDisonnectContext,NFCSTATUS_SUCCESS);
                  psLocalLlcpSocket->pfSocketDisconnect_Cb = NULL;
               }

            }break;

         case PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED:
         case PHFRINFC_LLCP_DM_OPCODE_CONNECT_NOT_ACCEPTED:
         case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_ACTIVE:
         case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND:
         case PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE:
            {
               /* Set the socket state to bound */
               psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
               if(psLocalLlcpSocket->pfSocketConnect_Cb != NULL)
               {
                  /* Call Connect CB */
                  psLocalLlcpSocket->pfSocketConnect_Cb(psLocalLlcpSocket->pConnectContext,dmOpCode,NFCSTATUS_FAILED);
                  psLocalLlcpSocket->pfSocketConnect_Cb = NULL;
               }
            }break;
         }
      }
   }
}

/* TODO: comment function Handle_Receive_IFrame */
static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t      *psTransport,
                                  phNfc_sData_t                 *psData,
                                  uint8_t                       dsap,
                                  uint8_t                       ssap)
{
   NFCSTATUS   status = NFCSTATUS_SUCCESS;

   phFriNfc_LlcpTransport_Socket_t*    psLocalLlcpSocket = NULL;
   phFriNfc_Llcp_sPacketSequence_t    sLlcpLocalSequence;

   uint32_t    dataLengthAvailable = 0;
   uint32_t    dataLengthWrite = 0;
   uint8_t     index;
   uint8_t     socketFound = FALSE;
   uint8_t     WFlag = 0;
   uint8_t     IFlag = 0;
   uint8_t     RFlag = 0;
   uint8_t     SFlag = 0;
   uint8_t     nr_val;
   uint32_t    offset = 0;
   uint32_t    rw_offset;

   /* Get NS and NR Value of the I Frame*/
   phFriNfc_Llcp_Buffer2Sequence( psData->buffer, offset, &sLlcpLocalSequence);


   /* Update the buffer pointer */
   psData->buffer = psData->buffer + PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;

   /* Update the length value (without the header length) */
   psData->length = psData->length - PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;

   /* Search a socket waiting for an I FRAME (Connected State) */
   for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
   {
      /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
      if((  (psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
         || (psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketAccepted))
         && psTransport->pSocketTable[index].socket_sSap == dsap
         && psTransport->pSocketTable[index].socket_dSap == ssap)
      {
         /* socket found */
         socketFound = TRUE;

         /* Store a pointer to the socket found */
         psLocalLlcpSocket = &psTransport->pSocketTable[index];
         break;
      }
   }

   /* Test if a socket has been found */
   if(socketFound)
   {
      /* Test NS */
      /*if(sLlcpLocalSequence.ns != psLocalLlcpSocket->socket_VR)
      {
         SFlag = TRUE;
      }*/

      /* Calculate offset of current frame in RW, and check validity */
      if(sLlcpLocalSequence.ns >= psLocalLlcpSocket->socket_VRA)
      {
         rw_offset = sLlcpLocalSequence.ns - psLocalLlcpSocket->socket_VRA;
      }
      else
      {
         rw_offset = 16 - (psLocalLlcpSocket->socket_VRA - sLlcpLocalSequence.ns);
      }
      if(rw_offset >= psLocalLlcpSocket->localRW)
      {
         /* FRMR 0x01 */
         SFlag = TRUE;
      }

      /* Check Info length */
      if(psData->length > (uint32_t)(psLocalLlcpSocket->localMIUX + PHFRINFC_LLCP_MIU_DEFAULT))
      {
         IFlag = TRUE;
      }


      /* Test NR */
      nr_val = (uint8_t)sLlcpLocalSequence.nr;
      do
      {
         if(nr_val == psLocalLlcpSocket->socket_VS)
         {
            break;
         }

         nr_val = (nr_val+1)%16;

         if(nr_val == psLocalLlcpSocket->socket_VSA)
         {
            /* FRMR 0x02 */
            RFlag = TRUE;
            break;
         }
      }while(nr_val != sLlcpLocalSequence.nr);


      if( WFlag != 0 || IFlag != 0 || RFlag != 0 || SFlag != 0)
      {
         /* Send FRMR */
         status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
                                                         ssap,
                                                         PHFRINFC_LLCP_PTYPE_I,
                                                         dsap,
                                                         &sLlcpLocalSequence,
                                                         WFlag,
                                                         IFlag,
                                                         RFlag,
                                                         SFlag,
                                                         psLocalLlcpSocket->socket_VS,
                                                         psLocalLlcpSocket->socket_VSA,
                                                         psLocalLlcpSocket->socket_VR,
                                                         psLocalLlcpSocket->socket_VRA);

      }
      else
      {
        /* Test if the Linear Buffer length is null */
        if(psLocalLlcpSocket->bufferLinearLength == 0)
        {
            /* Test if a Receive is pending and RW empty */
            if(psLocalLlcpSocket->bSocketRecvPending == TRUE && (psLocalLlcpSocket->indexRwWrite == psLocalLlcpSocket->indexRwRead))
            {
               /* Reset Flag */
               psTransport->pSocketTable[psTransport->socketIndex].bSocketRecvPending = FALSE;

               /* Save I_FRAME into the Receive Buffer */
               memcpy(psLocalLlcpSocket->sSocketRecvBuffer->buffer,psData->buffer,psData->length);
               psLocalLlcpSocket->sSocketRecvBuffer->length = psData->length;

               /* Update VR */
               psLocalLlcpSocket->socket_VR = (psLocalLlcpSocket->socket_VR+1)%16;

               /* Update VSA */
               psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;

               /* Call the Receive CB */
               psLocalLlcpSocket->pfSocketRecv_Cb(psLocalLlcpSocket->pRecvContext, NFCSTATUS_SUCCESS);
               psLocalLlcpSocket->pfSocketRecv_Cb = NULL;

               /* Test if a send is pending with this socket */
               if(psLocalLlcpSocket->bSocketSendPending == TRUE && CHECK_SEND_RW(psLocalLlcpSocket))
               {
                  /* Test if a send is pending at LLC layer */
                  if(psTransport->bSendPending != TRUE)
                  {
                     status = static_performSendInfo(psLocalLlcpSocket);
                  }
               }
               else
               {
                  /* RR */
                  status = phFriNfc_Llcp_Send_ReceiveReady_Frame(psLocalLlcpSocket);
               }
            }
            else
            {
               /* Test if RW is full */
               if((psLocalLlcpSocket->indexRwWrite - psLocalLlcpSocket->indexRwRead)<psLocalLlcpSocket->localRW)
               {
                  if(psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length == 0)
                  {
                     /* Save I_FRAME into the RW Buffers */
                     memcpy(psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].buffer,psData->buffer,psData->length);
                     psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = psData->length;

                     if(psLocalLlcpSocket->ReceiverBusyCondition != TRUE)
                     {
                        /* Receiver Busy condition */
                        psLocalLlcpSocket->ReceiverBusyCondition = TRUE;

                        /* Send RNR */
                        status = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(psLocalLlcpSocket);
                     }
                     /* Update the RW write index */
                     psLocalLlcpSocket->indexRwWrite++;
                  }
               }
            }
        }
        else
        {
           /* Copy the buffer into the RW buffer */
           memcpy(psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].buffer,psData->buffer,psData->length);

           /* Update the length */
           psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = psData->length;

           /* Test the length of the available place in the linear buffer */
           dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&psLocalLlcpSocket->sCyclicFifoBuffer);

           if(dataLengthAvailable >= psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length)
           {
              /* Store Data into the linear buffer */
              dataLengthWrite = phFriNfc_Llcp_CyclicFifoWrite(&psLocalLlcpSocket->sCyclicFifoBuffer,
                                                              psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].buffer,
                                                              psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length);

              /* Update VR */
              psLocalLlcpSocket->socket_VR = (psLocalLlcpSocket->socket_VR+1)%16;

              /* Update VSA */
              psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;

              /* Update the length */
              psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = 0x00;

              /* Test if a Receive Pending*/
              if(psLocalLlcpSocket->bSocketRecvPending == TRUE)
              {
                 /* Reset Flag */
                 psLocalLlcpSocket->bSocketRecvPending = FALSE;

                 phFriNfc_LlcpTransport_ConnectionOriented_Recv(psLocalLlcpSocket,
                                                                psLocalLlcpSocket->sSocketRecvBuffer,
                                                                psLocalLlcpSocket->pfSocketRecv_Cb,
                                                                psLocalLlcpSocket->pRecvContext);
              }

              /* Test if a send is pending with this socket */
              if((psLocalLlcpSocket->bSocketSendPending == TRUE) && CHECK_SEND_RW(psLocalLlcpSocket))
              {
                 /* Test if a send is pending at LLC layer */
                 if(psTransport->bSendPending != TRUE)
                 {
                    status = static_performSendInfo(psLocalLlcpSocket);
                 }
              }
              else
              {
                 /* RR */
                 status = phFriNfc_Llcp_Send_ReceiveReady_Frame(psLocalLlcpSocket);
              }
           }
           else
           {
               if(psLocalLlcpSocket->ReceiverBusyCondition != TRUE)
               {
                  /* Receiver Busy condition */
                  psLocalLlcpSocket->ReceiverBusyCondition = TRUE;

                  /* Send RNR */
                  status = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(psLocalLlcpSocket);
               }

              /* Update the RW write index */
              psLocalLlcpSocket->indexRwWrite++;
           }
         }
      }
   }
   else
   {
      /* No active  socket*/
      /* I FRAME not Handled */
   }
}

static void Handle_ReceiveReady_Frame(phFriNfc_LlcpTransport_t      *psTransport,
                                      phNfc_sData_t                 *psData,
                                      uint8_t                       dsap,
                                      uint8_t                       ssap)
{
   NFCSTATUS   status = NFCSTATUS_SUCCESS;
   uint8_t     index;
   uint8_t     socketFound = FALSE;
   uint8_t      WFlag = 0;
   uint8_t      IFlag = 0;
   uint8_t      RFlag = 0;
   uint8_t      SFlag = 0;
   uint32_t     offset = 0;
   uint8_t      nr_val;

   phFriNfc_LlcpTransport_Socket_t*   psLocalLlcpSocket = NULL;
   phFriNfc_Llcp_sPacketSequence_t    sLlcpLocalSequence;

   /* Get NS and NR Value of the I Frame*/
   phFriNfc_Llcp_Buffer2Sequence( psData->buffer, offset, &sLlcpLocalSequence);

   /* Search a socket waiting for an RR FRAME (Connected State) */
   for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
   {
      /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
      if(psTransport->pSocketTable[index].eSocket_State  == phFriNfc_LlcpTransportSocket_eSocketConnected 
         && psTransport->pSocketTable[index].socket_sSap == dsap
         && psTransport->pSocketTable[index].socket_dSap == ssap)
      {
         /* socket found */
         socketFound = TRUE;

         /* Store a pointer to the socket found */
         psLocalLlcpSocket = &psTransport->pSocketTable[index];
         psLocalLlcpSocket->index = psTransport->pSocketTable[index].index;
         break;
      }
   }

   /* Test if a socket has been found */
   if(socketFound)
   {
      /* Test NR */
      nr_val = (uint8_t)sLlcpLocalSequence.nr;
      do
      {
         if(nr_val == psLocalLlcpSocket->socket_VS)
         {
            break;
         }

         nr_val = (nr_val+1)%16;

         if(nr_val == psLocalLlcpSocket->socket_VSA)
         {
            RFlag = TRUE;
            break;
         }

      }while(nr_val != sLlcpLocalSequence.nr);


      /* Test if Info field present */
      if(psData->length > 1)
      {
         WFlag = TRUE;
         IFlag = TRUE;
      }

      if (WFlag || IFlag || RFlag || SFlag)
      {
         /* Send FRMR */
         status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
                                                         ssap, PHFRINFC_LLCP_PTYPE_RR, dsap,
                                                         &sLlcpLocalSequence,
                                                         WFlag, IFlag, RFlag, SFlag,
                                                         psLocalLlcpSocket->socket_VS,
                                                         psLocalLlcpSocket->socket_VSA,
                                                         psLocalLlcpSocket->socket_VR,
                                                         psLocalLlcpSocket->socket_VRA);
      }
      else
      {
         /* Test Receiver Busy condition */
         if(psLocalLlcpSocket->RemoteBusyConditionInfo == TRUE)
         {
            /* Notify the upper layer */
            psLocalLlcpSocket->pSocketErrCb(psLocalLlcpSocket->pContext,PHFRINFC_LLCP_ERR_NOT_BUSY_CONDITION);
            psLocalLlcpSocket->RemoteBusyConditionInfo = FALSE;
         }
         /* Update VSA */
         psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;

         /* Test if a send is pendind */
         if(psLocalLlcpSocket->bSocketSendPending == TRUE)
         {
            /* Test the RW window */
            if(CHECK_SEND_RW(psLocalLlcpSocket))
            {
               /* Test if a send is pending at LLC layer */
               if(psTransport->bSendPending != TRUE)
               {
                  status = static_performSendInfo(psLocalLlcpSocket);
               }
            }
         }
      }
   }
   else
   {
      /* No active  socket*/
      /* RR Frame not handled*/
   }
}

static void Handle_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_t      *psTransport,
                                      phNfc_sData_t                    *psData,
                                      uint8_t                          dsap,
                                      uint8_t                          ssap)
{
   NFCSTATUS   status = NFCSTATUS_SUCCESS;
   uint8_t     index;
   uint8_t     socketFound = FALSE;
   bool_t      bWFlag = 0;
   bool_t      bIFlag = 0;
   bool_t      bRFlag = 0;
   bool_t      bSFlag = 0;
   uint32_t    offset = 0;
   uint8_t     nr_val;

   phFriNfc_LlcpTransport_Socket_t*   psLocalLlcpSocket = NULL;
   phFriNfc_Llcp_sPacketSequence_t   sLlcpLocalSequence;

   /* Get NS and NR Value of the I Frame*/
   phFriNfc_Llcp_Buffer2Sequence( psData->buffer, offset, &sLlcpLocalSequence);

   /* Search a socket waiting for an RNR FRAME (Connected State) */
   for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
   {
      /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
      if(psTransport->pSocketTable[index].eSocket_State  == phFriNfc_LlcpTransportSocket_eSocketConnected 
         && psTransport->pSocketTable[index].socket_sSap == dsap
         && psTransport->pSocketTable[index].socket_dSap == ssap)
      {
         /* socket found */
         socketFound = TRUE;

         /* Store a pointer to the socket found */
         psLocalLlcpSocket = &psTransport->pSocketTable[index];
         break;
      }
   }

   /* Test if a socket has been found */
   if(socketFound)
   {
      /* Test NR */
      nr_val = (uint8_t)sLlcpLocalSequence.nr;
      do
      {

         if(nr_val == psLocalLlcpSocket->socket_VS)
         {
            break;
         }

         nr_val = (nr_val+1)%16;
         
         if(nr_val == psLocalLlcpSocket->socket_VSA)
         {
            /* FRMR 0x02 */
            bRFlag = TRUE;
            break;
         }
      }while(nr_val != sLlcpLocalSequence.nr);

      /* Test if Info field present */
      if(psData->length > 1)
      {
         /* Send FRMR */
         bWFlag = TRUE;
         bIFlag = TRUE;
      }

      if( bWFlag != 0 || bIFlag != 0 || bRFlag != 0 || bSFlag != 0)
      {
         /* Send FRMR */
         status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
                                                         ssap, PHFRINFC_LLCP_PTYPE_RNR, dsap,
                                                         &sLlcpLocalSequence,
                                                         bWFlag, bIFlag, bRFlag, bSFlag,
                                                         psLocalLlcpSocket->socket_VS,
                                                         psLocalLlcpSocket->socket_VSA,
                                                         psLocalLlcpSocket->socket_VR,
                                                         psLocalLlcpSocket->socket_VRA);
      }
      else
      {
         /* Notify the upper layer */
         psLocalLlcpSocket->pSocketErrCb(psTransport->pSocketTable[index].pContext,PHFRINFC_LLCP_ERR_BUSY_CONDITION);
         psLocalLlcpSocket->RemoteBusyConditionInfo = TRUE;

         /* Update VSA */
         psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;

         /* Test if a send is pendind */
         if(psLocalLlcpSocket->bSocketSendPending == TRUE && CHECK_SEND_RW(psLocalLlcpSocket))
         {
            /* Test if a send is pending at LLC layer */
            if(psTransport->bSendPending != TRUE)
            {
               status = static_performSendInfo(psLocalLlcpSocket);
            }
         }
      }
   }
   else
   {
      /* No active  socket*/
      /* RNR Frame not handled*/
   }
}

static void Handle_FrameReject_Frame(phFriNfc_LlcpTransport_t      *psTransport,
                                     uint8_t                       dsap,
                                     uint8_t                       ssap)
{
   NFCSTATUS   status = NFCSTATUS_SUCCESS;
   uint8_t     index;
   uint8_t     socketFound = FALSE;

   /* Search a socket waiting for a FRAME */
   for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
   {
      /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
      if(psTransport->pSocketTable[index].socket_sSap == dsap
         && psTransport->pSocketTable[index].socket_dSap == ssap)
      {
         /* socket found */
         socketFound = TRUE;
         break;
      }
   }

   /* Test if a socket has been found */
   if(socketFound)
   {
      /* Set socket state to disconnected */
      psTransport->pSocketTable[index].eSocket_State =  phFriNfc_LlcpTransportSocket_eSocketDisconnected;

      /* Call ErrCB due to a FRMR*/
      psTransport->pSocketTable[index].pSocketErrCb( psTransport->pSocketTable[index].pContext,PHFRINFC_LLCP_ERR_FRAME_REJECTED);

      /* Close the socket */
      status = phFriNfc_LlcpTransport_ConnectionOriented_Close(&psTransport->pSocketTable[index]);
   }
   else
   {
      /* No active  socket*/
      /* FRMR Frame not handled*/
   }
}

/* TODO: comment function Handle_ConnectionOriented_IncommingFrame */
void Handle_ConnectionOriented_IncommingFrame(phFriNfc_LlcpTransport_t           *psTransport,
                                              phNfc_sData_t                      *psData,
                                              uint8_t                            dsap,
                                              uint8_t                            ptype,
                                              uint8_t                            ssap)
{
   phFriNfc_Llcp_sPacketSequence_t  sSequence = {0,0};

   switch(ptype)
   {
      case PHFRINFC_LLCP_PTYPE_CONNECT:
         {
            Handle_ConnectionFrame(psTransport,
                                   psData,
                                   dsap,
                                   ssap);
         }break;

      case PHFRINFC_LLCP_PTYPE_DISC:
         {
            Handle_DisconnectFrame(psTransport,
                                   dsap,
                                   ssap);
         }break;

      case PHFRINFC_LLCP_PTYPE_CC:
         {
            Handle_ConnectionCompleteFrame(psTransport,
                                           psData,
                                           dsap,
                                           ssap);
         }break;

      case PHFRINFC_LLCP_PTYPE_DM:
         {
            Handle_DisconnetModeFrame(psTransport,
                                      psData,
                                      dsap,
                                      ssap);
         }break;

      case PHFRINFC_LLCP_PTYPE_FRMR:
         {
            Handle_FrameReject_Frame(psTransport,
                                     dsap,
                                     ssap);
         }break;

      case PHFRINFC_LLCP_PTYPE_I:
         {
            Handle_Receive_IFrame(psTransport,
                                  psData,
                                  dsap,
                                  ssap);
         }break;

      case PHFRINFC_LLCP_PTYPE_RR:
         {
            Handle_ReceiveReady_Frame(psTransport,
                                      psData,
                                      dsap,
                                      ssap);
         }break;

      case PHFRINFC_LLCP_PTYPE_RNR:
         {
            Handle_ReceiveNotReady_Frame(psTransport,
                                         psData,
                                         dsap,
                                         ssap);
         }break;

      case PHFRINFC_LLCP_PTYPE_RESERVED1:
      case PHFRINFC_LLCP_PTYPE_RESERVED2:
      case PHFRINFC_LLCP_PTYPE_RESERVED3:
         {
            phFriNfc_LlcpTransport_SendFrameReject( psTransport,
                                                    dsap, ptype, ssap,
                                                    &sSequence,
                                                    TRUE, FALSE, FALSE, FALSE,
                                                    0, 0, 0, 0);
         }break;
   }
}

/**
* \ingroup grp_lib_nfc
* \brief <b>Get the local options of a socket</b>.
*
* This function returns the local options (maximum packet size and receive window size) used
* for a given connection-oriented socket. This function shall not be used with connectionless
* sockets.
*
* \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  psLocalOptions        A pointer to be filled with the local options of the socket.
*
* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of 
*                                            a valid type to perform the requsted operation.
* \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
* \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetLocalOptions(phFriNfc_LlcpTransport_Socket_t  *pLlcpSocket,
                                                                          phLibNfc_Llcp_sSocketOptions_t   *psLocalOptions)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Get Local MIUX */
   psLocalOptions->miu = pLlcpSocket->sSocketOption.miu;

   /* Get Local Receive Window */
   psLocalOptions->rw = pLlcpSocket->sSocketOption.rw;

   return status;
}

/**
* \ingroup grp_lib_nfc
* \brief <b>Get the local options of a socket</b>.
*
* This function returns the remote options (maximum packet size and receive window size) used
* for a given connection-oriented socket. This function shall not be used with connectionless
* sockets.
*
* \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  psRemoteOptions       A pointer to be filled with the remote options of the socket.
*
* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of 
*                                            a valid type to perform the requsted operation.
* \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
* \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket,
                                                                           phLibNfc_Llcp_sSocketOptions_t*    psRemoteOptions)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Get Remote MIUX */
   psRemoteOptions->miu = pLlcpSocket->remoteMIU;

   /* Get Remote  Receive Window */
   psRemoteOptions->rw = pLlcpSocket->remoteRW;

   return status;
}


/**
* \ingroup grp_fri_nfc
* \brief <b>Listen for incoming connection requests on a socket</b>.
*
* This function switches a socket into a listening state and registers a callback on
* incoming connection requests. In this state, the socket is not able to communicate
* directly. The listening state is only available for connection-oriented sockets
* which are still not connected. The socket keeps listening until it is closed, and
* thus can trigger several times the pListen_Cb callback.
*
*
* \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  pListen_Cb         The callback to be called each time the
*                                socket receive a connection request.
* \param[in]  pContext           Upper layer context to be returned in
*                                the callback.
*
* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state to switch
*                                            to listening state.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Listen(phFriNfc_LlcpTransport_Socket_t*          pLlcpSocket,
                                                           pphFriNfc_LlcpTransportSocketListenCb_t   pListen_Cb,
                                                           void*                                     pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   uint8_t   index;

   /* Store the listen callback */
   pLlcpSocket->pfSocketListen_Cb = pListen_Cb;

   /* store the context */
   pLlcpSocket->pListenContext = pContext;

   /* Set RecvPending to TRUE */
   pLlcpSocket->bSocketListenPending = TRUE;

   /* Set the socket state*/
   pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketRegistered;

   return status;
}

/**
* \ingroup grp_fri_nfc
* \brief <b>Accept an incoming connection request for a socket</b>.
*
* This functions allows the client to accept an incoming connection request.
* It must be used with the socket provided within the listen callback. The socket
* is implicitly switched to the connected state when the function is called.
*
* \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  psOptions             The options to be used with the socket.
* \param[in]  psWorkingBuffer       A working buffer to be used by the library.
* \param[in]  pErr_Cb               The callback to be called each time the accepted socket
*                                   is in error.
* \param[in]  pAccept_RspCb         The callback to be called when the Accept operation is completed
* \param[in]  pContext              Upper layer context to be returned in the callback.
*
* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_BUFFER_TOO_SMALL         The working buffer is too small for the MIU and RW
*                                            declared in the options.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Accept(phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
                                                           phFriNfc_LlcpTransport_sSocketOptions_t*     psOptions,
                                                           phNfc_sData_t*                               psWorkingBuffer,
                                                           pphFriNfc_LlcpTransportSocketErrCb_t         pErr_Cb,
                                                           pphFriNfc_LlcpTransportSocketAcceptCb_t      pAccept_RspCb,
                                                           void*                                        pContext)

{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   uint32_t offset = 0;
   uint8_t miux[2];
   uint8_t  i;

   /* Store the options in the socket */
   memcpy(&pLlcpSocket->sSocketOption, psOptions, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));

   /* Set socket local params (MIUX & RW) */
   pLlcpSocket ->localMIUX = (pLlcpSocket->sSocketOption.miu - PHFRINFC_LLCP_MIU_DEFAULT) & PHFRINFC_LLCP_TLV_MIUX_MASK;
   pLlcpSocket ->localRW   = pLlcpSocket->sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK;

   /* Set the pointer and the length for the Receive Window Buffer */
   for(i=0;i<pLlcpSocket->localRW;i++)
   {
      pLlcpSocket->sSocketRwBufferTable[i].buffer = psWorkingBuffer->buffer + (i*pLlcpSocket->sSocketOption.miu);
      pLlcpSocket->sSocketRwBufferTable[i].length = 0;
   }

   /* Set the pointer and the length for the Send Buffer */
   pLlcpSocket->sSocketSendBuffer.buffer     = psWorkingBuffer->buffer + pLlcpSocket->bufferRwMaxLength;
   pLlcpSocket->sSocketSendBuffer.length     = pLlcpSocket->bufferSendMaxLength;
  
   /* Set the pointer and the length for the Linear Buffer */
   pLlcpSocket->sSocketLinearBuffer.buffer   = psWorkingBuffer->buffer + pLlcpSocket->bufferRwMaxLength + pLlcpSocket->bufferSendMaxLength;
   pLlcpSocket->sSocketLinearBuffer.length   = pLlcpSocket->bufferLinearLength;

   if(pLlcpSocket->sSocketLinearBuffer.length != 0)
   {
      /* Init Cyclic Fifo */
      phFriNfc_Llcp_CyclicFifoInit(&pLlcpSocket->sCyclicFifoBuffer,
                                   pLlcpSocket->sSocketLinearBuffer.buffer,
                                   pLlcpSocket->sSocketLinearBuffer.length);
   }

   pLlcpSocket->pSocketErrCb            = pErr_Cb;
   pLlcpSocket->pContext                = pContext;
   
   /* store the pointer to the Accept callback */
   pLlcpSocket->pfSocketAccept_Cb   = pAccept_RspCb;
   pLlcpSocket->pAcceptContext      = pContext;

   /* Reset the socket_VS,socket_VR,socket_VSA and socket_VRA variables */
   pLlcpSocket->socket_VR  = 0;
   pLlcpSocket->socket_VRA = 0;
   pLlcpSocket->socket_VS  = 0;
   pLlcpSocket->socket_VSA = 0;

   /* MIUX */
   if(pLlcpSocket->localMIUX != PHFRINFC_LLCP_MIUX_DEFAULT)
   {
      /* Encode MIUX value */
      phFriNfc_Llcp_EncodeMIUX(pLlcpSocket->localMIUX,
                               miux);

      /* Encode MIUX in TLV format */
      status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
                                        &offset,
                                        PHFRINFC_LLCP_TLV_TYPE_MIUX,
                                        PHFRINFC_LLCP_TLV_LENGTH_MIUX,
                                        miux);
      if(status != NFCSTATUS_SUCCESS)
      {
         /* Call the CB */
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
         goto clean_and_return;
      }
   }

   /* Receive Window */
   if(pLlcpSocket->sSocketOption.rw != PHFRINFC_LLCP_RW_DEFAULT)
   {
      /* Encode RW value */
      phFriNfc_Llcp_EncodeRW(&pLlcpSocket->sSocketOption.rw);

      /* Encode RW in TLV format */
      status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
                                        &offset,
                                        PHFRINFC_LLCP_TLV_TYPE_RW,
                                        PHFRINFC_LLCP_TLV_LENGTH_RW,
                                        &pLlcpSocket->sSocketOption.rw);
      if(status != NFCSTATUS_SUCCESS)
      {
         /* Call the CB */
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
         goto clean_and_return;
      }
   }


   /* Test if a send is pending */
   if(pLlcpSocket->psTransport->bSendPending == TRUE)
   {
      pLlcpSocket->bSocketAcceptPending = TRUE;

      /* Update Send Buffer length value */
      pLlcpSocket->sSocketSendBuffer.length = offset;

      status = NFCSTATUS_PENDING;
   }
   else
   {
      /* Fill the psLlcpHeader stuture with the DSAP,CC PTYPE and the SSAP */
      pLlcpSocket->sLlcpHeader.dsap  = pLlcpSocket->socket_dSap;
      pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC;
      pLlcpSocket->sLlcpHeader.ssap  = pLlcpSocket->socket_sSap;

      /* Set the socket state to accepted */
      pLlcpSocket->eSocket_State           = phFriNfc_LlcpTransportSocket_eSocketAccepted;

      /* Update Send Buffer length value */
      pLlcpSocket->sSocketSendBuffer.length = offset;

      /* Store the index of the socket */
      pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;

      /* Send a CC Frame */
      status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
                                   &pLlcpSocket->sLlcpHeader,
                                   NULL,
                                   &pLlcpSocket->sSocketSendBuffer,
                                   phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
                                   pLlcpSocket->psTransport);
   }

clean_and_return:
   if(status != NFCSTATUS_PENDING)
   {
      LLCP_PRINT("Release Accept callback");
      pLlcpSocket->pfSocketAccept_Cb = NULL;
      pLlcpSocket->pAcceptContext = NULL;
   }

   return status;
}

 /**
* \ingroup grp_fri_nfc
* \brief <b>Reject an incoming connection request for a socket</b>.
*
* This functions allows the client to reject an incoming connection request.
* It must be used with the socket provided within the listen callback. The socket
* is implicitly closed when the function is called.
*
* \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
*
* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phLibNfc_LlcpTransport_ConnectionOriented_Reject( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
                                                            pphFriNfc_LlcpTransportSocketRejectCb_t   pReject_RspCb,
                                                            void                                      *pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Set the state of the socket */
   pLlcpSocket->eSocket_State   = phFriNfc_LlcpTransportSocket_eSocketRejected;

   /* Store the Reject callback */
   pLlcpSocket->pfSocketSend_Cb = pReject_RspCb;
   pLlcpSocket->pRejectContext  = pContext;

   /* Store the index of the socket */
   pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;

   /* Send a DM*/
   status = phFriNfc_LlcpTransport_SendDisconnectMode(pLlcpSocket->psTransport,
                                                      pLlcpSocket->socket_dSap,
                                                      pLlcpSocket->socket_sSap,
                                                      PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED);

   return status;
}

/**
* \ingroup grp_fri_nfc
* \brief <b>Try to establish connection with a socket on a remote SAP</b>.
*
* This function tries to connect to a given SAP on the remote peer. If the
* socket is not bound to a local SAP, it is implicitly bound to a free SAP.
*
* \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  nSap               The destination SAP to connect to.
* \param[in]  psUri              The URI corresponding to the destination SAP to connect to.
* \param[in]  pConnect_RspCb     The callback to be called when the connection
*                                operation is completed.
* \param[in]  pContext           Upper layer context to be returned in
*                                the callback.
*
* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_PENDING                  Connection operation is in progress,
*                                            pConnect_RspCb will be called upon completion.
* \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of 
*                                            a valid type to perform the requsted operation.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Connect( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
                                                             uint8_t                                    nSap,
                                                             phNfc_sData_t*                             psUri,
                                                             pphFriNfc_LlcpTransportSocketConnectCb_t   pConnect_RspCb,
                                                             void*                                      pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   uint32_t offset = 0;
   uint8_t miux[2];

   /* Test if a nSap is present */
   if(nSap != PHFRINFC_LLCP_SAP_DEFAULT)
   {
      /* Set DSAP port number with the nSap value */
      pLlcpSocket->socket_dSap = nSap;
   }
   else
   {
      /* Set DSAP port number with the SDP port number */
      pLlcpSocket->socket_dSap = PHFRINFC_LLCP_SAP_SDP;
   }

   /* Store the Connect callback and context */
   pLlcpSocket->pfSocketConnect_Cb = pConnect_RspCb;
   pLlcpSocket->pConnectContext = pContext;

   /* Set the socket Header */
   pLlcpSocket->sLlcpHeader.dsap  = pLlcpSocket->socket_dSap;
   pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CONNECT;
   pLlcpSocket->sLlcpHeader.ssap  = pLlcpSocket->socket_sSap;

   /* MIUX */
   if(pLlcpSocket->localMIUX != PHFRINFC_LLCP_MIUX_DEFAULT)
   {
      /* Encode MIUX value */
      phFriNfc_Llcp_EncodeMIUX(pLlcpSocket->localMIUX,
                               miux);

      /* Encode MIUX in TLV format */
      status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
                                        &offset,
                                        PHFRINFC_LLCP_TLV_TYPE_MIUX,
                                        PHFRINFC_LLCP_TLV_LENGTH_MIUX,
                                        miux);
      if(status != NFCSTATUS_SUCCESS)
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
         goto clean_and_return;
      }
   }

   /* Receive Window */
   if(pLlcpSocket->sSocketOption.rw != PHFRINFC_LLCP_RW_DEFAULT)
   {
      /* Encode RW value */
      phFriNfc_Llcp_EncodeRW(&pLlcpSocket->sSocketOption.rw);

      /* Encode RW in TLV format */
      status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
                                        &offset,
                                        PHFRINFC_LLCP_TLV_TYPE_RW,
                                        PHFRINFC_LLCP_TLV_LENGTH_RW,
                                        &pLlcpSocket->sSocketOption.rw);
      if(status != NFCSTATUS_SUCCESS)
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
         goto clean_and_return;
      }
   }

   /* Test if a Service Name is present */
   if(psUri != NULL)
   {
      /* Encode SN in TLV format */
      status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
                                        &offset,
                                        PHFRINFC_LLCP_TLV_TYPE_SN,
                                        (uint8_t)psUri->length,
                                        psUri->buffer);
      if(status != NFCSTATUS_SUCCESS)
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
         goto clean_and_return;
      }
   }

   /* Test if a send is pending */
   if(pLlcpSocket->psTransport->bSendPending == TRUE)
   {
      pLlcpSocket->bSocketConnectPending =  TRUE;

      /* Update Send Buffer length value */
      pLlcpSocket->sSocketSendBuffer.length = offset;

      status = NFCSTATUS_PENDING;
   }
   else
   {
      /* Update Send Buffer length value */
      pLlcpSocket->sSocketSendBuffer.length = offset;

      /* Set the socket in connecting state */
      pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnecting;

      /* Store the index of the socket */
      pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;

      status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
                                   &pLlcpSocket->sLlcpHeader,
                                   NULL,
                                   &pLlcpSocket->sSocketSendBuffer,
                                   phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
                                   pLlcpSocket->psTransport);
   }

clean_and_return:
   if(status != NFCSTATUS_PENDING)
   {
      LLCP_PRINT("Release Connect callback");
      pLlcpSocket->pfSocketConnect_Cb = NULL;
      pLlcpSocket->pConnectContext = NULL;
   }

   return status;
}


/**
* \ingroup grp_lib_nfc
* \brief <b>Disconnect a currently connected socket</b>.
*
* This function initiates the disconnection of a previously connected socket.
*
* \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  pDisconnect_RspCb  The callback to be called when the 
*                                operation is completed.
* \param[in]  pContext           Upper layer context to be returned in
*                                the callback.
*
* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_PENDING                  Disconnection operation is in progress,
*                                            pDisconnect_RspCb will be called upon completion.
* \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of 
*                                            a valid type to perform the requsted operation.
* \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
* \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
                                                               pphLibNfc_LlcpSocketDisconnectCb_t         pDisconnect_RspCb,
                                                               void*                                      pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Store the Disconnect callback  and context*/
   pLlcpSocket->pfSocketDisconnect_Cb = pDisconnect_RspCb;
   pLlcpSocket->pDisonnectContext = pContext;

   /* Set the socket in connecting state */
   pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;

   /* Test if a send IFRAME is pending with this socket */
   if((pLlcpSocket->bSocketSendPending == TRUE) || (pLlcpSocket->bSocketRecvPending == TRUE))
   {
      pLlcpSocket->bSocketSendPending = FALSE;
      pLlcpSocket->bSocketRecvPending = FALSE;

      /* Call the send CB, a disconnect abort the send request */
      if (pLlcpSocket->pfSocketSend_Cb != NULL)
      {
         /* Copy CB + context in local variables */
         pphFriNfc_LlcpTransportSocketSendCb_t  pfSendCb     = pLlcpSocket->pfSocketSend_Cb;
         void*                                  pSendContext = pLlcpSocket->pSendContext;
         /* Reset CB + context */
         pLlcpSocket->pfSocketSend_Cb = NULL;
         pLlcpSocket->pSendContext = NULL;
         /* Perform callback */
         pfSendCb(pSendContext, NFCSTATUS_FAILED);
      }
      /* Call the send CB, a disconnect abort the receive request */
      if (pLlcpSocket->pfSocketRecv_Cb != NULL)
      {
         /* Copy CB + context in local variables */
         pphFriNfc_LlcpTransportSocketRecvCb_t  pfRecvCb     = pLlcpSocket->pfSocketRecv_Cb;
         void*                                  pRecvContext = pLlcpSocket->pRecvContext;
         /* Reset CB + context */
         pLlcpSocket->pfSocketRecv_Cb = NULL;
         pLlcpSocket->pRecvContext = NULL;
         /* Perform callback */
         pfRecvCb(pRecvContext, NFCSTATUS_FAILED);
       }
   }

   /* Set the socket Header */
   pLlcpSocket->sLlcpHeader.dsap  = pLlcpSocket->socket_dSap;
   pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_DISC;
   pLlcpSocket->sLlcpHeader.ssap  = pLlcpSocket->socket_sSap;

   /* Test if a send is pending */
   if( pLlcpSocket->psTransport->bSendPending == TRUE)
   {
      pLlcpSocket->bSocketDiscPending =  TRUE;
      status = NFCSTATUS_PENDING;
   }
   else
   {
      /* Store the index of the socket */
      pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;

      status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
                                   &pLlcpSocket->sLlcpHeader,
                                   NULL,
                                   NULL,
                                   phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
                                   pLlcpSocket->psTransport);
      if(status != NFCSTATUS_PENDING)
      {
         LLCP_PRINT("Release Disconnect callback");
         pLlcpSocket->pfSocketConnect_Cb = NULL;
         pLlcpSocket->pConnectContext = NULL;
      }
   }

   return status;
}

/* TODO: comment function phFriNfc_LlcpTransport_Connectionless_SendTo_CB */
static void phFriNfc_LlcpTransport_ConnectionOriented_DisconnectClose_CB(void*        pContext,
                                                                         NFCSTATUS    status)
{
   phFriNfc_LlcpTransport_Socket_t   *pLlcpSocket = (phFriNfc_LlcpTransport_Socket_t*)pContext;

   if(status == NFCSTATUS_SUCCESS)
   {
      /* Reset the pointer to the socket closed */
      pLlcpSocket->eSocket_State                      = phFriNfc_LlcpTransportSocket_eSocketDefault;
      pLlcpSocket->eSocket_Type                       = phFriNfc_LlcpTransport_eDefaultType;
      pLlcpSocket->pContext                           = NULL;
      pLlcpSocket->pSocketErrCb                       = NULL;
      pLlcpSocket->socket_sSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
      pLlcpSocket->socket_dSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
      pLlcpSocket->bSocketRecvPending                 = FALSE;
      pLlcpSocket->bSocketSendPending                 = FALSE;
      pLlcpSocket->bSocketListenPending               = FALSE;
      pLlcpSocket->bSocketDiscPending                 = FALSE;
      pLlcpSocket->socket_VS                          = 0;
      pLlcpSocket->socket_VSA                         = 0;
      pLlcpSocket->socket_VR                          = 0;
      pLlcpSocket->socket_VRA                         = 0;

      phFriNfc_LlcpTransport_ConnectionOriented_Abort(pLlcpSocket);

      memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));

      if (pLlcpSocket->sServiceName.buffer != NULL) {
          phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
      }
      pLlcpSocket->sServiceName.buffer = NULL;
      pLlcpSocket->sServiceName.length = 0;
   }
   else
   {
      /* Disconnect close Error */
   }
}

/**
* \ingroup grp_fri_nfc
* \brief <b>Close a socket on a LLCP-connected device</b>.
*
* This function closes a LLCP socket previously created using phFriNfc_LlcpTransport_Socket.
* If the socket was connected, it is first disconnected, and then closed.
*
* \param[in]  pLlcpSocket                    A pointer to a phFriNfc_LlcpTransport_Socket_t.

* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Close(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
   {
      status = phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(pLlcpSocket,
                                                                    phFriNfc_LlcpTransport_ConnectionOriented_DisconnectClose_CB,
                                                                    pLlcpSocket);
   }
   else
   {
      LLCP_PRINT("Socket not connected, no need to disconnect");
      /* Reset the pointer to the socket closed */
      pLlcpSocket->eSocket_State                      = phFriNfc_LlcpTransportSocket_eSocketDefault;
      pLlcpSocket->eSocket_Type                       = phFriNfc_LlcpTransport_eDefaultType;
      pLlcpSocket->pContext                           = NULL;
      pLlcpSocket->pSocketErrCb                       = NULL;
      pLlcpSocket->socket_sSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
      pLlcpSocket->socket_dSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
      pLlcpSocket->bSocketRecvPending                 = FALSE;
      pLlcpSocket->bSocketSendPending                 = FALSE;
      pLlcpSocket->bSocketListenPending               = FALSE;
      pLlcpSocket->bSocketDiscPending                 = FALSE;
      pLlcpSocket->RemoteBusyConditionInfo            = FALSE;
      pLlcpSocket->ReceiverBusyCondition              = FALSE;
      pLlcpSocket->socket_VS                          = 0;
      pLlcpSocket->socket_VSA                         = 0;
      pLlcpSocket->socket_VR                          = 0;
      pLlcpSocket->socket_VRA                         = 0;

      phFriNfc_LlcpTransport_ConnectionOriented_Abort(pLlcpSocket);

      memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));

      if (pLlcpSocket->sServiceName.buffer != NULL) {
          phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
      }
      pLlcpSocket->sServiceName.buffer = NULL;
      pLlcpSocket->sServiceName.length = 0;
   }
   return NFCSTATUS_SUCCESS;
} 


/**
* \ingroup grp_fri_nfc
* \brief <b>Send data on a socket</b>.
*
* This function is used to write data on a socket. This function
* can only be called on a connection-oriented socket which is already
* in a connected state.
* 
*
* \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  psBuffer           The buffer containing the data to send.
* \param[in]  pSend_RspCb        The callback to be called when the 
*                                operation is completed.
* \param[in]  pContext           Upper layer context to be returned in
*                                the callback.
*
* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_PENDING                  Reception operation is in progress,
*                                            pSend_RspCb will be called upon completion.
* \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of 
*                                            a valid type to perform the requsted operation.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Send(phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
                                                         phNfc_sData_t*                               psBuffer,
                                                         pphFriNfc_LlcpTransportSocketSendCb_t        pSend_RspCb,
                                                         void*                                        pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;


   /* Test the RW window */
   if(!CHECK_SEND_RW(pLlcpSocket))
   {
      /* Store the Send CB and context */
      pLlcpSocket->pfSocketSend_Cb    = pSend_RspCb;
      pLlcpSocket->pSendContext       = pContext;

      /* Set Send pending */
      pLlcpSocket->bSocketSendPending = TRUE;

      /* Store send buffer pointer */
      pLlcpSocket->sSocketSendBuffer = *psBuffer;

      /* Set status */
      status = NFCSTATUS_PENDING;
   }
   else
   {
      /* Store send buffer pointer */
      pLlcpSocket->sSocketSendBuffer = *psBuffer;

      /* Store the Send CB and context */
      pLlcpSocket->pfSocketSend_Cb    = pSend_RspCb;
      pLlcpSocket->pSendContext       = pContext;

      /* Test if a send is pending */
      if(pLlcpSocket->psTransport->bSendPending == TRUE)
      {
         /* Set Send pending */
         pLlcpSocket->bSocketSendPending = TRUE;

         /* Set status */
         status = NFCSTATUS_PENDING;
      }
      else
      {
         /* Store the Send CB and context */
         pLlcpSocket->pfSocketSend_Cb    = pSend_RspCb;
         pLlcpSocket->pSendContext       = pContext;

         status = static_performSendInfo(pLlcpSocket);

         if(status != NFCSTATUS_PENDING)
         {
            LLCP_PRINT("Release Send callback");
            pLlcpSocket->pfSocketSend_Cb = NULL;
            pLlcpSocket->pSendContext = NULL;
         }
      }

   }
   return status;
}


 /**
* \ingroup grp_fri_nfc
* \brief <b>Read data on a socket</b>.
*
* This function is used to read data from a socket. It reads at most the
* size of the reception buffer, but can also return less bytes if less bytes
* are available. If no data is available, the function will be pending until
* more data comes, and the response will be sent by the callback. This function
* can only be called on a connection-oriented socket.
* 
*
* \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  psBuffer           The buffer receiving the data.
* \param[in]  pRecv_RspCb        The callback to be called when the 
*                                operation is completed.
* \param[in]  pContext           Upper layer context to be returned in
*                                the callback.
*
* \retval NFCSTATUS_SUCCESS                  Operation successful.
* \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
*                                            could not be properly interpreted.
* \retval NFCSTATUS_PENDING                  Reception operation is in progress,
*                                            pRecv_RspCb will be called upon completion.
* \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of 
*                                            a valid type to perform the requsted operation.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Recv( phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
                                                          phNfc_sData_t*                               psBuffer,
                                                          pphFriNfc_LlcpTransportSocketRecvCb_t        pRecv_RspCb,
                                                          void*                                        pContext)
{
   NFCSTATUS   status = NFCSTATUS_SUCCESS;
   uint32_t    dataLengthStored = 0;
   uint32_t    dataLengthAvailable = 0; 
   uint32_t    dataLengthRead = 0;
   uint32_t    dataLengthWrite = 0;
   bool_t      dataBufferized = FALSE;

   /* Test if the WorkingBuffer Length is null */
   if(pLlcpSocket->bufferLinearLength == 0)
   {
      if (pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
      {
          return NFCSTATUS_FAILED;
      }
      
      /* Test If data is present in the RW Buffer */
      if(pLlcpSocket->indexRwRead != pLlcpSocket->indexRwWrite)
      {
         if(pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length != 0)
         {
            /* Save I_FRAME into the Receive Buffer */
            memcpy(psBuffer->buffer,pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].buffer,pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length);
            psBuffer->length = pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length;

            dataBufferized = TRUE;

            /* Update VR */
            pLlcpSocket->socket_VR = (pLlcpSocket->socket_VR+1)%16;

            /* Update RW Buffer length */
            pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length = 0;

            /* Update Value Rw Read Index*/
            pLlcpSocket->indexRwRead++;
         }
      }

      if(dataBufferized == TRUE)
      {
         /* Call the Receive CB */
         pRecv_RspCb(pContext,NFCSTATUS_SUCCESS);

         if(pLlcpSocket->ReceiverBusyCondition == TRUE)
         {
            /* Reset the ReceiverBusyCondition Flag */
            pLlcpSocket->ReceiverBusyCondition = FALSE;
            /* RR */
            /* TODO: report status? */
            phFriNfc_Llcp_Send_ReceiveReady_Frame(pLlcpSocket);
         }
      }
      else
      {
         /* Set Receive pending */
         pLlcpSocket->bSocketRecvPending = TRUE;

         /* Store the buffer pointer */
         pLlcpSocket->sSocketRecvBuffer = psBuffer;

         /* Store the Recv CB and context */
         pLlcpSocket->pfSocketRecv_Cb  = pRecv_RspCb;
         pLlcpSocket->pRecvContext     = pContext;

         /* Set status */
         status = NFCSTATUS_PENDING;
      }
   }
   else
   {
      /* Test if data is present in the linear buffer*/
      dataLengthStored = phFriNfc_Llcp_CyclicFifoUsage(&pLlcpSocket->sCyclicFifoBuffer);

      if(dataLengthStored != 0)
      {
         if(psBuffer->length > dataLengthStored)
         {
            psBuffer->length = dataLengthStored;
         }

         /* Read data from the linear buffer */
         dataLengthRead = phFriNfc_Llcp_CyclicFifoFifoRead(&pLlcpSocket->sCyclicFifoBuffer,
                                                           psBuffer->buffer,
                                                           psBuffer->length);

         if(dataLengthRead != 0)
         {
            /* Test If data is present in the RW Buffer */
            while(pLlcpSocket->indexRwRead != pLlcpSocket->indexRwWrite)
            {
               /* Get the data length available in the linear buffer  */
               dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&pLlcpSocket->sCyclicFifoBuffer);

               /* Exit if not enough memory available in linear buffer */
               if(dataLengthAvailable < pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length)
               {
                  break;
               }

               /* Write data into the linear buffer */
               dataLengthWrite = phFriNfc_Llcp_CyclicFifoWrite(&pLlcpSocket->sCyclicFifoBuffer,
                                                               pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].buffer,
                                                               pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length);
               /* Update VR */
               pLlcpSocket->socket_VR = (pLlcpSocket->socket_VR+1)%16;

               /* Set flag bufferized to TRUE */
               dataBufferized = TRUE;

               /* Update RW Buffer length */
               pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length = 0;

               /* Update Value Rw Read Index*/
               pLlcpSocket->indexRwRead++;
            }

            /* Test if data has been bufferized after a read access */
            if(dataBufferized == TRUE)
            {
               /* Get the data length available in the linear buffer  */
               dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&pLlcpSocket->sCyclicFifoBuffer);
               if((dataLengthAvailable >= pLlcpSocket->sSocketOption.miu) && (pLlcpSocket->ReceiverBusyCondition == TRUE))
               {
                  /* Reset the ReceiverBusyCondition Flag */
                  pLlcpSocket->ReceiverBusyCondition = FALSE;
                  /* RR */
                  /* TODO: report status? */
                  phFriNfc_Llcp_Send_ReceiveReady_Frame(pLlcpSocket);
               }
            }
            
            /* Call the Receive CB */
            pRecv_RspCb(pContext,NFCSTATUS_SUCCESS);
         }
         else
         {
            /* Call the Receive CB   */
            status = NFCSTATUS_FAILED;
         }
      }
      else
      {
         if (pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
         {
             status = NFCSTATUS_FAILED;
         }
         else
         {
            /* Set Receive pending */
            pLlcpSocket->bSocketRecvPending = TRUE;

            /* Store the buffer pointer */
            pLlcpSocket->sSocketRecvBuffer = psBuffer;

            /* Store the Recv CB and context */
            pLlcpSocket->pfSocketRecv_Cb  = pRecv_RspCb;
            pLlcpSocket->pRecvContext     = pContext;

            /* Set status */
            status = NFCSTATUS_PENDING;
         }
      }
   }

   if(status != NFCSTATUS_PENDING)
   {
      /* Note: The receive callback must be released to avoid being called at abort */
      LLCP_PRINT("Release Receive callback");
      pLlcpSocket->pfSocketRecv_Cb = NULL;
      pLlcpSocket->pRecvContext = NULL;
   }

   return status;
}


