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