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