Home | History | Annotate | Download | only in common
      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