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