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