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