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