1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 #include <android-base/stringprintf.h> 19 #include <base/logging.h> 20 #include "gki_int.h" 21 22 /* Make sure that this has been defined in target.h */ 23 #ifndef GKI_NUM_TIMERS 24 #error NO TIMERS: Must define at least 1 timer in the system! 25 #endif 26 27 /* Largest signed positive timer count */ 28 #define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL) 29 /* Marks an unused timer list entry (initial value) */ 30 #define GKI_UNUSED_LIST_ENTRY (0x80000000L) 31 #define GKI_MAX_INT32 (0x7fffffffL) 32 33 using android::base::StringPrintf; 34 35 extern bool nfc_debug_enabled; 36 37 /******************************************************************************* 38 ** 39 ** Function gki_timers_init 40 ** 41 ** Description This internal function is called once at startup to 42 ** initialize all the timer structures. 43 ** 44 ** Returns void 45 ** 46 *******************************************************************************/ 47 void gki_timers_init(void) { 48 uint8_t tt; 49 50 gki_cb.com.OSTicksTilExp = 51 0; /* Remaining time (of OSTimeCurTimeout) before next timer expires */ 52 gki_cb.com.OSNumOrigTicks = 0; 53 #if (GKI_DELAY_STOP_SYS_TICK > 0) 54 gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */ 55 #endif 56 57 for (tt = 0; tt < GKI_MAX_TASKS; tt++) { 58 gki_cb.com.OSWaitTmr[tt] = 0; 59 60 #if (GKI_NUM_TIMERS > 0) 61 gki_cb.com.OSTaskTmr0[tt] = 0; 62 gki_cb.com.OSTaskTmr0R[tt] = 0; 63 #endif 64 65 #if (GKI_NUM_TIMERS > 1) 66 gki_cb.com.OSTaskTmr1[tt] = 0; 67 gki_cb.com.OSTaskTmr1R[tt] = 0; 68 #endif 69 70 #if (GKI_NUM_TIMERS > 2) 71 gki_cb.com.OSTaskTmr2[tt] = 0; 72 gki_cb.com.OSTaskTmr2R[tt] = 0; 73 #endif 74 75 #if (GKI_NUM_TIMERS > 3) 76 gki_cb.com.OSTaskTmr3[tt] = 0; 77 gki_cb.com.OSTaskTmr3R[tt] = 0; 78 #endif 79 } 80 81 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) { 82 gki_cb.com.timer_queues[tt] = NULL; 83 } 84 85 gki_cb.com.p_tick_cb = NULL; 86 gki_cb.com.system_tick_running = false; 87 88 return; 89 } 90 91 /******************************************************************************* 92 ** 93 ** Function gki_timers_is_timer_running 94 ** 95 ** Description This internal function is called to test if any gki timer 96 ** are running 97 ** 98 ** 99 ** Returns TRUE if at least one time is running in the system, FALSE 100 ** else. 101 ** 102 *******************************************************************************/ 103 bool gki_timers_is_timer_running(void) { 104 uint8_t tt; 105 for (tt = 0; tt < GKI_MAX_TASKS; tt++) { 106 #if (GKI_NUM_TIMERS > 0) 107 if (gki_cb.com.OSTaskTmr0[tt]) { 108 return true; 109 } 110 #endif 111 112 #if (GKI_NUM_TIMERS > 1) 113 if (gki_cb.com.OSTaskTmr1[tt]) { 114 return true; 115 } 116 #endif 117 118 #if (GKI_NUM_TIMERS > 2) 119 if (gki_cb.com.OSTaskTmr2[tt]) { 120 return true; 121 } 122 #endif 123 124 #if (GKI_NUM_TIMERS > 3) 125 if (gki_cb.com.OSTaskTmr3[tt]) { 126 return true; 127 } 128 #endif 129 } 130 131 return false; 132 } 133 134 /******************************************************************************* 135 ** 136 ** Function GKI_get_tick_count 137 ** 138 ** Description This function returns the current system ticks 139 ** 140 ** Returns The current number of system ticks 141 ** 142 *******************************************************************************/ 143 uint32_t GKI_get_tick_count(void) { return gki_cb.com.OSTicks; } 144 145 /******************************************************************************* 146 ** 147 ** Function GKI_ready_to_sleep 148 ** 149 ** Description This function returns the number of system ticks until the 150 ** next timer will expire. It is typically called by a power 151 ** savings manager to find out how long it can have the system 152 ** sleep before it needs to service the next entry. 153 ** 154 ** Parameters: None 155 ** 156 ** Returns Number of ticks til the next timer expires 157 ** Note: The value is a signed value. This value should be 158 ** compared to x > 0, to avoid misinterpreting negative 159 ** tick values. 160 ** 161 *******************************************************************************/ 162 int32_t GKI_ready_to_sleep(void) { return (gki_cb.com.OSTicksTilExp); } 163 164 /******************************************************************************* 165 ** 166 ** Function GKI_start_timer 167 ** 168 ** Description An application can call this function to start one of 169 ** it's four general purpose timers. Any of the four timers 170 ** can be 1-shot or continuous. If a timer is already running, 171 ** it will be reset to the new parameters. 172 ** 173 ** Parameters tnum - (input) timer number to be started 174 ** (TIMER_0, TIMER_1, TIMER_2, or 175 ** TIMER_3) 176 ** ticks - (input) the number of system ticks til the 177 ** timer expires. 178 ** is_continuous - (input) TRUE if timer restarts 179 ** automatically, else FALSE if it is 180 ** a 'one-shot'. 181 ** 182 ** Returns void 183 ** 184 *******************************************************************************/ 185 void GKI_start_timer(uint8_t tnum, int32_t ticks, bool is_continuous) { 186 int32_t reload; 187 int32_t orig_ticks; 188 uint8_t task_id = GKI_get_taskid(); 189 bool bad_timer = false; 190 191 if (ticks <= 0) ticks = 1; 192 193 orig_ticks = ticks; /* save the ticks in case adjustment is necessary */ 194 195 /* If continuous timer, set reload, else set it to 0 */ 196 if (is_continuous) 197 reload = ticks; 198 else 199 reload = 0; 200 201 GKI_disable(); 202 203 if (gki_timers_is_timer_running() == false) { 204 #if (GKI_DELAY_STOP_SYS_TICK > 0) 205 /* if inactivity delay timer is not running, start system tick */ 206 if (gki_cb.com.OSTicksTilStop == 0) { 207 #endif 208 if (gki_cb.com.p_tick_cb) { 209 /* start system tick */ 210 gki_cb.com.system_tick_running = true; 211 (gki_cb.com.p_tick_cb)(true); 212 } 213 #if (GKI_DELAY_STOP_SYS_TICK > 0) 214 } else { 215 /* clear inactivity delay timer */ 216 gki_cb.com.OSTicksTilStop = 0; 217 } 218 #endif 219 } 220 /* Add the time since the last task timer update. 221 ** Note that this works when no timers are active since 222 ** both OSNumOrigTicks and OSTicksTilExp are 0. 223 */ 224 if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) > 225 ticks) { 226 ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp; 227 } else 228 ticks = GKI_MAX_INT32; 229 230 switch (tnum) { 231 #if (GKI_NUM_TIMERS > 0) 232 case TIMER_0: 233 gki_cb.com.OSTaskTmr0R[task_id] = reload; 234 gki_cb.com.OSTaskTmr0[task_id] = ticks; 235 break; 236 #endif 237 238 #if (GKI_NUM_TIMERS > 1) 239 case TIMER_1: 240 gki_cb.com.OSTaskTmr1R[task_id] = reload; 241 gki_cb.com.OSTaskTmr1[task_id] = ticks; 242 break; 243 #endif 244 245 #if (GKI_NUM_TIMERS > 2) 246 case TIMER_2: 247 gki_cb.com.OSTaskTmr2R[task_id] = reload; 248 gki_cb.com.OSTaskTmr2[task_id] = ticks; 249 break; 250 #endif 251 252 #if (GKI_NUM_TIMERS > 3) 253 case TIMER_3: 254 gki_cb.com.OSTaskTmr3R[task_id] = reload; 255 gki_cb.com.OSTaskTmr3[task_id] = ticks; 256 break; 257 #endif 258 default: 259 bad_timer = true; /* Timer number is bad, so do not use */ 260 } 261 262 /* Update the expiration timeout if a legitimate timer */ 263 if (!bad_timer) { 264 /* Only update the timeout value if it is less than any other newly started 265 * timers */ 266 gki_adjust_timer_count(orig_ticks); 267 } 268 269 GKI_enable(); 270 } 271 272 /******************************************************************************* 273 ** 274 ** Function GKI_stop_timer 275 ** 276 ** Description An application can call this function to stop one of 277 ** it's four general purpose timers. There is no harm in 278 ** stopping a timer that is already stopped. 279 ** 280 ** Parameters tnum - (input) timer number to be started (TIMER_0, 281 ** TIMER_1, TIMER_2, or TIMER_3) 282 ** Returns void 283 ** 284 *******************************************************************************/ 285 void GKI_stop_timer(uint8_t tnum) { 286 uint8_t task_id = GKI_get_taskid(); 287 288 GKI_disable(); 289 290 switch (tnum) { 291 #if (GKI_NUM_TIMERS > 0) 292 case TIMER_0: 293 gki_cb.com.OSTaskTmr0R[task_id] = 0; 294 gki_cb.com.OSTaskTmr0[task_id] = 0; 295 break; 296 #endif 297 298 #if (GKI_NUM_TIMERS > 1) 299 case TIMER_1: 300 gki_cb.com.OSTaskTmr1R[task_id] = 0; 301 gki_cb.com.OSTaskTmr1[task_id] = 0; 302 break; 303 #endif 304 305 #if (GKI_NUM_TIMERS > 2) 306 case TIMER_2: 307 gki_cb.com.OSTaskTmr2R[task_id] = 0; 308 gki_cb.com.OSTaskTmr2[task_id] = 0; 309 break; 310 #endif 311 312 #if (GKI_NUM_TIMERS > 3) 313 case TIMER_3: 314 gki_cb.com.OSTaskTmr3R[task_id] = 0; 315 gki_cb.com.OSTaskTmr3[task_id] = 0; 316 break; 317 #endif 318 } 319 320 if (gki_timers_is_timer_running() == false) { 321 if (gki_cb.com.p_tick_cb) { 322 #if (GKI_DELAY_STOP_SYS_TICK > 0) 323 /* if inactivity delay timer is not running */ 324 if ((gki_cb.com.system_tick_running) && 325 (gki_cb.com.OSTicksTilStop == 0)) { 326 /* set inactivity delay timer */ 327 /* when timer expires, system tick will be stopped */ 328 gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK; 329 } 330 #else 331 gki_cb.com.system_tick_running = false; 332 (gki_cb.com.p_tick_cb)(false); /* stop system tick */ 333 #endif 334 } 335 } 336 337 GKI_enable(); 338 } 339 340 /******************************************************************************* 341 ** 342 ** Function GKI_timer_update 343 ** 344 ** Description This function is called by an OS to drive the GKI's timers. 345 ** It is typically called at every system tick to 346 ** update the timers for all tasks, and check for timeouts. 347 ** 348 ** Note: It has been designed to also allow for variable tick 349 ** updates so that systems with strict power savings 350 ** requirements can have the update occur at variable 351 ** intervals. 352 ** 353 ** Parameters: ticks_since_last_update - (input) This is the number of 354 ** TICKS that have occurred since the last time 355 ** GKI_timer_update was called. 356 ** 357 ** Returns void 358 ** 359 *******************************************************************************/ 360 void GKI_timer_update(int32_t ticks_since_last_update) { 361 uint8_t task_id; 362 long next_expiration; /* Holds the next soonest expiration time after this 363 update */ 364 365 /* Increment the number of ticks used for time stamps */ 366 gki_cb.com.OSTicks += ticks_since_last_update; 367 368 /* If any timers are running in any tasks, decrement the remaining time til 369 * the timer updates need to take place (next expiration occurs) 370 */ 371 gki_cb.com.OSTicksTilExp -= ticks_since_last_update; 372 373 /* Don't allow timer interrupt nesting */ 374 if (gki_cb.com.timer_nesting) return; 375 376 gki_cb.com.timer_nesting = 1; 377 378 #if (GKI_DELAY_STOP_SYS_TICK > 0) 379 /* if inactivity delay timer is set and expired */ 380 if (gki_cb.com.OSTicksTilStop) { 381 if (gki_cb.com.OSTicksTilStop <= (uint32_t)ticks_since_last_update) { 382 if (gki_cb.com.p_tick_cb) { 383 gki_cb.com.system_tick_running = false; 384 (gki_cb.com.p_tick_cb)(false); /* stop system tick */ 385 } 386 gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */ 387 gki_cb.com.timer_nesting = 0; 388 return; 389 } else 390 gki_cb.com.OSTicksTilStop -= ticks_since_last_update; 391 } 392 #endif 393 394 /* No need to update the ticks if no timeout has occurred */ 395 if (gki_cb.com.OSTicksTilExp > 0) { 396 gki_cb.com.timer_nesting = 0; 397 return; 398 } 399 400 GKI_disable(); 401 402 next_expiration = GKI_NO_NEW_TMRS_STARTED; 403 404 /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase 405 gki_cb.com.OSNumOrigTicks 406 to account for the difference so timer updates below are decremented by the 407 full number 408 of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function 409 so changing this 410 value only affects the timer updates below 411 */ 412 gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp; 413 414 /* Check for OS Task Timers */ 415 for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) { 416 if (gki_cb.com.OSRdyTbl[task_id] == TASK_DEAD) { 417 // task is shutdown do not try to service timers 418 continue; 419 } 420 421 if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */ 422 { 423 gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks; 424 if (gki_cb.com.OSWaitTmr[task_id] <= 0) { 425 /* Timer Expired */ 426 gki_cb.com.OSRdyTbl[task_id] = TASK_READY; 427 } 428 } 429 430 #if (GKI_NUM_TIMERS > 0) 431 /* If any timer is running, decrement */ 432 if (gki_cb.com.OSTaskTmr0[task_id] > 0) { 433 gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks; 434 435 if (gki_cb.com.OSTaskTmr0[task_id] <= 0) { 436 /* Set Timer 0 Expired event mask and reload timer */ 437 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE) 438 GKI_isend_event(task_id, TIMER_0_EVT_MASK); 439 #else 440 GKI_send_event(task_id, TIMER_0_EVT_MASK); 441 #endif 442 gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id]; 443 } 444 } 445 446 /* Check to see if this timer is the next one to expire */ 447 if (gki_cb.com.OSTaskTmr0[task_id] > 0 && 448 gki_cb.com.OSTaskTmr0[task_id] < next_expiration) 449 next_expiration = gki_cb.com.OSTaskTmr0[task_id]; 450 #endif 451 452 #if (GKI_NUM_TIMERS > 1) 453 /* If any timer is running, decrement */ 454 if (gki_cb.com.OSTaskTmr1[task_id] > 0) { 455 gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks; 456 457 if (gki_cb.com.OSTaskTmr1[task_id] <= 0) { 458 /* Set Timer 1 Expired event mask and reload timer */ 459 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE) 460 GKI_isend_event(task_id, TIMER_1_EVT_MASK); 461 #else 462 GKI_send_event(task_id, TIMER_1_EVT_MASK); 463 #endif 464 gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id]; 465 } 466 } 467 468 /* Check to see if this timer is the next one to expire */ 469 if (gki_cb.com.OSTaskTmr1[task_id] > 0 && 470 gki_cb.com.OSTaskTmr1[task_id] < next_expiration) 471 next_expiration = gki_cb.com.OSTaskTmr1[task_id]; 472 #endif 473 474 #if (GKI_NUM_TIMERS > 2) 475 /* If any timer is running, decrement */ 476 if (gki_cb.com.OSTaskTmr2[task_id] > 0) { 477 gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks; 478 479 if (gki_cb.com.OSTaskTmr2[task_id] <= 0) { 480 /* Set Timer 2 Expired event mask and reload timer */ 481 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE) 482 GKI_isend_event(task_id, TIMER_2_EVT_MASK); 483 #else 484 GKI_send_event(task_id, TIMER_2_EVT_MASK); 485 #endif 486 gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id]; 487 } 488 } 489 490 /* Check to see if this timer is the next one to expire */ 491 if (gki_cb.com.OSTaskTmr2[task_id] > 0 && 492 gki_cb.com.OSTaskTmr2[task_id] < next_expiration) 493 next_expiration = gki_cb.com.OSTaskTmr2[task_id]; 494 #endif 495 496 #if (GKI_NUM_TIMERS > 3) 497 /* If any timer is running, decrement */ 498 if (gki_cb.com.OSTaskTmr3[task_id] > 0) { 499 gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks; 500 501 if (gki_cb.com.OSTaskTmr3[task_id] <= 0) { 502 /* Set Timer 3 Expired event mask and reload timer */ 503 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE) 504 GKI_isend_event(task_id, TIMER_3_EVT_MASK); 505 #else 506 GKI_send_event(task_id, TIMER_3_EVT_MASK); 507 #endif 508 gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id]; 509 } 510 } 511 512 /* Check to see if this timer is the next one to expire */ 513 if (gki_cb.com.OSTaskTmr3[task_id] > 0 && 514 gki_cb.com.OSTaskTmr3[task_id] < next_expiration) 515 next_expiration = gki_cb.com.OSTaskTmr3[task_id]; 516 #endif 517 } 518 519 /* Set the next timer experation value if there is one to start */ 520 if (next_expiration < GKI_NO_NEW_TMRS_STARTED) { 521 gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration; 522 } else { 523 gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0; 524 } 525 526 gki_cb.com.timer_nesting = 0; 527 528 GKI_enable(); 529 530 return; 531 } 532 533 /******************************************************************************* 534 ** 535 ** Function GKI_timer_queue_empty 536 ** 537 ** Description This function is called by applications to see whether the 538 ** timer queue is empty 539 ** 540 ** Parameters 541 ** 542 ** Returns bool 543 ** 544 *******************************************************************************/ 545 bool GKI_timer_queue_empty(void) { 546 uint8_t tt; 547 548 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) { 549 if (gki_cb.com.timer_queues[tt]) return false; 550 } 551 552 return true; 553 } 554 555 /******************************************************************************* 556 ** 557 ** Function GKI_timer_queue_register_callback 558 ** 559 ** Description This function is called by applications to register system 560 ** tick start/stop callback for time queues 561 ** 562 ** 563 ** Parameters p_callback - (input) pointer to the system tick callback 564 ** 565 ** Returns bool 566 ** 567 *******************************************************************************/ 568 void GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK* p_callback) { 569 gki_cb.com.p_tick_cb = p_callback; 570 571 return; 572 } 573 574 /******************************************************************************* 575 ** 576 ** Function GKI_init_timer_list 577 ** 578 ** Description This function is called by applications when they 579 ** want to initialize a timer list. 580 ** 581 ** Parameters p_timer_listq - (input) pointer to the timer list queue 582 ** object 583 ** 584 ** Returns void 585 ** 586 *******************************************************************************/ 587 void GKI_init_timer_list(TIMER_LIST_Q* p_timer_listq) { 588 p_timer_listq->p_first = NULL; 589 p_timer_listq->p_last = NULL; 590 p_timer_listq->last_ticks = 0; 591 592 return; 593 } 594 595 /******************************************************************************* 596 ** 597 ** Function GKI_init_timer_list_entry 598 ** 599 ** Description This function is called by the applications when they 600 ** want to initialize a timer list entry. This must be 601 ** done prior to first use of the entry. 602 ** 603 ** Parameters p_tle - (input) pointer to a timer list queue entry 604 ** 605 ** Returns void 606 ** 607 *******************************************************************************/ 608 void GKI_init_timer_list_entry(TIMER_LIST_ENT* p_tle) { 609 p_tle->p_next = NULL; 610 p_tle->p_prev = NULL; 611 p_tle->ticks = GKI_UNUSED_LIST_ENTRY; 612 p_tle->in_use = false; 613 } 614 615 /******************************************************************************* 616 ** 617 ** Function GKI_update_timer_list 618 ** 619 ** Description This function is called by the applications when they 620 ** want to update a timer list. This should be at every 621 ** timer list unit tick, e.g. once per sec, once per minute 622 ** etc. 623 ** 624 ** Parameters p_timer_listq - (input) pointer to the timer list queue 625 ** object 626 ** num_units_since_last_update - (input) number of units since 627 ** the last update (allows for variable unit update) 628 ** 629 ** NOTE: The following timer list update routines should not be used for exact 630 ** time critical purposes. The timer tasks should be used when exact 631 ** timing is needed. 632 ** 633 ** Returns the number of timers that have expired 634 ** 635 *******************************************************************************/ 636 uint16_t GKI_update_timer_list(TIMER_LIST_Q* p_timer_listq, 637 int32_t num_units_since_last_update) { 638 TIMER_LIST_ENT* p_tle; 639 uint16_t num_time_out = 0; 640 int32_t rem_ticks; 641 int32_t temp_ticks; 642 643 p_tle = p_timer_listq->p_first; 644 645 /* First, get the guys who have previously timed out */ 646 /* Note that the tick value of the timers should always be '0' */ 647 while ((p_tle) && (p_tle->ticks <= 0)) { 648 num_time_out++; 649 p_tle = p_tle->p_next; 650 } 651 652 /* Timer entriy tick values are relative to the preceeding entry */ 653 rem_ticks = num_units_since_last_update; 654 655 /* Now, adjust remaining timer entries */ 656 while ((p_tle != NULL) && (rem_ticks > 0)) { 657 temp_ticks = p_tle->ticks; 658 p_tle->ticks -= rem_ticks; 659 660 /* See if this timer has just timed out */ 661 if (p_tle->ticks <= 0) { 662 /* We set the number of ticks to '0' so that the legacy code 663 * that assumes a '0' or nonzero value will still work as coded. */ 664 p_tle->ticks = 0; 665 666 num_time_out++; 667 } 668 669 rem_ticks -= temp_ticks; /* Decrement the remaining ticks to process */ 670 p_tle = p_tle->p_next; 671 } 672 673 if (p_timer_listq->last_ticks > 0) { 674 p_timer_listq->last_ticks -= num_units_since_last_update; 675 676 /* If the last timer has expired set last_ticks to 0 so that other list 677 * update 678 * functions will calculate correctly 679 */ 680 if (p_timer_listq->last_ticks < 0) p_timer_listq->last_ticks = 0; 681 } 682 683 return (num_time_out); 684 } 685 686 /******************************************************************************* 687 ** 688 ** Function GKI_get_remaining_ticks 689 ** 690 ** Description This function is called by an application to get remaining 691 ** ticks to expire 692 ** 693 ** Parameters p_timer_listq - (input) pointer to the timer list queue 694 ** object 695 ** p_target_tle - (input) pointer to a timer list queue entry 696 ** 697 ** Returns 0 if timer is not used or timer is not in the list 698 ** remaining ticks if success 699 ** 700 *******************************************************************************/ 701 uint32_t GKI_get_remaining_ticks(TIMER_LIST_Q* p_timer_listq, 702 TIMER_LIST_ENT* p_target_tle) { 703 TIMER_LIST_ENT* p_tle; 704 uint32_t rem_ticks = 0; 705 706 if (p_target_tle->in_use) { 707 p_tle = p_timer_listq->p_first; 708 709 /* adding up all of ticks in previous entries */ 710 while ((p_tle) && (p_tle != p_target_tle)) { 711 rem_ticks += p_tle->ticks; 712 p_tle = p_tle->p_next; 713 } 714 715 /* if found target entry */ 716 if (p_tle == p_target_tle) { 717 rem_ticks += p_tle->ticks; 718 } else { 719 LOG(ERROR) << StringPrintf( 720 "GKI_get_remaining_ticks: No timer entry in the list"); 721 return (0); 722 } 723 } else { 724 LOG(ERROR) << StringPrintf( 725 "GKI_get_remaining_ticks: timer entry is not active"); 726 } 727 728 return (rem_ticks); 729 } 730 731 /******************************************************************************* 732 ** 733 ** Function GKI_add_to_timer_list 734 ** 735 ** Description This function is called by an application to add a timer 736 ** entry to a timer list. 737 ** 738 ** Note: A timer value of '0' will effectively insert an 739 ** already expired event. Negative tick values will be 740 ** ignored. 741 ** 742 ** Parameters p_timer_listq - (input) pointer to the timer list queue 743 ** object 744 ** p_tle - (input) pointer to a timer list queue entry 745 ** 746 ** Returns void 747 ** 748 *******************************************************************************/ 749 void GKI_add_to_timer_list(TIMER_LIST_Q* p_timer_listq, TIMER_LIST_ENT* p_tle) { 750 uint32_t nr_ticks_total; 751 uint8_t tt; 752 TIMER_LIST_ENT* p_temp; 753 if (p_tle == NULL || p_timer_listq == NULL) { 754 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 755 "%s: invalid argument %p, %p****************************<<", __func__, 756 p_timer_listq, p_tle); 757 return; 758 } 759 760 /* Only process valid tick values */ 761 if (p_tle->ticks >= 0) { 762 /* If this entry is the last in the list */ 763 if (p_tle->ticks >= p_timer_listq->last_ticks) { 764 /* If this entry is the only entry in the list */ 765 if (p_timer_listq->p_first == NULL) 766 p_timer_listq->p_first = p_tle; 767 else { 768 /* Insert the entry onto the end of the list */ 769 if (p_timer_listq->p_last != NULL) 770 p_timer_listq->p_last->p_next = p_tle; 771 772 p_tle->p_prev = p_timer_listq->p_last; 773 } 774 775 p_tle->p_next = NULL; 776 p_timer_listq->p_last = p_tle; 777 nr_ticks_total = p_tle->ticks; 778 p_tle->ticks -= p_timer_listq->last_ticks; 779 780 p_timer_listq->last_ticks = nr_ticks_total; 781 } else /* This entry needs to be inserted before the last entry */ 782 { 783 /* Find the entry that the new one needs to be inserted in front of */ 784 p_temp = p_timer_listq->p_first; 785 while (p_tle->ticks > p_temp->ticks) { 786 /* Update the tick value if looking at an unexpired entry */ 787 if (p_temp->ticks > 0) p_tle->ticks -= p_temp->ticks; 788 789 p_temp = p_temp->p_next; 790 } 791 792 /* The new entry is the first in the list */ 793 if (p_temp == p_timer_listq->p_first) { 794 p_tle->p_next = p_timer_listq->p_first; 795 p_timer_listq->p_first->p_prev = p_tle; 796 p_timer_listq->p_first = p_tle; 797 } else { 798 p_temp->p_prev->p_next = p_tle; 799 p_tle->p_prev = p_temp->p_prev; 800 p_temp->p_prev = p_tle; 801 p_tle->p_next = p_temp; 802 } 803 p_temp->ticks -= p_tle->ticks; 804 } 805 806 p_tle->in_use = true; 807 808 /* if we already add this timer queue to the array */ 809 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) { 810 if (gki_cb.com.timer_queues[tt] == p_timer_listq) return; 811 } 812 /* add this timer queue to the array */ 813 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) { 814 if (gki_cb.com.timer_queues[tt] == NULL) break; 815 } 816 if (tt < GKI_MAX_TIMER_QUEUES) { 817 gki_cb.com.timer_queues[tt] = p_timer_listq; 818 } 819 } 820 821 return; 822 } 823 824 /******************************************************************************* 825 ** 826 ** Function GKI_remove_from_timer_list 827 ** 828 ** Description This function is called by an application to remove a timer 829 ** entry from a timer list. 830 ** 831 ** Parameters p_timer_listq - (input) pointer to the timer list queue 832 ** object 833 ** p_tle - (input) pointer to a timer list queue entry 834 ** 835 ** Returns void 836 ** 837 *******************************************************************************/ 838 void GKI_remove_from_timer_list(TIMER_LIST_Q* p_timer_listq, 839 TIMER_LIST_ENT* p_tle) { 840 uint8_t tt; 841 842 /* Verify that the entry is valid */ 843 if (p_tle == NULL || p_tle->in_use == false || 844 p_timer_listq->p_first == NULL) { 845 return; 846 } 847 848 /* Add the ticks remaining in this timer (if any) to the next guy in the list. 849 ** Note: Expired timers have a tick value of '0'. 850 */ 851 if (p_tle->p_next != NULL) { 852 p_tle->p_next->ticks += p_tle->ticks; 853 } else { 854 p_timer_listq->last_ticks -= p_tle->ticks; 855 } 856 857 /* Unlink timer from the list. 858 */ 859 if (p_timer_listq->p_first == p_tle) { 860 p_timer_listq->p_first = p_tle->p_next; 861 862 if (p_timer_listq->p_first != NULL) p_timer_listq->p_first->p_prev = NULL; 863 864 if (p_timer_listq->p_last == p_tle) p_timer_listq->p_last = NULL; 865 } else { 866 if (p_timer_listq->p_last == p_tle) { 867 p_timer_listq->p_last = p_tle->p_prev; 868 869 if (p_timer_listq->p_last != NULL) p_timer_listq->p_last->p_next = NULL; 870 } else { 871 if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle) 872 p_tle->p_next->p_prev = p_tle->p_prev; 873 else { 874 /* Error case - chain messed up ?? */ 875 return; 876 } 877 878 if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle) 879 p_tle->p_prev->p_next = p_tle->p_next; 880 else { 881 /* Error case - chain messed up ?? */ 882 return; 883 } 884 } 885 } 886 887 p_tle->p_next = p_tle->p_prev = NULL; 888 p_tle->ticks = GKI_UNUSED_LIST_ENTRY; 889 p_tle->in_use = false; 890 891 /* if timer queue is empty */ 892 if (p_timer_listq->p_first == NULL && p_timer_listq->p_last == NULL) { 893 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) { 894 if (gki_cb.com.timer_queues[tt] == p_timer_listq) { 895 gki_cb.com.timer_queues[tt] = NULL; 896 break; 897 } 898 } 899 } 900 901 return; 902 } 903 904 /******************************************************************************* 905 ** 906 ** Function gki_adjust_timer_count 907 ** 908 ** Description This function is called whenever a new timer or GKI_wait 909 ** occurs to adjust (if necessary) the current time til the 910 ** first expiration. This only needs to make an adjustment if 911 ** the new timer (in ticks) is less than the number of ticks 912 ** remaining on the current timer. 913 ** 914 ** Parameters: ticks - (input) number of system ticks of the new timer 915 ** entry 916 ** 917 ** NOTE: This routine MUST be called while interrupts are 918 ** disabled to avoid updates while adjusting the timer 919 ** variables. 920 ** 921 ** Returns void 922 ** 923 *******************************************************************************/ 924 void gki_adjust_timer_count(int32_t ticks) { 925 if (ticks > 0) { 926 /* See if the new timer expires before the current first expiration */ 927 if (gki_cb.com.OSNumOrigTicks == 0 || 928 (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0)) { 929 gki_cb.com.OSNumOrigTicks = 930 (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks; 931 gki_cb.com.OSTicksTilExp = ticks; 932 } 933 } 934 935 return; 936 } 937