• 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 (task_id >= GKI_MAX_TASKS) {
192     LOG(ERROR) << StringPrintf("%s: invalid task_id:0x%02x. start timer failed",
193                                __func__, task_id);
194     return;
195   }
196 
197   if (ticks <= 0) ticks = 1;
198 
199   orig_ticks = ticks; /* save the ticks in case adjustment is necessary */
200 
201   /* If continuous timer, set reload, else set it to 0 */
202   if (is_continuous)
203     reload = ticks;
204   else
205     reload = 0;
206 
207   GKI_disable();
208 
209   if (gki_timers_is_timer_running() == false) {
210 #if (GKI_DELAY_STOP_SYS_TICK > 0)
211     /* if inactivity delay timer is not running, start system tick */
212     if (gki_cb.com.OSTicksTilStop == 0) {
213 #endif
214       if (gki_cb.com.p_tick_cb) {
215         /* start system tick */
216         gki_cb.com.system_tick_running = true;
217         (gki_cb.com.p_tick_cb)(true);
218       }
219 #if (GKI_DELAY_STOP_SYS_TICK > 0)
220     } else {
221       /* clear inactivity delay timer */
222       gki_cb.com.OSTicksTilStop = 0;
223     }
224 #endif
225   }
226   /* Add the time since the last task timer update.
227   ** Note that this works when no timers are active since
228   ** both OSNumOrigTicks and OSTicksTilExp are 0.
229   */
230   if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) >
231       ticks) {
232     ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
233   } else
234     ticks = GKI_MAX_INT32;
235 
236   switch (tnum) {
237 #if (GKI_NUM_TIMERS > 0)
238     case TIMER_0:
239       gki_cb.com.OSTaskTmr0R[task_id] = reload;
240       gki_cb.com.OSTaskTmr0[task_id] = ticks;
241       break;
242 #endif
243 
244 #if (GKI_NUM_TIMERS > 1)
245     case TIMER_1:
246       gki_cb.com.OSTaskTmr1R[task_id] = reload;
247       gki_cb.com.OSTaskTmr1[task_id] = ticks;
248       break;
249 #endif
250 
251 #if (GKI_NUM_TIMERS > 2)
252     case TIMER_2:
253       gki_cb.com.OSTaskTmr2R[task_id] = reload;
254       gki_cb.com.OSTaskTmr2[task_id] = ticks;
255       break;
256 #endif
257 
258 #if (GKI_NUM_TIMERS > 3)
259     case TIMER_3:
260       gki_cb.com.OSTaskTmr3R[task_id] = reload;
261       gki_cb.com.OSTaskTmr3[task_id] = ticks;
262       break;
263 #endif
264     default:
265       bad_timer = true; /* Timer number is bad, so do not use */
266   }
267 
268   /* Update the expiration timeout if a legitimate timer */
269   if (!bad_timer) {
270     /* Only update the timeout value if it is less than any other newly started
271      * timers */
272     gki_adjust_timer_count(orig_ticks);
273   }
274 
275   GKI_enable();
276 }
277 
278 /*******************************************************************************
279 **
280 ** Function         GKI_stop_timer
281 **
282 ** Description      An application can call this function to stop one of
283 **                  it's four general purpose timers. There is no harm in
284 **                  stopping a timer that is already stopped.
285 **
286 ** Parameters       tnum - (input) timer number to be started (TIMER_0,
287 **                                 TIMER_1, TIMER_2, or TIMER_3)
288 ** Returns          void
289 **
290 *******************************************************************************/
GKI_stop_timer(uint8_t tnum)291 void GKI_stop_timer(uint8_t tnum) {
292   uint8_t task_id = GKI_get_taskid();
293 
294   GKI_disable();
295   if (task_id < GKI_MAX_TASKS) {
296     switch (tnum) {
297 #if (GKI_NUM_TIMERS > 0)
298       case TIMER_0:
299         gki_cb.com.OSTaskTmr0R[task_id] = 0;
300         gki_cb.com.OSTaskTmr0[task_id] = 0;
301         break;
302 #endif
303 
304 #if (GKI_NUM_TIMERS > 1)
305       case TIMER_1:
306         gki_cb.com.OSTaskTmr1R[task_id] = 0;
307         gki_cb.com.OSTaskTmr1[task_id] = 0;
308         break;
309 #endif
310 
311 #if (GKI_NUM_TIMERS > 2)
312       case TIMER_2:
313         gki_cb.com.OSTaskTmr2R[task_id] = 0;
314         gki_cb.com.OSTaskTmr2[task_id] = 0;
315         break;
316 #endif
317 
318 #if (GKI_NUM_TIMERS > 3)
319       case TIMER_3:
320         gki_cb.com.OSTaskTmr3R[task_id] = 0;
321         gki_cb.com.OSTaskTmr3[task_id] = 0;
322         break;
323 #endif
324     }
325   }
326 
327   if (gki_timers_is_timer_running() == false) {
328     if (gki_cb.com.p_tick_cb) {
329 #if (GKI_DELAY_STOP_SYS_TICK > 0)
330       /* if inactivity delay timer is not running */
331       if ((gki_cb.com.system_tick_running) &&
332           (gki_cb.com.OSTicksTilStop == 0)) {
333         /* set inactivity delay timer */
334         /* when timer expires, system tick will be stopped */
335         gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
336       }
337 #else
338       gki_cb.com.system_tick_running = false;
339       (gki_cb.com.p_tick_cb)(false); /* stop system tick */
340 #endif
341     }
342   }
343 
344   GKI_enable();
345 }
346 
347 /*******************************************************************************
348 **
349 ** Function         GKI_timer_update
350 **
351 ** Description      This function is called by an OS to drive the GKI's timers.
352 **                  It is typically called at every system tick to
353 **                  update the timers for all tasks, and check for timeouts.
354 **
355 **                  Note: It has been designed to also allow for variable tick
356 **                        updates so that systems with strict power savings
357 **                        requirements can have the update occur at variable
358 **                        intervals.
359 **
360 ** Parameters:      ticks_since_last_update - (input) This is the number of
361 **                  TICKS that have occurred since the last time
362 **                  GKI_timer_update was called.
363 **
364 ** Returns          void
365 **
366 *******************************************************************************/
GKI_timer_update(int32_t ticks_since_last_update)367 void GKI_timer_update(int32_t ticks_since_last_update) {
368   uint8_t task_id;
369   long next_expiration; /* Holds the next soonest expiration time after this
370                            update */
371 
372   /* Increment the number of ticks used for time stamps */
373   gki_cb.com.OSTicks += ticks_since_last_update;
374 
375   /* If any timers are running in any tasks, decrement the remaining time til
376    * the timer updates need to take place (next expiration occurs)
377    */
378   gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
379 
380   /* Don't allow timer interrupt nesting */
381   if (gki_cb.com.timer_nesting) return;
382 
383   gki_cb.com.timer_nesting = 1;
384 
385 #if (GKI_DELAY_STOP_SYS_TICK > 0)
386   /* if inactivity delay timer is set and expired */
387   if (gki_cb.com.OSTicksTilStop) {
388     if (gki_cb.com.OSTicksTilStop <= (uint32_t)ticks_since_last_update) {
389       if (gki_cb.com.p_tick_cb) {
390         gki_cb.com.system_tick_running = false;
391         (gki_cb.com.p_tick_cb)(false); /* stop system tick */
392       }
393       gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */
394       gki_cb.com.timer_nesting = 0;
395       return;
396     } else
397       gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
398   }
399 #endif
400 
401   /* No need to update the ticks if no timeout has occurred */
402   if (gki_cb.com.OSTicksTilExp > 0) {
403     gki_cb.com.timer_nesting = 0;
404     return;
405   }
406 
407   GKI_disable();
408 
409   next_expiration = GKI_NO_NEW_TMRS_STARTED;
410 
411   /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase
412      gki_cb.com.OSNumOrigTicks
413      to account for the difference so timer updates below are decremented by the
414      full number
415      of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function
416      so changing this
417      value only affects the timer updates below
418    */
419   gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
420 
421   /* Check for OS Task Timers */
422   for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
423     if (gki_cb.com.OSRdyTbl[task_id] == TASK_DEAD) {
424       // task is shutdown do not try to service timers
425       continue;
426     }
427 
428     if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
429     {
430       gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
431       if (gki_cb.com.OSWaitTmr[task_id] <= 0) {
432         /* Timer Expired */
433         gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
434       }
435     }
436 
437 #if (GKI_NUM_TIMERS > 0)
438     /* If any timer is running, decrement */
439     if (gki_cb.com.OSTaskTmr0[task_id] > 0) {
440       gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
441 
442       if (gki_cb.com.OSTaskTmr0[task_id] <= 0) {
443 /* Set Timer 0 Expired event mask and reload timer */
444 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
445         GKI_isend_event(task_id, TIMER_0_EVT_MASK);
446 #else
447         GKI_send_event(task_id, TIMER_0_EVT_MASK);
448 #endif
449         gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
450       }
451     }
452 
453     /* Check to see if this timer is the next one to expire */
454     if (gki_cb.com.OSTaskTmr0[task_id] > 0 &&
455         gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
456       next_expiration = gki_cb.com.OSTaskTmr0[task_id];
457 #endif
458 
459 #if (GKI_NUM_TIMERS > 1)
460     /* If any timer is running, decrement */
461     if (gki_cb.com.OSTaskTmr1[task_id] > 0) {
462       gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
463 
464       if (gki_cb.com.OSTaskTmr1[task_id] <= 0) {
465 /* Set Timer 1 Expired event mask and reload timer */
466 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
467         GKI_isend_event(task_id, TIMER_1_EVT_MASK);
468 #else
469         GKI_send_event(task_id, TIMER_1_EVT_MASK);
470 #endif
471         gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
472       }
473     }
474 
475     /* Check to see if this timer is the next one to expire */
476     if (gki_cb.com.OSTaskTmr1[task_id] > 0 &&
477         gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
478       next_expiration = gki_cb.com.OSTaskTmr1[task_id];
479 #endif
480 
481 #if (GKI_NUM_TIMERS > 2)
482     /* If any timer is running, decrement */
483     if (gki_cb.com.OSTaskTmr2[task_id] > 0) {
484       gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
485 
486       if (gki_cb.com.OSTaskTmr2[task_id] <= 0) {
487 /* Set Timer 2 Expired event mask and reload timer */
488 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
489         GKI_isend_event(task_id, TIMER_2_EVT_MASK);
490 #else
491         GKI_send_event(task_id, TIMER_2_EVT_MASK);
492 #endif
493         gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
494       }
495     }
496 
497     /* Check to see if this timer is the next one to expire */
498     if (gki_cb.com.OSTaskTmr2[task_id] > 0 &&
499         gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
500       next_expiration = gki_cb.com.OSTaskTmr2[task_id];
501 #endif
502 
503 #if (GKI_NUM_TIMERS > 3)
504     /* If any timer is running, decrement */
505     if (gki_cb.com.OSTaskTmr3[task_id] > 0) {
506       gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
507 
508       if (gki_cb.com.OSTaskTmr3[task_id] <= 0) {
509 /* Set Timer 3 Expired event mask and reload timer */
510 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
511         GKI_isend_event(task_id, TIMER_3_EVT_MASK);
512 #else
513         GKI_send_event(task_id, TIMER_3_EVT_MASK);
514 #endif
515         gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
516       }
517     }
518 
519     /* Check to see if this timer is the next one to expire */
520     if (gki_cb.com.OSTaskTmr3[task_id] > 0 &&
521         gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
522       next_expiration = gki_cb.com.OSTaskTmr3[task_id];
523 #endif
524   }
525 
526   /* Set the next timer experation value if there is one to start */
527   if (next_expiration < GKI_NO_NEW_TMRS_STARTED) {
528     gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
529   } else {
530     gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
531   }
532 
533   gki_cb.com.timer_nesting = 0;
534 
535   GKI_enable();
536 
537   return;
538 }
539 
540 /*******************************************************************************
541 **
542 ** Function         GKI_timer_queue_empty
543 **
544 ** Description      This function is called by applications to see whether the
545 **                  timer queue is empty
546 **
547 ** Parameters
548 **
549 ** Returns          bool
550 **
551 *******************************************************************************/
GKI_timer_queue_empty(void)552 bool GKI_timer_queue_empty(void) {
553   uint8_t tt;
554 
555   for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
556     if (gki_cb.com.timer_queues[tt]) return false;
557   }
558 
559   return true;
560 }
561 
562 /*******************************************************************************
563 **
564 ** Function         GKI_timer_queue_register_callback
565 **
566 ** Description      This function is called by applications to register system
567 **                  tick start/stop callback for time queues
568 **
569 **
570 ** Parameters       p_callback - (input) pointer to the system tick callback
571 **
572 ** Returns          bool
573 **
574 *******************************************************************************/
GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK * p_callback)575 void GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK* p_callback) {
576   gki_cb.com.p_tick_cb = p_callback;
577 
578   return;
579 }
580 
581 /*******************************************************************************
582 **
583 ** Function         GKI_init_timer_list
584 **
585 ** Description      This function is called by applications when they
586 **                  want to initialize a timer list.
587 **
588 ** Parameters       p_timer_listq - (input) pointer to the timer list queue
589 **                                          object
590 **
591 ** Returns          void
592 **
593 *******************************************************************************/
GKI_init_timer_list(TIMER_LIST_Q * p_timer_listq)594 void GKI_init_timer_list(TIMER_LIST_Q* p_timer_listq) {
595   p_timer_listq->p_first = nullptr;
596   p_timer_listq->p_last = nullptr;
597   p_timer_listq->last_ticks = 0;
598 
599   return;
600 }
601 
602 /*******************************************************************************
603 **
604 ** Function         GKI_init_timer_list_entry
605 **
606 ** Description      This function is called by the applications when they
607 **                  want to initialize a timer list entry. This must be
608 **                  done prior to first use of the entry.
609 **
610 ** Parameters       p_tle - (input) pointer to a timer list queue entry
611 **
612 ** Returns          void
613 **
614 *******************************************************************************/
GKI_init_timer_list_entry(TIMER_LIST_ENT * p_tle)615 void GKI_init_timer_list_entry(TIMER_LIST_ENT* p_tle) {
616   p_tle->p_next = nullptr;
617   p_tle->p_prev = nullptr;
618   p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
619   p_tle->in_use = false;
620 }
621 
622 /*******************************************************************************
623 **
624 ** Function         GKI_update_timer_list
625 **
626 ** Description      This function is called by the applications when they
627 **                  want to update a timer list. This should be at every
628 **                  timer list unit tick, e.g. once per sec, once per minute
629 **                  etc.
630 **
631 ** Parameters       p_timer_listq - (input) pointer to the timer list queue
632 **                  object
633 **                  num_units_since_last_update - (input) number of units since
634 **                  the last update (allows for variable unit update)
635 **
636 ** NOTE: The following timer list update routines should not be used for exact
637 **       time critical purposes.  The timer tasks should be used when exact
638 **       timing is needed.
639 **
640 ** Returns          the number of timers that have expired
641 **
642 *******************************************************************************/
GKI_update_timer_list(TIMER_LIST_Q * p_timer_listq,int32_t num_units_since_last_update)643 uint16_t GKI_update_timer_list(TIMER_LIST_Q* p_timer_listq,
644                                int32_t num_units_since_last_update) {
645   TIMER_LIST_ENT* p_tle;
646   uint16_t num_time_out = 0;
647   int32_t rem_ticks;
648   int32_t temp_ticks;
649 
650   p_tle = p_timer_listq->p_first;
651 
652   /* First, get the guys who have previously timed out */
653   /* Note that the tick value of the timers should always be '0' */
654   while ((p_tle) && (p_tle->ticks <= 0)) {
655     num_time_out++;
656     p_tle = p_tle->p_next;
657   }
658 
659   /* Timer entriy tick values are relative to the preceeding entry */
660   rem_ticks = num_units_since_last_update;
661 
662   /* Now, adjust remaining timer entries */
663   while ((p_tle != nullptr) && (rem_ticks > 0)) {
664     temp_ticks = p_tle->ticks;
665     p_tle->ticks -= rem_ticks;
666 
667     /* See if this timer has just timed out */
668     if (p_tle->ticks <= 0) {
669       /* We set the number of ticks to '0' so that the legacy code
670        * that assumes a '0' or nonzero value will still work as coded. */
671       p_tle->ticks = 0;
672 
673       num_time_out++;
674     }
675 
676     rem_ticks -= temp_ticks; /* Decrement the remaining ticks to process */
677     p_tle = p_tle->p_next;
678   }
679 
680   if (p_timer_listq->last_ticks > 0) {
681     p_timer_listq->last_ticks -= num_units_since_last_update;
682 
683     /* If the last timer has expired set last_ticks to 0 so that other list
684     * update
685     * functions will calculate correctly
686     */
687     if (p_timer_listq->last_ticks < 0) p_timer_listq->last_ticks = 0;
688   }
689 
690   return (num_time_out);
691 }
692 
GKI_timer_list_empty(TIMER_LIST_Q * p_timer_listq)693 bool GKI_timer_list_empty(TIMER_LIST_Q* p_timer_listq) {
694   return p_timer_listq->p_first == nullptr;
695 }
696 
GKI_timer_list_first(TIMER_LIST_Q * p_timer_listq)697 TIMER_LIST_ENT* GKI_timer_list_first(TIMER_LIST_Q* p_timer_listq) {
698   return p_timer_listq->p_first;
699 }
700 
701 /*******************************************************************************
702 **
703 ** Function         GKI_get_remaining_ticks
704 **
705 ** Description      This function is called by an application to get remaining
706 **                  ticks to expire
707 **
708 ** Parameters       p_timer_listq - (input) pointer to the timer list queue
709 **                                          object
710 **                  p_target_tle - (input) pointer to a timer list queue entry
711 **
712 ** Returns          0 if timer is not used or timer is not in the list
713 **                  remaining ticks if success
714 **
715 *******************************************************************************/
GKI_get_remaining_ticks(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_target_tle)716 uint32_t GKI_get_remaining_ticks(TIMER_LIST_Q* p_timer_listq,
717                                  TIMER_LIST_ENT* p_target_tle) {
718   TIMER_LIST_ENT* p_tle;
719   uint32_t rem_ticks = 0;
720 
721   if (p_target_tle->in_use) {
722     p_tle = p_timer_listq->p_first;
723 
724     /* adding up all of ticks in previous entries */
725     while ((p_tle) && (p_tle != p_target_tle)) {
726       rem_ticks += p_tle->ticks;
727       p_tle = p_tle->p_next;
728     }
729 
730     /* if found target entry */
731     if (p_tle == p_target_tle) {
732       rem_ticks += p_tle->ticks;
733     } else {
734       LOG(ERROR) << StringPrintf(
735           "GKI_get_remaining_ticks: No timer entry in the list");
736       return (0);
737     }
738   } else {
739     LOG(ERROR) << StringPrintf(
740         "GKI_get_remaining_ticks: timer entry is not active");
741   }
742 
743   return (rem_ticks);
744 }
745 
746 /*******************************************************************************
747 **
748 ** Function         GKI_add_to_timer_list
749 **
750 ** Description      This function is called by an application to add a timer
751 **                  entry to a timer list.
752 **
753 **                  Note: A timer value of '0' will effectively insert an
754 **                        already expired event.  Negative tick values will be
755 **                        ignored.
756 **
757 ** Parameters       p_timer_listq - (input) pointer to the timer list queue
758 **                                          object
759 **                  p_tle - (input) pointer to a timer list queue entry
760 **
761 ** Returns          void
762 **
763 *******************************************************************************/
GKI_add_to_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)764 void GKI_add_to_timer_list(TIMER_LIST_Q* p_timer_listq, TIMER_LIST_ENT* p_tle) {
765   uint32_t nr_ticks_total;
766   uint8_t tt;
767   TIMER_LIST_ENT* p_temp;
768   if (p_tle == nullptr || p_timer_listq == nullptr) {
769     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
770         "%s: invalid argument %p, %p****************************<<", __func__,
771         p_timer_listq, p_tle);
772     return;
773   }
774 
775   /* Only process valid tick values */
776   if (p_tle->ticks >= 0) {
777     /* If this entry is the last in the list */
778     if (p_tle->ticks >= p_timer_listq->last_ticks) {
779       /* If this entry is the only entry in the list */
780       if (p_timer_listq->p_first == nullptr)
781         p_timer_listq->p_first = p_tle;
782       else {
783         /* Insert the entry onto the end of the list */
784         if (p_timer_listq->p_last != nullptr)
785           p_timer_listq->p_last->p_next = p_tle;
786 
787         p_tle->p_prev = p_timer_listq->p_last;
788       }
789 
790       p_tle->p_next = nullptr;
791       p_timer_listq->p_last = p_tle;
792       nr_ticks_total = p_tle->ticks;
793       p_tle->ticks -= p_timer_listq->last_ticks;
794 
795       p_timer_listq->last_ticks = nr_ticks_total;
796     } else /* This entry needs to be inserted before the last entry */
797     {
798       /* Find the entry that the new one needs to be inserted in front of */
799       p_temp = p_timer_listq->p_first;
800       while (p_tle->ticks > p_temp->ticks) {
801         /* Update the tick value if looking at an unexpired entry */
802         if (p_temp->ticks > 0) p_tle->ticks -= p_temp->ticks;
803 
804         p_temp = p_temp->p_next;
805       }
806 
807       /* The new entry is the first in the list */
808       if (p_temp == p_timer_listq->p_first) {
809         p_tle->p_next = p_timer_listq->p_first;
810         p_timer_listq->p_first->p_prev = p_tle;
811         p_timer_listq->p_first = p_tle;
812       } else {
813         p_temp->p_prev->p_next = p_tle;
814         p_tle->p_prev = p_temp->p_prev;
815         p_temp->p_prev = p_tle;
816         p_tle->p_next = p_temp;
817       }
818       p_temp->ticks -= p_tle->ticks;
819     }
820 
821     p_tle->in_use = true;
822 
823     /* if we already add this timer queue to the array */
824     for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
825       if (gki_cb.com.timer_queues[tt] == p_timer_listq) return;
826     }
827     /* add this timer queue to the array */
828     for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
829       if (gki_cb.com.timer_queues[tt] == nullptr) break;
830     }
831     if (tt < GKI_MAX_TIMER_QUEUES) {
832       gki_cb.com.timer_queues[tt] = p_timer_listq;
833     }
834   }
835 
836   return;
837 }
838 
839 /*******************************************************************************
840 **
841 ** Function         GKI_remove_from_timer_list
842 **
843 ** Description      This function is called by an application to remove a timer
844 **                  entry from a timer list.
845 **
846 ** Parameters       p_timer_listq  - (input) pointer to the timer list queue
847 **                                            object
848 **                  p_tle - (input) pointer to a timer list queue entry
849 **
850 ** Returns          void
851 **
852 *******************************************************************************/
GKI_remove_from_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)853 void GKI_remove_from_timer_list(TIMER_LIST_Q* p_timer_listq,
854                                 TIMER_LIST_ENT* p_tle) {
855   uint8_t tt;
856 
857   /* Verify that the entry is valid */
858   if (p_tle == nullptr || p_tle->in_use == false ||
859       p_timer_listq->p_first == nullptr) {
860     return;
861   }
862 
863   /* Add the ticks remaining in this timer (if any) to the next guy in the list.
864   ** Note: Expired timers have a tick value of '0'.
865   */
866   if (p_tle->p_next != nullptr) {
867     p_tle->p_next->ticks += p_tle->ticks;
868   } else {
869     p_timer_listq->last_ticks -= p_tle->ticks;
870   }
871 
872   /* Unlink timer from the list.
873   */
874   if (p_timer_listq->p_first == p_tle) {
875     p_timer_listq->p_first = p_tle->p_next;
876 
877     if (p_timer_listq->p_first != nullptr) p_timer_listq->p_first->p_prev = nullptr;
878 
879     if (p_timer_listq->p_last == p_tle) p_timer_listq->p_last = nullptr;
880   } else {
881     if (p_timer_listq->p_last == p_tle) {
882       p_timer_listq->p_last = p_tle->p_prev;
883 
884       if (p_timer_listq->p_last != nullptr) p_timer_listq->p_last->p_next = nullptr;
885     } else {
886       if (p_tle->p_next != nullptr && p_tle->p_next->p_prev == p_tle)
887         p_tle->p_next->p_prev = p_tle->p_prev;
888       else {
889         /* Error case - chain messed up ?? */
890         return;
891       }
892 
893       if (p_tle->p_prev != nullptr && p_tle->p_prev->p_next == p_tle)
894         p_tle->p_prev->p_next = p_tle->p_next;
895       else {
896         /* Error case - chain messed up ?? */
897         return;
898       }
899     }
900   }
901 
902   p_tle->p_next = p_tle->p_prev = nullptr;
903   p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
904   p_tle->in_use = false;
905 
906   /* if timer queue is empty */
907   if (p_timer_listq->p_first == nullptr && p_timer_listq->p_last == nullptr) {
908     for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
909       if (gki_cb.com.timer_queues[tt] == p_timer_listq) {
910         gki_cb.com.timer_queues[tt] = nullptr;
911         break;
912       }
913     }
914   }
915 
916   return;
917 }
918 
919 /*******************************************************************************
920 **
921 ** Function         gki_adjust_timer_count
922 **
923 ** Description      This function is called whenever a new timer or GKI_wait
924 **                  occurs to adjust (if necessary) the current time til the
925 **                  first expiration. This only needs to make an adjustment if
926 **                  the new timer (in ticks) is less than the number of ticks
927 **                  remaining on the current timer.
928 **
929 ** Parameters:      ticks - (input) number of system ticks of the new timer
930 **                                  entry
931 **
932 **                  NOTE:  This routine MUST be called while interrupts are
933 **                         disabled to avoid updates while adjusting the timer
934 **                         variables.
935 **
936 ** Returns          void
937 **
938 *******************************************************************************/
gki_adjust_timer_count(int32_t ticks)939 void gki_adjust_timer_count(int32_t ticks) {
940   if (ticks > 0) {
941     /* See if the new timer expires before the current first expiration */
942     if (gki_cb.com.OSNumOrigTicks == 0 ||
943         (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0)) {
944       gki_cb.com.OSNumOrigTicks =
945           (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
946       gki_cb.com.OSTicksTilExp = ticks;
947     }
948   }
949 
950   return;
951 }
952