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