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