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