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