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