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