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