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

/*include files*/
#include <phOsalNfc.h>
#include <phLibNfcStatus.h>
#include <phLibNfc.h>
#include <phNfcLlcpTypes.h>
#include <phFriNfc_Llcp.h>
#include <phFriNfc_LlcpTransport.h>
#include <phFriNfc_LlcpTransport_Connectionless.h>
#include <phFriNfc_LlcpTransport_Connection.h>

/* local macros */

/* Check if (a <= x < b) */
#define IS_BETWEEN(x, a, b) (((x)>=(a)) && ((x)<(b)))

static NFCSTATUS phFriNfc_LlcpTransport_RegisterName(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket,
                                                     uint8_t                            nSap,
                                                     phNfc_sData_t                      *psServiceName);

static NFCSTATUS phFriNfc_LlcpTransport_DiscoverServicesEx(phFriNfc_LlcpTransport_t *psTransport);

static void phFriNfc_LlcpTransport_Send_CB(void            *pContext,
                                           NFCSTATUS        status);

static NFCSTATUS phFriNfc_LlcpTransport_GetFreeSap(phFriNfc_LlcpTransport_t * psTransport, phNfc_sData_t *psServiceName, uint8_t * pnSap)
{
   uint8_t i;
   uint8_t sap;
   uint8_t min_sap_range, max_sap_range;
   phFriNfc_LlcpTransport_Socket_t* pSocketTable = psTransport->pSocketTable;

   /* Calculate authorized SAP range */
   if ((psServiceName != NULL) && (psServiceName->length > 0))
   {
      /* Make sure that we will return the same SAP if service name was already used in the past */
      for(i=0 ; i<PHFRINFC_LLCP_SDP_ADVERTISED_NB ; i++)
      {
         if((psTransport->pCachedServiceNames[i].sServiceName.length > 0) &&
            (memcmp(psTransport->pCachedServiceNames[i].sServiceName.buffer, psServiceName->buffer, psServiceName->length) == 0))
         {
            /* Service name matched in cached service names list */
            *pnSap = psTransport->pCachedServiceNames[i].nSap;
            return NFCSTATUS_SUCCESS;
         }
      }

      /* SDP advertised service */
      min_sap_range = PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST;
      max_sap_range = PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST;
   }
   else
   {
      /* Non-SDP advertised service */
      min_sap_range = PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST;
      max_sap_range = PHFRINFC_LLCP_SAP_NUMBER;
   }

   /* Try all possible SAPs */
   for(sap=min_sap_range ; sap<max_sap_range ; sap++)
   {
      /* Go through socket list to check if current SAP is in use */
      for(i=0 ; i<PHFRINFC_LLCP_NB_SOCKET_MAX ; i++)
      {
         if((pSocketTable[i].eSocket_State >= phFriNfc_LlcpTransportSocket_eSocketBound) &&
            (pSocketTable[i].socket_sSap == sap))
         {
            /* SAP is already in use */
            break;
         }
      }

      if (i >= PHFRINFC_LLCP_NB_SOCKET_MAX)
      {
         /* No socket is using current SAP, proceed with binding */
         *pnSap = sap;
         return NFCSTATUS_SUCCESS;
      }
   }

   /* If we reach this point, it means that no SAP is free */
   return NFCSTATUS_INSUFFICIENT_RESOURCES;
}

static NFCSTATUS phFriNfc_LlcpTransport_EncodeSdreqTlv(phNfc_sData_t  *psTlvData,
                                                       uint32_t       *pOffset,
                                                       uint8_t        nTid,
                                                       phNfc_sData_t  *psServiceName)
{
   NFCSTATUS result;
   uint32_t nTlvOffset = *pOffset;
   uint32_t nTlvStartOffset = nTlvOffset;

   /* Encode the TID */
   result = phFriNfc_Llcp_EncodeTLV(psTlvData,
                                    &nTlvOffset,
                                    PHFRINFC_LLCP_TLV_TYPE_SDREQ,
                                    1,
                                    &nTid);
   if (result != NFCSTATUS_SUCCESS)
   {
      goto clean_and_return;
   }

   /* Encode the service name itself */
   result = phFriNfc_Llcp_AppendTLV(psTlvData,
                                    nTlvStartOffset,
                                    &nTlvOffset,
                                    psServiceName->length,
                                    psServiceName->buffer);
   if (result != NFCSTATUS_SUCCESS)
   {
      goto clean_and_return;
   }

clean_and_return:
   /* Save offset if no error occured */
   if (result == NFCSTATUS_SUCCESS)
   {
      *pOffset = nTlvOffset;
   }

   return result;
}

static NFCSTATUS phFriNfc_LlcpTransport_EncodeSdresTlv(phNfc_sData_t  *psTlvData,
                                                       uint32_t       *pOffset,
                                                       uint8_t        nTid,
                                                       uint8_t        nSap)
{
   NFCSTATUS result;
   uint32_t nTlvStartOffset = *pOffset;

   /* Encode the TID */
   result = phFriNfc_Llcp_EncodeTLV(psTlvData,
                                    pOffset,
                                    PHFRINFC_LLCP_TLV_TYPE_SDRES,
                                    1,
                                    &nTid);
   if (result != NFCSTATUS_SUCCESS)
   {
      goto clean_and_return;
   }

   /* Encode the service name itself */
   result = phFriNfc_Llcp_AppendTLV(psTlvData,
                                    nTlvStartOffset,
                                    pOffset,
                                    1,
                                    &nSap);
   if (result != NFCSTATUS_SUCCESS)
   {
      goto clean_and_return;
   }

clean_and_return:
   /* Restore previous offset if an error occured */
   if (result != NFCSTATUS_SUCCESS)
   {
      *pOffset = nTlvStartOffset;
   }

   return result;
}

static phFriNfc_LlcpTransport_Socket_t* phFriNfc_LlcpTransport_ServiceNameLoockup(phFriNfc_LlcpTransport_t *psTransport,
                                                                                  phNfc_sData_t            *pServiceName)
{
   uint32_t                            index;
   uint8_t                             cacheIndex;
   phFriNfc_Llcp_CachedServiceName_t * pCachedServiceName;
   phFriNfc_LlcpTransport_Socket_t *   pSocket;

   /* Search a socket with the SN */
   for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
   {
      pSocket = &psTransport->pSocketTable[index];
      /* Test if the CO socket is in Listen state or the CL socket is bound
         and if its SN is the good one */
      if((((pSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionOriented)
         && (pSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketRegistered))
         || ((pSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionLess)
         && (pSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketBound)))
         &&
         (pServiceName->length == pSocket->sServiceName.length)
         && !memcmp(pServiceName->buffer, pSocket->sServiceName.buffer, pServiceName->length))
      {
         /* Add new entry to cached service name/sap if not already in table */
         for(cacheIndex=0;cacheIndex<PHFRINFC_LLCP_SDP_ADVERTISED_NB;cacheIndex++)
         {
            pCachedServiceName = &psTransport->pCachedServiceNames[cacheIndex];
            if (pCachedServiceName->sServiceName.buffer != NULL)
            {
               if ((pCachedServiceName->sServiceName.length == pServiceName->length) &&
                   (memcmp(pCachedServiceName->sServiceName.buffer, pServiceName->buffer, pServiceName->length) == 0))
               {
                  /* Already registered */
                  break;
               }
            }
            else
            {
               /* Reached end of existing entries and not found the service name,
                * => Add the new entry
                */
               pCachedServiceName->nSap = pSocket->socket_sSap;
               pCachedServiceName->sServiceName.buffer = phOsalNfc_GetMemory(pServiceName->length);
               if (pCachedServiceName->sServiceName.buffer == NULL)
               {
                  /* Unable to cache this entry, so report this service as not found */
                  return NULL;
               }
               memcpy(pCachedServiceName->sServiceName.buffer, pServiceName->buffer, pServiceName->length);
               pCachedServiceName->sServiceName.length = pServiceName->length;
               break;
            }
         }

         return pSocket;
      }
   }

   return NULL;
}


static NFCSTATUS phFriNfc_LlcpTransport_DiscoveryAnswer(phFriNfc_LlcpTransport_t *psTransport)
{
   NFCSTATUS         result = NFCSTATUS_PENDING;
   phNfc_sData_t     sInfoBuffer;
   uint32_t          nTlvOffset;
   uint8_t           index;
   uint8_t           nTid, nSap;

   /* Test if a send is pending */
   if(!psTransport->bSendPending)
   {
      /* Set the header */
      psTransport->sLlcpHeader.dsap  = PHFRINFC_LLCP_SAP_SDP;
      psTransport->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_SNL;
      psTransport->sLlcpHeader.ssap  = PHFRINFC_LLCP_SAP_SDP;

      /* Prepare the info buffer */
      sInfoBuffer.buffer = psTransport->pDiscoveryBuffer;
      sInfoBuffer.length = sizeof(psTransport->pDiscoveryBuffer);

      /* Encode as many requests as possible */
      nTlvOffset = 0;
      for(index=0 ; index<psTransport->nDiscoveryResListSize ; index++)
      {
         /* Get current TID/SAP and try to encode them in SNL frame */
         nTid = psTransport->nDiscoveryResTidList[index];
         nSap = psTransport->nDiscoveryResSapList[index];
         /* Encode response */
         result = phFriNfc_LlcpTransport_EncodeSdresTlv(&sInfoBuffer,
                                                        &nTlvOffset,
                                                        nTid,
                                                        nSap);
         if (result != NFCSTATUS_SUCCESS)
         {
            /* Impossible to fit the entire response */
            /* TODO: support reponse framgentation */
            break;
         }
      }

      /* Reset list size to be able to handle a new request */
      psTransport->nDiscoveryResListSize = 0;

      /* Update buffer length to match real TLV size */
      sInfoBuffer.length = nTlvOffset;

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

      /* Send SNL frame */
      result =  phFriNfc_Llcp_Send(psTransport->pLlcp,
                                   &psTransport->sLlcpHeader,
                                   NULL,
                                   &sInfoBuffer,
                                   phFriNfc_LlcpTransport_Send_CB,
                                   psTransport);
   }
   else
   {
      /* Impossible to send now, this function will be called again on next opportunity */
   }

   return result;
}


static void Handle_Discovery_IncomingFrame(phFriNfc_LlcpTransport_t           *psTransport,
                                           phNfc_sData_t                      *psData)
{
   NFCSTATUS                        result;
   phNfc_sData_t                    sValue;
   phNfc_sData_t                    sResponseData;
   phNfc_sData_t                    sServiceName;
   uint32_t                         nInTlvOffset;
   uint8_t                          nType;
   uint8_t                          nTid;
   uint8_t                          nSap;
   pphFriNfc_Cr_t                   pfSavedCb;
   void                             *pfSavedContext;
   phFriNfc_LlcpTransport_Socket_t  *pSocket;


   /* Prepare buffer */
   sResponseData.buffer = psTransport->pDiscoveryBuffer;
   sResponseData.length = sizeof(psTransport->pDiscoveryBuffer);

   /* Parse all TLVs in frame */
   nInTlvOffset = 0;
   while(nInTlvOffset < psData->length)
   {
      result = phFriNfc_Llcp_DecodeTLV(psData,
                                       &nInTlvOffset,
                                       &nType,
                                       &sValue );
      switch(nType)
      {
         case PHFRINFC_LLCP_TLV_TYPE_SDREQ:
            if (sValue.length < 2)
            {
               /* Erroneous request, ignore */
               break;
            }
            /* Decode TID */
            nTid = sValue.buffer[0];
            /* Decode service name */
            sServiceName.buffer = sValue.buffer + 1;
            sServiceName.length = sValue.length - 1;

            /* Handle SDP service name */
            if((sServiceName.length == sizeof(PHFRINFC_LLCP_SERVICENAME_SDP)-1)
               && !memcmp(sServiceName.buffer, PHFRINFC_LLCP_SERVICENAME_SDP, sServiceName.length))
            {
               nSap = PHFRINFC_LLCP_SAP_SDP;
            }
            else
            {
               /* Match service name in socket list */
               pSocket = phFriNfc_LlcpTransport_ServiceNameLoockup(psTransport, &sServiceName);
               if (pSocket != NULL)
               {
                  nSap = pSocket->socket_sSap;
               }
               else
               {
                  nSap = 0;
               }
            }

            /* Encode response */
            if (psTransport->nDiscoveryResListSize < PHFRINFC_LLCP_SNL_RESPONSE_MAX)
            {
               psTransport->nDiscoveryResSapList[psTransport->nDiscoveryResListSize] = nSap;
               psTransport->nDiscoveryResTidList[psTransport->nDiscoveryResListSize] = nTid;
               psTransport->nDiscoveryResListSize++;
            }
            else
            {
               /* Remote peer is sending more than max. allowed requests (max. 256
                  different TID values), drop invalid requests to avoid buffer overflow
               */
            }
            break;

         case PHFRINFC_LLCP_TLV_TYPE_SDRES:
            if (psTransport->pfDiscover_Cb == NULL)
            {
               /* Ignore response when no requests are pending */
               break;
            }
            if (sValue.length != 2)
            {
               /* Erroneous response, ignore it */
               break;
            }
            /* Decode TID and SAP */
            nTid = sValue.buffer[0];
            if (nTid >= psTransport->nDiscoveryListSize)
            {
               /* Unkown TID, ignore it */
               break;
            }
            nSap = sValue.buffer[1];
            /* Save response */
            psTransport->pnDiscoverySapList[nTid] = nSap;
            /* Update response counter */
            psTransport->nDiscoveryResOffset++;
            break;

         default:
            /* Ignored */
            break;
      }
   }

   /* If discovery requests have been received, send response */
   if (psTransport->nDiscoveryResListSize > 0)
   {
      phFriNfc_LlcpTransport_DiscoveryAnswer(psTransport);
   }

   /* If all discovery responses have been received, trigger callback (if any) */
   if ((psTransport->pfDiscover_Cb != NULL) &&
       (psTransport->nDiscoveryResOffset >= psTransport->nDiscoveryListSize))
   {
      pfSavedCb = psTransport->pfDiscover_Cb;
      pfSavedContext = psTransport->pDiscoverContext;

      psTransport->pfDiscover_Cb = NULL;
      psTransport->pDiscoverContext = NULL;

      pfSavedCb(pfSavedContext, NFCSTATUS_SUCCESS);
   }
}


/* TODO: comment function Transport recv CB */
static void phFriNfc_LlcpTransport__Recv_CB(void            *pContext,
                                            phNfc_sData_t   *psData,
                                            NFCSTATUS        status)
{
   phFriNfc_Llcp_sPacketHeader_t   sLlcpLocalHeader;
   uint8_t   dsap;
   uint8_t   ptype;
   uint8_t   ssap;

   phFriNfc_LlcpTransport_t* pLlcpTransport = (phFriNfc_LlcpTransport_t*)pContext;

   if(status != NFCSTATUS_SUCCESS)
   {
      pLlcpTransport->LinkStatusError = TRUE;
   }
   else
   {
      phFriNfc_Llcp_Buffer2Header( psData->buffer,0x00, &sLlcpLocalHeader);

      dsap  = (uint8_t)sLlcpLocalHeader.dsap;
      ptype = (uint8_t)sLlcpLocalHeader.ptype;
      ssap  = (uint8_t)sLlcpLocalHeader.ssap;

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

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

      switch(ptype)
      {
      /* Connectionless */
      case PHFRINFC_LLCP_PTYPE_UI:
         {
            Handle_Connectionless_IncommingFrame(pLlcpTransport,
                                                 psData,
                                                 dsap,
                                                 ssap);
         }break;

      /* Service Discovery Protocol */
      case PHFRINFC_LLCP_PTYPE_SNL:
         {
            if ((ssap == PHFRINFC_LLCP_SAP_SDP) && (dsap == PHFRINFC_LLCP_SAP_SDP))
            {
               Handle_Discovery_IncomingFrame(pLlcpTransport,
                                              psData);
            }
            else
            {
               /* Ignore frame if source and destination are not the SDP service */
            }
         }break;

      /* Connection oriented */
      /* NOTE: forward reserved PTYPE to enable FRMR sending */
      case PHFRINFC_LLCP_PTYPE_CONNECT:
      case PHFRINFC_LLCP_PTYPE_CC:
      case PHFRINFC_LLCP_PTYPE_DISC:
      case PHFRINFC_LLCP_PTYPE_DM:
      case PHFRINFC_LLCP_PTYPE_I:
      case PHFRINFC_LLCP_PTYPE_RR:
      case PHFRINFC_LLCP_PTYPE_RNR:
      case PHFRINFC_LLCP_PTYPE_FRMR:
      case PHFRINFC_LLCP_PTYPE_RESERVED1:
      case PHFRINFC_LLCP_PTYPE_RESERVED2:
      case PHFRINFC_LLCP_PTYPE_RESERVED3:
         {
            Handle_ConnectionOriented_IncommingFrame(pLlcpTransport,
                                                     psData,
                                                     dsap,
                                                     ptype,
                                                     ssap);
         }break;
      default:
         {

         }break;
      }

      /*Restart the Receive Loop */
      status  = phFriNfc_Llcp_Recv(pLlcpTransport->pLlcp,
                                   phFriNfc_LlcpTransport__Recv_CB,
                                   pLlcpTransport);
   }
}


/* TODO: comment function Transport recv CB */
static void phFriNfc_LlcpTransport_Send_CB(void            *pContext,
                                           NFCSTATUS        status)
{
   phFriNfc_LlcpTransport_t         *psTransport = (phFriNfc_LlcpTransport_t*)pContext;
   NFCSTATUS                        result = NFCSTATUS_FAILED;
   phNfc_sData_t                    sFrmrBuffer;
   phFriNfc_Llcp_Send_CB_t          pfSavedCb;
   void                             *pSavedContext;
   phFriNfc_LlcpTransport_Socket_t  *pCurrentSocket = NULL;
   uint8_t                          index;

   /* 1 - Reset the FLAG send pending*/
   psTransport->bSendPending = FALSE;

   /* 2 - Handle pending error responses */

   if(psTransport->bFrmrPending)
   {
      /* Reset FRMR pending */
      psTransport->bFrmrPending = FALSE;

      /* Send Frmr */
      sFrmrBuffer.buffer = psTransport->FrmrInfoBuffer;
      sFrmrBuffer.length = 0x04; /* Size of FRMR Information field */

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

      result =  phFriNfc_Llcp_Send(psTransport->pLlcp,
                                   &psTransport->sLlcpHeader,
                                   NULL,
                                   &sFrmrBuffer,
                                   phFriNfc_LlcpTransport_Send_CB,
                                   psTransport);

   }
   else if(psTransport->bDmPending)
   {
      /* Reset DM pending */
      psTransport->bDmPending = FALSE;

      /* Send DM pending */
      result = phFriNfc_LlcpTransport_SendDisconnectMode(psTransport,
                                                         psTransport->DmInfoBuffer[0],
                                                         psTransport->DmInfoBuffer[1],
                                                         psTransport->DmInfoBuffer[2]);
   }

   /* 3 - Call the original callback */

   if (psTransport->pfLinkSendCb != NULL)
   {
      pfSavedCb = psTransport->pfLinkSendCb;
      pSavedContext = psTransport->pLinkSendContext;

      psTransport->pfLinkSendCb = NULL;
      psTransport->pLinkSendContext = NULL;

      (*pfSavedCb)(pSavedContext, status);
   }

   /* 4 - Handle pending send operations */

   /* Check for pending discovery requests/responses */
   if (psTransport->nDiscoveryResListSize > 0)
   {
      phFriNfc_LlcpTransport_DiscoveryAnswer(psTransport);
   }
   if ( (psTransport->pfDiscover_Cb != NULL) &&
        (psTransport->nDiscoveryReqOffset < psTransport->nDiscoveryListSize) )
   {
      result = phFriNfc_LlcpTransport_DiscoverServicesEx(psTransport);
   }

   /* Init index */
   index = psTransport->socketIndex;

   /* Check all sockets for pending operation */
   do
   {
      /* Modulo-increment index */
      index = (index + 1) % PHFRINFC_LLCP_NB_SOCKET_MAX;

      pCurrentSocket = &psTransport->pSocketTable[index];

      /* Dispatch to the corresponding transport layer */
      if (pCurrentSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionOriented)
      {
         result = phFriNfc_LlcpTransport_ConnectionOriented_HandlePendingOperations(pCurrentSocket);
      }
      else if (pCurrentSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionLess)
      {
         result = phFriNfc_LlcpTransport_Connectionless_HandlePendingOperations(pCurrentSocket);
      }

      if (result != NFCSTATUS_FAILED)
      {
         /* Stop looping if pending operation has been found */
         break;
      }

   } while(index != psTransport->socketIndex);

   /* Save the new index */
   psTransport->socketIndex = index;
}


/* TODO: comment function Transport reset */
NFCSTATUS phFriNfc_LlcpTransport_Reset (phFriNfc_LlcpTransport_t      *pLlcpTransport,
                                        phFriNfc_Llcp_t               *pLlcp)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   uint8_t i;

   /* Check for NULL pointers */
   if(pLlcpTransport == NULL || pLlcp == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      /* Reset Transport structure */ 
      pLlcpTransport->pLlcp            = pLlcp;
      pLlcpTransport->LinkStatusError  = FALSE;
      pLlcpTransport->bSendPending     = FALSE;
      pLlcpTransport->bRecvPending     = FALSE;
      pLlcpTransport->bDmPending       = FALSE;
      pLlcpTransport->bFrmrPending     = FALSE;
      pLlcpTransport->socketIndex      = FALSE;
      pLlcpTransport->LinkStatusError  = 0;
      pLlcpTransport->pfDiscover_Cb    = NULL;

      /* Initialize cached service name/sap table */
      memset(pLlcpTransport->pCachedServiceNames, 0x00, sizeof(phFriNfc_Llcp_CachedServiceName_t)*PHFRINFC_LLCP_SDP_ADVERTISED_NB);

      /* Reset all the socket info in the table */
      for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
      {
         pLlcpTransport->pSocketTable[i].eSocket_State                  = phFriNfc_LlcpTransportSocket_eSocketDefault;
         pLlcpTransport->pSocketTable[i].eSocket_Type                   = phFriNfc_LlcpTransport_eDefaultType;
         pLlcpTransport->pSocketTable[i].index                          = i;
         pLlcpTransport->pSocketTable[i].pContext                       = NULL;
         pLlcpTransport->pSocketTable[i].pListenContext                 = NULL;
         pLlcpTransport->pSocketTable[i].pAcceptContext                 = NULL;
         pLlcpTransport->pSocketTable[i].pRejectContext                 = NULL;
         pLlcpTransport->pSocketTable[i].pConnectContext                = NULL;
         pLlcpTransport->pSocketTable[i].pDisonnectContext              = NULL;
         pLlcpTransport->pSocketTable[i].pSendContext                   = NULL;
         pLlcpTransport->pSocketTable[i].pRecvContext                   = NULL;
         pLlcpTransport->pSocketTable[i].pSocketErrCb                   = NULL;
         pLlcpTransport->pSocketTable[i].bufferLinearLength             = 0;
         pLlcpTransport->pSocketTable[i].bufferSendMaxLength            = 0;
         pLlcpTransport->pSocketTable[i].bufferRwMaxLength              = 0;
         pLlcpTransport->pSocketTable[i].ReceiverBusyCondition          = FALSE;
         pLlcpTransport->pSocketTable[i].RemoteBusyConditionInfo        = FALSE;
         pLlcpTransport->pSocketTable[i].socket_sSap                    = PHFRINFC_LLCP_SAP_DEFAULT;
         pLlcpTransport->pSocketTable[i].socket_dSap                    = PHFRINFC_LLCP_SAP_DEFAULT;
         pLlcpTransport->pSocketTable[i].bSocketRecvPending             = FALSE;
         pLlcpTransport->pSocketTable[i].bSocketSendPending             = FALSE;
         pLlcpTransport->pSocketTable[i].bSocketListenPending           = FALSE;
         pLlcpTransport->pSocketTable[i].bSocketDiscPending             = FALSE;
         pLlcpTransport->pSocketTable[i].bSocketConnectPending          = FALSE;
         pLlcpTransport->pSocketTable[i].bSocketAcceptPending           = FALSE;
         pLlcpTransport->pSocketTable[i].bSocketRRPending               = FALSE;
         pLlcpTransport->pSocketTable[i].bSocketRNRPending              = FALSE;
         pLlcpTransport->pSocketTable[i].psTransport                    = pLlcpTransport;
         pLlcpTransport->pSocketTable[i].pfSocketSend_Cb                = NULL;
         pLlcpTransport->pSocketTable[i].pfSocketRecv_Cb                = NULL;
         pLlcpTransport->pSocketTable[i].pfSocketRecvFrom_Cb            = NULL;
         pLlcpTransport->pSocketTable[i].pfSocketListen_Cb              = NULL;
         pLlcpTransport->pSocketTable[i].pfSocketConnect_Cb             = NULL;
         pLlcpTransport->pSocketTable[i].pfSocketDisconnect_Cb          = NULL;
         pLlcpTransport->pSocketTable[i].socket_VS                      = 0;
         pLlcpTransport->pSocketTable[i].socket_VSA                     = 0;
         pLlcpTransport->pSocketTable[i].socket_VR                      = 0;
         pLlcpTransport->pSocketTable[i].socket_VRA                     = 0;
         pLlcpTransport->pSocketTable[i].remoteRW                       = 0;
         pLlcpTransport->pSocketTable[i].localRW                        = 0;
         pLlcpTransport->pSocketTable[i].remoteMIU                      = 0;
         pLlcpTransport->pSocketTable[i].localMIUX                      = 0;
         pLlcpTransport->pSocketTable[i].index                          = 0;
         pLlcpTransport->pSocketTable[i].indexRwRead                    = 0;
         pLlcpTransport->pSocketTable[i].indexRwWrite                   = 0;

         memset(&pLlcpTransport->pSocketTable[i].sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));

         if (pLlcpTransport->pSocketTable[i].sServiceName.buffer != NULL) {
            phOsalNfc_FreeMemory(pLlcpTransport->pSocketTable[i].sServiceName.buffer);
         }
         pLlcpTransport->pSocketTable[i].sServiceName.buffer = NULL;
         pLlcpTransport->pSocketTable[i].sServiceName.length = 0;
      }

      /* Start The Receive Loop */
      status  = phFriNfc_Llcp_Recv(pLlcpTransport->pLlcp,
                                   phFriNfc_LlcpTransport__Recv_CB,
                                   pLlcpTransport);
   }
   return status;
}

/* TODO: comment function Transport CloseAll */
NFCSTATUS phFriNfc_LlcpTransport_CloseAll (phFriNfc_LlcpTransport_t *pLlcpTransport)
{
   NFCSTATUS                           status = NFCSTATUS_SUCCESS;
   phFriNfc_Llcp_CachedServiceName_t * pCachedServiceName;
   uint8_t                             i;

   /* Check for NULL pointers */
   if(pLlcpTransport == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }

   /* Close all sockets */
   for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
   {
      if(pLlcpTransport->pSocketTable[i].eSocket_Type == phFriNfc_LlcpTransport_eConnectionOriented)
      {
         switch(pLlcpTransport->pSocketTable[i].eSocket_State)
         {
         case phFriNfc_LlcpTransportSocket_eSocketConnected:
         case phFriNfc_LlcpTransportSocket_eSocketConnecting:
         case phFriNfc_LlcpTransportSocket_eSocketAccepted:
         case phFriNfc_LlcpTransportSocket_eSocketDisconnected:
         case phFriNfc_LlcpTransportSocket_eSocketDisconnecting:
         case phFriNfc_LlcpTransportSocket_eSocketRejected:
            phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]);
            break;
         default:
            /* Do nothing */
            break;
         }
      }
      else
      {
         phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]);
      }
   }

   /* Reset cached service name/sap table */
   for(i=0;i<PHFRINFC_LLCP_SDP_ADVERTISED_NB;i++)
   {
      pCachedServiceName = &pLlcpTransport->pCachedServiceNames[i];

      pCachedServiceName->nSap = 0;
      if (pCachedServiceName->sServiceName.buffer != NULL)
      {
         phOsalNfc_FreeMemory(pCachedServiceName->sServiceName.buffer);
         pCachedServiceName->sServiceName.buffer = NULL;
      }
      pCachedServiceName->sServiceName.length = 0;
   }

   return status;
}


/* TODO: comment function Transport LinkSend */
NFCSTATUS phFriNfc_LlcpTransport_LinkSend( phFriNfc_LlcpTransport_t         *LlcpTransport,
                                           phFriNfc_Llcp_sPacketHeader_t    *psHeader,
                                           phFriNfc_Llcp_sPacketSequence_t  *psSequence,
                                           phNfc_sData_t                    *psInfo,
                                           phFriNfc_Llcp_Send_CB_t          pfSend_CB,
                                           void                             *pContext )
{
   NFCSTATUS status;
   /* Check if a send is already ongoing */
   if (LlcpTransport->pfLinkSendCb != NULL)
   {
      return NFCSTATUS_BUSY;
   }
   /* Save callback details */
   LlcpTransport->pfLinkSendCb = pfSend_CB;
   LlcpTransport->pLinkSendContext = pContext;

   /* Call the link-level send function */
   status = phFriNfc_Llcp_Send(LlcpTransport->pLlcp, psHeader, psSequence, psInfo, phFriNfc_LlcpTransport_Send_CB, (void*)LlcpTransport);
   if (status != NFCSTATUS_PENDING && status != NFCSTATUS_SUCCESS) {
       // Clear out callbacks
       LlcpTransport->pfLinkSendCb = NULL;
       LlcpTransport->pLinkSendContext = NULL;
   }
   return status;
}


/* TODO: comment function Transport SendFrameReject */
NFCSTATUS phFriNfc_LlcpTransport_SendFrameReject(phFriNfc_LlcpTransport_t           *psTransport,
                                                 uint8_t                            dsap,
                                                 uint8_t                            rejectedPTYPE,
                                                 uint8_t                            ssap,
                                                 phFriNfc_Llcp_sPacketSequence_t*   sLlcpSequence,
                                                 uint8_t                            WFlag,
                                                 uint8_t                            IFlag,
                                                 uint8_t                            RFlag,
                                                 uint8_t                            SFlag,
                                                 uint8_t                            vs,
                                                 uint8_t                            vsa,
                                                 uint8_t                            vr,
                                                 uint8_t                            vra)
{
   NFCSTATUS                       status = NFCSTATUS_SUCCESS;
   phNfc_sData_t                   sFrmrBuffer;
   uint8_t                         flagValue;
   uint8_t                         sequence = 0;
   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_eSocketDefault;

      /* 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]);

      /* Set FRMR Header */
      psTransport->sLlcpHeader.dsap   = ssap;
      psTransport->sLlcpHeader.ptype  = PHFRINFC_LLCP_PTYPE_FRMR;
      psTransport->sLlcpHeader.ssap   = dsap;

      /* Set FRMR Information Field */
      flagValue = (WFlag<<7) | (IFlag<<6) | (RFlag<<5) | (SFlag<<4) | rejectedPTYPE;
      if (sLlcpSequence != NULL)
      {
         sequence = (uint8_t)((sLlcpSequence->ns<<4)|(sLlcpSequence->nr));
      }

      psTransport->FrmrInfoBuffer[0] = flagValue;
      psTransport->FrmrInfoBuffer[1] = sequence;
      psTransport->FrmrInfoBuffer[2] = (vs<<4)|vr ;
      psTransport->FrmrInfoBuffer[3] = (vsa<<4)|vra ;

      /* Test if a send is pending */
      if(psTransport->bSendPending)
      {
         psTransport->bFrmrPending = TRUE;
         status = NFCSTATUS_PENDING;
      }
      else
      {
         sFrmrBuffer.buffer =  psTransport->FrmrInfoBuffer;
         sFrmrBuffer.length =  0x04; /* Size of FRMR Information field */

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

         /* Send FRMR frame */
         status =  phFriNfc_Llcp_Send(psTransport->pLlcp,
                                      &psTransport->sLlcpHeader,
                                      NULL,
                                      &sFrmrBuffer,
                                      phFriNfc_LlcpTransport_Send_CB,
                                      psTransport);
      }
   }
   else
   {
      /* No active  socket*/
      /* FRMR Frame not handled*/
   }
   return status;
}


/* TODO: comment function Transport SendDisconnectMode (NOTE: used only
 * for requests not bound to a socket, like "service not found")
 */
NFCSTATUS phFriNfc_LlcpTransport_SendDisconnectMode(phFriNfc_LlcpTransport_t* psTransport,
                                                    uint8_t                   dsap,
                                                    uint8_t                   ssap,
                                                    uint8_t                   dmOpCode)
{
   NFCSTATUS                       status = NFCSTATUS_SUCCESS;

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

      /* Store DM Info */
      psTransport->DmInfoBuffer[0] = dsap;
      psTransport->DmInfoBuffer[1] = ssap;
      psTransport->DmInfoBuffer[2] = dmOpCode;

     status = NFCSTATUS_PENDING;
   }
   else
   {
      /* Set the header */
      psTransport->sDmHeader.dsap  = dsap;
      psTransport->sDmHeader.ptype = PHFRINFC_LLCP_PTYPE_DM;
      psTransport->sDmHeader.ssap  = ssap;

      /* Save Operation Code to be provided in DM frame payload */
      psTransport->DmInfoBuffer[2] = dmOpCode;
      psTransport->sDmPayload.buffer    = &psTransport->DmInfoBuffer[2];
      psTransport->sDmPayload.length    = PHFRINFC_LLCP_DM_LENGTH;

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

      /* Send DM frame */
      status =  phFriNfc_Llcp_Send(psTransport->pLlcp,
                                   &psTransport->sDmHeader,
                                   NULL,
                                   &psTransport->sDmPayload,
                                   phFriNfc_LlcpTransport_Send_CB,
                                   psTransport);
   }

   return status;
}


/**
* \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_SocketGetLocalOptions(phFriNfc_LlcpTransport_Socket_t  *pLlcpSocket,
                                                       phLibNfc_Llcp_sSocketOptions_t   *psLocalOptions)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Check for NULL pointers */
   if (pLlcpSocket == NULL || psLocalOptions == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /*  Test the socket type */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /*  Test the socket state */
   else if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   else
   {
     status = phFriNfc_LlcpTransport_ConnectionOriented_SocketGetLocalOptions(pLlcpSocket,
                                                                              psLocalOptions);
   }

   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_SocketGetRemoteOptions(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket,
                                                        phLibNfc_Llcp_sSocketOptions_t*    psRemoteOptions)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Check for NULL pointers */
   if (pLlcpSocket == NULL || psRemoteOptions == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /*  Test the socket type */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /*  Test the socket state */
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   else
   {
      status = phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(pLlcpSocket,
                                                                                psRemoteOptions);
   }

   return status;
}


static NFCSTATUS phFriNfc_LlcpTransport_DiscoverServicesEx(phFriNfc_LlcpTransport_t *psTransport)
{
   NFCSTATUS         result = NFCSTATUS_PENDING;
   phNfc_sData_t     sInfoBuffer;
   phNfc_sData_t     *psServiceName;
   uint32_t          nTlvOffset;

   /* Test if a send is pending */
   if(!psTransport->bSendPending)
   {
      /* Set the header */
      psTransport->sLlcpHeader.dsap  = PHFRINFC_LLCP_SAP_SDP;
      psTransport->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_SNL;
      psTransport->sLlcpHeader.ssap  = PHFRINFC_LLCP_SAP_SDP;

      /* Prepare the info buffer */
      sInfoBuffer.buffer = psTransport->pDiscoveryBuffer;
      sInfoBuffer.length = sizeof(psTransport->pDiscoveryBuffer);

      /* Encode as many requests as possible */
      nTlvOffset = 0;
      while(psTransport->nDiscoveryReqOffset < psTransport->nDiscoveryListSize)
      {
         /* Get current service name and try to encode it in SNL frame */
         psServiceName = &psTransport->psDiscoveryServiceNameList[psTransport->nDiscoveryReqOffset];
         result = phFriNfc_LlcpTransport_EncodeSdreqTlv(&sInfoBuffer,
                                                        &nTlvOffset,
                                                        psTransport->nDiscoveryReqOffset,
                                                        psServiceName);
         if (result != NFCSTATUS_SUCCESS)
         {
            /* Impossible to fit more requests in a single frame,
             * will be continued on next opportunity
             */
            break;
         }

         /* Update request counter */
         psTransport->nDiscoveryReqOffset++;
      }

      /* Update buffer length to match real TLV size */
      sInfoBuffer.length = nTlvOffset;

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

      /* Send SNL frame */
      result =  phFriNfc_Llcp_Send(psTransport->pLlcp,
                                   &psTransport->sLlcpHeader,
                                   NULL,
                                   &sInfoBuffer,
                                   phFriNfc_LlcpTransport_Send_CB,
                                   psTransport);
   }
   else
   {
      /* Impossible to send now, this function will be called again on next opportunity */
   }

   return result;
}

/*!
* \ingroup grp_fri_nfc
* \brief <b>Discover remote services SAP using SDP protocol</b>.
 */
NFCSTATUS phFriNfc_LlcpTransport_DiscoverServices( phFriNfc_LlcpTransport_t  *pLlcpTransport,
                                                   phNfc_sData_t             *psServiceNameList,
                                                   uint8_t                   *pnSapList,
                                                   uint8_t                   nListSize,
                                                   pphFriNfc_Cr_t            pDiscover_Cb,
                                                   void                      *pContext )
{
   NFCSTATUS         result = NFCSTATUS_FAILED;

   /* Save request details */
   pLlcpTransport->psDiscoveryServiceNameList = psServiceNameList;
   pLlcpTransport->pnDiscoverySapList = pnSapList;
   pLlcpTransport->nDiscoveryListSize = nListSize;
   pLlcpTransport->pfDiscover_Cb = pDiscover_Cb;
   pLlcpTransport->pDiscoverContext = pContext;

   /* Reset internal counters */
   pLlcpTransport->nDiscoveryReqOffset = 0;
   pLlcpTransport->nDiscoveryResOffset = 0;

   /* Perform request */
   result = phFriNfc_LlcpTransport_DiscoverServicesEx(pLlcpTransport);

   return result;
}


 /**
* \ingroup grp_fri_nfc
* \brief <b>Create a socket on a LLCP-connected device</b>.
*
* This function creates a socket for a given LLCP link. Sockets can be of two types : 
* connection-oriented and connectionless. If the socket is connection-oriented, the caller
* must provide a working buffer to the socket in order to handle incoming data. This buffer
* must be large enough to fit the receive window (RW * MIU), the remaining space being
* used as a linear buffer to store incoming data as a stream. Data will be readable later
* using the phLibNfc_LlcpTransport_Recv function.
* The options and working buffer are not required if the socket is used as a listening socket,
* since it cannot be directly used for communication.
*
* \param[in]  pLlcpSocketTable      A pointer to a table of PHFRINFC_LLCP_NB_SOCKET_DEFAULT sockets.
* \param[in]  eType                 The socket type.
* \param[in]  psOptions             The options to be used with the socket.
* \param[in]  psWorkingBuffer       A working buffer to be used by the library.
* \param[out] pLlcpSocket           A pointer on the socket to be filled with a
                                    socket found on the socket table.
* \param[in]  pErr_Cb               The callback to be called each time the socket
*                                   is in error.
* \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_INSUFFICIENT_RESOURCES   No more socket handle available.
* \retval NFCSTATUS_FAILED                   Operation failed.  
* */
NFCSTATUS phFriNfc_LlcpTransport_Socket(phFriNfc_LlcpTransport_t                  *pLlcpTransport,
                                        phFriNfc_LlcpTransport_eSocketType_t      eType,
                                        phFriNfc_LlcpTransport_sSocketOptions_t   *psOptions,
                                        phNfc_sData_t                             *psWorkingBuffer,
                                        phFriNfc_LlcpTransport_Socket_t           **pLlcpSocket,
                                        pphFriNfc_LlcpTransportSocketErrCb_t      pErr_Cb,
                                        void                                      *pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   phFriNfc_Llcp_sLinkParameters_t  LlcpLinkParamInfo;
   uint8_t index=0;
   uint8_t cpt;

   /* Check for NULL pointers */
   if (   ((psOptions == NULL) && (eType == phFriNfc_LlcpTransport_eConnectionOriented))
       || ((psWorkingBuffer == NULL) && (eType == phFriNfc_LlcpTransport_eConnectionOriented))
       || (pLlcpSocket == NULL)
       || (pErr_Cb == NULL)
       || (pContext == NULL)
       || (pLlcpTransport == NULL))
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
      return status;
   }
   /*  Test the socket type*/
   else if(eType != phFriNfc_LlcpTransport_eConnectionOriented && eType != phFriNfc_LlcpTransport_eConnectionLess)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
      return status;
   }
   /* Connectionless sockets don't support options */
   else if ((psOptions != NULL) && (eType == phFriNfc_LlcpTransport_eConnectionLess))
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
      return status;
   }

   /* Get the local parameters of the LLCP Link */
   status = phFriNfc_Llcp_GetLocalInfo(pLlcpTransport->pLlcp,&LlcpLinkParamInfo);
   if(status != NFCSTATUS_SUCCESS)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
      return status;
   }
   else
   {
      /* Search a socket free in the Socket Table*/
      do
      {
         if(pLlcpTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault)
         {
            /* Set the socket pointer to socket of the table */
            *pLlcpSocket = &pLlcpTransport->pSocketTable[index];

            /* Store the socket info in the socket pointer */
            pLlcpTransport->pSocketTable[index].eSocket_Type     = eType;
            pLlcpTransport->pSocketTable[index].pSocketErrCb     = pErr_Cb;

            /* Store the context of the upper layer */
            pLlcpTransport->pSocketTable[index].pContext   = pContext;

            /* Set the pointers to the different working buffers */
            if (eType == phFriNfc_LlcpTransport_eConnectionOriented)
            {
                /* Test the socket options */
                if (psOptions->rw > PHFRINFC_LLCP_RW_MAX)
                {
                    status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
                    return status;
                }

                /* Set socket options */
                memcpy(&pLlcpTransport->pSocketTable[index].sSocketOption, psOptions, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));

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

                /* Set the Max length for the Send and Receive Window Buffer */
                pLlcpTransport->pSocketTable[index].bufferSendMaxLength   = pLlcpTransport->pSocketTable[index].sSocketOption.miu;
                pLlcpTransport->pSocketTable[index].bufferRwMaxLength     = pLlcpTransport->pSocketTable[index].sSocketOption.miu * ((pLlcpTransport->pSocketTable[index].sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK));
                pLlcpTransport->pSocketTable[index].bufferLinearLength    = psWorkingBuffer->length - pLlcpTransport->pSocketTable[index].bufferSendMaxLength - pLlcpTransport->pSocketTable[index].bufferRwMaxLength;

                /* Test the connection oriented buffers length */
                if((pLlcpTransport->pSocketTable[index].bufferSendMaxLength + pLlcpTransport->pSocketTable[index].bufferRwMaxLength) > psWorkingBuffer->length  
                    || ((pLlcpTransport->pSocketTable[index].bufferLinearLength < PHFRINFC_LLCP_MIU_DEFAULT) && (pLlcpTransport->pSocketTable[index].bufferLinearLength != 0)))
                {
                    status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_BUFFER_TOO_SMALL);
                    return status;
                }

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

                /* Set the pointer and the length for the Send Buffer */
                pLlcpTransport->pSocketTable[index].sSocketSendBuffer.buffer     = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength;
                pLlcpTransport->pSocketTable[index].sSocketSendBuffer.length     = pLlcpTransport->pSocketTable[index].bufferSendMaxLength;

                /** Set the pointer and the length for the Linear Buffer */
                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer   = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength + pLlcpTransport->pSocketTable[index].bufferSendMaxLength;
                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length   = pLlcpTransport->pSocketTable[index].bufferLinearLength;

                if(pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length != 0)
                {
                    /* Init Cyclic Fifo */
                    phFriNfc_Llcp_CyclicFifoInit(&pLlcpTransport->pSocketTable[index].sCyclicFifoBuffer,
                                                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer,
                                                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length);
                }
            }
            /* Handle connectionless socket with buffering option */
            else if (eType == phFriNfc_LlcpTransport_eConnectionLess)
            {
               /* Determine how many packets can be bufferized in working buffer */
               if (psWorkingBuffer != NULL)
               {
                  /* NOTE: the extra byte is used to store SSAP */
                  pLlcpTransport->pSocketTable[index].localRW = psWorkingBuffer->length / (pLlcpTransport->pLlcp->sLocalParams.miu + 1);
               }
               else
               {
                  pLlcpTransport->pSocketTable[index].localRW = 0;
               }

               if (pLlcpTransport->pSocketTable[index].localRW > PHFRINFC_LLCP_RW_MAX)
               {
                  pLlcpTransport->pSocketTable[index].localRW = PHFRINFC_LLCP_RW_MAX;
               }

               /* Set the pointers and the lengths for buffering */
               for(cpt=0 ; cpt<pLlcpTransport->pSocketTable[index].localRW ; cpt++)
               {
                  pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].buffer = psWorkingBuffer->buffer + (cpt*(pLlcpTransport->pLlcp->sLocalParams.miu + 1));
                  pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].length = 0;
               }

               /* Set other socket internals */
               pLlcpTransport->pSocketTable[index].indexRwRead      = 0;
               pLlcpTransport->pSocketTable[index].indexRwWrite     = 0;
            }

            /* Store index of the socket */
            pLlcpTransport->pSocketTable[index].index = index;

            /* Set the socket into created state */
            pLlcpTransport->pSocketTable[index].eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
            return status;
         }
         else
         {
            index++;
         }
      }while(index<PHFRINFC_LLCP_NB_SOCKET_MAX);
      
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INSUFFICIENT_RESOURCES);
   }
   return status;
}

/**
* \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_Close(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Check for NULL pointers */
   if( pLlcpSocket == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   else if(pLlcpSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = phFriNfc_LlcpTransport_ConnectionOriented_Close(pLlcpSocket);
   }
   else if(pLlcpSocket->eSocket_Type ==  phFriNfc_LlcpTransport_eConnectionLess)
   {
      status = phFriNfc_LlcpTransport_Connectionless_Close(pLlcpSocket);
   }
   else
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }

   return status;
}

/**
* \ingroup grp_fri_nfc
* \brief <b>Bind a socket to a local SAP</b>.
*
* This function binds the socket to a local Service Access Point.
*
* \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  nSap                  The SAP number to bind with, or 0 for auto-bind to a free SAP.
* \param[in]  psServiceName         A pointer to Service Name, or NULL if no service name.
*
* \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_ALREADY_REGISTERED       The selected SAP is already bound to another
                                             socket.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/

NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t    *pLlcpSocket,
                                      uint8_t                            nSap,
                                      phNfc_sData_t                      *psServiceName)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   uint8_t i;
   uint8_t min_sap_range;
   uint8_t max_sap_range;

   /* Check for NULL pointers */
   if(pLlcpSocket == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketCreated)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   else
   {
      /* Calculate authorized SAP range */
      if ((psServiceName != NULL) && (psServiceName->length > 0))
      {
         /* SDP advertised service */
         min_sap_range = PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST;
         max_sap_range = PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST;
      }
      else
      {
         /* Non-SDP advertised service */
         min_sap_range = PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST;
         max_sap_range = PHFRINFC_LLCP_SAP_NUMBER;
      }

      /* Handle dynamic SAP allocation */
      if (nSap == 0)
      {
         status = phFriNfc_LlcpTransport_GetFreeSap(pLlcpSocket->psTransport, psServiceName, &nSap);
         if (status != NFCSTATUS_SUCCESS)
         {
            return status;
         }
      }

      /* Test the SAP range */
      if(!IS_BETWEEN(nSap, min_sap_range, max_sap_range) &&
         !IS_BETWEEN(nSap, PHFRINFC_LLCP_SAP_WKS_FIRST, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST))
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
      }
      else
      {
         /* Test if the nSap it is used by another socket */
         for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
         {
            if(pLlcpSocket->psTransport->pSocketTable[i].socket_sSap == nSap)
            {
               return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_ALREADY_REGISTERED);
            }
         }
         /* Set service name */
         status = phFriNfc_LlcpTransport_RegisterName(pLlcpSocket, nSap, psServiceName);
         if (status != NFCSTATUS_SUCCESS)
         {
            return status;
         }
         /* Set the nSap value of the socket */
         pLlcpSocket->socket_sSap = nSap;
         /* Set the socket state */
         pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
      }
   }
   return status;
}

/*********************************************/
/*           ConnectionOriented              */
/*********************************************/

/**
* \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_Listen(phFriNfc_LlcpTransport_Socket_t*          pLlcpSocket,
                                        pphFriNfc_LlcpTransportSocketListenCb_t   pListen_Cb,
                                        void*                                     pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Check for NULL pointers */
   if(pLlcpSocket == NULL || pListen_Cb == NULL|| pContext == NULL )
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Check for socket state */
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   /* Check for socket type */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if a listen is not pending with this socket */
   else if(pLlcpSocket->bSocketListenPending)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      status = phFriNfc_LlcpTransport_ConnectionOriented_Listen(pLlcpSocket,
                                                                pListen_Cb,
                                                                pContext);
   }
   return status;
}


/**
* \ingroup grp_fri_nfc
* \brief <b>Register the socket service name</b>.
*
* This function changes the service name of the corresponding socket.
*
* \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
* \param[in]  nSap               SAP number associated to the service name.
* \param[in]  psServiceName      A pointer to a Service Name.
*
* \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.
*/
static NFCSTATUS phFriNfc_LlcpTransport_RegisterName(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket,
                                                     uint8_t                            nSap,
                                                     phNfc_sData_t                      *psServiceName)
{
   phFriNfc_LlcpTransport_t *       psTransport = pLlcpSocket->psTransport;
   uint8_t                          index;
   uint8_t                          bSnMatch, bSapMatch;

   /* Check in cache if sap has been used for different service name */
   for(index=0 ; index<PHFRINFC_LLCP_SDP_ADVERTISED_NB ; index++)
   {
      if(psTransport->pCachedServiceNames[index].sServiceName.length == 0)
      {
         /* Reached end of table */
         break;
      }

      bSnMatch = (memcmp(psTransport->pCachedServiceNames[index].sServiceName.buffer, psServiceName->buffer, psServiceName->length) == 0);
      bSapMatch = psTransport->pCachedServiceNames[index].nSap == nSap;
      if(bSnMatch && bSapMatch)
      {
         /* Request match cache */
         break;
      }
      else if((bSnMatch && !bSapMatch) || (!bSnMatch && bSapMatch))
      {
         /* Request mismatch with cache */
         return NFCSTATUS_INVALID_PARAMETER;
      }
   }

   /* Handle service with no name */
   if (psServiceName == NULL)
   {
      if (pLlcpSocket->sServiceName.buffer != NULL)
      {
         phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
      }
      pLlcpSocket->sServiceName.buffer = NULL;
      pLlcpSocket->sServiceName.length = 0;
   }
   else
   {
      /* Check if name already in use */
      for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
      {
         phFriNfc_LlcpTransport_Socket_t* pCurrentSocket = &pLlcpSocket->psTransport->pSocketTable[index];

         if(   (pCurrentSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
            && (pCurrentSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketRegistered))
         {
            /* Only bound or listening sockets may have a service name */
            continue;
         }
         if(pCurrentSocket->sServiceName.length != psServiceName->length) {
            /* Service name do not match, check next */
            continue;
         }
         if(memcmp(pCurrentSocket->sServiceName.buffer, psServiceName->buffer, psServiceName->length) == 0)
         {
            /* Service name already in use */
            return NFCSTATUS_INVALID_PARAMETER;
         }
      }

      /* Store the listen socket SN */
      pLlcpSocket->sServiceName.length = psServiceName->length;
      pLlcpSocket->sServiceName.buffer = phOsalNfc_GetMemory(psServiceName->length);
      if (pLlcpSocket->sServiceName.buffer == NULL)
      {
          return NFCSTATUS_NOT_ENOUGH_MEMORY;
      }
      memcpy(pLlcpSocket->sServiceName.buffer, psServiceName->buffer, psServiceName->length);
   }

   return NFCSTATUS_SUCCESS;
}

/**
* \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]  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_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;

   /* Check for NULL pointers */
   if(pLlcpSocket == NULL || psOptions == NULL || psWorkingBuffer == NULL || pErr_Cb == NULL || pContext == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Check for socket state */
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   /* Check for socket type */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test the socket options */
   else if(psOptions->rw > PHFRINFC_LLCP_RW_MAX)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      /* Set the Max length for the Send and Receive Window Buffer */
      pLlcpSocket->bufferSendMaxLength   = psOptions->miu;
      pLlcpSocket->bufferRwMaxLength     = psOptions->miu * ((psOptions->rw & PHFRINFC_LLCP_TLV_RW_MASK));
      pLlcpSocket->bufferLinearLength    = psWorkingBuffer->length - pLlcpSocket->bufferSendMaxLength - pLlcpSocket->bufferRwMaxLength;

      /* Test the buffers length */
      if((pLlcpSocket->bufferSendMaxLength + pLlcpSocket->bufferRwMaxLength) > psWorkingBuffer->length
          || ((pLlcpSocket->bufferLinearLength < PHFRINFC_LLCP_MIU_DEFAULT)  && (pLlcpSocket->bufferLinearLength != 0)))
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_BUFFER_TOO_SMALL);
      }
      else
      {
         pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;

         status  = phFriNfc_LlcpTransport_ConnectionOriented_Accept(pLlcpSocket,
                                                                    psOptions,
                                                                    psWorkingBuffer,
                                                                    pErr_Cb,
                                                                    pAccept_RspCb,
                                                                    pContext);
      }
   }
   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.
* \param[in]  pReject_RspCb         The callback to be call when the Reject 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_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_Reject( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
                                          pphFriNfc_LlcpTransportSocketRejectCb_t   pReject_RspCb,
                                          void                                      *pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Check for NULL pointers */
   if(pLlcpSocket == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Check for socket state */
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   /* Check for socket type */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      status = phLibNfc_LlcpTransport_ConnectionOriented_Reject(pLlcpSocket,
                                                                pReject_RspCb,
                                                                pContext);
   }

   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]  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_Connect( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
                                          uint8_t                                    nSap,
                                          pphFriNfc_LlcpTransportSocketConnectCb_t   pConnect_RspCb,
                                          void*                                      pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   uint8_t nLocalSap;
   uint8_t i;

   /* Check for NULL pointers */
   if(pLlcpSocket == NULL || pConnect_RspCb == NULL || pContext == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test the port number value */
   else if(nSap<02 || nSap>63)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is a connectionOriented socket */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket has a service name */
   else if(pLlcpSocket->sServiceName.length != 0)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   /* Test if the socket is not in connecting or connected state*/
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketCreated && pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   else 
   {
      /* Implicit bind if socket is not already bound */
      if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
      {
         /* Bind to a free sap */
         status = phFriNfc_LlcpTransport_GetFreeSap(pLlcpSocket->psTransport, NULL, &nLocalSap);
         if (status != NFCSTATUS_SUCCESS)
         {
            return status;
         }
         pLlcpSocket->socket_sSap = nLocalSap;
      }

      /* Test the SAP range for non SDP-advertised services */
      if(!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST, PHFRINFC_LLCP_SAP_NUMBER))
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
      }
      else
      {
         status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket,
                                                                    nSap,
                                                                    NULL,
                                                                    pConnect_RspCb,
                                                                    pContext);
      }
   }
   
   return status;
}

/**
* \ingroup grp_fri_nfc
* \brief <b>Try to establish connection with a socket on a remote service, given its URI</b>.
*
* This function tries to connect to a SAP designated by an URI. 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]  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_NOT_INITIALISED          Indicates stack is not yet initialized.
* \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_ConnectByUri(phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
                                              phNfc_sData_t*                             psUri,
                                              pphFriNfc_LlcpTransportSocketConnectCb_t   pConnect_RspCb,
                                              void*                                      pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   uint8_t i;
   uint8_t nLocalSap;

   /* Check for NULL pointers */
   if(pLlcpSocket == NULL || pConnect_RspCb == NULL || pContext == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is a connectionOriented socket */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is not in connect pending or connected state*/
   else if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnecting || pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test the length of the SN */
   else if(psUri->length > PHFRINFC_LLCP_SN_MAX_LENGTH)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   else 
   {
      /* Implicit bind if socket is not already bound */
      if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
      {
         /* Bind to a free sap */
         status = phFriNfc_LlcpTransport_GetFreeSap(pLlcpSocket->psTransport, NULL, &nLocalSap);
         if (status != NFCSTATUS_SUCCESS)
         {
            return status;
         }
         pLlcpSocket->socket_sSap = nLocalSap;
      }

      /* Test the SAP range for non SDP-advertised services */
      if(!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST, PHFRINFC_LLCP_SAP_NUMBER))
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
      }
      else
      {
         status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket,
                                                                    PHFRINFC_LLCP_SAP_DEFAULT,
                                                                    psUri,
                                                                    pConnect_RspCb,
                                                                    pContext);
      }
   }

   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 phFriNfc_LlcpTransport_Disconnect(phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
                                            pphLibNfc_LlcpSocketDisconnectCb_t         pDisconnect_RspCb,
                                            void*                                      pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Check for NULL pointers */
   if(pLlcpSocket == NULL || pDisconnect_RspCb == NULL || pContext == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is a connectionOriented socket */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is connected  state*/
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
   {
       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   else
   {
      status = phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(pLlcpSocket,
                                                                    pDisconnect_RspCb,
                                                                    pContext);
   }

   return status;
}

/**
* \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_Send(phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
                                      phNfc_sData_t*                               psBuffer,
                                      pphFriNfc_LlcpTransportSocketSendCb_t        pSend_RspCb,
                                      void*                                        pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Check for NULL pointers */
   if(pLlcpSocket == NULL || psBuffer == NULL || pSend_RspCb == NULL || pContext == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is a connectionOriented socket */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is in connected state */
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   /* Test the length of the buffer */
   else if(psBuffer->length > pLlcpSocket->remoteMIU )
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if a send is pending */
   else if(pLlcpSocket->pfSocketSend_Cb != NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
   }
   else
   {
      status = phFriNfc_LlcpTransport_ConnectionOriented_Send(pLlcpSocket,
                                                              psBuffer,
                                                              pSend_RspCb,
                                                              pContext);
   }

   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_Recv( phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
                                       phNfc_sData_t*                               psBuffer,
                                       pphFriNfc_LlcpTransportSocketRecvCb_t        pRecv_RspCb,
                                       void*                                        pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;

   /* Check for NULL pointers */
   if(pLlcpSocket == NULL || psBuffer == NULL || pRecv_RspCb == NULL || pContext == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is a connectionOriented socket */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is in connected state */
   else if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if a receive is pending */
   else if(pLlcpSocket->bSocketRecvPending == TRUE)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
   }
   else
   {
      status = phFriNfc_LlcpTransport_ConnectionOriented_Recv(pLlcpSocket,
                                                              psBuffer,
                                                              pRecv_RspCb,
                                                              pContext);
   }

   return status;
}

/*****************************************/
/*           ConnectionLess              */
/*****************************************/

/**
* \ingroup grp_fri_nfc
* \brief <b>Send data on a socket to a given destination SAP</b>.
*
* This function is used to write data on a socket to a given destination SAP.
* This function can only be called on a connectionless socket.
* 
*
* \param[in]  pLlcpSocket        A pointer to a LlcpSocket created.
* \param[in]  nSap               The destination SAP.
* \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_SendTo( phFriNfc_LlcpTransport_Socket_t             *pLlcpSocket,
                                         uint8_t                                     nSap,
                                         phNfc_sData_t                               *psBuffer,
                                         pphFriNfc_LlcpTransportSocketSendCb_t       pSend_RspCb,
                                         void*                                       pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   phFriNfc_Llcp_sLinkParameters_t  LlcpRemoteLinkParamInfo;

   if(pLlcpSocket == NULL || psBuffer == NULL || pSend_RspCb == NULL || pContext == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test the port number value */
   else if(nSap<2 || nSap>63)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is a connectionless socket */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionLess)
   {
       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is in an updated state */
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   /* Test if a send is pending */
   else if(pLlcpSocket->pfSocketSend_Cb != NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
   }
   else
   {
      /* Get the local parameters of the LLCP Link */
      status = phFriNfc_Llcp_GetRemoteInfo(pLlcpSocket->psTransport->pLlcp,&LlcpRemoteLinkParamInfo);
      if(status != NFCSTATUS_SUCCESS)
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
      }
      /* Test the length of the socket buffer for ConnectionLess mode*/
      else if(psBuffer->length > LlcpRemoteLinkParamInfo.miu)
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
      }
      /* Test if the link is in error state */
      else if(pLlcpSocket->psTransport->LinkStatusError)
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
      }
      else
      {
         status = phFriNfc_LlcpTransport_Connectionless_SendTo(pLlcpSocket,
                                                               nSap,
                                                               psBuffer,
                                                               pSend_RspCb,
                                                               pContext);
      }
   }

   return status;
}


 /**
* \ingroup grp_lib_nfc
* \brief <b>Read data on a socket and get the source SAP</b>.
*
* This function is the same as phLibNfc_Llcp_Recv, except that the callback includes
* the source SAP. This functions can only be called on a connectionless socket.
* 
*
* \param[in]  pLlcpSocket        A pointer to a LlcpSocket created.
* \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_NOT_INITIALISED          Indicates stack is not yet initialized.
* \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
* \retval NFCSTATUS_FAILED                   Operation failed.
*/
NFCSTATUS phFriNfc_LlcpTransport_RecvFrom( phFriNfc_LlcpTransport_Socket_t                   *pLlcpSocket,
                                           phNfc_sData_t*                                    psBuffer,
                                           pphFriNfc_LlcpTransportSocketRecvFromCb_t         pRecv_Cb,
                                           void*                                             pContext)
{
   NFCSTATUS status = NFCSTATUS_SUCCESS;
   if(pLlcpSocket == NULL || psBuffer == NULL || pRecv_Cb == NULL || pContext == NULL)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is a connectionless socket */
   else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionLess)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   }
   /* Test if the socket is in an updated state */
   else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
   {
      status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   }
   else
   {
      if(pLlcpSocket->bSocketRecvPending)
      {
         status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
      }
      else
      {
         status = phLibNfc_LlcpTransport_Connectionless_RecvFrom(pLlcpSocket,
                                                                 psBuffer,
                                                                 pRecv_Cb,
                                                                 pContext);
      }
   }

   return status;
}
