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 phLlcNfc_Frame.c 19 * \brief To append the I or S or U frames (LLC header). 20 * 21 * Project: NFC-FRI-1.1 22 * 23 * $Date: Tue Jun 1 14:41:26 2010 $ 24 * $Author: ing02260 $ 25 * $Revision: 1.88 $ 26 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $ 27 * 28 */ 29 30 /*************************** Includes *******************************/ 31 #include <phNfcTypes.h> 32 #include <phNfcStatus.h> 33 #include <phOsalNfc.h> 34 #include <phOsalNfc_Timer.h> 35 #include <phNfcInterface.h> 36 #include <phLlcNfc_DataTypes.h> 37 #include <phLlcNfc_Frame.h> 38 #include <phLlcNfc_Interface.h> 39 #include <phLlcNfc_Timer.h> 40 #ifdef ANDROID 41 #include <string.h> 42 #endif 43 44 /*********************** End of includes ****************************/ 45 46 /***************************** Macros *******************************/ 47 48 /************************ End of macros *****************************/ 49 50 /***************************** Global variables *******************************/ 51 52 #ifdef LLC_RELEASE_FLAG 53 extern uint8_t g_release_flag; 54 #endif /* #ifdef LLC_RELEASE_FLAG */ 55 56 /************************ End of global variables *****************************/ 57 58 /*********************** Local functions ****************************/ 59 static 60 void 61 phLlcNfc_H_UpdateCrc( 62 uint8_t crcByte, 63 uint16_t *pCrc 64 ); 65 66 /** 67 * \ingroup grp_hal_nfc_llc_helper 68 * 69 * \brief LLC helper functions <b>process the received U frame</b> function 70 * 71 * \copydoc page_reg This function is to process the U frame received from 72 * the device 73 * 74 * \param[in] psLlcCtxt Llc main structure information 75 * \param[in] llcPacket LLC packet information, inlcuding length information 76 * 77 * \retval NFCSTATUS_SUCCESS Operation successful. 78 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. 79 * 80 */ 81 static 82 NFCSTATUS 83 phLlcNfc_H_ProcessUFrame ( 84 phLlcNfc_Context_t *psLlcCtxt 85 ); 86 87 /** 88 * \ingroup grp_hal_nfc_llc_helper 89 * 90 * \brief LLC helper functions <b>process the received S frame</b> function 91 * 92 * \copydoc page_reg This function is to process the S frame received from 93 * the device 94 * 95 * \param[in] psLlcCtxt Llc main structure information 96 * 97 * \retval NFCSTATUS_SUCCESS Operation successful. 98 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. 99 * 100 */ 101 static 102 void 103 phLlcNfc_H_ProcessSFrame ( 104 phLlcNfc_Context_t *psLlcCtxt 105 ); 106 107 /** 108 * \ingroup grp_hal_nfc_llc_helper 109 * 110 * \brief LLC component <b>Create S frame</b> function 111 * 112 * \copydoc page_reg This is a helper function which, creates the S frame 113 * 114 * \param[in/out] psFrameInfo Generic frame information 115 * \param[in/out] cmdType Command type of S frame 116 * 117 * \retval NFCSTATUS_SUCCESS Operation successful. 118 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. 119 * 120 */ 121 static 122 NFCSTATUS 123 phLlcNfc_H_CreateSFramePayload ( 124 phLlcNfc_Frame_t *psFrameInfo, 125 phLlcNfc_LlcCmd_t cmdType 126 ); 127 128 129 /** 130 * \ingroup grp_hal_nfc_llc_helper 131 * 132 * \brief LLC helper functions <b>Update I frame list</b> function 133 * 134 * \copydoc page_reg This function checks the nr value with the stored I frames 135 * and deletes the nodes which has been acknowledged. 136 * 137 * \param[in/out] psFrameInfo Frame structure information 138 * \param[in/out] psListInfo List information 139 * 140 * \retval number of deleted frames 141 * 142 */ 143 static 144 uint8_t 145 phLlcNfc_H_UpdateIFrameList( 146 phLlcNfc_Frame_t *psFrameInfo, 147 phLlcNfc_StoreIFrame_t *psListInfo 148 ); 149 150 /** 151 * \ingroup grp_hal_nfc_llc_helper 152 * 153 * \brief LLC helper functions \b Delete list function 154 * 155 * \copydoc page_reg Delete the front node from the list 156 * 157 * \param[in] psFrameInfo Frame structure information 158 * 159 * \retval NFCSTATUS_SUCCESS Operation successful. 160 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. 161 * 162 */ 163 static 164 void 165 phLlcNfc_H_DeleteIFrame ( 166 phLlcNfc_StoreIFrame_t *psList 167 ); 168 169 /** 170 * \ingroup grp_hal_nfc_llc_helper 171 * 172 * \brief LLC helper functions <b>Get the LLC header</b> function 173 * 174 * \copydoc page_reg This function checks for the correctness fo the llc header 175 * 176 * \param[in] llcHeader The byte which gives the header information 177 * 178 * \retval phLlcNfc_eU_frame U frame type. 179 * \retval phLlcNfc_eI_frame I frame type. 180 * \retval phLlcNfc_eS_frame S frame type. 181 * \retval phLlcNfc_eErr_frame Error type 182 * 183 */ 184 static 185 phLlcNfc_FrameType_t 186 phLlcNfc_H_ChkGetLlcFrameType ( 187 uint8_t llcHeader 188 ); 189 190 /** 191 * \ingroup grp_hal_nfc_llc_helper 192 * 193 * \brief LLC helper functions \b Peek the data function 194 * 195 * \copydoc page_reg Get the packet information from the front node from the list 196 * 197 * \param[in] psListInfo The List information 198 * \param[in] packetinfo The packet information from the front node of the list 199 * 200 * \retval NFCSTATUS_SUCCESS Operation successful. 201 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. 202 * 203 */ 204 static 205 NFCSTATUS 206 phLlcNfc_H_IFrameList_Peek ( 207 phLlcNfc_StoreIFrame_t *psList, 208 phLlcNfc_LlcPacket_t **psPacketinfo, 209 uint8_t position 210 ); 211 212 /** 213 * \ingroup grp_hal_nfc_llc_helper 214 * 215 * \brief LLC helper functions <b>Update U frame information</b> function 216 * 217 * \copydoc page_reg This function updates the U frame information in the 218 * phLlcNfc_sFrame_t structure 219 * 220 * \param[in/out] psFrameInfo Frame information structure 221 * \param[in] llcPayload Llc payload information 222 * 223 * \retval NFCSTATUS_SUCCESS Operation successful. 224 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. 225 * 226 */ 227 static 228 NFCSTATUS 229 phLlcNfc_H_Update_ReceivedRSETInfo ( 230 phLlcNfc_Frame_t *psFrameInfo, 231 phLlcNfc_Payload_t llcInfo 232 ); 233 234 /** 235 * \ingroup grp_hal_nfc_llc_helper 236 * 237 * \brief LLC Reset frame information function 238 * 239 * \copydoc page_reg resets ns and nr value, when ack for U frame is received 240 * 241 * \param[in, out] psLlcCtxt Llc main structure information 242 * 243 * \retval NFCSTATUS_SUCCESS Operation successful. 244 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. 245 * 246 */ 247 static 248 void 249 phLlcNfc_H_ResetFrameInfo ( 250 phLlcNfc_Context_t *psLlcCtxt 251 ); 252 253 /** 254 * \ingroup grp_hal_nfc_llc_helper 255 * 256 * \brief LLC Reset frame sending function 257 * 258 * \copydoc page_reg Send URSET frame to PN544 259 * 260 * \param[in, out] psLlcCtxt Llc main structure information 261 * 262 * \retval NFCSTATUS_SUCCESS Operation successful. 263 * \retval NFCSTATUS_BUSY Write is pended, so wait till it completes. 264 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. 265 * 266 */ 267 NFCSTATUS 268 phLlcNfc_H_SendRSETFrame ( 269 phLlcNfc_Context_t *psLlcCtxt 270 ); 271 272 /** 273 * \ingroup grp_hal_nfc_llc_helper 274 * 275 * \brief LLC helper functions <b>process the received I frame</b> function 276 * 277 * \copydoc page_reg This function is to process the I frame received from 278 * the device 279 * 280 * \param[in] psLlcCtxt Llc main structure information 281 * 282 * \retval NFCSTATUS_SUCCESS Operation successful. 283 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. 284 * 285 */ 286 void 287 phLlcNfc_H_ProcessIFrame ( 288 phLlcNfc_Context_t *psLlcCtxt 289 ); 290 291 /******************** End of Local functions ************************/ 292 293 /********************** Global variables ****************************/ 294 295 /******************** End of Global Variables ***********************/ 296 297 void phLlcNfc_H_Frame_Init ( 298 phLlcNfc_Context_t *psLlcCtxt 299 ) 300 { 301 302 if (NULL != psLlcCtxt) 303 { 304 /* Set all the other values to 0 */ 305 (void)memset (&psLlcCtxt->s_frameinfo.s_llcpacket, 0, 306 sizeof(phLlcNfc_LlcPacket_t)); 307 308 psLlcCtxt->s_frameinfo.window_size = 309 PH_LLCNFC_U_FRAME_MAX_WIN_SIZE; 310 /* Initialise the window size, N(S) and N(R) */ 311 #ifdef PIGGY_BACK 312 psLlcCtxt->s_frameinfo.s_recv_store.winsize_cnt = 0; 313 #endif 314 psLlcCtxt->s_frameinfo.s_send_store.winsize_cnt = 0; 315 psLlcCtxt->s_frameinfo.n_s = 0; 316 psLlcCtxt->s_frameinfo.n_r = 0; 317 psLlcCtxt->s_frameinfo.rejected_ns = DEFAULT_PACKET_INPUT; 318 } 319 } 320 321 void 322 phLlcNfc_H_Frame_DeInit ( 323 phLlcNfc_Frame_t *psFrameInfo 324 ) 325 { 326 if (NULL != psFrameInfo) 327 { 328 /* Empty the frame information */ 329 (void)memset(&psFrameInfo->s_llcpacket, 0, 330 sizeof(phLlcNfc_LlcPacket_t)); 331 } 332 } 333 334 NFCSTATUS 335 phLlcNfc_H_CreateUFramePayload ( 336 phLlcNfc_Context_t *psLlcCtxt, 337 phLlcNfc_LlcPacket_t *psLlcPacket, 338 uint8_t *pLlcPacketLength, 339 phLlcNfc_LlcCmd_t cmdType 340 ) 341 { 342 /* 343 U frame packet (RSET) 344 Byte 0 = Length (4 to 6 bytes) 345 Byte 1 = Header 346 Byte 2 = window size (2 >= window size <= 4) 347 Byte 3 = capabilities (SREJ option enable/disable) (optional) 348 Byte 4 = Baud rate (optional) 349 Byte 5 = CRC1 350 Byte 6 = CRC2 351 */ 352 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC, 353 NFCSTATUS_INVALID_PARAMETER); 354 phLlcNfc_Buffer_t *ps_llc_buf = NULL; 355 uint8_t index = 0; 356 357 if ((NULL != psLlcCtxt) && (NULL != psLlcPacket) 358 && (NULL != pLlcPacketLength) && 359 ((phLlcNfc_e_rset == cmdType) || (phLlcNfc_e_ua == cmdType))) 360 { 361 result = NFCSTATUS_SUCCESS; 362 ps_llc_buf = &(psLlcPacket->s_llcbuf); 363 /* Get the header information */ 364 ps_llc_buf->sllcpayload.llcheader = 365 (uint8_t)PH_LLCNFC_U_HEADER_INIT; 366 if (phLlcNfc_e_rset == cmdType) 367 { 368 /* RSET command */ 369 ps_llc_buf->sllcpayload.llcheader = 370 (uint8_t)SET_BITS8( 371 ps_llc_buf->sllcpayload.llcheader, 372 PH_LLCNFC_U_FRAME_START_POS, 373 PH_LLCNFC_U_FRAME_NO_OF_POS, 374 (uint8_t)phLlcNfc_e_rset); 375 /* Default window size */ 376 ps_llc_buf->sllcpayload.llcpayload[index] = 377 PH_LLCNFC_U_FRAME_MAX_WIN_SIZE; 378 index++; 379 /* Endpoint capabilities, SREJ not supported */ 380 ps_llc_buf->sllcpayload.llcpayload[index] = 381 PH_LLCNFC_SREJ_BYTE_VALUE; 382 index++; 383 #ifdef ENABLE_BAUDRATE 384 /* baud rate 0x00 = 9600, 0x05 = 115200 */ 385 ps_llc_buf->sllcpayload.llcpayload[index] = 386 (uint8_t)phLlcNfc_e_115200; 387 index++; 388 #endif /* #ifdef ENABLE_BAUDRATE */ 389 390 } 391 else 392 { 393 /* UA frame */ 394 ps_llc_buf->sllcpayload.llcheader = (uint8_t) 395 SET_BITS8(ps_llc_buf->sllcpayload.llcheader, 396 PH_LLCNFC_U_FRAME_START_POS, 397 PH_LLCNFC_U_FRAME_NO_OF_POS, 398 (uint8_t)phLlcNfc_e_ua); 399 } 400 /* LLC length byte updated (index + 2 CRC bytes + 401 1 byte of header) */ 402 ps_llc_buf->llc_length_byte = (index + 403 PH_LLCNFC_NUM_OF_CRC_BYTES + 1); 404 /* Total LLC buffer size */ 405 *pLlcPacketLength = psLlcPacket->llcbuf_len = 406 (ps_llc_buf->llc_length_byte + 1); 407 /* 408 psLlcPacket->s_llcbuf : 409 consists llc length byte + llc header + data + CRC 410 (which needs to be calculated by the below function) 411 psLlcPacket->llcbuf_len : 412 Total length of the above buffer 413 psLlcPacket->llcbuf_len - 2 : 414 -2 because the CRC has to be calculated, only for the 415 bytes which has llc length byte + llc header + data. 416 But total length (llcbuf_len) consists of above mentioned 417 things with 2 byte CRC 418 psLlcPacket->s_llcbuf.sllcpayload.llcpayload : 419 consists only data (no length byte and no llc header) 420 (psLlcPacket->llcbuf_len - 4) : 421 is the array index of the first CRC byte to be calculated 422 (psLlcPacket->llcbuf_len - 3) : 423 is the array index of the second CRC byte to be calculated 424 */ 425 index = psLlcPacket->llcbuf_len; 426 427 phLlcNfc_H_ComputeCrc((uint8_t *)ps_llc_buf, 428 (psLlcPacket->llcbuf_len - 2), 429 &(ps_llc_buf->sllcpayload.llcpayload[(index - 4)]), 430 &(ps_llc_buf->sllcpayload.llcpayload[(index - 3)])); 431 } 432 433 return result; 434 } 435 436 static 437 NFCSTATUS 438 phLlcNfc_H_CreateSFramePayload ( 439 phLlcNfc_Frame_t *psFrameInfo, 440 phLlcNfc_LlcCmd_t cmdType 441 ) 442 { 443 /* 444 S frame packet (RR or RNR or REJ or SREJ). Total bytes = 4 445 Byte 0 = Length (Length = 3 always for S frame) 446 Byte 1 = Header 447 Byte 2 = CRC1 448 Byte 3 = CRC2 449 */ 450 NFCSTATUS result = NFCSTATUS_SUCCESS; 451 phLlcNfc_Buffer_t *ps_llc_buf = NULL; 452 uint8_t length = 0; 453 454 ps_llc_buf = &(psFrameInfo->s_llcpacket.s_llcbuf); 455 456 /* Initial S frame header */ 457 ps_llc_buf->sllcpayload.llcheader = PH_LLCNFC_S_HEADER_INIT; 458 /* Update the N(R) value */ 459 ps_llc_buf->sllcpayload.llcheader = (uint8_t)SET_BITS8( 460 ps_llc_buf->sllcpayload.llcheader, 461 PH_LLCNFC_NR_START_BIT_POS, 462 PH_LLCNFC_NR_NS_NO_OF_BITS, 463 psFrameInfo->n_r); 464 465 /* Update the type bits of S frame */ 466 ps_llc_buf->sllcpayload.llcheader = (uint8_t) 467 (ps_llc_buf->sllcpayload.llcheader | (uint8_t)cmdType); 468 469 /* Maximum S frame length */ 470 psFrameInfo->s_llcpacket.llcbuf_len = (uint8_t) 471 PH_LLCNFC_MAX_S_FRAME_LEN; 472 /* S frame length byte value */ 473 ps_llc_buf->llc_length_byte = (uint8_t) 474 (psFrameInfo->s_llcpacket.llcbuf_len - 1); 475 476 /* 477 psFrameInfo->s_llcpacket.s_llcbuf : 478 consists llc length byte + llc header + data + CRC 479 (which needs to be calculated by the below function) 480 psFrameInfo->s_llcpacket.llcbuf_len : 481 Total length of the above buffer 482 psFrameInfo->s_llcpacket.llcbuf_len - 2 : 483 -2 because the CRC has to be calculated, only for the 484 bytes which has llc length byte + llc header + data. 485 But total length (llcbuf_len) consists of above mentioned 486 things with 2 byte CRC 487 psFrameInfo->s_llcpacket.s_llcbuf.sllcpayload.llcpayload : 488 consists only data (no length byte and no llc header) 489 psFrameInfo->s_llcpacket.s_llcbuf.sllcpayload.llcpayload : 490 contains only data sent by user. 491 (psFrameInfo->s_llcpacket.llcbuf_len - 4) : 492 is the array index of the first CRC byte to be calculated 493 (psFrameInfo->s_llcpacket.llcbuf_len - 3) : 494 is the array index of the second CRC byte to be calculated 495 */ 496 length = psFrameInfo->s_llcpacket.llcbuf_len; 497 phLlcNfc_H_ComputeCrc( 498 (uint8_t *)ps_llc_buf, (length - 2), 499 &(ps_llc_buf->sllcpayload.llcpayload[(length - 4)]), 500 &(ps_llc_buf->sllcpayload.llcpayload[(length - 3)])); 501 502 return result; 503 } 504 505 NFCSTATUS 506 phLlcNfc_H_CreateIFramePayload ( 507 phLlcNfc_Frame_t *psFrameInfo, 508 phLlcNfc_LlcPacket_t *psLlcPacket, 509 uint8_t *pLlcBuf, 510 uint8_t llcBufLength 511 ) 512 { 513 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC, 514 NFCSTATUS_INVALID_PARAMETER); 515 phLlcNfc_Buffer_t *ps_llc_buf = NULL; 516 517 if ((NULL != psFrameInfo) && (NULL != psLlcPacket) && 518 (NULL != pLlcBuf) && (llcBufLength > 0)) 519 { 520 result = NFCSTATUS_SUCCESS; 521 ps_llc_buf = &(psLlcPacket->s_llcbuf); 522 523 (void)memcpy(&(ps_llc_buf->sllcpayload.llcpayload[0]), 524 pLlcBuf, llcBufLength); 525 526 psLlcPacket->llcbuf_len = (uint8_t)llcBufLength; 527 528 /* I frame header byte */ 529 ps_llc_buf->sllcpayload.llcheader = PH_LLCNFC_I_HEADER_INIT; 530 531 /* Set the N(S) value */ 532 ps_llc_buf->sllcpayload.llcheader = (uint8_t) 533 SET_BITS8( 534 ps_llc_buf->sllcpayload.llcheader, 535 PH_LLCNFC_NS_START_BIT_POS, 536 PH_LLCNFC_NR_NS_NO_OF_BITS, 537 psFrameInfo->n_s); 538 539 /* Set the N(R) value */ 540 ps_llc_buf->sllcpayload.llcheader = (uint8_t) 541 SET_BITS8( 542 ps_llc_buf->sllcpayload.llcheader, 543 PH_LLCNFC_NR_START_BIT_POS, 544 PH_LLCNFC_NR_NS_NO_OF_BITS, 545 psFrameInfo->n_r); 546 547 /* Update the length byte, llc length byte value includes 548 data + CRC bytes + llc length byte */ 549 ps_llc_buf->llc_length_byte = 550 (psLlcPacket->llcbuf_len + 551 PH_LLCNFC_NUM_OF_CRC_BYTES + 1); 552 553 /* Update total length, Total length is always equal to 554 llc length byte + 1 */ 555 psLlcPacket->llcbuf_len = 556 (ps_llc_buf->llc_length_byte + 1); 557 558 /* 559 psFrameInfo->s_llcpacket.s_llcbuf : 560 consists llc length byte + llc header + data + CRC (which 561 needs to be calculated by the below function) 562 psFrameInfo->s_llcpacket.llcbuf_len : 563 Total length of the above buffer 564 psFrameInfo->s_llcpacket.llcbuf_len - 2 : 565 -2 because the CRC has to be calculated, only for the 566 bytes which has llc length byte + llc header + data. 567 But total length (llcbuf_len) consists of above mentioned 568 things with 2 byte CRC 569 psFrameInfo->s_llcpacket.s_llcbuf.sllcpayload.llcpayload : 570 contains only data sent by user. 571 (psFrameInfo->s_llcpacket.llcbuf_len - 4) : 572 is the array index of the first CRC byte to be calculated 573 (psFrameInfo->s_llcpacket.llcbuf_len - 3) : 574 is the array index of the second CRC byte to be calculated 575 576 */ 577 phLlcNfc_H_ComputeCrc( 578 (uint8_t*)ps_llc_buf, 579 (psLlcPacket->llcbuf_len - 2), 580 &(ps_llc_buf->sllcpayload.llcpayload 581 [(psLlcPacket->llcbuf_len - 4)]), 582 &(ps_llc_buf->sllcpayload.llcpayload 583 [(psLlcPacket->llcbuf_len - 3)])); 584 585 586 } 587 588 return result; 589 } 590 591 static 592 phLlcNfc_FrameType_t 593 phLlcNfc_H_ChkGetLlcFrameType ( 594 uint8_t llcHeader 595 ) 596 { 597 phLlcNfc_FrameType_t frame_type = phLlcNfc_eErr_frame; 598 599 /* Mask the header byte to know the actual frame types */ 600 switch((llcHeader & PH_LLCNFC_LLC_HEADER_MASK)) 601 { 602 case PH_LLCNFC_U_HEADER_INIT: 603 { 604 frame_type = phLlcNfc_eU_frame; 605 break; 606 } 607 608 case PH_LLCNFC_S_HEADER_INIT: 609 { 610 frame_type = phLlcNfc_eS_frame; 611 break; 612 } 613 614 default: 615 { 616 if (PH_LLCNFC_I_HEADER_INIT == 617 (PH_LLCNFC_I_FRM_HEADER_MASK & llcHeader)) 618 { 619 frame_type = phLlcNfc_eI_frame; 620 } 621 else 622 { 623 frame_type = phLlcNfc_eErr_frame; 624 } 625 break; 626 } 627 } 628 return frame_type; 629 } 630 631 static 632 NFCSTATUS 633 phLlcNfc_H_Update_ReceivedRSETInfo ( 634 phLlcNfc_Frame_t *psFrameInfo, 635 phLlcNfc_Payload_t llcInfo 636 ) 637 { 638 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_FORMAT); 639 uint8_t payload_index = 0; 640 641 if ((llcInfo.llcpayload[payload_index] >= PH_LLCNFC_U_FRAME_MIN_WIN_SIZE) && 642 (llcInfo.llcpayload[payload_index] <= PH_LLCNFC_U_FRAME_MAX_WIN_SIZE)) 643 { 644 result = NFCSTATUS_SUCCESS; 645 /* From the received buffer, get the window size from the 646 3rd byte (recvUBufLen[3]) of the buffer */ 647 psFrameInfo->window_size = llcInfo.llcpayload[payload_index]; 648 payload_index = (uint8_t)(payload_index + 1); 649 650 /* If 4th byte of the receive buffer (pRecvUBuf[4]) is 651 0x01 then SREJ can come from the device*/ 652 psFrameInfo->srej_on_off = ((PH_LLCNFC_SREJ_BYTE_VALUE == 653 llcInfo.llcpayload[payload_index])? 654 PH_LLCNFC_SREJ_BYTE_VALUE:0); 655 656 /* For present implementation, this should be always false 657 later stage remove if statement to work */ 658 if (PH_LLCNFC_SREJ_BYTE_VALUE != psFrameInfo->srej_on_off) 659 { 660 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_FORMAT); 661 } 662 else 663 { 664 payload_index = (uint8_t)(payload_index + 1); 665 666 667 if (llcInfo.llcpayload[payload_index] > 668 (uint8_t)phLlcNfc_e_1228000) 669 { 670 /* Error byte */ 671 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_FORMAT); 672 } 673 else 674 { 675 /* Get the baud rate from the 5th byte of the receive buffer */ 676 psFrameInfo->baud_rate = (phLlcNfc_LlcBaudRate_t) 677 (llcInfo.llcpayload[payload_index]); 678 } 679 } 680 } 681 682 return result; 683 } 684 685 static 686 uint8_t 687 phLlcNfc_H_UpdateIFrameList( 688 phLlcNfc_Frame_t *psFrameInfo, 689 phLlcNfc_StoreIFrame_t *psListInfo 690 ) 691 { 692 NFCSTATUS result = NFCSTATUS_SUCCESS; 693 phLlcNfc_LlcPacket_t *pspktInfo = NULL; 694 uint8_t while_exit = FALSE; 695 uint8_t nr = 0; 696 uint8_t ns = 0; 697 uint8_t no_of_del_frames = 0; 698 699 PHNFC_UNUSED_VARIABLE(result); 700 if(0 == psListInfo->winsize_cnt) 701 { 702 while_exit = TRUE; 703 } 704 while (FALSE == while_exit) 705 { 706 /* Get the first node from the list */ 707 result = phLlcNfc_H_IFrameList_Peek (psListInfo, &pspktInfo, 708 DEFAULT_PACKET_INPUT); 709 if (NULL != pspktInfo) 710 { 711 /* Get the N(R) value of the received packet and N(S) value of the 712 sent stored i frame */ 713 ns = (uint8_t)GET_BITS8 ( 714 pspktInfo->s_llcbuf.sllcpayload.llcheader, 715 PH_LLCNFC_NS_START_BIT_POS, 716 PH_LLCNFC_NR_NS_NO_OF_BITS); 717 718 nr = (uint8_t)GET_BITS8( 719 psFrameInfo->s_recvpacket.s_llcbuf.sllcpayload.llcheader, 720 PH_LLCNFC_NR_START_BIT_POS, 721 PH_LLCNFC_NR_NS_NO_OF_BITS); 722 723 /* Check the value of each i frame N(S) and 724 received ACKs N(R) */ 725 #if 0 726 if(((ns <= nr) && ((nr - ns) <= psFrameInfo->window_size)) 727 || ((ns > nr) && (((PH_LLCNFC_MOD_NS_NR + nr) - ns) <= 728 PH_LLCNFC_U_FRAME_MAX_WIN_SIZE))) 729 #endif 730 if(((ns < nr) && ((nr - ns) <= psFrameInfo->window_size)) 731 || ((ns > nr) && (((PH_LLCNFC_MOD_NS_NR + nr) - ns) <= 732 PH_LLCNFC_U_FRAME_MAX_WIN_SIZE))) 733 { 734 phLlcNfc_H_DeleteIFrame (psListInfo); 735 no_of_del_frames = (uint8_t)(no_of_del_frames + 1); 736 } 737 else 738 { 739 while_exit = TRUE; 740 } 741 742 if(0 == psListInfo->winsize_cnt) 743 { 744 while_exit = TRUE; 745 } 746 } 747 else 748 { 749 while_exit = TRUE; 750 } 751 } 752 return no_of_del_frames; 753 } 754 755 NFCSTATUS 756 phLlcNfc_H_SendUserIFrame ( 757 phLlcNfc_Context_t *psLlcCtxt, 758 phLlcNfc_StoreIFrame_t *psListInfo 759 ) 760 { 761 NFCSTATUS result = NFCSTATUS_SUCCESS; 762 phLlcNfc_Frame_t *ps_frame_info = NULL; 763 phLlcNfc_LlcPacket_t *ps_create_packet = NULL; 764 phLlcNfc_LlcPacket_t *ps_get_packet = NULL; 765 phLlcNfc_Payload_t *ps_llc_payload = NULL; 766 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; 767 uint8_t llc_header = 0, 768 length = 0; 769 770 if ((NULL == psLlcCtxt) || (NULL == psListInfo)) 771 { 772 result = PHNFCSTVAL (CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER); 773 } 774 else if (0 == psListInfo->winsize_cnt) 775 { 776 result = PHNFCSTVAL (CID_NFC_LLC, NFCSTATUS_NOT_ALLOWED); 777 } 778 else 779 { 780 ps_frame_info = &(psLlcCtxt->s_frameinfo); 781 ps_create_packet = &(ps_frame_info->s_llcpacket); 782 ps_store_frame = &(ps_frame_info->s_send_store); 783 784 if ( 785 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt + 786 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR)) 787 ) 788 { 789 /* Get the stored I frame, only if the new frame is sent 790 from the upper layer */ 791 result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet, 792 ps_frame_info->n_s); 793 } 794 795 if (NULL != ps_get_packet) 796 { 797 llc_header = ps_get_packet->s_llcbuf.sllcpayload.llcheader; 798 799 /* Update n(r) value for the header */ 800 llc_header = (uint8_t)(llc_header | ps_frame_info->n_r); 801 802 /* Create the packet */ 803 (void)memcpy ((void *)ps_create_packet, (void *)ps_get_packet, 804 sizeof (phLlcNfc_LlcPacket_t)); 805 806 ps_create_packet->s_llcbuf.sllcpayload.llcheader = llc_header; 807 ps_llc_payload = &(ps_create_packet->s_llcbuf.sllcpayload); 808 809 /* Length of the complete llc buffer, sent to PN544 */ 810 length = ps_create_packet->llcbuf_len; 811 812 /* Compute CRC for the created packet */ 813 phLlcNfc_H_ComputeCrc ((uint8_t *)&(ps_create_packet->s_llcbuf), 814 (length - 2), 815 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]), 816 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 3)])); 817 818 /* Send the i frame */ 819 result = phLlcNfc_Interface_Write (psLlcCtxt, 820 (uint8_t *)&(ps_create_packet->s_llcbuf), 821 (uint32_t)ps_create_packet->llcbuf_len); 822 823 ps_frame_info->write_status = result; 824 825 if (NFCSTATUS_BUSY == PHNFCSTATUS (result)) 826 { 827 /* The below check is added because, write is already pended by some other 828 operation, so it has to complete, when it completes, then immediately 829 next write shall be called using the below updated variable 830 831 The below variable is checked for the resend or rejected i frame 832 because if due to timer or reject frame from PN544, an I frame 833 has been sent (means write has been pended then the variable shall 834 not be overwritten. 835 */ 836 ps_frame_info->write_wait_call = (phLlcNfc_eSentFrameType_t) 837 (((resend_i_frame == ps_frame_info->write_wait_call) || 838 (rejected_i_frame == ps_frame_info->write_wait_call)) ? 839 ps_frame_info->write_wait_call : user_i_frame); 840 } 841 else 842 { 843 if (NFCSTATUS_PENDING == result) 844 { 845 /* Start the timer */ 846 (void)phLlcNfc_StartTimers (PH_LLCNFC_GUARDTIMER, 847 ps_frame_info->n_s); 848 849 /* "sent_frame_type is updated" only if the data is 850 written to the lower layer */ 851 ps_frame_info->sent_frame_type = user_i_frame; 852 } 853 } 854 } 855 } 856 return result; 857 } 858 859 NFCSTATUS 860 phLlcNfc_H_SendRejectedIFrame ( 861 phLlcNfc_Context_t *psLlcCtxt, 862 phLlcNfc_StoreIFrame_t *psListInfo, 863 uint8_t ns_rejected 864 ) 865 { 866 NFCSTATUS result = NFCSTATUS_SUCCESS; 867 phLlcNfc_Frame_t *ps_frame_info = NULL; 868 phLlcNfc_LlcPacket_t *ps_create_packet = NULL; 869 phLlcNfc_LlcPacket_t *ps_get_packet = NULL; 870 phLlcNfc_Payload_t *ps_llc_payload = NULL; 871 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; 872 uint8_t llc_header = 0; 873 uint8_t length = 0; 874 875 if ((NULL == psLlcCtxt) || (NULL == psListInfo)) 876 { 877 result = PHNFCSTVAL (CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER); 878 } 879 else if (0 == psListInfo->winsize_cnt) 880 { 881 result = PHNFCSTVAL (CID_NFC_LLC, NFCSTATUS_NOT_ALLOWED); 882 } 883 else 884 { 885 ps_frame_info = &(psLlcCtxt->s_frameinfo); 886 ps_create_packet = &(ps_frame_info->s_llcpacket); 887 ps_store_frame = &(ps_frame_info->s_send_store); 888 889 890 if (ns_rejected < (uint8_t)(ps_store_frame->winsize_cnt + 891 ps_store_frame->start_pos)) 892 { 893 /* To send rejected frame, first thing shall be done is 894 windows size count shall be checked. if the 895 start position 896 */ 897 if (invalid_frame != 898 ps_store_frame->s_llcpacket[ns_rejected].frame_to_send) 899 { 900 /* Above check is added to know only if */ 901 result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet, 902 ns_rejected); 903 } 904 else 905 { 906 ps_frame_info->rejected_ns = DEFAULT_PACKET_INPUT; 907 /* Get the stored I frame, only if the new frame is sent 908 from the upper layer */ 909 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, psListInfo); 910 } 911 } 912 913 if (NULL != ps_get_packet) 914 { 915 llc_header = ps_get_packet->s_llcbuf.sllcpayload.llcheader; 916 917 /* Update n(r) value for the header */ 918 llc_header = (uint8_t)(llc_header | ps_frame_info->n_r); 919 920 /* Create the packet */ 921 (void)memcpy ((void *)ps_create_packet, (void *)ps_get_packet, 922 sizeof (phLlcNfc_LlcPacket_t)); 923 924 ps_create_packet->s_llcbuf.sllcpayload.llcheader = llc_header; 925 ps_llc_payload = &(ps_create_packet->s_llcbuf.sllcpayload); 926 927 /* Length of the complete llc buffer, sent to PN544 */ 928 length = ps_create_packet->llcbuf_len; 929 930 /* Compute CRC for the created packet */ 931 phLlcNfc_H_ComputeCrc ((uint8_t *)&(ps_create_packet->s_llcbuf), 932 (length - 2), 933 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]), 934 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 3)])); 935 936 /* Send the i frame */ 937 result = phLlcNfc_Interface_Write (psLlcCtxt, 938 (uint8_t *)&(ps_create_packet->s_llcbuf), 939 (uint32_t)ps_create_packet->llcbuf_len); 940 941 ps_frame_info->write_status = result; 942 943 if (NFCSTATUS_BUSY == PHNFCSTATUS (result)) 944 { 945 /* Already a frame is sent and response is waited for the sent frame, 946 so update the below variable */ 947 ps_frame_info->write_wait_call = (phLlcNfc_eSentFrameType_t) 948 (((ns_rejected != ps_store_frame->start_pos) && 949 (resend_i_frame != ps_frame_info->write_wait_call))? 950 rejected_i_frame : ps_frame_info->write_wait_call); 951 } 952 else 953 { 954 /* NFCSTATUS_PENDING means that the no other write is pending, apart 955 from the present write 956 957 Start the timer */ 958 (void)phLlcNfc_StartTimers (PH_LLCNFC_GUARDTIMER, ns_rejected); 959 960 /* "sent_frame_type is updated" only if the data is 961 written to the lower layer. This will be used in the write 962 response callback and also indicates, what is the frame sent 963 and why 964 */ 965 ps_frame_info->sent_frame_type = rejected_i_frame; 966 967 if ((ns_rejected + 1) < ps_frame_info->n_s) 968 { 969 ps_frame_info->rejected_ns = (uint8_t)(ns_rejected + 1); 970 971 ps_frame_info->write_status = PHNFCSTVAL(CID_NFC_LLC, 972 NFCSTATUS_BUSY); 973 974 if (invalid_frame == 975 ps_store_frame->s_llcpacket[ns_rejected].frame_to_send) 976 { 977 ps_frame_info->rejected_ns = DEFAULT_PACKET_INPUT; 978 ps_frame_info->write_wait_call = user_i_frame; 979 } 980 else 981 { 982 ps_frame_info->write_wait_call = rejected_i_frame; 983 } 984 } 985 else 986 { 987 ps_frame_info->rejected_ns = DEFAULT_PACKET_INPUT; 988 /* This check is added to see that new frame has arrived 989 from the upper layer */ 990 if (ps_frame_info->n_s < (ps_store_frame->start_pos + 991 ps_store_frame->winsize_cnt)) 992 { 993 ps_frame_info->write_wait_call = user_i_frame; 994 } 995 } 996 } 997 } 998 } 999 return result; 1000 } 1001 1002 NFCSTATUS 1003 phLlcNfc_H_SendTimedOutIFrame ( 1004 phLlcNfc_Context_t *psLlcCtxt, 1005 phLlcNfc_StoreIFrame_t *psListInfo, 1006 uint8_t frame_to_send 1007 ) 1008 { 1009 NFCSTATUS result = NFCSTATUS_SUCCESS; 1010 phLlcNfc_Frame_t *ps_frame_info = NULL; 1011 phLlcNfc_Timerinfo_t *ps_timer_info = NULL; 1012 phLlcNfc_LlcPacket_t *ps_create_packet = NULL; 1013 phLlcNfc_LlcPacket_t *ps_get_packet = NULL; 1014 phLlcNfc_Payload_t *ps_llc_payload = NULL; 1015 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; 1016 1017 PHNFC_UNUSED_VARIABLE(frame_to_send); 1018 if((NULL == psLlcCtxt) || (NULL == psListInfo)) 1019 { 1020 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER); 1021 } 1022 else if (psListInfo->winsize_cnt == 0) 1023 { 1024 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_NOT_ALLOWED); 1025 } 1026 else 1027 { 1028 uint8_t llc_header = 0; 1029 uint8_t length = 0; 1030 uint8_t timer_count = 0; 1031 uint8_t timer_index = 0; 1032 uint8_t ns_index = 0; 1033 1034 ps_frame_info = &(psLlcCtxt->s_frameinfo); 1035 ps_timer_info = &(psLlcCtxt->s_timerinfo); 1036 ps_create_packet = &(ps_frame_info->s_llcpacket); 1037 ps_store_frame = &(ps_frame_info->s_send_store); 1038 1039 timer_index = ps_timer_info->index_to_send; 1040 timer_count = ps_timer_info->guard_to_count; 1041 ns_index = ps_timer_info->timer_ns_value[timer_index]; 1042 1043 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL WIN SIZE CNT : 0x%02X\n", ps_store_frame->winsize_cnt); 1044 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL START POS : 0x%02X\n", ps_store_frame->start_pos); 1045 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL N S value : 0x%02X\n", ps_frame_info->n_s); 1046 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL frame type : 0x%02X\n", ps_timer_info->frame_type[timer_index]); 1047 1048 if (resend_i_frame == ps_timer_info->frame_type[timer_index]) 1049 { 1050 /* Get the stored I frame */ 1051 result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet, 1052 ns_index); 1053 } 1054 1055 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL Packet : 0x%02X\n", ps_get_packet); 1056 if (NULL != ps_get_packet) 1057 { 1058 llc_header = ps_get_packet->s_llcbuf.sllcpayload.llcheader; 1059 1060 /* Update n(r) value for the header */ 1061 llc_header = (uint8_t)(llc_header | ps_frame_info->n_r); 1062 1063 /* create the packet */ 1064 (void)memcpy ((void *)ps_create_packet, (void *)ps_get_packet, 1065 sizeof (phLlcNfc_LlcPacket_t)); 1066 1067 ps_create_packet->s_llcbuf.sllcpayload.llcheader = llc_header; 1068 ps_llc_payload = &(ps_create_packet->s_llcbuf.sllcpayload); 1069 1070 /* Length of the complete llc buffer, sent to PN544 */ 1071 length = ps_create_packet->llcbuf_len; 1072 1073 /* Compute CRC */ 1074 phLlcNfc_H_ComputeCrc((uint8_t *)&(ps_create_packet->s_llcbuf), 1075 (length - 2), 1076 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]), 1077 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 3)])); 1078 1079 /* Send the i frame */ 1080 result = phLlcNfc_Interface_Write (psLlcCtxt, 1081 (uint8_t *)&(ps_create_packet->s_llcbuf), 1082 (uint32_t)ps_create_packet->llcbuf_len); 1083 1084 ps_frame_info->write_status = result; 1085 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL Write status : 0x%02X\n", result); 1086 1087 if (NFCSTATUS_BUSY == PHNFCSTATUS (result)) 1088 { 1089 ps_frame_info->write_wait_call = resend_i_frame; 1090 } 1091 else 1092 { 1093 /* result = NFCSTATUS_PENDING and 1094 Timer is not started because the remaining timer 1095 will be running */ 1096 uint16_t time_out_value = 0; 1097 1098 /* Each frame has the send count, so increment this 1099 as soon as the frame is sent */ 1100 ps_timer_info->iframe_send_count[timer_index] = (uint8_t) 1101 (ps_timer_info->iframe_send_count[timer_index] + 1); 1102 1103 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL timer index : 0x%02X\n", timer_index); 1104 1105 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL GUARD TO VALUE : 0x%02X\n", ps_timer_info->guard_to_value[(timer_index - 1)]); 1106 if (timer_index > 0) 1107 { 1108 /* Copy the maximum time-out value. */ 1109 time_out_value = (uint16_t) 1110 ((ps_timer_info->guard_to_value[(timer_index - 1)] >= 1111 PH_LLCNFC_GUARD_TO_VALUE) ? 1112 (ps_timer_info->guard_to_value[(timer_index - 1)] + 1113 PH_LLCNFC_RESOLUTION): 1114 PH_LLCNFC_GUARD_TO_VALUE); 1115 } 1116 else 1117 { 1118 /* If the timer_index is 0 means, the previous timed out 1119 frame is the last frame in the list */ 1120 time_out_value = (uint16_t) 1121 ((ps_timer_info->guard_to_value[(timer_count - 1)] >= 1122 PH_LLCNFC_GUARD_TO_VALUE) ? 1123 (ps_timer_info->guard_to_value[(timer_count - 1)] + 1124 PH_LLCNFC_RESOLUTION): 1125 PH_LLCNFC_GUARD_TO_VALUE); 1126 } 1127 1128 ps_timer_info->guard_to_value[timer_index] = time_out_value; 1129 1130 ps_frame_info->sent_frame_type = resend_i_frame; 1131 1132 ps_timer_info->frame_type[timer_index] = invalid_frame; 1133 1134 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL Next frame type : 0x%02X\n", ps_timer_info->frame_type[((timer_index + 1) % PH_LLCNFC_MAX_ACK_GUARD_TIMER)]); 1135 /* Now check if next timer has expired, if yes, 1136 set the index to next, on receiving the write response 1137 callback for this send, then next frame can be sent */ 1138 if (resend_i_frame == 1139 ps_timer_info->frame_type[((timer_index + 1) % 1140 PH_LLCNFC_MAX_ACK_GUARD_TIMER)]) 1141 { 1142 /* If next frame has to be sent, then update write wait */ 1143 ps_frame_info->write_status = NFCSTATUS_BUSY; 1144 ps_frame_info->write_wait_call = resend_i_frame; 1145 ps_timer_info->index_to_send = (uint8_t) 1146 ((timer_index + 1) % 1147 PH_LLCNFC_MAX_ACK_GUARD_TIMER); 1148 } 1149 else 1150 { 1151 /* Timer is not expired, 1152 Now, Check if the new frame is ready to be sent, if yes, 1153 then update the variable */ 1154 if ( 1155 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt + 1156 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR)) 1157 ) 1158 { 1159 ps_frame_info->write_status = PHNFCSTVAL (CID_NFC_LLC, 1160 NFCSTATUS_BUSY); 1161 ps_frame_info->write_wait_call = user_i_frame; 1162 } 1163 } 1164 1165 #if 0 1166 result = phLlcNfc_StartTimers (PH_LLCNFC_GUARDTIMER, 1167 ((llc_header >> 1168 PH_LLCNFC_NS_START_BIT_POS) | 1169 MAX_NS_NR_VALUE)); 1170 #endif /* #if 0 */ 1171 1172 } 1173 } 1174 else 1175 { 1176 if ( 1177 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt + 1178 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR)) 1179 ) 1180 { 1181 ps_frame_info->write_status = PHNFCSTVAL (CID_NFC_LLC, 1182 NFCSTATUS_BUSY); 1183 ps_frame_info->write_wait_call = user_i_frame; 1184 } 1185 } 1186 } 1187 1188 return result; 1189 } 1190 1191 1192 void 1193 phLlcNfc_H_ProcessIFrame ( 1194 phLlcNfc_Context_t *psLlcCtxt 1195 ) 1196 { 1197 NFCSTATUS result = NFCSTATUS_SUCCESS; 1198 uint8_t ns_index = 0; 1199 #if defined (LLC_SEND_RR_ACK) 1200 /* uint8_t nr_index = 0; */ 1201 #endif /* #if defined (LLC_SEND_RR_ACK) */ 1202 phLlcNfc_Frame_t *ps_frame_info = NULL; 1203 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; 1204 phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL; 1205 phLlcNfc_LlcCmd_t cmdtype = phLlcNfc_e_error; 1206 phLlcNfc_eSentFrameType_t eframe_type = invalid_frame; 1207 uint8_t dont_send_s_frame = FALSE; 1208 uint8_t no_of_del_frames = 0; 1209 phNfc_sCompletionInfo_t notifyinfo = {0}; 1210 1211 #ifdef RECV_NR_CHECK_ENABLE 1212 uint8_t recvd_nr = 0; 1213 #endif /* #ifdef RECV_NR_CHECK_ENABLE */ 1214 1215 #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB 1216 /* Nothing required in this define */ 1217 #else 1218 uint8_t prev_local_nr = 0; 1219 #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ 1220 1221 ps_frame_info = &(psLlcCtxt->s_frameinfo); 1222 ps_store_frame = &(ps_frame_info->s_send_store); 1223 ps_recv_pkt = &(ps_frame_info->s_recvpacket); 1224 1225 PHNFC_UNUSED_VARIABLE(result); 1226 /* Received buffer, N(S) value */ 1227 ns_index = (uint8_t)GET_BITS8( 1228 ps_recv_pkt->s_llcbuf.sllcpayload.llcheader, 1229 PH_LLCNFC_NS_START_BIT_POS, 1230 PH_LLCNFC_NR_NS_NO_OF_BITS); 1231 1232 PH_LLCNFC_DEBUG("NS START POS BEFORE DEL : 0x%02X\n", ps_store_frame->start_pos); 1233 PH_LLCNFC_DEBUG("WIN SIZE BEFORE DEL : 0x%02X\n", ps_store_frame->winsize_cnt); 1234 1235 /* Correct frame is received, so remove the stored i frame info */ 1236 no_of_del_frames = phLlcNfc_H_UpdateIFrameList (ps_frame_info, 1237 &(ps_frame_info->s_send_store)); 1238 1239 PH_LLCNFC_DEBUG("NS START POS AFTER DEL : 0x%02X\n", ps_store_frame->start_pos); 1240 PH_LLCNFC_DEBUG("WIN SIZE AFTER DEL : 0x%02X\n", ps_store_frame->winsize_cnt); 1241 1242 #ifdef RECV_NR_CHECK_ENABLE 1243 1244 recvd_nr = (uint8_t)GET_BITS8( 1245 ps_recv_pkt->s_llcbuf.sllcpayload.llcheader, 1246 PH_LLCNFC_NR_START_BIT_POS, 1247 PH_LLCNFC_NR_NS_NO_OF_BITS); 1248 1249 if (((ps_frame_info->n_s > recvd_nr) && 1250 (0 == ((ps_frame_info->n_s + 1) % PH_LLCNFC_MOD_NS_NR))) 1251 || (recvd_nr > ps_frame_info->n_s)) 1252 1253 #else /* #ifdef RECV_NR_CHECK_ENABLE */ 1254 1255 if (no_of_del_frames > 0) 1256 1257 #endif /* #ifdef RECV_NR_CHECK_ENABLE */ 1258 { 1259 phLlcNfc_StopTimers (PH_LLCNFC_GUARDTIMER, no_of_del_frames); 1260 } 1261 1262 #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB 1263 /* Nothing required in this define */ 1264 #else 1265 prev_local_nr = ps_frame_info->n_r; 1266 #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ 1267 1268 /* Received buffer, N(S) value = N(R) of host (our 1269 structure) then send RR type of s frame else send 1270 REJ type of s frame */ 1271 if ((ns_index == ps_frame_info->n_r) 1272 #if defined (LLC_SEND_RR_ACK) 1273 1274 || ((ns_index < ps_frame_info->n_r) && 1275 ((ps_frame_info->n_r - ns_index) < ps_frame_info->window_size)) 1276 || ((ns_index > ps_frame_info->n_r) && 1277 ((ns_index - ps_frame_info->n_r) > ps_frame_info->window_size)) 1278 1279 #endif /* #if defined (LLC_SEND_RR_ACK) */ 1280 ) 1281 { 1282 PH_LLCNFC_PRINT(" Type bits of S frame to be sent is RR \n"); 1283 ps_frame_info->recv_error_count = 0; 1284 ps_frame_info->send_error_count = 0; 1285 1286 psLlcCtxt->recvbuf_length = (ps_recv_pkt->llcbuf_len - 1287 PH_LLCNFC_LEN_APPEND); 1288 1289 (void)memcpy ((void *)psLlcCtxt->precv_buf, (void *)( 1290 ps_recv_pkt->s_llcbuf.sllcpayload.llcpayload), 1291 psLlcCtxt->recvbuf_length); 1292 1293 1294 #if defined (LLC_SEND_RR_ACK) 1295 1296 if (((ns_index < ps_frame_info->n_r) && 1297 ((ps_frame_info->n_r - ns_index) < ps_frame_info->window_size)) 1298 || ((ns_index > ps_frame_info->n_r) && 1299 ((ns_index - ps_frame_info->n_r) > ps_frame_info->window_size))) 1300 { 1301 ps_frame_info->n_r = ((ns_index + 1) 1302 % PH_LLCNFC_MOD_NS_NR); 1303 } 1304 else 1305 1306 #endif /* #if defined (LLC_SEND_RR_ACK) */ 1307 { 1308 /* Update the N(R) value in I and S frame context */ 1309 ps_frame_info->n_r = ((ps_frame_info->n_r + 1) 1310 % PH_LLCNFC_MOD_NS_NR); 1311 1312 } 1313 1314 if (NFCSTATUS_BUSY == PHNFCSTATUS (ps_frame_info->write_status)) 1315 { 1316 /* Any how write cannot be done and some frame is ready to be sent 1317 so this frame will act as the ACK */ 1318 result = phLlcNfc_H_WriteWaitCall (psLlcCtxt); 1319 } 1320 else 1321 { 1322 if ( 1323 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt + 1324 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR)) 1325 ) 1326 { 1327 /* If user has sent a frame and DAL write is busy, then 1328 it has to be sent */ 1329 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, ps_store_frame); 1330 } 1331 } 1332 1333 if (NFCSTATUS_PENDING == result) 1334 { 1335 dont_send_s_frame = TRUE; 1336 #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB 1337 1338 phLlcNfc_H_SendInfo (psLlcCtxt); 1339 1340 #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ 1341 } 1342 else 1343 { 1344 cmdtype = phLlcNfc_e_rr; 1345 /* If i frame is sent from the stored list, it got the correct 1346 acknowledge i frame, so now for an i frame , s frame acknowledge 1347 is sent */ 1348 eframe_type = ((resend_i_frame == ps_frame_info->sent_frame_type)? 1349 resend_s_frame : s_frame); 1350 } 1351 1352 #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB 1353 1354 /* Nothing required in this define */ 1355 1356 #else /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ 1357 1358 phLlcNfc_H_SendInfo (psLlcCtxt); 1359 1360 #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ 1361 } 1362 else 1363 { 1364 ps_frame_info->send_error_count = (uint8_t) 1365 (ps_frame_info->send_error_count + 1); 1366 1367 #ifdef LLC_SEND_ERROR_COUNT 1368 1369 if (ps_frame_info->send_error_count < RECV_ERROR_FRAME_COUNT) 1370 1371 #endif /* #ifdef LLC_SEND_ERROR_COUNT */ 1372 { 1373 1374 #ifdef LLC_RR_INSTEAD_OF_REJ 1375 1376 if (((ps_frame_info->n_r > 0) && (ns_index == (ps_frame_info->n_r - 1))) 1377 || (0 == ps_frame_info->n_r) && 1378 (ns_index == (PH_LLCNFC_MOD_NS_NR - 1))) 1379 { 1380 cmdtype = phLlcNfc_e_rr; 1381 eframe_type = rej_rr_s_frame; 1382 } 1383 else 1384 1385 #endif /* #ifdef LLC_RR_INSTEAD_OF_REJ */ 1386 { 1387 cmdtype = phLlcNfc_e_rej; 1388 eframe_type = ((resend_i_frame == ps_frame_info->sent_frame_type)? 1389 resend_rej_s_frame : reject_s_frame); 1390 } 1391 } 1392 1393 #ifdef LLC_SEND_ERROR_COUNT 1394 else 1395 { 1396 #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION 1397 1398 result = phLlcNfc_H_SendRSETFrame (psLlcCtxt); 1399 1400 #else /* #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION */ 1401 1402 dont_send_s_frame = TRUE; 1403 PH_LLCNFC_DEBUG("SEND ERROR COUNT : 0x%02X\n", ps_frame_info->send_error_count); 1404 /* Error count has reached the limit, raise exception */ 1405 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC, 1406 NFCSTATUS_BOARD_COMMUNICATION_ERROR); 1407 #if 0 1408 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1); 1409 #endif /* #if 0 */ 1410 /* Resend done, no answer from the device */ 1411 psLlcCtxt->cb_for_if.notify ( 1412 psLlcCtxt->cb_for_if.pif_ctxt, 1413 psLlcCtxt->phwinfo, 1414 NFC_NOTIFY_DEVICE_ERROR, 1415 ¬ifyinfo); 1416 1417 #endif /* #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION */ 1418 } 1419 #endif /* #ifdef LLC_SEND_ERROR_COUNT */ 1420 } 1421 1422 #ifdef LLC_RELEASE_FLAG 1423 1424 if (FALSE == g_release_flag) 1425 1426 #endif /* #ifdef LLC_RELEASE_FLAG */ 1427 { 1428 result = phLlcNfc_Interface_Read(psLlcCtxt, 1429 PH_LLCNFC_READWAIT_OFF, 1430 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 1431 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 1432 1433 1434 1435 if ((TRUE != ps_frame_info->write_pending) && 1436 (PH_LLCNFC_READPEND_REMAIN_BYTE != ps_frame_info->read_pending) && 1437 (FALSE == dont_send_s_frame)) 1438 { 1439 /* Create S frame */ 1440 (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, cmdtype); 1441 1442 result = phLlcNfc_Interface_Write(psLlcCtxt, 1443 (uint8_t *)&(ps_frame_info->s_llcpacket.s_llcbuf), 1444 (uint32_t)(ps_frame_info->s_llcpacket.llcbuf_len)); 1445 1446 1447 if (0 == ps_frame_info->send_error_count) 1448 { 1449 ps_frame_info->write_wait_call = invalid_frame; 1450 } 1451 ps_frame_info->sent_frame_type = eframe_type; 1452 } 1453 } 1454 1455 return ; 1456 } 1457 1458 static 1459 NFCSTATUS 1460 phLlcNfc_H_ProcessUFrame ( 1461 phLlcNfc_Context_t *psLlcCtxt 1462 ) 1463 { 1464 NFCSTATUS result = NFCSTATUS_SUCCESS; 1465 phLlcNfc_Frame_t *ps_frame_info = NULL; 1466 phLlcNfc_LlcPacket_t *ps_uframe_pkt = NULL; 1467 #ifdef LLC_URSET_NO_DELAY 1468 phNfc_sCompletionInfo_t notifyinfo = {0}; 1469 #else /* #ifdef LLC_URSET_NO_DELAY */ 1470 uint32_t delay_timer_id = 1471 PH_OSALNFC_INVALID_TIMER_ID; 1472 #endif /* #ifdef LLC_URSET_NO_DELAY */ 1473 uint8_t cmdtype = phLlcNfc_e_error; 1474 1475 phLlcNfc_StopTimers(PH_LLCNFC_CONNECTIONTIMER, 0); 1476 ps_frame_info = &(psLlcCtxt->s_frameinfo); 1477 ps_uframe_pkt = &(ps_frame_info->s_recvpacket); 1478 /* Check the command type */ 1479 cmdtype = (ps_uframe_pkt->s_llcbuf.sllcpayload.llcheader & 1480 PH_LLCNFC_U_FRAME_MODIFIER_MASK); 1481 PHNFC_UNUSED_VARIABLE(result); 1482 switch(cmdtype) 1483 { 1484 case phLlcNfc_e_rset: 1485 { 1486 psLlcCtxt->s_frameinfo.rset_recvd = TRUE; 1487 /* command type is RSET, so update the U frame parameters */ 1488 result = phLlcNfc_H_Update_ReceivedRSETInfo (ps_frame_info, 1489 ps_uframe_pkt->s_llcbuf.sllcpayload); 1490 /* Create a UA frame */ 1491 result = phLlcNfc_H_CreateUFramePayload(psLlcCtxt, 1492 ps_uframe_pkt, 1493 &(ps_uframe_pkt->llcbuf_len), 1494 phLlcNfc_e_ua); 1495 1496 if (NFCSTATUS_SUCCESS == result) 1497 { 1498 /* Call DAL write */ 1499 result = phLlcNfc_Interface_Write( psLlcCtxt, 1500 (uint8_t*)&(ps_uframe_pkt->s_llcbuf), 1501 (uint32_t)ps_uframe_pkt->llcbuf_len); 1502 1503 phLlcNfc_H_ResetFrameInfo(psLlcCtxt); 1504 ps_frame_info->write_status = result; 1505 ps_frame_info->write_wait_call = invalid_frame; 1506 if (NFCSTATUS_PENDING == result) 1507 { 1508 ps_frame_info->sent_frame_type = 1509 ((ps_frame_info->sent_frame_type != init_u_rset_frame) ? 1510 u_a_frame : init_u_a_frame); 1511 } 1512 else 1513 { 1514 if (NFCSTATUS_BUSY == PHNFCSTATUS(result)) 1515 { 1516 ps_frame_info->write_wait_call = 1517 ((ps_frame_info->sent_frame_type != init_u_rset_frame) ? 1518 u_a_frame : init_u_a_frame); 1519 result = NFCSTATUS_PENDING; 1520 } 1521 } 1522 } 1523 break; 1524 } 1525 case phLlcNfc_e_ua: 1526 { 1527 phLlcNfc_H_ResetFrameInfo (psLlcCtxt); 1528 /* Add timer here, to delay the next command to the PN544 */ 1529 #ifdef LLC_URSET_NO_DELAY 1530 if (ps_frame_info->s_send_store.winsize_cnt > 0) 1531 { 1532 #if 0 1533 /* Resend I frame */ 1534 result = phLlcNfc_H_SendTimedOutIFrame (psLlcCtxt, 1535 &(ps_frame_info->s_send_store, 0); 1536 #else 1537 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, 1538 &(ps_frame_info->s_send_store)); 1539 #endif /* #if 0 */ 1540 } 1541 else 1542 { 1543 if ((init_u_rset_frame == ps_frame_info->sent_frame_type) && 1544 (NULL != psLlcCtxt->cb_for_if.notify)) 1545 { 1546 ps_frame_info->sent_frame_type = write_resp_received; 1547 notifyinfo.status = NFCSTATUS_SUCCESS; 1548 /* Send the notification to the upper layer */ 1549 psLlcCtxt->cb_for_if.notify( 1550 psLlcCtxt->cb_for_if.pif_ctxt, 1551 psLlcCtxt->phwinfo, 1552 NFC_NOTIFY_INIT_COMPLETED, 1553 ¬ifyinfo); 1554 } 1555 } 1556 #else /* #ifdef LLC_URSET_NO_DELAY */ 1557 delay_timer_id = phOsalNfc_Timer_Create (); 1558 phOsalNfc_Timer_Start (delay_timer_id, LLC_URSET_DELAY_TIME_OUT, 1559 phLlcNfc_URSET_Delay_Notify, (void*)0); 1560 #endif /* #ifdef LLC_URSET_NO_DELAY */ 1561 break; 1562 } 1563 default: 1564 { 1565 result = PHNFCSTVAL(CID_NFC_LLC, 1566 NFCSTATUS_INVALID_FORMAT); 1567 break; 1568 } 1569 } 1570 return result; 1571 } 1572 1573 static 1574 void 1575 phLlcNfc_H_ProcessSFrame ( 1576 phLlcNfc_Context_t *psLlcCtxt) 1577 { 1578 NFCSTATUS result = NFCSTATUS_SUCCESS; 1579 uint8_t cmdtype = phLlcNfc_e_error; 1580 #if 0 1581 prev_win_count = 0; 1582 #endif /* #if 0 */ 1583 phNfc_sTransactionInfo_t compinfo = {0}; 1584 phLlcNfc_Frame_t *ps_frame_info = NULL; 1585 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; 1586 phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL; 1587 uint8_t no_of_del_frames = 0; 1588 phNfc_sCompletionInfo_t notifyinfo = {0}; 1589 1590 ps_frame_info = &(psLlcCtxt->s_frameinfo); 1591 ps_recv_pkt = &(ps_frame_info->s_recvpacket); 1592 ps_store_frame = &(ps_frame_info->s_send_store); 1593 1594 cmdtype = (ps_recv_pkt->s_llcbuf.sllcpayload.llcheader & 1595 PH_LLCNFC_S_FRAME_TYPE_MASK); 1596 PHNFC_UNUSED_VARIABLE(result); 1597 1598 PH_LLCNFC_DEBUG("NS START POS BEFORE DEL : 0x%02X\n", ps_store_frame->start_pos); 1599 PH_LLCNFC_DEBUG("WIN SIZE BEFORE DEL : 0x%02X\n", ps_store_frame->winsize_cnt); 1600 1601 /* Correct frame is received, so remove the 1602 stored i frame info for the acknowledged frames */ 1603 no_of_del_frames = phLlcNfc_H_UpdateIFrameList (ps_frame_info, 1604 &(ps_frame_info->s_send_store)); 1605 1606 PH_LLCNFC_DEBUG("NS START POS AFTER DEL : 0x%02X\n", ps_store_frame->start_pos); 1607 PH_LLCNFC_DEBUG("WIN SIZE AFTER DEL : 0x%02X\n", ps_store_frame->winsize_cnt); 1608 1609 #if 0 1610 prev_win_count = ps_frame_info->s_send_store.winsize_cnt; 1611 #endif /* #if 0 */ 1612 1613 /* Pend the read */ 1614 result = phLlcNfc_Interface_Read (psLlcCtxt, 1615 PH_LLCNFC_READWAIT_OFF, 1616 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 1617 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 1618 switch(cmdtype) 1619 { 1620 case phLlcNfc_e_rr: 1621 case phLlcNfc_e_rej: 1622 { 1623 /* RR frame received */ 1624 phLlcNfc_StopTimers (PH_LLCNFC_GUARDTIMER, no_of_del_frames); 1625 1626 if (phLlcNfc_e_rr == cmdtype) 1627 { 1628 ps_frame_info->recv_error_count = 0; 1629 ps_frame_info->send_error_count = 0; 1630 } 1631 else 1632 { 1633 ps_frame_info->recv_error_count = (uint8_t) 1634 (ps_frame_info->recv_error_count + 1); 1635 } 1636 1637 if (ps_frame_info->recv_error_count >= RECV_ERROR_FRAME_COUNT) 1638 { 1639 /* Do nothing */ 1640 } 1641 else if (NFCSTATUS_BUSY == PHNFCSTATUS(ps_frame_info->write_status)) 1642 { 1643 result = phLlcNfc_H_WriteWaitCall (psLlcCtxt); 1644 } 1645 else 1646 { 1647 if ( 1648 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt + 1649 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR)) 1650 ) 1651 { 1652 /* If user has sent a frame and DAL write is busy, then 1653 it has to be sent */ 1654 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, ps_store_frame); 1655 } 1656 } 1657 1658 if ((0 != psLlcCtxt->send_cb_len) && 1659 (ps_store_frame->winsize_cnt < ps_frame_info->window_size)) 1660 { 1661 /* Due to the window size count (i.e., count has reached 1662 the limit), send completion was not sent for the previous 1663 send from the upper layer. So to allow next send from the 1664 upper layer, send completion is called */ 1665 compinfo.length = (uint16_t)psLlcCtxt->send_cb_len; 1666 compinfo.status = NFCSTATUS_SUCCESS; 1667 1668 if (NULL != psLlcCtxt->cb_for_if.send_complete) 1669 { 1670 psLlcCtxt->send_cb_len = 0; 1671 /* Call the send callback, if the window size 1672 count becomes less than actual window size */ 1673 psLlcCtxt->cb_for_if.send_complete ( 1674 psLlcCtxt->cb_for_if.pif_ctxt, 1675 psLlcCtxt->phwinfo, &compinfo); 1676 } 1677 } 1678 break; 1679 } 1680 1681 #if 0 1682 case phLlcNfc_e_rej: 1683 { 1684 ps_frame_info->recv_error_count = (uint8_t) 1685 (ps_frame_info->recv_error_count + 1); 1686 /* RR frame received */ 1687 phLlcNfc_StopTimers (PH_LLCNFC_GUARDTIMER, no_of_del_frames); 1688 1689 if (ps_frame_info->recv_error_count < RECV_ERROR_FRAME_COUNT) 1690 { 1691 /* Below check is added because if PN544 sends REJ to a frame, but 1692 the next frame has already been sent from PN544, then 1693 Send the user I frame */ 1694 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, ps_store_frame); 1695 } 1696 break; 1697 } 1698 #endif /* #if 0 */ 1699 1700 case phLlcNfc_e_rnr: 1701 { 1702 phLlcNfc_StopAllTimers (); 1703 ps_frame_info->recv_error_count = (uint8_t) 1704 (ps_frame_info->recv_error_count + 1); 1705 break; 1706 } 1707 1708 case phLlcNfc_e_srej: 1709 default: 1710 { 1711 ps_frame_info->recv_error_count = (uint8_t) 1712 (ps_frame_info->recv_error_count + 1); 1713 result = PHNFCSTVAL (CID_NFC_LLC, 1714 NFCSTATUS_INVALID_FORMAT); 1715 break; 1716 } 1717 } 1718 1719 if (ps_frame_info->recv_error_count >= RECV_ERROR_FRAME_COUNT) 1720 { 1721 #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION 1722 1723 result = phLlcNfc_H_SendRSETFrame (psLlcCtxt); 1724 1725 #else /* #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION */ 1726 1727 PH_LLCNFC_DEBUG("RECV ERROR COUNT : 0x%02X\n", ps_frame_info->recv_error_count); 1728 /* Raise the exception for CRC error received from the */ 1729 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC, 1730 NFCSTATUS_BOARD_COMMUNICATION_ERROR); 1731 #if 0 1732 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1); 1733 #endif /* #if 0 */ 1734 /* Resend done, no answer from the device */ 1735 psLlcCtxt->cb_for_if.notify ( 1736 psLlcCtxt->cb_for_if.pif_ctxt, 1737 psLlcCtxt->phwinfo, 1738 NFC_NOTIFY_DEVICE_ERROR, 1739 ¬ifyinfo); 1740 1741 #endif /* #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION */ 1742 } 1743 1744 return ; 1745 } 1746 1747 1748 void 1749 phLlcNfc_H_ComputeCrc( 1750 uint8_t *pData, 1751 uint8_t length, 1752 uint8_t *pCrc1, 1753 uint8_t *pCrc2 1754 ) 1755 { 1756 uint8_t crc_byte = 0, 1757 index = 0; 1758 uint16_t crc = 0; 1759 1760 #ifdef CRC_A 1761 crc = 0x6363; /* ITU-V.41 */ 1762 #else 1763 crc = 0xFFFF; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ 1764 #endif /* #ifdef CRC_A */ 1765 1766 do 1767 { 1768 crc_byte = pData[index]; 1769 phLlcNfc_H_UpdateCrc(crc_byte, &crc); 1770 index++; 1771 } while (index < length); 1772 1773 #ifndef INVERT_CRC 1774 crc = ~crc; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ 1775 #endif /* #ifndef INVERT_CRC */ 1776 1777 *pCrc1 = (uint8_t) (crc & 0xFF); 1778 *pCrc2 = (uint8_t) ((crc >> 8) & 0xFF); 1779 return; 1780 } 1781 1782 static 1783 void 1784 phLlcNfc_H_UpdateCrc( 1785 uint8_t crcByte, 1786 uint16_t *pCrc 1787 ) 1788 { 1789 crcByte = (crcByte ^ (uint8_t)((*pCrc) & 0x00FF)); 1790 crcByte = (crcByte ^ (uint8_t)(crcByte << 4)); 1791 *pCrc = (*pCrc >> 8) ^ ((uint16_t)crcByte << 8) ^ 1792 ((uint16_t)crcByte << 3) ^ 1793 ((uint16_t)crcByte >> 4); 1794 } 1795 1796 NFCSTATUS 1797 phLlcNfc_H_StoreIFrame ( 1798 phLlcNfc_StoreIFrame_t *psList, 1799 phLlcNfc_LlcPacket_t sPacketInfo 1800 ) 1801 { 1802 NFCSTATUS result = NFCSTATUS_SUCCESS; 1803 uint8_t ns_index = 0, 1804 llc_header = 0; 1805 1806 if ((NULL == psList) || (0 == sPacketInfo.llcbuf_len) || 1807 (PH_LLCNFC_I_HEADER_INIT != 1808 (sPacketInfo.s_llcbuf.sllcpayload.llcheader & 1809 PH_LLCNFC_I_FRM_HEADER_MASK))) 1810 { 1811 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER); 1812 } 1813 else 1814 { 1815 /* Get the index from the start index */ 1816 if(psList->winsize_cnt > 0) 1817 { 1818 ns_index = (uint8_t)((psList->start_pos + psList->winsize_cnt) % 1819 PH_LLCNFC_MOD_NS_NR); 1820 } 1821 else 1822 { 1823 ns_index = psList->start_pos; 1824 } 1825 1826 llc_header = (uint8_t)(PH_LLCNFC_I_HEADER_INIT | (ns_index << 1827 PH_LLCNFC_NS_START_BIT_POS)); 1828 sPacketInfo.s_llcbuf.sllcpayload.llcheader = llc_header; 1829 1830 (void)memcpy (&(psList->s_llcpacket[ns_index]), 1831 &(sPacketInfo), sizeof(phLlcNfc_LlcPacket_t)); 1832 1833 /* This variable says that LLC has to send complete 1834 callback for stored I frame */ 1835 psList->s_llcpacket[ns_index].frame_to_send = invalid_frame; 1836 1837 psList->winsize_cnt++; 1838 } 1839 return result; 1840 } 1841 1842 static 1843 void 1844 phLlcNfc_H_DeleteIFrame ( 1845 phLlcNfc_StoreIFrame_t *psList 1846 ) 1847 { 1848 if (NULL != psList) 1849 { 1850 (void)memset( &(psList->s_llcpacket[psList->start_pos]), 1851 0, sizeof(phLlcNfc_LlcPacket_t)); 1852 1853 /* Go to next N(S) position */ 1854 psList->start_pos = ((psList->start_pos + 1) % 1855 PH_LLCNFC_MOD_NS_NR); 1856 1857 if (psList->winsize_cnt > 0) 1858 { 1859 psList->winsize_cnt--; 1860 } 1861 } 1862 } 1863 1864 static 1865 NFCSTATUS 1866 phLlcNfc_H_IFrameList_Peek ( 1867 phLlcNfc_StoreIFrame_t *psList, 1868 phLlcNfc_LlcPacket_t **psPacketinfo, 1869 uint8_t position 1870 ) 1871 { 1872 NFCSTATUS result = NFCSTATUS_SUCCESS; 1873 uint8_t index = 0; 1874 1875 *psPacketinfo = NULL; 1876 if ((NULL != psList) && (psList->winsize_cnt > 0)) 1877 { 1878 result = NFCSTATUS_SUCCESS; 1879 if ((position < (psList->start_pos + psList->winsize_cnt)) || 1880 (DEFAULT_PACKET_INPUT == position)) 1881 { 1882 index = (uint8_t)((DEFAULT_PACKET_INPUT == position) ? 1883 psList->start_pos : position); 1884 *psPacketinfo = &(psList->s_llcpacket[index]); 1885 } 1886 } 1887 1888 return result; 1889 } 1890 1891 NFCSTATUS 1892 phLlcNfc_H_ProRecvFrame ( 1893 phLlcNfc_Context_t *psLlcCtxt 1894 ) 1895 { 1896 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC, 1897 NFCSTATUS_INVALID_PARAMETER); 1898 phLlcNfc_FrameType_t frame_type = phLlcNfc_eErr_frame; 1899 #ifdef LLC_DATA_BYTES 1900 uint8_t *print_buf = (uint8_t *) 1901 &(psLlcCtxt->s_frameinfo.s_recvpacket.s_llcbuf); 1902 uint8_t buf_len = 1903 psLlcCtxt->s_frameinfo.s_recvpacket.llcbuf_len; 1904 PH_LLCNFC_STRING("** Response "); 1905 1906 #endif /* LLC_DATA_BYTES */ 1907 if (NULL != psLlcCtxt) 1908 { 1909 result = NFCSTATUS_SUCCESS; 1910 /* Get the received frame type */ 1911 frame_type = phLlcNfc_H_ChkGetLlcFrameType( 1912 psLlcCtxt->s_frameinfo.s_recvpacket.s_llcbuf.sllcpayload.llcheader); 1913 1914 /* Depending on the received frame type, process the 1915 received buffer */ 1916 switch(frame_type) 1917 { 1918 case phLlcNfc_eU_frame: 1919 { 1920 PH_LLCNFC_PRINT("U frame received \n"); 1921 PH_LLCNFC_STRING("U frame "); 1922 PH_LLCNFC_PRINT_DATA(print_buf, buf_len); 1923 PH_LLCNFC_STRING(";\n"); 1924 result = phLlcNfc_H_ProcessUFrame(psLlcCtxt); 1925 break; 1926 } 1927 case phLlcNfc_eI_frame: 1928 { 1929 PH_LLCNFC_PRINT("I frame received \n"); 1930 PH_LLCNFC_STRING("I frame "); 1931 PH_LLCNFC_PRINT_DATA(print_buf, buf_len); 1932 PH_LLCNFC_STRING(";\n"); 1933 phLlcNfc_H_ProcessIFrame(psLlcCtxt); 1934 break; 1935 } 1936 case phLlcNfc_eS_frame: 1937 { 1938 PH_LLCNFC_PRINT("S frame received \n"); 1939 PH_LLCNFC_STRING("S frame "); 1940 PH_LLCNFC_PRINT_DATA(print_buf, buf_len); 1941 PH_LLCNFC_STRING(";\n"); 1942 phLlcNfc_H_ProcessSFrame(psLlcCtxt); 1943 break; 1944 } 1945 case phLlcNfc_eErr_frame: 1946 default: 1947 { 1948 PH_LLCNFC_PRINT("Error frame received \n"); 1949 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_FORMAT); 1950 break; 1951 } 1952 } 1953 1954 } 1955 return result; 1956 } 1957 1958 #ifdef CRC_ERROR_REJ 1959 NFCSTATUS 1960 phLlcNfc_H_SendRejectFrame( 1961 phLlcNfc_Context_t *psLlcCtxt 1962 ) 1963 { 1964 NFCSTATUS result = NFCSTATUS_SUCCESS; 1965 result = phLlcNfc_H_CreateSFramePayload( 1966 &(psLlcCtxt->s_frameinfo), 1967 phLlcNfc_e_rej); 1968 /* Send the "S" frame to the lower layer */ 1969 result = phLlcNfc_Interface_Write(psLlcCtxt, 1970 (uint8_t *)&(psLlcCtxt->s_frameinfo.s_llcpacket.s_llcbuf), 1971 (uint32_t)(psLlcCtxt->s_frameinfo.s_llcpacket.llcbuf_len)); 1972 1973 if (NFCSTATUS_PENDING == result) 1974 { 1975 /* Increment the retry count of the reject frame */ 1976 psLlcCtxt->s_frameinfo.recv_error_count = 1977 (psLlcCtxt->s_frameinfo.recv_error_count + 1); 1978 } 1979 1980 1981 return result; 1982 } 1983 #endif /* #ifdef CRC_ERROR_REJ */ 1984 1985 static 1986 void 1987 phLlcNfc_H_ResetFrameInfo ( 1988 phLlcNfc_Context_t *psLlcCtxt 1989 ) 1990 { 1991 uint8_t i = 0, 1992 win_cnt = 0, 1993 pos = 0, 1994 while_exit = FALSE, 1995 index_flag = FALSE; 1996 phLlcNfc_StoreIFrame_t *ps_send_store = NULL; 1997 phLlcNfc_Buffer_t *ps_buffer = NULL; 1998 1999 ps_send_store = &(psLlcCtxt->s_frameinfo.s_send_store); 2000 win_cnt = ps_send_store->winsize_cnt; 2001 pos = ps_send_store->start_pos; 2002 PH_LLCNFC_PRINT ("\n\nLLC : phLlcNfc_H_ResetFrameInfo called\n\n"); 2003 PH_LLCNFC_DEBUG ("\n\nLLC : ps_send_store->start_pos %08X\n", ps_send_store->start_pos); 2004 PH_LLCNFC_DEBUG ("\n\nLLC : ps_send_store->winsize_cnt before reset %08X\n", ps_send_store->winsize_cnt); 2005 2006 2007 if (0 != pos) 2008 { 2009 /* If the start position of the ns = 0, then 2010 no need to shift the stored llc data, 2011 Else it has to be shifted to the first 2012 index of the array */ 2013 if(TRUE == ((pos + win_cnt) / 2014 PH_LLCNFC_MAX_I_FRAME_STORE)) 2015 { 2016 /* 'i' is the array index, So to store data in the array, 2017 windows size count shall be subtracted by 1 */ 2018 i = (win_cnt - 1); 2019 /* if window size > 1 and ns for 2 frames are 7 and 0, then 2020 to reset the ns index to 0, the frames are copied from 2021 the reverse order, so to do it a flag is declared */ 2022 index_flag = TRUE; 2023 pos = (((pos - 1) + win_cnt) % PH_LLCNFC_MAX_I_FRAME_STORE); 2024 } 2025 2026 while (FALSE == while_exit) 2027 { 2028 (void)memcpy ((void *)&(ps_send_store->s_llcpacket[i]), 2029 (void *)&(ps_send_store->s_llcpacket[pos]), 2030 sizeof (phLlcNfc_LlcPacket_t)); 2031 2032 ps_send_store->s_llcpacket[i].frame_to_send = invalid_frame; 2033 2034 ps_buffer = &(ps_send_store->s_llcpacket[i].s_llcbuf); 2035 /* change n(s) value */ 2036 ps_buffer->sllcpayload.llcheader = (uint8_t) 2037 (PH_LLCNFC_I_HEADER_INIT | 2038 (i << PH_LLCNFC_NS_START_BIT_POS)); 2039 if(TRUE == index_flag) 2040 { 2041 if(0 == i) 2042 { 2043 while_exit = TRUE; 2044 } 2045 else 2046 { 2047 i = ((i - 1) % PH_LLCNFC_MAX_I_FRAME_STORE); 2048 if (0 == pos) 2049 { 2050 pos = (PH_LLCNFC_MAX_I_FRAME_STORE - 1); 2051 } 2052 else 2053 { 2054 pos = ((pos - 1) % PH_LLCNFC_MAX_I_FRAME_STORE); 2055 } 2056 } 2057 } 2058 else 2059 { 2060 if (i >= win_cnt) 2061 { 2062 while_exit = TRUE; 2063 } 2064 else 2065 { 2066 i = ((i + 1) % PH_LLCNFC_MAX_I_FRAME_STORE); 2067 pos = ((pos + 1) % PH_LLCNFC_MAX_I_FRAME_STORE); 2068 } 2069 2070 } 2071 } 2072 } 2073 psLlcCtxt->s_timerinfo.guard_to_count = 0; 2074 psLlcCtxt->s_timerinfo.timer_flag = 0; 2075 ps_send_store->start_pos = 0; 2076 psLlcCtxt->s_frameinfo.n_r = psLlcCtxt->s_frameinfo.n_s = 0; 2077 if (ps_send_store->winsize_cnt > 0) 2078 { 2079 psLlcCtxt->s_frameinfo.rejected_ns = 0; 2080 } 2081 else 2082 { 2083 psLlcCtxt->s_frameinfo.rejected_ns = DEFAULT_PACKET_INPUT; 2084 } 2085 2086 PH_LLCNFC_DEBUG ("\n\nLLC : ps_send_store->winsize_cnt after reset %08X\n", ps_send_store->winsize_cnt); 2087 return; 2088 } 2089 2090 NFCSTATUS 2091 phLlcNfc_H_WriteWaitCall ( 2092 phLlcNfc_Context_t *psLlcCtxt 2093 ) 2094 { 2095 NFCSTATUS result = NFCSTATUS_SUCCESS; 2096 phLlcNfc_StoreIFrame_t *ps_store_info = NULL; 2097 phLlcNfc_Frame_t *ps_frame_info = NULL; 2098 2099 ps_frame_info = &(psLlcCtxt->s_frameinfo); 2100 ps_store_info = &(ps_frame_info->s_send_store); 2101 2102 PH_LLCNFC_PRINT ("\nLLC : phLlcNfc_H_WriteWaitCall call ..\n"); 2103 PH_LLCNFC_DEBUG ("\n\nLLC : ps_frame_info->write_wait_call before call %08X\n", ps_frame_info->write_wait_call); 2104 2105 ps_frame_info->write_status = NFCSTATUS_PENDING; 2106 switch (ps_frame_info->write_wait_call) 2107 { 2108 case user_i_frame: 2109 { 2110 ps_frame_info->write_wait_call = invalid_frame; 2111 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, ps_store_info); 2112 break; 2113 } 2114 2115 case resend_i_frame: 2116 { 2117 ps_frame_info->write_wait_call = invalid_frame; 2118 result = phLlcNfc_H_SendTimedOutIFrame (psLlcCtxt, ps_store_info, 0); 2119 break; 2120 } 2121 2122 case rejected_i_frame: 2123 { 2124 ps_frame_info->write_wait_call = invalid_frame; 2125 result = phLlcNfc_H_SendRejectedIFrame (psLlcCtxt, ps_store_info, 2126 ps_frame_info->rejected_ns); 2127 break; 2128 } 2129 2130 case resend_s_frame: 2131 case reject_s_frame: 2132 case resend_rej_s_frame: 2133 { 2134 ps_frame_info->write_wait_call = invalid_frame; 2135 break; 2136 } 2137 2138 case u_rset_frame: 2139 { 2140 ps_frame_info->write_wait_call = invalid_frame; 2141 result = phLlcNfc_H_SendRSETFrame (psLlcCtxt); 2142 break; 2143 } 2144 2145 default : 2146 { 2147 ps_frame_info->write_wait_call = invalid_frame; 2148 break; 2149 } 2150 } 2151 2152 PH_LLCNFC_DEBUG ("\n\nLLC : ps_frame_info->write_wait_call after call %08X\n", ps_frame_info->write_wait_call); 2153 PH_LLCNFC_PRINT ("\nLLC : phLlcNfc_H_WriteWaitCall end ..\n"); 2154 return result; 2155 } 2156 2157 NFCSTATUS 2158 phLlcNfc_H_SendRSETFrame ( 2159 phLlcNfc_Context_t *psLlcCtxt 2160 ) 2161 { 2162 NFCSTATUS result = NFCSTATUS_SUCCESS; 2163 phLlcNfc_LlcPacket_t *ps_packet_info = NULL; 2164 phLlcNfc_Frame_t *ps_frame_info = NULL; 2165 2166 ps_frame_info = &(psLlcCtxt->s_frameinfo); 2167 ps_packet_info = &(psLlcCtxt->s_frameinfo.s_llcpacket); 2168 2169 result = phLlcNfc_H_CreateUFramePayload(psLlcCtxt, 2170 ps_packet_info, 2171 &(ps_packet_info->llcbuf_len), 2172 phLlcNfc_e_rset); 2173 2174 if (NFCSTATUS_SUCCESS == result) 2175 { 2176 /* Call DAL write */ 2177 result = phLlcNfc_Interface_Write(psLlcCtxt, 2178 (uint8_t*)&(ps_packet_info->s_llcbuf), 2179 (uint32_t)ps_packet_info->llcbuf_len); 2180 } 2181 2182 ps_frame_info->write_status = result; 2183 if (NFCSTATUS_PENDING == result) 2184 { 2185 /* Start the timer */ 2186 result = phLlcNfc_StartTimers (PH_LLCNFC_CONNECTIONTIMER, 0); 2187 if (NFCSTATUS_SUCCESS == result) 2188 { 2189 ps_frame_info->sent_frame_type = u_rset_frame; 2190 result = NFCSTATUS_PENDING; 2191 } 2192 } 2193 else 2194 { 2195 ps_frame_info->write_wait_call = u_rset_frame; 2196 } 2197 2198 return result; 2199 } 2200 2201 2202