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