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_Connection.c
     19  * \brief
     20  *
     21  * Project: NFC-FRI
     22  *
     23  */
     24 /*include files*/
     25 #define LOG_TAG "NFC"
     26 #include <cutils/log.h>
     27 #include <phOsalNfc.h>
     28 #include <phLibNfcStatus.h>
     29 #include <phLibNfc.h>
     30 #include <phNfcLlcpTypes.h>
     31 #include <phFriNfc_LlcpTransport.h>
     32 #include <phFriNfc_LlcpTransport_Connection.h>
     33 #include <phFriNfc_Llcp.h>
     34 #include <phFriNfc_LlcpUtils.h>
     35 
     36 /* Function definition */
     37 static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_Socket_t*    pLlcpSocket);
     38 static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket);
     39 
     40 static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket);
     41 /**********   End Function definition   ***********/
     42 
     43 /* TODO: comment functionphFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB */
     44 static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void*        pContext,
     45                                                                   uint8_t      socketIndex,
     46                                                                   NFCSTATUS    status)
     47 {
     48    phFriNfc_LlcpTransport_t          *psTransport;
     49    phFriNfc_LlcpTransport_Socket_t    psTempLlcpSocket;
     50    phFriNfc_LlcpTransport_Socket_t   *psLocalLlcpSocket = NULL;
     51    phNfc_sData_t                     sFrmrBuffer;
     52    uint8_t                           index;
     53    uint8_t                           socketFound = FALSE;
     54    NFCSTATUS                         result;
     55    /* Get Send CB context */
     56    psTransport = (phFriNfc_LlcpTransport_t*)pContext;
     57 
     58    if(status == NFCSTATUS_SUCCESS)
     59    {
     60       /* Test the socket */
     61       switch(psTransport->pSocketTable[socketIndex].eSocket_State)
     62       {
     63       case phFriNfc_LlcpTransportSocket_eSocketAccepted:
     64          {
     65             /* Set socket state to Connected */
     66             psTransport->pSocketTable[socketIndex].eSocket_State  = phFriNfc_LlcpTransportSocket_eSocketConnected;
     67             /* Call the Accept Callback */
     68             psTransport->pSocketTable[socketIndex].pfSocketAccept_Cb(psTransport->pSocketTable[socketIndex].pAcceptContext,status);
     69             psTransport->pSocketTable[socketIndex].pfSocketAccept_Cb = NULL;
     70             psTransport->pSocketTable[socketIndex].pAcceptContext = NULL;
     71          }break;
     72 
     73       case phFriNfc_LlcpTransportSocket_eSocketRejected:
     74          {
     75             /* Store the Llcp socket in a local Llcp socket */
     76             psTempLlcpSocket = psTransport->pSocketTable[socketIndex];
     77 
     78             /* Reset the socket  and set the socket state to default */
     79             result = phFriNfc_LlcpTransport_Close(&psTransport->pSocketTable[socketIndex]);
     80 
     81             /* Call the Reject Callback */
     82             psTempLlcpSocket.pfSocketSend_Cb(psTempLlcpSocket.pRejectContext,status);
     83             psTempLlcpSocket.pfSocketSend_Cb = NULL;
     84          }break;
     85 
     86       case phFriNfc_LlcpTransportSocket_eSocketConnected:
     87          {
     88             if(!psTransport->pSocketTable[socketIndex].bSocketSendPending && psTransport->pSocketTable[socketIndex].pfSocketSend_Cb != NULL)
     89             {
     90                psTransport->pSocketTable[socketIndex].pfSocketSend_Cb(psTransport->pSocketTable[socketIndex].pSendContext,status);
     91                psTransport->pSocketTable[socketIndex].pfSocketSend_Cb = NULL;
     92             }
     93          }break;
     94       default:
     95          /* Nothing to do */
     96          break;
     97       }
     98    }
     99    else
    100    {
    101       /* Send CB error */
    102       if(!psTransport->pSocketTable[socketIndex].bSocketSendPending && psTransport->pSocketTable[socketIndex].pfSocketSend_Cb != NULL)
    103       {
    104          psTransport->pSocketTable[socketIndex].pfSocketSend_Cb(psTransport->pSocketTable[socketIndex].pSendContext,status);
    105          psTransport->pSocketTable[socketIndex].pfSocketSend_Cb = NULL;
    106       }
    107    }
    108 }
    109 
    110 
    111 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_HandlePendingOperations(phFriNfc_LlcpTransport_Socket_t *pSocket)
    112 {
    113    NFCSTATUS                  result = NFCSTATUS_FAILED;
    114    phFriNfc_LlcpTransport_t   *psTransport = pSocket->psTransport;
    115    /* I FRAME */
    116    if(pSocket->bSocketSendPending == TRUE)
    117    {
    118       /* Test the RW window */
    119       if(CHECK_SEND_RW(pSocket))
    120       {
    121          if (!testAndSetSendPending(psTransport)) {
    122             result = static_performSendInfo(pSocket);
    123             if (result != NFCSTATUS_SUCCESS && result != NFCSTATUS_PENDING) {
    124                 clearSendPending(psTransport);
    125             }
    126          }
    127       }
    128    }
    129    /* RR FRAME */
    130    else if(pSocket->bSocketRRPending == TRUE)
    131    {
    132       /* Reset RR pending */
    133       pSocket->bSocketRRPending = FALSE;
    134 
    135       /* Send RR Frame */
    136       result = phFriNfc_Llcp_Send_ReceiveReady_Frame(pSocket);
    137    }
    138    /* RNR Frame */
    139    else if(pSocket->bSocketRNRPending == TRUE)
    140    {
    141       /* Reset RNR pending */
    142       pSocket->bSocketRNRPending = FALSE;
    143 
    144       /* Send RNR Frame */
    145       result = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(pSocket);
    146    }
    147    /* CC Frame */
    148    else if(pSocket->bSocketAcceptPending == TRUE)
    149    {
    150       if (!testAndSetSendPending(psTransport))
    151       {
    152          /* Reset Accept pending */
    153          pSocket->bSocketAcceptPending = FALSE;
    154 
    155          /* Fill the psLlcpHeader stuture with the DSAP,CC PTYPE and the SSAP */
    156          pSocket->sLlcpHeader.dsap  = pSocket->socket_dSap;
    157          pSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC;
    158          pSocket->sLlcpHeader.ssap  = pSocket->socket_sSap;
    159 
    160          /* Set the socket state to accepted */
    161          pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketAccepted;
    162 
    163          /* Send a CC Frame */
    164          result =  phFriNfc_LlcpTransport_LinkSend(psTransport,
    165                                    &pSocket->sLlcpHeader,
    166                                    NULL,
    167                                    &pSocket->sSocketSendBuffer,
    168                                    phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
    169                                    pSocket->index,
    170                                    psTransport);
    171 
    172          if (result != NFCSTATUS_SUCCESS && result != NFCSTATUS_PENDING) {
    173             clearSendPending(psTransport);
    174          }
    175       }
    176    }
    177    /* CONNECT FRAME */
    178    else if(pSocket->bSocketConnectPending == TRUE)
    179    {
    180       if (!testAndSetSendPending(psTransport))
    181       {
    182          /* Reset Accept pending */
    183          pSocket->bSocketConnectPending = FALSE;
    184 
    185          /* Set the socket in connecting state */
    186          pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnecting;
    187 
    188          /* send CONNECT */
    189          result =  phFriNfc_LlcpTransport_LinkSend(psTransport,
    190                                  &pSocket->sLlcpHeader,
    191                                  NULL,
    192                                  &pSocket->sSocketSendBuffer,
    193                                  phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
    194                                  pSocket->index,
    195                                  psTransport);
    196 
    197          if (result != NFCSTATUS_SUCCESS && result != NFCSTATUS_PENDING) {
    198             clearSendPending(psTransport);
    199          }
    200       }
    201    }
    202    /* DISC FRAME */
    203    else if(pSocket->bSocketDiscPending == TRUE)
    204    {
    205       if (!testAndSetSendPending(psTransport))
    206       {
    207          /* Reset Disc Pending */
    208          pSocket->bSocketDiscPending = FALSE;
    209 
    210          /* Set the socket in connecting state */
    211          pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
    212 
    213          /* Send DISC */
    214          result =  phFriNfc_LlcpTransport_LinkSend(psTransport,
    215                                    &pSocket->sLlcpHeader,
    216                                    NULL,
    217                                    &pSocket->sSocketSendBuffer,
    218                                    phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
    219                                    pSocket->index,
    220                                    psTransport);
    221 
    222          if (result != NFCSTATUS_SUCCESS && result != NFCSTATUS_PENDING) {
    223             clearSendPending(psTransport);
    224          }
    225          /* Call ErrCB due to a DISC */
    226          pSocket->pSocketErrCb(pSocket->pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
    227       }
    228    }
    229    return result;
    230 }
    231 
    232 static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket)
    233 {
    234    phFriNfc_LlcpTransport_t   *psTransport = psLlcpSocket->psTransport;
    235    NFCSTATUS                  status;
    236 
    237    /* Set the Header */
    238    psLlcpSocket->sLlcpHeader.dsap   = psLlcpSocket->socket_dSap;
    239    psLlcpSocket->sLlcpHeader.ptype  = PHFRINFC_LLCP_PTYPE_I;
    240    psLlcpSocket->sLlcpHeader.ssap   = psLlcpSocket->socket_sSap;
    241 
    242    /* Set Sequence Numbers */
    243    psLlcpSocket->sSequence.ns = psLlcpSocket->socket_VS;
    244    psLlcpSocket->sSequence.nr = psLlcpSocket->socket_VR;
    245 
    246    /* Update the VRA */
    247    psLlcpSocket->socket_VRA = psLlcpSocket->socket_VR;
    248 
    249 
    250    /* Send I_PDU */
    251    status =  phFriNfc_LlcpTransport_LinkSend(psTransport,
    252                                 &psLlcpSocket->sLlcpHeader,
    253                                 &psLlcpSocket->sSequence,
    254                                 &psLlcpSocket->sSocketSendBuffer,
    255                                 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
    256                                 psLlcpSocket->index,
    257                                 psLlcpSocket->psTransport);
    258    if (status == NFCSTATUS_SUCCESS || status == NFCSTATUS_PENDING) {
    259       /* Update VS */
    260       psLlcpSocket->socket_VS = (psLlcpSocket->socket_VS+1)%16;
    261 
    262       /* Reset Send Pending */
    263       psLlcpSocket->bSocketSendPending = FALSE;
    264    }
    265 
    266    return status;
    267 }
    268 
    269 static void phFriNfc_LlcpTransport_ConnectionOriented_Abort(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket)
    270 {
    271    if (pLlcpSocket->pfSocketSend_Cb != NULL)
    272    {
    273       pLlcpSocket->pfSocketSend_Cb(pLlcpSocket->pSendContext, NFCSTATUS_ABORTED);
    274       pLlcpSocket->pfSocketSend_Cb = NULL;
    275    }
    276    pLlcpSocket->pSendContext = NULL;
    277    if (pLlcpSocket->pfSocketRecv_Cb != NULL)
    278    {
    279       pLlcpSocket->pfSocketRecv_Cb(pLlcpSocket->pRecvContext, NFCSTATUS_ABORTED);
    280       pLlcpSocket->pfSocketRecv_Cb = NULL;
    281    }
    282    pLlcpSocket->pRecvContext = NULL;
    283    if (pLlcpSocket->pfSocketAccept_Cb != NULL)
    284    {
    285       pLlcpSocket->pfSocketAccept_Cb(pLlcpSocket->pAcceptContext, NFCSTATUS_ABORTED);
    286       pLlcpSocket->pfSocketAccept_Cb = NULL;
    287    }
    288    pLlcpSocket->pAcceptContext = NULL;
    289    if (pLlcpSocket->pfSocketConnect_Cb != NULL)
    290    {
    291       pLlcpSocket->pfSocketConnect_Cb(pLlcpSocket->pConnectContext, 0, NFCSTATUS_ABORTED);
    292       pLlcpSocket->pfSocketConnect_Cb = NULL;
    293    }
    294    pLlcpSocket->pConnectContext = NULL;
    295    if (pLlcpSocket->pfSocketDisconnect_Cb != NULL)
    296    {
    297       pLlcpSocket->pfSocketDisconnect_Cb(pLlcpSocket->pDisconnectContext, NFCSTATUS_ABORTED);
    298       pLlcpSocket->pfSocketDisconnect_Cb = NULL;
    299    }
    300    pLlcpSocket->pDisconnectContext = NULL;
    301 
    302    pLlcpSocket->pfSocketRecvFrom_Cb = NULL;
    303    pLlcpSocket->pfSocketListen_Cb = NULL;
    304    pLlcpSocket->pListenContext = NULL;
    305 }
    306 
    307 
    308 static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_Socket_t*    pLlcpSocket)
    309 {
    310    NFCSTATUS   status = NFCSTATUS_SUCCESS;
    311 
    312    /* Test if a send is pending */
    313    if(testAndSetSendPending(pLlcpSocket->psTransport))
    314    {
    315       pLlcpSocket->bSocketRRPending = TRUE;
    316       status = NFCSTATUS_PENDING;
    317    }
    318    else
    319    {
    320       /* Set the header of the RR frame */
    321       pLlcpSocket->sLlcpHeader.dsap   = pLlcpSocket->socket_dSap;
    322       pLlcpSocket->sLlcpHeader.ptype  = PHFRINFC_LLCP_PTYPE_RR;
    323       pLlcpSocket->sLlcpHeader.ssap   = pLlcpSocket->socket_sSap;
    324 
    325       /* Set sequence number for RR Frame */
    326       pLlcpSocket->sSequence.ns = 0;
    327       pLlcpSocket->sSequence.nr = pLlcpSocket->socket_VR;
    328 
    329       /* Update VRA */
    330       pLlcpSocket->socket_VRA = (uint8_t)pLlcpSocket->sSequence.nr;
    331 
    332       /* Send RR frame */
    333       status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
    334                                    &pLlcpSocket->sLlcpHeader,
    335                                    &pLlcpSocket->sSequence,
    336                                    NULL,
    337                                    phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
    338                                    pLlcpSocket->index,
    339                                    pLlcpSocket->psTransport);
    340       if (status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING) {
    341          clearSendPending(pLlcpSocket->psTransport);
    342       }
    343    }
    344 
    345    return status;
    346 }
    347 
    348 static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket)
    349 {
    350    NFCSTATUS   status = NFCSTATUS_SUCCESS;
    351 
    352 
    353    /* Test if a send is pending */
    354    if(testAndSetSendPending(pLlcpSocket->psTransport))
    355    {
    356       pLlcpSocket->bSocketRNRPending = TRUE;
    357       status = NFCSTATUS_PENDING;
    358    }
    359    else
    360    {
    361       /* Set the header of the RNR frame */
    362       pLlcpSocket->sLlcpHeader.dsap   = pLlcpSocket->socket_dSap;
    363       pLlcpSocket->sLlcpHeader.ptype  = PHFRINFC_LLCP_PTYPE_RNR;
    364       pLlcpSocket->sLlcpHeader.ssap   = pLlcpSocket->socket_sSap;
    365 
    366       /* Set sequence number for RNR Frame */
    367       pLlcpSocket->sSequence.ns = 0x00;
    368       pLlcpSocket->sSequence.nr = pLlcpSocket->socket_VR;
    369 
    370       /* Update VRA */
    371       pLlcpSocket->socket_VRA = (uint8_t)pLlcpSocket->sSequence.nr;
    372 
    373       /* Send RNR frame */
    374       status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
    375                                    &pLlcpSocket->sLlcpHeader,
    376                                    &pLlcpSocket->sSequence,
    377                                    NULL,
    378                                    phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
    379                                    pLlcpSocket->index,
    380                                    pLlcpSocket->psTransport);
    381       if (status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING) {
    382          clearSendPending(pLlcpSocket->psTransport);
    383       }
    384    }
    385    return status;
    386 }
    387 
    388 static NFCSTATUS phFriNfc_Llcp_GetSocket_Params(phNfc_sData_t                    *psParamsTLV,
    389                                                 phNfc_sData_t                    *psServiceName,
    390                                                 uint8_t                          *pRemoteRW_Size,
    391                                                 uint16_t                         *pRemoteMIU)
    392 {
    393    NFCSTATUS         status = NFCSTATUS_SUCCESS;
    394    phNfc_sData_t     sValueBuffer;
    395    uint32_t          offset = 0;
    396    uint8_t           type;
    397 
    398    /* Check for NULL pointers */
    399    if ((psParamsTLV == NULL) || (pRemoteRW_Size == NULL) || (pRemoteMIU == NULL))
    400    {
    401       return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
    402    }
    403    else
    404    {
    405       /* Decode TLV */
    406       while (offset < psParamsTLV->length)
    407       {
    408          status = phFriNfc_Llcp_DecodeTLV(psParamsTLV, &offset, &type,&sValueBuffer);
    409          if (status != NFCSTATUS_SUCCESS)
    410          {
    411             /* Error: Ill-formed TLV */
    412             return status;
    413          }
    414          switch(type)
    415          {
    416             case PHFRINFC_LLCP_TLV_TYPE_SN:
    417             {
    418                /* Test if a SN is present in the TLV */
    419                if(sValueBuffer.length == 0)
    420                {
    421                   /* Error : Ill-formed SN parameter TLV */
    422                   break;
    423                }
    424                /* Get the Service Name */
    425                *psServiceName = sValueBuffer;
    426             }break;
    427 
    428             case PHFRINFC_LLCP_TLV_TYPE_RW:
    429             {
    430                /* Check length */
    431                if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_RW)
    432                {
    433                   /* Error : Ill-formed MIUX parameter TLV */
    434                   break;
    435                }
    436                *pRemoteRW_Size = sValueBuffer.buffer[0];
    437             }break;
    438 
    439             case PHFRINFC_LLCP_TLV_TYPE_MIUX:
    440             {
    441                /* Check length */
    442                if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_MIUX)
    443                {
    444                   /* Error : Ill-formed MIUX parameter TLV */
    445                   break;
    446                }
    447                *pRemoteMIU = PHFRINFC_LLCP_MIU_DEFAULT + (((sValueBuffer.buffer[0] << 8) | sValueBuffer.buffer[1]) & PHFRINFC_LLCP_TLV_MIUX_MASK);
    448             }break;
    449 
    450             default:
    451             {
    452                /* Error : Unknown type */
    453                break;
    454             }
    455          }
    456       }
    457    }
    458    return status;
    459 }
    460 
    461 
    462 /* TODO: comment function Handle_ConnectFrame */
    463 static void Handle_ConnectionFrame(phFriNfc_LlcpTransport_t      *psTransport,
    464                                    phNfc_sData_t                 *psData,
    465                                    uint8_t                       dsap,
    466                                    uint8_t                       ssap)
    467 {
    468    NFCSTATUS                         status = NFCSTATUS_SUCCESS;
    469 
    470    uint8_t                                   index;
    471    uint8_t                                   socketFound = FALSE;
    472    phFriNfc_LlcpTransport_Socket_t           *pLlcpSocket = NULL;
    473    phFriNfc_LlcpTransport_Socket_t           *psLocalLlcpSocket = NULL;
    474    pphFriNfc_LlcpTransportSocketListenCb_t   pListen_Cb = NULL;
    475    void                                      *pListenContext = NULL;
    476 
    477    phNfc_sData_t                             sServiceName;
    478    uint8_t                                   remoteRW  = PHFRINFC_LLCP_RW_DEFAULT;
    479    uint16_t                                  remoteMIU = PHFRINFC_LLCP_MIU_DEFAULT;
    480 
    481    status = phFriNfc_Llcp_GetSocket_Params(psData,
    482                                            &sServiceName,
    483                                            &remoteRW,
    484                                            &remoteMIU);
    485 
    486    if(status != NFCSTATUS_SUCCESS)
    487    {
    488       /* Incorrect TLV */
    489       /* send FRMR */
    490       status  = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
    491                                                        dsap,
    492                                                        PHFRINFC_LLCP_PTYPE_CONNECT,
    493                                                        ssap,
    494                                                        0x00,
    495                                                        0x00,
    496                                                        0x00,
    497                                                        0x00,
    498                                                        0x00,
    499                                                        0x00,
    500                                                        0x00,
    501                                                        0x00,
    502                                                        0x00);
    503    }
    504    else
    505    {
    506       if(dsap == PHFRINFC_LLCP_SAP_SDP)
    507       {
    508          /* Search a socket with the SN */
    509          for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
    510          {
    511             /* Test if the socket is in Listen state and if its SN is the good one */
    512             if(psTransport->pSocketTable[index].bSocketListenPending
    513                &&  (sServiceName.length == psTransport->pSocketTable[index].sServiceName.length)
    514                && !memcmp(sServiceName.buffer,psTransport->pSocketTable[index].sServiceName.buffer,sServiceName.length))
    515             {
    516                /* socket with the SN found */
    517                socketFound = TRUE;
    518 
    519                psLocalLlcpSocket = &psTransport->pSocketTable[index];
    520 
    521                /* Get the new ssap number, it is the ssap number of the socket found */
    522                dsap = psLocalLlcpSocket->socket_sSap;
    523                /* Get the ListenCB of the socket */
    524                pListen_Cb = psLocalLlcpSocket->pfSocketListen_Cb;
    525                pListenContext = psLocalLlcpSocket->pListenContext;
    526                break;
    527             }
    528          }
    529      }
    530      else
    531      {
    532         /* Search a socket with the DSAP */
    533         for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
    534         {
    535            /* Test if the socket is in Listen state and if its port number is the good one */
    536            if(psTransport->pSocketTable[index].bSocketListenPending && psTransport->pSocketTable[index].socket_sSap == dsap)
    537            {
    538               /* socket with the SN found */
    539               socketFound = TRUE;
    540 
    541               psLocalLlcpSocket = &psTransport->pSocketTable[index];
    542 
    543               /* Get the Listen CB and the Context of the socket */
    544                pListen_Cb = psLocalLlcpSocket->pfSocketListen_Cb;
    545                pListenContext = psLocalLlcpSocket->pListenContext;
    546               break;
    547            }
    548         }
    549      }
    550    }
    551 
    552    /* Test if a socket has beeen found */
    553    if(socketFound)
    554    {
    555       /* Reset the FLAG socketFound*/
    556       socketFound = FALSE;
    557 
    558       /* Search a socket free and no socket connect on this DSAP*/
    559       for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
    560       {
    561          if(psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault && socketFound != TRUE)
    562          {
    563             socketFound = TRUE;
    564 
    565             psTransport->pSocketTable[index].index = index;
    566 
    567             /* Create a communication socket */
    568             pLlcpSocket = &psTransport->pSocketTable[index];
    569 
    570             /* Set the communication option of the Remote Socket */
    571             pLlcpSocket->remoteMIU = remoteMIU;
    572             pLlcpSocket->remoteRW  = remoteRW;
    573 
    574             /* Set SSAP/DSAP of the new socket created for the communication with the remote */
    575             pLlcpSocket->socket_dSap = ssap;
    576             pLlcpSocket->socket_sSap = dsap;
    577 
    578             /* Set the state and the type of the new socket */
    579             pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
    580             pLlcpSocket->eSocket_Type  = phFriNfc_LlcpTransport_eConnectionOriented;
    581 
    582          }
    583          else if(((psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
    584                   || (psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketAccepted))
    585                   && ((psTransport->pSocketTable[index].socket_sSap == ssap)&&(psTransport->pSocketTable[index].socket_dSap == dsap)))
    586 
    587          {
    588             socketFound = FALSE;
    589 
    590             if(pLlcpSocket != NULL)
    591             {
    592                /* Reset Socket Information */
    593                pLlcpSocket->remoteMIU = 0;
    594                pLlcpSocket->remoteRW  = 0;
    595 
    596                /* Set SSAP/DSAP of the new socket created for the communication with the remote */
    597                pLlcpSocket->socket_dSap = 0;
    598                pLlcpSocket->socket_sSap = 0;
    599 
    600                /* Set the state and the type of the new socket */
    601                pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDefault;
    602                pLlcpSocket->eSocket_Type  = phFriNfc_LlcpTransport_eDefaultType;
    603                break;
    604             }
    605          }
    606       }
    607 
    608 
    609 
    610       /* Test if a socket has been found */
    611       if(socketFound)
    612       {
    613          /* Call the Listen CB */
    614          pListen_Cb(pListenContext,pLlcpSocket);
    615       }
    616       else
    617       {
    618          /* No more socket are available */
    619          /* Send a DM (0x21) */
    620          status = phFriNfc_LlcpTransport_SendDisconnectMode (psTransport,
    621                                                              ssap,
    622                                                              dsap,
    623                                                              PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE);
    624       }
    625    }
    626    else
    627    {
    628       /* Service Name not found or Port number not found */
    629       /* Send a DM (0x02) */
    630       status = phFriNfc_LlcpTransport_SendDisconnectMode (psTransport,
    631                                                           ssap,
    632                                                           dsap,
    633                                                           PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND);
    634    }
    635 }
    636 
    637 /* TODO: comment function Handle_ConnectFrame */
    638 static void Handle_ConnectionCompleteFrame(phFriNfc_LlcpTransport_t      *psTransport,
    639                                            phNfc_sData_t                 *psData,
    640                                            uint8_t                       dsap,
    641                                            uint8_t                       ssap)
    642 {
    643    NFCSTATUS                          status = NFCSTATUS_SUCCESS;
    644    uint8_t                            index;
    645    uint8_t                            remoteRW  = PHFRINFC_LLCP_RW_DEFAULT;
    646    uint16_t                           remoteMIU = PHFRINFC_LLCP_MIU_DEFAULT;
    647    uint8_t                            socketFound = FALSE;
    648    phFriNfc_LlcpTransport_Socket_t*   psLocalLlcpSocket = NULL;
    649 
    650    status = phFriNfc_Llcp_GetSocket_Params(psData,
    651                                            NULL,
    652                                            &remoteRW,
    653                                            &remoteMIU);
    654 
    655    if(status != NFCSTATUS_SUCCESS)
    656    {
    657       /* Incorrect TLV */
    658       /* send FRMR */
    659       status  = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
    660                                                        dsap,
    661                                                        PHFRINFC_LLCP_PTYPE_CC,
    662                                                        ssap,
    663                                                        0x00,
    664                                                        0x00,
    665                                                        0x00,
    666                                                        0x00,
    667                                                        0x00,
    668                                                        0x00,
    669                                                        0x00,
    670                                                        0x00,
    671                                                        0x00);
    672    }
    673    else
    674    {
    675       /* Search a socket in connecting state and with the good SSAP */
    676       for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
    677       {
    678          /* Test if the socket is in Connecting state and if its SSAP number is the good one */
    679          if(psTransport->pSocketTable[index].eSocket_State  == phFriNfc_LlcpTransportSocket_eSocketConnecting
    680             && psTransport->pSocketTable[index].socket_sSap == dsap)
    681          {
    682             /* socket with the SN found */
    683             socketFound = TRUE;
    684 
    685             /* Update the DSAP value with the incomming Socket sSap */
    686             psTransport->pSocketTable[index].socket_dSap = ssap;
    687 
    688             /* Store a pointer to the socket found */
    689             psLocalLlcpSocket = &psTransport->pSocketTable[index];
    690             break;
    691          }
    692       }
    693       /* Test if a socket has been found */
    694       if(socketFound)
    695       {
    696          /* Set the socket state to connected */
    697          psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnected;
    698 
    699          /* Reset the socket_VS,socket_VR,socket_VSA and socket_VRA variables */
    700          psLocalLlcpSocket->socket_VR  = 0;
    701          psLocalLlcpSocket->socket_VRA = 0;
    702          psLocalLlcpSocket->socket_VS  = 0;
    703          psLocalLlcpSocket->socket_VSA = 0;
    704 
    705          /* Store the Remote parameters (MIU,RW) */
    706          psLocalLlcpSocket->remoteMIU  = remoteMIU;
    707          psLocalLlcpSocket->remoteRW   = remoteRW;
    708 
    709          /* Call the Connect CB and reset callback info */
    710          psLocalLlcpSocket->pfSocketConnect_Cb(psLocalLlcpSocket->pConnectContext,0x00,NFCSTATUS_SUCCESS);
    711          psLocalLlcpSocket->pfSocketConnect_Cb = NULL;
    712          psLocalLlcpSocket->pConnectContext = NULL;
    713       }
    714       else
    715       {
    716          /* No socket Active */
    717          /* CC Frame not handled */
    718       }
    719    }
    720 }
    721 
    722 /* TODO: comment function Handle_DisconnectFrame */
    723 static void Handle_DisconnectFrame(phFriNfc_LlcpTransport_t      *psTransport,
    724                                    uint8_t                       dsap,
    725                                    uint8_t                       ssap)
    726 {
    727    NFCSTATUS   status = NFCSTATUS_SUCCESS;
    728    uint8_t     index;
    729    uint8_t     socketFound = FALSE;
    730    phFriNfc_LlcpTransport_Socket_t*   psLocalLlcpSocket = NULL;
    731 
    732    /* Search a socket in connected state and the good SSAP */
    733    for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
    734    {
    735       /* Test if the socket is in Connected state and if its SSAP number is the good one */
    736       if(psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected
    737          && psTransport->pSocketTable[index].socket_sSap == dsap)
    738       {
    739          /* socket found */
    740          socketFound = TRUE;
    741 
    742          /* Store a pointer to the socket found */
    743          psLocalLlcpSocket = &psTransport->pSocketTable[index];
    744          break;
    745       }
    746    }
    747 
    748    /* Test if a socket has been found */
    749    if(socketFound)
    750    {
    751       /* Test if a send IFRAME is pending with this socket */
    752       if((psLocalLlcpSocket->bSocketSendPending == TRUE) || (psLocalLlcpSocket->bSocketRecvPending == TRUE))
    753       {
    754          /* Call the send CB, a disconnect abort the send request */
    755          if (psLocalLlcpSocket->pfSocketSend_Cb != NULL && psLocalLlcpSocket->bSocketSendPending == TRUE)
    756          {
    757             /* Copy CB + context in local variables */
    758             pphFriNfc_LlcpTransportSocketSendCb_t  pfSendCb = psLocalLlcpSocket->pfSocketSend_Cb;
    759             void*                                  pSendContext = psLocalLlcpSocket->pSendContext;
    760             /* Reset CB + context */
    761             psLocalLlcpSocket->pfSocketSend_Cb = NULL;
    762             psLocalLlcpSocket->pSendContext = NULL;
    763             /* Perform callback */
    764             pfSendCb(pSendContext, NFCSTATUS_FAILED);
    765          }
    766          /* Call the send CB, a disconnect abort the receive request */
    767          if (psLocalLlcpSocket->pfSocketRecv_Cb != NULL && psLocalLlcpSocket->bSocketRecvPending == TRUE)
    768          {
    769             /* Copy CB + context in local variables */
    770             pphFriNfc_LlcpTransportSocketRecvCb_t  pfRecvCb = psLocalLlcpSocket->pfSocketRecv_Cb;
    771             void*                                  pRecvContext = psLocalLlcpSocket->pRecvContext;
    772             /* Reset CB + context */
    773             psLocalLlcpSocket->pfSocketRecv_Cb = NULL;
    774             psLocalLlcpSocket->pRecvContext = NULL;
    775             /* Perform callback */
    776             pfRecvCb(pRecvContext, NFCSTATUS_FAILED);
    777          }
    778          psLocalLlcpSocket->bSocketRecvPending = FALSE;
    779          psLocalLlcpSocket->bSocketSendPending = FALSE;
    780       }
    781 
    782       /* Update the socket state */
    783       psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
    784 
    785       /* Send a DM*/
    786       /* TODO: use a socket internal flag to save */
    787       status = phFriNfc_LlcpTransport_SendDisconnectMode(psTransport,
    788                                                          ssap,
    789                                                          dsap,
    790                                                          PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED);
    791 
    792       /* Call ErrCB due to a DISC */
    793       psTransport->pSocketTable[index].pSocketErrCb(psTransport->pSocketTable[index].pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
    794    }
    795    else
    796    {
    797       /* No socket Active */
    798       /* DISC Frame not handled */
    799    }
    800 }
    801 
    802 /* TODO: comment function Handle_ConnectFrame */
    803 static void Handle_DisconnetModeFrame(phFriNfc_LlcpTransport_t      *psTransport,
    804                                       phNfc_sData_t                 *psData,
    805                                       uint8_t                       dsap,
    806                                       uint8_t                       ssap)
    807 {
    808    NFCSTATUS                           status = NFCSTATUS_SUCCESS;
    809    uint8_t                             index;
    810    uint8_t                             socketFound = FALSE;
    811    uint8_t                             dmOpCode;
    812    phFriNfc_LlcpTransport_Socket_t     *psLocalLlcpSocket = NULL;
    813 
    814    /* Test if the DM buffer is correct */
    815    if(psData->length != PHFRINFC_LLCP_DM_LENGTH)
    816    {
    817       /* send FRMR */
    818       status  = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
    819                                                        dsap,
    820                                                        PHFRINFC_LLCP_PTYPE_DM,
    821                                                        ssap,
    822                                                        0x00,
    823                                                        0x00,
    824                                                        0x00,
    825                                                        0x00,
    826                                                        0x00,
    827                                                        0x00,
    828                                                        0x00,
    829                                                        0x00,
    830                                                        0x00);
    831    }
    832    else
    833    {
    834       /* Search a socket waiting for a DM (Disconnecting State) */
    835       for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
    836       {
    837          /* Test if the socket is in Disconnecting  or connecting state and if its SSAP number is the good one */
    838          if((psTransport->pSocketTable[index].eSocket_State   == phFriNfc_LlcpTransportSocket_eSocketDisconnecting
    839             || psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnecting)
    840             && psTransport->pSocketTable[index].socket_sSap   == dsap)
    841          {
    842             /* socket found */
    843             socketFound = TRUE;
    844 
    845             /* Store a pointer to the socket found */
    846             psLocalLlcpSocket = &psTransport->pSocketTable[index];
    847             break;
    848          }
    849       }
    850 
    851       /* Test if a socket has been found */
    852       if(socketFound)
    853       {
    854          /* Set dmOpcode */
    855          dmOpCode = psData->buffer[0];
    856 
    857          switch(dmOpCode)
    858          {
    859          case PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED:
    860             {
    861                /* Set the socket state to disconnected */
    862                psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
    863 
    864                /* Call Disconnect CB */
    865                if (psLocalLlcpSocket->pfSocketDisconnect_Cb != NULL)
    866                {
    867                   psLocalLlcpSocket->pfSocketDisconnect_Cb(psLocalLlcpSocket->pDisconnectContext,NFCSTATUS_SUCCESS);
    868                   psLocalLlcpSocket->pfSocketDisconnect_Cb = NULL;
    869                }
    870 
    871             }break;
    872 
    873          case PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED:
    874          case PHFRINFC_LLCP_DM_OPCODE_CONNECT_NOT_ACCEPTED:
    875          case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_ACTIVE:
    876          case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND:
    877          case PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE:
    878             {
    879                /* Set the socket state to bound */
    880                psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
    881                if(psLocalLlcpSocket->pfSocketConnect_Cb != NULL)
    882                {
    883                   /* Call Connect CB */
    884                   psLocalLlcpSocket->pfSocketConnect_Cb(psLocalLlcpSocket->pConnectContext,dmOpCode,NFCSTATUS_FAILED);
    885                   psLocalLlcpSocket->pfSocketConnect_Cb = NULL;
    886                }
    887             }break;
    888          }
    889       }
    890    }
    891 }
    892 
    893 /* TODO: comment function Handle_Receive_IFrame */
    894 static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t      *psTransport,
    895                                   phNfc_sData_t                 *psData,
    896                                   uint8_t                       dsap,
    897                                   uint8_t                       ssap)
    898 {
    899    NFCSTATUS   status = NFCSTATUS_SUCCESS;
    900 
    901    phFriNfc_LlcpTransport_Socket_t*    psLocalLlcpSocket = NULL;
    902    phFriNfc_Llcp_sPacketSequence_t    sLlcpLocalSequence;
    903 
    904    uint32_t    dataLengthAvailable = 0;
    905    uint32_t    dataLengthWrite = 0;
    906    uint8_t     index;
    907    uint8_t     socketFound = FALSE;
    908    uint8_t     WFlag = 0;
    909    uint8_t     IFlag = 0;
    910    uint8_t     RFlag = 0;
    911    uint8_t     SFlag = 0;
    912    uint8_t     nr_val;
    913    uint32_t    offset = 0;
    914    uint32_t    rw_offset;
    915 
    916    /* Get NS and NR Value of the I Frame*/
    917    phFriNfc_Llcp_Buffer2Sequence( psData->buffer, offset, &sLlcpLocalSequence);
    918 
    919 
    920    /* Update the buffer pointer */
    921    psData->buffer = psData->buffer + PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;
    922 
    923    /* Update the length value (without the header length) */
    924    psData->length = psData->length - PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;
    925 
    926    /* Search a socket waiting for an I FRAME (Connected State) */
    927    for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
    928    {
    929       /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
    930       if((  (psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
    931          || (psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketAccepted))
    932          && psTransport->pSocketTable[index].socket_sSap == dsap
    933          && psTransport->pSocketTable[index].socket_dSap == ssap)
    934       {
    935          /* socket found */
    936          socketFound = TRUE;
    937 
    938          /* Store a pointer to the socket found */
    939          psLocalLlcpSocket = &psTransport->pSocketTable[index];
    940          break;
    941       }
    942    }
    943 
    944    /* Test if a socket has been found */
    945    if(socketFound)
    946    {
    947       /* Test NS */
    948       /*if(sLlcpLocalSequence.ns != psLocalLlcpSocket->socket_VR)
    949       {
    950          SFlag = TRUE;
    951       }*/
    952 
    953       /* Calculate offset of current frame in RW, and check validity */
    954       if(sLlcpLocalSequence.ns >= psLocalLlcpSocket->socket_VRA)
    955       {
    956          rw_offset = sLlcpLocalSequence.ns - psLocalLlcpSocket->socket_VRA;
    957       }
    958       else
    959       {
    960          rw_offset = 16 - (psLocalLlcpSocket->socket_VRA - sLlcpLocalSequence.ns);
    961       }
    962       if(rw_offset >= psLocalLlcpSocket->localRW)
    963       {
    964          /* FRMR 0x01 */
    965          SFlag = TRUE;
    966       }
    967 
    968       /* Check Info length */
    969       if(psData->length > (uint32_t)(psLocalLlcpSocket->localMIUX + PHFRINFC_LLCP_MIU_DEFAULT))
    970       {
    971          IFlag = TRUE;
    972       }
    973 
    974 
    975       /* Test NR */
    976       nr_val = (uint8_t)sLlcpLocalSequence.nr;
    977       do
    978       {
    979          if(nr_val == psLocalLlcpSocket->socket_VS)
    980          {
    981             break;
    982          }
    983 
    984          nr_val = (nr_val+1)%16;
    985 
    986          if(nr_val == psLocalLlcpSocket->socket_VSA)
    987          {
    988             /* FRMR 0x02 */
    989             RFlag = TRUE;
    990             break;
    991          }
    992       }while(nr_val != sLlcpLocalSequence.nr);
    993 
    994 
    995       if( WFlag != 0 || IFlag != 0 || RFlag != 0 || SFlag != 0)
    996       {
    997          /* Send FRMR */
    998          status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
    999                                                          dsap,
   1000                                                          PHFRINFC_LLCP_PTYPE_I,
   1001                                                          ssap,
   1002                                                          &sLlcpLocalSequence,
   1003                                                          WFlag,
   1004                                                          IFlag,
   1005                                                          RFlag,
   1006                                                          SFlag,
   1007                                                          psLocalLlcpSocket->socket_VS,
   1008                                                          psLocalLlcpSocket->socket_VSA,
   1009                                                          psLocalLlcpSocket->socket_VR,
   1010                                                          psLocalLlcpSocket->socket_VRA);
   1011 
   1012       }
   1013       else
   1014       {
   1015         /* Update VSA */
   1016         psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
   1017 
   1018         /* Test if the Linear Buffer length is null */
   1019         if(psLocalLlcpSocket->bufferLinearLength == 0)
   1020         {
   1021             /* Test if a Receive is pending and RW empty */
   1022             if(psLocalLlcpSocket->bSocketRecvPending == TRUE && (psLocalLlcpSocket->indexRwWrite == psLocalLlcpSocket->indexRwRead))
   1023             {
   1024                /* Reset Flag */
   1025                psLocalLlcpSocket->bSocketRecvPending = FALSE;
   1026 
   1027                /* Save I_FRAME into the Receive Buffer */
   1028                memcpy(psLocalLlcpSocket->sSocketRecvBuffer->buffer,psData->buffer,psData->length);
   1029                psLocalLlcpSocket->sSocketRecvBuffer->length = psData->length;
   1030 
   1031                /* Update VR */
   1032                psLocalLlcpSocket->socket_VR = (psLocalLlcpSocket->socket_VR+1)%16;
   1033 
   1034                /* Call the Receive CB */
   1035                psLocalLlcpSocket->pfSocketRecv_Cb(psLocalLlcpSocket->pRecvContext, NFCSTATUS_SUCCESS);
   1036                psLocalLlcpSocket->pfSocketRecv_Cb = NULL;
   1037 
   1038                /* Test if a send is pending with this socket */
   1039                if(psLocalLlcpSocket->bSocketSendPending == TRUE && CHECK_SEND_RW(psLocalLlcpSocket))
   1040                {
   1041                   /* Test if a send is pending at LLC layer */
   1042                   if(!testAndSetSendPending(psLocalLlcpSocket->psTransport))
   1043                   {
   1044                      status = static_performSendInfo(psLocalLlcpSocket);
   1045                      if (status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING) {
   1046                          clearSendPending(psTransport);
   1047                      }
   1048                   }
   1049                }
   1050                else
   1051                {
   1052                   /* RR */
   1053                   status = phFriNfc_Llcp_Send_ReceiveReady_Frame(psLocalLlcpSocket);
   1054                }
   1055             }
   1056             else
   1057             {
   1058                /* Test if RW is full */
   1059                if((psLocalLlcpSocket->indexRwWrite - psLocalLlcpSocket->indexRwRead)<psLocalLlcpSocket->localRW)
   1060                {
   1061                   if(psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length == 0)
   1062                   {
   1063                      /* Save I_FRAME into the RW Buffers */
   1064                      memcpy(psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].buffer,psData->buffer,psData->length);
   1065                      psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = psData->length;
   1066 
   1067                      if(psLocalLlcpSocket->ReceiverBusyCondition != TRUE)
   1068                      {
   1069                         /* Receiver Busy condition */
   1070                         psLocalLlcpSocket->ReceiverBusyCondition = TRUE;
   1071 
   1072                         /* Send RNR */
   1073                         status = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(psLocalLlcpSocket);
   1074                      }
   1075                      /* Update the RW write index */
   1076                      psLocalLlcpSocket->indexRwWrite++;
   1077                   }
   1078                }
   1079             }
   1080         }
   1081         else
   1082         {
   1083            /* Copy the buffer into the RW buffer */
   1084            memcpy(psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].buffer,psData->buffer,psData->length);
   1085 
   1086            /* Update the length */
   1087            psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = psData->length;
   1088 
   1089            /* Test the length of the available place in the linear buffer */
   1090            dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&psLocalLlcpSocket->sCyclicFifoBuffer);
   1091 
   1092            if(dataLengthAvailable >= psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length)
   1093            {
   1094               /* Store Data into the linear buffer */
   1095               dataLengthWrite = phFriNfc_Llcp_CyclicFifoWrite(&psLocalLlcpSocket->sCyclicFifoBuffer,
   1096                                                               psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].buffer,
   1097                                                               psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length);
   1098 
   1099               /* Update VR */
   1100               psLocalLlcpSocket->socket_VR = (psLocalLlcpSocket->socket_VR+1)%16;
   1101 
   1102               /* Update the length */
   1103               psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = 0x00;
   1104 
   1105               /* Test if a Receive Pending*/
   1106               if(psLocalLlcpSocket->bSocketRecvPending == TRUE)
   1107               {
   1108                  /* Reset Flag */
   1109                  psLocalLlcpSocket->bSocketRecvPending = FALSE;
   1110 
   1111                  phFriNfc_LlcpTransport_ConnectionOriented_Recv(psLocalLlcpSocket,
   1112                                                                 psLocalLlcpSocket->sSocketRecvBuffer,
   1113                                                                 psLocalLlcpSocket->pfSocketRecv_Cb,
   1114                                                                 psLocalLlcpSocket->pRecvContext);
   1115               }
   1116 
   1117               /* Test if a send is pending with this socket */
   1118               if((psLocalLlcpSocket->bSocketSendPending == TRUE) && CHECK_SEND_RW(psLocalLlcpSocket))
   1119               {
   1120                  /* Test if a send is pending at LLC layer */
   1121                  if(!testAndSetSendPending(psLocalLlcpSocket->psTransport))
   1122                  {
   1123                     status = static_performSendInfo(psLocalLlcpSocket);
   1124                     if (status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING) {
   1125                         clearSendPending(psTransport);
   1126                     }
   1127                  }
   1128               }
   1129               else
   1130               {
   1131                  /* RR */
   1132                  status = phFriNfc_Llcp_Send_ReceiveReady_Frame(psLocalLlcpSocket);
   1133               }
   1134            }
   1135            else
   1136            {
   1137                if(psLocalLlcpSocket->ReceiverBusyCondition != TRUE)
   1138                {
   1139                   /* Receiver Busy condition */
   1140                   psLocalLlcpSocket->ReceiverBusyCondition = TRUE;
   1141 
   1142                   /* Send RNR */
   1143                   status = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(psLocalLlcpSocket);
   1144                }
   1145 
   1146               /* Update the RW write index */
   1147               psLocalLlcpSocket->indexRwWrite++;
   1148            }
   1149          }
   1150       }
   1151    }
   1152    else
   1153    {
   1154       /* No active  socket*/
   1155       /* I FRAME not Handled */
   1156    }
   1157 }
   1158 
   1159 static void Handle_ReceiveReady_Frame(phFriNfc_LlcpTransport_t      *psTransport,
   1160                                       phNfc_sData_t                 *psData,
   1161                                       uint8_t                       dsap,
   1162                                       uint8_t                       ssap)
   1163 {
   1164    NFCSTATUS   status = NFCSTATUS_SUCCESS;
   1165    uint8_t     index;
   1166    uint8_t     socketFound = FALSE;
   1167    uint8_t      WFlag = 0;
   1168    uint8_t      IFlag = 0;
   1169    uint8_t      RFlag = 0;
   1170    uint8_t      SFlag = 0;
   1171    uint32_t     offset = 0;
   1172    uint8_t      nr_val;
   1173 
   1174    phFriNfc_LlcpTransport_Socket_t*   psLocalLlcpSocket = NULL;
   1175    phFriNfc_Llcp_sPacketSequence_t    sLlcpLocalSequence;
   1176 
   1177    /* Get NS and NR Value of the I Frame*/
   1178    phFriNfc_Llcp_Buffer2Sequence( psData->buffer, offset, &sLlcpLocalSequence);
   1179 
   1180    /* Search a socket waiting for an RR FRAME (Connected State) */
   1181    for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
   1182    {
   1183       /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
   1184       if(psTransport->pSocketTable[index].eSocket_State  == phFriNfc_LlcpTransportSocket_eSocketConnected
   1185          && psTransport->pSocketTable[index].socket_sSap == dsap
   1186          && psTransport->pSocketTable[index].socket_dSap == ssap)
   1187       {
   1188          /* socket found */
   1189          socketFound = TRUE;
   1190 
   1191          /* Store a pointer to the socket found */
   1192          psLocalLlcpSocket = &psTransport->pSocketTable[index];
   1193          psLocalLlcpSocket->index = psTransport->pSocketTable[index].index;
   1194          break;
   1195       }
   1196    }
   1197 
   1198    /* Test if a socket has been found */
   1199    if(socketFound)
   1200    {
   1201       /* Test NR */
   1202       nr_val = (uint8_t)sLlcpLocalSequence.nr;
   1203       do
   1204       {
   1205          if(nr_val == psLocalLlcpSocket->socket_VS)
   1206          {
   1207             break;
   1208          }
   1209 
   1210          nr_val = (nr_val+1)%16;
   1211 
   1212          if(nr_val == psLocalLlcpSocket->socket_VSA)
   1213          {
   1214             RFlag = TRUE;
   1215             break;
   1216          }
   1217 
   1218       }while(nr_val != sLlcpLocalSequence.nr);
   1219 
   1220 
   1221       /* Test if Info field present */
   1222       if(psData->length > 1)
   1223       {
   1224          WFlag = TRUE;
   1225          IFlag = TRUE;
   1226       }
   1227 
   1228       if (WFlag || IFlag || RFlag || SFlag)
   1229       {
   1230          /* Send FRMR */
   1231          status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
   1232                                                          dsap, PHFRINFC_LLCP_PTYPE_RR, ssap,
   1233                                                          &sLlcpLocalSequence,
   1234                                                          WFlag, IFlag, RFlag, SFlag,
   1235                                                          psLocalLlcpSocket->socket_VS,
   1236                                                          psLocalLlcpSocket->socket_VSA,
   1237                                                          psLocalLlcpSocket->socket_VR,
   1238                                                          psLocalLlcpSocket->socket_VRA);
   1239       }
   1240       else
   1241       {
   1242          /* Test Receiver Busy condition */
   1243          if(psLocalLlcpSocket->RemoteBusyConditionInfo == TRUE)
   1244          {
   1245             /* Notify the upper layer */
   1246             psLocalLlcpSocket->pSocketErrCb(psLocalLlcpSocket->pContext,PHFRINFC_LLCP_ERR_NOT_BUSY_CONDITION);
   1247             psLocalLlcpSocket->RemoteBusyConditionInfo = FALSE;
   1248          }
   1249          /* Update VSA */
   1250          psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
   1251 
   1252          /* Test if a send is pendind */
   1253          if(psLocalLlcpSocket->bSocketSendPending == TRUE)
   1254          {
   1255             /* Test the RW window */
   1256             if(CHECK_SEND_RW(psLocalLlcpSocket))
   1257             {
   1258                /* Test if a send is pending at LLC layer */
   1259                if(!testAndSetSendPending(psLocalLlcpSocket->psTransport))
   1260                {
   1261                   status = static_performSendInfo(psLocalLlcpSocket);
   1262                   if (status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING) {
   1263                       clearSendPending(psTransport);
   1264                   }
   1265                }
   1266             }
   1267          }
   1268       }
   1269    }
   1270    else
   1271    {
   1272       /* No active  socket*/
   1273       /* RR Frame not handled*/
   1274    }
   1275 }
   1276 
   1277 static void Handle_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_t      *psTransport,
   1278                                       phNfc_sData_t                    *psData,
   1279                                       uint8_t                          dsap,
   1280                                       uint8_t                          ssap)
   1281 {
   1282    NFCSTATUS   status = NFCSTATUS_SUCCESS;
   1283    uint8_t     index;
   1284    uint8_t     socketFound = FALSE;
   1285    bool_t      bWFlag = 0;
   1286    bool_t      bIFlag = 0;
   1287    bool_t      bRFlag = 0;
   1288    bool_t      bSFlag = 0;
   1289    uint32_t    offset = 0;
   1290    uint8_t     nr_val;
   1291 
   1292    phFriNfc_LlcpTransport_Socket_t*   psLocalLlcpSocket = NULL;
   1293    phFriNfc_Llcp_sPacketSequence_t   sLlcpLocalSequence;
   1294 
   1295    /* Get NS and NR Value of the I Frame*/
   1296    phFriNfc_Llcp_Buffer2Sequence( psData->buffer, offset, &sLlcpLocalSequence);
   1297 
   1298    /* Search a socket waiting for an RNR FRAME (Connected State) */
   1299    for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
   1300    {
   1301       /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
   1302       if(psTransport->pSocketTable[index].eSocket_State  == phFriNfc_LlcpTransportSocket_eSocketConnected
   1303          && psTransport->pSocketTable[index].socket_sSap == dsap
   1304          && psTransport->pSocketTable[index].socket_dSap == ssap)
   1305       {
   1306          /* socket found */
   1307          socketFound = TRUE;
   1308 
   1309          /* Store a pointer to the socket found */
   1310          psLocalLlcpSocket = &psTransport->pSocketTable[index];
   1311          break;
   1312       }
   1313    }
   1314 
   1315    /* Test if a socket has been found */
   1316    if(socketFound)
   1317    {
   1318       /* Test NR */
   1319       nr_val = (uint8_t)sLlcpLocalSequence.nr;
   1320       do
   1321       {
   1322 
   1323          if(nr_val == psLocalLlcpSocket->socket_VS)
   1324          {
   1325             break;
   1326          }
   1327 
   1328          nr_val = (nr_val+1)%16;
   1329 
   1330          if(nr_val == psLocalLlcpSocket->socket_VSA)
   1331          {
   1332             /* FRMR 0x02 */
   1333             bRFlag = TRUE;
   1334             break;
   1335          }
   1336       }while(nr_val != sLlcpLocalSequence.nr);
   1337 
   1338       /* Test if Info field present */
   1339       if(psData->length > 1)
   1340       {
   1341          /* Send FRMR */
   1342          bWFlag = TRUE;
   1343          bIFlag = TRUE;
   1344       }
   1345 
   1346       if( bWFlag != 0 || bIFlag != 0 || bRFlag != 0 || bSFlag != 0)
   1347       {
   1348          /* Send FRMR */
   1349          status = phFriNfc_LlcpTransport_SendFrameReject(psTransport,
   1350                                                          dsap, PHFRINFC_LLCP_PTYPE_RNR, ssap,
   1351                                                          &sLlcpLocalSequence,
   1352                                                          bWFlag, bIFlag, bRFlag, bSFlag,
   1353                                                          psLocalLlcpSocket->socket_VS,
   1354                                                          psLocalLlcpSocket->socket_VSA,
   1355                                                          psLocalLlcpSocket->socket_VR,
   1356                                                          psLocalLlcpSocket->socket_VRA);
   1357       }
   1358       else
   1359       {
   1360          /* Notify the upper layer */
   1361          psLocalLlcpSocket->pSocketErrCb(psTransport->pSocketTable[index].pContext,PHFRINFC_LLCP_ERR_BUSY_CONDITION);
   1362          psLocalLlcpSocket->RemoteBusyConditionInfo = TRUE;
   1363 
   1364          /* Update VSA */
   1365          psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
   1366 
   1367          /* Test if a send is pendind */
   1368          if(psLocalLlcpSocket->bSocketSendPending == TRUE && CHECK_SEND_RW(psLocalLlcpSocket))
   1369          {
   1370             /* Test if a send is pending at LLC layer */
   1371             if(!testAndSetSendPending(psLocalLlcpSocket->psTransport))
   1372             {
   1373                status = static_performSendInfo(psLocalLlcpSocket);
   1374                if (status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING) {
   1375                    clearSendPending(psTransport);
   1376                }
   1377             }
   1378          }
   1379       }
   1380    }
   1381    else
   1382    {
   1383       /* No active  socket*/
   1384       /* RNR Frame not handled*/
   1385    }
   1386 }
   1387 
   1388 static void Handle_FrameReject_Frame(phFriNfc_LlcpTransport_t      *psTransport,
   1389                                      uint8_t                       dsap,
   1390                                      uint8_t                       ssap)
   1391 {
   1392    NFCSTATUS   status = NFCSTATUS_SUCCESS;
   1393    uint8_t     index;
   1394    uint8_t     socketFound = FALSE;
   1395 
   1396    /* Search a socket waiting for a FRAME */
   1397    for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
   1398    {
   1399       /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
   1400       if(psTransport->pSocketTable[index].socket_sSap == dsap
   1401          && psTransport->pSocketTable[index].socket_dSap == ssap)
   1402       {
   1403          /* socket found */
   1404          socketFound = TRUE;
   1405          break;
   1406       }
   1407    }
   1408 
   1409    /* Test if a socket has been found */
   1410    if(socketFound)
   1411    {
   1412       /* Set socket state to disconnected */
   1413       psTransport->pSocketTable[index].eSocket_State =  phFriNfc_LlcpTransportSocket_eSocketDisconnected;
   1414 
   1415       /* Call ErrCB due to a FRMR*/
   1416       psTransport->pSocketTable[index].pSocketErrCb( psTransport->pSocketTable[index].pContext,PHFRINFC_LLCP_ERR_FRAME_REJECTED);
   1417 
   1418       /* Close the socket */
   1419       status = phFriNfc_LlcpTransport_ConnectionOriented_Close(&psTransport->pSocketTable[index]);
   1420    }
   1421    else
   1422    {
   1423       /* No active  socket*/
   1424       /* FRMR Frame not handled*/
   1425    }
   1426 }
   1427 
   1428 /* TODO: comment function Handle_ConnectionOriented_IncommingFrame */
   1429 void Handle_ConnectionOriented_IncommingFrame(phFriNfc_LlcpTransport_t           *psTransport,
   1430                                               phNfc_sData_t                      *psData,
   1431                                               uint8_t                            dsap,
   1432                                               uint8_t                            ptype,
   1433                                               uint8_t                            ssap)
   1434 {
   1435    phFriNfc_Llcp_sPacketSequence_t  sSequence = {0,0};
   1436 
   1437    switch(ptype)
   1438    {
   1439       case PHFRINFC_LLCP_PTYPE_CONNECT:
   1440          {
   1441             Handle_ConnectionFrame(psTransport,
   1442                                    psData,
   1443                                    dsap,
   1444                                    ssap);
   1445          }break;
   1446 
   1447       case PHFRINFC_LLCP_PTYPE_DISC:
   1448          {
   1449             Handle_DisconnectFrame(psTransport,
   1450                                    dsap,
   1451                                    ssap);
   1452          }break;
   1453 
   1454       case PHFRINFC_LLCP_PTYPE_CC:
   1455          {
   1456             Handle_ConnectionCompleteFrame(psTransport,
   1457                                            psData,
   1458                                            dsap,
   1459                                            ssap);
   1460          }break;
   1461 
   1462       case PHFRINFC_LLCP_PTYPE_DM:
   1463          {
   1464             Handle_DisconnetModeFrame(psTransport,
   1465                                       psData,
   1466                                       dsap,
   1467                                       ssap);
   1468          }break;
   1469 
   1470       case PHFRINFC_LLCP_PTYPE_FRMR:
   1471          {
   1472             Handle_FrameReject_Frame(psTransport,
   1473                                      dsap,
   1474                                      ssap);
   1475          }break;
   1476 
   1477       case PHFRINFC_LLCP_PTYPE_I:
   1478          {
   1479             Handle_Receive_IFrame(psTransport,
   1480                                   psData,
   1481                                   dsap,
   1482                                   ssap);
   1483          }break;
   1484 
   1485       case PHFRINFC_LLCP_PTYPE_RR:
   1486          {
   1487             Handle_ReceiveReady_Frame(psTransport,
   1488                                       psData,
   1489                                       dsap,
   1490                                       ssap);
   1491          }break;
   1492 
   1493       case PHFRINFC_LLCP_PTYPE_RNR:
   1494          {
   1495             Handle_ReceiveNotReady_Frame(psTransport,
   1496                                          psData,
   1497                                          dsap,
   1498                                          ssap);
   1499          }break;
   1500 
   1501       case PHFRINFC_LLCP_PTYPE_RESERVED1:
   1502       case PHFRINFC_LLCP_PTYPE_RESERVED2:
   1503       case PHFRINFC_LLCP_PTYPE_RESERVED3:
   1504          {
   1505             phFriNfc_LlcpTransport_SendFrameReject( psTransport,
   1506                                                     dsap, ptype, ssap,
   1507                                                     &sSequence,
   1508                                                     TRUE, FALSE, FALSE, FALSE,
   1509                                                     0, 0, 0, 0);
   1510          }break;
   1511    }
   1512 }
   1513 
   1514 /**
   1515 * \ingroup grp_lib_nfc
   1516 * \brief <b>Get the local options of a socket</b>.
   1517 *
   1518 * This function returns the local options (maximum packet size and receive window size) used
   1519 * for a given connection-oriented socket. This function shall not be used with connectionless
   1520 * sockets.
   1521 *
   1522 * \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
   1523 * \param[in]  psLocalOptions        A pointer to be filled with the local options of the socket.
   1524 *
   1525 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1526 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1527 *                                            could not be properly interpreted.
   1528 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   1529 *                                            a valid type to perform the requsted operation.
   1530 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
   1531 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
   1532 * \retval NFCSTATUS_FAILED                   Operation failed.
   1533 */
   1534 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetLocalOptions(phFriNfc_LlcpTransport_Socket_t  *pLlcpSocket,
   1535                                                                           phLibNfc_Llcp_sSocketOptions_t   *psLocalOptions)
   1536 {
   1537    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1538 
   1539    /* Get Local MIUX */
   1540    psLocalOptions->miu = pLlcpSocket->sSocketOption.miu;
   1541 
   1542    /* Get Local Receive Window */
   1543    psLocalOptions->rw = pLlcpSocket->sSocketOption.rw;
   1544 
   1545    return status;
   1546 }
   1547 
   1548 /**
   1549 * \ingroup grp_lib_nfc
   1550 * \brief <b>Get the local options of a socket</b>.
   1551 *
   1552 * This function returns the remote options (maximum packet size and receive window size) used
   1553 * for a given connection-oriented socket. This function shall not be used with connectionless
   1554 * sockets.
   1555 *
   1556 * \param[out] pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
   1557 * \param[in]  psRemoteOptions       A pointer to be filled with the remote options of the socket.
   1558 *
   1559 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1560 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1561 *                                            could not be properly interpreted.
   1562 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   1563 *                                            a valid type to perform the requsted operation.
   1564 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
   1565 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
   1566 * \retval NFCSTATUS_FAILED                   Operation failed.
   1567 */
   1568 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket,
   1569                                                                            phLibNfc_Llcp_sSocketOptions_t*    psRemoteOptions)
   1570 {
   1571    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1572 
   1573    /* Get Remote MIUX */
   1574    psRemoteOptions->miu = pLlcpSocket->remoteMIU;
   1575 
   1576    /* Get Remote  Receive Window */
   1577    psRemoteOptions->rw = pLlcpSocket->remoteRW;
   1578 
   1579    return status;
   1580 }
   1581 
   1582 
   1583 /**
   1584 * \ingroup grp_fri_nfc
   1585 * \brief <b>Listen for incoming connection requests on a socket</b>.
   1586 *
   1587 * This function switches a socket into a listening state and registers a callback on
   1588 * incoming connection requests. In this state, the socket is not able to communicate
   1589 * directly. The listening state is only available for connection-oriented sockets
   1590 * which are still not connected. The socket keeps listening until it is closed, and
   1591 * thus can trigger several times the pListen_Cb callback.
   1592 *
   1593 *
   1594 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
   1595 * \param[in]  pListen_Cb         The callback to be called each time the
   1596 *                                socket receive a connection request.
   1597 * \param[in]  pContext           Upper layer context to be returned in
   1598 *                                the callback.
   1599 *
   1600 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1601 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1602 *                                            could not be properly interpreted.
   1603 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state to switch
   1604 *                                            to listening state.
   1605 * \retval NFCSTATUS_FAILED                   Operation failed.
   1606 */
   1607 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Listen(phFriNfc_LlcpTransport_Socket_t*          pLlcpSocket,
   1608                                                            pphFriNfc_LlcpTransportSocketListenCb_t   pListen_Cb,
   1609                                                            void*                                     pContext)
   1610 {
   1611    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1612    uint8_t   index;
   1613 
   1614    /* Store the listen callback */
   1615    pLlcpSocket->pfSocketListen_Cb = pListen_Cb;
   1616 
   1617    /* store the context */
   1618    pLlcpSocket->pListenContext = pContext;
   1619 
   1620    /* Set RecvPending to TRUE */
   1621    pLlcpSocket->bSocketListenPending = TRUE;
   1622 
   1623    /* Set the socket state*/
   1624    pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketRegistered;
   1625 
   1626    return status;
   1627 }
   1628 
   1629 /**
   1630 * \ingroup grp_fri_nfc
   1631 * \brief <b>Accept an incoming connection request for a socket</b>.
   1632 *
   1633 * This functions allows the client to accept an incoming connection request.
   1634 * It must be used with the socket provided within the listen callback. The socket
   1635 * is implicitly switched to the connected state when the function is called.
   1636 *
   1637 * \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
   1638 * \param[in]  psOptions             The options to be used with the socket.
   1639 * \param[in]  psWorkingBuffer       A working buffer to be used by the library.
   1640 * \param[in]  pErr_Cb               The callback to be called each time the accepted socket
   1641 *                                   is in error.
   1642 * \param[in]  pAccept_RspCb         The callback to be called when the Accept operation is completed
   1643 * \param[in]  pContext              Upper layer context to be returned in the callback.
   1644 *
   1645 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1646 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1647 *                                            could not be properly interpreted.
   1648 * \retval NFCSTATUS_BUFFER_TOO_SMALL         The working buffer is too small for the MIU and RW
   1649 *                                            declared in the options.
   1650 * \retval NFCSTATUS_FAILED                   Operation failed.
   1651 */
   1652 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Accept(phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
   1653                                                            phFriNfc_LlcpTransport_sSocketOptions_t*     psOptions,
   1654                                                            phNfc_sData_t*                               psWorkingBuffer,
   1655                                                            pphFriNfc_LlcpTransportSocketErrCb_t         pErr_Cb,
   1656                                                            pphFriNfc_LlcpTransportSocketAcceptCb_t      pAccept_RspCb,
   1657                                                            void*                                        pContext)
   1658 
   1659 {
   1660    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1661 
   1662    uint32_t offset = 0;
   1663    uint8_t miux[2];
   1664    uint8_t  i;
   1665    /* Store the options in the socket */
   1666    memcpy(&pLlcpSocket->sSocketOption, psOptions, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
   1667 
   1668    /* Set socket local params (MIUX & RW) */
   1669    pLlcpSocket ->localMIUX = (pLlcpSocket->sSocketOption.miu - PHFRINFC_LLCP_MIU_DEFAULT) & PHFRINFC_LLCP_TLV_MIUX_MASK;
   1670    pLlcpSocket ->localRW   = pLlcpSocket->sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK;
   1671 
   1672    /* Set the pointer and the length for the Receive Window Buffer */
   1673    for(i=0;i<pLlcpSocket->localRW;i++)
   1674    {
   1675       pLlcpSocket->sSocketRwBufferTable[i].buffer = psWorkingBuffer->buffer + (i*pLlcpSocket->sSocketOption.miu);
   1676       pLlcpSocket->sSocketRwBufferTable[i].length = 0;
   1677    }
   1678 
   1679    /* Set the pointer and the length for the Send Buffer */
   1680    pLlcpSocket->sSocketSendBuffer.buffer     = psWorkingBuffer->buffer + pLlcpSocket->bufferRwMaxLength;
   1681    pLlcpSocket->sSocketSendBuffer.length     = pLlcpSocket->bufferSendMaxLength;
   1682 
   1683    /* Set the pointer and the length for the Linear Buffer */
   1684    pLlcpSocket->sSocketLinearBuffer.buffer   = psWorkingBuffer->buffer + pLlcpSocket->bufferRwMaxLength + pLlcpSocket->bufferSendMaxLength;
   1685    pLlcpSocket->sSocketLinearBuffer.length   = pLlcpSocket->bufferLinearLength;
   1686 
   1687    if(pLlcpSocket->sSocketLinearBuffer.length != 0)
   1688    {
   1689       /* Init Cyclic Fifo */
   1690       phFriNfc_Llcp_CyclicFifoInit(&pLlcpSocket->sCyclicFifoBuffer,
   1691                                    pLlcpSocket->sSocketLinearBuffer.buffer,
   1692                                    pLlcpSocket->sSocketLinearBuffer.length);
   1693    }
   1694 
   1695    pLlcpSocket->pSocketErrCb            = pErr_Cb;
   1696    pLlcpSocket->pContext                = pContext;
   1697 
   1698    /* store the pointer to the Accept callback */
   1699    pLlcpSocket->pfSocketAccept_Cb   = pAccept_RspCb;
   1700    pLlcpSocket->pAcceptContext      = pContext;
   1701 
   1702    /* Reset the socket_VS,socket_VR,socket_VSA and socket_VRA variables */
   1703    pLlcpSocket->socket_VR  = 0;
   1704    pLlcpSocket->socket_VRA = 0;
   1705    pLlcpSocket->socket_VS  = 0;
   1706    pLlcpSocket->socket_VSA = 0;
   1707 
   1708    /* MIUX */
   1709    if(pLlcpSocket->localMIUX != PHFRINFC_LLCP_MIUX_DEFAULT)
   1710    {
   1711       /* Encode MIUX value */
   1712       phFriNfc_Llcp_EncodeMIUX(pLlcpSocket->localMIUX,
   1713                                miux);
   1714 
   1715       /* Encode MIUX in TLV format */
   1716       status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
   1717                                         &offset,
   1718                                         PHFRINFC_LLCP_TLV_TYPE_MIUX,
   1719                                         PHFRINFC_LLCP_TLV_LENGTH_MIUX,
   1720                                         miux);
   1721       if(status != NFCSTATUS_SUCCESS)
   1722       {
   1723          /* Call the CB */
   1724          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
   1725          goto clean_and_return;
   1726       }
   1727    }
   1728 
   1729    /* Receive Window */
   1730    if(pLlcpSocket->sSocketOption.rw != PHFRINFC_LLCP_RW_DEFAULT)
   1731    {
   1732       /* Encode RW value */
   1733       phFriNfc_Llcp_EncodeRW(&pLlcpSocket->sSocketOption.rw);
   1734 
   1735       /* Encode RW in TLV format */
   1736       status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
   1737                                         &offset,
   1738                                         PHFRINFC_LLCP_TLV_TYPE_RW,
   1739                                         PHFRINFC_LLCP_TLV_LENGTH_RW,
   1740                                         &pLlcpSocket->sSocketOption.rw);
   1741       if(status != NFCSTATUS_SUCCESS)
   1742       {
   1743          /* Call the CB */
   1744          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
   1745          goto clean_and_return;
   1746       }
   1747    }
   1748 
   1749 
   1750    /* Test if a send is pending */
   1751    if(testAndSetSendPending(pLlcpSocket->psTransport))
   1752    {
   1753       pLlcpSocket->bSocketAcceptPending = TRUE;
   1754 
   1755       /* Update Send Buffer length value */
   1756       pLlcpSocket->sSocketSendBuffer.length = offset;
   1757 
   1758       status = NFCSTATUS_PENDING;
   1759    }
   1760    else
   1761    {
   1762       /* Fill the psLlcpHeader stuture with the DSAP,CC PTYPE and the SSAP */
   1763       pLlcpSocket->sLlcpHeader.dsap  = pLlcpSocket->socket_dSap;
   1764       pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC;
   1765       pLlcpSocket->sLlcpHeader.ssap  = pLlcpSocket->socket_sSap;
   1766 
   1767       /* Set the socket state to accepted */
   1768       pLlcpSocket->eSocket_State           = phFriNfc_LlcpTransportSocket_eSocketAccepted;
   1769 
   1770       /* Update Send Buffer length value */
   1771       pLlcpSocket->sSocketSendBuffer.length = offset;
   1772 
   1773       /* Send a CC Frame */
   1774       status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
   1775                                    &pLlcpSocket->sLlcpHeader,
   1776                                    NULL,
   1777                                    &pLlcpSocket->sSocketSendBuffer,
   1778                                    phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
   1779                                    pLlcpSocket->index,
   1780                                    pLlcpSocket->psTransport);
   1781       if (status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING) {
   1782           clearSendPending(pLlcpSocket->psTransport);
   1783       }
   1784    }
   1785 
   1786 clean_and_return:
   1787    if(status != NFCSTATUS_PENDING)
   1788    {
   1789       LLCP_PRINT("Release Accept callback");
   1790       pLlcpSocket->pfSocketAccept_Cb = NULL;
   1791       pLlcpSocket->pAcceptContext = NULL;
   1792    }
   1793 
   1794    return status;
   1795 }
   1796 
   1797  /**
   1798 * \ingroup grp_fri_nfc
   1799 * \brief <b>Reject an incoming connection request for a socket</b>.
   1800 *
   1801 * This functions allows the client to reject an incoming connection request.
   1802 * It must be used with the socket provided within the listen callback. The socket
   1803 * is implicitly closed when the function is called.
   1804 *
   1805 * \param[in]  pLlcpSocket           A pointer to a phFriNfc_LlcpTransport_Socket_t.
   1806 *
   1807 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1808 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1809 *                                            could not be properly interpreted.
   1810 * \retval NFCSTATUS_FAILED                   Operation failed.
   1811 */
   1812 NFCSTATUS phLibNfc_LlcpTransport_ConnectionOriented_Reject( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
   1813                                                             pphFriNfc_LlcpTransportSocketRejectCb_t   pReject_RspCb,
   1814                                                             void                                      *pContext)
   1815 {
   1816    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1817 
   1818    /* Set the state of the socket */
   1819    pLlcpSocket->eSocket_State   = phFriNfc_LlcpTransportSocket_eSocketRejected;
   1820 
   1821    /* Store the Reject callback */
   1822    pLlcpSocket->pfSocketSend_Cb = pReject_RspCb;
   1823    pLlcpSocket->pRejectContext  = pContext;
   1824 
   1825    /* Send a DM*/
   1826    status = phFriNfc_LlcpTransport_SendDisconnectMode(pLlcpSocket->psTransport,
   1827                                                       pLlcpSocket->socket_dSap,
   1828                                                       pLlcpSocket->socket_sSap,
   1829                                                       PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED);
   1830 
   1831    return status;
   1832 }
   1833 
   1834 /**
   1835 * \ingroup grp_fri_nfc
   1836 * \brief <b>Try to establish connection with a socket on a remote SAP</b>.
   1837 *
   1838 * This function tries to connect to a given SAP on the remote peer. If the
   1839 * socket is not bound to a local SAP, it is implicitly bound to a free SAP.
   1840 *
   1841 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
   1842 * \param[in]  nSap               The destination SAP to connect to.
   1843 * \param[in]  psUri              The URI corresponding to the destination SAP to connect to.
   1844 * \param[in]  pConnect_RspCb     The callback to be called when the connection
   1845 *                                operation is completed.
   1846 * \param[in]  pContext           Upper layer context to be returned in
   1847 *                                the callback.
   1848 *
   1849 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1850 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   1851 *                                            could not be properly interpreted.
   1852 * \retval NFCSTATUS_PENDING                  Connection operation is in progress,
   1853 *                                            pConnect_RspCb will be called upon completion.
   1854 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   1855 *                                            a valid type to perform the requsted operation.
   1856 * \retval NFCSTATUS_FAILED                   Operation failed.
   1857 */
   1858 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Connect( phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
   1859                                                              uint8_t                                    nSap,
   1860                                                              phNfc_sData_t*                             psUri,
   1861                                                              pphFriNfc_LlcpTransportSocketConnectCb_t   pConnect_RspCb,
   1862                                                              void*                                      pContext)
   1863 {
   1864    NFCSTATUS status = NFCSTATUS_SUCCESS;
   1865    uint32_t offset = 0;
   1866    uint8_t miux[2];
   1867 
   1868    /* Test if a nSap is present */
   1869    if(nSap != PHFRINFC_LLCP_SAP_DEFAULT)
   1870    {
   1871       /* Set DSAP port number with the nSap value */
   1872       pLlcpSocket->socket_dSap = nSap;
   1873    }
   1874    else
   1875    {
   1876       /* Set DSAP port number with the SDP port number */
   1877       pLlcpSocket->socket_dSap = PHFRINFC_LLCP_SAP_SDP;
   1878    }
   1879 
   1880    /* Store the Connect callback and context */
   1881    pLlcpSocket->pfSocketConnect_Cb = pConnect_RspCb;
   1882    pLlcpSocket->pConnectContext = pContext;
   1883 
   1884    /* Set the socket Header */
   1885    pLlcpSocket->sLlcpHeader.dsap  = pLlcpSocket->socket_dSap;
   1886    pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CONNECT;
   1887    pLlcpSocket->sLlcpHeader.ssap  = pLlcpSocket->socket_sSap;
   1888 
   1889    /* MIUX */
   1890    if(pLlcpSocket->localMIUX != PHFRINFC_LLCP_MIUX_DEFAULT)
   1891    {
   1892       /* Encode MIUX value */
   1893       phFriNfc_Llcp_EncodeMIUX(pLlcpSocket->localMIUX,
   1894                                miux);
   1895 
   1896       /* Encode MIUX in TLV format */
   1897       status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
   1898                                         &offset,
   1899                                         PHFRINFC_LLCP_TLV_TYPE_MIUX,
   1900                                         PHFRINFC_LLCP_TLV_LENGTH_MIUX,
   1901                                         miux);
   1902       if(status != NFCSTATUS_SUCCESS)
   1903       {
   1904          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
   1905          goto clean_and_return;
   1906       }
   1907    }
   1908 
   1909    /* Receive Window */
   1910    if(pLlcpSocket->sSocketOption.rw != PHFRINFC_LLCP_RW_DEFAULT)
   1911    {
   1912       /* Encode RW value */
   1913       phFriNfc_Llcp_EncodeRW(&pLlcpSocket->sSocketOption.rw);
   1914 
   1915       /* Encode RW in TLV format */
   1916       status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
   1917                                         &offset,
   1918                                         PHFRINFC_LLCP_TLV_TYPE_RW,
   1919                                         PHFRINFC_LLCP_TLV_LENGTH_RW,
   1920                                         &pLlcpSocket->sSocketOption.rw);
   1921       if(status != NFCSTATUS_SUCCESS)
   1922       {
   1923          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
   1924          goto clean_and_return;
   1925       }
   1926    }
   1927 
   1928    /* Test if a Service Name is present */
   1929    if(psUri != NULL)
   1930    {
   1931       /* Encode SN in TLV format */
   1932       status =  phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
   1933                                         &offset,
   1934                                         PHFRINFC_LLCP_TLV_TYPE_SN,
   1935                                         (uint8_t)psUri->length,
   1936                                         psUri->buffer);
   1937       if(status != NFCSTATUS_SUCCESS)
   1938       {
   1939          status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
   1940          goto clean_and_return;
   1941       }
   1942    }
   1943 
   1944    /* Test if a send is pending */
   1945    if(testAndSetSendPending(pLlcpSocket->psTransport))
   1946    {
   1947       pLlcpSocket->bSocketConnectPending =  TRUE;
   1948 
   1949       /* Update Send Buffer length value */
   1950       pLlcpSocket->sSocketSendBuffer.length = offset;
   1951 
   1952       status = NFCSTATUS_PENDING;
   1953    }
   1954    else
   1955    {
   1956       /* Update Send Buffer length value */
   1957       pLlcpSocket->sSocketSendBuffer.length = offset;
   1958 
   1959       /* Set the socket in connecting state */
   1960       pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnecting;
   1961 
   1962       status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
   1963                                    &pLlcpSocket->sLlcpHeader,
   1964                                    NULL,
   1965                                    &pLlcpSocket->sSocketSendBuffer,
   1966                                    phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
   1967                                    pLlcpSocket->index,
   1968                                    pLlcpSocket->psTransport);
   1969       if (status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING) {
   1970           clearSendPending(pLlcpSocket->psTransport);
   1971       }
   1972    }
   1973 
   1974 clean_and_return:
   1975    if(status != NFCSTATUS_PENDING)
   1976    {
   1977       LLCP_PRINT("Release Connect callback");
   1978       pLlcpSocket->pfSocketConnect_Cb = NULL;
   1979       pLlcpSocket->pConnectContext = NULL;
   1980    }
   1981 
   1982    return status;
   1983 }
   1984 
   1985 
   1986 /**
   1987 * \ingroup grp_lib_nfc
   1988 * \brief <b>Disconnect a currently connected socket</b>.
   1989 *
   1990 * This function initiates the disconnection of a previously connected socket.
   1991 *
   1992 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
   1993 * \param[in]  pDisconnect_RspCb  The callback to be called when the
   1994 *                                operation is completed.
   1995 * \param[in]  pContext           Upper layer context to be returned in
   1996 *                                the callback.
   1997 *
   1998 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   1999 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   2000 *                                            could not be properly interpreted.
   2001 * \retval NFCSTATUS_PENDING                  Disconnection operation is in progress,
   2002 *                                            pDisconnect_RspCb will be called upon completion.
   2003 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   2004 *                                            a valid type to perform the requsted operation.
   2005 * \retval NFCSTATUS_NOT_INITIALISED          Indicates stack is not yet initialized.
   2006 * \retval NFCSTATUS_SHUTDOWN                 Shutdown in progress.
   2007 * \retval NFCSTATUS_FAILED                   Operation failed.
   2008 */
   2009 NFCSTATUS phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(phFriNfc_LlcpTransport_Socket_t*           pLlcpSocket,
   2010                                                                pphLibNfc_LlcpSocketDisconnectCb_t         pDisconnect_RspCb,
   2011                                                                void*                                      pContext)
   2012 {
   2013    NFCSTATUS status = NFCSTATUS_SUCCESS;
   2014 
   2015    /* Store the Disconnect callback  and context*/
   2016    pLlcpSocket->pfSocketDisconnect_Cb = pDisconnect_RspCb;
   2017    pLlcpSocket->pDisconnectContext = pContext;
   2018 
   2019    /* Set the socket in connecting state */
   2020    pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
   2021 
   2022    /* Test if a send IFRAME is pending with this socket */
   2023    if((pLlcpSocket->bSocketSendPending == TRUE) || (pLlcpSocket->bSocketRecvPending == TRUE))
   2024    {
   2025       pLlcpSocket->bSocketSendPending = FALSE;
   2026       pLlcpSocket->bSocketRecvPending = FALSE;
   2027 
   2028       /* Call the send CB, a disconnect abort the send request */
   2029       if (pLlcpSocket->pfSocketSend_Cb != NULL)
   2030       {
   2031          /* Copy CB + context in local variables */
   2032          pphFriNfc_LlcpTransportSocketSendCb_t  pfSendCb     = pLlcpSocket->pfSocketSend_Cb;
   2033          void*                                  pSendContext = pLlcpSocket->pSendContext;
   2034          /* Reset CB + context */
   2035          pLlcpSocket->pfSocketSend_Cb = NULL;
   2036          pLlcpSocket->pSendContext = NULL;
   2037          /* Perform callback */
   2038          pfSendCb(pSendContext, NFCSTATUS_FAILED);
   2039       }
   2040       /* Call the send CB, a disconnect abort the receive request */
   2041       if (pLlcpSocket->pfSocketRecv_Cb != NULL)
   2042       {
   2043          /* Copy CB + context in local variables */
   2044          pphFriNfc_LlcpTransportSocketRecvCb_t  pfRecvCb     = pLlcpSocket->pfSocketRecv_Cb;
   2045          void*                                  pRecvContext = pLlcpSocket->pRecvContext;
   2046          /* Reset CB + context */
   2047          pLlcpSocket->pfSocketRecv_Cb = NULL;
   2048          pLlcpSocket->pRecvContext = NULL;
   2049          /* Perform callback */
   2050          pfRecvCb(pRecvContext, NFCSTATUS_FAILED);
   2051        }
   2052    }
   2053 
   2054    /* Test if a send is pending */
   2055    if( testAndSetSendPending(pLlcpSocket->psTransport))
   2056    {
   2057       pLlcpSocket->bSocketDiscPending =  TRUE;
   2058       status = NFCSTATUS_PENDING;
   2059    }
   2060    else
   2061    {
   2062       /* Set the socket Header */
   2063       pLlcpSocket->sLlcpHeader.dsap  = pLlcpSocket->socket_dSap;
   2064       pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_DISC;
   2065       pLlcpSocket->sLlcpHeader.ssap  = pLlcpSocket->socket_sSap;
   2066 
   2067       status =  phFriNfc_LlcpTransport_LinkSend(pLlcpSocket->psTransport,
   2068                                    &pLlcpSocket->sLlcpHeader,
   2069                                    NULL,
   2070                                    NULL,
   2071                                    phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
   2072                                    pLlcpSocket->index,
   2073                                    pLlcpSocket->psTransport);
   2074       if(status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING)
   2075       {
   2076          clearSendPending(pLlcpSocket->psTransport);
   2077          LLCP_PRINT("Release Disconnect callback");
   2078          pLlcpSocket->pfSocketDisconnect_Cb = NULL;
   2079          pLlcpSocket->pDisconnectContext = NULL;
   2080       }
   2081    }
   2082 
   2083    return status;
   2084 }
   2085 
   2086 /* TODO: comment function phFriNfc_LlcpTransport_Connectionless_SendTo_CB */
   2087 static void phFriNfc_LlcpTransport_ConnectionOriented_DisconnectClose_CB(void*        pContext,
   2088                                                                          NFCSTATUS    status)
   2089 {
   2090    phFriNfc_LlcpTransport_Socket_t   *pLlcpSocket = (phFriNfc_LlcpTransport_Socket_t*)pContext;
   2091 
   2092    if(status == NFCSTATUS_SUCCESS)
   2093    {
   2094       /* Reset the pointer to the socket closed */
   2095       pLlcpSocket->eSocket_State                      = phFriNfc_LlcpTransportSocket_eSocketDefault;
   2096       pLlcpSocket->eSocket_Type                       = phFriNfc_LlcpTransport_eDefaultType;
   2097       pLlcpSocket->pContext                           = NULL;
   2098       pLlcpSocket->pSocketErrCb                       = NULL;
   2099       pLlcpSocket->socket_sSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
   2100       pLlcpSocket->socket_dSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
   2101       pLlcpSocket->bSocketRecvPending                 = FALSE;
   2102       pLlcpSocket->bSocketSendPending                 = FALSE;
   2103       pLlcpSocket->bSocketListenPending               = FALSE;
   2104       pLlcpSocket->bSocketDiscPending                 = FALSE;
   2105       pLlcpSocket->socket_VS                          = 0;
   2106       pLlcpSocket->socket_VSA                         = 0;
   2107       pLlcpSocket->socket_VR                          = 0;
   2108       pLlcpSocket->socket_VRA                         = 0;
   2109 
   2110       pLlcpSocket->indexRwRead                        = 0;
   2111       pLlcpSocket->indexRwWrite                       = 0;
   2112 
   2113       phFriNfc_LlcpTransport_ConnectionOriented_Abort(pLlcpSocket);
   2114 
   2115       memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
   2116 
   2117       if (pLlcpSocket->sServiceName.buffer != NULL) {
   2118           phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
   2119       }
   2120       pLlcpSocket->sServiceName.buffer = NULL;
   2121       pLlcpSocket->sServiceName.length = 0;
   2122    }
   2123    else
   2124    {
   2125       /* Disconnect close Error */
   2126    }
   2127 }
   2128 
   2129 /**
   2130 * \ingroup grp_fri_nfc
   2131 * \brief <b>Close a socket on a LLCP-connected device</b>.
   2132 *
   2133 * This function closes a LLCP socket previously created using phFriNfc_LlcpTransport_Socket.
   2134 * If the socket was connected, it is first disconnected, and then closed.
   2135 *
   2136 * \param[in]  pLlcpSocket                    A pointer to a phFriNfc_LlcpTransport_Socket_t.
   2137 
   2138 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   2139 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   2140 *                                            could not be properly interpreted.
   2141 * \retval NFCSTATUS_FAILED                   Operation failed.
   2142 */
   2143 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Close(phFriNfc_LlcpTransport_Socket_t*   pLlcpSocket)
   2144 {
   2145    NFCSTATUS status = NFCSTATUS_SUCCESS;
   2146 
   2147    if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
   2148    {
   2149       status = phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(pLlcpSocket,
   2150                                                                     phFriNfc_LlcpTransport_ConnectionOriented_DisconnectClose_CB,
   2151                                                                     pLlcpSocket);
   2152    }
   2153    else
   2154    {
   2155       LLCP_PRINT("Socket not connected, no need to disconnect");
   2156       /* Reset the pointer to the socket closed */
   2157       pLlcpSocket->eSocket_State                      = phFriNfc_LlcpTransportSocket_eSocketDefault;
   2158       pLlcpSocket->eSocket_Type                       = phFriNfc_LlcpTransport_eDefaultType;
   2159       pLlcpSocket->pContext                           = NULL;
   2160       pLlcpSocket->pSocketErrCb                       = NULL;
   2161       pLlcpSocket->socket_sSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
   2162       pLlcpSocket->socket_dSap                        = PHFRINFC_LLCP_SAP_DEFAULT;
   2163       pLlcpSocket->bSocketRecvPending                 = FALSE;
   2164       pLlcpSocket->bSocketSendPending                 = FALSE;
   2165       pLlcpSocket->bSocketListenPending               = FALSE;
   2166       pLlcpSocket->bSocketDiscPending                 = FALSE;
   2167       pLlcpSocket->RemoteBusyConditionInfo            = FALSE;
   2168       pLlcpSocket->ReceiverBusyCondition              = FALSE;
   2169       pLlcpSocket->socket_VS                          = 0;
   2170       pLlcpSocket->socket_VSA                         = 0;
   2171       pLlcpSocket->socket_VR                          = 0;
   2172       pLlcpSocket->socket_VRA                         = 0;
   2173 
   2174       pLlcpSocket->indexRwRead                        = 0;
   2175       pLlcpSocket->indexRwWrite                       = 0;
   2176 
   2177       phFriNfc_LlcpTransport_ConnectionOriented_Abort(pLlcpSocket);
   2178 
   2179       memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
   2180 
   2181       if (pLlcpSocket->sServiceName.buffer != NULL) {
   2182           phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
   2183       }
   2184       pLlcpSocket->sServiceName.buffer = NULL;
   2185       pLlcpSocket->sServiceName.length = 0;
   2186    }
   2187    return NFCSTATUS_SUCCESS;
   2188 }
   2189 
   2190 
   2191 /**
   2192 * \ingroup grp_fri_nfc
   2193 * \brief <b>Send data on a socket</b>.
   2194 *
   2195 * This function is used to write data on a socket. This function
   2196 * can only be called on a connection-oriented socket which is already
   2197 * in a connected state.
   2198 *
   2199 *
   2200 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
   2201 * \param[in]  psBuffer           The buffer containing the data to send.
   2202 * \param[in]  pSend_RspCb        The callback to be called when the
   2203 *                                operation is completed.
   2204 * \param[in]  pContext           Upper layer context to be returned in
   2205 *                                the callback.
   2206 *
   2207 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   2208 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   2209 *                                            could not be properly interpreted.
   2210 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
   2211 *                                            pSend_RspCb will be called upon completion.
   2212 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   2213 *                                            a valid type to perform the requsted operation.
   2214 * \retval NFCSTATUS_FAILED                   Operation failed.
   2215 */
   2216 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Send(phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
   2217                                                          phNfc_sData_t*                               psBuffer,
   2218                                                          pphFriNfc_LlcpTransportSocketSendCb_t        pSend_RspCb,
   2219                                                          void*                                        pContext)
   2220 {
   2221    NFCSTATUS status = NFCSTATUS_SUCCESS;
   2222 
   2223 
   2224    /* Test the RW window */
   2225    if(!CHECK_SEND_RW(pLlcpSocket))
   2226    {
   2227       /* Store the Send CB and context */
   2228       pLlcpSocket->pfSocketSend_Cb    = pSend_RspCb;
   2229       pLlcpSocket->pSendContext       = pContext;
   2230 
   2231       /* Set Send pending */
   2232       pLlcpSocket->bSocketSendPending = TRUE;
   2233 
   2234       /* Store send buffer pointer */
   2235       pLlcpSocket->sSocketSendBuffer = *psBuffer;
   2236 
   2237       /* Set status */
   2238       status = NFCSTATUS_PENDING;
   2239    }
   2240    else
   2241    {
   2242       /* Store send buffer pointer */
   2243       pLlcpSocket->sSocketSendBuffer = *psBuffer;
   2244 
   2245       /* Store the Send CB and context */
   2246       pLlcpSocket->pfSocketSend_Cb    = pSend_RspCb;
   2247       pLlcpSocket->pSendContext       = pContext;
   2248 
   2249       /* Test if a send is pending */
   2250       if(testAndSetSendPending(pLlcpSocket->psTransport))
   2251       {
   2252          /* Set Send pending */
   2253          pLlcpSocket->bSocketSendPending = TRUE;
   2254 
   2255          /* Set status */
   2256          status = NFCSTATUS_PENDING;
   2257       }
   2258       else
   2259       {
   2260          /* Store the Send CB and context */
   2261          pLlcpSocket->pfSocketSend_Cb    = pSend_RspCb;
   2262          pLlcpSocket->pSendContext       = pContext;
   2263 
   2264          status = static_performSendInfo(pLlcpSocket);
   2265 
   2266          if(status != NFCSTATUS_SUCCESS && status != NFCSTATUS_PENDING)
   2267          {
   2268             clearSendPending(pLlcpSocket->psTransport);
   2269             LLCP_PRINT("Release Send callback");
   2270             pLlcpSocket->pfSocketSend_Cb = NULL;
   2271             pLlcpSocket->pSendContext = NULL;
   2272          }
   2273       }
   2274 
   2275    }
   2276    return status;
   2277 }
   2278 
   2279 
   2280  /**
   2281 * \ingroup grp_fri_nfc
   2282 * \brief <b>Read data on a socket</b>.
   2283 *
   2284 * This function is used to read data from a socket. It reads at most the
   2285 * size of the reception buffer, but can also return less bytes if less bytes
   2286 * are available. If no data is available, the function will be pending until
   2287 * more data comes, and the response will be sent by the callback. This function
   2288 * can only be called on a connection-oriented socket.
   2289 *
   2290 *
   2291 * \param[in]  pLlcpSocket        A pointer to a phFriNfc_LlcpTransport_Socket_t.
   2292 * \param[in]  psBuffer           The buffer receiving the data.
   2293 * \param[in]  pRecv_RspCb        The callback to be called when the
   2294 *                                operation is completed.
   2295 * \param[in]  pContext           Upper layer context to be returned in
   2296 *                                the callback.
   2297 *
   2298 * \retval NFCSTATUS_SUCCESS                  Operation successful.
   2299 * \retval NFCSTATUS_INVALID_PARAMETER        One or more of the supplied parameters
   2300 *                                            could not be properly interpreted.
   2301 * \retval NFCSTATUS_PENDING                  Reception operation is in progress,
   2302 *                                            pRecv_RspCb will be called upon completion.
   2303 * \retval NFCSTATUS_INVALID_STATE            The socket is not in a valid state, or not of
   2304 *                                            a valid type to perform the requsted operation.
   2305 * \retval NFCSTATUS_FAILED                   Operation failed.
   2306 */
   2307 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Recv( phFriNfc_LlcpTransport_Socket_t*             pLlcpSocket,
   2308                                                           phNfc_sData_t*                               psBuffer,
   2309                                                           pphFriNfc_LlcpTransportSocketRecvCb_t        pRecv_RspCb,
   2310                                                           void*                                        pContext)
   2311 {
   2312    NFCSTATUS   status = NFCSTATUS_SUCCESS;
   2313    uint32_t    dataLengthStored = 0;
   2314    uint32_t    dataLengthAvailable = 0;
   2315    uint32_t    dataLengthRead = 0;
   2316    uint32_t    dataLengthWrite = 0;
   2317    bool_t      dataBufferized = FALSE;
   2318 
   2319    /* Test if the WorkingBuffer Length is null */
   2320    if(pLlcpSocket->bufferLinearLength == 0)
   2321    {
   2322       if (pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
   2323       {
   2324           return NFCSTATUS_FAILED;
   2325       }
   2326 
   2327       /* Test If data is present in the RW Buffer */
   2328       if(pLlcpSocket->indexRwRead != pLlcpSocket->indexRwWrite)
   2329       {
   2330          if(pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length != 0)
   2331          {
   2332             /* Save I_FRAME into the Receive Buffer */
   2333             memcpy(psBuffer->buffer,pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].buffer,pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length);
   2334             psBuffer->length = pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length;
   2335 
   2336             dataBufferized = TRUE;
   2337 
   2338             /* Update VR */
   2339             pLlcpSocket->socket_VR = (pLlcpSocket->socket_VR+1)%16;
   2340 
   2341             /* Update RW Buffer length */
   2342             pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length = 0;
   2343 
   2344             /* Update Value Rw Read Index*/
   2345             pLlcpSocket->indexRwRead++;
   2346          }
   2347       }
   2348 
   2349       if(dataBufferized == TRUE)
   2350       {
   2351          /* Call the Receive CB */
   2352          pRecv_RspCb(pContext,NFCSTATUS_SUCCESS);
   2353 
   2354          if(pLlcpSocket->ReceiverBusyCondition == TRUE)
   2355          {
   2356             /* Reset the ReceiverBusyCondition Flag */
   2357             pLlcpSocket->ReceiverBusyCondition = FALSE;
   2358             /* RR */
   2359             /* TODO: report status? */
   2360             phFriNfc_Llcp_Send_ReceiveReady_Frame(pLlcpSocket);
   2361          }
   2362       }
   2363       else
   2364       {
   2365          /* Set Receive pending */
   2366          pLlcpSocket->bSocketRecvPending = TRUE;
   2367 
   2368          /* Store the buffer pointer */
   2369          pLlcpSocket->sSocketRecvBuffer = psBuffer;
   2370 
   2371          /* Store the Recv CB and context */
   2372          pLlcpSocket->pfSocketRecv_Cb  = pRecv_RspCb;
   2373          pLlcpSocket->pRecvContext     = pContext;
   2374 
   2375          /* Set status */
   2376          status = NFCSTATUS_PENDING;
   2377       }
   2378    }
   2379    else
   2380    {
   2381       /* Test if data is present in the linear buffer*/
   2382       dataLengthStored = phFriNfc_Llcp_CyclicFifoUsage(&pLlcpSocket->sCyclicFifoBuffer);
   2383 
   2384       if(dataLengthStored != 0)
   2385       {
   2386          if(psBuffer->length > dataLengthStored)
   2387          {
   2388             psBuffer->length = dataLengthStored;
   2389          }
   2390 
   2391          /* Read data from the linear buffer */
   2392          dataLengthRead = phFriNfc_Llcp_CyclicFifoFifoRead(&pLlcpSocket->sCyclicFifoBuffer,
   2393                                                            psBuffer->buffer,
   2394                                                            psBuffer->length);
   2395 
   2396          if(dataLengthRead != 0)
   2397          {
   2398             /* Test If data is present in the RW Buffer */
   2399             while(pLlcpSocket->indexRwRead != pLlcpSocket->indexRwWrite)
   2400             {
   2401                /* Get the data length available in the linear buffer  */
   2402                dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&pLlcpSocket->sCyclicFifoBuffer);
   2403 
   2404                /* Exit if not enough memory available in linear buffer */
   2405                if(dataLengthAvailable < pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length)
   2406                {
   2407                   break;
   2408                }
   2409 
   2410                /* Write data into the linear buffer */
   2411                dataLengthWrite = phFriNfc_Llcp_CyclicFifoWrite(&pLlcpSocket->sCyclicFifoBuffer,
   2412                                                                pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].buffer,
   2413                                                                pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length);
   2414                /* Update VR */
   2415                pLlcpSocket->socket_VR = (pLlcpSocket->socket_VR+1)%16;
   2416 
   2417                /* Set flag bufferized to TRUE */
   2418                dataBufferized = TRUE;
   2419 
   2420                /* Update RW Buffer length */
   2421                pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length = 0;
   2422 
   2423                /* Update Value Rw Read Index*/
   2424                pLlcpSocket->indexRwRead++;
   2425             }
   2426 
   2427             /* Test if data has been bufferized after a read access */
   2428             if(dataBufferized == TRUE)
   2429             {
   2430                /* Get the data length available in the linear buffer  */
   2431                dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&pLlcpSocket->sCyclicFifoBuffer);
   2432                if((dataLengthAvailable >= pLlcpSocket->sSocketOption.miu) && (pLlcpSocket->ReceiverBusyCondition == TRUE))
   2433                {
   2434                   /* Reset the ReceiverBusyCondition Flag */
   2435                   pLlcpSocket->ReceiverBusyCondition = FALSE;
   2436                   /* RR */
   2437                   /* TODO: report status? */
   2438                   phFriNfc_Llcp_Send_ReceiveReady_Frame(pLlcpSocket);
   2439                }
   2440             }
   2441 
   2442             /* Call the Receive CB */
   2443             pRecv_RspCb(pContext,NFCSTATUS_SUCCESS);
   2444          }
   2445          else
   2446          {
   2447             /* Call the Receive CB   */
   2448             status = NFCSTATUS_FAILED;
   2449          }
   2450       }
   2451       else
   2452       {
   2453          if (pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
   2454          {
   2455              status = NFCSTATUS_FAILED;
   2456          }
   2457          else
   2458          {
   2459             /* Set Receive pending */
   2460             pLlcpSocket->bSocketRecvPending = TRUE;
   2461 
   2462             /* Store the buffer pointer */
   2463             pLlcpSocket->sSocketRecvBuffer = psBuffer;
   2464 
   2465             /* Store the Recv CB and context */
   2466             pLlcpSocket->pfSocketRecv_Cb  = pRecv_RspCb;
   2467             pLlcpSocket->pRecvContext     = pContext;
   2468 
   2469             /* Set status */
   2470             status = NFCSTATUS_PENDING;
   2471          }
   2472       }
   2473    }
   2474 
   2475    if(status != NFCSTATUS_PENDING)
   2476    {
   2477       /* Note: The receive callback must be released to avoid being called at abort */
   2478       LLCP_PRINT("Release Receive callback");
   2479       pLlcpSocket->pfSocketRecv_Cb = NULL;
   2480       pLlcpSocket->pRecvContext = NULL;
   2481    }
   2482 
   2483    return status;
   2484 }
   2485 
   2486 
   2487