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 (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 *******************************************************************************/
GKI_stop_timer(uint8_t tnum)285 void 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 *******************************************************************************/
GKI_timer_update(int32_t ticks_since_last_update)360 void 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 *******************************************************************************/
GKI_timer_queue_empty(void)545 bool 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 *******************************************************************************/
GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK * p_callback)568 void 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 *******************************************************************************/
GKI_init_timer_list(TIMER_LIST_Q * p_timer_listq)587 void GKI_init_timer_list(TIMER_LIST_Q* p_timer_listq) {
588 p_timer_listq->p_first = nullptr;
589 p_timer_listq->p_last = nullptr;
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 *******************************************************************************/
GKI_init_timer_list_entry(TIMER_LIST_ENT * p_tle)608 void GKI_init_timer_list_entry(TIMER_LIST_ENT* p_tle) {
609 p_tle->p_next = nullptr;
610 p_tle->p_prev = nullptr;
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 *******************************************************************************/
GKI_update_timer_list(TIMER_LIST_Q * p_timer_listq,int32_t num_units_since_last_update)636 uint16_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 != nullptr) && (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 *******************************************************************************/
GKI_get_remaining_ticks(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_target_tle)701 uint32_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 *******************************************************************************/
GKI_add_to_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)749 void 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 == nullptr || p_timer_listq == nullptr) {
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 == nullptr)
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 != nullptr)
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 = nullptr;
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] == nullptr) 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 *******************************************************************************/
GKI_remove_from_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)838 void 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 == nullptr || p_tle->in_use == false ||
844 p_timer_listq->p_first == nullptr) {
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 != nullptr) {
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 != nullptr) p_timer_listq->p_first->p_prev = nullptr;
863
864 if (p_timer_listq->p_last == p_tle) p_timer_listq->p_last = nullptr;
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 != nullptr) p_timer_listq->p_last->p_next = nullptr;
870 } else {
871 if (p_tle->p_next != nullptr && 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 != nullptr && 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 = nullptr;
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 == nullptr && p_timer_listq->p_last == nullptr) {
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] = nullptr;
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 *******************************************************************************/
gki_adjust_timer_count(int32_t ticks)924 void 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