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