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