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