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