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