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