Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2010 NXP Semiconductors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /**
     18  * \file  phFriNfc_LlcpTransport.c
     19  * \brief
     20  *
     21  * Project: NFC-FRI
     22  *
     23  */
     24 
     25 /*include files*/
     26 #include <phOsalNfc.h>
     27 #include <phLibNfcStatus.h>
     28 #include <phLibNfc.h>
     29 #include <phNfcLlcpTypes.h>
     30 #include <phFriNfc_Llcp.h>
     31 #include <phFriNfc_LlcpTransport.h>
     32 #include <phFriNfc_LlcpTransport_Connectionless.h>
     33 #include <phFriNfc_LlcpTransport_Connection.h>
     34 
     35 
     36 /* TODO: comment function Transport recv CB */
     37 static void phFriNfc_LlcpTransport__Recv_CB(void            *pContext,
     38                                             phNfc_sData_t   *psData,
     39                                             NFCSTATUS        status)
     40 {
     41    phFriNfc_Llcp_sPacketHeader_t   sLlcpLocalHeader;
     42    uint8_t   dsap;
     43    uint8_t   ptype;
     44    uint8_t   ssap;
     45 
     46    phFriNfc_LlcpTransport_t* pLlcpTransport = (phFriNfc_LlcpTransport_t*)pContext;
     47 
     48    if(status != NFCSTATUS_SUCCESS)
     49    {
     50       pLlcpTransport->LinkStatusError = TRUE;
     51    }
     52    else
     53    {
     54       phFriNfc_Llcp_Buffer2Header( psData->buffer,0x00, &sLlcpLocalHeader);
     55 
     56       dsap  = (uint8_t)sLlcpLocalHeader.dsap;
     57       ptype = (uint8_t)sLlcpLocalHeader.ptype;
     58       ssap  = (uint8_t)sLlcpLocalHeader.ssap;
     59 
     60       /* Update the length value (without the header length) */
     61       psData->length = psData->length - PHFRINFC_LLCP_PACKET_HEADER_SIZE;
     62 
     63       /* Update the buffer pointer */
     64       psData->buffer = psData->buffer + PHFRINFC_LLCP_PACKET_HEADER_SIZE;
     65 
     66       switch(ptype)
     67       {
     68       /* Connectionless */
     69       case PHFRINFC_LLCP_PTYPE_UI:
     70          {
     71             Handle_Connectionless_IncommingFrame(pLlcpTransport,
     72                                                  psData,
     73                                                  dsap,
     74                                                  ssap);
     75          }break;
     76 
     77       /* Connection oriented */
     78       /* NOTE: forward reserved PTYPE to enable FRMR sending */
     79       case PHFRINFC_LLCP_PTYPE_CONNECT:
     80       case PHFRINFC_LLCP_PTYPE_CC:
     81       case PHFRINFC_LLCP_PTYPE_DISC:
     82       case PHFRINFC_LLCP_PTYPE_DM:
     83       case PHFRINFC_LLCP_PTYPE_I:
     84       case PHFRINFC_LLCP_PTYPE_RR:
     85       case PHFRINFC_LLCP_PTYPE_RNR:
     86       case PHFRINFC_LLCP_PTYPE_FRMR:
     87       case PHFRINFC_LLCP_PTYPE_RESERVED1:
     88       case PHFRINFC_LLCP_PTYPE_RESERVED2:
     89       case PHFRINFC_LLCP_PTYPE_RESERVED3:
     90       case PHFRINFC_LLCP_PTYPE_RESERVED4:
     91          {
     92             Handle_ConnectionOriented_IncommingFrame(pLlcpTransport,
     93                                                      psData,
     94                                                      dsap,
     95                                                      ptype,
     96                                                      ssap);
     97          }break;
     98       default:
     99          {
    100 
    101          }break;
    102       }
    103 
    104       /*Restart the Receive Loop */
    105       status  = phFriNfc_Llcp_Recv(pLlcpTransport->pLlcp,
    106                                    phFriNfc_LlcpTransport__Recv_CB,
    107                                    pLlcpTransport);
    108    }
    109 }
    110 
    111 
    112 /* TODO: comment function Transport reset */
    113 NFCSTATUS phFriNfc_LlcpTransport_Reset (phFriNfc_LlcpTransport_t      *pLlcpTransport,
    114                                         phFriNfc_Llcp_t               *pLlcp)
    115 {
    116    NFCSTATUS status = NFCSTATUS_SUCCESS;
    117    uint8_t i;
    118 
    119    /* Check for NULL pointers */
    120    if(pLlcpTransport == NULL || pLlcp == NULL)
    121    {
    122       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    123    }
    124    else
    125    {
    126       /* Reset Transport structure */
    127       pLlcpTransport->pLlcp            = pLlcp;
    128       pLlcpTransport->LinkStatusError  = FALSE;
    129       pLlcpTransport->bSendPending     = FALSE;
    130       pLlcpTransport->bRecvPending     = FALSE;
    131       pLlcpTransport->bDmPending       = FALSE;
    132       pLlcpTransport->bFrmrPending     = FALSE;
    133       pLlcpTransport->socketIndex      = FALSE;
    134       pLlcpTransport->LinkStatusError  = 0;
    135 
    136 
    137       /* Reset all the socket info in the table */
    138       for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
    139       {
    140          pLlcpTransport->pSocketTable[i].eSocket_State                  = phFriNfc_LlcpTransportSocket_eSocketDefault;
    141          pLlcpTransport->pSocketTable[i].eSocket_Type                   = phFriNfc_LlcpTransport_eDefaultType;
    142          pLlcpTransport->pSocketTable[i].index                          = i;
    143          pLlcpTransport->pSocketTable[i].pContext                       = NULL;
    144          pLlcpTransport->pSocketTable[i].pListenContext                 = NULL;
    145          pLlcpTransport->pSocketTable[i].pAcceptContext                 = NULL;
    146          pLlcpTransport->pSocketTable[i].pRejectContext                 = NULL;
    147          pLlcpTransport->pSocketTable[i].pConnectContext                = NULL;
    148          pLlcpTransport->pSocketTable[i].pDisonnectContext              = NULL;
    149          pLlcpTransport->pSocketTable[i].pSendContext                   = NULL;
    150          pLlcpTransport->pSocketTable[i].pRecvContext                   = NULL;
    151          pLlcpTransport->pSocketTable[i].pSocketErrCb                   = NULL;
    152          pLlcpTransport->pSocketTable[i].bufferLinearLength             = 0;
    153          pLlcpTransport->pSocketTable[i].bufferSendMaxLength            = 0;
    154          pLlcpTransport->pSocketTable[i].bufferRwMaxLength              = 0;
    155          pLlcpTransport->pSocketTable[i].ReceiverBusyCondition          = FALSE;
    156          pLlcpTransport->pSocketTable[i].RemoteBusyConditionInfo        = FALSE;
    157          pLlcpTransport->pSocketTable[i].socket_sSap                    = PHFRINFC_LLCP_SAP_DEFAULT;
    158          pLlcpTransport->pSocketTable[i].socket_dSap                    = PHFRINFC_LLCP_SAP_DEFAULT;
    159          pLlcpTransport->pSocketTable[i].bSocketRecvPending             = FALSE;
    160          pLlcpTransport->pSocketTable[i].bSocketSendPending             = FALSE;
    161          pLlcpTransport->pSocketTable[i].bSocketListenPending           = FALSE;
    162          pLlcpTransport->pSocketTable[i].bSocketDiscPending             = FALSE;
    163          pLlcpTransport->pSocketTable[i].bSocketConnectPending          = FALSE;
    164          pLlcpTransport->pSocketTable[i].bSocketAcceptPending           = FALSE;
    165          pLlcpTransport->pSocketTable[i].bSocketRRPending               = FALSE;
    166          pLlcpTransport->pSocketTable[i].bSocketRNRPending              = FALSE;
    167          pLlcpTransport->pSocketTable[i].psTransport                    = pLlcpTransport;
    168          pLlcpTransport->pSocketTable[i].pfSocketSend_Cb                = NULL;
    169          pLlcpTransport->pSocketTable[i].pfSocketRecv_Cb                = NULL;
    170          pLlcpTransport->pSocketTable[i].pfSocketRecvFrom_Cb            = NULL;
    171          pLlcpTransport->pSocketTable[i].pfSocketListen_Cb              = NULL;
    172          pLlcpTransport->pSocketTable[i].pfSocketConnect_Cb             = NULL;
    173          pLlcpTransport->pSocketTable[i].pfSocketDisconnect_Cb          = NULL;
    174          pLlcpTransport->pSocketTable[i].socket_VS                      = 0;
    175          pLlcpTransport->pSocketTable[i].socket_VSA                     = 0;
    176          pLlcpTransport->pSocketTable[i].socket_VR                      = 0;
    177          pLlcpTransport->pSocketTable[i].socket_VRA                     = 0;
    178          pLlcpTransport->pSocketTable[i].remoteRW                       = 0;
    179          pLlcpTransport->pSocketTable[i].localRW                        = 0;
    180          pLlcpTransport->pSocketTable[i].remoteMIU                      = 0;
    181          pLlcpTransport->pSocketTable[i].localMIUX                      = 0;
    182          pLlcpTransport->pSocketTable[i].index                          = 0;
    183          pLlcpTransport->pSocketTable[i].indexRwRead                    = 0;
    184          pLlcpTransport->pSocketTable[i].indexRwWrite                   = 0;
    185 
    186          memset(&pLlcpTransport->pSocketTable[i].sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
    187 
    188          if (pLlcpTransport->pSocketTable[i].sServiceName.buffer != NULL) {
    189             phOsalNfc_FreeMemory(pLlcpTransport->pSocketTable[i].sServiceName.buffer);
    190          }
    191          pLlcpTransport->pSocketTable[i].sServiceName.buffer = NULL;
    192          pLlcpTransport->pSocketTable[i].sServiceName.length = 0;
    193       }
    194 
    195       /* Start The Receive Loop */
    196       status  = phFriNfc_Llcp_Recv(pLlcpTransport->pLlcp,
    197                                    phFriNfc_LlcpTransport__Recv_CB,
    198                                    pLlcpTransport);
    199    }
    200    return status;
    201 }
    202 
    203 /**
    204 * \ingroup grp_lib_nfc
    205 * \brief <b>Get the local options of a socket</b>.
    206 *
    207 * This function returns the local options (maximum packet size and receive window size) used
    208 * for a given connection-oriented socket. This function shall not be used with connectionless
    209 * sockets.
    210 *
    211 * \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
    212 * \param[in]  psLocalOptions        A pointer to be filled with the local options of the socket.
    213 *
    214 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    215 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    216 *                                            could not be properly interpreted.
    217 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
    218 *                                            a valid type to perform the requsted operation.
    219 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
    220 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
    221 * \retval NFCSTATUS_FAILED                   Operation failed.
    222 */
    223 NFCSTATUS phFriNfc_LlcpTransport_SocketGetLocalOptions(phFriNfc_LlcpTransport_Socket_t  *pLlcpSocket,
    224                                                        phLibNfc_Llcp_sSocketOptions_t   *psLocalOptions)
    225 {
    226    NFCSTATUS status = NFCSTATUS_SUCCESS;
    227 
    228    /* Check for NULL pointers */
    229    if (pLlcpSocket == NULL || psLocalOptions == NULL)
    230    {
    231       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    232    }
    233    /*  Test the socket type */
    234    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
    235    {
    236       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    237    }
    238    /*  Test the socket state */
    239    else if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault)
    240    {
    241       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
    242    }
    243    else
    244    {
    245      status = phFriNfc_LlcpTransport_ConnectionOriented_SocketGetLocalOptions(pLlcpSocket,
    246                                                                               psLocalOptions);
    247    }
    248 
    249    return status;
    250 }
    251 
    252 
    253 /**
    254 * \ingroup grp_lib_nfc
    255 * \brief <b>Get the local options of a socket</b>.
    256 *
    257 * This function returns the remote options (maximum packet size and receive window size) used
    258 * for a given connection-oriented socket. This function shall not be used with connectionless
    259 * sockets.
    260 *
    261 * \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
    262 * \param[in]  psRemoteOptions       A pointer to be filled with the remote options of the socket.
    263 *
    264 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    265 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    266 *                                            could not be properly interpreted.
    267 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
    268 *                                            a valid type to perform the requsted operation.
    269 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
    270 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
    271 * \retval NFCSTATUS_FAILED                   Operation failed.
    272 */
    273 NFCSTATUS phFriNfc_LlcpTransport_SocketGetRemoteOptions(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket,
    274                                                         phLibNfc_Llcp_sSocketOptions_t*    psRemoteOptions)
    275 {
    276    NFCSTATUS status = NFCSTATUS_SUCCESS;
    277 
    278    /* Check for NULL pointers */
    279    if (pLlcpSocket == NULL || psRemoteOptions == NULL)
    280    {
    281       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    282    }
    283    /*  Test the socket type */
    284    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
    285    {
    286       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    287    }
    288    /*  Test the socket state */
    289    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
    290    {
    291       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
    292    }
    293    else
    294    {
    295       status = phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(pLlcpSocket,
    296                                                                                 psRemoteOptions);
    297    }
    298 
    299    return status;
    300 }
    301 
    302  /**
    303 * \ingroup grp_fri_nfc
    304 * \brief <b>Create a socket on a LLCP-connected device</b>.
    305 *
    306 * This function creates a socket for a given LLCP link. Sockets can be of two types :
    307 * connection-oriented and connectionless. If the socket is connection-oriented, the caller
    308 * must provide a working buffer to the socket in order to handle incoming data. This buffer
    309 * must be large enough to fit the receive window (RW * MIU), the remaining space being
    310 * used as a linear buffer to store incoming data as a stream. Data will be readable later
    311 * using the phLibNfc_LlcpTransport_Recv function.
    312 * The options and working buffer are not required if the socket is used as a listening socket,
    313 * since it cannot be directly used for communication.
    314 *
    315 * \param[in]  pLlcpSocketTable      A pointer to a table of PHFRINFC_LLCP_NB_SOCKET_DEFAULT sockets.
    316 * \param[in]  eType                 The socket type.
    317 * \param[in]  psOptions             The options to be used with the socket.
    318 * \param[in]  psWorkingBuffer       A working buffer to be used by the library.
    319 * \param[out] pLlcpSocket           A pointer on the socket to be filled with a
    320                                     socket found on the socket table.
    321 * \param[in]  pErr_Cb               The callback to be called each time the socket
    322 *                                   is in error.
    323 * \param[in]  pContext              Upper layer context to be returned in the callback.
    324 *
    325 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    326 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    327 *                                            could not be properly interpreted.
    328 * \retval NFCSTATUS_BUFFER_TOO_SMALL         The working buffer is too small for the MIU and RW
    329 *                                            declared in the options.
    330 * \retval NFCSTATUS_INSUFFICIENT_RESOURCES   No more socket handle available.
    331 * \retval NFCSTATUS_FAILED                   Operation failed.
    332 * */
    333 NFCSTATUS phFriNfc_LlcpTransport_Socket(phFriNfc_LlcpTransport_t                  *pLlcpTransport,
    334                                         phFriNfc_LlcpTransport_eSocketType_t      eType,
    335                                         phFriNfc_LlcpTransport_sSocketOptions_t   *psOptions,
    336                                         phNfc_sData_t                             *psWorkingBuffer,
    337                                         phFriNfc_LlcpTransport_Socket_t           **pLlcpSocket,
    338                                         pphFriNfc_LlcpTransportSocketErrCb_t      pErr_Cb,
    339                                         void                                      *pContext)
    340 {
    341    NFCSTATUS status = NFCSTATUS_SUCCESS;
    342    phFriNfc_Llcp_sLinkParameters_t  LlcpLinkParamInfo;
    343    uint8_t index=0;
    344    uint8_t cpt;
    345 
    346    /* Check for NULL pointers */
    347    if (((NULL == psOptions) && (eType != phFriNfc_LlcpTransport_eConnectionLess)) || ((psWorkingBuffer == NULL) && (eType != phFriNfc_LlcpTransport_eConnectionLess)) || pLlcpSocket == NULL || pErr_Cb == NULL || pContext == NULL || pLlcpTransport == NULL)
    348    {
    349       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    350       return status;
    351    }
    352    /*  Test the socket type*/
    353    else if(eType != phFriNfc_LlcpTransport_eConnectionOriented && eType != phFriNfc_LlcpTransport_eConnectionLess)
    354    {
    355       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    356       return status;
    357    }
    358 
    359    /* Get the local parameters of the LLCP Link */
    360    status = phFriNfc_Llcp_GetLocalInfo(pLlcpTransport->pLlcp,&LlcpLinkParamInfo);
    361    if(status != NFCSTATUS_SUCCESS)
    362    {
    363       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
    364    }
    365    else
    366    {
    367       /* Search a socket free in the Socket Table*/
    368       do
    369       {
    370          if(pLlcpTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault)
    371          {
    372             /* Set the socket pointer to socket of the table */
    373             *pLlcpSocket = &pLlcpTransport->pSocketTable[index];
    374 
    375             /* Store the socket info in the socket pointer */
    376             pLlcpTransport->pSocketTable[index].eSocket_Type     = eType;
    377             pLlcpTransport->pSocketTable[index].pSocketErrCb     = pErr_Cb;
    378 
    379             /* Store the context of the upper layer */
    380             pLlcpTransport->pSocketTable[index].pContext   = pContext;
    381 
    382             /* Set the pointers to the different working buffers */
    383             if(pLlcpTransport->pSocketTable[index].eSocket_Type != phFriNfc_LlcpTransport_eConnectionLess)
    384             {
    385                /* Test the socket options */
    386                if((psOptions->rw > PHFRINFC_LLCP_RW_MAX) && (eType == phFriNfc_LlcpTransport_eConnectionOriented))
    387                {
    388                   status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    389                }
    390                /* Set socket options */
    391                memcpy(&pLlcpTransport->pSocketTable[index].sSocketOption, psOptions, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
    392 
    393                /* Set socket local params (MIUX & RW) */
    394                pLlcpTransport->pSocketTable[index].localMIUX = (pLlcpTransport->pSocketTable[index].sSocketOption.miu - PHFRINFC_LLCP_MIU_DEFAULT) & PHFRINFC_LLCP_TLV_MIUX_MASK;
    395                pLlcpTransport->pSocketTable[index].localRW   = pLlcpTransport->pSocketTable[index].sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK;
    396 
    397                /* Set the Max length for the Send and Receive Window Buffer */
    398                pLlcpTransport->pSocketTable[index].bufferSendMaxLength   = pLlcpTransport->pSocketTable[index].sSocketOption.miu;
    399                pLlcpTransport->pSocketTable[index].bufferRwMaxLength     = pLlcpTransport->pSocketTable[index].sSocketOption.miu * ((pLlcpTransport->pSocketTable[index].sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK));
    400                pLlcpTransport->pSocketTable[index].bufferLinearLength    = psWorkingBuffer->length - pLlcpTransport->pSocketTable[index].bufferSendMaxLength - pLlcpTransport->pSocketTable[index].bufferRwMaxLength;
    401 
    402                /* Test the connection oriented buffers length */
    403                if((pLlcpTransport->pSocketTable[index].bufferSendMaxLength + pLlcpTransport->pSocketTable[index].bufferRwMaxLength) > psWorkingBuffer->length
    404                    || ((pLlcpTransport->pSocketTable[index].bufferLinearLength < PHFRINFC_LLCP_MIU_DEFAULT) && (pLlcpTransport->pSocketTable[index].bufferLinearLength != 0)))
    405                {
    406                   status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_BUFFER_TOO_SMALL);
    407                   return status;
    408                }
    409 
    410                /* Set the pointer and the length for the Receive Window Buffer */
    411                for(cpt=0;cpt<pLlcpTransport->pSocketTable[index].localRW;cpt++)
    412                {
    413                   pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].buffer = psWorkingBuffer->buffer + (cpt*pLlcpTransport->pSocketTable[index].sSocketOption.miu);
    414                   pLlcpTransport->pSocketTable[index].sSocketRwBufferTable[cpt].length = 0;
    415                }
    416 
    417                /* Set the pointer and the length for the Send Buffer */
    418                pLlcpTransport->pSocketTable[index].sSocketSendBuffer.buffer     = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength;
    419                pLlcpTransport->pSocketTable[index].sSocketSendBuffer.length     = pLlcpTransport->pSocketTable[index].bufferSendMaxLength;
    420 
    421                /** Set the pointer and the length for the Linear Buffer */
    422                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer   = psWorkingBuffer->buffer + pLlcpTransport->pSocketTable[index].bufferRwMaxLength + pLlcpTransport->pSocketTable[index].bufferSendMaxLength;
    423                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length   = pLlcpTransport->pSocketTable[index].bufferLinearLength;
    424 
    425                if(pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length != 0)
    426                {
    427                   /* Init Cyclic Fifo */
    428                   phFriNfc_Llcp_CyclicFifoInit(&pLlcpTransport->pSocketTable[index].sCyclicFifoBuffer,
    429                                                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.buffer,
    430                                                pLlcpTransport->pSocketTable[index].sSocketLinearBuffer.length);
    431                }
    432             }
    433             /* Store index of the socket */
    434             pLlcpTransport->pSocketTable[index].index = index;
    435 
    436             /* Set the socket into created state */
    437             pLlcpTransport->pSocketTable[index].eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
    438             return status;
    439          }
    440          else
    441          {
    442             index++;
    443          }
    444       }while(index<PHFRINFC_LLCP_NB_SOCKET_MAX);
    445 
    446       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INSUFFICIENT_RESOURCES);
    447    }
    448    return status;
    449 }
    450 
    451 /**
    452 * \ingroup grp_fri_nfc
    453 * \brief <b>Close a socket on a LLCP-connected device</b>.
    454 *
    455 * This function closes a LLCP socket previously created using phFriNfc_LlcpTransport_Socket.
    456 * If the socket was connected, it is first disconnected, and then closed.
    457 *
    458 * \param[in]  pLlcpSocket                    A pointer to a phFriNfc_LlcpTransport_Socket_t.
    459 
    460 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    461 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    462 *                                            could not be properly interpreted.
    463 * \retval NFCSTATUS_FAILED                   Operation failed.
    464 */
    465 NFCSTATUS phFriNfc_LlcpTransport_Close(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket)
    466 {
    467    NFCSTATUS status = NFCSTATUS_SUCCESS;
    468 
    469    /* Check for NULL pointers */
    470    if( pLlcpSocket == NULL)
    471    {
    472       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    473    }
    474    else if(pLlcpSocket->eSocket_Type == phFriNfc_LlcpTransport_eConnectionOriented)
    475    {
    476       status = phFriNfc_LlcpTransport_ConnectionOriented_Close(pLlcpSocket);
    477    }
    478    else if(pLlcpSocket->eSocket_Type ==  phFriNfc_LlcpTransport_eConnectionLess)
    479    {
    480       status = phFriNfc_LlcpTransport_Connectionless_Close(pLlcpSocket);
    481    }
    482    else
    483    {
    484       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    485    }
    486 
    487    return status;
    488 }
    489 
    490 /**
    491 * \ingroup grp_fri_nfc
    492 * \brief <b>Bind a socket to a local SAP</b>.
    493 *
    494 * This function binds the socket to a local Service Access Point.
    495 *
    496 * \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
    497 * \param[in]  pConfigInfo           A port number for a specific socket
    498 *
    499 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    500 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    501 *                                            could not be properly interpreted.
    502 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
    503 *                                            a valid type to perform the requsted operation.
    504 * \retval NFCSTATUS_ALREADY_REGISTERED       The selected SAP is already bound to another
    505                                              socket.
    506 * \retval NFCSTATUS_FAILED                   Operation failed.
    507 */
    508 
    509 NFCSTATUS phFriNfc_LlcpTransport_Bind(phFriNfc_LlcpTransport_Socket_t    *pLlcpSocket,
    510                                       uint8_t                            nSap)
    511 {
    512    NFCSTATUS status = NFCSTATUS_SUCCESS;
    513    uint8_t i;
    514 
    515    /* Check for NULL pointers */
    516    if(pLlcpSocket == NULL)
    517    {
    518       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    519    }
    520    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketCreated)
    521    {
    522       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
    523    }
    524    else if(nSap<2 || nSap>63)
    525    {
    526       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    527    }
    528    else
    529    {
    530       /* Test if the nSap it is useb by another socket */
    531       for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
    532       {
    533          if((pLlcpSocket->psTransport->pSocketTable[i].socket_sSap == nSap)
    534             && (pLlcpSocket->psTransport->pSocketTable[i].eSocket_Type == pLlcpSocket->eSocket_Type))
    535          {
    536             return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_ALREADY_REGISTERED);
    537          }
    538       }
    539       /* Set the nSap value of the socket */
    540       pLlcpSocket->socket_sSap = nSap;
    541       /* Set the socket state */
    542       pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
    543    }
    544    return status;
    545 }
    546 
    547 /*********************************************/
    548 /*           ConnectionOriented              */
    549 /*********************************************/
    550 
    551 /**
    552 * \ingroup grp_fri_nfc
    553 * \brief <b>Listen for incoming connection requests on a socket</b>.
    554 *
    555 * This function switches a socket into a listening state and registers a callback on
    556 * incoming connection requests. In this state, the socket is not able to communicate
    557 * directly. The listening state is only available for connection-oriented sockets
    558 * which are still not connected. The socket keeps listening until it is closed, and
    559 * thus can trigger several times the pListen_Cb callback.
    560 *
    561 *
    562 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
    563 * \param[in]  psServiceName      A pointer to Service Name
    564 * \param[in]  pListen_Cb         The callback to be called each time the
    565 *                                socket receive a connection request.
    566 * \param[in]  pContext           Upper layer context to be returned in
    567 *                                the callback.
    568 *
    569 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    570 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    571 *                                            could not be properly interpreted.
    572 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state to switch
    573 *                                            to listening state.
    574 * \retval NFCSTATUS_FAILED                   Operation failed.
    575 */
    576 NFCSTATUS phFriNfc_LlcpTransport_Listen(phFriNfc_LlcpTransport_Socket_t*          pLlcpSocket,
    577                                         phNfc_sData_t                             *psServiceName,
    578                                         pphFriNfc_LlcpTransportSocketListenCb_t   pListen_Cb,
    579                                         void*                                     pContext)
    580 {
    581    NFCSTATUS status = NFCSTATUS_SUCCESS;
    582 
    583    /* Check for NULL pointers */
    584    if(pLlcpSocket == NULL || pListen_Cb == NULL|| pContext == NULL || psServiceName == NULL)
    585    {
    586       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    587    }
    588    /* Check for socket state */
    589    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
    590    {
    591       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
    592    }
    593    /* Check for socket type */
    594    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
    595    {
    596       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    597    }
    598    /* Test if a listen is not pending with this socket */
    599    else if(pLlcpSocket->bSocketListenPending)
    600    {
    601       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    602    }
    603    /* Test the length of the SN */
    604    else if(psServiceName->length > PHFRINFC_LLCP_SN_MAX_LENGTH)
    605    {
    606          return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    607    }
    608    else
    609    {
    610       status = phFriNfc_LlcpTransport_ConnectionOriented_Listen(pLlcpSocket,
    611                                                                 psServiceName,
    612                                                                 pListen_Cb,
    613                                                                 pContext);
    614    }
    615    return status;
    616 }
    617 
    618 /**
    619 * \ingroup grp_fri_nfc
    620 * \brief <b>Accept an incoming connection request for a socket</b>.
    621 *
    622 * This functions allows the client to accept an incoming connection request.
    623 * It must be used with the socket provided within the listen callback. The socket
    624 * is implicitly switched to the connected state when the function is called.
    625 *
    626 * \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
    627 * \param[in]  psOptions             The options to be used with the socket.
    628 * \param[in]  psWorkingBuffer       A working buffer to be used by the library.
    629 * \param[in]  pErr_Cb               The callback to be called each time the accepted socket
    630 *                                   is in error.
    631 * \param[in]  pContext              Upper layer context to be returned in the callback.
    632 *
    633 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    634 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    635 *                                            could not be properly interpreted.
    636 * \retval NFCSTATUS_BUFFER_TOO_SMALL         The working buffer is too small for the MIU and RW
    637 *                                            declared in the options.
    638 * \retval NFCSTATUS_FAILED                   Operation failed.
    639 */
    640 NFCSTATUS phFriNfc_LlcpTransport_Accept(phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
    641                                         phFriNfc_LlcpTransport_sSocketOptions_t*     psOptions,
    642                                         phNfc_sData_t*                               psWorkingBuffer,
    643                                         pphFriNfc_LlcpTransportSocketErrCb_t         pErr_Cb,
    644                                         pphFriNfc_LlcpTransportSocketAcceptCb_t      pAccept_RspCb,
    645                                         void*                                        pContext)
    646 {
    647    NFCSTATUS status = NFCSTATUS_SUCCESS;
    648 
    649    /* Check for NULL pointers */
    650    if(pLlcpSocket == NULL || psOptions == NULL || psWorkingBuffer == NULL || pErr_Cb == NULL || pContext == NULL)
    651    {
    652       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    653       /* Call the CB */
    654       pAccept_RspCb(pContext,status);
    655    }
    656    /* Check for socket state */
    657    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
    658    {
    659       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
    660       /* Call the CB */
    661       pAccept_RspCb(pContext,status);
    662    }
    663    /* Check for socket type */
    664    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
    665    {
    666       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    667       /* Call the CB */
    668       pAccept_RspCb(pContext,status);
    669    }
    670    /* Test the socket options */
    671    else if(psOptions->rw > PHFRINFC_LLCP_RW_MAX)
    672    {
    673       /* Call the callback */
    674       pAccept_RspCb(pContext,status);
    675       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    676    }
    677 
    678    /* Set the Max length for the Send and Receive Window Buffer */
    679    pLlcpSocket->bufferSendMaxLength   = psOptions->miu;
    680    pLlcpSocket->bufferRwMaxLength     = psOptions->miu * ((psOptions->rw & PHFRINFC_LLCP_TLV_RW_MASK));
    681    pLlcpSocket->bufferLinearLength    = psWorkingBuffer->length - pLlcpSocket->bufferSendMaxLength - pLlcpSocket->bufferRwMaxLength;
    682 
    683    /* Test the buffers length */
    684    if((pLlcpSocket->bufferSendMaxLength + pLlcpSocket->bufferRwMaxLength) > psWorkingBuffer->length
    685        || ((pLlcpSocket->bufferLinearLength < PHFRINFC_LLCP_MIU_DEFAULT)  && (pLlcpSocket->bufferLinearLength != 0)))
    686    {
    687        /* Call the callback */
    688       pAccept_RspCb(pContext,status);
    689       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_BUFFER_TOO_SMALL);
    690    }
    691    else
    692    {
    693       pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
    694 
    695       status  = phFriNfc_LlcpTransport_ConnectionOriented_Accept(pLlcpSocket,
    696                                                                  psOptions,
    697                                                                  psWorkingBuffer,
    698                                                                  pErr_Cb,
    699                                                                  pAccept_RspCb,
    700                                                                  pContext);
    701    }
    702    return status;
    703 }
    704 
    705  /**
    706 * \ingroup grp_fri_nfc
    707 * \brief <b>Reject an incoming connection request for a socket</b>.
    708 *
    709 * This functions allows the client to reject an incoming connection request.
    710 * It must be used with the socket provided within the listen callback. The socket
    711 * is implicitly closed when the function is called.
    712 *
    713 * \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
    714 * \param[in]  pReject_RspCb         The callback to be call when the Reject operation is completed
    715 * \param[in]  pContext              Upper layer context to be returned in the callback.
    716 *
    717 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    718 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    719 *                                            could not be properly interpreted.
    720 * \retval NFCSTATUS_FAILED                   Operation failed.
    721 */
    722 NFCSTATUS phFriNfc_LlcpTransport_Reject( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
    723                                           pphFriNfc_LlcpTransportSocketRejectCb_t   pReject_RspCb,
    724                                           void                                      *pContext)
    725 {
    726    NFCSTATUS status = NFCSTATUS_SUCCESS;
    727 
    728    /* Check for NULL pointers */
    729    if(pLlcpSocket == NULL)
    730    {
    731       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    732       /* Call the CB */
    733       pReject_RspCb(pContext,status);
    734    }
    735    /* Check for socket state */
    736    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
    737    {
    738       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
    739       /* Call the CB */
    740       pReject_RspCb(pContext,status);
    741    }
    742    /* Check for socket type */
    743    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
    744    {
    745       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    746       /* Call the CB */
    747       pReject_RspCb(pContext,status);
    748    }
    749    else
    750    {
    751       status = phLibNfc_LlcpTransport_ConnectionOriented_Reject(pLlcpSocket,
    752                                                                 pReject_RspCb,
    753                                                                 pContext);
    754    }
    755 
    756    return status;
    757 }
    758 
    759 /**
    760 * \ingroup grp_fri_nfc
    761 * \brief <b>Try to establish connection with a socket on a remote SAP</b>.
    762 *
    763 * This function tries to connect to a given SAP on the remote peer. If the
    764 * socket is not bound to a local SAP, it is implicitly bound to a free SAP.
    765 *
    766 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
    767 * \param[in]  nSap               The destination SAP to connect to.
    768 * \param[in]  pConnect_RspCb     The callback to be called when the connection
    769 *                                operation is completed.
    770 * \param[in]  pContext           Upper layer context to be returned in
    771 *                                the callback.
    772 *
    773 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    774 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    775 *                                            could not be properly interpreted.
    776 * \retval NFCSTATUS_PENDING                  Connection operation is in progress,
    777 *                                            pConnect_RspCb will be called upon completion.
    778 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
    779 *                                            a valid type to perform the requsted operation.
    780 * \retval NFCSTATUS_FAILED                   Operation failed.
    781 */
    782 NFCSTATUS phFriNfc_LlcpTransport_Connect( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
    783                                           uint8_t                                    nSap,
    784                                           pphFriNfc_LlcpTransportSocketConnectCb_t   pConnect_RspCb,
    785                                           void*                                      pContext)
    786 {
    787    NFCSTATUS status = NFCSTATUS_SUCCESS;
    788    uint8_t i;
    789 
    790       /* Check for NULL pointers */
    791    if(pLlcpSocket == NULL || pConnect_RspCb == NULL || pContext == NULL)
    792    {
    793       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    794       /* Call the CB */
    795       pConnect_RspCb(pContext,FALSE,status);
    796    }
    797    /* Test the port number value */
    798    else if(nSap<02 || nSap>63)
    799    {
    800       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    801       /* Call the CB */
    802       pConnect_RspCb(pContext,FALSE,status);
    803    }
    804    /* Test if the socket is a connectionOriented socket */
    805    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
    806    {
    807       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    808       /* Call the CB */
    809       pConnect_RspCb(pContext,FALSE,status);
    810    }
    811 
    812    /* Test if the socket is not in connecting or connected state*/
    813    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketCreated && pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
    814    {
    815       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
    816       /* Call the CB */
    817       pConnect_RspCb(pContext,FALSE,status);
    818    }
    819    else
    820    {
    821       if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
    822       {
    823          /* Bind with a sSap Free */
    824          pLlcpSocket->socket_sSap = 32;
    825 
    826          for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
    827          {
    828             if(pLlcpSocket->socket_sSap == pLlcpSocket->psTransport->pSocketTable[i].socket_sSap)
    829             {
    830                pLlcpSocket->socket_sSap++;
    831             }
    832          }
    833       }
    834       pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
    835 
    836       status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket,
    837                                                                  nSap,
    838                                                                  NULL,
    839                                                                  pConnect_RspCb,
    840                                                                  pContext);
    841    }
    842 
    843    return status;
    844 }
    845 
    846 /**
    847 * \ingroup grp_fri_nfc
    848 * \brief <b>Try to establish connection with a socket on a remote service, given its URI</b>.
    849 *
    850 * This function tries to connect to a SAP designated by an URI. If the
    851 * socket is not bound to a local SAP, it is implicitly bound to a free SAP.
    852 *
    853 * \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
    854 * \param[in]  psUri              The URI corresponding to the destination SAP to connect to.
    855 * \param[in]  pConnect_RspCb     The callback to be called when the connection
    856 *                                operation is completed.
    857 * \param[in]  pContext           Upper layer context to be returned in
    858 *                                the callback.
    859 *
    860 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    861 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    862 *                                            could not be properly interpreted.
    863 * \retval NFCSTATUS_PENDING                  Connection operation is in progress,
    864 *                                            pConnect_RspCb will be called upon completion.
    865 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
    866 *                                            a valid type to perform the requsted operation.
    867 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
    868 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
    869 * \retval NFCSTATUS_FAILED                   Operation failed.
    870 */
    871 NFCSTATUS phFriNfc_LlcpTransport_ConnectByUri(phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
    872                                               phNfc_sData_t*                             psUri,
    873                                               pphFriNfc_LlcpTransportSocketConnectCb_t   pConnect_RspCb,
    874                                               void*                                      pContext)
    875 {
    876    NFCSTATUS status = NFCSTATUS_SUCCESS;
    877    uint8_t i;
    878 
    879    /* Check for NULL pointers */
    880    if(pLlcpSocket == NULL || pConnect_RspCb == NULL || pContext == NULL)
    881    {
    882       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    883       /* Call the CB */
    884       pConnect_RspCb(pContext,FALSE,status);
    885    }
    886    /* Test if the socket is a connectionOriented socket */
    887    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
    888    {
    889       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    890       /* Call the CB */
    891       pConnect_RspCb(pContext,FALSE,status);
    892    }
    893    /* Test if the socket is not in connect pending or connected state*/
    894    else if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnecting || pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
    895    {
    896       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    897       /* Call the CB */
    898       pConnect_RspCb(pContext,FALSE,status);
    899    }
    900    /* Test the length of the SN */
    901    else if(psUri->length > PHFRINFC_LLCP_SN_MAX_LENGTH)
    902    {
    903          return status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    904    }
    905    else
    906    {
    907       if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
    908       {
    909          /* Bind with a sSap Free */
    910          pLlcpSocket->socket_sSap = 32;
    911 
    912          for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++)
    913          {
    914             if(pLlcpSocket->socket_sSap == pLlcpSocket->psTransport->pSocketTable[i].socket_sSap)
    915             {
    916                pLlcpSocket->socket_sSap++;
    917             }
    918          }
    919       }
    920       status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket,
    921                                                                  PHFRINFC_LLCP_SAP_DEFAULT,
    922                                                                  psUri,
    923                                                                  pConnect_RspCb,
    924                                                                  pContext);
    925    }
    926 
    927    return status;
    928 }
    929 
    930 /**
    931 * \ingroup grp_lib_nfc
    932 * \brief <b>Disconnect a currently connected socket</b>.
    933 *
    934 * This function initiates the disconnection of a previously connected socket.
    935 *
    936 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
    937 * \param[in]  pDisconnect_RspCb  The callback to be called when the
    938 *                                operation is completed.
    939 * \param[in]  pContext           Upper layer context to be returned in
    940 *                                the callback.
    941 *
    942 * \retval NFCSTATUS_SUCCESS                  Operation successful.
    943 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
    944 *                                            could not be properly interpreted.
    945 * \retval NFCSTATUS_PENDING                  Disconnection operation is in progress,
    946 *                                            pDisconnect_RspCb will be called upon completion.
    947 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
    948 *                                            a valid type to perform the requsted operation.
    949 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
    950 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
    951 * \retval NFCSTATUS_FAILED                   Operation failed.
    952 */
    953 NFCSTATUS phFriNfc_LlcpTransport_Disconnect(phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
    954                                             pphLibNfc_LlcpSocketDisconnectCb_t         pDisconnect_RspCb,
    955                                             void*                                      pContext)
    956 {
    957    NFCSTATUS status = NFCSTATUS_SUCCESS;
    958 
    959    /* Check for NULL pointers */
    960    if(pLlcpSocket == NULL || pDisconnect_RspCb == NULL || pContext == NULL)
    961    {
    962       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    963       /* Call the CB */
    964       pDisconnect_RspCb(pContext,status);
    965    }
    966    /* Test if the socket is a connectionOriented socket */
    967    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
    968    {
    969        status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    970       /* Call the CB */
    971       pDisconnect_RspCb(pContext,status);
    972    }
    973    /* Test if the socket is connected  state*/
    974    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
    975    {
    976        status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
    977       /* Call the CB */
    978       pDisconnect_RspCb(pContext,status);
    979    }
    980    else
    981    {
    982       status = phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(pLlcpSocket,
    983                                                                     pDisconnect_RspCb,
    984                                                                     pContext);
    985    }
    986 
    987    return status;
    988 }
    989 
    990 /**
    991 * \ingroup grp_fri_nfc
    992 * \brief <b>Send data on a socket</b>.
    993 *
    994 * This function is used to write data on a socket. This function
    995 * can only be called on a connection-oriented socket which is already
    996 * in a connected state.
    997 *
    998 *
    999 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
   1000 * \param[in]  psBuffer           The buffer containing the data to send.
   1001 * \param[in]  pSend_RspCb        The callback to be called when the
   1002 *                                operation is completed.
   1003 * \param[in]  pContext           Upper layer context to be returned in
   1004 *                                the callback.
   1005 *
   1006 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1007 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1008 *                                            could not be properly interpreted.
   1009 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
   1010 *                                            pSend_RspCb will be called upon completion.
   1011 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   1012 *                                            a valid type to perform the requsted operation.
   1013 * \retval NFCSTATUS_FAILED                   Operation failed.
   1014 */
   1015 NFCSTATUS phFriNfc_LlcpTransport_Send(phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
   1016                                       phNfc_sData_t*                               psBuffer,
   1017                                       pphFriNfc_LlcpTransportSocketSendCb_t        pSend_RspCb,
   1018                                       void*                                        pContext)
   1019 {
   1020    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1021 
   1022    /* Check for NULL pointers */
   1023    if(pLlcpSocket == NULL || psBuffer == NULL || pSend_RspCb == NULL || pContext == NULL)
   1024    {
   1025       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1026       /* Call the CB */
   1027       pSend_RspCb(pContext,status);
   1028    }
   1029    /* Test if the socket is a connectionOriented socket */
   1030    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   1031    {
   1032       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1033       /* Call the CB */
   1034       pSend_RspCb(pContext,status);
   1035    }
   1036    /* Test if the socket is in connected state */
   1037    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
   1038    {
   1039       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   1040       /* Call the CB */
   1041       pSend_RspCb(pContext,status);
   1042    }
   1043    /* Test the length of the buffer */
   1044    else if(psBuffer->length > pLlcpSocket->remoteMIU )
   1045    {
   1046       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1047       /* Call the CB */
   1048       pSend_RspCb(pContext,status);
   1049    }
   1050    /* Test if a send is pending */
   1051    else if(pLlcpSocket->bSocketSendPending == TRUE)
   1052    {
   1053       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
   1054       /* Call the CB */
   1055       pSend_RspCb(pContext,status);
   1056    }
   1057    else
   1058    {
   1059       status = phFriNfc_LlcpTransport_ConnectionOriented_Send(pLlcpSocket,
   1060                                                               psBuffer,
   1061                                                               pSend_RspCb,
   1062                                                               pContext);
   1063    }
   1064 
   1065    return status;
   1066 }
   1067 
   1068  /**
   1069 * \ingroup grp_fri_nfc
   1070 * \brief <b>Read data on a socket</b>.
   1071 *
   1072 * This function is used to read data from a socket. It reads at most the
   1073 * size of the reception buffer, but can also return less bytes if less bytes
   1074 * are available. If no data is available, the function will be pending until
   1075 * more data comes, and the response will be sent by the callback. This function
   1076 * can only be called on a connection-oriented socket.
   1077 *
   1078 *
   1079 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
   1080 * \param[in]  psBuffer           The buffer receiving the data.
   1081 * \param[in]  pRecv_RspCb        The callback to be called when the
   1082 *                                operation is completed.
   1083 * \param[in]  pContext           Upper layer context to be returned in
   1084 *                                the callback.
   1085 *
   1086 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1087 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1088 *                                            could not be properly interpreted.
   1089 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
   1090 *                                            pRecv_RspCb will be called upon completion.
   1091 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   1092 *                                            a valid type to perform the requsted operation.
   1093 * \retval NFCSTATUS_FAILED                   Operation failed.
   1094 */
   1095 NFCSTATUS phFriNfc_LlcpTransport_Recv( phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
   1096                                        phNfc_sData_t*                               psBuffer,
   1097                                        pphFriNfc_LlcpTransportSocketRecvCb_t        pRecv_RspCb,
   1098                                        void*                                        pContext)
   1099 {
   1100    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1101 
   1102 
   1103    /* Check for NULL pointers */
   1104    if(pLlcpSocket == NULL || psBuffer == NULL || pRecv_RspCb == NULL || pContext == NULL)
   1105    {
   1106       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1107       /* Call the CB */
   1108       pRecv_RspCb(pContext,status);
   1109    }
   1110    /* Test if the socket is a connectionOriented socket */
   1111    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionOriented)
   1112    {
   1113       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1114       /* Call the CB */
   1115       pRecv_RspCb(pContext,status);
   1116    }
   1117    /* Test if the socket is in connected state */
   1118    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
   1119    {
   1120       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1121       /* Call the CB */
   1122       pRecv_RspCb(pContext,status);
   1123    }
   1124    /* Test if a receive is pending */
   1125    else if(pLlcpSocket->bSocketRecvPending == TRUE)
   1126    {
   1127       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
   1128       /* Call the CB */
   1129       pRecv_RspCb(pContext,status);
   1130    }
   1131    else
   1132    {
   1133       status = phFriNfc_LlcpTransport_ConnectionOriented_Recv(pLlcpSocket,
   1134                                                               psBuffer,
   1135                                                               pRecv_RspCb,
   1136                                                               pContext);
   1137    }
   1138 
   1139 
   1140    return status;
   1141 }
   1142 
   1143 /*****************************************/
   1144 /*           ConnectionLess              */
   1145 /*****************************************/
   1146 
   1147 /**
   1148 * \ingroup grp_fri_nfc
   1149 * \brief <b>Send data on a socket to a given destination SAP</b>.
   1150 *
   1151 * This function is used to write data on a socket to a given destination SAP.
   1152 * This function can only be called on a connectionless socket.
   1153 *
   1154 *
   1155 * \param[in]  pLlcpSocket        A pointer to a LlcpSocket created.
   1156 * \param[in]  nSap               The destination SAP.
   1157 * \param[in]  psBuffer           The buffer containing the data to send.
   1158 * \param[in]  pSend_RspCb        The callback to be called when the
   1159 *                                operation is completed.
   1160 * \param[in]  pContext           Upper layer context to be returned in
   1161 *                                the callback.
   1162 *
   1163 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1164 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1165 *                                            could not be properly interpreted.
   1166 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
   1167 *                                            pSend_RspCb will be called upon completion.
   1168 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   1169 *                                            a valid type to perform the requsted operation.
   1170 * \retval NFCSTATUS_FAILED                   Operation failed.
   1171 */
   1172 NFCSTATUS phFriNfc_LlcpTransport_SendTo( phFriNfc_LlcpTransport_Socket_t             *pLlcpSocket,
   1173                                          uint8_t                                     nSap,
   1174                                          phNfc_sData_t                               *psBuffer,
   1175                                          pphFriNfc_LlcpTransportSocketSendCb_t       pSend_RspCb,
   1176                                          void*                                       pContext)
   1177 {
   1178    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1179    phFriNfc_Llcp_sLinkParameters_t  LlcpRemoteLinkParamInfo;
   1180 
   1181 
   1182    if(pLlcpSocket == NULL || psBuffer == NULL || pSend_RspCb == NULL || pContext == NULL)
   1183    {
   1184       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1185       pSend_RspCb(pContext,status);
   1186    }
   1187    /* Test the port number value */
   1188    else if(nSap<2 || nSap>63)
   1189    {
   1190       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1191       pSend_RspCb(pContext,status);
   1192       return status;
   1193    }
   1194    /* Test if the socket is a connectionless socket */
   1195    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionLess)
   1196    {
   1197        status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1198        pSend_RspCb(pContext,status);
   1199        return status;
   1200    }
   1201    /* Test if the socket is in an updated state */
   1202    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
   1203    {
   1204       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   1205       pSend_RspCb(pContext,status);
   1206       return status;
   1207    }
   1208    /* Get the local parameters of the LLCP Link */
   1209    status = phFriNfc_Llcp_GetRemoteInfo(pLlcpSocket->psTransport->pLlcp,&LlcpRemoteLinkParamInfo);
   1210    if(status != NFCSTATUS_SUCCESS)
   1211    {
   1212       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
   1213    }
   1214    /* Test the length of the socket buffer for ConnectionLess mode*/
   1215    else if(psBuffer->length > LlcpRemoteLinkParamInfo.miu)
   1216    {
   1217       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1218       pSend_RspCb(pContext,status);
   1219    }
   1220    /* Test if the link is in error state */
   1221    else if(pLlcpSocket->psTransport->LinkStatusError)
   1222    {
   1223       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
   1224       pSend_RspCb(pContext,status);
   1225    }
   1226    else
   1227    {
   1228       status = phFriNfc_LlcpTransport_Connectionless_SendTo(pLlcpSocket,
   1229                                                             nSap,
   1230                                                             psBuffer,
   1231                                                             pSend_RspCb,
   1232                                                             pContext);
   1233    }
   1234    return status;
   1235 }
   1236 
   1237 
   1238  /**
   1239 * \ingroup grp_lib_nfc
   1240 * \brief <b>Read data on a socket and get the source SAP</b>.
   1241 *
   1242 * This function is the same as phLibNfc_Llcp_Recv, except that the callback includes
   1243 * the source SAP. This functions can only be called on a connectionless socket.
   1244 *
   1245 *
   1246 * \param[in]  pLlcpSocket        A pointer to a LlcpSocket created.
   1247 * \param[in]  psBuffer           The buffer receiving the data.
   1248 * \param[in]  pRecv_RspCb        The callback to be called when the
   1249 *                                operation is completed.
   1250 * \param[in]  pContext           Upper layer context to be returned in
   1251 *                                the callback.
   1252 *
   1253 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1254 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1255 *                                            could not be properly interpreted.
   1256 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
   1257 *                                            pRecv_RspCb will be called upon completion.
   1258 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   1259 *                                            a valid type to perform the requsted operation.
   1260 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
   1261 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
   1262 * \retval NFCSTATUS_FAILED                   Operation failed.
   1263 */
   1264 NFCSTATUS phFriNfc_LlcpTransport_RecvFrom( phFriNfc_LlcpTransport_Socket_t                   *pLlcpSocket,
   1265                                            phNfc_sData_t*                                    psBuffer,
   1266                                            pphFriNfc_LlcpTransportSocketRecvFromCb_t         pRecv_Cb,
   1267                                            void*                                             pContext)
   1268 {
   1269    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1270    if(pLlcpSocket == NULL || psBuffer == NULL || pRecv_Cb == NULL || pContext == NULL)
   1271    {
   1272       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1273       pRecv_Cb(pContext,0x00,status);
   1274    }
   1275    /* Test if the socket is a connectionless socket */
   1276    else if(pLlcpSocket->eSocket_Type != phFriNfc_LlcpTransport_eConnectionLess)
   1277    {
   1278        status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER);
   1279        pRecv_Cb(pContext,0x00,status);
   1280    }
   1281    /* Test if the socket is in an updated state */
   1282    else if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound)
   1283    {
   1284       status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_STATE);
   1285       pRecv_Cb(pContext,0x00,status);
   1286    }
   1287    else
   1288    {
   1289       if(pLlcpSocket->bSocketRecvPending)
   1290       {
   1291          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_REJECTED);
   1292          pRecv_Cb(pContext,0x00,status);
   1293       }
   1294       else
   1295       {
   1296          status = phLibNfc_LlcpTransport_Connectionless_RecvFrom(pLlcpSocket,
   1297                                                                  psBuffer,
   1298                                                                  pRecv_Cb,
   1299                                                                  pContext);
   1300       }
   1301    }
   1302    return status;
   1303 }
   1304