]> granicus.if.org Git - esp-idf/blob - components/bt/bluedroid/stack/btu/btu_task.c
f3a738359ce6a676f76ae1852ff0f71ed55c8a6b
[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     if (p_tle->in_use == FALSE) {
517         return;
518     }
519     p_tle->in_use = FALSE;
520
521     // Get the alarm for the timer list entry.
522     osi_alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
523     if (alarm == NULL) {
524         LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
525         return;
526     }
527     osi_alarm_cancel(alarm);
528     hash_map_erase(btu_general_alarm_hash_map, p_tle);
529 }
530
531 #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
532 /*******************************************************************************
533 **
534 ** Function         btu_start_quick_timer
535 **
536 ** Description      Start a timer for the specified amount of time in ticks.
537 **
538 ** Returns          void
539 **
540 *******************************************************************************/
541 static void btu_l2cap_alarm_process(TIMER_LIST_ENT *p_tle)
542 {
543     assert(p_tle != NULL);
544
545     switch (p_tle->event) {
546     case BTU_TTYPE_L2CAP_CHNL:      /* monitor or retransmission timer */
547     case BTU_TTYPE_L2CAP_FCR_ACK:   /* ack timer */
548         l2c_process_timeout (p_tle);
549         break;
550
551     default:
552         break;
553     }
554 }
555
556 static void btu_l2cap_alarm_cb(void *data)
557 {
558     assert(data != NULL);
559     TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
560
561     btu_task_post(SIG_BTU_L2CAP_ALARM, p_tle, TASK_POST_BLOCKING);
562 }
563
564 void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ticks)
565 {
566     osi_alarm_t *alarm = NULL;
567
568     assert(p_tle != NULL);
569
570     // Get the alarm for the timer list entry.
571     osi_mutex_lock(&btu_l2cap_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
572     if (!hash_map_has_key(btu_l2cap_alarm_hash_map, p_tle)) {
573         alarm = osi_alarm_new("btu_l2cap", btu_l2cap_alarm_cb, (void *)p_tle, 0);
574         hash_map_set(btu_l2cap_alarm_hash_map, p_tle, (void *)alarm);
575     }
576     osi_mutex_unlock(&btu_l2cap_alarm_lock);
577
578     alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
579     if (alarm == NULL) {
580         LOG_ERROR("%s Unable to create alarm", __func__);
581         return;
582     }
583     osi_alarm_cancel(alarm);
584
585     p_tle->event = type;
586     p_tle->ticks = timeout_ticks;
587     p_tle->in_use = TRUE;
588     // The quick timer ticks are 100ms long.
589     osi_alarm_set(alarm, (period_ms_t)(timeout_ticks * 100));
590 }
591
592 /*******************************************************************************
593 **
594 ** Function         btu_stop_quick_timer
595 **
596 ** Description      Stop a timer.
597 **
598 ** Returns          void
599 **
600 *******************************************************************************/
601 void btu_stop_quick_timer(TIMER_LIST_ENT *p_tle)
602 {
603     assert(p_tle != NULL);
604
605     if (p_tle->in_use == FALSE) {
606         return;
607     }
608     p_tle->in_use = FALSE;
609
610     // Get the alarm for the timer list entry.
611     osi_alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
612     if (alarm == NULL) {
613         LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
614         return;
615     }
616     osi_alarm_cancel(alarm);
617 }
618 #endif /* defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) */
619
620 void btu_oneshot_alarm_cb(void *data)
621 {
622     assert(data != NULL);
623     TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
624
625     btu_stop_timer_oneshot(p_tle);
626
627     btu_task_post(SIG_BTU_ONESHOT_ALARM, p_tle, TASK_POST_BLOCKING);
628 }
629
630 /*
631  * Starts a oneshot timer with a timeout in seconds.
632  */
633 void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
634 {
635     osi_alarm_t *alarm = NULL;
636
637     assert(p_tle != NULL);
638
639     // Get the alarm for the timer list entry.
640     osi_mutex_lock(&btu_oneshot_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
641     if (!hash_map_has_key(btu_oneshot_alarm_hash_map, p_tle)) {
642         alarm = osi_alarm_new("btu_oneshot", btu_oneshot_alarm_cb, (void *)p_tle, 0);
643         hash_map_set(btu_oneshot_alarm_hash_map, p_tle, alarm);
644     }
645     osi_mutex_unlock(&btu_oneshot_alarm_lock);
646
647     alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
648     if (alarm == NULL) {
649         LOG_ERROR("%s Unable to create alarm", __func__);
650         return;
651     }
652     osi_alarm_cancel(alarm);
653
654     p_tle->event = type;
655     p_tle->in_use = TRUE;
656     // NOTE: This value is in seconds but stored in a ticks field.
657     p_tle->ticks = timeout_sec;
658     osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000));
659 }
660
661 void btu_stop_timer_oneshot(TIMER_LIST_ENT *p_tle)
662 {
663     assert(p_tle != NULL);
664
665     if (p_tle->in_use == FALSE) {
666         return;
667     }
668     p_tle->in_use = FALSE;
669
670     // Get the alarm for the timer list entry.
671     osi_alarm_t *alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
672     if (alarm == NULL) {
673         LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
674         return;
675     }
676     osi_alarm_cancel(alarm);
677 }
678
679 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
680 /*******************************************************************************
681 **
682 ** Function         btu_check_bt_sleep
683 **
684 ** Description      This function is called to check if controller can go to sleep.
685 **
686 ** Returns          void
687 **
688 *******************************************************************************/
689 void btu_check_bt_sleep (void)
690 {
691     // TODO(zachoverflow) take pending commands into account?
692     if (l2cb.controller_xmit_window == l2cb.num_lm_acl_bufs) {
693         bte_main_lpm_allow_bt_device_sleep();
694     }
695 }
696 #endif