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