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_Interface.c 19 * \brief Interface for both LLC and transport layer 20 * 21 * Project: NFC-FRI-1.1 22 * 23 * $Date: Tue Jun 1 14:41:26 2010 $ 24 * $Author: ing02260 $ 25 * $Revision: 1.75 $ 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 <phNfcInterface.h> 35 #include <phLlcNfc_DataTypes.h> 36 #include <phLlcNfc_Timer.h> 37 #include <phLlcNfc_Frame.h> 38 #include <phLlcNfc.h> 39 #include <phLlcNfc_Interface.h> 40 #ifdef PH_LLCNFC_STUB 41 #include <phDalNfc_Stub.h> 42 #endif 43 #ifdef PH_LLCNFC_DALINT 44 #include <phDal4Nfc.h> 45 #endif 46 #define LOG_TAG "NFC-LLC" 47 48 #include <utils/Log.h> 49 /*********************** End of includes ****************************/ 50 51 /***************************** Macros *******************************/ 52 #define PH_LLCNFC_APPEND_LEN (4) 53 #define LLC_NS_FRAME_HEADER_MASK (0x38U) 54 /************************ End of macros *****************************/ 55 56 /*********************** Local functions ****************************/ 57 static 58 void 59 phLlcNfc_WrResp_Cb( 60 void *pContext, 61 void *pHwInfo, 62 phNfc_sTransactionInfo_t *pCompInfo 63 ); 64 65 static 66 void 67 phLlcNfc_RdResp_Cb( 68 void *pContext, 69 void *pHwInfo, 70 phNfc_sTransactionInfo_t *pCompInfo 71 ); 72 73 /******************** End of Local functions ************************/ 74 75 /********************** Global variables ****************************/ 76 int libnfc_llc_error_count = 0; 77 78 /******************** End of Global Variables ***********************/ 79 80 NFCSTATUS 81 phLlcNfc_Interface_Register( 82 phLlcNfc_Context_t *psLlcCtxt, 83 phNfcLayer_sCfg_t *psIFConfig 84 ) 85 { 86 NFCSTATUS result = NFCSTATUS_SUCCESS; 87 phNfcIF_sCallBack_t if_cb = {0,0,0,0}; 88 phNfcIF_sReference_t sreference = {0,0,0}; 89 90 if ((NULL == psLlcCtxt) || (NULL == psIFConfig)) 91 { 92 result = PHNFCSTVAL(CID_NFC_LLC, 93 NFCSTATUS_INVALID_PARAMETER); 94 } 95 else 96 { 97 result = NFCSTATUS_SUCCESS; 98 if_cb.notify = NULL; 99 if_cb.receive_complete = (pphNfcIF_Transact_Completion_CB_t)&phLlcNfc_RdResp_Cb; 100 if_cb.send_complete = (pphNfcIF_Transact_Completion_CB_t)&phLlcNfc_WrResp_Cb; 101 if_cb.pif_ctxt = psLlcCtxt; 102 sreference.plower_if = &(psLlcCtxt->lower_if); 103 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER); 104 #ifdef PH_LLCNFC_STUB 105 result = phDalNfc_StubRegister(&sreference, if_cb, psIFConfig->layer_next); 106 #endif /* #ifdef PH_LLCNFC_STUB */ 107 #ifdef PH_LLCNFC_DALINT 108 result = phDal4Nfc_Register(&sreference, if_cb, psIFConfig->layer_next); 109 #else 110 if ((NULL != psIFConfig->layer_next) && 111 (NULL != psIFConfig->layer_next->layer_registry)) 112 { 113 result = psIFConfig->layer_next->layer_registry( 114 &sreference, 115 if_cb, 116 (void *)&psIFConfig[(psIFConfig->layer_index - 1)]); 117 } 118 #endif /* #ifdef PH_LLCNFC_DALINT */ 119 } 120 PH_LLCNFC_DEBUG("Llc Dal Interface Register result : 0x%x\n", result); 121 return result; 122 } 123 124 NFCSTATUS 125 phLlcNfc_Interface_Init( 126 phLlcNfc_Context_t *psLlcCtxt 127 ) 128 { 129 /* 130 1. Get the pointer of the main llc context 131 */ 132 NFCSTATUS result = NFCSTATUS_SUCCESS; 133 if ((NULL == psLlcCtxt) || 134 (NULL == psLlcCtxt->lower_if.init)) 135 { 136 result = PHNFCSTVAL(CID_NFC_LLC, 137 NFCSTATUS_INVALID_PARAMETER); 138 } 139 else 140 { 141 /* Initialise the main context */ 142 result = psLlcCtxt->lower_if.init( psLlcCtxt->lower_if.pcontext, 143 psLlcCtxt->phwinfo); 144 } 145 PH_LLCNFC_DEBUG("Llc Dal Interface Init result : 0x%x\n", result); 146 return result; 147 } 148 149 NFCSTATUS 150 phLlcNfc_Interface_Read( 151 phLlcNfc_Context_t *psLlcCtxt, 152 uint8_t readWaitOn, 153 uint8_t *pLlcBuffer, 154 uint32_t llcBufferLength 155 ) 156 { 157 NFCSTATUS result = NFCSTATUS_PENDING; 158 /* 159 1. Call DAL or TL read with "phLlcNfc_LlcTl_RdResp_Cb" as 160 callback function 161 */ 162 PH_LLCNFC_PRINT("Llc Dal Interface Read called\n"); 163 if ((NULL == psLlcCtxt) || (NULL == pLlcBuffer) || 164 (0 == llcBufferLength) || (NULL == psLlcCtxt->lower_if.receive) || 165 (readWaitOn > PH_LLCNFC_READWAIT_ON)) 166 { 167 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER); 168 } 169 else if (PH_LLCNFC_READPEND_FLAG_OFF != 170 psLlcCtxt->s_frameinfo.read_pending) 171 { 172 /* do nothing */ 173 } 174 else 175 { 176 if (PH_LLCNFC_READWAIT_OFF == readWaitOn) 177 { 178 result = psLlcCtxt->lower_if.receive( 179 psLlcCtxt->lower_if.pcontext, 180 psLlcCtxt->phwinfo, 181 pLlcBuffer, 182 (uint8_t)llcBufferLength); 183 } 184 else 185 { 186 result = psLlcCtxt->lower_if.receive_wait( 187 psLlcCtxt->lower_if.pcontext, 188 psLlcCtxt->phwinfo, 189 pLlcBuffer, 190 (uint16_t)llcBufferLength); 191 } 192 193 if(NFCSTATUS_PENDING == result) 194 { 195 if (PH_LLCNFC_READPEND_ONE_BYTE == llcBufferLength) 196 { 197 psLlcCtxt->s_frameinfo.read_pending = 198 PH_LLCNFC_READPEND_ONE_BYTE; 199 } 200 else 201 { 202 psLlcCtxt->s_frameinfo.read_pending = 203 PH_LLCNFC_READPEND_REMAIN_BYTE; 204 } 205 } 206 } 207 PH_LLCNFC_DEBUG("Llc Dal Interface Read result : 0x%x\n", result); 208 return result; 209 } 210 211 NFCSTATUS 212 phLlcNfc_Interface_Write( 213 phLlcNfc_Context_t *psLlcCtxt, 214 uint8_t *pLlcBuffer, 215 uint32_t llcBufferLength 216 ) 217 { 218 NFCSTATUS result = NFCSTATUS_PENDING; 219 220 PH_LLCNFC_PRINT("Llc Dal Interface Write called\n"); 221 /* 222 1. Call DAL or TL write with "phLlcNfc_LlcTl_WrResp_Cb" as 223 callback function 224 */ 225 if ((NULL == psLlcCtxt) || (NULL == pLlcBuffer) || 226 (0 == llcBufferLength) || 227 (NULL == psLlcCtxt->lower_if.send)) 228 { 229 PH_LLCNFC_DEBUG ("psLlcCtxt : 0x%p\n", psLlcCtxt); 230 PH_LLCNFC_DEBUG ("pLlcBuffer : 0x%p\n", pLlcBuffer); 231 PH_LLCNFC_DEBUG ("llcBufferLength : 0x%08X\n", llcBufferLength); 232 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER); 233 } 234 else 235 { 236 PH_LLCNFC_PRINT("Buffer to be send to Dal : \n"); 237 PH_LLCNFC_PRINT_BUFFER(pLlcBuffer, llcBufferLength); 238 239 if ((TRUE == psLlcCtxt->s_frameinfo.write_pending) || 240 (PH_LLCNFC_READPEND_REMAIN_BYTE == 241 psLlcCtxt->s_frameinfo.read_pending)) 242 { 243 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_BUSY); 244 } 245 else 246 { 247 #ifdef LLC_DATA_BYTES 248 249 PH_LLCNFC_PRINT_DATA (pLlcBuffer, llcBufferLength); 250 PH_LLCNFC_STRING (";\n"); 251 252 #endif /* LLC_DATA_BYTES */ 253 254 psLlcCtxt->s_frameinfo.s_llcpacket.llcbuf_len = (uint8_t)llcBufferLength; 255 (void)memcpy ((void *)&(psLlcCtxt->s_frameinfo.s_llcpacket.s_llcbuf), 256 (void *)pLlcBuffer, llcBufferLength); 257 258 result = psLlcCtxt->lower_if.send(psLlcCtxt->lower_if.pcontext, 259 psLlcCtxt->phwinfo, 260 (uint8_t *)&(psLlcCtxt->s_frameinfo.s_llcpacket.s_llcbuf), 261 (uint16_t)llcBufferLength); 262 if(NFCSTATUS_PENDING == result) 263 { 264 psLlcCtxt->s_frameinfo.write_pending = TRUE; 265 #ifdef PIGGY_BACK 266 /* Stop the ACK timer, as the ACK or I frame is sent */ 267 phLlcNfc_StopTimers (PH_LLCNFC_ACKTIMER, 0); 268 /* ACK is sent, so reset the response received count */ 269 psLlcCtxt->s_frameinfo.resp_recvd_count = 0; 270 #endif /* #ifdef PIGGY_BACK */ 271 } 272 } 273 } 274 PH_LLCNFC_DEBUG("Llc Dal Interface Write result : 0x%x\n", result); 275 return result; 276 } 277 278 static 279 void 280 phLlcNfc_WrResp_Cb( 281 void *pContext, 282 void *pHwInfo, 283 phNfc_sTransactionInfo_t *pCompInfo 284 ) 285 { 286 /* 287 1. Check the window size, if window size = windows 288 1. Call the send callback, which has been registered by upper 289 layer 290 */ 291 NFCSTATUS result = NFCSTATUS_SUCCESS; 292 phLlcNfc_Context_t *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext; 293 phLlcNfc_Frame_t *ps_frame_info = NULL; 294 phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL; 295 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; 296 phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; 297 uint8_t count = 0; 298 299 PH_LLCNFC_PRINT("\n\nLLC : WRITE RESP CB CALLED\n\n"); 300 301 if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo) && (NULL != pHwInfo)) 302 { 303 ps_llc_ctxt->s_frameinfo.write_pending = FALSE; 304 305 PHNFC_UNUSED_VARIABLE(result); 306 307 if(NFCSTATUS_SUCCESS == pCompInfo->status) 308 { 309 ps_frame_info = &(ps_llc_ctxt->s_frameinfo); 310 ps_recv_pkt = &(ps_frame_info->s_recvpacket); 311 ps_store_frame = &(ps_frame_info->s_send_store); 312 count = ps_frame_info->s_send_store.start_pos; 313 314 PH_LLCNFC_DEBUG("RECEIVE length : 0x%02X\n", ps_recv_pkt->llcbuf_len); 315 PH_LLCNFC_DEBUG("SENT frame type : 0x%02X\n", ps_frame_info->sent_frame_type); 316 PH_LLCNFC_DEBUG("WRITE PENDING : 0x%02X\n", ps_frame_info->write_pending); 317 PH_LLCNFC_DEBUG("WRITE PENDING status : 0x%04X\n", ps_frame_info->write_status); 318 PH_LLCNFC_DEBUG("WRITE wait frame type : 0x%02X\n", ps_frame_info->write_wait_call); 319 PH_LLCNFC_DEBUG("NS START POS : 0x%02X\n", ps_store_frame->start_pos); 320 PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_store_frame->winsize_cnt); 321 322 switch(ps_frame_info->sent_frame_type) 323 { 324 case init_u_rset_frame: 325 { 326 /* First U frame sent properly, update sent frame type 327 in the callback */ 328 result = phLlcNfc_Interface_Read (ps_llc_ctxt, 329 PH_LLCNFC_READWAIT_OFF, 330 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 331 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 332 333 if (NFCSTATUS_BUSY == 334 PHNFCSTATUS (ps_frame_info->write_status)) 335 { 336 ps_frame_info->write_status = NFCSTATUS_PENDING; 337 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt); 338 } 339 break; 340 } 341 342 case init_u_a_frame: 343 { 344 /* First UA frame sent properly, update sent frame type 345 in the callback. Send the notification to the 346 upper layer */ 347 ps_frame_info->sent_frame_type = write_resp_received; 348 result = phLlcNfc_Interface_Read (ps_llc_ctxt, 349 PH_LLCNFC_READWAIT_OFF, 350 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 351 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 352 353 if(NULL != ps_llc_ctxt->cb_for_if.notify) 354 { 355 notifyinfo.status = NFCSTATUS_SUCCESS; 356 ps_llc_ctxt->cb_for_if.notify ( 357 ps_llc_ctxt->cb_for_if.pif_ctxt, 358 ps_llc_ctxt->phwinfo, 359 NFC_NOTIFY_INIT_COMPLETED, 360 ¬ifyinfo); 361 } 362 break; 363 } 364 365 case u_rset_frame: 366 { 367 /* Retries has failed to work, so U frame is sent */ 368 ps_frame_info->sent_frame_type = write_resp_received; 369 370 if (NFCSTATUS_BUSY == 371 PHNFCSTATUS (ps_frame_info->write_status)) 372 { 373 ps_frame_info->write_status = NFCSTATUS_PENDING; 374 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt); 375 } 376 break; 377 } 378 379 case user_i_frame: 380 { 381 /* Send complete */ 382 count = ps_frame_info->n_s; 383 384 ps_store_frame->s_llcpacket[count].frame_to_send = 385 ps_frame_info->sent_frame_type = write_resp_received; 386 387 /* N(S) shall be incremented now, because, this callback 388 ensures that packet is sent */ 389 count = 390 ps_frame_info->n_s = ((ps_frame_info->n_s + 1) % 391 PH_LLCNFC_MOD_NS_NR); 392 393 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 394 PH_LLCNFC_READWAIT_OFF, 395 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 396 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 397 398 if (NFCSTATUS_BUSY == 399 PHNFCSTATUS (ps_frame_info->write_status)) 400 { 401 ps_frame_info->write_status = NFCSTATUS_PENDING; 402 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt); 403 } 404 405 406 if ((((ps_store_frame->start_pos + ps_store_frame->winsize_cnt) % 407 PH_LLCNFC_MOD_NS_NR) == ps_frame_info->n_s) && 408 (ps_frame_info->window_size == ps_store_frame->winsize_cnt)) 409 { 410 /* Don't call the upper layer send completion callback, 411 because last sent frame is the maximum that can be 412 held by LLC due to windowing 413 store the callback info, call send completion shall 414 be sent to upper layer only after the ACK is received for the 415 I frames */ 416 ps_llc_ctxt->send_cb_len = (pCompInfo->length - 417 PH_LLCNFC_APPEND_LEN); 418 } 419 else 420 { 421 /* Send completion is sent to upper layer 422 Actually, this allows the upper layer to send data, if any 423 */ 424 if (NULL != ps_llc_ctxt->cb_for_if.send_complete) 425 { 426 pCompInfo->length = (pCompInfo->length - 427 PH_LLCNFC_APPEND_LEN); 428 ps_llc_ctxt->cb_for_if.send_complete ( 429 ps_llc_ctxt->cb_for_if.pif_ctxt, 430 pHwInfo, pCompInfo); 431 } 432 } 433 break; 434 } 435 436 case s_frame: 437 { 438 #if 0 439 uint8_t i_frame_ns_value = 0; 440 #endif /* #if 0 */ 441 /* S frame is only sent when ever a I frame is received from 442 the PN544 in the read response callback, so the received I 443 frame is acknowledged with S frame. The write response 444 callback for sent S frame is in progress. */ 445 ps_frame_info->sent_frame_type = write_resp_received; 446 447 #if 0 448 i_frame_ns_value = 449 ((ps_store_frame->s_llcpacket[count].s_llcbuf.sllcpayload.llcheader 450 & LLC_NS_FRAME_HEADER_MASK) >> PH_LLCNFC_NS_START_BIT_POS); 451 452 453 PH_LLCNFC_DEBUG("Actual ns value : 0x%02X\n", 454 i_frame_ns_value); 455 #endif /* #if 0 */ 456 457 PH_LLCNFC_DEBUG("Window size : 0x%02X\n", 458 ps_frame_info->s_send_store.winsize_cnt); 459 PH_LLCNFC_DEBUG("frame to send : 0x%02X\n", 460 ps_store_frame->s_llcpacket[count].frame_to_send); 461 462 if (NFCSTATUS_BUSY == 463 PHNFCSTATUS(ps_frame_info->write_status)) 464 { 465 ps_frame_info->write_status = NFCSTATUS_PENDING; 466 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt); 467 } 468 #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB 469 phLlcNfc_H_SendInfo (ps_llc_ctxt); 470 #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ 471 break; 472 } 473 474 #ifdef LLC_RR_INSTEAD_OF_REJ 475 case rej_rr_s_frame: 476 { 477 if (NFCSTATUS_BUSY == 478 PHNFCSTATUS(ps_frame_info->write_status)) 479 { 480 ps_frame_info->write_status = NFCSTATUS_PENDING; 481 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt); 482 } 483 break; 484 } 485 #endif /* #ifdef LLC_RR_INSTEAD_OF_REJ */ 486 487 case resend_i_frame: 488 { 489 /* The code reaches here, only if stored I frame is sent 490 No changes here, but send next I frame from the stored list, 491 in the read response callback, only if proper S or I frame 492 is received from the PN544 */ 493 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 494 PH_LLCNFC_READWAIT_OFF, 495 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 496 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 497 498 if (NFCSTATUS_BUSY == PHNFCSTATUS(ps_frame_info->write_status)) 499 { 500 ps_frame_info->write_status = NFCSTATUS_PENDING; 501 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt); 502 } 503 504 if (ps_store_frame->winsize_cnt == 505 ps_frame_info->window_size) 506 { 507 /* Don't call the upper layer send completion callback, 508 store the callback info, call send completion after 509 ack for written frame 510 ps_llc_ctxt->send_cb_len = pCompInfo->length; */ 511 } 512 else 513 { 514 /* ***** This notification needs to be disabled ***** */ 515 if(NULL != ps_llc_ctxt->cb_for_if.send_complete) 516 { 517 pCompInfo->length = (pCompInfo->length - 518 PH_LLCNFC_APPEND_LEN); 519 ps_llc_ctxt->cb_for_if.send_complete( 520 ps_llc_ctxt->cb_for_if.pif_ctxt, 521 pHwInfo, pCompInfo); 522 } 523 } 524 525 if(user_i_frame == 526 ps_store_frame->s_llcpacket[count].frame_to_send) 527 { 528 /* Send complete */ 529 ps_store_frame->s_llcpacket[count].frame_to_send = 530 resend_i_frame; 531 } 532 break; 533 } 534 535 case rejected_i_frame: 536 { 537 /* Update the sent frame type, if window size count is 0 */ 538 ps_frame_info->sent_frame_type = write_resp_received; 539 /* The code enters here, whenever a I frame is resent and for 540 this resent I frame, an I frame received from PN544. 541 So the S frame is sent as the acknowledgment */ 542 if (NFCSTATUS_BUSY == 543 PHNFCSTATUS(ps_frame_info->write_status)) 544 { 545 ps_frame_info->write_status = NFCSTATUS_PENDING; 546 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt); 547 } 548 break; 549 } 550 551 case resend_s_frame: 552 { 553 /* Update the sent frame type, if window size count is 0 */ 554 ps_frame_info->sent_frame_type = write_resp_received; 555 /* The code enters here, whenever a I frame is resent and for 556 this resent I frame, an I frame received from PN544. 557 So the S frame is sent as the acknowledgment */ 558 if (NFCSTATUS_BUSY == 559 PHNFCSTATUS(ps_frame_info->write_status)) 560 { 561 ps_frame_info->write_status = NFCSTATUS_PENDING; 562 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt); 563 } 564 565 #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB 566 phLlcNfc_H_SendInfo (ps_llc_ctxt); 567 #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ 568 break; 569 } 570 571 case reject_s_frame: 572 { 573 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 574 PH_LLCNFC_READWAIT_OFF, 575 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 576 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 577 578 if (NFCSTATUS_BUSY == 579 PHNFCSTATUS(ps_frame_info->write_status)) 580 { 581 ps_frame_info->write_status = NFCSTATUS_PENDING; 582 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt); 583 } 584 break; 585 } 586 587 case u_a_frame: 588 { 589 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 590 PH_LLCNFC_READWAIT_OFF, 591 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 592 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 593 594 PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_frame_info->s_send_store.winsize_cnt); 595 596 if(ps_frame_info->s_send_store.winsize_cnt > 0) 597 { 598 result = phLlcNfc_H_SendUserIFrame (ps_llc_ctxt, 599 &(ps_frame_info->s_send_store)); 600 } 601 break; 602 } 603 604 case resend_rej_s_frame: 605 { 606 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 607 PH_LLCNFC_READWAIT_OFF, 608 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 609 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 610 611 PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_frame_info->s_send_store.winsize_cnt); 612 613 if(ps_frame_info->s_send_store.winsize_cnt > 0) 614 { 615 result = phLlcNfc_H_SendTimedOutIFrame (ps_llc_ctxt, 616 &(ps_frame_info->s_send_store), 0); 617 } 618 break; 619 } 620 621 default : 622 { 623 break; 624 } 625 } 626 } 627 else 628 { 629 /* Write not successful */ 630 if(NULL != ps_llc_ctxt->cb_for_if.send_complete) 631 { 632 phLlcNfc_StopTimers(PH_LLCNFC_GUARDTIMER, 633 ps_llc_ctxt->s_timerinfo.guard_to_count); 634 PH_LLCNFC_DEBUG("Error status received : 0x%x\n", pCompInfo->status); 635 ps_llc_ctxt->cb_for_if.send_complete( 636 ps_llc_ctxt->cb_for_if.pif_ctxt, 637 pHwInfo, pCompInfo); 638 } 639 } 640 } 641 PH_LLCNFC_PRINT("\n\nLLC : WRITE RESP CB END\n\n"); 642 } 643 644 static 645 void 646 phLlcNfc_RdResp_Cb( 647 void *pContext, 648 void *pHwInfo, 649 phNfc_sTransactionInfo_t *pCompInfo 650 ) 651 { 652 /* 653 1. LLC Receive has been called by the upper layer, the response 654 for this function is called by the lower layer 655 2. Get the frame information from the receive buffer 656 3. Depending on the received frame type, process the received 657 buffer 658 */ 659 NFCSTATUS result = NFCSTATUS_SUCCESS; 660 phLlcNfc_Context_t *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext; 661 void *p_upperctxt = NULL; 662 uint8_t crc1 = 0, 663 crc2 = 0; 664 phLlcNfc_Frame_t *ps_frame_info = NULL; 665 phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL; 666 phLlcNfc_Payload_t *ps_llc_payload = NULL; 667 pphNfcIF_Notification_CB_t notifyul = NULL; 668 phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; 669 670 PH_LLCNFC_PRINT("\n\nLLC : READ RESP CB CALLED\n\n"); 671 672 if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo) && (NULL != pHwInfo) 673 && (NULL != pCompInfo->buffer)) 674 { 675 ps_frame_info = &(ps_llc_ctxt->s_frameinfo); 676 ps_recv_pkt = &(ps_frame_info->s_recvpacket); 677 ps_llc_payload = &(ps_recv_pkt->s_llcbuf.sllcpayload); 678 679 ps_llc_ctxt->s_frameinfo.read_pending = PH_LLCNFC_READPEND_FLAG_OFF; 680 681 if (NFCSTATUS_SUCCESS == pCompInfo->status) 682 { 683 if ((PH_LLCNFC_MIN_BUFLEN_RECVD == pCompInfo->length) && 684 (((PH_LLCNFC_MIN_BUFLEN_RECVD + 1) < *(pCompInfo->buffer)) && 685 (PH_LLCNFC_MAX_BUFLEN_RECV_SEND > *(pCompInfo->buffer)))) 686 { 687 PH_LLCNFC_PRINT("Buffer received : \n"); 688 PH_LLCNFC_PRINT_BUFFER(pCompInfo->buffer, pCompInfo->length); 689 690 #if 0 691 /* Received length is 1 and receive buffer 692 contains the length field which is greater than 2, 693 so read the remaining bytes*/ 694 ps_recv_pkt->s_llcbuf.llc_length_byte = pCompInfo->buffer[0]; 695 #endif 696 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 697 PH_LLCNFC_READWAIT_OFF, 698 (uint8_t *)ps_llc_payload, 699 (uint32_t)(ps_recv_pkt->s_llcbuf.llc_length_byte)); 700 701 if ((init_u_rset_frame == ps_frame_info->sent_frame_type) && 702 (NFCSTATUS_PENDING != result) && 703 (NULL != ps_llc_ctxt->cb_for_if.notify)) 704 { 705 PH_LLCNFC_PRINT("Initialised error\n"); 706 notifyinfo.status = result; 707 /* Copy the upper layer callback pointer and the upper 708 layer context, after that call release */ 709 notifyul = ps_llc_ctxt->cb_for_if.notify; 710 p_upperctxt = ps_llc_ctxt->cb_for_if.pif_ctxt; 711 result = phLlcNfc_Release(ps_llc_ctxt, pHwInfo); 712 713 /* Wrong result, so Init failed sent */ 714 notifyul(p_upperctxt, pHwInfo, 715 NFC_NOTIFY_INIT_FAILED, ¬ifyinfo); 716 } 717 } 718 else if (TRUE == ps_llc_ctxt->s_frameinfo.write_pending) 719 { 720 /* Ignore the bytes as write is not complete and 721 pend a read for reading 1 byte */ 722 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 723 PH_LLCNFC_READWAIT_OFF, 724 (uint8_t *)&( 725 ps_recv_pkt->s_llcbuf.llc_length_byte), 726 PH_LLCNFC_MIN_BUFLEN_RECVD); 727 } 728 else if (((PH_LLCNFC_MIN_BUFLEN_RECVD + 1) < pCompInfo->length) && 729 (PH_LLCNFC_MAX_BUFLEN_RECV_SEND > pCompInfo->length) && 730 (pCompInfo->length == ps_recv_pkt->s_llcbuf.llc_length_byte)) 731 { 732 PH_LLCNFC_PRINT("Buffer received : \n"); 733 PH_LLCNFC_PRINT_BUFFER(pCompInfo->buffer, pCompInfo->length); 734 PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_frame_info->s_send_store.winsize_cnt); 735 736 /* Receive is complete, so move the state to INITIALISED */ 737 if (phLlcNfc_Resend_State != ps_llc_ctxt->state) 738 { 739 result = phLlcNfc_H_ChangeState(ps_llc_ctxt, 740 phLlcNfc_Initialised_State); 741 } 742 /* Copy the received buffer and length */ 743 ps_recv_pkt->llcbuf_len = (uint8_t) 744 (ps_recv_pkt->s_llcbuf.llc_length_byte + 1); 745 #if 0 746 (void)memcpy(ps_llc_payload, pCompInfo->buffer, 747 pCompInfo->length); 748 #endif 749 750 /* 751 Check the CRC 752 ps_llc_ctxt->s_frameinfo.s_recvpacket.s_llcbuf : 753 consists llc length byte + llc header + data + CRC 754 (which needs to be calculated by the below function) 755 ps_llc_ctxt->s_frameinfo.s_recvpacket.llcbuf_len : 756 Total length of the above buffer 757 ps_llc_ctxt->s_frameinfo.s_recvpacket.llcbuf_len - 2 : 758 -2 because the CRC has to be calculated, only for the 759 bytes which has llc length byte + llc header + data. 760 But total length (llcbuf_len) consists of above mentioned 761 things with 2 byte CRC 762 ps_llc_ctxt->s_frameinfo.s_recvpacket.s_llcbuf.sllcpayload.llcpayload : 763 consists only data (no length byte and no llc header) 764 (psllcctxt->s_frameinfo.s_recvpacket.llcbuf_len - 4) : 765 is the array index of the first CRC byte to be calculated 766 (psllcctxt->s_frameinfo.s_recvpacket.llcbuf_len - 3) : 767 is the array index of the second CRC byte to be calculated 768 */ 769 phLlcNfc_H_ComputeCrc((uint8_t *)&(ps_recv_pkt->s_llcbuf), 770 (ps_recv_pkt->llcbuf_len - 2), 771 &crc1, &crc2); 772 773 if ((crc1 == ps_llc_payload->llcpayload[ 774 (ps_recv_pkt->llcbuf_len - 4)]) 775 && (crc2 == ps_llc_payload->llcpayload[ 776 (ps_recv_pkt->llcbuf_len - 3)])) 777 { 778 result = phLlcNfc_H_ProRecvFrame(ps_llc_ctxt); 779 } 780 #ifdef LLC_DISABLE_CRC 781 else 782 { 783 result = phLlcNfc_H_ProRecvFrame(ps_llc_ctxt); 784 } 785 #else 786 else if (ps_frame_info->recv_error_count < 787 PH_LLCNFC_MAX_REJ_RETRY_COUNT) 788 { 789 LOGW("LLC bad crc"); 790 PH_LLCNFC_PRINT("CRC ERROR RECVD \n"); 791 PH_LLCNFC_DEBUG("RECV ERROR COUNT : 0x%02X\n", ps_frame_info->recv_error_count); 792 793 ps_frame_info->recv_error_count = (uint8_t) 794 (ps_frame_info->recv_error_count + 1); 795 libnfc_llc_error_count++; 796 797 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 798 PH_LLCNFC_READWAIT_OFF, 799 (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), 800 PH_LLCNFC_BYTES_INIT_READ); 801 #ifdef CRC_ERROR_REJ 802 /* Send REJ (S frame), as the CRC received has error */ 803 result = phLlcNfc_H_SendRejectFrame (ps_llc_ctxt); 804 805 #endif /* #ifdef CRC_ERROR_REJ */ 806 807 } 808 else 809 { 810 LOGE("max LLC retries exceeded, stack restart"); 811 result = phLlcNfc_Interface_Read (ps_llc_ctxt, 812 PH_LLCNFC_READWAIT_OFF, 813 (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), 814 PH_LLCNFC_BYTES_INIT_READ); 815 816 /* Raise the exception for CRC error received from the */ 817 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC, 818 NFCSTATUS_BOARD_COMMUNICATION_ERROR); 819 #if 0 820 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1); 821 #endif /* #if 0 */ 822 /* Resend done, no answer from the device */ 823 ps_llc_ctxt->cb_for_if.notify ( 824 ps_llc_ctxt->cb_for_if.pif_ctxt, 825 ps_llc_ctxt->phwinfo, 826 NFC_NOTIFY_DEVICE_ERROR, 827 ¬ifyinfo); 828 } 829 830 #endif /* #ifdef LLC_DISABLE_CRC */ 831 } /* read more than 1 byte */ 832 else if (ps_frame_info->recv_error_count >= 833 PH_LLCNFC_MAX_REJ_RETRY_COUNT) 834 { 835 LOGE("max LLC retries exceeded, stack restart"); 836 result = phLlcNfc_Interface_Read (ps_llc_ctxt, 837 PH_LLCNFC_READWAIT_OFF, 838 (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), 839 PH_LLCNFC_BYTES_INIT_READ); 840 841 /* Raise the exception for CRC error received from the */ 842 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC, 843 NFCSTATUS_BOARD_COMMUNICATION_ERROR); 844 #if 0 845 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1); 846 #endif /* #if 0 */ 847 /* Resend done, no answer from the device */ 848 ps_llc_ctxt->cb_for_if.notify ( 849 ps_llc_ctxt->cb_for_if.pif_ctxt, 850 ps_llc_ctxt->phwinfo, 851 NFC_NOTIFY_DEVICE_ERROR, 852 ¬ifyinfo); 853 } 854 else if (((PH_LLCNFC_MIN_BUFLEN_RECVD + 1) < pCompInfo->length) && 855 (PH_LLCNFC_MAX_BUFLEN_RECV_SEND > pCompInfo->length) && 856 (pCompInfo->length != ps_recv_pkt->s_llcbuf.llc_length_byte)) 857 { 858 LOGE("bad LLC length1 %d", pCompInfo->length); 859 ps_frame_info->recv_error_count = (uint8_t) 860 (ps_frame_info->recv_error_count + 1); 861 libnfc_llc_error_count++; 862 863 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 864 PH_LLCNFC_READWAIT_OFF, 865 (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), 866 PH_LLCNFC_BYTES_INIT_READ); 867 868 #ifdef CRC_ERROR_REJ 869 870 /* Send REJ (S frame), as the CRC received has error */ 871 result = phLlcNfc_H_SendRejectFrame (ps_llc_ctxt); 872 873 #endif /* #ifdef CRC_ERROR_REJ */ 874 } 875 else if ((PH_LLCNFC_MIN_BUFLEN_RECVD == pCompInfo->length) && 876 ((*(pCompInfo->buffer) > (PH_LLCNFC_MAX_BUFLEN_RECV_SEND - 1)) 877 ||(*(pCompInfo->buffer) <= (PH_LLCNFC_MIN_BUFLEN_RECVD + 1)))) 878 { 879 /* Temporary fix for the 0xFF data received 880 Solution for the read one byte, giving error in buffer 881 PH_LLCNFC_MAX_BUFLEN_RECV_SEND (0x21) is the maximum 882 bytes expected by LLC, if the buffer 883 value is greater than (0x21 - 1), then pend a read to 884 get 1 byte again 885 */ 886 LOGW("bad LLC length byte %x\n", *(pCompInfo->buffer)); 887 ps_frame_info->recv_error_count = (uint8_t) 888 (ps_frame_info->recv_error_count + 1); 889 libnfc_llc_error_count++; 890 891 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 892 PH_LLCNFC_READWAIT_OFF, 893 (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), 894 PH_LLCNFC_BYTES_INIT_READ); 895 } 896 else 897 { 898 LOGW("unknown LLC error1"); 899 ps_frame_info->recv_error_count = (uint8_t) 900 (ps_frame_info->recv_error_count + 1); 901 libnfc_llc_error_count++; 902 903 phLlcNfc_StopTimers(PH_LLCNFC_GUARDTIMER, 904 ps_llc_ctxt->s_timerinfo.guard_to_count); 905 pCompInfo->status = PHNFCSTVAL(CID_NFC_LLC, 906 NFCSTATUS_INVALID_FORMAT); 907 pCompInfo->buffer = NULL; 908 pCompInfo->length = 0; 909 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 910 PH_LLCNFC_READWAIT_OFF, 911 (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), 912 PH_LLCNFC_BYTES_INIT_READ); 913 if (NULL != ps_llc_ctxt->cb_for_if.receive_complete) 914 { 915 ps_llc_ctxt->cb_for_if.receive_complete( 916 ps_llc_ctxt->cb_for_if.pif_ctxt, 917 pHwInfo, pCompInfo); 918 } 919 } 920 } else if (NFCSTATUS_READ_FAILED == pCompInfo->status) { 921 // partial read - try reading the length byte again 922 LOGW("LLC length mis-match\n"); 923 ps_frame_info->recv_error_count = (uint8_t) 924 (ps_frame_info->recv_error_count + 1); 925 libnfc_llc_error_count++; 926 927 result = phLlcNfc_Interface_Read(ps_llc_ctxt, 928 PH_LLCNFC_READWAIT_OFF, 929 (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), 930 PH_LLCNFC_BYTES_INIT_READ); 931 } 932 else 933 { 934 LOGW("unknown LLC error2"); 935 ps_frame_info->recv_error_count = (uint8_t) 936 (ps_frame_info->recv_error_count + 1); 937 libnfc_llc_error_count++; 938 939 phLlcNfc_StopTimers(PH_LLCNFC_GUARDTIMER, 940 ps_llc_ctxt->s_timerinfo.guard_to_count); 941 PH_LLCNFC_DEBUG("Status Error : 0x%x\n", pCompInfo->status); 942 if (NULL != ps_llc_ctxt->cb_for_if.receive_complete) 943 { 944 ps_llc_ctxt->cb_for_if.receive_complete( 945 ps_llc_ctxt->cb_for_if.pif_ctxt, 946 pHwInfo, pCompInfo); 947 } 948 } 949 } 950 else 951 { 952 if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo) 953 && (NULL != ps_llc_ctxt->cb_for_if.receive_complete)) 954 { 955 ps_llc_ctxt->cb_for_if.receive_complete( 956 ps_llc_ctxt->cb_for_if.pif_ctxt, 957 pHwInfo, pCompInfo); 958 } 959 } 960 961 PH_LLCNFC_PRINT("\n\nLLC : READ RESP CB END\n\n"); 962 } 963 964 void 965 phLlcNfc_H_SendInfo ( 966 phLlcNfc_Context_t *psLlcCtxt 967 ) 968 { 969 phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL; 970 phLlcNfc_Frame_t *ps_frame_info = NULL; 971 phNfc_sTransactionInfo_t comp_info = {0,0,0,0,0}; 972 973 ps_frame_info = &(psLlcCtxt->s_frameinfo); 974 ps_recv_pkt = &(ps_frame_info->s_recvpacket); 975 976 if ((ps_recv_pkt->llcbuf_len > 0) && 977 (ps_recv_pkt->llcbuf_len <= PH_LLCNFC_MAX_LLC_PAYLOAD)) 978 { 979 comp_info.status = NFCSTATUS_SUCCESS; 980 /* Chop the extra Llc bytes received */ 981 #if 0 982 comp_info.length = (ps_recv_pkt->llcbuf_len - 983 PH_LLCNFC_LEN_APPEND); 984 #else 985 comp_info.length = (uint16_t)psLlcCtxt->recvbuf_length; 986 #endif /* */ 987 988 if (0 != comp_info.length) 989 { 990 #if 0 991 (void)memcpy ((void *)psLlcCtxt->precv_buf, (void *)( 992 ps_recv_pkt->s_llcbuf.sllcpayload.llcpayload), 993 comp_info.length); 994 #endif /* #if 0 */ 995 comp_info.buffer = psLlcCtxt->precv_buf; 996 } 997 else 998 { 999 comp_info.buffer = NULL; 1000 } 1001 } 1002 else 1003 { 1004 comp_info.status = PHNFCSTVAL(CID_NFC_LLC, 1005 NFCSTATUS_INVALID_FORMAT); 1006 comp_info.length = 0; 1007 comp_info.buffer = NULL; 1008 } 1009 1010 (void)phLlcNfc_Interface_Read(psLlcCtxt, 1011 PH_LLCNFC_READWAIT_OFF, 1012 &(ps_recv_pkt->s_llcbuf.llc_length_byte), 1013 (uint8_t)PH_LLCNFC_BYTES_INIT_READ); 1014 1015 if ((NFCSTATUS_SUCCESS == comp_info.status) && 1016 (0 == comp_info.length)) 1017 { 1018 /* May be a NULL I frame received from PN544, so dont do 1019 any thing */ 1020 } 1021 else 1022 { 1023 if ((NULL != psLlcCtxt->cb_for_if.receive_complete) && 1024 (TRUE == ps_frame_info->upper_recv_call)) 1025 { 1026 ps_frame_info->upper_recv_call = FALSE; 1027 psLlcCtxt->cb_for_if.receive_complete( 1028 psLlcCtxt->cb_for_if.pif_ctxt, 1029 psLlcCtxt->phwinfo, 1030 &comp_info); 1031 } 1032 else 1033 { 1034 if (NULL != psLlcCtxt->cb_for_if.notify) 1035 { 1036 psLlcCtxt->cb_for_if.notify( 1037 psLlcCtxt->cb_for_if.pif_ctxt, 1038 psLlcCtxt->phwinfo, 1039 NFC_NOTIFY_RECV_COMPLETED, 1040 &comp_info); 1041 } 1042 } 1043 } 1044 return; 1045 } 1046 1047