123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- /******************************************************************************
- *
- * Copyright 2003-2012 Broadcom Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************/
- /******************************************************************************
- *
- * This is the main implementation file for the BTA system manager.
- *
- ******************************************************************************/
- #define LOG_TAG "bt_bta_sys_main"
- #include <base/bind.h>
- #include <base/logging.h>
- #include <string.h>
- #include "bt_common.h"
- #include "bta_api.h"
- #include "bta_sys.h"
- #include "bta_sys_int.h"
- #include "btm_api.h"
- #include "btu.h"
- #include "osi/include/alarm.h"
- #include "osi/include/fixed_queue.h"
- #include "osi/include/log.h"
- #include "osi/include/osi.h"
- #include "utl.h"
- #if (defined BTA_AR_INCLUDED) && (BTA_AR_INCLUDED == TRUE)
- #include "bta_ar_api.h"
- #endif
- /* system manager control block definition */
- tBTA_SYS_CB bta_sys_cb;
- /* trace level */
- /* TODO Hard-coded trace levels - Needs to be configurable */
- uint8_t appl_trace_level = BT_TRACE_LEVEL_WARNING; // APPL_INITIAL_TRACE_LEVEL;
- uint8_t btif_trace_level = BT_TRACE_LEVEL_WARNING;
- static const tBTA_SYS_REG bta_sys_hw_reg = {bta_sys_sm_execute, NULL};
- /* type for action functions */
- typedef void (*tBTA_SYS_ACTION)(tBTA_SYS_HW_MSG* p_data);
- /* action function list */
- const tBTA_SYS_ACTION bta_sys_action[] = {
- /* device manager local device API events - cf bta_sys.h for events */
- bta_sys_hw_api_enable, /* 0 BTA_SYS_HW_API_ENABLE_EVT */
- bta_sys_hw_evt_enabled, /* 1 BTA_SYS_HW_EVT_ENABLED_EVT */
- bta_sys_hw_evt_stack_enabled, /* 2 BTA_SYS_HW_EVT_STACK_ENABLED_EVT */
- bta_sys_hw_api_disable, /* 3 BTA_SYS_HW_API_DISABLE_EVT */
- bta_sys_hw_evt_disabled, /* 4 BTA_SYS_HW_EVT_DISABLED_EVT */
- bta_sys_hw_error /* 5 BTA_SYS_HW_ERROR_EVT */
- };
- /* state machine action enumeration list */
- enum {
- /* device manager local device API events */
- BTA_SYS_HW_API_ENABLE,
- BTA_SYS_HW_EVT_ENABLED,
- BTA_SYS_HW_EVT_STACK_ENABLED,
- BTA_SYS_HW_API_DISABLE,
- BTA_SYS_HW_EVT_DISABLED,
- BTA_SYS_HW_ERROR
- };
- #define BTA_SYS_NUM_ACTIONS (BTA_SYS_MAX_EVT & 0x00ff)
- #define BTA_SYS_IGNORE BTA_SYS_NUM_ACTIONS
- /* state table information */
- #define BTA_SYS_ACTIONS 2 /* number of actions */
- #define BTA_SYS_NEXT_STATE 2 /* position of next state */
- #define BTA_SYS_NUM_COLS 3 /* number of columns in state tables */
- /* state table for OFF state */
- const uint8_t bta_sys_hw_off[][BTA_SYS_NUM_COLS] = {
- /* Event Action 1 Action 2
- Next State */
- /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE,
- BTA_SYS_HW_STARTING},
- /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
- /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
- /* API_DISABLE */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE,
- BTA_SYS_HW_OFF},
- /* EVT_DISABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
- /* EVT_ERROR */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}};
- const uint8_t bta_sys_hw_starting[][BTA_SYS_NUM_COLS] = {
- /* Event Action 1 Action 2
- Next State */
- /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE,
- BTA_SYS_HW_STARTING}, /* wait for completion event */
- /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE,
- BTA_SYS_HW_STARTING},
- /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_IGNORE,
- BTA_SYS_HW_ON},
- /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE,
- BTA_SYS_HW_STOPPING}, /* successive disable/enable:
- change state wait for
- completion to disable */
- /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_HW_API_ENABLE,
- BTA_SYS_HW_STARTING}, /* successive enable/disable:
- notify, then restart HW */
- /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}};
- const uint8_t bta_sys_hw_on[][BTA_SYS_NUM_COLS] = {
- /* Event Action 1 Action 2
- Next State */
- /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
- /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
- /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
- /* 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 */
- /* EVT_DISABLED */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
- /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}};
- const uint8_t bta_sys_hw_stopping[][BTA_SYS_NUM_COLS] = {
- /* Event Action 1 Action 2
- Next State */
- /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE,
- BTA_SYS_HW_STARTING}, /* change state, and wait for
- completion event to enable */
- /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE,
- BTA_SYS_HW_STOPPING}, /* successive enable/disable:
- finish the enable before
- disabling */
- /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_HW_API_DISABLE,
- BTA_SYS_HW_STOPPING}, /* successive enable/disable:
- notify, then stop */
- /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE,
- BTA_SYS_HW_STOPPING}, /* wait for completion event */
- /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE,
- BTA_SYS_HW_OFF},
- /* EVT_ERROR */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE,
- BTA_SYS_HW_STOPPING}};
- typedef const uint8_t (*tBTA_SYS_ST_TBL)[BTA_SYS_NUM_COLS];
- /* state table */
- const tBTA_SYS_ST_TBL bta_sys_st_tbl[] = {
- bta_sys_hw_off, /* BTA_SYS_HW_OFF */
- bta_sys_hw_starting, /* BTA_SYS_HW_STARTING */
- bta_sys_hw_on, /* BTA_SYS_HW_ON */
- bta_sys_hw_stopping /* BTA_SYS_HW_STOPPING */
- };
- /*******************************************************************************
- *
- * Function bta_sys_init
- *
- * Description BTA initialization; called from task initialization.
- *
- *
- * Returns void
- *
- ******************************************************************************/
- void bta_sys_init(void) {
- memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));
- appl_trace_level = APPL_INITIAL_TRACE_LEVEL;
- /* register BTA SYS message handler */
- bta_sys_register(BTA_ID_SYS, &bta_sys_hw_reg);
- /* register for BTM notifications */
- BTM_RegisterForDeviceStatusNotif(&bta_sys_hw_btm_cback);
- #if (defined BTA_AR_INCLUDED) && (BTA_AR_INCLUDED == TRUE)
- bta_ar_init();
- #endif
- }
- void bta_sys_free(void) {
- }
- /*******************************************************************************
- *
- * Function bta_dm_sm_execute
- *
- * Description State machine event handling function for DM
- *
- *
- * Returns void
- *
- ******************************************************************************/
- bool bta_sys_sm_execute(BT_HDR* p_msg) {
- bool freebuf = true;
- tBTA_SYS_ST_TBL state_table;
- uint8_t action;
- int i;
- APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x", bta_sys_cb.state,
- p_msg->event);
- /* look up the state table for the current state */
- state_table = bta_sys_st_tbl[bta_sys_cb.state];
- /* update state */
- bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE];
- /* execute action functions */
- for (i = 0; i < BTA_SYS_ACTIONS; i++) {
- action = state_table[p_msg->event & 0x00ff][i];
- if (action != BTA_SYS_IGNORE) {
- (*bta_sys_action[action])((tBTA_SYS_HW_MSG*)p_msg);
- } else {
- break;
- }
- }
- return freebuf;
- }
- void bta_sys_hw_register(tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK* cback) {
- bta_sys_cb.sys_hw_cback[module] = cback;
- }
- void bta_sys_hw_unregister(tBTA_SYS_HW_MODULE module) {
- bta_sys_cb.sys_hw_cback[module] = NULL;
- }
- /*******************************************************************************
- *
- * Function bta_sys_hw_btm_cback
- *
- * Description This function is registered by BTA SYS to BTM in order to get
- * status notifications
- *
- *
- * Returns
- *
- ******************************************************************************/
- void bta_sys_hw_btm_cback(tBTM_DEV_STATUS status) {
- tBTA_SYS_HW_MSG* sys_event =
- (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
- APPL_TRACE_DEBUG("%s was called with parameter: %i", __func__, status);
- /* send a message to BTA SYS */
- if (status == BTM_DEV_STATUS_UP) {
- sys_event->hdr.event = BTA_SYS_EVT_STACK_ENABLED_EVT;
- } else if (status == BTM_DEV_STATUS_DOWN) {
- sys_event->hdr.event = BTA_SYS_ERROR_EVT;
- } else {
- /* BTM_DEV_STATUS_CMD_TOUT is ignored for now. */
- osi_free_and_reset((void**)&sys_event);
- }
- if (sys_event) bta_sys_sendmsg(sys_event);
- }
- /*******************************************************************************
- *
- * Function bta_sys_hw_error
- *
- * Description In case the HW device stops answering... Try to turn it off,
- * then re-enable all
- * previously active SW modules.
- *
- * Returns success or failure
- *
- ******************************************************************************/
- void bta_sys_hw_error(UNUSED_ATTR tBTA_SYS_HW_MSG* p_sys_hw_msg) {
- uint8_t module_index;
- APPL_TRACE_DEBUG("%s", __func__);
- for (module_index = 0; module_index < BTA_SYS_MAX_HW_MODULES;
- module_index++) {
- if (bta_sys_cb.sys_hw_module_active & ((uint32_t)1 << module_index)) {
- switch (module_index) {
- case BTA_SYS_HW_BLUETOOTH:
- /* Send BTA_SYS_HW_ERROR_EVT to DM */
- if (bta_sys_cb.sys_hw_cback[module_index] != NULL)
- bta_sys_cb.sys_hw_cback[module_index](BTA_SYS_HW_ERROR_EVT);
- break;
- default:
- /* not yet supported */
- break;
- }
- }
- }
- }
- /*******************************************************************************
- *
- * Function bta_sys_hw_enable
- *
- * Description this function is called after API enable and HW has been
- * turned on
- *
- *
- * Returns success or failure
- *
- ******************************************************************************/
- void bta_sys_hw_api_enable(tBTA_SYS_HW_MSG* p_sys_hw_msg) {
- if ((!bta_sys_cb.sys_hw_module_active) &&
- (bta_sys_cb.state != BTA_SYS_HW_ON)) {
- /* register which HW module was turned on */
- bta_sys_cb.sys_hw_module_active |= ((uint32_t)1 << p_sys_hw_msg->hw_module);
- tBTA_SYS_HW_MSG* p_msg =
- (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
- p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT;
- p_msg->hw_module = p_sys_hw_msg->hw_module;
- bta_sys_sendmsg(p_msg);
- } else {
- /* register which HW module was turned on */
- bta_sys_cb.sys_hw_module_active |= ((uint32_t)1 << p_sys_hw_msg->hw_module);
- /* HW already in use, so directly notify the caller */
- if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module] != NULL)
- bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module](BTA_SYS_HW_ON_EVT);
- }
- APPL_TRACE_EVENT("bta_sys_hw_api_enable for %d, active modules 0x%04X",
- p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active);
- }
- /*******************************************************************************
- *
- * Function bta_sys_hw_disable
- *
- * Description if no other module is using the HW, this function will call
- * (if defined) a user-macro to turn off the HW
- *
- *
- * Returns success or failure
- *
- ******************************************************************************/
- void bta_sys_hw_api_disable(tBTA_SYS_HW_MSG* p_sys_hw_msg) {
- APPL_TRACE_DEBUG("bta_sys_hw_api_disable for %d, active modules: 0x%04X",
- p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active);
- /* make sure the related SW blocks were stopped */
- bta_sys_disable(p_sys_hw_msg->hw_module);
- /* register which module we turn off */
- bta_sys_cb.sys_hw_module_active &= ~((uint32_t)1 << p_sys_hw_msg->hw_module);
- /* if there are still some SW modules using the HW, just provide an answer to
- * the calling */
- if (bta_sys_cb.sys_hw_module_active != 0) {
- /* if there are still some SW modules using the HW, directly notify the
- * caller */
- if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module] != NULL)
- bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module](BTA_SYS_HW_OFF_EVT);
- } else {
- /* manually update the state of our system */
- bta_sys_cb.state = BTA_SYS_HW_STOPPING;
- tBTA_SYS_HW_MSG* p_msg =
- (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
- p_msg->hdr.event = BTA_SYS_EVT_DISABLED_EVT;
- p_msg->hw_module = p_sys_hw_msg->hw_module;
- bta_sys_sendmsg(p_msg);
- }
- }
- /*******************************************************************************
- *
- * Function bta_sys_hw_event_enabled
- *
- * Description
- *
- *
- * Returns success or failure
- *
- ******************************************************************************/
- void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG* p_sys_hw_msg) {
- APPL_TRACE_EVENT("bta_sys_hw_evt_enabled for %i", p_sys_hw_msg->hw_module);
- BTM_DeviceReset(NULL);
- }
- /*******************************************************************************
- *
- * Function bta_sys_hw_event_disabled
- *
- * Description
- *
- *
- * Returns success or failure
- *
- ******************************************************************************/
- void bta_sys_hw_evt_disabled(tBTA_SYS_HW_MSG* p_sys_hw_msg) {
- uint8_t hw_module_index;
- APPL_TRACE_DEBUG("bta_sys_hw_evt_disabled - module 0x%X",
- p_sys_hw_msg->hw_module);
- for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES;
- hw_module_index++) {
- if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL)
- bta_sys_cb.sys_hw_cback[hw_module_index](BTA_SYS_HW_OFF_EVT);
- }
- }
- /*******************************************************************************
- *
- * Function bta_sys_hw_event_stack_enabled
- *
- * Description we receive this event once the SW side is ready (stack, FW
- * download,... ), i.e. we can really start using the device. So
- * notify the app.
- *
- * Returns success or failure
- *
- ******************************************************************************/
- void bta_sys_hw_evt_stack_enabled(UNUSED_ATTR tBTA_SYS_HW_MSG* p_sys_hw_msg) {
- uint8_t hw_module_index;
- APPL_TRACE_DEBUG(" bta_sys_hw_evt_stack_enabled!notify the callers");
- for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES;
- hw_module_index++) {
- if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL)
- bta_sys_cb.sys_hw_cback[hw_module_index](BTA_SYS_HW_ON_EVT);
- }
- }
- /*******************************************************************************
- *
- * Function bta_sys_event
- *
- * Description BTA event handler; called from task event handler.
- *
- *
- * Returns void
- *
- ******************************************************************************/
- void bta_sys_event(BT_HDR* p_msg) {
- uint8_t id;
- bool freebuf = true;
- APPL_TRACE_EVENT("%s: Event 0x%x", __func__, p_msg->event);
- /* get subsystem id from event */
- id = (uint8_t)(p_msg->event >> 8);
- /* verify id and call subsystem event handler */
- if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) {
- freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
- } else {
- APPL_TRACE_WARNING("%s: Received unregistered event id %d", __func__, id);
- }
- if (freebuf) {
- osi_free(p_msg);
- }
- }
- /*******************************************************************************
- *
- * Function bta_sys_register
- *
- * Description Called by other BTA subsystems to register their event
- * handler.
- *
- *
- * Returns void
- *
- ******************************************************************************/
- void bta_sys_register(uint8_t id, const tBTA_SYS_REG* p_reg) {
- bta_sys_cb.reg[id] = (tBTA_SYS_REG*)p_reg;
- bta_sys_cb.is_reg[id] = true;
- }
- /*******************************************************************************
- *
- * Function bta_sys_deregister
- *
- * Description Called by other BTA subsystems to de-register
- * handler.
- *
- *
- * Returns void
- *
- ******************************************************************************/
- void bta_sys_deregister(uint8_t id) { bta_sys_cb.is_reg[id] = false; }
- /*******************************************************************************
- *
- * Function bta_sys_is_register
- *
- * Description Called by other BTA subsystems to get registeration
- * status.
- *
- *
- * Returns void
- *
- ******************************************************************************/
- bool bta_sys_is_register(uint8_t id) { return bta_sys_cb.is_reg[id]; }
- /*******************************************************************************
- *
- * Function bta_sys_sendmsg
- *
- * Description Send a GKI message to BTA. This function is designed to
- * optimize sending of messages to BTA. It is called by BTA
- * API functions and call-in functions.
- *
- * TODO (apanicke): Add location object as parameter for easier
- * future debugging when doing alarm refactor
- *
- *
- * Returns void
- *
- ******************************************************************************/
- void bta_sys_sendmsg(void* p_msg) {
- if (do_in_main_thread(
- FROM_HERE, base::Bind(&bta_sys_event, static_cast<BT_HDR*>(p_msg))) !=
- BT_STATUS_SUCCESS) {
- LOG(ERROR) << __func__ << ": do_in_main_thread failed";
- }
- }
- /*******************************************************************************
- *
- * Function bta_sys_start_timer
- *
- * Description Start a protocol timer for the specified amount
- * of time in milliseconds.
- *
- * Returns void
- *
- ******************************************************************************/
- void bta_sys_start_timer(alarm_t* alarm, uint64_t interval_ms, uint16_t event,
- uint16_t layer_specific) {
- BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR));
- p_buf->event = event;
- p_buf->layer_specific = layer_specific;
- alarm_set_on_mloop(alarm, interval_ms, bta_sys_sendmsg, p_buf);
- }
- /*******************************************************************************
- *
- * Function bta_sys_disable
- *
- * Description For each registered subsystem execute its disable function.
- *
- * Returns void
- *
- ******************************************************************************/
- void bta_sys_disable(tBTA_SYS_HW_MODULE module) {
- int bta_id = 0;
- int bta_id_max = 0;
- APPL_TRACE_DEBUG("bta_sys_disable: module %i", module);
- switch (module) {
- case BTA_SYS_HW_BLUETOOTH:
- bta_id = BTA_ID_DM_SEARCH;
- bta_id_max = BTA_ID_BLUETOOTH_MAX;
- break;
- default:
- APPL_TRACE_WARNING("bta_sys_disable: unkown module");
- return;
- }
- for (; bta_id <= bta_id_max; bta_id++) {
- if (bta_sys_cb.reg[bta_id] != NULL) {
- if (bta_sys_cb.is_reg[bta_id] &&
- bta_sys_cb.reg[bta_id]->disable != NULL) {
- (*bta_sys_cb.reg[bta_id]->disable)();
- }
- }
- }
- }
- /*******************************************************************************
- *
- * Function bta_sys_set_trace_level
- *
- * Description Set trace level for BTA
- *
- * Returns void
- *
- ******************************************************************************/
- void bta_sys_set_trace_level(uint8_t level) { appl_trace_level = level; }
- /*******************************************************************************
- *
- * Function bta_sys_get_sys_features
- *
- * Description Returns sys_features to other BTA modules.
- *
- * Returns sys_features
- *
- ******************************************************************************/
- uint16_t bta_sys_get_sys_features(void) { return bta_sys_cb.sys_features; }
|