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