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