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 33using android::base::StringPrintf; 34 35extern 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*******************************************************************************/ 47void 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*******************************************************************************/ 103bool 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*******************************************************************************/ 143uint32_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*******************************************************************************/ 162int32_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*******************************************************************************/ 185void 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*******************************************************************************/ 285void 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*******************************************************************************/ 360void 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*******************************************************************************/ 545bool 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*******************************************************************************/ 568void 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*******************************************************************************/ 587void 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*******************************************************************************/ 608void 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*******************************************************************************/ 636uint16_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*******************************************************************************/ 701uint32_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*******************************************************************************/ 749void 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*******************************************************************************/ 838void 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*******************************************************************************/ 924void 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