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