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