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