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