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_Timer.c 19 * \brief To create, start, stop and destroy timer. 20 * 21 * Project: NFC-FRI-1.1 22 * 23 * $Date: Mon Jun 14 11:47:54 2010 $ 24 * $Author: ing02260 $ 25 * $Revision: 1.55 $ 26 * $Aliases: NFC_FRI1.1_WK1023_R35_2,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.h> 37 #include <phLlcNfc_DataTypes.h> 38 #include <phLlcNfc_Interface.h> 39 #include <phLlcNfc_Frame.h> 40 #include <phLlcNfc_Timer.h> 41 42 /*********************** End of includes ****************************/ 43 44 /***************************** Macros *******************************/ 45 /**< Timer for connection timer index */ 46 #define PH_LLCNFC_CONNECTION_TO_INDEX (0x00) 47 /**< Maximum guard timer can be present */ 48 #define PH_LLCNFC_MAX_GUARD_TIMER (0x04) 49 /** Connection time out bit to set */ 50 #define PH_LLCNFC_CON_TO_BIT (0) 51 /** Guard time out bit to set */ 52 #define PH_LLCNFC_GUARD_TO_BIT (1) 53 /** Ack time out bit to set */ 54 #define PH_LLCNFC_ACK_TO_BIT (2) 55 /** No of bits to set */ 56 #define PH_LLCNFC_TO_NOOFBITS (1) 57 /** Connection time out bit value */ 58 #define PH_LLCNFC_CON_TO_BIT_VAL (0x01) 59 /** Guard time out bit to set */ 60 #define PH_LLCNFC_GUARD_TO_BIT_VAL (0x02) 61 /** ACK time out bit to set */ 62 #define PH_LLCNFC_ACK_TO_BIT_VAL (0x04) 63 64 #define GUARD_TO_URSET 65 66 67 /************************ End of macros *****************************/ 68 69 /*********************** Local functions ****************************/ 70 /* This callback is for guard time out */ 71 #ifdef LLC_TIMER_ENABLE 72 static 73 void 74 phLlcNfc_GuardTimeoutCb ( 75 uint32_t TimerId, 76 void *pContext 77 ); 78 79 80 #ifdef PIGGY_BACK 81 /* This callback is for acknowledge time out */ 82 static 83 void 84 phLlcNfc_AckTimeoutCb ( 85 uint32_t TimerId 86 ); 87 #endif /* #ifdef PIGGY_BACK */ 88 89 /* This callback is for connection time out */ 90 static 91 void 92 phLlcNfc_ConnectionTimeoutCb ( 93 uint32_t TimerId, 94 void *pContext 95 ); 96 #endif /* #ifdef LLC_TIMER_ENABLE */ 97 98 /******************** End of Local functions ************************/ 99 100 /********************** Global variables ****************************/ 101 static phLlcNfc_Context_t *gpphLlcNfc_Ctxt = NULL; 102 103 /******************** End of Global Variables ***********************/ 104 105 NFCSTATUS 106 phLlcNfc_TimerInit( 107 phLlcNfc_Context_t *psLlcCtxt 108 ) 109 { 110 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC, 111 NFCSTATUS_INVALID_PARAMETER); 112 uint8_t index = 0; 113 if (NULL != psLlcCtxt) 114 { 115 result = NFCSTATUS_SUCCESS; 116 gpphLlcNfc_Ctxt = psLlcCtxt; 117 while (index < PH_LLCNFC_MAX_TIMER_USED) 118 { 119 #ifdef LLC_TIMER_ENABLE 120 gpphLlcNfc_Ctxt->s_timerinfo.timer_id[index] = 121 PH_OSALNFC_INVALID_TIMER_ID; 122 #endif /* #ifdef LLC_TIMER_ENABLE */ 123 index++; 124 } 125 } 126 return result; 127 } 128 129 void 130 phLlcNfc_TimerUnInit( 131 phLlcNfc_Context_t *psLlcCtxt 132 ) 133 { 134 uint8_t index = 0; 135 if ((NULL != gpphLlcNfc_Ctxt) && 136 (gpphLlcNfc_Ctxt == psLlcCtxt)) 137 { 138 while (index <= PH_LLCNFC_ACKTIMER) 139 { 140 if (PH_LLCNFC_GUARDTIMER == index) 141 { 142 phLlcNfc_StopTimers (index, 143 gpphLlcNfc_Ctxt->s_timerinfo.guard_to_count); 144 } 145 else 146 { 147 phLlcNfc_StopTimers (index, 0); 148 } 149 index++; 150 } 151 phLlcNfc_DeleteTimer(); 152 } 153 } 154 155 void 156 phLlcNfc_CreateTimers(void) 157 { 158 uint8_t index = 0; 159 160 while (index < PH_LLCNFC_MAX_TIMER_USED) 161 { 162 #ifdef LLC_TIMER_ENABLE 163 gpphLlcNfc_Ctxt->s_timerinfo.timer_id[index] = 164 phOsalNfc_Timer_Create(); 165 #endif /* #ifdef LLC_TIMER_ENABLE */ 166 index++; 167 } 168 return; 169 } 170 171 NFCSTATUS 172 phLlcNfc_StartTimers ( 173 uint8_t TimerType, 174 uint8_t ns_value 175 ) 176 { 177 NFCSTATUS result = NFCSTATUS_SUCCESS; 178 #ifdef LLC_TIMER_ENABLE 179 180 uint32_t timerid = 0; 181 uint8_t timerstarted = 0; 182 uint8_t timer_count = 0; 183 uint16_t timer_resolution = 0; 184 ppCallBck_t Callback = NULL; 185 phLlcNfc_Timerinfo_t *ps_timer_info = NULL; 186 187 ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); 188 PHNFC_UNUSED_VARIABLE(result); 189 190 PH_LLCNFC_PRINT("\n\nLLC : START TIMER CALLED\n\n"); 191 /* Depending on the timer type, use the Osal callback */ 192 switch(TimerType) 193 { 194 case PH_LLCNFC_CONNECTIONTIMER: 195 { 196 /* Get the connection timer flag */ 197 timerstarted = (uint8_t) 198 GET_BITS8(ps_timer_info->timer_flag, 199 PH_LLCNFC_CON_TO_BIT, 200 PH_LLCNFC_TO_NOOFBITS); 201 if (0 == timerstarted) 202 { 203 /* Timer not started, so start the timer */ 204 gpphLlcNfc_Ctxt->s_timerinfo.timer_flag = (uint8_t) 205 SET_BITS8 (ps_timer_info->timer_flag, 206 PH_LLCNFC_CON_TO_BIT, 207 PH_LLCNFC_TO_NOOFBITS, 208 (PH_LLCNFC_CON_TO_BIT + 1)); 209 } 210 211 timerid = ps_timer_info->timer_id[PH_LLCNFC_CONNECTION_TO_INDEX]; 212 Callback = (ppCallBck_t)&phLlcNfc_ConnectionTimeoutCb; 213 timer_resolution = ps_timer_info->con_to_value = (uint16_t) 214 PH_LLCNFC_CONNECTION_TO_VALUE; 215 break; 216 } 217 218 case PH_LLCNFC_GUARDTIMER: 219 { 220 if (ps_timer_info->guard_to_count < PH_LLCNFC_MAX_GUARD_TIMER) 221 { 222 timer_count = ps_timer_info->guard_to_count; 223 timer_resolution = (uint16_t)PH_LLCNFC_RESOLUTION; 224 225 PH_LLCNFC_DEBUG("RESOLUTION VALUE : 0x%02X\n", PH_LLCNFC_RESOLUTION); 226 PH_LLCNFC_DEBUG("TIME-OUT VALUE : 0x%02X\n", PH_LLCNFC_GUARD_TO_VALUE); 227 228 /* Get the guard timer flag */ 229 timerstarted = (uint8_t) 230 GET_BITS8 (ps_timer_info->timer_flag, 231 PH_LLCNFC_GUARD_TO_BIT, 232 PH_LLCNFC_TO_NOOFBITS); 233 234 PH_LLCNFC_DEBUG("GUARD TIMER NS INDEX : 0x%02X\n", ns_value); 235 PH_LLCNFC_DEBUG("GUARD TIMER COUNT : 0x%02X\n", timer_count); 236 PH_LLCNFC_DEBUG("GUARD TIMER STARTED : 0x%02X\n", timerstarted); 237 238 if (0 == timerstarted) 239 { 240 /* Timer not started, so start the timer */ 241 ps_timer_info->timer_flag = (uint8_t) 242 SET_BITS8 (ps_timer_info->timer_flag, 243 PH_LLCNFC_GUARD_TO_BIT, 244 PH_LLCNFC_TO_NOOFBITS, 245 PH_LLCNFC_GUARD_TO_BIT); 246 } 247 248 timerid = ps_timer_info->timer_id[PH_LLCNFC_GUARDTIMER]; 249 Callback = (ppCallBck_t)&phLlcNfc_GuardTimeoutCb; 250 251 /* Guard time out value */ 252 ps_timer_info->guard_to_value[timer_count] = (uint16_t) 253 PH_LLCNFC_GUARD_TO_VALUE; 254 255 ps_timer_info->timer_ns_value[timer_count] = ns_value; 256 ps_timer_info->frame_type[timer_count] = (uint8_t)invalid_frame; 257 ps_timer_info->iframe_send_count[timer_count] = 0; 258 259 if ((timer_count > 0) && 260 (ps_timer_info->guard_to_value[(timer_count - 1)] >= 261 PH_LLCNFC_GUARD_TO_VALUE)) 262 { 263 /* If the timer has been started already and the 264 value is same as the previous means that timer has still 265 not expired, so the time out value is increased by 266 a resolution */ 267 ps_timer_info->guard_to_value[timer_count] = (uint16_t) 268 (ps_timer_info->guard_to_value[(timer_count - 1)] + 269 PH_LLCNFC_RESOLUTION); 270 } 271 272 PH_LLCNFC_DEBUG("GUARD TIMER VALUE : 0x%04X\n", ps_timer_info->guard_to_value[timer_count]); 273 274 275 ps_timer_info->guard_to_count = (uint8_t)( 276 ps_timer_info->guard_to_count + 1); 277 } 278 else 279 { 280 /* TIMER should not start, because the time out count has readched the limit */ 281 timerstarted = TRUE; 282 } 283 break; 284 } 285 286 #ifdef PIGGY_BACK 287 288 case PH_LLCNFC_ACKTIMER: 289 { 290 /* Get the ack timer flag */ 291 timerstarted = (uint8_t)GET_BITS8 ( 292 ps_timer_info->timer_flag, 293 PH_LLCNFC_ACK_TO_BIT, 294 PH_LLCNFC_TO_NOOFBITS); 295 296 if (FALSE == timerstarted) 297 { 298 /* Timer not started, so start the timer */ 299 ps_timer_info->timer_flag = (uint8_t) 300 SET_BITS8 (ps_timer_info->timer_flag, 301 PH_LLCNFC_ACK_TO_BIT, 302 PH_LLCNFC_TO_NOOFBITS, 303 (PH_LLCNFC_ACK_TO_BIT - 1)); 304 } 305 306 307 timer_resolution = ps_timer_info->ack_to_value = (uint16_t) 308 PH_LLCNFC_ACK_TO_VALUE; 309 timerid = ps_timer_info->timer_id[PH_LLCNFC_ACKTIMER]; 310 Callback = (ppCallBck_t)&phLlcNfc_AckTimeoutCb; 311 break; 312 } 313 314 #endif /* #ifdef PIGGY_BACK */ 315 316 default: 317 { 318 result = PHNFCSTVAL(CID_NFC_LLC, 319 NFCSTATUS_INVALID_PARAMETER); 320 break; 321 } 322 } 323 if ((NFCSTATUS_SUCCESS == result) && 324 (FALSE == timerstarted)) 325 { 326 PH_LLCNFC_DEBUG("OSAL START TIMER CALLED TIMER ID : 0x%02X\n", timerid); 327 phOsalNfc_Timer_Start (timerid, timer_resolution, Callback, NULL); 328 } 329 330 PH_LLCNFC_PRINT("\n\nLLC : START TIMER END\n\n"); 331 332 #else /* #ifdef LLC_TIMER_ENABLE */ 333 334 PHNFC_UNUSED_VARIABLE(result); 335 PHNFC_UNUSED_VARIABLE(TimerType); 336 PHNFC_UNUSED_VARIABLE(ns_value); 337 338 #endif /* #ifdef LLC_TIMER_ENABLE */ 339 return result; 340 } 341 342 void 343 phLlcNfc_StopTimers ( 344 uint8_t TimerType, 345 uint8_t no_of_guard_to_del 346 ) 347 { 348 NFCSTATUS result = NFCSTATUS_SUCCESS; 349 #ifdef LLC_TIMER_ENABLE 350 351 uint32_t timerid = 0, 352 timerflag = FALSE; 353 uint8_t timer_count = 0; 354 phLlcNfc_Timerinfo_t *ps_timer_info = NULL; 355 356 357 ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); 358 timerflag = ps_timer_info->timer_flag; 359 360 PHNFC_UNUSED_VARIABLE (result); 361 PH_LLCNFC_PRINT("\n\nLLC : STOP TIMER CALLED\n\n"); 362 switch(TimerType) 363 { 364 case PH_LLCNFC_CONNECTIONTIMER: 365 { 366 ps_timer_info->timer_flag = (uint8_t) 367 SET_BITS8(ps_timer_info->timer_flag, 368 PH_LLCNFC_CON_TO_BIT, 369 PH_LLCNFC_TO_NOOFBITS, 0); 370 timerid = ps_timer_info->timer_id 371 [PH_LLCNFC_CONNECTION_TO_INDEX]; 372 break; 373 } 374 375 case PH_LLCNFC_GUARDTIMER: 376 { 377 uint8_t start_index = 0; 378 379 timer_count = ps_timer_info->guard_to_count; 380 381 PH_LLCNFC_DEBUG("GUARD TIMER COUNT BEFORE DELETE: 0x%02X\n", timer_count); 382 PH_LLCNFC_DEBUG("GUARD TIMER TO DELETE: 0x%02X\n", no_of_guard_to_del); 383 384 if (timer_count > no_of_guard_to_del) 385 { 386 /* The number of guard timer count is more than the 387 guard timer to delete */ 388 while (start_index < (timer_count - no_of_guard_to_del)) 389 { 390 /* Copy the previous stored timer values to the present */ 391 ps_timer_info->guard_to_value[start_index] = (uint16_t) 392 (ps_timer_info->guard_to_value[ 393 (no_of_guard_to_del + start_index)]); 394 395 ps_timer_info->iframe_send_count[start_index] = (uint8_t) 396 (ps_timer_info->iframe_send_count[ 397 (no_of_guard_to_del + start_index)]); 398 399 PH_LLCNFC_DEBUG("GUARD TIMER NS INDEX DELETED : 0x%02X\n", ps_timer_info->timer_ns_value[start_index]); 400 401 ps_timer_info->timer_ns_value[start_index] = (uint8_t) 402 (ps_timer_info->timer_ns_value[ 403 (no_of_guard_to_del + start_index)]); 404 405 ps_timer_info->frame_type[start_index] = (uint8_t) 406 (ps_timer_info->frame_type[ 407 (no_of_guard_to_del + start_index)]); 408 409 start_index = (uint8_t)(start_index + 1); 410 } 411 } 412 else 413 { 414 while (start_index < no_of_guard_to_del) 415 { 416 ps_timer_info->guard_to_value[start_index] = 0; 417 418 ps_timer_info->iframe_send_count[start_index] = 0; 419 420 PH_LLCNFC_DEBUG("GUARD TIMER NS INDEX DELETED ELSE : 0x%02X\n", ps_timer_info->timer_ns_value[start_index]); 421 422 ps_timer_info->timer_ns_value[start_index] = 0; 423 424 ps_timer_info->frame_type[start_index] = 0; 425 426 start_index = (uint8_t)(start_index + 1); 427 } 428 } 429 430 if (timer_count >= no_of_guard_to_del) 431 { 432 timer_count = (uint8_t)(timer_count - no_of_guard_to_del); 433 } 434 else 435 { 436 if (0 != no_of_guard_to_del) 437 { 438 timer_count = 0; 439 } 440 } 441 442 timerid = ps_timer_info->timer_id[PH_LLCNFC_GUARDTIMER]; 443 ps_timer_info->guard_to_count = timer_count; 444 PH_LLCNFC_DEBUG("GUARD TIMER COUNT AFTER DELETE: 0x%02X\n", timer_count); 445 446 if (0 == ps_timer_info->guard_to_count) 447 { 448 /* This means that there are no frames to run guard 449 timer, so set the timer flag to 0 */ 450 ps_timer_info->timer_flag = (uint8_t) 451 SET_BITS8 (ps_timer_info->timer_flag, 452 PH_LLCNFC_GUARD_TO_BIT, 453 PH_LLCNFC_TO_NOOFBITS, 0); 454 } 455 else 456 { 457 timerflag = 0; 458 } 459 break; 460 } 461 462 #ifdef PIGGY_BACK 463 case PH_LLCNFC_ACKTIMER: 464 { 465 timerflag = (timerflag & PH_LLCNFC_ACK_TO_BIT_VAL); 466 467 ps_timer_info->timer_flag = (uint8_t) 468 SET_BITS8 (ps_timer_info->timer_flag, 469 PH_LLCNFC_ACK_TO_BIT, 470 PH_LLCNFC_TO_NOOFBITS, 0); 471 timerid = ps_timer_info->timer_id[PH_LLCNFC_ACKTIMER]; 472 ps_timer_info->ack_to_value = 0; 473 break; 474 } 475 #endif /* #ifdef PIGGY_BACK */ 476 477 default: 478 { 479 result = PHNFCSTVAL(CID_NFC_LLC, 480 NFCSTATUS_INVALID_PARAMETER); 481 break; 482 } 483 } 484 485 if ((NFCSTATUS_SUCCESS == result) && (timerflag > 0)) 486 { 487 PH_LLCNFC_DEBUG("OSAL STOP TIMER CALLED TIMER ID : 0x%02X\n", timerid); 488 phOsalNfc_Timer_Stop (timerid); 489 } 490 491 PH_LLCNFC_PRINT("\n\nLLC : STOP TIMER END\n\n"); 492 493 #else /* #ifdef LLC_TIMER_ENABLE */ 494 495 PHNFC_UNUSED_VARIABLE (result); 496 PHNFC_UNUSED_VARIABLE (TimerType); 497 PHNFC_UNUSED_VARIABLE (no_of_guard_to_del); 498 499 #endif /* #ifdef LLC_TIMER_ENABLE */ 500 } 501 502 void 503 phLlcNfc_StopAllTimers (void) 504 { 505 506 #ifdef LLC_TIMER_ENABLE 507 508 phLlcNfc_Timerinfo_t *ps_timer_info = NULL; 509 uint8_t timer_started = 0; 510 uint32_t timerid = 0; 511 uint8_t timer_index = 0; 512 513 514 ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); 515 516 PH_LLCNFC_PRINT("\n\nLLC : STOP ALL TIMERS CALLED \n\n"); 517 518 timerid = ps_timer_info->timer_id[timer_index]; 519 timer_started = (uint8_t) 520 GET_BITS8(ps_timer_info->timer_flag, 521 PH_LLCNFC_CON_TO_BIT, 522 PH_LLCNFC_TO_NOOFBITS); 523 524 PH_LLCNFC_DEBUG("CONNECTION TIMER ID: 0x%02X\n", timerid); 525 526 if (0 != timer_started) 527 { 528 /* Connection timer is started, so now stop it */ 529 ps_timer_info->timer_flag = (uint8_t) 530 SET_BITS8 (ps_timer_info->timer_flag, 531 PH_LLCNFC_CON_TO_BIT, 532 PH_LLCNFC_TO_NOOFBITS, 0); 533 #if 0 534 535 ps_timer_info->con_to_value = 0; 536 537 #endif /* #if 0 */ 538 539 phOsalNfc_Timer_Stop (timerid); 540 } 541 542 timer_index = (uint8_t)(timer_index + 1); 543 timerid = ps_timer_info->timer_id[timer_index]; 544 timer_started = (uint8_t)GET_BITS8 (ps_timer_info->timer_flag, 545 PH_LLCNFC_GUARD_TO_BIT, 546 PH_LLCNFC_TO_NOOFBITS); 547 548 if (0 != timer_started) 549 { 550 /* Guard timer is already started */ 551 ps_timer_info->timer_flag = (uint8_t) 552 SET_BITS8 (ps_timer_info->timer_flag, 553 PH_LLCNFC_GUARD_TO_BIT, 554 PH_LLCNFC_TO_NOOFBITS, 0); 555 556 timer_index = 0; 557 ps_timer_info->guard_to_count = 0; 558 559 #if 0 560 561 /* Reset all the guard timer related variables */ 562 while (timer_index < ps_timer_info->guard_to_count) 563 { 564 ps_timer_info->guard_to_value[timer_index] = 0; 565 ps_timer_info->iframe_send_count[timer_index] = 0; 566 567 timer_index = (uint8_t)(timer_index + 1); 568 } 569 570 #endif /* #if 0 */ 571 572 PH_LLCNFC_DEBUG("GUARD TIMER ID: 0x%02X\n", timerid); 573 574 /* Stop the timer */ 575 phOsalNfc_Timer_Stop (timerid); 576 577 PH_LLCNFC_PRINT("\n\nLLC : STOP ALL TIMERS END \n\n"); 578 } 579 580 #endif /* #ifdef LLC_TIMER_ENABLE */ 581 } 582 583 void 584 phLlcNfc_DeleteTimer (void) 585 { 586 uint8_t index = 0; 587 while (index < PH_LLCNFC_MAX_TIMER_USED) 588 { 589 #ifdef LLC_TIMER_ENABLE 590 phOsalNfc_Timer_Delete( 591 gpphLlcNfc_Ctxt->s_timerinfo.timer_id[index]); 592 gpphLlcNfc_Ctxt->s_timerinfo.timer_id[index] = 593 PH_OSALNFC_INVALID_TIMER_ID; 594 #endif /* #ifdef LLC_TIMER_ENABLE */ 595 index++; 596 } 597 } 598 599 #ifdef LLC_TIMER_ENABLE 600 601 #define LLC_GUARD_TIMER_RETRIES (0x03U) 602 603 static 604 void 605 phLlcNfc_GuardTimeoutCb ( 606 uint32_t TimerId, 607 void *pContext 608 ) 609 { 610 NFCSTATUS result = NFCSTATUS_SUCCESS; 611 phLlcNfc_Timerinfo_t *ps_timer_info = NULL; 612 phLlcNfc_Frame_t *ps_frame_info = NULL; 613 phLlcNfc_LlcPacket_t s_packet_info; 614 uint8_t index = 0; 615 /* zero_to_index = Time out index has become 0 */ 616 uint8_t zero_to_index = 0; 617 618 #if defined (GUARD_TO_ERROR) 619 phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; 620 #endif /* #if defined (GUARD_TO_ERROR) */ 621 622 PH_LLCNFC_PRINT("\n\nLLC : GUARD TIMEOUT CB CALLED \n\n"); 623 624 if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == 625 gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_GUARDTIMER]) && 626 (PH_LLCNFC_GUARD_TO_BIT_VAL == 627 (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag & 628 PH_LLCNFC_GUARD_TO_BIT_VAL))) 629 { 630 uint8_t timer_expired = FALSE; 631 632 ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo); 633 ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); 634 635 #if !defined (CYCLIC_TIMER) 636 phOsalNfc_Timer_Stop( 637 ps_timer_info->timer_id[PH_LLCNFC_GUARDTIMER]); 638 #endif 639 640 PH_LLCNFC_DEBUG("NO OF TIMEOUT COUNT : 0x%02X\n", ps_timer_info->guard_to_count); 641 /* Loop is completely depending on the number of different LLC 642 send called */ 643 while (index < ps_timer_info->guard_to_count) 644 { 645 /* This loop runs for all the timer present in the data structure. 646 This means if there are 2 I frame has been sent and 647 response is not received for the I frames sent then the 648 each time this timer expires, the time out value is decremented 649 by the PH_LLCNFC_RESOLUTION value */ 650 if (0 != ps_timer_info->guard_to_value[index]) 651 { 652 /* If timer value is not zero then enter, 653 this means that the value is not zero */ 654 if (ps_timer_info->guard_to_value[index] > 0) 655 { 656 if (ps_timer_info->guard_to_value[index] >= 657 PH_LLCNFC_RESOLUTION) 658 { 659 ps_timer_info->guard_to_value[index] = (uint16_t) 660 (ps_timer_info->guard_to_value[index] - 661 PH_LLCNFC_RESOLUTION); 662 } 663 else 664 { 665 ps_timer_info->guard_to_value[index] = 0; 666 } 667 } 668 669 if (0 == ps_timer_info->guard_to_value[index]) 670 { 671 /* Timer value has expired, so resend has to be done 672 Timer value is 0 */ 673 ps_timer_info->frame_type[index] = (uint8_t)resend_i_frame; 674 if (FALSE == timer_expired) 675 { 676 /* As the statement is in the loop, so there are possibilities 677 of more than 1 timer value can be 0, so if previous timer 678 value has already been 0, then again dont change the 679 index */ 680 zero_to_index = index; 681 timer_expired = TRUE; 682 } 683 } 684 } 685 index = (uint8_t)(index + 1); 686 } 687 688 #if !defined (CYCLIC_TIMER) 689 /* Start the timer again */ 690 phOsalNfc_Timer_Start( 691 ps_timer_info->timer_id[PH_LLCNFC_GUARDTIMER], 692 PH_LLCNFC_RESOLUTION, phLlcNfc_GuardTimeoutCb, NULL); 693 #endif 694 PH_LLCNFC_DEBUG("TIMER EXPIRED : 0x%02X\n", timer_expired); 695 696 if (TRUE == timer_expired) 697 { 698 PH_LLCNFC_DEBUG("TIMER EXPIRED INDEX: 0x%02X\n", zero_to_index); 699 PH_LLCNFC_DEBUG("TIMER EXPIRED NS INDEX: 0x%02X\n", ps_timer_info->timer_ns_value[zero_to_index]); 700 PH_LLCNFC_DEBUG("TIMER EXPIRED RETRIES : 0x%02X\n", ps_timer_info->iframe_send_count[zero_to_index]); 701 702 PH_LLCNFC_DEBUG("TIMER EXPIRED GUARD TIME-OUT COUNT: 0x%02X\n", ps_timer_info->guard_to_value[zero_to_index]); 703 704 if ((0 == ps_timer_info->guard_to_value[zero_to_index]) && 705 (ps_timer_info->iframe_send_count[zero_to_index] < 706 LLC_GUARD_TIMER_RETRIES)) 707 { 708 if (ps_frame_info->s_send_store.winsize_cnt > 0) 709 { 710 uint8_t start_index = 0; 711 uint8_t timer_count = 0; 712 uint8_t while_exit = FALSE; 713 714 timer_count = ps_timer_info->guard_to_count; 715 716 /* Check before changing the index to resend, if index 717 already exist then dont set the index */ 718 while ((FALSE == while_exit) && (start_index < timer_count)) 719 { 720 if (resend_i_frame == 721 ps_timer_info->frame_type[start_index]) 722 { 723 while_exit = TRUE; 724 } 725 else 726 { 727 start_index = (uint8_t)(start_index + 1); 728 } 729 } 730 731 if (FALSE == while_exit) 732 { 733 /* This " ps_timer_info->index_to_send " member is 734 useful, when 2 time out values are 0, then 735 only first timed out value has to be resent and 736 other has to wait until the the first timed out 737 I frame is resent 738 This statement is executed only if, none of the timer 739 has expires previously, this is the first timer in the 740 list that has time out value has 0 741 */ 742 ps_timer_info->index_to_send = zero_to_index; 743 } 744 else 745 { 746 /* This statement is executed only if, any one of the time 747 out value was 0 previously, so first resend has to be done 748 for the previous I frame, so the index is set to the previous 749 I frame 750 */ 751 ps_timer_info->index_to_send = start_index; 752 } 753 754 /* Now resend the frame stored */ 755 result = phLlcNfc_H_SendTimedOutIFrame (gpphLlcNfc_Ctxt, 756 &(ps_frame_info->s_send_store), 757 0); 758 } 759 } 760 else 761 { 762 if ((LLC_GUARD_TIMER_RETRIES == 763 ps_timer_info->iframe_send_count[zero_to_index]) && 764 (NULL != gpphLlcNfc_Ctxt->cb_for_if.notify)) 765 { 766 phLlcNfc_StopAllTimers (); 767 #if defined (GUARD_TO_ERROR) 768 769 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC, 770 NFCSTATUS_BOARD_COMMUNICATION_ERROR); 771 #if 0 772 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1); 773 #endif /* #if 0 */ 774 /* Resend done, no answer from the device */ 775 gpphLlcNfc_Ctxt->cb_for_if.notify ( 776 gpphLlcNfc_Ctxt->cb_for_if.pif_ctxt, 777 gpphLlcNfc_Ctxt->phwinfo, 778 NFC_NOTIFY_DEVICE_ERROR, 779 ¬ifyinfo); 780 781 #endif /* #if defined (GUARD_TO_ERROR) */ 782 783 #if (!defined (GUARD_TO_ERROR) && defined (GUARD_TO_URSET)) 784 785 PH_LLCNFC_PRINT("U-RSET IS SENT \n"); 786 787 result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt, 788 &(s_packet_info), 789 &(s_packet_info.llcbuf_len), 790 phLlcNfc_e_rset); 791 792 result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt, 793 (uint8_t*)&(s_packet_info.s_llcbuf), 794 (uint32_t)s_packet_info.llcbuf_len); 795 796 ps_frame_info->write_status = result; 797 if (NFCSTATUS_PENDING == result) 798 { 799 /* Start the timer */ 800 result = phLlcNfc_StartTimers (PH_LLCNFC_CONNECTIONTIMER, 0); 801 if (NFCSTATUS_SUCCESS == result) 802 { 803 ps_frame_info->retry_cnt = 0; 804 gpphLlcNfc_Ctxt->s_frameinfo.sent_frame_type = 805 u_rset_frame; 806 result = NFCSTATUS_PENDING; 807 } 808 } 809 else 810 { 811 if (NFCSTATUS_BUSY == PHNFCSTATUS (result)) 812 { 813 ps_frame_info->write_wait_call = u_rset_frame; 814 } 815 } 816 817 #endif /* #if defined (GUARD_TO_ERROR) */ 818 } 819 } 820 } 821 } 822 PH_LLCNFC_PRINT("\n\nLLC : GUARD TIMEOUT CB END\n\n"); 823 } 824 825 #ifdef PIGGY_BACK 826 827 static 828 void 829 phLlcNfc_AckTimeoutCb ( 830 uint32_t TimerId 831 ) 832 { 833 NFCSTATUS result = NFCSTATUS_SUCCESS; 834 phLlcNfc_Frame_t *ps_frame_info = NULL; 835 phLlcNfc_Timerinfo_t *ps_timer_info = NULL; 836 phLlcNfc_LlcPacket_t s_packet_info; 837 838 PH_LLCNFC_PRINT("\n\nLLC : ACK TIMEOUT CB CALLED\n\n"); 839 840 if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == 841 gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_ACKTIMER]) 842 && (PH_LLCNFC_ACK_TO_BIT_VAL == 843 (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag & 844 PH_LLCNFC_ACK_TO_BIT_VAL))) 845 { 846 ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo); 847 ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); 848 849 phLlcNfc_StopTimers (PH_LLCNFC_ACKTIMER, 0); 850 851 if (NFCSTATUS_BUSY == PHNFCSTATUS (ps_frame_info->write_status)) 852 { 853 /* Any how write cannot be done and some frame is ready to be sent 854 so this frame will act as the ACK */ 855 result = phLlcNfc_H_WriteWaitCall (gpphLlcNfc_Ctxt); 856 } 857 else 858 { 859 /* Create S frame */ 860 (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, &(s_packet_info), phLlcNfc_e_rr); 861 862 result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt, 863 (uint8_t *)&(s_packet_info.s_llcbuf), 864 (uint32_t)(s_packet_info.llcbuf_len)); 865 866 if (NFCSTATUS_PENDING == result) 867 { 868 if (0 == ps_frame_info->send_error_count) 869 { 870 ps_frame_info->write_wait_call = invalid_frame; 871 } 872 ps_frame_info->sent_frame_type = s_frame; 873 } 874 else 875 { 876 if (invalid_frame == ps_frame_info->write_wait_call) 877 { 878 ps_frame_info->write_wait_call = s_frame; 879 } 880 } 881 } 882 } 883 884 /* ACK is sent, so reset the response received count */ 885 gpphLlcNfc_Ctxt->s_frameinfo.resp_recvd_count = 0; 886 887 PH_LLCNFC_PRINT("\n\nLLC : ACK TIMEOUT CB END\n\n"); 888 } 889 890 #endif /* #ifdef PIGGY_BACK */ 891 892 static 893 void 894 phLlcNfc_ConnectionTimeoutCb ( 895 uint32_t TimerId, 896 void *pContext 897 ) 898 { 899 NFCSTATUS result = NFCSTATUS_SUCCESS; 900 phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; 901 pphNfcIF_Notification_CB_t notifyul = NULL; 902 void *p_upperctxt = NULL; 903 phLlcNfc_Frame_t *ps_frame_info = NULL; 904 phLlcNfc_Timerinfo_t *ps_timer_info = NULL; 905 phLlcNfc_LlcPacket_t s_packet_info; 906 907 PH_LLCNFC_PRINT("\n\nLLC : CONNECTION TIMEOUT CB CALLED\n\n"); 908 if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == 909 gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_CONNECTIONTIMER]) 910 && (PH_LLCNFC_CON_TO_BIT_VAL == 911 (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag & 912 PH_LLCNFC_CON_TO_BIT_VAL))) 913 { 914 ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo); 915 ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); 916 if (ps_timer_info->con_to_value > 0) 917 { 918 #if !defined (CYCLIC_TIMER) 919 phOsalNfc_Timer_Stop( 920 ps_timer_info->timer_id[PH_LLCNFC_CONNECTIONTIMER]); 921 /* phLlcNfc_StopTimers(PH_LLCNFC_CONNECTIONTIMER, 0); */ 922 #endif 923 ps_timer_info->con_to_value = 0; 924 925 if (0 == ps_timer_info->con_to_value) 926 { 927 PH_LLCNFC_DEBUG("TIMER EXPIRED RETRY COUNT : %02X\n", ps_frame_info->retry_cnt); 928 phLlcNfc_StopTimers (PH_LLCNFC_CONNECTIONTIMER, 0); 929 930 if (ps_frame_info->retry_cnt < PH_LLCNFC_MAX_RETRY_COUNT) 931 { 932 /* Create a U frame */ 933 result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt, 934 &(s_packet_info), 935 &(s_packet_info.llcbuf_len), 936 phLlcNfc_e_rset); 937 938 if (NFCSTATUS_SUCCESS == result) 939 { 940 /* Call DAL write */ 941 result = phLlcNfc_Interface_Write (gpphLlcNfc_Ctxt, 942 (uint8_t*)&(s_packet_info.s_llcbuf), 943 (uint32_t)(s_packet_info.llcbuf_len)); 944 } 945 if (NFCSTATUS_PENDING == result) 946 { 947 /* Start the timer */ 948 result = phLlcNfc_StartTimers(PH_LLCNFC_CONNECTIONTIMER, 0); 949 if (NFCSTATUS_SUCCESS == result) 950 { 951 ps_frame_info->retry_cnt++; 952 result = NFCSTATUS_PENDING; 953 } 954 } 955 else 956 { 957 if (NFCSTATUS_BUSY == PHNFCSTATUS(result)) 958 { 959 result = NFCSTATUS_PENDING; 960 } 961 } 962 } 963 else 964 { 965 PH_LLCNFC_PRINT("RETRY COUNT LIMIT REACHED \n"); 966 if ((ps_frame_info->retry_cnt == PH_LLCNFC_MAX_RETRY_COUNT) 967 && (NULL != gpphLlcNfc_Ctxt->cb_for_if.notify)) 968 { 969 void *p_hw_info = NULL; 970 uint8_t type = 0; 971 972 p_hw_info = gpphLlcNfc_Ctxt->phwinfo; 973 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC, 974 NFCSTATUS_BOARD_COMMUNICATION_ERROR); 975 976 notifyul = gpphLlcNfc_Ctxt->cb_for_if.notify; 977 p_upperctxt = gpphLlcNfc_Ctxt->cb_for_if.pif_ctxt; 978 type = NFC_NOTIFY_ERROR; 979 if (init_u_rset_frame == ps_frame_info->sent_frame_type) 980 { 981 type = NFC_NOTIFY_INIT_FAILED; 982 /* Release if, the initialisation is not complete */ 983 result = phLlcNfc_Release(gpphLlcNfc_Ctxt, p_hw_info); 984 gpphLlcNfc_Ctxt = NULL; 985 } 986 else 987 { 988 type = NFC_NOTIFY_DEVICE_ERROR; 989 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC, 990 NFCSTATUS_BOARD_COMMUNICATION_ERROR); 991 #if 0 992 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1); 993 #endif /* #if 0 */ 994 } 995 /* Notify the upper layer */ 996 notifyul(p_upperctxt, p_hw_info, type, ¬ifyinfo); 997 } 998 } 999 } 1000 #if !defined (CYCLIC_TIMER) 1001 else 1002 { 1003 /* Start the timer again */ 1004 phOsalNfc_Timer_Start( 1005 ps_timer_info->timer_id[PH_LLCNFC_CONNECTIONTIMER], 1006 ps_timer_info->con_to_value, phLlcNfc_ConnectionTimeoutCb, NULL); 1007 } 1008 #endif 1009 } 1010 } 1011 PH_LLCNFC_PRINT("\n\nLLC : CONNECTION TIMEOUT CB END\n\n"); 1012 } 1013 #endif /* #ifdef LLC_TIMER_ENABLE */ 1014 1015 #ifdef LLC_URSET_NO_DELAY 1016 1017 /* NO definition required */ 1018 1019 #else /* #ifdef LLC_URSET_NO_DELAY */ 1020 1021 void 1022 phLlcNfc_URSET_Delay_Notify ( 1023 uint32_t delay_id, 1024 void *pContext) 1025 { 1026 phLlcNfc_Frame_t *ps_frame_info = NULL; 1027 phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; 1028 1029 if (NULL != gpphLlcNfc_Ctxt) 1030 { 1031 ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo); 1032 1033 phOsalNfc_Timer_Stop (delay_id); 1034 phOsalNfc_Timer_Delete (delay_id); 1035 if (ps_frame_info->s_send_store.winsize_cnt > 0) 1036 { 1037 #if 0 1038 1039 /* Resend I frame */ 1040 (void)phLlcNfc_H_SendTimedOutIFrame (gpphLlcNfc_Ctxt, 1041 &(ps_frame_info->s_send_store), 0); 1042 1043 #else 1044 1045 (void)phLlcNfc_H_SendUserIFrame (gpphLlcNfc_Ctxt, 1046 &(ps_frame_info->s_send_store)); 1047 1048 #endif /* #if 0 */ 1049 gpphLlcNfc_Ctxt->state = phLlcNfc_Resend_State; 1050 } 1051 else 1052 { 1053 if ((init_u_rset_frame == ps_frame_info->sent_frame_type) && 1054 (NULL != gpphLlcNfc_Ctxt->cb_for_if.notify)) 1055 { 1056 ps_frame_info->sent_frame_type = write_resp_received; 1057 notifyinfo.status = NFCSTATUS_SUCCESS; 1058 /* Send the notification to the upper layer */ 1059 gpphLlcNfc_Ctxt->cb_for_if.notify ( 1060 gpphLlcNfc_Ctxt->cb_for_if.pif_ctxt, 1061 gpphLlcNfc_Ctxt->phwinfo, 1062 NFC_NOTIFY_INIT_COMPLETED, 1063 ¬ifyinfo); 1064 } 1065 } 1066 } 1067 } 1068 1069 #endif /* #ifdef LLC_URSET_NO_DELAY */ 1070 1071