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