• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *******************************************************************************/
gki_timers_init(void)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] = nullptr;
83   }
84 
85   gki_cb.com.p_tick_cb = nullptr;
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 *******************************************************************************/
gki_timers_is_timer_running(void)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 *******************************************************************************/
GKI_get_tick_count(void)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 *******************************************************************************/
GKI_ready_to_sleep(void)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 *******************************************************************************/
GKI_start_timer(uint8_t tnum,int32_t ticks,bool is_continuous)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 *******************************************************************************/
GKI_stop_timer(uint8_t tnum)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 *******************************************************************************/
GKI_timer_update(int32_t ticks_since_last_update)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 *******************************************************************************/
GKI_timer_queue_empty(void)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 *******************************************************************************/
GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK * p_callback)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 *******************************************************************************/
GKI_init_timer_list(TIMER_LIST_Q * p_timer_listq)587 void GKI_init_timer_list(TIMER_LIST_Q* p_timer_listq) {
588   p_timer_listq->p_first = nullptr;
589   p_timer_listq->p_last = nullptr;
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 *******************************************************************************/
GKI_init_timer_list_entry(TIMER_LIST_ENT * p_tle)608 void GKI_init_timer_list_entry(TIMER_LIST_ENT* p_tle) {
609   p_tle->p_next = nullptr;
610   p_tle->p_prev = nullptr;
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 *******************************************************************************/
GKI_update_timer_list(TIMER_LIST_Q * p_timer_listq,int32_t num_units_since_last_update)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 != nullptr) && (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 *******************************************************************************/
GKI_get_remaining_ticks(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_target_tle)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 *******************************************************************************/
GKI_add_to_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)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 == nullptr || p_timer_listq == nullptr) {
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 == nullptr)
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 != nullptr)
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 = nullptr;
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] == nullptr) 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 *******************************************************************************/
GKI_remove_from_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)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 == nullptr || p_tle->in_use == false ||
844       p_timer_listq->p_first == nullptr) {
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 != nullptr) {
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 != nullptr) p_timer_listq->p_first->p_prev = nullptr;
863 
864     if (p_timer_listq->p_last == p_tle) p_timer_listq->p_last = nullptr;
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 != nullptr) p_timer_listq->p_last->p_next = nullptr;
870     } else {
871       if (p_tle->p_next != nullptr && 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 != nullptr && 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 = nullptr;
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 == nullptr && p_timer_listq->p_last == nullptr) {
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] = nullptr;
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 *******************************************************************************/
gki_adjust_timer_count(int32_t ticks)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