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