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