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