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