1 /****************************************************************************** 2 * 3 * Copyright 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 25 #define LOG_TAG "bt_bta_sys_main" 26 27 #include <base/bind.h> 28 #include <base/logging.h> 29 #include <base/threading/thread.h> 30 #include <pthread.h> 31 #include <string.h> 32 33 #include "bt_common.h" 34 #include "bta_api.h" 35 #include "bta_sys.h" 36 #include "bta_sys_int.h" 37 #include "btm_api.h" 38 #include "btu.h" 39 #include "osi/include/alarm.h" 40 #include "osi/include/fixed_queue.h" 41 #include "osi/include/log.h" 42 #include "osi/include/osi.h" 43 #include "osi/include/thread.h" 44 #include "utl.h" 45 46 #if (defined BTA_AR_INCLUDED) && (BTA_AR_INCLUDED == TRUE) 47 #include "bta_ar_api.h" 48 #endif 49 50 /* system manager control block definition */ 51 tBTA_SYS_CB bta_sys_cb; 52 53 extern thread_t* bt_workqueue_thread; 54 55 /* trace level */ 56 /* TODO Hard-coded trace levels - Needs to be configurable */ 57 uint8_t appl_trace_level = BT_TRACE_LEVEL_WARNING; // APPL_INITIAL_TRACE_LEVEL; 58 uint8_t btif_trace_level = BT_TRACE_LEVEL_WARNING; 59 60 static const tBTA_SYS_REG bta_sys_hw_reg = {bta_sys_sm_execute, NULL}; 61 62 /* type for action functions */ 63 typedef void (*tBTA_SYS_ACTION)(tBTA_SYS_HW_MSG* p_data); 64 65 /* action function list */ 66 const tBTA_SYS_ACTION bta_sys_action[] = { 67 /* device manager local device API events - cf bta_sys.h for events */ 68 bta_sys_hw_api_enable, /* 0 BTA_SYS_HW_API_ENABLE_EVT */ 69 bta_sys_hw_evt_enabled, /* 1 BTA_SYS_HW_EVT_ENABLED_EVT */ 70 bta_sys_hw_evt_stack_enabled, /* 2 BTA_SYS_HW_EVT_STACK_ENABLED_EVT */ 71 bta_sys_hw_api_disable, /* 3 BTA_SYS_HW_API_DISABLE_EVT */ 72 bta_sys_hw_evt_disabled, /* 4 BTA_SYS_HW_EVT_DISABLED_EVT */ 73 bta_sys_hw_error /* 5 BTA_SYS_HW_ERROR_EVT */ 74 }; 75 76 /* state machine action enumeration list */ 77 enum { 78 /* device manager local device API events */ 79 BTA_SYS_HW_API_ENABLE, 80 BTA_SYS_HW_EVT_ENABLED, 81 BTA_SYS_HW_EVT_STACK_ENABLED, 82 BTA_SYS_HW_API_DISABLE, 83 BTA_SYS_HW_EVT_DISABLED, 84 BTA_SYS_HW_ERROR 85 }; 86 87 #define BTA_SYS_NUM_ACTIONS (BTA_SYS_MAX_EVT & 0x00ff) 88 #define BTA_SYS_IGNORE BTA_SYS_NUM_ACTIONS 89 90 /* state table information */ 91 #define BTA_SYS_ACTIONS 2 /* number of actions */ 92 #define BTA_SYS_NEXT_STATE 2 /* position of next state */ 93 #define BTA_SYS_NUM_COLS 3 /* number of columns in state tables */ 94 95 /* state table for OFF state */ 96 const uint8_t bta_sys_hw_off[][BTA_SYS_NUM_COLS] = { 97 /* Event Action 1 Action 2 98 Next State */ 99 /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, 100 BTA_SYS_HW_STARTING}, 101 /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, 102 /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 103 /* API_DISABLE */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, 104 BTA_SYS_HW_OFF}, 105 /* EVT_DISABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}, 106 /* EVT_ERROR */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}}; 107 108 const uint8_t bta_sys_hw_starting[][BTA_SYS_NUM_COLS] = { 109 /* Event Action 1 Action 2 110 Next State */ 111 /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, 112 BTA_SYS_HW_STARTING}, /* wait for completion event */ 113 /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, 114 BTA_SYS_HW_STARTING}, 115 /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_IGNORE, 116 BTA_SYS_HW_ON}, 117 /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, 118 BTA_SYS_HW_STOPPING}, /* successive disable/enable: 119 change state wait for 120 completion to disable */ 121 /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_HW_API_ENABLE, 122 BTA_SYS_HW_STARTING}, /* successive enable/disable: 123 notify, then restart HW */ 124 /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}}; 125 126 const uint8_t bta_sys_hw_on[][BTA_SYS_NUM_COLS] = { 127 /* Event Action 1 Action 2 128 Next State */ 129 /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 130 /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 131 /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 132 /* API_DISABLE */ 133 {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, 134 BTA_SYS_HW_ON}, /* don't change the state here, as some 135 other modules might be active */ 136 /* EVT_DISABLED */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, 137 /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}}; 138 139 const uint8_t bta_sys_hw_stopping[][BTA_SYS_NUM_COLS] = { 140 /* Event Action 1 Action 2 141 Next State */ 142 /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, 143 BTA_SYS_HW_STARTING}, /* change state, and wait for 144 completion event to enable */ 145 /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, 146 BTA_SYS_HW_STOPPING}, /* successive enable/disable: 147 finish the enable before 148 disabling */ 149 /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_HW_API_DISABLE, 150 BTA_SYS_HW_STOPPING}, /* successive enable/disable: 151 notify, then stop */ 152 /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, 153 BTA_SYS_HW_STOPPING}, /* wait for completion event */ 154 /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, 155 BTA_SYS_HW_OFF}, 156 /* EVT_ERROR */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, 157 BTA_SYS_HW_STOPPING}}; 158 159 typedef const uint8_t (*tBTA_SYS_ST_TBL)[BTA_SYS_NUM_COLS]; 160 161 /* state table */ 162 const tBTA_SYS_ST_TBL bta_sys_st_tbl[] = { 163 bta_sys_hw_off, /* BTA_SYS_HW_OFF */ 164 bta_sys_hw_starting, /* BTA_SYS_HW_STARTING */ 165 bta_sys_hw_on, /* BTA_SYS_HW_ON */ 166 bta_sys_hw_stopping /* BTA_SYS_HW_STOPPING */ 167 }; 168 169 /******************************************************************************* 170 * 171 * Function bta_sys_init 172 * 173 * Description BTA initialization; called from task initialization. 174 * 175 * 176 * Returns void 177 * 178 ******************************************************************************/ 179 void bta_sys_init(void) { 180 memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB)); 181 182 appl_trace_level = APPL_INITIAL_TRACE_LEVEL; 183 184 /* register BTA SYS message handler */ 185 bta_sys_register(BTA_ID_SYS, &bta_sys_hw_reg); 186 187 /* register for BTM notifications */ 188 BTM_RegisterForDeviceStatusNotif(&bta_sys_hw_btm_cback); 189 190 #if (defined BTA_AR_INCLUDED) && (BTA_AR_INCLUDED == TRUE) 191 bta_ar_init(); 192 #endif 193 } 194 195 void bta_sys_free(void) { 196 } 197 198 /******************************************************************************* 199 * 200 * Function bta_dm_sm_execute 201 * 202 * Description State machine event handling function for DM 203 * 204 * 205 * Returns void 206 * 207 ******************************************************************************/ 208 bool bta_sys_sm_execute(BT_HDR* p_msg) { 209 bool freebuf = true; 210 tBTA_SYS_ST_TBL state_table; 211 uint8_t action; 212 int i; 213 214 APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x", bta_sys_cb.state, 215 p_msg->event); 216 217 /* look up the state table for the current state */ 218 state_table = bta_sys_st_tbl[bta_sys_cb.state]; 219 /* update state */ 220 bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE]; 221 222 /* execute action functions */ 223 for (i = 0; i < BTA_SYS_ACTIONS; i++) { 224 action = state_table[p_msg->event & 0x00ff][i]; 225 if (action != BTA_SYS_IGNORE) { 226 (*bta_sys_action[action])((tBTA_SYS_HW_MSG*)p_msg); 227 } else { 228 break; 229 } 230 } 231 return freebuf; 232 } 233 234 void bta_sys_hw_register(tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK* cback) { 235 bta_sys_cb.sys_hw_cback[module] = cback; 236 } 237 238 void bta_sys_hw_unregister(tBTA_SYS_HW_MODULE module) { 239 bta_sys_cb.sys_hw_cback[module] = NULL; 240 } 241 242 /******************************************************************************* 243 * 244 * Function bta_sys_hw_btm_cback 245 * 246 * Description This function is registered by BTA SYS to BTM in order to get 247 * status notifications 248 * 249 * 250 * Returns 251 * 252 ******************************************************************************/ 253 void bta_sys_hw_btm_cback(tBTM_DEV_STATUS status) { 254 tBTA_SYS_HW_MSG* sys_event = 255 (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG)); 256 257 APPL_TRACE_DEBUG("%s was called with parameter: %i", __func__, status); 258 259 /* send a message to BTA SYS */ 260 if (status == BTM_DEV_STATUS_UP) { 261 sys_event->hdr.event = BTA_SYS_EVT_STACK_ENABLED_EVT; 262 } else if (status == BTM_DEV_STATUS_DOWN) { 263 sys_event->hdr.event = BTA_SYS_ERROR_EVT; 264 } else { 265 /* BTM_DEV_STATUS_CMD_TOUT is ignored for now. */ 266 osi_free_and_reset((void**)&sys_event); 267 } 268 269 if (sys_event) bta_sys_sendmsg(sys_event); 270 } 271 272 /******************************************************************************* 273 * 274 * Function bta_sys_hw_error 275 * 276 * Description In case the HW device stops answering... Try to turn it off, 277 * then re-enable all 278 * previously active SW modules. 279 * 280 * Returns success or failure 281 * 282 ******************************************************************************/ 283 void bta_sys_hw_error(UNUSED_ATTR tBTA_SYS_HW_MSG* p_sys_hw_msg) { 284 uint8_t module_index; 285 286 APPL_TRACE_DEBUG("%s", __func__); 287 288 for (module_index = 0; module_index < BTA_SYS_MAX_HW_MODULES; 289 module_index++) { 290 if (bta_sys_cb.sys_hw_module_active & ((uint32_t)1 << module_index)) { 291 switch (module_index) { 292 case BTA_SYS_HW_BLUETOOTH: 293 /* Send BTA_SYS_HW_ERROR_EVT to DM */ 294 if (bta_sys_cb.sys_hw_cback[module_index] != NULL) 295 bta_sys_cb.sys_hw_cback[module_index](BTA_SYS_HW_ERROR_EVT); 296 break; 297 default: 298 /* not yet supported */ 299 break; 300 } 301 } 302 } 303 } 304 305 /******************************************************************************* 306 * 307 * Function bta_sys_hw_enable 308 * 309 * Description this function is called after API enable and HW has been 310 * turned on 311 * 312 * 313 * Returns success or failure 314 * 315 ******************************************************************************/ 316 317 void bta_sys_hw_api_enable(tBTA_SYS_HW_MSG* p_sys_hw_msg) { 318 if ((!bta_sys_cb.sys_hw_module_active) && 319 (bta_sys_cb.state != BTA_SYS_HW_ON)) { 320 /* register which HW module was turned on */ 321 bta_sys_cb.sys_hw_module_active |= ((uint32_t)1 << p_sys_hw_msg->hw_module); 322 323 tBTA_SYS_HW_MSG* p_msg = 324 (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG)); 325 p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT; 326 p_msg->hw_module = p_sys_hw_msg->hw_module; 327 328 bta_sys_sendmsg(p_msg); 329 } else { 330 /* register which HW module was turned on */ 331 bta_sys_cb.sys_hw_module_active |= ((uint32_t)1 << p_sys_hw_msg->hw_module); 332 333 /* HW already in use, so directly notify the caller */ 334 if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module] != NULL) 335 bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module](BTA_SYS_HW_ON_EVT); 336 } 337 338 APPL_TRACE_EVENT("bta_sys_hw_api_enable for %d, active modules 0x%04X", 339 p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active); 340 } 341 342 /******************************************************************************* 343 * 344 * Function bta_sys_hw_disable 345 * 346 * Description if no other module is using the HW, this function will call 347 * (if defined) a user-macro to turn off the HW 348 * 349 * 350 * Returns success or failure 351 * 352 ******************************************************************************/ 353 void bta_sys_hw_api_disable(tBTA_SYS_HW_MSG* p_sys_hw_msg) { 354 APPL_TRACE_DEBUG("bta_sys_hw_api_disable for %d, active modules: 0x%04X", 355 p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active); 356 357 /* make sure the related SW blocks were stopped */ 358 bta_sys_disable(p_sys_hw_msg->hw_module); 359 360 /* register which module we turn off */ 361 bta_sys_cb.sys_hw_module_active &= ~((uint32_t)1 << p_sys_hw_msg->hw_module); 362 363 /* if there are still some SW modules using the HW, just provide an answer to 364 * the calling */ 365 if (bta_sys_cb.sys_hw_module_active != 0) { 366 /* if there are still some SW modules using the HW, directly notify the 367 * caller */ 368 if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module] != NULL) 369 bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module](BTA_SYS_HW_OFF_EVT); 370 } else { 371 /* manually update the state of our system */ 372 bta_sys_cb.state = BTA_SYS_HW_STOPPING; 373 374 tBTA_SYS_HW_MSG* p_msg = 375 (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG)); 376 p_msg->hdr.event = BTA_SYS_EVT_DISABLED_EVT; 377 p_msg->hw_module = p_sys_hw_msg->hw_module; 378 379 bta_sys_sendmsg(p_msg); 380 } 381 } 382 383 /******************************************************************************* 384 * 385 * Function bta_sys_hw_event_enabled 386 * 387 * Description 388 * 389 * 390 * Returns success or failure 391 * 392 ******************************************************************************/ 393 void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG* p_sys_hw_msg) { 394 APPL_TRACE_EVENT("bta_sys_hw_evt_enabled for %i", p_sys_hw_msg->hw_module); 395 BTM_DeviceReset(NULL); 396 } 397 398 /******************************************************************************* 399 * 400 * Function bta_sys_hw_event_disabled 401 * 402 * Description 403 * 404 * 405 * Returns success or failure 406 * 407 ******************************************************************************/ 408 void bta_sys_hw_evt_disabled(tBTA_SYS_HW_MSG* p_sys_hw_msg) { 409 uint8_t hw_module_index; 410 411 APPL_TRACE_DEBUG("bta_sys_hw_evt_disabled - module 0x%X", 412 p_sys_hw_msg->hw_module); 413 414 for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; 415 hw_module_index++) { 416 if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) 417 bta_sys_cb.sys_hw_cback[hw_module_index](BTA_SYS_HW_OFF_EVT); 418 } 419 } 420 421 /******************************************************************************* 422 * 423 * Function bta_sys_hw_event_stack_enabled 424 * 425 * Description we receive this event once the SW side is ready (stack, FW 426 * download,... ), i.e. we can really start using the device. So 427 * notify the app. 428 * 429 * Returns success or failure 430 * 431 ******************************************************************************/ 432 void bta_sys_hw_evt_stack_enabled(UNUSED_ATTR tBTA_SYS_HW_MSG* p_sys_hw_msg) { 433 uint8_t hw_module_index; 434 435 APPL_TRACE_DEBUG(" bta_sys_hw_evt_stack_enabled!notify the callers"); 436 437 for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; 438 hw_module_index++) { 439 if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) 440 bta_sys_cb.sys_hw_cback[hw_module_index](BTA_SYS_HW_ON_EVT); 441 } 442 } 443 444 /******************************************************************************* 445 * 446 * Function bta_sys_event 447 * 448 * Description BTA event handler; called from task event handler. 449 * 450 * 451 * Returns void 452 * 453 ******************************************************************************/ 454 void bta_sys_event(BT_HDR* p_msg) { 455 uint8_t id; 456 bool freebuf = true; 457 458 APPL_TRACE_EVENT("%s: Event 0x%x", __func__, p_msg->event); 459 460 /* get subsystem id from event */ 461 id = (uint8_t)(p_msg->event >> 8); 462 463 /* verify id and call subsystem event handler */ 464 if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) { 465 freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg); 466 } else { 467 APPL_TRACE_WARNING("%s: Received unregistered event id %d", __func__, id); 468 } 469 470 if (freebuf) { 471 osi_free(p_msg); 472 } 473 } 474 475 /******************************************************************************* 476 * 477 * Function bta_sys_register 478 * 479 * Description Called by other BTA subsystems to register their event 480 * handler. 481 * 482 * 483 * Returns void 484 * 485 ******************************************************************************/ 486 void bta_sys_register(uint8_t id, const tBTA_SYS_REG* p_reg) { 487 bta_sys_cb.reg[id] = (tBTA_SYS_REG*)p_reg; 488 bta_sys_cb.is_reg[id] = true; 489 } 490 491 /******************************************************************************* 492 * 493 * Function bta_sys_deregister 494 * 495 * Description Called by other BTA subsystems to de-register 496 * handler. 497 * 498 * 499 * Returns void 500 * 501 ******************************************************************************/ 502 void bta_sys_deregister(uint8_t id) { bta_sys_cb.is_reg[id] = false; } 503 504 /******************************************************************************* 505 * 506 * Function bta_sys_is_register 507 * 508 * Description Called by other BTA subsystems to get registeration 509 * status. 510 * 511 * 512 * Returns void 513 * 514 ******************************************************************************/ 515 bool bta_sys_is_register(uint8_t id) { return bta_sys_cb.is_reg[id]; } 516 517 /******************************************************************************* 518 * 519 * Function bta_sys_sendmsg 520 * 521 * Description Send a GKI message to BTA. This function is designed to 522 * optimize sending of messages to BTA. It is called by BTA 523 * API functions and call-in functions. 524 * 525 * TODO (apanicke): Add location object as parameter for easier 526 * future debugging when doing alarm refactor 527 * 528 * 529 * Returns void 530 * 531 ******************************************************************************/ 532 void bta_sys_sendmsg(void* p_msg) { 533 base::MessageLoop* bta_message_loop = get_message_loop(); 534 535 if (!bta_message_loop || !bta_message_loop->task_runner().get()) { 536 APPL_TRACE_ERROR("%s: MessageLooper not initialized", __func__); 537 return; 538 } 539 540 bta_message_loop->task_runner()->PostTask( 541 FROM_HERE, base::Bind(&bta_sys_event, static_cast<BT_HDR*>(p_msg))); 542 } 543 544 /******************************************************************************* 545 * 546 * Function do_in_bta_thread 547 * 548 * Description Post a closure to be ran in the bta thread 549 * 550 * Returns BT_STATUS_SUCCESS on success 551 * 552 ******************************************************************************/ 553 bt_status_t do_in_bta_thread(const tracked_objects::Location& from_here, 554 const base::Closure& task) { 555 base::MessageLoop* bta_message_loop = get_message_loop(); 556 if (!bta_message_loop) { 557 APPL_TRACE_ERROR("%s: MessageLooper not initialized", __func__); 558 return BT_STATUS_FAIL; 559 } 560 561 scoped_refptr<base::SingleThreadTaskRunner> task_runner = 562 bta_message_loop->task_runner(); 563 if (!task_runner.get()) { 564 APPL_TRACE_ERROR("%s: task runner is dead", __func__); 565 return BT_STATUS_FAIL; 566 } 567 568 if (!task_runner->PostTask(from_here, task)) { 569 APPL_TRACE_ERROR("%s: Post task to task runner failed!", __func__); 570 return BT_STATUS_FAIL; 571 } 572 return BT_STATUS_SUCCESS; 573 } 574 575 /******************************************************************************* 576 * 577 * Function bta_sys_start_timer 578 * 579 * Description Start a protocol timer for the specified amount 580 * of time in milliseconds. 581 * 582 * Returns void 583 * 584 ******************************************************************************/ 585 void bta_sys_start_timer(alarm_t* alarm, period_ms_t interval, uint16_t event, 586 uint16_t layer_specific) { 587 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 588 589 p_buf->event = event; 590 p_buf->layer_specific = layer_specific; 591 592 alarm_set_on_mloop(alarm, interval, bta_sys_sendmsg, p_buf); 593 } 594 595 /******************************************************************************* 596 * 597 * Function bta_sys_disable 598 * 599 * Description For each registered subsystem execute its disable function. 600 * 601 * Returns void 602 * 603 ******************************************************************************/ 604 void bta_sys_disable(tBTA_SYS_HW_MODULE module) { 605 int bta_id = 0; 606 int bta_id_max = 0; 607 608 APPL_TRACE_DEBUG("bta_sys_disable: module %i", module); 609 610 switch (module) { 611 case BTA_SYS_HW_BLUETOOTH: 612 bta_id = BTA_ID_DM_SEARCH; 613 bta_id_max = BTA_ID_BLUETOOTH_MAX; 614 break; 615 default: 616 APPL_TRACE_WARNING("bta_sys_disable: unkown module"); 617 return; 618 } 619 620 for (; bta_id <= bta_id_max; bta_id++) { 621 if (bta_sys_cb.reg[bta_id] != NULL) { 622 if (bta_sys_cb.is_reg[bta_id] && 623 bta_sys_cb.reg[bta_id]->disable != NULL) { 624 (*bta_sys_cb.reg[bta_id]->disable)(); 625 } 626 } 627 } 628 } 629 630 /******************************************************************************* 631 * 632 * Function bta_sys_set_trace_level 633 * 634 * Description Set trace level for BTA 635 * 636 * Returns void 637 * 638 ******************************************************************************/ 639 void bta_sys_set_trace_level(uint8_t level) { appl_trace_level = level; } 640 641 /******************************************************************************* 642 * 643 * Function bta_sys_get_sys_features 644 * 645 * Description Returns sys_features to other BTA modules. 646 * 647 * Returns sys_features 648 * 649 ******************************************************************************/ 650 uint16_t bta_sys_get_sys_features(void) { return bta_sys_cb.sys_features; } 651