1 /****************************************************************************** 2 * 3 * Copyright (C) 2003-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 /****************************************************************************** 20 * 21 * This is the main implementation file for the BTA system manager. 22 * 23 ******************************************************************************/ 24 #define LOG_TAG "bt_bta_sys_main" 25 26 #include <assert.h> 27 #include <string.h> 28 29 #include "osi/include/alarm.h" 30 #include "btm_api.h" 31 #include "bta_api.h" 32 #include "bta_sys.h" 33 #include "bta_sys_int.h" 34 35 #include "osi/include/fixed_queue.h" 36 #include "gki.h" 37 #include "osi/include/hash_map.h" 38 #include "osi/include/osi.h" 39 #include "osi/include/hash_functions.h" 40 #include "osi/include/log.h" 41 #include "osi/include/thread.h" 42 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) 43 #include "bta_ar_api.h" 44 #endif 45 #include "utl.h" 46 47 /* system manager control block definition */ 48 #if BTA_DYNAMIC_MEMORY == FALSE 49 tBTA_SYS_CB bta_sys_cb; 50 #endif 51 52 fixed_queue_t *btu_bta_alarm_queue; 53 static hash_map_t *bta_alarm_hash_map; 54 static const size_t BTA_ALARM_HASH_MAP_SIZE = 17; 55 static pthread_mutex_t bta_alarm_lock; 56 extern thread_t *bt_workqueue_thread; 57 58 /* trace level */ 59 /* TODO Bluedroid - Hard-coded trace levels - Needs to be configurable */ 60 UINT8 appl_trace_level = BT_TRACE_LEVEL_WARNING; //APPL_INITIAL_TRACE_LEVEL; 61 UINT8 btif_trace_level = BT_TRACE_LEVEL_WARNING; 62 63 // Communication queue between btu_task and bta. 64 extern fixed_queue_t *btu_bta_msg_queue; 65 void btu_bta_alarm_ready(fixed_queue_t *queue, UNUSED_ATTR void *context); 66 67 static const tBTA_SYS_REG bta_sys_hw_reg = 68 { 69 bta_sys_sm_execute, 70 NULL 71 }; 72 73 74 /* type for action functions */ 75 typedef void (*tBTA_SYS_ACTION)(tBTA_SYS_HW_MSG *p_data); 76 77 /* action function list */ 78 const tBTA_SYS_ACTION bta_sys_action[] = 79 { 80 /* device manager local device API events - cf bta_sys.h for events */ 81 bta_sys_hw_api_enable, /* 0 BTA_SYS_HW_API_ENABLE_EVT */ 82 bta_sys_hw_evt_enabled, /* 1 BTA_SYS_HW_EVT_ENABLED_EVT */ 83 bta_sys_hw_evt_stack_enabled, /* 2 BTA_SYS_HW_EVT_STACK_ENABLED_EVT */ 84 bta_sys_hw_api_disable, /* 3 BTA_SYS_HW_API_DISABLE_EVT */ 85 bta_sys_hw_evt_disabled, /* 4 BTA_SYS_HW_EVT_DISABLED_EVT */ 86 bta_sys_hw_error /* 5 BTA_SYS_HW_ERROR_EVT */ 87 }; 88 89 /* state machine action enumeration list */ 90 enum 91 { 92 /* device manager local device API events */ 93 BTA_SYS_HW_API_ENABLE, 94 BTA_SYS_HW_EVT_ENABLED, 95 BTA_SYS_HW_EVT_STACK_ENABLED, 96 BTA_SYS_HW_API_DISABLE, 97 BTA_SYS_HW_EVT_DISABLED, 98 BTA_SYS_HW_ERROR 99 }; 100 101 #define BTA_SYS_NUM_ACTIONS (BTA_SYS_MAX_EVT & 0x00ff) 102 #define BTA_SYS_IGNORE BTA_SYS_NUM_ACTIONS 103 104 /* state table information */ 105 #define BTA_SYS_ACTIONS 2 /* number of actions */ 106 #define BTA_SYS_NEXT_STATE 2 /* position of next state */ 107 #define BTA_SYS_NUM_COLS 3 /* number of columns in state tables */ 108 109 110 /* state table for OFF state */ 111 const UINT8 bta_sys_hw_off[][BTA_SYS_NUM_COLS] = 112 { 113 /* Event Action 1 Action 2 Next State */ 114 /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, 115 /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, 116 /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 117 /* API_DISABLE */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}, 118 /* EVT_DISABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}, 119 /* EVT_ERROR */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF} 120 }; 121 122 const UINT8 bta_sys_hw_starting[][BTA_SYS_NUM_COLS] = 123 { 124 /* Event Action 1 Action 2 Next State */ 125 /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* wait for completion event */ 126 /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, 127 /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 128 /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive disable/enable: change state wait for completion to disable */ 129 /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_HW_API_ENABLE, BTA_SYS_HW_STARTING}, /* successive enable/disable: notify, then restart HW */ 130 /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON} 131 }; 132 133 const UINT8 bta_sys_hw_on[][BTA_SYS_NUM_COLS] = 134 { 135 /* Event Action 1 Action 2 Next State */ 136 /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 137 /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 138 /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 139 /* API_DISABLE */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* don't change the state here, as some other modules might be active */ 140 /* EVT_DISABLED */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 141 /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON} 142 }; 143 144 const UINT8 bta_sys_hw_stopping[][BTA_SYS_NUM_COLS] = 145 { 146 /* Event Action 1 Action 2 Next State */ 147 /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* change state, and wait for completion event to enable */ 148 /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: finish the enable before disabling */ 149 /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_HW_API_DISABLE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: notify, then stop */ 150 /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* wait for completion event */ 151 /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}, 152 /* EVT_ERROR */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING} 153 }; 154 155 typedef const UINT8 (*tBTA_SYS_ST_TBL)[BTA_SYS_NUM_COLS]; 156 157 /* state table */ 158 const tBTA_SYS_ST_TBL bta_sys_st_tbl[] = { 159 bta_sys_hw_off, 160 bta_sys_hw_starting, 161 bta_sys_hw_on, 162 bta_sys_hw_stopping 163 }; 164 165 /******************************************************************************* 166 ** 167 ** Function bta_sys_init 168 ** 169 ** Description BTA initialization; called from task initialization. 170 ** 171 ** 172 ** Returns void 173 ** 174 *******************************************************************************/ 175 void bta_sys_init(void) 176 { 177 memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB)); 178 179 pthread_mutex_init(&bta_alarm_lock, NULL); 180 181 bta_alarm_hash_map = hash_map_new(BTA_ALARM_HASH_MAP_SIZE, 182 hash_function_pointer, NULL, (data_free_fn)alarm_free, NULL); 183 btu_bta_alarm_queue = fixed_queue_new(SIZE_MAX); 184 185 fixed_queue_register_dequeue(btu_bta_alarm_queue, 186 thread_get_reactor(bt_workqueue_thread), 187 btu_bta_alarm_ready, 188 NULL); 189 190 appl_trace_level = APPL_INITIAL_TRACE_LEVEL; 191 192 /* register BTA SYS message handler */ 193 bta_sys_register( BTA_ID_SYS, &bta_sys_hw_reg); 194 195 /* register for BTM notifications */ 196 BTM_RegisterForDeviceStatusNotif ((tBTM_DEV_STATUS_CB*)&bta_sys_hw_btm_cback ); 197 198 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE) 199 bta_ar_init(); 200 #endif 201 202 } 203 204 void bta_sys_free(void) { 205 fixed_queue_free(btu_bta_alarm_queue, NULL); 206 hash_map_free(bta_alarm_hash_map); 207 pthread_mutex_destroy(&bta_alarm_lock); 208 } 209 210 /******************************************************************************* 211 ** 212 ** Function bta_dm_sm_execute 213 ** 214 ** Description State machine event handling function for DM 215 ** 216 ** 217 ** Returns void 218 ** 219 *******************************************************************************/ 220 BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg) 221 { 222 BOOLEAN freebuf = TRUE; 223 tBTA_SYS_ST_TBL state_table; 224 UINT8 action; 225 int i; 226 227 APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x", bta_sys_cb.state, p_msg->event); 228 229 /* look up the state table for the current state */ 230 state_table = bta_sys_st_tbl[bta_sys_cb.state]; 231 /* update state */ 232 bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE]; 233 234 /* execute action functions */ 235 for (i = 0; i < BTA_SYS_ACTIONS; i++) 236 { 237 if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_SYS_IGNORE) 238 { 239 (*bta_sys_action[action])( (tBTA_SYS_HW_MSG*) p_msg); 240 } 241 else 242 { 243 break; 244 } 245 } 246 return freebuf; 247 248 } 249 250 251 void bta_sys_hw_register( tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK *cback) 252 { 253 bta_sys_cb.sys_hw_cback[module]=cback; 254 } 255 256 257 void bta_sys_hw_unregister( tBTA_SYS_HW_MODULE module ) 258 { 259 bta_sys_cb.sys_hw_cback[module]=NULL; 260 } 261 262 /******************************************************************************* 263 ** 264 ** Function bta_sys_hw_btm_cback 265 ** 266 ** Description This function is registered by BTA SYS to BTM in order to get status notifications 267 ** 268 ** 269 ** Returns 270 ** 271 *******************************************************************************/ 272 void bta_sys_hw_btm_cback( tBTM_DEV_STATUS status ) 273 { 274 275 tBTA_SYS_HW_MSG *sys_event; 276 277 APPL_TRACE_DEBUG(" bta_sys_hw_btm_cback was called with parameter: %i" , status ); 278 279 /* send a message to BTA SYS */ 280 if ((sys_event = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) 281 { 282 if (status == BTM_DEV_STATUS_UP) 283 sys_event->hdr.event = BTA_SYS_EVT_STACK_ENABLED_EVT; 284 else if (status == BTM_DEV_STATUS_DOWN) 285 sys_event->hdr.event = BTA_SYS_ERROR_EVT; 286 else 287 { 288 /* BTM_DEV_STATUS_CMD_TOUT is ignored for now. */ 289 GKI_freebuf (sys_event); 290 sys_event = NULL; 291 } 292 293 if (sys_event) 294 { 295 bta_sys_sendmsg(sys_event); 296 } 297 } 298 else 299 { 300 APPL_TRACE_DEBUG("ERROR bta_sys_hw_btm_cback couldn't send msg" ); 301 } 302 } 303 304 305 306 /******************************************************************************* 307 ** 308 ** Function bta_sys_hw_error 309 ** 310 ** Description In case the HW device stops answering... Try to turn it off, then re-enable all 311 ** previously active SW modules. 312 ** 313 ** Returns success or failure 314 ** 315 *******************************************************************************/ 316 void bta_sys_hw_error(tBTA_SYS_HW_MSG *p_sys_hw_msg) 317 { 318 UINT8 module_index; 319 UNUSED(p_sys_hw_msg); 320 321 APPL_TRACE_DEBUG("%s", __FUNCTION__); 322 323 for (module_index = 0; module_index < BTA_SYS_MAX_HW_MODULES; module_index++) 324 { 325 if( bta_sys_cb.sys_hw_module_active & ((UINT32)1 << module_index )) { 326 switch( module_index) 327 { 328 case BTA_SYS_HW_BLUETOOTH: 329 /* Send BTA_SYS_HW_ERROR_EVT to DM */ 330 if (bta_sys_cb.sys_hw_cback[module_index] != NULL) 331 bta_sys_cb.sys_hw_cback[module_index] (BTA_SYS_HW_ERROR_EVT); 332 break; 333 default: 334 /* not yet supported */ 335 break; 336 } 337 } 338 } 339 } 340 341 342 343 /******************************************************************************* 344 ** 345 ** Function bta_sys_hw_enable 346 ** 347 ** Description this function is called after API enable and HW has been turned on 348 ** 349 ** 350 ** Returns success or failure 351 ** 352 *******************************************************************************/ 353 354 void bta_sys_hw_api_enable( tBTA_SYS_HW_MSG *p_sys_hw_msg ) 355 { 356 if ((!bta_sys_cb.sys_hw_module_active) && (bta_sys_cb.state != BTA_SYS_HW_ON)) 357 { 358 /* register which HW module was turned on */ 359 bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module ); 360 361 tBTA_SYS_HW_MSG *p_msg; 362 if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) 363 { 364 p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT; 365 p_msg->hw_module = p_sys_hw_msg->hw_module; 366 367 bta_sys_sendmsg(p_msg); 368 } 369 } 370 else 371 { 372 /* register which HW module was turned on */ 373 bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module ); 374 375 /* HW already in use, so directly notify the caller */ 376 if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]!= NULL ) 377 bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]( BTA_SYS_HW_ON_EVT ); 378 } 379 380 APPL_TRACE_EVENT ("bta_sys_hw_api_enable for %d, active modules 0x%04X", 381 p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active); 382 383 } 384 385 /******************************************************************************* 386 ** 387 ** Function bta_sys_hw_disable 388 ** 389 ** Description if no other module is using the HW, this function will call ( if defined ) a user-macro to turn off the HW 390 ** 391 ** 392 ** Returns success or failure 393 ** 394 *******************************************************************************/ 395 void bta_sys_hw_api_disable(tBTA_SYS_HW_MSG *p_sys_hw_msg) 396 { 397 APPL_TRACE_DEBUG("bta_sys_hw_api_disable for %d, active modules: 0x%04X", 398 p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active ); 399 400 /* make sure the related SW blocks were stopped */ 401 bta_sys_disable( p_sys_hw_msg->hw_module ); 402 403 404 /* register which module we turn off */ 405 bta_sys_cb.sys_hw_module_active &= ~((UINT32)1 << p_sys_hw_msg->hw_module ); 406 407 408 /* if there are still some SW modules using the HW, just provide an answer to the calling */ 409 if( bta_sys_cb.sys_hw_module_active != 0 ) 410 { 411 /* if there are still some SW modules using the HW, directly notify the caller */ 412 if( bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]!= NULL ) 413 bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]( BTA_SYS_HW_OFF_EVT ); 414 } 415 else 416 { 417 /* manually update the state of our system */ 418 bta_sys_cb.state = BTA_SYS_HW_STOPPING; 419 420 tBTA_SYS_HW_MSG *p_msg; 421 if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) 422 { 423 p_msg->hdr.event = BTA_SYS_EVT_DISABLED_EVT; 424 p_msg->hw_module = p_sys_hw_msg->hw_module; 425 426 bta_sys_sendmsg(p_msg); 427 } 428 } 429 430 } 431 432 433 /******************************************************************************* 434 ** 435 ** Function bta_sys_hw_event_enabled 436 ** 437 ** Description 438 ** 439 ** 440 ** Returns success or failure 441 ** 442 *******************************************************************************/ 443 void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg) 444 { 445 APPL_TRACE_EVENT("bta_sys_hw_evt_enabled for %i", p_sys_hw_msg->hw_module); 446 BTM_DeviceReset( NULL ); 447 } 448 449 450 /******************************************************************************* 451 ** 452 ** Function bta_sys_hw_event_disabled 453 ** 454 ** Description 455 ** 456 ** 457 ** Returns success or failure 458 ** 459 *******************************************************************************/ 460 void bta_sys_hw_evt_disabled(tBTA_SYS_HW_MSG *p_sys_hw_msg) 461 { 462 UINT8 hw_module_index; 463 464 APPL_TRACE_DEBUG("bta_sys_hw_evt_disabled - module 0x%X", p_sys_hw_msg->hw_module); 465 466 for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++) 467 { 468 if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) 469 bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_OFF_EVT); 470 } 471 } 472 473 /******************************************************************************* 474 ** 475 ** Function bta_sys_hw_event_stack_enabled 476 ** 477 ** Description we receive this event once the SW side is ready ( stack, FW download,... ), 478 ** i.e. we can really start using the device. So notify the app. 479 ** 480 ** Returns success or failure 481 ** 482 *******************************************************************************/ 483 void bta_sys_hw_evt_stack_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg) 484 { 485 UINT8 hw_module_index; 486 UNUSED(p_sys_hw_msg); 487 488 APPL_TRACE_DEBUG(" bta_sys_hw_evt_stack_enabled!notify the callers"); 489 490 for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++ ) 491 { 492 if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) 493 bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_ON_EVT); 494 } 495 } 496 497 498 499 500 /******************************************************************************* 501 ** 502 ** Function bta_sys_event 503 ** 504 ** Description BTA event handler; called from task event handler. 505 ** 506 ** 507 ** Returns void 508 ** 509 *******************************************************************************/ 510 void bta_sys_event(BT_HDR *p_msg) 511 { 512 UINT8 id; 513 BOOLEAN freebuf = TRUE; 514 515 APPL_TRACE_EVENT("BTA got event 0x%x", p_msg->event); 516 517 /* get subsystem id from event */ 518 id = (UINT8) (p_msg->event >> 8); 519 520 /* verify id and call subsystem event handler */ 521 if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) 522 { 523 freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg); 524 } 525 else 526 { 527 APPL_TRACE_WARNING("BTA got unregistered event id %d", id); 528 } 529 530 if (freebuf) 531 { 532 GKI_freebuf(p_msg); 533 } 534 535 } 536 537 /******************************************************************************* 538 ** 539 ** Function bta_sys_register 540 ** 541 ** Description Called by other BTA subsystems to register their event 542 ** handler. 543 ** 544 ** 545 ** Returns void 546 ** 547 *******************************************************************************/ 548 void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg) 549 { 550 bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg; 551 bta_sys_cb.is_reg[id] = TRUE; 552 } 553 554 /******************************************************************************* 555 ** 556 ** Function bta_sys_deregister 557 ** 558 ** Description Called by other BTA subsystems to de-register 559 ** handler. 560 ** 561 ** 562 ** Returns void 563 ** 564 *******************************************************************************/ 565 void bta_sys_deregister(UINT8 id) 566 { 567 bta_sys_cb.is_reg[id] = FALSE; 568 } 569 570 /******************************************************************************* 571 ** 572 ** Function bta_sys_is_register 573 ** 574 ** Description Called by other BTA subsystems to get registeration 575 ** status. 576 ** 577 ** 578 ** Returns void 579 ** 580 *******************************************************************************/ 581 BOOLEAN bta_sys_is_register(UINT8 id) 582 { 583 return bta_sys_cb.is_reg[id]; 584 } 585 586 /******************************************************************************* 587 ** 588 ** Function bta_sys_sendmsg 589 ** 590 ** Description Send a GKI message to BTA. This function is designed to 591 ** optimize sending of messages to BTA. It is called by BTA 592 ** API functions and call-in functions. 593 ** 594 ** 595 ** Returns void 596 ** 597 *******************************************************************************/ 598 void bta_sys_sendmsg(void *p_msg) 599 { 600 // There is a race condition that occurs if the stack is shut down while 601 // there is a procedure in progress that can schedule a task via this 602 // message queue. This causes |btu_bta_msg_queue| to get cleaned up before 603 // it gets used here; hence we check for NULL before using it. 604 if (btu_bta_msg_queue) 605 fixed_queue_enqueue(btu_bta_msg_queue, p_msg); 606 } 607 608 /******************************************************************************* 609 ** 610 ** Function bta_sys_start_timer 611 ** 612 ** Description Start a protocol timer for the specified amount 613 ** of time in milliseconds. 614 ** 615 ** Returns void 616 ** 617 *******************************************************************************/ 618 void bta_alarm_cb(void *data) { 619 assert(data != NULL); 620 TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data; 621 622 fixed_queue_enqueue(btu_bta_alarm_queue, p_tle); 623 } 624 625 void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms) { 626 assert(p_tle != NULL); 627 628 // Get the alarm for this p_tle. 629 pthread_mutex_lock(&bta_alarm_lock); 630 if (!hash_map_has_key(bta_alarm_hash_map, p_tle)) { 631 hash_map_set(bta_alarm_hash_map, p_tle, alarm_new()); 632 } 633 pthread_mutex_unlock(&bta_alarm_lock); 634 635 alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle); 636 if (alarm == NULL) { 637 LOG_ERROR("%s unable to create alarm.", __func__); 638 return; 639 } 640 641 p_tle->event = type; 642 p_tle->ticks = timeout_ms; 643 alarm_set(alarm, (period_ms_t)timeout_ms, bta_alarm_cb, p_tle); 644 } 645 646 bool hash_iter_ro_cb(hash_map_entry_t *hash_map_entry, void *context) 647 { 648 alarm_t *alarm = (alarm_t *)hash_map_entry->data; 649 period_ms_t *p_remaining_ms = (period_ms_t*)context; 650 *p_remaining_ms += alarm_get_remaining_ms(alarm); 651 return true; 652 } 653 654 UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle) 655 { 656 period_ms_t remaining_ms = 0; 657 pthread_mutex_lock(&bta_alarm_lock); 658 // Get the alarm for this p_tle 659 hash_map_foreach(bta_alarm_hash_map, hash_iter_ro_cb, &remaining_ms); 660 pthread_mutex_unlock(&bta_alarm_lock); 661 return remaining_ms; 662 } 663 664 665 /******************************************************************************* 666 ** 667 ** Function bta_sys_stop_timer 668 ** 669 ** Description Stop a BTA timer. 670 ** 671 ** Returns void 672 ** 673 *******************************************************************************/ 674 void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle) { 675 assert(p_tle != NULL); 676 677 alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle); 678 if (alarm == NULL) { 679 LOG_DEBUG("%s expected alarm was not in bta alarm hash map.", __func__); 680 return; 681 } 682 alarm_cancel(alarm); 683 } 684 685 /******************************************************************************* 686 ** 687 ** Function bta_sys_disable 688 ** 689 ** Description For each registered subsystem execute its disable function. 690 ** 691 ** Returns void 692 ** 693 *******************************************************************************/ 694 void bta_sys_disable(tBTA_SYS_HW_MODULE module) 695 { 696 int bta_id = 0; 697 int bta_id_max = 0; 698 699 APPL_TRACE_DEBUG("bta_sys_disable: module %i", module); 700 701 switch( module ) 702 { 703 case BTA_SYS_HW_BLUETOOTH: 704 bta_id = BTA_ID_DM; 705 bta_id_max = BTA_ID_BLUETOOTH_MAX; 706 break; 707 default: 708 APPL_TRACE_WARNING("bta_sys_disable: unkown module"); 709 return; 710 } 711 712 for ( ; bta_id <= bta_id_max; bta_id++) 713 { 714 if (bta_sys_cb.reg[bta_id] != NULL) 715 { 716 if (bta_sys_cb.is_reg[bta_id] == TRUE && bta_sys_cb.reg[bta_id]->disable != NULL) 717 { 718 (*bta_sys_cb.reg[bta_id]->disable)(); 719 } 720 } 721 } 722 } 723 724 /******************************************************************************* 725 ** 726 ** Function bta_sys_set_trace_level 727 ** 728 ** Description Set trace level for BTA 729 ** 730 ** Returns void 731 ** 732 *******************************************************************************/ 733 void bta_sys_set_trace_level(UINT8 level) 734 { 735 appl_trace_level = level; 736 } 737 738 /******************************************************************************* 739 ** 740 ** Function bta_sys_get_sys_features 741 ** 742 ** Description Returns sys_features to other BTA modules. 743 ** 744 ** Returns sys_features 745 ** 746 *******************************************************************************/ 747 UINT16 bta_sys_get_sys_features (void) 748 { 749 return bta_sys_cb.sys_features; 750 } 751