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