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