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