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 <string.h>
19
20
21 #include "osi/alarm.h"
22 #include "osi/thread.h"
23 #include "common/bt_target.h"
24 #include "common/bt_trace.h"
25 #include "stack/bt_types.h"
26 #include "osi/allocator.h"
27 #include "osi/mutex.h"
28 #include "stack/btm_api.h"
29 #include "btm_int.h"
30 #include "stack/btu.h"
31 #include "osi/hash_map.h"
32 #include "stack/hcimsgs.h"
33 #include "l2c_int.h"
34 #include "osi/osi.h"
35 #if (defined(SDP_INCLUDED) && SDP_INCLUDED == TRUE)
36 #include "sdpint.h"
37 #endif
38
39 #if (defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE)
40 #include "stack/port_api.h"
41 #include "stack/port_ext.h"
42 #endif
43
44 #if (defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE)
45 #include "gap_int.h"
46 #endif
47
48 #if (defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE)
49 #include "bnep_int.h"
50 #endif
51
52 #if (defined(PAN_INCLUDED) && PAN_INCLUDED == TRUE)
53 #include "pan_int.h"
54 #endif
55
56 #if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE )
57 #include "hidh_int.h"
58 #endif
59
60 #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
61 #include "avdt_int.h"
62 #else
63 extern void avdt_rcv_sync_info (BT_HDR *p_buf);
64 #endif
65
66 #if (defined(MCA_INCLUDED) && MCA_INCLUDED == TRUE)
67 #include "mca_api.h"
68 #include "mca_defs.h"
69 #include "mca_int.h"
70 #endif
71
72 #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
73 #include "bta/bta_sys.h"
74 #endif
75
76 #if (BLE_INCLUDED == TRUE)
77 #include "gatt_int.h"
78 #if (SMP_INCLUDED == TRUE)
79 #include "smp_int.h"
80 #endif
81 #include "btm_ble_int.h"
82 #endif
83
84 typedef struct {
85 uint32_t sig;
86 void *param;
87 } btu_thread_evt_t;
88
89 //#if (defined(BT_APP_DEMO) && BT_APP_DEMO == TRUE)
90 //#include "bt_app_common.h"
91 //#endif
92
93 extern bt_status_t BTE_InitStack(void);
94 extern void BTE_DeinitStack(void);
95
96 /* Define BTU storage area
97 */
98 #if BTU_DYNAMIC_MEMORY == FALSE
99 tBTU_CB btu_cb;
100 #else
101 tBTU_CB *btu_cb_ptr;
102 #endif
103
104 extern hash_map_t *btu_general_alarm_hash_map;
105 extern osi_mutex_t btu_general_alarm_lock;
106
107 // Oneshot timer queue.
108 extern hash_map_t *btu_oneshot_alarm_hash_map;
109 extern osi_mutex_t btu_oneshot_alarm_lock;
110
111 // l2cap timer queue.
112 extern hash_map_t *btu_l2cap_alarm_hash_map;
113 extern osi_mutex_t btu_l2cap_alarm_lock;
114
115 extern void *btu_thread;
116
117 extern bluedroid_init_done_cb_t bluedroid_init_done_cb;
118
119 /* Define a function prototype to allow a generic timeout handler */
120 typedef void (tUSER_TIMEOUT_FUNC) (TIMER_LIST_ENT *p_tle);
121
122 static void btu_l2cap_alarm_process(void *param);
123 static void btu_general_alarm_process(void *param);
124 static void btu_hci_msg_process(void *param);
125
126 #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
127 static void btu_bta_alarm_process(void *param);
128 #endif
129
btu_hci_msg_process(void * param)130 static void btu_hci_msg_process(void *param)
131 {
132 /* Determine the input message type. */
133 BT_HDR *p_msg = (BT_HDR *)param;
134
135 switch (p_msg->event & BT_EVT_MASK) {
136 case BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK: // TODO(zachoverflow): remove this
137 {
138 post_to_task_hack_t *ph = (post_to_task_hack_t *) &p_msg->data[0];
139 ph->callback(p_msg);
140 break;
141 }
142 case BT_EVT_TO_BTU_HCI_ACL:
143 /* All Acl Data goes to L2CAP */
144 l2c_rcv_acl_data (p_msg);
145 break;
146
147 case BT_EVT_TO_BTU_L2C_SEG_XMIT:
148 /* L2CAP segment transmit complete */
149 l2c_link_segments_xmitted (p_msg);
150 break;
151
152 case BT_EVT_TO_BTU_HCI_SCO:
153 #if BTM_SCO_INCLUDED == TRUE
154 btm_route_sco_data (p_msg);
155 break;
156 #endif
157
158 case BT_EVT_TO_BTU_HCI_EVT:
159 btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
160 osi_free(p_msg);
161
162 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
163 /* If host receives events which it doesn't response to, */
164 /* host should start idle timer to enter sleep mode. */
165 btu_check_bt_sleep ();
166 #endif
167 break;
168
169 case BT_EVT_TO_BTU_HCI_CMD:
170 btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
171 break;
172
173 default:;
174 int i = 0;
175 uint16_t mask = (UINT16) (p_msg->event & BT_EVT_MASK);
176 BOOLEAN handled = FALSE;
177
178 for (; !handled && i < BTU_MAX_REG_EVENT; i++) {
179 if (btu_cb.event_reg[i].event_cb == NULL) {
180 continue;
181 }
182
183 if (mask == btu_cb.event_reg[i].event_range) {
184 if (btu_cb.event_reg[i].event_cb) {
185 btu_cb.event_reg[i].event_cb(p_msg);
186 handled = TRUE;
187 }
188 }
189 }
190
191 if (handled == FALSE) {
192 osi_free (p_msg);
193 }
194
195 break;
196 }
197
198 }
199
200 #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
btu_bta_alarm_process(void * param)201 static void btu_bta_alarm_process(void *param)
202 {
203 TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)param;
204 // call timer callback
205 if (p_tle->p_cback) {
206 (*p_tle->p_cback)(p_tle);
207 } else if (p_tle->event) {
208 BT_HDR *p_msg;
209 if ((p_msg = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
210 p_msg->event = p_tle->event;
211 p_msg->layer_specific = 0;
212 //osi_free(p_msg);
213 bta_sys_sendmsg(p_msg);
214 }
215 }
216 }
217 #endif
218
btu_task_post(uint32_t sig,void * param,uint32_t timeout)219 bool btu_task_post(uint32_t sig, void *param, uint32_t timeout)
220 {
221 bool status = false;
222
223 switch (sig) {
224 case SIG_BTU_START_UP:
225 status = osi_thread_post(btu_thread, btu_task_start_up, param, 0, timeout);
226 break;
227 case SIG_BTU_HCI_MSG:
228 status = osi_thread_post(btu_thread, btu_hci_msg_process, param, 0, timeout);
229 break;
230 #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
231 case SIG_BTU_BTA_MSG:
232 status = osi_thread_post(btu_thread, bta_sys_event, param, 0, timeout);
233 break;
234 case SIG_BTU_BTA_ALARM:
235 status = osi_thread_post(btu_thread, btu_bta_alarm_process, param, 0, timeout);
236 break;
237 #endif
238 case SIG_BTU_GENERAL_ALARM:
239 case SIG_BTU_ONESHOT_ALARM:
240 status = osi_thread_post(btu_thread, btu_general_alarm_process, param, 0, timeout);
241 break;
242 case SIG_BTU_L2CAP_ALARM:
243 status = osi_thread_post(btu_thread, btu_l2cap_alarm_process, param, 0, timeout);
244 break;
245 default:
246 break;
247 }
248
249 return status;
250 }
251
btu_task_start_up(void * param)252 void btu_task_start_up(void *param)
253 {
254 UNUSED(param);
255 /* Initialize the mandatory core stack control blocks
256 (BTU, BTM, L2CAP, and SDP)
257 */
258 btu_init_core();
259
260 /* Initialize any optional stack components */
261 BTE_InitStack();
262
263 #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
264 bta_sys_init();
265 #endif
266
267 // Inform the bt jni thread initialization is ok.
268 // btif_transfer_context(btif_init_ok, 0, NULL, 0, NULL);
269 #if(defined(BT_APP_DEMO) && BT_APP_DEMO == TRUE)
270 if (bluedroid_init_done_cb) {
271 bluedroid_init_done_cb();
272 }
273 #endif
274 }
275
btu_task_shut_down(void)276 void btu_task_shut_down(void)
277 {
278 #if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
279 bta_sys_free();
280 #endif
281 BTE_DeinitStack();
282
283 btu_free_core();
284 }
285
286 /*******************************************************************************
287 **
288 ** Function btu_start_timer
289 **
290 ** Description Start a timer for the specified amount of time.
291 ** NOTE: The timeout resolution is in SECONDS! (Even
292 ** though the timer structure field is ticks)
293 **
294 ** Returns void
295 **
296 *******************************************************************************/
btu_general_alarm_process(void * param)297 static void btu_general_alarm_process(void *param)
298 {
299 TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)param;
300 assert(p_tle != NULL);
301
302 switch (p_tle->event) {
303 case BTU_TTYPE_BTM_DEV_CTL:
304 btm_dev_timeout(p_tle);
305 break;
306
307 case BTU_TTYPE_L2CAP_LINK:
308 case BTU_TTYPE_L2CAP_CHNL:
309 case BTU_TTYPE_L2CAP_HOLD:
310 case BTU_TTYPE_L2CAP_INFO:
311 case BTU_TTYPE_L2CAP_FCR_ACK:
312 case BTU_TTYPE_L2CAP_UPDA_CONN_PARAMS:
313 l2c_process_timeout (p_tle);
314 break;
315 #if (defined(SDP_INCLUDED) && SDP_INCLUDED == TRUE)
316 case BTU_TTYPE_SDP:
317 sdp_conn_timeout ((tCONN_CB *)p_tle->param);
318 break;
319 #endif
320 case BTU_TTYPE_BTM_RMT_NAME:
321 btm_inq_rmt_name_failed();
322 break;
323 #if (defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE)
324 case BTU_TTYPE_RFCOMM_MFC:
325 case BTU_TTYPE_RFCOMM_PORT:
326 rfcomm_process_timeout (p_tle);
327 break;
328 #endif
329 #if ((defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE))
330 case BTU_TTYPE_BNEP:
331 bnep_process_timeout(p_tle);
332 break;
333 #endif
334
335
336 #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
337 case BTU_TTYPE_AVDT_CCB_RET:
338 case BTU_TTYPE_AVDT_CCB_RSP:
339 case BTU_TTYPE_AVDT_CCB_IDLE:
340 case BTU_TTYPE_AVDT_SCB_TC:
341 avdt_process_timeout(p_tle);
342 break;
343 #endif
344
345 #if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
346 case BTU_TTYPE_HID_HOST_REPAGE_TO :
347 hidh_proc_repage_timeout(p_tle);
348 break;
349 #endif
350
351 #if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
352 case BTU_TTYPE_BLE_INQUIRY:
353 case BTU_TTYPE_BLE_GAP_LIM_DISC:
354 case BTU_TTYPE_BLE_RANDOM_ADDR:
355 case BTU_TTYPE_BLE_GAP_FAST_ADV:
356 case BTU_TTYPE_BLE_SCAN:
357 case BTU_TTYPE_BLE_OBSERVE:
358 btm_ble_timeout(p_tle);
359 break;
360
361 case BTU_TTYPE_ATT_WAIT_FOR_RSP:
362 gatt_rsp_timeout(p_tle);
363 break;
364
365 case BTU_TTYPE_ATT_WAIT_FOR_IND_ACK:
366 gatt_ind_ack_timeout(p_tle);
367 break;
368
369 #if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE)
370 case BTU_TTYPE_SMP_PAIRING_CMD:
371 smp_rsp_timeout(p_tle);
372 break;
373 #endif
374
375 #endif
376
377 #if (MCA_INCLUDED == TRUE)
378 case BTU_TTYPE_MCA_CCB_RSP:
379 mca_process_timeout(p_tle);
380 break;
381 #endif
382 case BTU_TTYPE_USER_FUNC: {
383 tUSER_TIMEOUT_FUNC *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param;
384 (*p_uf)(p_tle);
385 }
386 break;
387
388 case BTU_TTYPE_BTM_QOS:
389 btm_qos_setup_timeout(p_tle);
390 break;
391 default:
392 for (int i = 0; i < BTU_MAX_REG_TIMER; i++) {
393 if (btu_cb.timer_reg[i].timer_cb == NULL) {
394 continue;
395 }
396 if (btu_cb.timer_reg[i].p_tle == p_tle) {
397 btu_cb.timer_reg[i].timer_cb(p_tle);
398 break;
399 }
400 }
401 break;
402 }
403 }
404
btu_general_alarm_cb(void * data)405 void btu_general_alarm_cb(void *data)
406 {
407 assert(data != NULL);
408 TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
409
410 btu_task_post(SIG_BTU_GENERAL_ALARM, p_tle, OSI_THREAD_MAX_TIMEOUT);
411 }
412
btu_start_timer(TIMER_LIST_ENT * p_tle,UINT16 type,UINT32 timeout_sec)413 void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
414 {
415 osi_alarm_t *alarm = NULL;
416
417 assert(p_tle != NULL);
418
419 // Get the alarm for the timer list entry.
420 osi_mutex_lock(&btu_general_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
421 if (!hash_map_has_key(btu_general_alarm_hash_map, p_tle)) {
422 alarm = osi_alarm_new("btu_gen", btu_general_alarm_cb, (void *)p_tle, 0);
423 hash_map_set(btu_general_alarm_hash_map, p_tle, alarm);
424 }
425 osi_mutex_unlock(&btu_general_alarm_lock);
426
427 alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
428 if (alarm == NULL) {
429 HCI_TRACE_ERROR("%s Unable to create alarm", __func__);
430 return;
431 }
432 osi_alarm_cancel(alarm);
433
434 p_tle->event = type;
435 // NOTE: This value is in seconds but stored in a ticks field.
436 p_tle->ticks = timeout_sec;
437 p_tle->in_use = TRUE;
438 osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000));
439 }
440
441
442 /*******************************************************************************
443 **
444 ** Function btu_stop_timer
445 **
446 ** Description Stop a timer.
447 **
448 ** Returns void
449 **
450 *******************************************************************************/
btu_stop_timer(TIMER_LIST_ENT * p_tle)451 void btu_stop_timer(TIMER_LIST_ENT *p_tle)
452 {
453 assert(p_tle != NULL);
454
455 if (p_tle->in_use == FALSE) {
456 return;
457 }
458 p_tle->in_use = FALSE;
459
460 // Get the alarm for the timer list entry.
461 osi_alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
462 if (alarm == NULL) {
463 HCI_TRACE_WARNING("%s Unable to find expected alarm in hashmap", __func__);
464 return;
465 }
466 osi_alarm_cancel(alarm);
467 }
468
469 /*******************************************************************************
470 **
471 ** Function btu_free_timer
472 **
473 ** Description Stop and free a timer.
474 **
475 ** Returns void
476 **
477 *******************************************************************************/
btu_free_timer(TIMER_LIST_ENT * p_tle)478 void btu_free_timer(TIMER_LIST_ENT *p_tle)
479 {
480 assert(p_tle != NULL);
481
482 p_tle->in_use = FALSE;
483
484 // Get the alarm for the timer list entry.
485 osi_alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
486 if (alarm == NULL) {
487 HCI_TRACE_DEBUG("%s Unable to find expected alarm in hashmap", __func__);
488 return;
489 }
490 osi_alarm_cancel(alarm);
491 hash_map_erase(btu_general_alarm_hash_map, p_tle);
492 }
493
494 #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
495 /*******************************************************************************
496 **
497 ** Function btu_start_quick_timer
498 **
499 ** Description Start a timer for the specified amount of time in ticks.
500 **
501 ** Returns void
502 **
503 *******************************************************************************/
btu_l2cap_alarm_process(void * param)504 static void btu_l2cap_alarm_process(void *param)
505 {
506 TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)param;
507 assert(p_tle != NULL);
508
509 switch (p_tle->event) {
510 case BTU_TTYPE_L2CAP_CHNL: /* monitor or retransmission timer */
511 case BTU_TTYPE_L2CAP_FCR_ACK: /* ack timer */
512 l2c_process_timeout (p_tle);
513 break;
514
515 default:
516 break;
517 }
518 }
519
btu_l2cap_alarm_cb(void * data)520 static void btu_l2cap_alarm_cb(void *data)
521 {
522 assert(data != NULL);
523 TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
524
525 btu_task_post(SIG_BTU_L2CAP_ALARM, p_tle, OSI_THREAD_MAX_TIMEOUT);
526 }
527
btu_start_quick_timer(TIMER_LIST_ENT * p_tle,UINT16 type,UINT32 timeout_ticks)528 void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ticks)
529 {
530 osi_alarm_t *alarm = NULL;
531
532 assert(p_tle != NULL);
533
534 // Get the alarm for the timer list entry.
535 osi_mutex_lock(&btu_l2cap_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
536 if (!hash_map_has_key(btu_l2cap_alarm_hash_map, p_tle)) {
537 alarm = osi_alarm_new("btu_l2cap", btu_l2cap_alarm_cb, (void *)p_tle, 0);
538 hash_map_set(btu_l2cap_alarm_hash_map, p_tle, (void *)alarm);
539 }
540 osi_mutex_unlock(&btu_l2cap_alarm_lock);
541
542 alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
543 if (alarm == NULL) {
544 HCI_TRACE_ERROR("%s Unable to create alarm", __func__);
545 return;
546 }
547 osi_alarm_cancel(alarm);
548
549 p_tle->event = type;
550 p_tle->ticks = timeout_ticks;
551 p_tle->in_use = TRUE;
552 // The quick timer ticks are 100ms long.
553 osi_alarm_set(alarm, (period_ms_t)(timeout_ticks * 100));
554 }
555
556 /*******************************************************************************
557 **
558 ** Function btu_stop_quick_timer
559 **
560 ** Description Stop a timer.
561 **
562 ** Returns void
563 **
564 *******************************************************************************/
btu_stop_quick_timer(TIMER_LIST_ENT * p_tle)565 void btu_stop_quick_timer(TIMER_LIST_ENT *p_tle)
566 {
567 assert(p_tle != NULL);
568
569 if (p_tle->in_use == FALSE) {
570 return;
571 }
572 p_tle->in_use = FALSE;
573
574 // Get the alarm for the timer list entry.
575 osi_alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
576 if (alarm == NULL) {
577 HCI_TRACE_WARNING("%s Unable to find expected alarm in hashmap", __func__);
578 return;
579 }
580 osi_alarm_cancel(alarm);
581 }
582
btu_free_quick_timer(TIMER_LIST_ENT * p_tle)583 void btu_free_quick_timer(TIMER_LIST_ENT *p_tle)
584 {
585 assert(p_tle != NULL);
586
587 p_tle->in_use = FALSE;
588
589 // Get the alarm for the timer list entry.
590 osi_alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
591 if (alarm == NULL) {
592 HCI_TRACE_DEBUG("%s Unable to find expected alarm in hashmap", __func__);
593 return;
594 }
595 osi_alarm_cancel(alarm);
596 hash_map_erase(btu_l2cap_alarm_hash_map, p_tle);
597 }
598
599 #endif /* defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) */
600
btu_oneshot_alarm_cb(void * data)601 void btu_oneshot_alarm_cb(void *data)
602 {
603 assert(data != NULL);
604 TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
605
606 btu_stop_timer_oneshot(p_tle);
607
608 btu_task_post(SIG_BTU_ONESHOT_ALARM, p_tle, OSI_THREAD_MAX_TIMEOUT);
609 }
610
611 /*
612 * Starts a oneshot timer with a timeout in seconds.
613 */
btu_start_timer_oneshot(TIMER_LIST_ENT * p_tle,UINT16 type,UINT32 timeout_sec)614 void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
615 {
616 osi_alarm_t *alarm = NULL;
617
618 assert(p_tle != NULL);
619
620 // Get the alarm for the timer list entry.
621 osi_mutex_lock(&btu_oneshot_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
622 if (!hash_map_has_key(btu_oneshot_alarm_hash_map, p_tle)) {
623 alarm = osi_alarm_new("btu_oneshot", btu_oneshot_alarm_cb, (void *)p_tle, 0);
624 hash_map_set(btu_oneshot_alarm_hash_map, p_tle, alarm);
625 }
626 osi_mutex_unlock(&btu_oneshot_alarm_lock);
627
628 alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
629 if (alarm == NULL) {
630 HCI_TRACE_ERROR("%s Unable to create alarm", __func__);
631 return;
632 }
633 osi_alarm_cancel(alarm);
634
635 p_tle->event = type;
636 p_tle->in_use = TRUE;
637 // NOTE: This value is in seconds but stored in a ticks field.
638 p_tle->ticks = timeout_sec;
639 osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000));
640 }
641
btu_stop_timer_oneshot(TIMER_LIST_ENT * p_tle)642 void btu_stop_timer_oneshot(TIMER_LIST_ENT *p_tle)
643 {
644 assert(p_tle != NULL);
645
646 if (p_tle->in_use == FALSE) {
647 return;
648 }
649 p_tle->in_use = FALSE;
650
651 // Get the alarm for the timer list entry.
652 osi_alarm_t *alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
653 if (alarm == NULL) {
654 HCI_TRACE_WARNING("%s Unable to find expected alarm in hashmap", __func__);
655 return;
656 }
657 osi_alarm_cancel(alarm);
658 }
659
660 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
661 /*******************************************************************************
662 **
663 ** Function btu_check_bt_sleep
664 **
665 ** Description This function is called to check if controller can go to sleep.
666 **
667 ** Returns void
668 **
669 *******************************************************************************/
btu_check_bt_sleep(void)670 void btu_check_bt_sleep (void)
671 {
672 // TODO(zachoverflow) take pending commands into account?
673 if (l2cb.controller_xmit_window == l2cb.num_lm_acl_bufs) {
674 bte_main_lpm_allow_bt_device_sleep();
675 }
676 }
677 #endif
678