2 * Copyright (C) 2010 NXP Semiconductors
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
18 * \file phFriNfc_LlcpTransport_Connection.c
\r
25 #include <phOsalNfc.h>
\r
26 #include <phLibNfcStatus.h>
\r
27 #include <phLibNfc.h>
\r
28 #include <phNfcLlcpTypes.h>
\r
29 #include <phFriNfc_LlcpTransport.h>
\r
30 #include <phFriNfc_LlcpTransport_Connection.h>
\r
31 #include <phFriNfc_Llcp.h>
\r
32 #include <phFriNfc_LlcpUtils.h>
\r
34 /* Function definition */
\r
35 static NFCSTATUS phFriNfc_Llcp_Send_DisconnectMode_Frame(phFriNfc_LlcpTransport_t* psTransport,
\r
40 static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket);
\r
42 static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket);
\r
44 static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket);
\r
46 /********** End Function definition ***********/
\r
48 NFCSTATUS phFriNfc_LlcpConnTransport_Send( phFriNfc_Llcp_t *Llcp,
\r
49 phFriNfc_Llcp_sPacketHeader_t *psHeader,
\r
50 phFriNfc_Llcp_sPacketSequence_t *psSequence,
\r
51 phNfc_sData_t *psInfo,
\r
52 phFriNfc_Llcp_Send_CB_t pfSend_CB,
\r
53 phFriNfc_LlcpTransport_t* psTransport ) {
\r
54 NFCSTATUS result = phFriNfc_Llcp_Send(Llcp, psHeader, psSequence, psInfo,
\r
55 pfSend_CB, psTransport);
\r
56 if (result == NFCSTATUS_PENDING) {
\r
57 psTransport->bSendPending = TRUE;
\r
62 /* TODO: comment functionphFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB */
\r
63 static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* pContext,
\r
66 phFriNfc_LlcpTransport_t *psTransport;
\r
67 phFriNfc_LlcpTransport_Socket_t psTempLlcpSocket;
\r
68 phFriNfc_LlcpTransport_Socket_t *psLocalLlcpSocket = NULL;
\r
69 phNfc_sData_t sFrmrBuffer;
\r
71 uint8_t socketFound = FALSE;
\r
74 /* Get Send CB context */
\r
75 psTransport = (phFriNfc_LlcpTransport_t*)pContext;
\r
77 /* Reset the FLAG send pending*/
\r
78 psTransport->bSendPending = FALSE;
\r
80 if(status == NFCSTATUS_SUCCESS)
\r
82 if(psTransport->bFrmrPending)
\r
84 /* Reset FRMR pending */
\r
85 psTransport->bFrmrPending = FALSE;
\r
88 sFrmrBuffer.buffer = psTransport->FrmrInfoBuffer;
\r
89 sFrmrBuffer.length = 0x04; /* Size of FRMR Information field */
\r
91 result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
\r
92 &psTransport->sLlcpHeader,
\r
95 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
98 else if(psTransport->bDmPending)
\r
100 /* Reset DM pending */
\r
101 psTransport->bDmPending = FALSE;
\r
103 /* Send DM pending */
\r
104 result = phFriNfc_Llcp_Send_DisconnectMode_Frame(psTransport,
\r
105 psTransport->DmInfoBuffer[0],
\r
106 psTransport->DmInfoBuffer[1],
\r
107 psTransport->DmInfoBuffer[2]);
\r
111 /* Test the socket */
\r
112 switch(psTransport->pSocketTable[psTransport->socketIndex].eSocket_State)
\r
114 case phFriNfc_LlcpTransportSocket_eSocketAccepted:
\r
116 /* Set socket state to Connected */
\r
117 psTransport->pSocketTable[psTransport->socketIndex].eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnected;
\r
118 /* Call the Accept Callback */
\r
119 psTransport->pSocketTable[psTransport->socketIndex].pfSocketAccept_Cb(psTransport->pSocketTable[psTransport->socketIndex].pAcceptContext,status);
\r
120 psTransport->pSocketTable[psTransport->socketIndex].pfSocketAccept_Cb = NULL;
\r
121 psTransport->pSocketTable[psTransport->socketIndex].pAcceptContext = NULL;
\r
124 case phFriNfc_LlcpTransportSocket_eSocketRejected:
\r
126 /* Store the Llcp socket in a local Llcp socket */
\r
127 psTempLlcpSocket = psTransport->pSocketTable[psTransport->socketIndex];
\r
129 /* Reset the socket and set the socket state to default */
\r
130 result = phFriNfc_LlcpTransport_Close(&psTransport->pSocketTable[psTransport->socketIndex]);
\r
132 /* Call the Reject Callback */
\r
133 psTempLlcpSocket.pfSocketSend_Cb(psTempLlcpSocket.pRejectContext,status);
\r
134 psTempLlcpSocket.pfSocketSend_Cb = NULL;
\r
137 case phFriNfc_LlcpTransportSocket_eSocketConnected:
\r
139 if(!psTransport->pSocketTable[psTransport->socketIndex].bSocketSendPending && psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb != NULL)
\r
141 psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb(psTransport->pSocketTable[psTransport->socketIndex].pSendContext,status);
\r
142 psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb = NULL;
\r
148 /* Update Index value with the next socket */
\r
149 index = psTransport->socketIndex+1;
\r
151 /* Search for a socket with a flag Pending */
\r
154 if(index >= PHFRINFC_LLCP_NB_SOCKET_MAX)
\r
159 if(psTransport->pSocketTable[index].bSocketAcceptPending == TRUE
\r
160 || psTransport->pSocketTable[index].bSocketConnectPending == TRUE
\r
161 || psTransport->pSocketTable[index].bSocketDiscPending == TRUE
\r
162 || psTransport->pSocketTable[index].bSocketRNRPending == TRUE
\r
163 || psTransport->pSocketTable[index].bSocketRRPending == TRUE
\r
164 || psTransport->pSocketTable[index].bSocketSendPending == TRUE
\r
165 || psTransport->pSocketTable[index].pfSocketSend_Cb != NULL)
\r
168 socketFound = TRUE;
\r
169 psLocalLlcpSocket = &psTransport->pSocketTable[index];
\r
174 if(index == psTransport->socketIndex)
\r
183 }while(index != ((psTransport->socketIndex+1)%PHFRINFC_LLCP_NB_SOCKET_MAX));
\r
186 if(socketFound == TRUE)
\r
188 socketFound = FALSE;
\r
189 /* perform the command pending */
\r
192 if(psLocalLlcpSocket->bSocketSendPending == TRUE)
\r
194 /* Test the RW window */
\r
195 if(CHECK_SEND_RW(psLocalLlcpSocket))
\r
197 result = static_performSendInfo(psLocalLlcpSocket);
\r
199 /* Reset Send Pending Flag */
\r
200 psLocalLlcpSocket->bSocketSendPending = FALSE;
\r
204 else if(psLocalLlcpSocket->bSocketRRPending == TRUE)
\r
206 /* Reset RR pending */
\r
207 psLocalLlcpSocket->bSocketRRPending = FALSE;
\r
209 /* Send RR Frame */
\r
210 result = phFriNfc_Llcp_Send_ReceiveReady_Frame(psLocalLlcpSocket);
\r
214 else if(psLocalLlcpSocket->bSocketRNRPending == TRUE)
\r
216 /* Reset RNR pending */
\r
217 psLocalLlcpSocket->bSocketRNRPending = FALSE;
\r
219 /* Send RNR Frame */
\r
220 result = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(psLocalLlcpSocket);
\r
223 else if(psLocalLlcpSocket->bSocketAcceptPending == TRUE)
\r
225 /* Reset Accept pending */
\r
226 psLocalLlcpSocket->bSocketAcceptPending = FALSE;
\r
228 /* Fill the psLlcpHeader stuture with the DSAP,CC PTYPE and the SSAP */
\r
229 psLocalLlcpSocket->sLlcpHeader.dsap = psLocalLlcpSocket->socket_dSap;
\r
230 psLocalLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC;
\r
231 psLocalLlcpSocket->sLlcpHeader.ssap = psLocalLlcpSocket->socket_sSap;
\r
233 /* Set the socket state to accepted */
\r
234 psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketAccepted;
\r
236 /* Store the index of the socket */
\r
237 psTransport->socketIndex = psLocalLlcpSocket->index;
\r
239 /* Send a CC Frame */
\r
240 result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
\r
241 &psLocalLlcpSocket->sLlcpHeader,
\r
243 &psLocalLlcpSocket->sSocketSendBuffer,
\r
244 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
247 /* CONNECT FRAME */
\r
248 else if(psLocalLlcpSocket->bSocketConnectPending == TRUE)
\r
250 /* Reset Accept pending */
\r
251 psLocalLlcpSocket->bSocketConnectPending = FALSE;
\r
253 /* Store the index of the socket */
\r
254 psTransport->socketIndex = psLocalLlcpSocket->index;
\r
256 /* Set the socket in connecting state */
\r
257 psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnecting;
\r
260 result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
\r
261 &psLocalLlcpSocket->sLlcpHeader,
\r
263 &psLocalLlcpSocket->sSocketSendBuffer,
\r
264 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
268 else if(psLocalLlcpSocket->bSocketDiscPending == TRUE)
\r
270 /* Reset Disc Pending */
\r
271 psLocalLlcpSocket->bSocketDiscPending = FALSE;
\r
273 /* Set the socket in connecting state */
\r
274 psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
\r
276 /* Store the index of the socket */
\r
277 psTransport->socketIndex = psLocalLlcpSocket->index;
\r
280 result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
\r
281 &psLocalLlcpSocket->sLlcpHeader,
\r
283 &psLocalLlcpSocket->sSocketSendBuffer,
\r
284 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
287 /* Call ErrCB due to a DISC */
\r
288 psLocalLlcpSocket->pSocketErrCb(psLocalLlcpSocket->pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
\r
290 /* Call SEND IFRAME CB */
\r
291 else if((psLocalLlcpSocket->pfSocketSend_Cb != NULL) && !psLocalLlcpSocket->bSocketSendPending)
\r
293 psLocalLlcpSocket->pfSocketSend_Cb(psLocalLlcpSocket->pSendContext,status);
\r
294 psLocalLlcpSocket->pfSocketSend_Cb = NULL;
\r
297 /* Reset the current length of the send buffer */
\r
298 //psTransport->pSocketTable[psTransport->socketIndex].sSocketSendBuffer.length = psTransport->pSocketTable[psTransport->socketIndex].bufferSendMaxLength;
\r
302 /* Send CB error */
\r
303 if(!psTransport->pSocketTable[psTransport->socketIndex].bSocketSendPending && psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb != NULL)
\r
305 psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb(psTransport->pSocketTable[psTransport->socketIndex].pSendContext,status);
\r
306 psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb = NULL;
\r
311 static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket)
\r
313 phFriNfc_LlcpTransport_t *psTransport = psLlcpSocket->psTransport;
\r
316 /* Reset Send Pending */
\r
317 psLlcpSocket->bSocketSendPending = FALSE;
\r
319 /* Set the Header */
\r
320 psLlcpSocket->sLlcpHeader.dsap = psLlcpSocket->socket_dSap;
\r
321 psLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_I;
\r
322 psLlcpSocket->sLlcpHeader.ssap = psLlcpSocket->socket_sSap;
\r
324 /* Set Sequence Numbers */
\r
325 psLlcpSocket->sSequence.ns = psLlcpSocket->socket_VS;
\r
326 psLlcpSocket->sSequence.nr = psLlcpSocket->socket_VR;
\r
328 /* Update the VRA */
\r
329 psLlcpSocket->socket_VRA = psLlcpSocket->socket_VR;
\r
331 /* Store the index of the socket */
\r
332 psTransport->socketIndex = psLlcpSocket->index;
\r
335 status = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
\r
336 &psLlcpSocket->sLlcpHeader,
\r
337 &psLlcpSocket->sSequence,
\r
338 &psLlcpSocket->sSocketSendBuffer,
\r
339 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
343 psLlcpSocket->socket_VS = (psLlcpSocket->socket_VS+1)%16;
\r
348 static void phFriNfc_LlcpTransport_ConnectionOriented_Abort(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket)
\r
350 if (pLlcpSocket->pfSocketSend_Cb != NULL)
\r
352 pLlcpSocket->pfSocketSend_Cb(pLlcpSocket->pSendContext, NFCSTATUS_ABORTED);
\r
353 pLlcpSocket->pfSocketSend_Cb = NULL;
\r
355 pLlcpSocket->pSendContext = NULL;
\r
356 if (pLlcpSocket->pfSocketRecv_Cb != NULL)
\r
358 pLlcpSocket->pfSocketRecv_Cb(pLlcpSocket->pRecvContext, NFCSTATUS_ABORTED);
\r
359 pLlcpSocket->pfSocketRecv_Cb = NULL;
\r
361 pLlcpSocket->pRecvContext = NULL;
\r
362 if (pLlcpSocket->pfSocketAccept_Cb != NULL)
\r
364 pLlcpSocket->pfSocketAccept_Cb(pLlcpSocket->pAcceptContext, NFCSTATUS_ABORTED);
\r
365 pLlcpSocket->pfSocketAccept_Cb = NULL;
\r
367 pLlcpSocket->pAcceptContext = NULL;
\r
368 if (pLlcpSocket->pfSocketConnect_Cb != NULL)
\r
370 pLlcpSocket->pfSocketConnect_Cb(pLlcpSocket->pConnectContext, 0, NFCSTATUS_ABORTED);
\r
371 pLlcpSocket->pfSocketConnect_Cb = NULL;
\r
373 pLlcpSocket->pConnectContext = NULL;
\r
374 if (pLlcpSocket->pfSocketDisconnect_Cb != NULL)
\r
376 pLlcpSocket->pfSocketDisconnect_Cb(pLlcpSocket->pDisonnectContext, NFCSTATUS_ABORTED);
\r
377 pLlcpSocket->pfSocketDisconnect_Cb = NULL;
\r
379 pLlcpSocket->pDisonnectContext = NULL;
\r
381 pLlcpSocket->pfSocketRecvFrom_Cb = NULL;
\r
382 pLlcpSocket->pfSocketListen_Cb = NULL;
\r
383 pLlcpSocket->pListenContext = NULL;
\r
386 static NFCSTATUS phFriNfc_Llcp_Send_DisconnectMode_Frame(phFriNfc_LlcpTransport_t* psTransport,
\r
391 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
393 /* Test if a send is pending */
\r
394 if(psTransport->bSendPending)
\r
397 psTransport->bDmPending = TRUE;
\r
399 /* Store DM Info */
\r
400 psTransport->DmInfoBuffer[0] = dsap;
\r
401 psTransport->DmInfoBuffer[1] = ssap;
\r
402 psTransport->DmInfoBuffer[2] = dmOpCode;
\r
404 status = NFCSTATUS_PENDING;
\r
408 /* Set the header */
\r
409 psTransport->sDmHeader.dsap = dsap;
\r
410 psTransport->sDmHeader.ptype = PHFRINFC_LLCP_PTYPE_DM;
\r
411 psTransport->sDmHeader.ssap = ssap;
\r
413 /* Save Operation Code to be provided in DM frame payload */
\r
414 psTransport->DmInfoBuffer[2] = dmOpCode;
\r
415 psTransport->sDmPayload.buffer = &psTransport->DmInfoBuffer[2];
\r
416 psTransport->sDmPayload.length = PHFRINFC_LLCP_DM_LENGTH;
\r
418 /* Send DM frame */
\r
419 status = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
\r
420 &psTransport->sDmHeader,
\r
422 &psTransport->sDmPayload,
\r
423 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
430 static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket)
\r
432 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
434 /* Test if a send is pending */
\r
435 if(pLlcpSocket->psTransport->bSendPending == TRUE)
\r
437 pLlcpSocket->bSocketRRPending = TRUE;
\r
438 status = NFCSTATUS_PENDING;
\r
442 /* Set the header of the RR frame */
\r
443 pLlcpSocket->sLlcpHeader.dsap = pLlcpSocket->socket_dSap;
\r
444 pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_RR;
\r
445 pLlcpSocket->sLlcpHeader.ssap = pLlcpSocket->socket_sSap;
\r
447 /* Set sequence number for RR Frame */
\r
448 pLlcpSocket->sSequence.ns = 0;
\r
449 pLlcpSocket->sSequence.nr = pLlcpSocket->socket_VR;
\r
452 pLlcpSocket->socket_VRA = (uint8_t)pLlcpSocket->sSequence.nr;
\r
454 /* Store the index of the socket */
\r
455 pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
\r
457 /* Send RR frame */
\r
458 status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
\r
459 &pLlcpSocket->sLlcpHeader,
\r
460 &pLlcpSocket->sSequence,
\r
462 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
463 pLlcpSocket->psTransport);
\r
469 static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket)
\r
471 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
474 /* Test if a send is pending */
\r
475 if(pLlcpSocket->psTransport->bSendPending == TRUE)
\r
477 pLlcpSocket->bSocketRNRPending = TRUE;
\r
478 status = NFCSTATUS_PENDING;
\r
482 /* Set the header of the RNR frame */
\r
483 pLlcpSocket->sLlcpHeader.dsap = pLlcpSocket->socket_dSap;
\r
484 pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_RNR;
\r
485 pLlcpSocket->sLlcpHeader.ssap = pLlcpSocket->socket_sSap;
\r
487 /* Set sequence number for RNR Frame */
\r
488 pLlcpSocket->sSequence.ns = 0x00;
\r
489 pLlcpSocket->sSequence.nr = pLlcpSocket->socket_VR;
\r
492 pLlcpSocket->socket_VRA = (uint8_t)pLlcpSocket->sSequence.nr;
\r
494 /* Store the index of the socket */
\r
495 pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
\r
497 /* Send RNR frame */
\r
498 status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
\r
499 &pLlcpSocket->sLlcpHeader,
\r
500 &pLlcpSocket->sSequence,
\r
502 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
503 pLlcpSocket->psTransport);
\r
508 static NFCSTATUS phFriNfc_Llcp_Send_FrameReject_Frame(phFriNfc_LlcpTransport_t *psTransport,
\r
510 uint8_t rejectedPTYPE,
\r
512 phFriNfc_Llcp_sPacketSequence_t* sLlcpSequence,
\r
522 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
523 phNfc_sData_t sFrmrBuffer;
\r
525 uint8_t sequence = 0;
\r
527 uint8_t socketFound = FALSE;
\r
529 /* Search a socket waiting for a FRAME */
\r
530 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
532 /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
\r
533 if(psTransport->pSocketTable[index].socket_sSap == dsap
\r
534 && psTransport->pSocketTable[index].socket_dSap == ssap)
\r
537 socketFound = TRUE;
\r
542 /* Test if a socket has been found */
\r
545 /* Set socket state to disconnected */
\r
546 psTransport->pSocketTable[index].eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDefault;
\r
548 /* Call ErrCB due to a FRMR*/
\r
549 psTransport->pSocketTable[index].pSocketErrCb( psTransport->pSocketTable[index].pContext,PHFRINFC_LLCP_ERR_FRAME_REJECTED);
\r
551 /* Close the socket */
\r
552 status = phFriNfc_LlcpTransport_ConnectionOriented_Close(&psTransport->pSocketTable[index]);
\r
554 /* Set FRMR Header */
\r
555 psTransport->sLlcpHeader.dsap = dsap;
\r
556 psTransport->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_FRMR;
\r
557 psTransport->sLlcpHeader.ssap = ssap;
\r
559 /* Set FRMR Information Field */
\r
560 flagValue = (WFlag<<7) | (IFlag<<6) | (RFlag<<5) | (SFlag<<4) | rejectedPTYPE;
\r
561 if (sLlcpSequence != NULL)
\r
563 sequence = (uint8_t)((sLlcpSequence->ns<<4)|(sLlcpSequence->nr));
\r
566 psTransport->FrmrInfoBuffer[0] = flagValue;
\r
567 psTransport->FrmrInfoBuffer[1] = sequence;
\r
568 psTransport->FrmrInfoBuffer[2] = (vs<<4)|vr ;
\r
569 psTransport->FrmrInfoBuffer[3] = (vsa<<4)|vra ;
\r
571 /* Test if a send is pending */
\r
572 if(psTransport->bSendPending)
\r
574 psTransport->bFrmrPending = TRUE;
\r
575 status = NFCSTATUS_PENDING;
\r
579 sFrmrBuffer.buffer = psTransport->FrmrInfoBuffer;
\r
580 sFrmrBuffer.length = 0x04; /* Size of FRMR Information field */
\r
582 /* Send FRMR frame */
\r
583 status = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp,
\r
584 &psTransport->sLlcpHeader,
\r
587 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
593 /* No active socket*/
\r
594 /* FRMR Frame not handled*/
\r
599 static NFCSTATUS phFriNfc_Llcp_GetSocket_Params(phNfc_sData_t *psParamsTLV,
\r
600 phNfc_sData_t *psServiceName,
\r
601 uint8_t *pRemoteRW_Size,
\r
602 uint16_t *pRemoteMIU)
\r
604 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
605 phNfc_sData_t sValueBuffer;
\r
606 uint32_t offset = 0;
\r
609 /* Check for NULL pointers */
\r
610 if ((psParamsTLV == NULL) || (pRemoteRW_Size == NULL) || (pRemoteMIU == NULL))
\r
612 return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
\r
617 while (offset < psParamsTLV->length)
\r
619 status = phFriNfc_Llcp_DecodeTLV(psParamsTLV, &offset, &type,&sValueBuffer);
\r
620 if (status != NFCSTATUS_SUCCESS)
\r
622 /* Error: Ill-formed TLV */
\r
627 case PHFRINFC_LLCP_TLV_TYPE_SN:
\r
629 /* Test if a SN is present in the TLV */
\r
630 if(sValueBuffer.length == 0)
\r
632 /* Error : Ill-formed SN parameter TLV */
\r
635 /* Get the Service Name */
\r
636 *psServiceName = sValueBuffer;
\r
639 case PHFRINFC_LLCP_TLV_TYPE_RW:
\r
642 if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_RW)
\r
644 /* Error : Ill-formed MIUX parameter TLV */
\r
647 *pRemoteRW_Size = sValueBuffer.buffer[0];
\r
650 case PHFRINFC_LLCP_TLV_TYPE_MIUX:
\r
653 if (sValueBuffer.length != PHFRINFC_LLCP_TLV_LENGTH_MIUX)
\r
655 /* Error : Ill-formed MIUX parameter TLV */
\r
658 *pRemoteMIU = PHFRINFC_LLCP_MIU_DEFAULT + (((sValueBuffer.buffer[0] << 8) | sValueBuffer.buffer[1]) & PHFRINFC_LLCP_TLV_MIUX_MASK);
\r
663 /* Error : Unknown type */
\r
673 /* TODO: comment function Handle_ConnectFrame */
\r
674 static void Handle_ConnectionFrame(phFriNfc_LlcpTransport_t *psTransport,
\r
675 phNfc_sData_t *psData,
\r
679 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
682 uint8_t socketFound = FALSE;
\r
683 phFriNfc_LlcpTransport_Socket_t *pLlcpSocket = NULL;
\r
684 phFriNfc_LlcpTransport_Socket_t *psLocalLlcpSocket = NULL;
\r
685 pphFriNfc_LlcpTransportSocketListenCb_t pListen_Cb = NULL;
\r
686 void *pListenContext = NULL;
\r
688 phNfc_sData_t sServiceName;
\r
689 uint8_t remoteRW = PHFRINFC_LLCP_RW_DEFAULT;
\r
690 uint16_t remoteMIU = PHFRINFC_LLCP_MIU_DEFAULT;
\r
692 status = phFriNfc_Llcp_GetSocket_Params(psData,
\r
697 if(status != NFCSTATUS_SUCCESS)
\r
699 /* Incorrect TLV */
\r
701 status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
\r
703 PHFRINFC_LLCP_PTYPE_CONNECT,
\r
717 if(dsap == PHFRINFC_LLCP_SAP_SDP)
\r
719 /* Search a socket with the SN */
\r
720 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
722 /* Test if the socket is in Listen state and if its SN is the good one */
\r
723 if(psTransport->pSocketTable[index].bSocketListenPending
\r
724 && (sServiceName.length == psTransport->pSocketTable[index].sServiceName.length)
\r
725 && !memcmp(sServiceName.buffer,psTransport->pSocketTable[index].sServiceName.buffer,sServiceName.length))
\r
727 /* socket with the SN found */
\r
728 socketFound = TRUE;
\r
730 psLocalLlcpSocket = &psTransport->pSocketTable[index];
\r
732 /* Get the new ssap number, it is the ssap number of the socket found */
\r
733 dsap = psLocalLlcpSocket->socket_sSap;
\r
734 /* Get the ListenCB of the socket */
\r
735 pListen_Cb = psLocalLlcpSocket->pfSocketListen_Cb;
\r
736 pListenContext = psLocalLlcpSocket->pListenContext;
\r
743 /* Search a socket with the DSAP */
\r
744 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
746 /* Test if the socket is in Listen state and if its port number is the good one */
\r
747 if(psTransport->pSocketTable[index].bSocketListenPending && psTransport->pSocketTable[index].socket_sSap == dsap)
\r
749 /* socket with the SN found */
\r
750 socketFound = TRUE;
\r
752 psLocalLlcpSocket = &psTransport->pSocketTable[index];
\r
754 /* Get the Listen CB and the Context of the socket */
\r
755 pListen_Cb = psLocalLlcpSocket->pfSocketListen_Cb;
\r
756 pListenContext = psLocalLlcpSocket->pListenContext;
\r
763 /* Test if a socket has beeen found */
\r
766 /* Reset the FLAG socketFound*/
\r
767 socketFound = FALSE;
\r
769 /* Search a socket free and no socket connect on this DSAP*/
\r
770 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
772 if(psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDefault && socketFound != TRUE)
\r
774 socketFound = TRUE;
\r
776 psTransport->pSocketTable[index].index = index;
\r
777 psTransport->socketIndex = psTransport->pSocketTable[index].index;
\r
779 /* Create a communication socket */
\r
780 pLlcpSocket = &psTransport->pSocketTable[index];
\r
782 /* Set the communication option of the Remote Socket */
\r
783 pLlcpSocket->remoteMIU = remoteMIU;
\r
784 pLlcpSocket->remoteRW = remoteRW;
\r
786 /* Set SSAP/DSAP of the new socket created for the communication with the remote */
\r
787 pLlcpSocket->socket_dSap = ssap;
\r
788 pLlcpSocket->socket_sSap = dsap;
\r
790 /* Set the state and the type of the new socket */
\r
791 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound;
\r
792 pLlcpSocket->eSocket_Type = phFriNfc_LlcpTransport_eConnectionOriented;
\r
795 else if(((psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
\r
796 || (psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketAccepted))
\r
797 && ((psTransport->pSocketTable[index].socket_sSap == ssap)&&(psTransport->pSocketTable[index].socket_dSap == dsap)))
\r
800 socketFound = FALSE;
\r
802 if(pLlcpSocket != NULL)
\r
804 /* Reset Socket Information */
\r
805 pLlcpSocket->remoteMIU = 0;
\r
806 pLlcpSocket->remoteRW = 0;
\r
808 /* Set SSAP/DSAP of the new socket created for the communication with the remote */
\r
809 pLlcpSocket->socket_dSap = 0;
\r
810 pLlcpSocket->socket_sSap = 0;
\r
812 /* Set the state and the type of the new socket */
\r
813 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDefault;
\r
814 pLlcpSocket->eSocket_Type = phFriNfc_LlcpTransport_eDefaultType;
\r
822 /* Test if a socket has been found */
\r
825 /* Call the Listen CB */
\r
826 pListen_Cb(pListenContext,pLlcpSocket);
\r
830 /* No more socket are available */
\r
831 /* Send a DM (0x21) */
\r
832 status = phFriNfc_Llcp_Send_DisconnectMode_Frame (psTransport,
\r
835 PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE);
\r
840 /* Service Name not found or Port number not found */
\r
841 /* Send a DM (0x02) */
\r
842 status = phFriNfc_Llcp_Send_DisconnectMode_Frame (psTransport,
\r
845 PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND);
\r
849 /* TODO: comment function Handle_ConnectFrame */
\r
850 static void Handle_ConnectionCompleteFrame(phFriNfc_LlcpTransport_t *psTransport,
\r
851 phNfc_sData_t *psData,
\r
855 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
857 uint8_t remoteRW = PHFRINFC_LLCP_RW_DEFAULT;
\r
858 uint16_t remoteMIU = PHFRINFC_LLCP_MIU_DEFAULT;
\r
859 uint8_t socketFound = FALSE;
\r
860 phFriNfc_LlcpTransport_Socket_t* psLocalLlcpSocket = NULL;
\r
862 status = phFriNfc_Llcp_GetSocket_Params(psData,
\r
867 if(status != NFCSTATUS_SUCCESS)
\r
869 /* Incorrect TLV */
\r
871 status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
\r
873 PHFRINFC_LLCP_PTYPE_CC,
\r
887 /* Search a socket in connecting state and with the good SSAP */
\r
888 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
890 /* Test if the socket is in Connecting state and if its SSAP number is the good one */
\r
891 if(psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnecting
\r
892 && psTransport->pSocketTable[index].socket_sSap == dsap)
\r
894 /* socket with the SN found */
\r
895 socketFound = TRUE;
\r
897 /* Update the DSAP value with the incomming Socket sSap */
\r
898 psTransport->pSocketTable[index].socket_dSap = ssap;
\r
900 /* Store a pointer to the socket found */
\r
901 psLocalLlcpSocket = &psTransport->pSocketTable[index];
\r
905 /* Test if a socket has been found */
\r
908 /* Set the socket state to connected */
\r
909 psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnected;
\r
911 /* Reset the socket_VS,socket_VR,socket_VSA and socket_VRA variables */
\r
912 psLocalLlcpSocket->socket_VR = 0;
\r
913 psLocalLlcpSocket->socket_VRA = 0;
\r
914 psLocalLlcpSocket->socket_VS = 0;
\r
915 psLocalLlcpSocket->socket_VSA = 0;
\r
917 /* Store the Remote parameters (MIU,RW) */
\r
918 psLocalLlcpSocket->remoteMIU = remoteMIU;
\r
919 psLocalLlcpSocket->remoteRW = remoteRW;
\r
921 /* Call the Connect CB and reset callback info */
\r
922 psLocalLlcpSocket->pfSocketConnect_Cb(psLocalLlcpSocket->pConnectContext,0x00,NFCSTATUS_SUCCESS);
\r
923 psLocalLlcpSocket->pfSocketConnect_Cb = NULL;
\r
924 psLocalLlcpSocket->pConnectContext = NULL;
\r
928 /* No socket Active */
\r
929 /* CC Frame not handled */
\r
934 /* TODO: comment function Handle_DisconnectFrame */
\r
935 static void Handle_DisconnectFrame(phFriNfc_LlcpTransport_t *psTransport,
\r
939 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
941 uint8_t socketFound = FALSE;
\r
942 phFriNfc_LlcpTransport_Socket_t* psLocalLlcpSocket = NULL;
\r
944 /* Search a socket in connected state and the good SSAP */
\r
945 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
947 /* Test if the socket is in Connected state and if its SSAP number is the good one */
\r
948 if(psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected
\r
949 && psTransport->pSocketTable[index].socket_sSap == dsap)
\r
952 socketFound = TRUE;
\r
954 /* Store a pointer to the socket found */
\r
955 psLocalLlcpSocket = &psTransport->pSocketTable[index];
\r
960 /* Test if a socket has been found */
\r
963 /* Test if a send IFRAME is pending with this socket */
\r
964 if((psLocalLlcpSocket->bSocketSendPending == TRUE) || (psLocalLlcpSocket->bSocketRecvPending == TRUE))
\r
966 /* Call the send CB, a disconnect abort the send request */
\r
967 if (psLocalLlcpSocket->pfSocketSend_Cb != NULL && psLocalLlcpSocket->bSocketSendPending == TRUE)
\r
969 /* Copy CB + context in local variables */
\r
970 pphFriNfc_LlcpTransportSocketSendCb_t pfSendCb = psLocalLlcpSocket->pfSocketSend_Cb;
\r
971 void* pSendContext = psLocalLlcpSocket->pSendContext;
\r
972 /* Reset CB + context */
\r
973 psLocalLlcpSocket->pfSocketSend_Cb = NULL;
\r
974 psLocalLlcpSocket->pSendContext = NULL;
\r
975 /* Perform callback */
\r
976 pfSendCb(pSendContext, NFCSTATUS_FAILED);
\r
978 /* Call the send CB, a disconnect abort the receive request */
\r
979 if (psLocalLlcpSocket->pfSocketRecv_Cb != NULL && psLocalLlcpSocket->bSocketRecvPending == TRUE)
\r
981 /* Copy CB + context in local variables */
\r
982 pphFriNfc_LlcpTransportSocketRecvCb_t pfRecvCb = psLocalLlcpSocket->pfSocketRecv_Cb;
\r
983 void* pRecvContext = psLocalLlcpSocket->pRecvContext;
\r
984 /* Reset CB + context */
\r
985 psLocalLlcpSocket->pfSocketRecv_Cb = NULL;
\r
986 psLocalLlcpSocket->pRecvContext = NULL;
\r
987 /* Perform callback */
\r
988 pfRecvCb(pRecvContext, NFCSTATUS_FAILED);
\r
990 psLocalLlcpSocket->bSocketRecvPending = FALSE;
\r
991 psLocalLlcpSocket->bSocketSendPending = FALSE;
\r
994 /* Test if a send is pending with this scoket */
\r
995 if(psTransport->bSendPending)
\r
997 /* Set DM pending */
\r
998 psTransport->bDmPending = TRUE;
\r
1000 /* Set the socket disconnecting */
\r
1001 psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
\r
1003 /* Send pending, store the DISC request */
\r
1004 psTransport->DmInfoBuffer[0] = ssap;
\r
1005 psTransport->DmInfoBuffer[1] = dsap;
\r
1006 psTransport->DmInfoBuffer[2] = PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED;
\r
1010 /* Set the socket disconnected */
\r
1011 psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
\r
1013 /* Store the index of the socket */
\r
1014 psTransport->socketIndex = psLocalLlcpSocket->index;
\r
1017 status = phFriNfc_Llcp_Send_DisconnectMode_Frame(psTransport,
\r
1020 PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED);
\r
1022 /* Call ErrCB due to a DISC */
\r
1023 psTransport->pSocketTable[index].pSocketErrCb(psTransport->pSocketTable[index].pContext, PHFRINFC_LLCP_ERR_DISCONNECTED);
\r
1028 /* No socket Active */
\r
1029 /* DISC Frame not handled */
\r
1033 /* TODO: comment function Handle_ConnectFrame */
\r
1034 static void Handle_DisconnetModeFrame(phFriNfc_LlcpTransport_t *psTransport,
\r
1035 phNfc_sData_t *psData,
\r
1039 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
1041 uint8_t socketFound = FALSE;
\r
1043 phFriNfc_LlcpTransport_Socket_t *psLocalLlcpSocket = NULL;
\r
1045 /* Test if the DM buffer is correct */
\r
1046 if(psData->length != PHFRINFC_LLCP_DM_LENGTH)
\r
1049 status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
\r
1051 PHFRINFC_LLCP_PTYPE_DM,
\r
1065 /* Search a socket waiting for a DM (Disconnecting State) */
\r
1066 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
1068 /* Test if the socket is in Disconnecting or connecting state and if its SSAP number is the good one */
\r
1069 if((psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketDisconnecting
\r
1070 || psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnecting)
\r
1071 && psTransport->pSocketTable[index].socket_sSap == dsap)
\r
1073 /* socket found */
\r
1074 socketFound = TRUE;
\r
1076 /* Store a pointer to the socket found */
\r
1077 psLocalLlcpSocket = &psTransport->pSocketTable[index];
\r
1082 /* Test if a socket has been found */
\r
1085 /* Set dmOpcode */
\r
1086 dmOpCode = psData->buffer[0];
\r
1090 case PHFRINFC_LLCP_DM_OPCODE_DISCONNECTED:
\r
1092 /* Set the socket state to disconnected */
\r
1093 psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
\r
1095 /* Call Disconnect CB */
\r
1096 if (psLocalLlcpSocket->pfSocketDisconnect_Cb != NULL)
\r
1098 psLocalLlcpSocket->pfSocketDisconnect_Cb(psLocalLlcpSocket->pDisonnectContext,NFCSTATUS_SUCCESS);
\r
1099 psLocalLlcpSocket->pfSocketDisconnect_Cb = NULL;
\r
1104 case PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED:
\r
1105 case PHFRINFC_LLCP_DM_OPCODE_CONNECT_NOT_ACCEPTED:
\r
1106 case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_ACTIVE:
\r
1107 case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND:
\r
1108 case PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE:
\r
1110 /* Set the socket state to bound */
\r
1111 psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketCreated;
\r
1112 if(psLocalLlcpSocket->pfSocketConnect_Cb != NULL)
\r
1114 /* Call Connect CB */
\r
1115 psLocalLlcpSocket->pfSocketConnect_Cb(psLocalLlcpSocket->pConnectContext,dmOpCode,NFCSTATUS_FAILED);
\r
1116 psLocalLlcpSocket->pfSocketConnect_Cb = NULL;
\r
1124 /* TODO: comment function Handle_Receive_IFrame */
\r
1125 static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t *psTransport,
\r
1126 phNfc_sData_t *psData,
\r
1130 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
1132 phFriNfc_LlcpTransport_Socket_t* psLocalLlcpSocket = NULL;
\r
1133 phFriNfc_Llcp_sPacketSequence_t sLlcpLocalSequence;
\r
1135 uint32_t dataLengthAvailable = 0;
\r
1136 uint32_t dataLengthWrite = 0;
\r
1138 uint8_t socketFound = FALSE;
\r
1139 uint8_t WFlag = 0;
\r
1140 uint8_t IFlag = 0;
\r
1141 uint8_t RFlag = 0;
\r
1142 uint8_t SFlag = 0;
\r
1144 uint32_t offset = 0;
\r
1145 uint32_t rw_offset;
\r
1147 /* Get NS and NR Value of the I Frame*/
\r
1148 phFriNfc_Llcp_Buffer2Sequence( psData->buffer, offset, &sLlcpLocalSequence);
\r
1151 /* Update the buffer pointer */
\r
1152 psData->buffer = psData->buffer + PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;
\r
1154 /* Update the length value (without the header length) */
\r
1155 psData->length = psData->length - PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;
\r
1157 /* Search a socket waiting for an I FRAME (Connected State) */
\r
1158 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
1160 /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
\r
1161 if(( (psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
\r
1162 || (psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketAccepted))
\r
1163 && psTransport->pSocketTable[index].socket_sSap == dsap
\r
1164 && psTransport->pSocketTable[index].socket_dSap == ssap)
\r
1166 /* socket found */
\r
1167 socketFound = TRUE;
\r
1169 /* Store a pointer to the socket found */
\r
1170 psLocalLlcpSocket = &psTransport->pSocketTable[index];
\r
1175 /* Test if a socket has been found */
\r
1179 /*if(sLlcpLocalSequence.ns != psLocalLlcpSocket->socket_VR)
\r
1184 /* Calculate offset of current frame in RW, and check validity */
\r
1185 if(sLlcpLocalSequence.ns >= psLocalLlcpSocket->socket_VRA)
\r
1187 rw_offset = sLlcpLocalSequence.ns - psLocalLlcpSocket->socket_VRA;
\r
1191 rw_offset = 16 - (psLocalLlcpSocket->socket_VRA - sLlcpLocalSequence.ns);
\r
1193 if(rw_offset >= psLocalLlcpSocket->localRW)
\r
1199 /* Check Info length */
\r
1200 if(psData->length > (uint32_t)(psLocalLlcpSocket->localMIUX + PHFRINFC_LLCP_MIU_DEFAULT))
\r
1207 nr_val = (uint8_t)sLlcpLocalSequence.nr;
\r
1210 if(nr_val == psLocalLlcpSocket->socket_VS)
\r
1215 nr_val = (nr_val+1)%16;
\r
1217 if(nr_val == psLocalLlcpSocket->socket_VSA)
\r
1223 }while(nr_val != sLlcpLocalSequence.nr);
\r
1226 if( WFlag != 0 || IFlag != 0 || RFlag != 0 || SFlag != 0)
\r
1229 status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
\r
1231 PHFRINFC_LLCP_PTYPE_I,
\r
1233 &sLlcpLocalSequence,
\r
1238 psLocalLlcpSocket->socket_VS,
\r
1239 psLocalLlcpSocket->socket_VSA,
\r
1240 psLocalLlcpSocket->socket_VR,
\r
1241 psLocalLlcpSocket->socket_VRA);
\r
1246 /* Test if the Linear Buffer length is null */
\r
1247 if(psLocalLlcpSocket->bufferLinearLength == 0)
\r
1249 /* Test if a Receive is pending and RW empty */
\r
1250 if(psLocalLlcpSocket->bSocketRecvPending == TRUE && (psLocalLlcpSocket->indexRwWrite == psLocalLlcpSocket->indexRwRead))
\r
1253 psTransport->pSocketTable[psTransport->socketIndex].bSocketRecvPending = FALSE;
\r
1255 /* Save I_FRAME into the Receive Buffer */
\r
1256 memcpy(psLocalLlcpSocket->sSocketRecvBuffer->buffer,psData->buffer,psData->length);
\r
1257 psLocalLlcpSocket->sSocketRecvBuffer->length = psData->length;
\r
1260 psLocalLlcpSocket->socket_VR = (psLocalLlcpSocket->socket_VR+1)%16;
\r
1263 psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
\r
1265 /* Call the Receive CB */
\r
1266 psLocalLlcpSocket->pfSocketRecv_Cb(psLocalLlcpSocket->pRecvContext, NFCSTATUS_SUCCESS);
\r
1267 psLocalLlcpSocket->pfSocketRecv_Cb = NULL;
\r
1269 /* Test if a send is pending with this socket */
\r
1270 if(psLocalLlcpSocket->bSocketSendPending == TRUE && CHECK_SEND_RW(psLocalLlcpSocket))
\r
1272 /* Test if a send is pending at LLC layer */
\r
1273 if(psTransport->bSendPending != TRUE)
\r
1275 status = static_performSendInfo(psLocalLlcpSocket);
\r
1281 status = phFriNfc_Llcp_Send_ReceiveReady_Frame(psLocalLlcpSocket);
\r
1286 /* Test if RW is full */
\r
1287 if((psLocalLlcpSocket->indexRwWrite - psLocalLlcpSocket->indexRwRead)<psLocalLlcpSocket->localRW)
\r
1289 if(psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length == 0)
\r
1291 /* Save I_FRAME into the RW Buffers */
\r
1292 memcpy(psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].buffer,psData->buffer,psData->length);
\r
1293 psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = psData->length;
\r
1295 if(psLocalLlcpSocket->ReceiverBusyCondition != TRUE)
\r
1297 /* Receiver Busy condition */
\r
1298 psLocalLlcpSocket->ReceiverBusyCondition = TRUE;
\r
1301 status = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(psLocalLlcpSocket);
\r
1303 /* Update the RW write index */
\r
1304 psLocalLlcpSocket->indexRwWrite++;
\r
1311 /* Copy the buffer into the RW buffer */
\r
1312 memcpy(psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].buffer,psData->buffer,psData->length);
\r
1314 /* Update the length */
\r
1315 psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = psData->length;
\r
1317 /* Test the length of the available place in the linear buffer */
\r
1318 dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&psLocalLlcpSocket->sCyclicFifoBuffer);
\r
1320 if(dataLengthAvailable >= psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length)
\r
1322 /* Store Data into the linear buffer */
\r
1323 dataLengthWrite = phFriNfc_Llcp_CyclicFifoWrite(&psLocalLlcpSocket->sCyclicFifoBuffer,
\r
1324 psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].buffer,
\r
1325 psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length);
\r
1328 psLocalLlcpSocket->socket_VR = (psLocalLlcpSocket->socket_VR+1)%16;
\r
1331 psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
\r
1333 /* Update the length */
\r
1334 psLocalLlcpSocket->sSocketRwBufferTable[(psLocalLlcpSocket->indexRwWrite%psLocalLlcpSocket->localRW)].length = 0x00;
\r
1336 /* Test if a Receive Pending*/
\r
1337 if(psLocalLlcpSocket->bSocketRecvPending == TRUE)
\r
1340 psLocalLlcpSocket->bSocketRecvPending = FALSE;
\r
1342 phFriNfc_LlcpTransport_ConnectionOriented_Recv(psLocalLlcpSocket,
\r
1343 psLocalLlcpSocket->sSocketRecvBuffer,
\r
1344 psLocalLlcpSocket->pfSocketRecv_Cb,
\r
1345 psLocalLlcpSocket->pRecvContext);
\r
1348 /* Test if a send is pending with this socket */
\r
1349 if((psLocalLlcpSocket->bSocketSendPending == TRUE) && CHECK_SEND_RW(psLocalLlcpSocket))
\r
1351 /* Test if a send is pending at LLC layer */
\r
1352 if(psTransport->bSendPending != TRUE)
\r
1354 status = static_performSendInfo(psLocalLlcpSocket);
\r
1360 status = phFriNfc_Llcp_Send_ReceiveReady_Frame(psLocalLlcpSocket);
\r
1365 if(psLocalLlcpSocket->ReceiverBusyCondition != TRUE)
\r
1367 /* Receiver Busy condition */
\r
1368 psLocalLlcpSocket->ReceiverBusyCondition = TRUE;
\r
1371 status = phFriNfc_Llcp_Send_ReceiveNotReady_Frame(psLocalLlcpSocket);
\r
1374 /* Update the RW write index */
\r
1375 psLocalLlcpSocket->indexRwWrite++;
\r
1382 /* No active socket*/
\r
1383 /* I FRAME not Handled */
\r
1387 static void Handle_ReceiveReady_Frame(phFriNfc_LlcpTransport_t *psTransport,
\r
1388 phNfc_sData_t *psData,
\r
1392 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
1394 uint8_t socketFound = FALSE;
\r
1395 uint8_t WFlag = 0;
\r
1396 uint8_t IFlag = 0;
\r
1397 uint8_t RFlag = 0;
\r
1398 uint8_t SFlag = 0;
\r
1399 uint32_t offset = 0;
\r
1402 phFriNfc_LlcpTransport_Socket_t* psLocalLlcpSocket = NULL;
\r
1403 phFriNfc_Llcp_sPacketSequence_t sLlcpLocalSequence;
\r
1405 /* Get NS and NR Value of the I Frame*/
\r
1406 phFriNfc_Llcp_Buffer2Sequence( psData->buffer, offset, &sLlcpLocalSequence);
\r
1408 /* Search a socket waiting for an RR FRAME (Connected State) */
\r
1409 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
1411 /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
\r
1412 if(psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected
\r
1413 && psTransport->pSocketTable[index].socket_sSap == dsap
\r
1414 && psTransport->pSocketTable[index].socket_dSap == ssap)
\r
1416 /* socket found */
\r
1417 socketFound = TRUE;
\r
1419 /* Store a pointer to the socket found */
\r
1420 psLocalLlcpSocket = &psTransport->pSocketTable[index];
\r
1421 psLocalLlcpSocket->index = psTransport->pSocketTable[index].index;
\r
1426 /* Test if a socket has been found */
\r
1430 nr_val = (uint8_t)sLlcpLocalSequence.nr;
\r
1433 if(nr_val == psLocalLlcpSocket->socket_VS)
\r
1438 nr_val = (nr_val+1)%16;
\r
1440 if(nr_val == psLocalLlcpSocket->socket_VSA)
\r
1446 }while(nr_val != sLlcpLocalSequence.nr);
\r
1449 /* Test if Info field present */
\r
1450 if(psData->length > 1)
\r
1456 if (WFlag || IFlag || RFlag || SFlag)
\r
1459 status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
\r
1460 ssap, PHFRINFC_LLCP_PTYPE_RR, dsap,
\r
1461 &sLlcpLocalSequence,
\r
1462 WFlag, IFlag, RFlag, SFlag,
\r
1463 psLocalLlcpSocket->socket_VS,
\r
1464 psLocalLlcpSocket->socket_VSA,
\r
1465 psLocalLlcpSocket->socket_VR,
\r
1466 psLocalLlcpSocket->socket_VRA);
\r
1470 /* Test Receiver Busy condition */
\r
1471 if(psLocalLlcpSocket->RemoteBusyConditionInfo == TRUE)
\r
1473 /* Notify the upper layer */
\r
1474 psLocalLlcpSocket->pSocketErrCb(psLocalLlcpSocket->pContext,PHFRINFC_LLCP_ERR_NOT_BUSY_CONDITION);
\r
1475 psLocalLlcpSocket->RemoteBusyConditionInfo = FALSE;
\r
1478 psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
\r
1480 /* Test if a send is pendind */
\r
1481 if(psLocalLlcpSocket->bSocketSendPending == TRUE)
\r
1483 /* Test the RW window */
\r
1484 if(CHECK_SEND_RW(psLocalLlcpSocket))
\r
1486 /* Test if a send is pending at LLC layer */
\r
1487 if(psTransport->bSendPending != TRUE)
\r
1489 status = static_performSendInfo(psLocalLlcpSocket);
\r
1497 /* No active socket*/
\r
1498 /* RR Frame not handled*/
\r
1502 static void Handle_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_t *psTransport,
\r
1503 phNfc_sData_t *psData,
\r
1507 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
1509 uint8_t socketFound = FALSE;
\r
1510 bool_t bWFlag = 0;
\r
1511 bool_t bIFlag = 0;
\r
1512 bool_t bRFlag = 0;
\r
1513 bool_t bSFlag = 0;
\r
1514 uint32_t offset = 0;
\r
1517 phFriNfc_LlcpTransport_Socket_t* psLocalLlcpSocket = NULL;
\r
1518 phFriNfc_Llcp_sPacketSequence_t sLlcpLocalSequence;
\r
1520 /* Get NS and NR Value of the I Frame*/
\r
1521 phFriNfc_Llcp_Buffer2Sequence( psData->buffer, offset, &sLlcpLocalSequence);
\r
1523 /* Search a socket waiting for an RNR FRAME (Connected State) */
\r
1524 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
1526 /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
\r
1527 if(psTransport->pSocketTable[index].eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected
\r
1528 && psTransport->pSocketTable[index].socket_sSap == dsap
\r
1529 && psTransport->pSocketTable[index].socket_dSap == ssap)
\r
1531 /* socket found */
\r
1532 socketFound = TRUE;
\r
1534 /* Store a pointer to the socket found */
\r
1535 psLocalLlcpSocket = &psTransport->pSocketTable[index];
\r
1540 /* Test if a socket has been found */
\r
1544 nr_val = (uint8_t)sLlcpLocalSequence.nr;
\r
1548 if(nr_val == psLocalLlcpSocket->socket_VS)
\r
1553 nr_val = (nr_val+1)%16;
\r
1555 if(nr_val == psLocalLlcpSocket->socket_VSA)
\r
1561 }while(nr_val != sLlcpLocalSequence.nr);
\r
1563 /* Test if Info field present */
\r
1564 if(psData->length > 1)
\r
1571 if( bWFlag != 0 || bIFlag != 0 || bRFlag != 0 || bSFlag != 0)
\r
1574 status = phFriNfc_Llcp_Send_FrameReject_Frame(psTransport,
\r
1575 ssap, PHFRINFC_LLCP_PTYPE_RNR, dsap,
\r
1576 &sLlcpLocalSequence,
\r
1577 bWFlag, bIFlag, bRFlag, bSFlag,
\r
1578 psLocalLlcpSocket->socket_VS,
\r
1579 psLocalLlcpSocket->socket_VSA,
\r
1580 psLocalLlcpSocket->socket_VR,
\r
1581 psLocalLlcpSocket->socket_VRA);
\r
1585 /* Notify the upper layer */
\r
1586 psLocalLlcpSocket->pSocketErrCb(psTransport->pSocketTable[index].pContext,PHFRINFC_LLCP_ERR_BUSY_CONDITION);
\r
1587 psLocalLlcpSocket->RemoteBusyConditionInfo = TRUE;
\r
1590 psLocalLlcpSocket->socket_VSA = (uint8_t)sLlcpLocalSequence.nr;
\r
1592 /* Test if a send is pendind */
\r
1593 if(psLocalLlcpSocket->bSocketSendPending == TRUE && CHECK_SEND_RW(psLocalLlcpSocket))
\r
1595 /* Test if a send is pending at LLC layer */
\r
1596 if(psTransport->bSendPending != TRUE)
\r
1598 status = static_performSendInfo(psLocalLlcpSocket);
\r
1605 /* No active socket*/
\r
1606 /* RNR Frame not handled*/
\r
1610 static void Handle_FrameReject_Frame(phFriNfc_LlcpTransport_t *psTransport,
\r
1614 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
1616 uint8_t socketFound = FALSE;
\r
1618 /* Search a socket waiting for a FRAME */
\r
1619 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
1621 /* Test if the socket is in connected state and if its SSAP and DSAP are valid */
\r
1622 if(psTransport->pSocketTable[index].socket_sSap == dsap
\r
1623 && psTransport->pSocketTable[index].socket_dSap == ssap)
\r
1625 /* socket found */
\r
1626 socketFound = TRUE;
\r
1631 /* Test if a socket has been found */
\r
1634 /* Set socket state to disconnected */
\r
1635 psTransport->pSocketTable[index].eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnected;
\r
1637 /* Call ErrCB due to a FRMR*/
\r
1638 psTransport->pSocketTable[index].pSocketErrCb( psTransport->pSocketTable[index].pContext,PHFRINFC_LLCP_ERR_FRAME_REJECTED);
\r
1640 /* Close the socket */
\r
1641 status = phFriNfc_LlcpTransport_ConnectionOriented_Close(&psTransport->pSocketTable[index]);
\r
1645 /* No active socket*/
\r
1646 /* FRMR Frame not handled*/
\r
1650 /* TODO: comment function Handle_ConnectionOriented_IncommingFrame */
\r
1651 void Handle_ConnectionOriented_IncommingFrame(phFriNfc_LlcpTransport_t *psTransport,
\r
1652 phNfc_sData_t *psData,
\r
1657 phFriNfc_Llcp_sPacketSequence_t sSequence = {0,0};
\r
1661 case PHFRINFC_LLCP_PTYPE_CONNECT:
\r
1663 Handle_ConnectionFrame(psTransport,
\r
1669 case PHFRINFC_LLCP_PTYPE_DISC:
\r
1671 Handle_DisconnectFrame(psTransport,
\r
1676 case PHFRINFC_LLCP_PTYPE_CC:
\r
1678 Handle_ConnectionCompleteFrame(psTransport,
\r
1684 case PHFRINFC_LLCP_PTYPE_DM:
\r
1686 Handle_DisconnetModeFrame(psTransport,
\r
1692 case PHFRINFC_LLCP_PTYPE_FRMR:
\r
1694 Handle_FrameReject_Frame(psTransport,
\r
1699 case PHFRINFC_LLCP_PTYPE_I:
\r
1701 Handle_Receive_IFrame(psTransport,
\r
1707 case PHFRINFC_LLCP_PTYPE_RR:
\r
1709 Handle_ReceiveReady_Frame(psTransport,
\r
1715 case PHFRINFC_LLCP_PTYPE_RNR:
\r
1717 Handle_ReceiveNotReady_Frame(psTransport,
\r
1723 case PHFRINFC_LLCP_PTYPE_RESERVED1:
\r
1724 case PHFRINFC_LLCP_PTYPE_RESERVED2:
\r
1725 case PHFRINFC_LLCP_PTYPE_RESERVED3:
\r
1726 case PHFRINFC_LLCP_PTYPE_RESERVED4:
\r
1728 phFriNfc_Llcp_Send_FrameReject_Frame( psTransport,
\r
1729 dsap, ptype, ssap,
\r
1731 TRUE, FALSE, FALSE, FALSE,
\r
1738 * \ingroup grp_lib_nfc
\r
1739 * \brief <b>Get the local options of a socket</b>.
\r
1741 * This function returns the local options (maximum packet size and receive window size) used
\r
1742 * for a given connection-oriented socket. This function shall not be used with connectionless
\r
1745 * \param[out] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
1746 * \param[in] psLocalOptions A pointer to be filled with the local options of the socket.
\r
1748 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
1749 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
1750 * could not be properly interpreted.
\r
1751 * \retval NFCSTATUS_INVALID_STATE The socket is not in a valid state, or not of
\r
1752 * a valid type to perform the requsted operation.
\r
1753 * \retval NFCSTATUS_NOT_INITIALISED Indicates stack is not yet initialized.
\r
1754 * \retval NFCSTATUS_SHUTDOWN Shutdown in progress.
\r
1755 * \retval NFCSTATUS_FAILED Operation failed.
\r
1757 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetLocalOptions(phFriNfc_LlcpTransport_Socket_t *pLlcpSocket,
\r
1758 phLibNfc_Llcp_sSocketOptions_t *psLocalOptions)
\r
1760 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
1762 /* Get Local MIUX */
\r
1763 psLocalOptions->miu = pLlcpSocket->sSocketOption.miu;
\r
1765 /* Get Local Receive Window */
\r
1766 psLocalOptions->rw = pLlcpSocket->sSocketOption.rw;
\r
1772 * \ingroup grp_lib_nfc
\r
1773 * \brief <b>Get the local options of a socket</b>.
\r
1775 * This function returns the remote options (maximum packet size and receive window size) used
\r
1776 * for a given connection-oriented socket. This function shall not be used with connectionless
\r
1779 * \param[out] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
1780 * \param[in] psRemoteOptions A pointer to be filled with the remote options of the socket.
\r
1782 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
1783 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
1784 * could not be properly interpreted.
\r
1785 * \retval NFCSTATUS_INVALID_STATE The socket is not in a valid state, or not of
\r
1786 * a valid type to perform the requsted operation.
\r
1787 * \retval NFCSTATUS_NOT_INITIALISED Indicates stack is not yet initialized.
\r
1788 * \retval NFCSTATUS_SHUTDOWN Shutdown in progress.
\r
1789 * \retval NFCSTATUS_FAILED Operation failed.
\r
1791 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_SocketGetRemoteOptions(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
\r
1792 phLibNfc_Llcp_sSocketOptions_t* psRemoteOptions)
\r
1794 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
1796 /* Get Remote MIUX */
\r
1797 psRemoteOptions->miu = pLlcpSocket->remoteMIU;
\r
1799 /* Get Remote Receive Window */
\r
1800 psRemoteOptions->rw = pLlcpSocket->remoteRW;
\r
1807 * \ingroup grp_fri_nfc
\r
1808 * \brief <b>Listen for incoming connection requests on a socket</b>.
\r
1810 * This function switches a socket into a listening state and registers a callback on
\r
1811 * incoming connection requests. In this state, the socket is not able to communicate
\r
1812 * directly. The listening state is only available for connection-oriented sockets
\r
1813 * which are still not connected. The socket keeps listening until it is closed, and
\r
1814 * thus can trigger several times the pListen_Cb callback.
\r
1817 * \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
1818 * \param[in] psServiceName A pointer to a Service Name
\r
1819 * \param[in] pListen_Cb The callback to be called each time the
\r
1820 * socket receive a connection request.
\r
1821 * \param[in] pContext Upper layer context to be returned in
\r
1824 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
1825 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
1826 * could not be properly interpreted.
\r
1827 * \retval NFCSTATUS_INVALID_STATE The socket is not in a valid state to switch
\r
1828 * to listening state.
\r
1829 * \retval NFCSTATUS_FAILED Operation failed.
\r
1831 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Listen(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
\r
1832 phNfc_sData_t *psServiceName,
\r
1833 pphFriNfc_LlcpTransportSocketListenCb_t pListen_Cb,
\r
1836 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
1839 /* Check if the service name is already registered */
\r
1840 if (psServiceName != NULL)
\r
1842 for(index=0;index<PHFRINFC_LLCP_NB_SOCKET_MAX;index++)
\r
1844 phFriNfc_LlcpTransport_Socket_t* pCurrentSocket = &pLlcpSocket->psTransport->pSocketTable[index];
\r
1846 if((pCurrentSocket->sServiceName.length == 0) ||
\r
1847 (pCurrentSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketRegistered))
\r
1849 /* Do not check inactive or non-SDP registered sockets */
\r
1852 if(pCurrentSocket->sServiceName.length != psServiceName->length) {
\r
1853 /* Service name do not match, check next */
\r
1856 if(memcmp(pCurrentSocket->sServiceName.buffer, psServiceName->buffer, psServiceName->length) == 0)
\r
1858 /* Service name already in use */
\r
1859 return NFCSTATUS_INVALID_PARAMETER;
\r
1864 /* Store the listen callback */
\r
1865 pLlcpSocket->pfSocketListen_Cb = pListen_Cb;
\r
1867 /* store the context */
\r
1868 pLlcpSocket->pListenContext = pContext;
\r
1870 /* Set RecvPending to TRUE */
\r
1871 pLlcpSocket->bSocketListenPending = TRUE;
\r
1873 /* Store the listen socket SN */
\r
1874 pLlcpSocket->sServiceName.length = psServiceName->length;
\r
1875 pLlcpSocket->sServiceName.buffer = phOsalNfc_GetMemory(psServiceName->length);
\r
1876 if (pLlcpSocket->sServiceName.buffer == NULL)
\r
1878 return NFCSTATUS_NOT_ENOUGH_MEMORY;
\r
1880 memcpy(pLlcpSocket->sServiceName.buffer, psServiceName->buffer, psServiceName->length);
\r
1882 /* Set the socket state*/
\r
1883 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketRegistered;
\r
1889 * \ingroup grp_fri_nfc
\r
1890 * \brief <b>Accept an incoming connection request for a socket</b>.
\r
1892 * This functions allows the client to accept an incoming connection request.
\r
1893 * It must be used with the socket provided within the listen callback. The socket
\r
1894 * is implicitly switched to the connected state when the function is called.
\r
1896 * \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
1897 * \param[in] psOptions The options to be used with the socket.
\r
1898 * \param[in] psWorkingBuffer A working buffer to be used by the library.
\r
1899 * \param[in] pErr_Cb The callback to be called each time the accepted socket
\r
1901 * \param[in] pAccept_RspCb The callback to be called when the Accept operation is completed
\r
1902 * \param[in] pContext Upper layer context to be returned in the callback.
\r
1904 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
1905 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
1906 * could not be properly interpreted.
\r
1907 * \retval NFCSTATUS_BUFFER_TOO_SMALL The working buffer is too small for the MIU and RW
\r
1908 * declared in the options.
\r
1909 * \retval NFCSTATUS_FAILED Operation failed.
\r
1911 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Accept(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
\r
1912 phFriNfc_LlcpTransport_sSocketOptions_t* psOptions,
\r
1913 phNfc_sData_t* psWorkingBuffer,
\r
1914 pphFriNfc_LlcpTransportSocketErrCb_t pErr_Cb,
\r
1915 pphFriNfc_LlcpTransportSocketAcceptCb_t pAccept_RspCb,
\r
1919 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
1921 uint32_t offset = 0;
\r
1925 /* Store the options in the socket */
\r
1926 memcpy(&pLlcpSocket->sSocketOption, psOptions, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
\r
1928 /* Set socket local params (MIUX & RW) */
\r
1929 pLlcpSocket ->localMIUX = (pLlcpSocket->sSocketOption.miu - PHFRINFC_LLCP_MIU_DEFAULT) & PHFRINFC_LLCP_TLV_MIUX_MASK;
\r
1930 pLlcpSocket ->localRW = pLlcpSocket->sSocketOption.rw & PHFRINFC_LLCP_TLV_RW_MASK;
\r
1932 /* Set the pointer and the length for the Receive Window Buffer */
\r
1933 for(i=0;i<pLlcpSocket->localRW;i++)
\r
1935 pLlcpSocket->sSocketRwBufferTable[i].buffer = psWorkingBuffer->buffer + (i*pLlcpSocket->sSocketOption.miu);
\r
1936 pLlcpSocket->sSocketRwBufferTable[i].length = 0;
\r
1939 /* Set the pointer and the length for the Send Buffer */
\r
1940 pLlcpSocket->sSocketSendBuffer.buffer = psWorkingBuffer->buffer + pLlcpSocket->bufferRwMaxLength;
\r
1941 pLlcpSocket->sSocketSendBuffer.length = pLlcpSocket->bufferSendMaxLength;
\r
1943 /* Set the pointer and the length for the Linear Buffer */
\r
1944 pLlcpSocket->sSocketLinearBuffer.buffer = psWorkingBuffer->buffer + pLlcpSocket->bufferRwMaxLength + pLlcpSocket->bufferSendMaxLength;
\r
1945 pLlcpSocket->sSocketLinearBuffer.length = pLlcpSocket->bufferLinearLength;
\r
1947 if(pLlcpSocket->sSocketLinearBuffer.length != 0)
\r
1949 /* Init Cyclic Fifo */
\r
1950 phFriNfc_Llcp_CyclicFifoInit(&pLlcpSocket->sCyclicFifoBuffer,
\r
1951 pLlcpSocket->sSocketLinearBuffer.buffer,
\r
1952 pLlcpSocket->sSocketLinearBuffer.length);
\r
1955 pLlcpSocket->pSocketErrCb = pErr_Cb;
\r
1956 pLlcpSocket->pContext = pContext;
\r
1958 /* store the pointer to the Accept callback */
\r
1959 pLlcpSocket->pfSocketAccept_Cb = pAccept_RspCb;
\r
1960 pLlcpSocket->pAcceptContext = pContext;
\r
1962 /* Reset the socket_VS,socket_VR,socket_VSA and socket_VRA variables */
\r
1963 pLlcpSocket->socket_VR = 0;
\r
1964 pLlcpSocket->socket_VRA = 0;
\r
1965 pLlcpSocket->socket_VS = 0;
\r
1966 pLlcpSocket->socket_VSA = 0;
\r
1969 if(pLlcpSocket->localMIUX != PHFRINFC_LLCP_MIUX_DEFAULT)
\r
1971 /* Encode MIUX value */
\r
1972 phFriNfc_Llcp_EncodeMIUX(pLlcpSocket->localMIUX,
\r
1975 /* Encode MIUX in TLV format */
\r
1976 status = phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
\r
1978 PHFRINFC_LLCP_TLV_TYPE_MIUX,
\r
1979 PHFRINFC_LLCP_TLV_LENGTH_MIUX,
\r
1981 if(status != NFCSTATUS_SUCCESS)
\r
1984 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
\r
1985 goto clean_and_return;
\r
1989 /* Receive Window */
\r
1990 if(pLlcpSocket->sSocketOption.rw != PHFRINFC_LLCP_RW_DEFAULT)
\r
1992 /* Encode RW value */
\r
1993 phFriNfc_Llcp_EncodeRW(&pLlcpSocket->sSocketOption.rw);
\r
1995 /* Encode RW in TLV format */
\r
1996 status = phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
\r
1998 PHFRINFC_LLCP_TLV_TYPE_RW,
\r
1999 PHFRINFC_LLCP_TLV_LENGTH_RW,
\r
2000 &pLlcpSocket->sSocketOption.rw);
\r
2001 if(status != NFCSTATUS_SUCCESS)
\r
2004 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
\r
2005 goto clean_and_return;
\r
2010 /* Test if a send is pending */
\r
2011 if(pLlcpSocket->psTransport->bSendPending == TRUE)
\r
2013 pLlcpSocket->bSocketAcceptPending = TRUE;
\r
2015 /* Update Send Buffer length value */
\r
2016 pLlcpSocket->sSocketSendBuffer.length = offset;
\r
2018 status = NFCSTATUS_PENDING;
\r
2022 /* Fill the psLlcpHeader stuture with the DSAP,CC PTYPE and the SSAP */
\r
2023 pLlcpSocket->sLlcpHeader.dsap = pLlcpSocket->socket_dSap;
\r
2024 pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC;
\r
2025 pLlcpSocket->sLlcpHeader.ssap = pLlcpSocket->socket_sSap;
\r
2027 /* Set the socket state to accepted */
\r
2028 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketAccepted;
\r
2030 /* Update Send Buffer length value */
\r
2031 pLlcpSocket->sSocketSendBuffer.length = offset;
\r
2033 /* Store the index of the socket */
\r
2034 pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
\r
2036 /* Send a CC Frame */
\r
2037 status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
\r
2038 &pLlcpSocket->sLlcpHeader,
\r
2040 &pLlcpSocket->sSocketSendBuffer,
\r
2041 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
2042 pLlcpSocket->psTransport);
\r
2046 if(status != NFCSTATUS_PENDING)
\r
2048 LLCP_PRINT("Release Accept callback");
\r
2049 pLlcpSocket->pfSocketAccept_Cb = NULL;
\r
2050 pLlcpSocket->pAcceptContext = NULL;
\r
2057 * \ingroup grp_fri_nfc
\r
2058 * \brief <b>Reject an incoming connection request for a socket</b>.
\r
2060 * This functions allows the client to reject an incoming connection request.
\r
2061 * It must be used with the socket provided within the listen callback. The socket
\r
2062 * is implicitly closed when the function is called.
\r
2064 * \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
2066 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
2067 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
2068 * could not be properly interpreted.
\r
2069 * \retval NFCSTATUS_FAILED Operation failed.
\r
2071 NFCSTATUS phLibNfc_LlcpTransport_ConnectionOriented_Reject( phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
\r
2072 pphFriNfc_LlcpTransportSocketRejectCb_t pReject_RspCb,
\r
2075 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
2077 /* Set the state of the socket */
\r
2078 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketRejected;
\r
2080 /* Store the Reject callback */
\r
2081 pLlcpSocket->pfSocketSend_Cb = pReject_RspCb;
\r
2082 pLlcpSocket->pRejectContext = pContext;
\r
2084 /* Store the index of the socket */
\r
2085 pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
\r
2088 status = phFriNfc_Llcp_Send_DisconnectMode_Frame(pLlcpSocket->psTransport,
\r
2089 pLlcpSocket->socket_dSap,
\r
2090 pLlcpSocket->socket_sSap,
\r
2091 PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED);
\r
2097 * \ingroup grp_fri_nfc
\r
2098 * \brief <b>Try to establish connection with a socket on a remote SAP</b>.
\r
2100 * This function tries to connect to a given SAP on the remote peer. If the
\r
2101 * socket is not bound to a local SAP, it is implicitly bound to a free SAP.
\r
2103 * \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
2104 * \param[in] nSap The destination SAP to connect to.
\r
2105 * \param[in] psUri The URI corresponding to the destination SAP to connect to.
\r
2106 * \param[in] pConnect_RspCb The callback to be called when the connection
\r
2107 * operation is completed.
\r
2108 * \param[in] pContext Upper layer context to be returned in
\r
2111 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
2112 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
2113 * could not be properly interpreted.
\r
2114 * \retval NFCSTATUS_PENDING Connection operation is in progress,
\r
2115 * pConnect_RspCb will be called upon completion.
\r
2116 * \retval NFCSTATUS_INVALID_STATE The socket is not in a valid state, or not of
\r
2117 * a valid type to perform the requsted operation.
\r
2118 * \retval NFCSTATUS_FAILED Operation failed.
\r
2120 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Connect( phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
\r
2122 phNfc_sData_t* psUri,
\r
2123 pphFriNfc_LlcpTransportSocketConnectCb_t pConnect_RspCb,
\r
2126 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
2128 uint32_t offset = 0;
\r
2131 /* Test if a nSap is present */
\r
2132 if(nSap != PHFRINFC_LLCP_SAP_DEFAULT)
\r
2134 /* Set DSAP port number with the nSap value */
\r
2135 pLlcpSocket->socket_dSap = nSap;
\r
2139 /* Set DSAP port number with the SDP port number */
\r
2140 pLlcpSocket->socket_dSap = PHFRINFC_LLCP_SAP_SDP;
\r
2143 /* Store the Connect callback and context */
\r
2144 pLlcpSocket->pfSocketConnect_Cb = pConnect_RspCb;
\r
2145 pLlcpSocket->pConnectContext = pContext;
\r
2147 /* Set the socket Header */
\r
2148 pLlcpSocket->sLlcpHeader.dsap = pLlcpSocket->socket_dSap;
\r
2149 pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CONNECT;
\r
2150 pLlcpSocket->sLlcpHeader.ssap = pLlcpSocket->socket_sSap;
\r
2153 if(pLlcpSocket->localMIUX != PHFRINFC_LLCP_MIUX_DEFAULT)
\r
2155 /* Encode MIUX value */
\r
2156 phFriNfc_Llcp_EncodeMIUX(pLlcpSocket->localMIUX,
\r
2159 /* Encode MIUX in TLV format */
\r
2160 status = phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
\r
2162 PHFRINFC_LLCP_TLV_TYPE_MIUX,
\r
2163 PHFRINFC_LLCP_TLV_LENGTH_MIUX,
\r
2165 if(status != NFCSTATUS_SUCCESS)
\r
2167 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
\r
2168 goto clean_and_return;
\r
2172 /* Receive Window */
\r
2173 if(pLlcpSocket->sSocketOption.rw != PHFRINFC_LLCP_RW_DEFAULT)
\r
2175 /* Encode RW value */
\r
2176 phFriNfc_Llcp_EncodeRW(&pLlcpSocket->sSocketOption.rw);
\r
2178 /* Encode RW in TLV format */
\r
2179 status = phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
\r
2181 PHFRINFC_LLCP_TLV_TYPE_RW,
\r
2182 PHFRINFC_LLCP_TLV_LENGTH_RW,
\r
2183 &pLlcpSocket->sSocketOption.rw);
\r
2184 if(status != NFCSTATUS_SUCCESS)
\r
2186 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
\r
2187 goto clean_and_return;
\r
2191 /* Test if a Service Name is present */
\r
2194 /* Encode SN in TLV format */
\r
2195 status = phFriNfc_Llcp_EncodeTLV(&pLlcpSocket->sSocketSendBuffer,
\r
2197 PHFRINFC_LLCP_TLV_TYPE_SN,
\r
2198 (uint8_t)psUri->length,
\r
2200 if(status != NFCSTATUS_SUCCESS)
\r
2202 status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_FAILED);
\r
2203 goto clean_and_return;
\r
2207 /* Test if a send is pending */
\r
2208 if(pLlcpSocket->psTransport->bSendPending == TRUE)
\r
2210 pLlcpSocket->bSocketConnectPending = TRUE;
\r
2212 /* Update Send Buffer length value */
\r
2213 pLlcpSocket->sSocketSendBuffer.length = offset;
\r
2215 status = NFCSTATUS_PENDING;
\r
2219 /* Update Send Buffer length value */
\r
2220 pLlcpSocket->sSocketSendBuffer.length = offset;
\r
2222 /* Set the socket in connecting state */
\r
2223 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnecting;
\r
2225 /* Store the index of the socket */
\r
2226 pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
\r
2227 status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
\r
2228 &pLlcpSocket->sLlcpHeader,
\r
2230 &pLlcpSocket->sSocketSendBuffer,
\r
2231 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
2232 pLlcpSocket->psTransport);
\r
2236 if(status != NFCSTATUS_PENDING)
\r
2238 LLCP_PRINT("Release Connect callback");
\r
2239 pLlcpSocket->pfSocketConnect_Cb = NULL;
\r
2240 pLlcpSocket->pConnectContext = NULL;
\r
2248 * \ingroup grp_lib_nfc
\r
2249 * \brief <b>Disconnect a currently connected socket</b>.
\r
2251 * This function initiates the disconnection of a previously connected socket.
\r
2253 * \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
2254 * \param[in] pDisconnect_RspCb The callback to be called when the
\r
2255 * operation is completed.
\r
2256 * \param[in] pContext Upper layer context to be returned in
\r
2259 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
2260 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
2261 * could not be properly interpreted.
\r
2262 * \retval NFCSTATUS_PENDING Disconnection operation is in progress,
\r
2263 * pDisconnect_RspCb will be called upon completion.
\r
2264 * \retval NFCSTATUS_INVALID_STATE The socket is not in a valid state, or not of
\r
2265 * a valid type to perform the requsted operation.
\r
2266 * \retval NFCSTATUS_NOT_INITIALISED Indicates stack is not yet initialized.
\r
2267 * \retval NFCSTATUS_SHUTDOWN Shutdown in progress.
\r
2268 * \retval NFCSTATUS_FAILED Operation failed.
\r
2270 NFCSTATUS phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
\r
2271 pphLibNfc_LlcpSocketDisconnectCb_t pDisconnect_RspCb,
\r
2274 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
2276 /* Store the Disconnect callback and context*/
\r
2277 pLlcpSocket->pfSocketDisconnect_Cb = pDisconnect_RspCb;
\r
2278 pLlcpSocket->pDisonnectContext = pContext;
\r
2280 /* Set the socket in connecting state */
\r
2281 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting;
\r
2283 /* Test if a send IFRAME is pending with this socket */
\r
2284 if((pLlcpSocket->bSocketSendPending == TRUE) || (pLlcpSocket->bSocketRecvPending == TRUE))
\r
2286 pLlcpSocket->bSocketSendPending = FALSE;
\r
2287 pLlcpSocket->bSocketRecvPending = FALSE;
\r
2289 /* Call the send CB, a disconnect abort the send request */
\r
2290 if (pLlcpSocket->pfSocketSend_Cb != NULL)
\r
2292 /* Copy CB + context in local variables */
\r
2293 pphFriNfc_LlcpTransportSocketSendCb_t pfSendCb = pLlcpSocket->pfSocketSend_Cb;
\r
2294 void* pSendContext = pLlcpSocket->pSendContext;
\r
2295 /* Reset CB + context */
\r
2296 pLlcpSocket->pfSocketSend_Cb = NULL;
\r
2297 pLlcpSocket->pSendContext = NULL;
\r
2298 /* Perform callback */
\r
2299 pfSendCb(pSendContext, NFCSTATUS_FAILED);
\r
2301 /* Call the send CB, a disconnect abort the receive request */
\r
2302 if (pLlcpSocket->pfSocketRecv_Cb != NULL)
\r
2304 /* Copy CB + context in local variables */
\r
2305 pphFriNfc_LlcpTransportSocketRecvCb_t pfRecvCb = pLlcpSocket->pfSocketRecv_Cb;
\r
2306 void* pRecvContext = pLlcpSocket->pRecvContext;
\r
2307 /* Reset CB + context */
\r
2308 pLlcpSocket->pfSocketRecv_Cb = NULL;
\r
2309 pLlcpSocket->pRecvContext = NULL;
\r
2310 /* Perform callback */
\r
2311 pfRecvCb(pRecvContext, NFCSTATUS_FAILED);
\r
2315 /* Set the socket Header */
\r
2316 pLlcpSocket->sLlcpHeader.dsap = pLlcpSocket->socket_dSap;
\r
2317 pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_DISC;
\r
2318 pLlcpSocket->sLlcpHeader.ssap = pLlcpSocket->socket_sSap;
\r
2320 /* Test if a send is pending */
\r
2321 if( pLlcpSocket->psTransport->bSendPending == TRUE)
\r
2323 pLlcpSocket->bSocketDiscPending = TRUE;
\r
2324 status = NFCSTATUS_PENDING;
\r
2328 /* Store the index of the socket */
\r
2329 pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index;
\r
2331 status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp,
\r
2332 &pLlcpSocket->sLlcpHeader,
\r
2335 phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB,
\r
2336 pLlcpSocket->psTransport);
\r
2337 if(status != NFCSTATUS_PENDING)
\r
2339 LLCP_PRINT("Release Disconnect callback");
\r
2340 pLlcpSocket->pfSocketConnect_Cb = NULL;
\r
2341 pLlcpSocket->pConnectContext = NULL;
\r
2348 /* TODO: comment function phFriNfc_LlcpTransport_Connectionless_SendTo_CB */
\r
2349 static void phFriNfc_LlcpTransport_ConnectionOriented_DisconnectClose_CB(void* pContext,
\r
2352 phFriNfc_LlcpTransport_Socket_t *pLlcpSocket = (phFriNfc_LlcpTransport_Socket_t*)pContext;
\r
2354 if(status == NFCSTATUS_SUCCESS)
\r
2356 /* Reset the pointer to the socket closed */
\r
2357 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDefault;
\r
2358 pLlcpSocket->eSocket_Type = phFriNfc_LlcpTransport_eDefaultType;
\r
2359 pLlcpSocket->pContext = NULL;
\r
2360 pLlcpSocket->pSocketErrCb = NULL;
\r
2361 pLlcpSocket->socket_sSap = PHFRINFC_LLCP_SAP_DEFAULT;
\r
2362 pLlcpSocket->socket_dSap = PHFRINFC_LLCP_SAP_DEFAULT;
\r
2363 pLlcpSocket->bSocketRecvPending = FALSE;
\r
2364 pLlcpSocket->bSocketSendPending = FALSE;
\r
2365 pLlcpSocket->bSocketListenPending = FALSE;
\r
2366 pLlcpSocket->bSocketDiscPending = FALSE;
\r
2367 pLlcpSocket->socket_VS = 0;
\r
2368 pLlcpSocket->socket_VSA = 0;
\r
2369 pLlcpSocket->socket_VR = 0;
\r
2370 pLlcpSocket->socket_VRA = 0;
\r
2372 phFriNfc_LlcpTransport_ConnectionOriented_Abort(pLlcpSocket);
\r
2374 memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
\r
2376 if (pLlcpSocket->sServiceName.buffer != NULL) {
\r
2377 phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
\r
2379 pLlcpSocket->sServiceName.buffer = NULL;
\r
2380 pLlcpSocket->sServiceName.length = 0;
\r
2384 /* Disconnect close Error */
\r
2389 * \ingroup grp_fri_nfc
\r
2390 * \brief <b>Close a socket on a LLCP-connected device</b>.
\r
2392 * This function closes a LLCP socket previously created using phFriNfc_LlcpTransport_Socket.
\r
2393 * If the socket was connected, it is first disconnected, and then closed.
\r
2395 * \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
2397 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
2398 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
2399 * could not be properly interpreted.
\r
2400 * \retval NFCSTATUS_FAILED Operation failed.
\r
2402 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Close(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket)
\r
2404 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
2406 if(pLlcpSocket->eSocket_State == phFriNfc_LlcpTransportSocket_eSocketConnected)
\r
2408 status = phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(pLlcpSocket,
\r
2409 phFriNfc_LlcpTransport_ConnectionOriented_DisconnectClose_CB,
\r
2414 LLCP_PRINT("Socket not connected, no need to disconnect");
\r
2415 /* Reset the pointer to the socket closed */
\r
2416 pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDefault;
\r
2417 pLlcpSocket->eSocket_Type = phFriNfc_LlcpTransport_eDefaultType;
\r
2418 pLlcpSocket->pContext = NULL;
\r
2419 pLlcpSocket->pSocketErrCb = NULL;
\r
2420 pLlcpSocket->socket_sSap = PHFRINFC_LLCP_SAP_DEFAULT;
\r
2421 pLlcpSocket->socket_dSap = PHFRINFC_LLCP_SAP_DEFAULT;
\r
2422 pLlcpSocket->bSocketRecvPending = FALSE;
\r
2423 pLlcpSocket->bSocketSendPending = FALSE;
\r
2424 pLlcpSocket->bSocketListenPending = FALSE;
\r
2425 pLlcpSocket->bSocketDiscPending = FALSE;
\r
2426 pLlcpSocket->RemoteBusyConditionInfo = FALSE;
\r
2427 pLlcpSocket->ReceiverBusyCondition = FALSE;
\r
2428 pLlcpSocket->socket_VS = 0;
\r
2429 pLlcpSocket->socket_VSA = 0;
\r
2430 pLlcpSocket->socket_VR = 0;
\r
2431 pLlcpSocket->socket_VRA = 0;
\r
2433 phFriNfc_LlcpTransport_ConnectionOriented_Abort(pLlcpSocket);
\r
2435 memset(&pLlcpSocket->sSocketOption, 0x00, sizeof(phFriNfc_LlcpTransport_sSocketOptions_t));
\r
2437 if (pLlcpSocket->sServiceName.buffer != NULL) {
\r
2438 phOsalNfc_FreeMemory(pLlcpSocket->sServiceName.buffer);
\r
2440 pLlcpSocket->sServiceName.buffer = NULL;
\r
2441 pLlcpSocket->sServiceName.length = 0;
\r
2443 return NFCSTATUS_SUCCESS;
\r
2448 * \ingroup grp_fri_nfc
\r
2449 * \brief <b>Send data on a socket</b>.
\r
2451 * This function is used to write data on a socket. This function
\r
2452 * can only be called on a connection-oriented socket which is already
\r
2453 * in a connected state.
\r
2456 * \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
2457 * \param[in] psBuffer The buffer containing the data to send.
\r
2458 * \param[in] pSend_RspCb The callback to be called when the
\r
2459 * operation is completed.
\r
2460 * \param[in] pContext Upper layer context to be returned in
\r
2463 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
2464 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
2465 * could not be properly interpreted.
\r
2466 * \retval NFCSTATUS_PENDING Reception operation is in progress,
\r
2467 * pSend_RspCb will be called upon completion.
\r
2468 * \retval NFCSTATUS_INVALID_STATE The socket is not in a valid state, or not of
\r
2469 * a valid type to perform the requsted operation.
\r
2470 * \retval NFCSTATUS_FAILED Operation failed.
\r
2472 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Send(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
\r
2473 phNfc_sData_t* psBuffer,
\r
2474 pphFriNfc_LlcpTransportSocketSendCb_t pSend_RspCb,
\r
2477 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
2480 /* Test the RW window */
\r
2481 if(!CHECK_SEND_RW(pLlcpSocket))
\r
2483 /* Store the Send CB and context */
\r
2484 pLlcpSocket->pfSocketSend_Cb = pSend_RspCb;
\r
2485 pLlcpSocket->pSendContext = pContext;
\r
2487 /* Set Send pending */
\r
2488 pLlcpSocket->bSocketSendPending = TRUE;
\r
2490 /* Store send buffer pointer */
\r
2491 pLlcpSocket->sSocketSendBuffer = *psBuffer;
\r
2494 status = NFCSTATUS_PENDING;
\r
2498 /* Store send buffer pointer */
\r
2499 pLlcpSocket->sSocketSendBuffer = *psBuffer;
\r
2501 /* Store the Send CB and context */
\r
2502 pLlcpSocket->pfSocketSend_Cb = pSend_RspCb;
\r
2503 pLlcpSocket->pSendContext = pContext;
\r
2505 /* Test if a send is pending */
\r
2506 if(pLlcpSocket->psTransport->bSendPending == TRUE)
\r
2508 /* Set Send pending */
\r
2509 pLlcpSocket->bSocketSendPending = TRUE;
\r
2512 status = NFCSTATUS_PENDING;
\r
2516 /* Perform I-Frame send */
\r
2517 status = static_performSendInfo(pLlcpSocket);
\r
2518 if(status != NFCSTATUS_PENDING)
\r
2520 LLCP_PRINT("Release Send callback");
\r
2521 pLlcpSocket->pfSocketSend_Cb = NULL;
\r
2522 pLlcpSocket->pSendContext = NULL;
\r
2532 * \ingroup grp_fri_nfc
\r
2533 * \brief <b>Read data on a socket</b>.
\r
2535 * This function is used to read data from a socket. It reads at most the
\r
2536 * size of the reception buffer, but can also return less bytes if less bytes
\r
2537 * are available. If no data is available, the function will be pending until
\r
2538 * more data comes, and the response will be sent by the callback. This function
\r
2539 * can only be called on a connection-oriented socket.
\r
2542 * \param[in] pLlcpSocket A pointer to a phFriNfc_LlcpTransport_Socket_t.
\r
2543 * \param[in] psBuffer The buffer receiving the data.
\r
2544 * \param[in] pRecv_RspCb The callback to be called when the
\r
2545 * operation is completed.
\r
2546 * \param[in] pContext Upper layer context to be returned in
\r
2549 * \retval NFCSTATUS_SUCCESS Operation successful.
\r
2550 * \retval NFCSTATUS_INVALID_PARAMETER One or more of the supplied parameters
\r
2551 * could not be properly interpreted.
\r
2552 * \retval NFCSTATUS_PENDING Reception operation is in progress,
\r
2553 * pRecv_RspCb will be called upon completion.
\r
2554 * \retval NFCSTATUS_INVALID_STATE The socket is not in a valid state, or not of
\r
2555 * a valid type to perform the requsted operation.
\r
2556 * \retval NFCSTATUS_FAILED Operation failed.
\r
2558 NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Recv( phFriNfc_LlcpTransport_Socket_t* pLlcpSocket,
\r
2559 phNfc_sData_t* psBuffer,
\r
2560 pphFriNfc_LlcpTransportSocketRecvCb_t pRecv_RspCb,
\r
2563 NFCSTATUS status = NFCSTATUS_SUCCESS;
\r
2564 uint32_t dataLengthStored = 0;
\r
2565 uint32_t dataLengthAvailable = 0;
\r
2566 uint32_t dataLengthRead = 0;
\r
2567 uint32_t dataLengthWrite = 0;
\r
2568 bool_t dataBufferized = FALSE;
\r
2570 /* Test if the WorkingBuffer Length is null */
\r
2571 if(pLlcpSocket->bufferLinearLength == 0)
\r
2573 if (pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
\r
2575 return NFCSTATUS_FAILED;
\r
2578 /* Test If data is present in the RW Buffer */
\r
2579 if(pLlcpSocket->indexRwRead != pLlcpSocket->indexRwWrite)
\r
2581 if(pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length != 0)
\r
2583 /* Save I_FRAME into the Receive Buffer */
\r
2584 memcpy(psBuffer->buffer,pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].buffer,pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length);
\r
2585 psBuffer->length = pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length;
\r
2587 dataBufferized = TRUE;
\r
2590 pLlcpSocket->socket_VR = (pLlcpSocket->socket_VR+1)%16;
\r
2592 /* Update RW Buffer length */
\r
2593 pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length = 0;
\r
2595 /* Update Value Rw Read Index*/
\r
2596 pLlcpSocket->indexRwRead++;
\r
2600 if(dataBufferized == TRUE)
\r
2602 /* Call the Receive CB */
\r
2603 pRecv_RspCb(pContext,NFCSTATUS_SUCCESS);
\r
2605 if(pLlcpSocket->ReceiverBusyCondition == TRUE)
\r
2607 /* Reset the ReceiverBusyCondition Flag */
\r
2608 pLlcpSocket->ReceiverBusyCondition = FALSE;
\r
2610 /* TODO: report status? */
\r
2611 phFriNfc_Llcp_Send_ReceiveReady_Frame(pLlcpSocket);
\r
2616 /* Set Receive pending */
\r
2617 pLlcpSocket->bSocketRecvPending = TRUE;
\r
2619 /* Store the buffer pointer */
\r
2620 pLlcpSocket->sSocketRecvBuffer = psBuffer;
\r
2622 /* Store the Recv CB and context */
\r
2623 pLlcpSocket->pfSocketRecv_Cb = pRecv_RspCb;
\r
2624 pLlcpSocket->pRecvContext = pContext;
\r
2627 status = NFCSTATUS_PENDING;
\r
2632 /* Test if data is present in the linear buffer*/
\r
2633 dataLengthStored = phFriNfc_Llcp_CyclicFifoUsage(&pLlcpSocket->sCyclicFifoBuffer);
\r
2635 if(dataLengthStored != 0)
\r
2637 if(psBuffer->length > dataLengthStored)
\r
2639 psBuffer->length = dataLengthStored;
\r
2642 /* Read data from the linear buffer */
\r
2643 dataLengthRead = phFriNfc_Llcp_CyclicFifoFifoRead(&pLlcpSocket->sCyclicFifoBuffer,
\r
2645 psBuffer->length);
\r
2647 if(dataLengthRead != 0)
\r
2649 /* Test If data is present in the RW Buffer */
\r
2650 while(pLlcpSocket->indexRwRead != pLlcpSocket->indexRwWrite)
\r
2652 /* Get the data length available in the linear buffer */
\r
2653 dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&pLlcpSocket->sCyclicFifoBuffer);
\r
2655 /* Exit if not enough memory available in linear buffer */
\r
2656 if(dataLengthAvailable < pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length)
\r
2661 /* Write data into the linear buffer */
\r
2662 dataLengthWrite = phFriNfc_Llcp_CyclicFifoWrite(&pLlcpSocket->sCyclicFifoBuffer,
\r
2663 pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].buffer,
\r
2664 pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length);
\r
2666 pLlcpSocket->socket_VR = (pLlcpSocket->socket_VR+1)%16;
\r
2668 /* Set flag bufferized to TRUE */
\r
2669 dataBufferized = TRUE;
\r
2671 /* Update RW Buffer length */
\r
2672 pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length = 0;
\r
2674 /* Update Value Rw Read Index*/
\r
2675 pLlcpSocket->indexRwRead++;
\r
2678 /* Test if data has been bufferized after a read access */
\r
2679 if(dataBufferized == TRUE)
\r
2681 /* Get the data length available in the linear buffer */
\r
2682 dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&pLlcpSocket->sCyclicFifoBuffer);
\r
2683 if((dataLengthAvailable >= pLlcpSocket->sSocketOption.miu) && (pLlcpSocket->ReceiverBusyCondition == TRUE))
\r
2685 /* Reset the ReceiverBusyCondition Flag */
\r
2686 pLlcpSocket->ReceiverBusyCondition = FALSE;
\r
2688 /* TODO: report status? */
\r
2689 phFriNfc_Llcp_Send_ReceiveReady_Frame(pLlcpSocket);
\r
2693 /* Call the Receive CB */
\r
2694 pRecv_RspCb(pContext,NFCSTATUS_SUCCESS);
\r
2698 /* Call the Receive CB */
\r
2699 status = NFCSTATUS_FAILED;
\r
2704 if (pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketConnected)
\r
2706 status = NFCSTATUS_FAILED;
\r
2710 /* Set Receive pending */
\r
2711 pLlcpSocket->bSocketRecvPending = TRUE;
\r
2713 /* Store the buffer pointer */
\r
2714 pLlcpSocket->sSocketRecvBuffer = psBuffer;
\r
2716 /* Store the Recv CB and context */
\r
2717 pLlcpSocket->pfSocketRecv_Cb = pRecv_RspCb;
\r
2718 pLlcpSocket->pRecvContext = pContext;
\r
2721 status = NFCSTATUS_PENDING;
\r
2726 if(status != NFCSTATUS_PENDING)
\r
2728 /* Note: The receive callback must be released to avoid being called at abort */
\r
2729 LLCP_PRINT("Release Receive callback");
\r
2730 pLlcpSocket->pfSocketRecv_Cb = NULL;
\r
2731 pLlcpSocket->pRecvContext = NULL;
\r