• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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