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