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