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