1 /******************************************************************************
3 * Copyright (C) 2003-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This is the main implementation file for the BTA system manager.
23 ******************************************************************************/
25 #define LOG_TAG "bt_bta_sys_main"
33 #include "bta_sys_int.h"
36 #include "osi/include/alarm.h"
37 #include "osi/include/fixed_queue.h"
38 #include "osi/include/hash_functions.h"
39 #include "osi/include/hash_map.h"
40 #include "osi/include/log.h"
41 #include "osi/include/osi.h"
42 #include "osi/include/thread.h"
45 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
46 #include "bta_ar_api.h"
49 /* system manager control block definition */
50 #if BTA_DYNAMIC_MEMORY == FALSE
51 tBTA_SYS_CB bta_sys_cb;
54 fixed_queue_t *btu_bta_alarm_queue;
55 static hash_map_t *bta_alarm_hash_map;
56 static const size_t BTA_ALARM_HASH_MAP_SIZE = 17;
57 static pthread_mutex_t bta_alarm_lock;
58 extern thread_t *bt_workqueue_thread;
61 /* TODO Bluedroid - Hard-coded trace levels - Needs to be configurable */
62 UINT8 appl_trace_level = BT_TRACE_LEVEL_WARNING; //APPL_INITIAL_TRACE_LEVEL;
63 UINT8 btif_trace_level = BT_TRACE_LEVEL_WARNING;
65 // Communication queue between btu_task and bta.
66 extern fixed_queue_t *btu_bta_msg_queue;
67 void btu_bta_alarm_ready(fixed_queue_t *queue, UNUSED_ATTR void *context);
69 static const tBTA_SYS_REG bta_sys_hw_reg =
76 /* type for action functions */
77 typedef void (*tBTA_SYS_ACTION)(tBTA_SYS_HW_MSG *p_data);
79 /* action function list */
80 const tBTA_SYS_ACTION bta_sys_action[] =
82 /* device manager local device API events - cf bta_sys.h for events */
83 bta_sys_hw_api_enable, /* 0 BTA_SYS_HW_API_ENABLE_EVT */
84 bta_sys_hw_evt_enabled, /* 1 BTA_SYS_HW_EVT_ENABLED_EVT */
85 bta_sys_hw_evt_stack_enabled, /* 2 BTA_SYS_HW_EVT_STACK_ENABLED_EVT */
86 bta_sys_hw_api_disable, /* 3 BTA_SYS_HW_API_DISABLE_EVT */
87 bta_sys_hw_evt_disabled, /* 4 BTA_SYS_HW_EVT_DISABLED_EVT */
88 bta_sys_hw_error /* 5 BTA_SYS_HW_ERROR_EVT */
91 /* state machine action enumeration list */
94 /* device manager local device API events */
95 BTA_SYS_HW_API_ENABLE,
96 BTA_SYS_HW_EVT_ENABLED,
97 BTA_SYS_HW_EVT_STACK_ENABLED,
98 BTA_SYS_HW_API_DISABLE,
99 BTA_SYS_HW_EVT_DISABLED,
103 #define BTA_SYS_NUM_ACTIONS (BTA_SYS_MAX_EVT & 0x00ff)
104 #define BTA_SYS_IGNORE BTA_SYS_NUM_ACTIONS
106 /* state table information */
107 #define BTA_SYS_ACTIONS 2 /* number of actions */
108 #define BTA_SYS_NEXT_STATE 2 /* position of next state */
109 #define BTA_SYS_NUM_COLS 3 /* number of columns in state tables */
112 /* state table for OFF state */
113 const UINT8 bta_sys_hw_off[][BTA_SYS_NUM_COLS] =
115 /* Event Action 1 Action 2 Next State */
116 /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
117 /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
118 /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
119 /* API_DISABLE */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
120 /* EVT_DISABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
121 /* EVT_ERROR */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}
124 const UINT8 bta_sys_hw_starting[][BTA_SYS_NUM_COLS] =
126 /* Event Action 1 Action 2 Next State */
127 /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* wait for completion event */
128 /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
129 /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
130 /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive disable/enable: change state wait for completion to disable */
131 /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_HW_API_ENABLE, BTA_SYS_HW_STARTING}, /* successive enable/disable: notify, then restart HW */
132 /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}
135 const UINT8 bta_sys_hw_on[][BTA_SYS_NUM_COLS] =
137 /* Event Action 1 Action 2 Next State */
138 /* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
139 /* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
140 /* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
141 /* 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 */
142 /* EVT_DISABLED */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
143 /* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}
146 const UINT8 bta_sys_hw_stopping[][BTA_SYS_NUM_COLS] =
148 /* Event Action 1 Action 2 Next State */
149 /* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* change state, and wait for completion event to enable */
150 /* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: finish the enable before disabling */
151 /* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_HW_API_DISABLE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: notify, then stop */
152 /* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* wait for completion event */
153 /* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
154 /* EVT_ERROR */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}
157 typedef const UINT8 (*tBTA_SYS_ST_TBL)[BTA_SYS_NUM_COLS];
160 const tBTA_SYS_ST_TBL bta_sys_st_tbl[] = {
167 /*******************************************************************************
169 ** Function bta_sys_init
171 ** Description BTA initialization; called from task initialization.
176 *******************************************************************************/
177 void bta_sys_init(void)
179 memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));
181 pthread_mutex_init(&bta_alarm_lock, NULL);
183 bta_alarm_hash_map = hash_map_new(BTA_ALARM_HASH_MAP_SIZE,
184 hash_function_pointer, NULL, (data_free_fn)alarm_free, NULL);
185 btu_bta_alarm_queue = fixed_queue_new(SIZE_MAX);
187 fixed_queue_register_dequeue(btu_bta_alarm_queue,
188 thread_get_reactor(bt_workqueue_thread),
192 appl_trace_level = APPL_INITIAL_TRACE_LEVEL;
194 /* register BTA SYS message handler */
195 bta_sys_register( BTA_ID_SYS, &bta_sys_hw_reg);
197 /* register for BTM notifications */
198 BTM_RegisterForDeviceStatusNotif ((tBTM_DEV_STATUS_CB*)&bta_sys_hw_btm_cback );
200 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
206 void bta_sys_free(void) {
207 fixed_queue_free(btu_bta_alarm_queue, NULL);
208 hash_map_free(bta_alarm_hash_map);
209 pthread_mutex_destroy(&bta_alarm_lock);
212 /*******************************************************************************
214 ** Function bta_dm_sm_execute
216 ** Description State machine event handling function for DM
221 *******************************************************************************/
222 BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg)
224 BOOLEAN freebuf = TRUE;
225 tBTA_SYS_ST_TBL state_table;
229 APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x", bta_sys_cb.state, p_msg->event);
231 /* look up the state table for the current state */
232 state_table = bta_sys_st_tbl[bta_sys_cb.state];
234 bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE];
236 /* execute action functions */
237 for (i = 0; i < BTA_SYS_ACTIONS; i++)
239 if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_SYS_IGNORE)
241 (*bta_sys_action[action])( (tBTA_SYS_HW_MSG*) p_msg);
253 void bta_sys_hw_register( tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK *cback)
255 bta_sys_cb.sys_hw_cback[module]=cback;
259 void bta_sys_hw_unregister( tBTA_SYS_HW_MODULE module )
261 bta_sys_cb.sys_hw_cback[module]=NULL;
264 /*******************************************************************************
266 ** Function bta_sys_hw_btm_cback
268 ** Description This function is registered by BTA SYS to BTM in order to get status notifications
273 *******************************************************************************/
274 void bta_sys_hw_btm_cback( tBTM_DEV_STATUS status )
277 tBTA_SYS_HW_MSG *sys_event;
279 APPL_TRACE_DEBUG(" bta_sys_hw_btm_cback was called with parameter: %i" , status );
281 /* send a message to BTA SYS */
282 if ((sys_event = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL)
284 if (status == BTM_DEV_STATUS_UP)
285 sys_event->hdr.event = BTA_SYS_EVT_STACK_ENABLED_EVT;
286 else if (status == BTM_DEV_STATUS_DOWN)
287 sys_event->hdr.event = BTA_SYS_ERROR_EVT;
290 /* BTM_DEV_STATUS_CMD_TOUT is ignored for now. */
291 GKI_freebuf (sys_event);
297 bta_sys_sendmsg(sys_event);
302 APPL_TRACE_DEBUG("ERROR bta_sys_hw_btm_cback couldn't send msg" );
308 /*******************************************************************************
310 ** Function bta_sys_hw_error
312 ** Description In case the HW device stops answering... Try to turn it off, then re-enable all
313 ** previously active SW modules.
315 ** Returns success or failure
317 *******************************************************************************/
318 void bta_sys_hw_error(tBTA_SYS_HW_MSG *p_sys_hw_msg)
321 UNUSED(p_sys_hw_msg);
323 APPL_TRACE_DEBUG("%s", __FUNCTION__);
325 for (module_index = 0; module_index < BTA_SYS_MAX_HW_MODULES; module_index++)
327 if( bta_sys_cb.sys_hw_module_active & ((UINT32)1 << module_index )) {
328 switch( module_index)
330 case BTA_SYS_HW_BLUETOOTH:
331 /* Send BTA_SYS_HW_ERROR_EVT to DM */
332 if (bta_sys_cb.sys_hw_cback[module_index] != NULL)
333 bta_sys_cb.sys_hw_cback[module_index] (BTA_SYS_HW_ERROR_EVT);
336 /* not yet supported */
345 /*******************************************************************************
347 ** Function bta_sys_hw_enable
349 ** Description this function is called after API enable and HW has been turned on
352 ** Returns success or failure
354 *******************************************************************************/
356 void bta_sys_hw_api_enable( tBTA_SYS_HW_MSG *p_sys_hw_msg )
358 if ((!bta_sys_cb.sys_hw_module_active) && (bta_sys_cb.state != BTA_SYS_HW_ON))
360 /* register which HW module was turned on */
361 bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module );
363 tBTA_SYS_HW_MSG *p_msg;
364 if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL)
366 p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT;
367 p_msg->hw_module = p_sys_hw_msg->hw_module;
369 bta_sys_sendmsg(p_msg);
374 /* register which HW module was turned on */
375 bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module );
377 /* HW already in use, so directly notify the caller */
378 if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]!= NULL )
379 bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]( BTA_SYS_HW_ON_EVT );
382 APPL_TRACE_EVENT ("bta_sys_hw_api_enable for %d, active modules 0x%04X",
383 p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active);
387 /*******************************************************************************
389 ** Function bta_sys_hw_disable
391 ** Description if no other module is using the HW, this function will call ( if defined ) a user-macro to turn off the HW
394 ** Returns success or failure
396 *******************************************************************************/
397 void bta_sys_hw_api_disable(tBTA_SYS_HW_MSG *p_sys_hw_msg)
399 APPL_TRACE_DEBUG("bta_sys_hw_api_disable for %d, active modules: 0x%04X",
400 p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active );
402 /* make sure the related SW blocks were stopped */
403 bta_sys_disable( p_sys_hw_msg->hw_module );
406 /* register which module we turn off */
407 bta_sys_cb.sys_hw_module_active &= ~((UINT32)1 << p_sys_hw_msg->hw_module );
410 /* if there are still some SW modules using the HW, just provide an answer to the calling */
411 if( bta_sys_cb.sys_hw_module_active != 0 )
413 /* if there are still some SW modules using the HW, directly notify the caller */
414 if( bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]!= NULL )
415 bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]( BTA_SYS_HW_OFF_EVT );
419 /* manually update the state of our system */
420 bta_sys_cb.state = BTA_SYS_HW_STOPPING;
422 tBTA_SYS_HW_MSG *p_msg;
423 if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL)
425 p_msg->hdr.event = BTA_SYS_EVT_DISABLED_EVT;
426 p_msg->hw_module = p_sys_hw_msg->hw_module;
428 bta_sys_sendmsg(p_msg);
435 /*******************************************************************************
437 ** Function bta_sys_hw_event_enabled
442 ** Returns success or failure
444 *******************************************************************************/
445 void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
447 APPL_TRACE_EVENT("bta_sys_hw_evt_enabled for %i", p_sys_hw_msg->hw_module);
448 BTM_DeviceReset( NULL );
452 /*******************************************************************************
454 ** Function bta_sys_hw_event_disabled
459 ** Returns success or failure
461 *******************************************************************************/
462 void bta_sys_hw_evt_disabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
464 UINT8 hw_module_index;
466 APPL_TRACE_DEBUG("bta_sys_hw_evt_disabled - module 0x%X", p_sys_hw_msg->hw_module);
468 for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++)
470 if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL)
471 bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_OFF_EVT);
475 /*******************************************************************************
477 ** Function bta_sys_hw_event_stack_enabled
479 ** Description we receive this event once the SW side is ready ( stack, FW download,... ),
480 ** i.e. we can really start using the device. So notify the app.
482 ** Returns success or failure
484 *******************************************************************************/
485 void bta_sys_hw_evt_stack_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
487 UINT8 hw_module_index;
488 UNUSED(p_sys_hw_msg);
490 APPL_TRACE_DEBUG(" bta_sys_hw_evt_stack_enabled!notify the callers");
492 for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++ )
494 if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL)
495 bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_ON_EVT);
502 /*******************************************************************************
504 ** Function bta_sys_event
506 ** Description BTA event handler; called from task event handler.
511 *******************************************************************************/
512 void bta_sys_event(BT_HDR *p_msg)
515 BOOLEAN freebuf = TRUE;
517 APPL_TRACE_EVENT("BTA got event 0x%x", p_msg->event);
519 /* get subsystem id from event */
520 id = (UINT8) (p_msg->event >> 8);
522 /* verify id and call subsystem event handler */
523 if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL))
525 freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
529 APPL_TRACE_WARNING("BTA got unregistered event id %d", id);
539 /*******************************************************************************
541 ** Function bta_sys_register
543 ** Description Called by other BTA subsystems to register their event
549 *******************************************************************************/
550 void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)
552 bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;
553 bta_sys_cb.is_reg[id] = TRUE;
556 /*******************************************************************************
558 ** Function bta_sys_deregister
560 ** Description Called by other BTA subsystems to de-register
566 *******************************************************************************/
567 void bta_sys_deregister(UINT8 id)
569 bta_sys_cb.is_reg[id] = FALSE;
572 /*******************************************************************************
574 ** Function bta_sys_is_register
576 ** Description Called by other BTA subsystems to get registeration
582 *******************************************************************************/
583 BOOLEAN bta_sys_is_register(UINT8 id)
585 return bta_sys_cb.is_reg[id];
588 /*******************************************************************************
590 ** Function bta_sys_sendmsg
592 ** Description Send a GKI message to BTA. This function is designed to
593 ** optimize sending of messages to BTA. It is called by BTA
594 ** API functions and call-in functions.
599 *******************************************************************************/
600 void bta_sys_sendmsg(void *p_msg)
602 // There is a race condition that occurs if the stack is shut down while
603 // there is a procedure in progress that can schedule a task via this
604 // message queue. This causes |btu_bta_msg_queue| to get cleaned up before
605 // it gets used here; hence we check for NULL before using it.
606 if (btu_bta_msg_queue)
607 fixed_queue_enqueue(btu_bta_msg_queue, p_msg);
610 /*******************************************************************************
612 ** Function bta_sys_start_timer
614 ** Description Start a protocol timer for the specified amount
615 ** of time in milliseconds.
619 *******************************************************************************/
620 void bta_alarm_cb(void *data) {
621 assert(data != NULL);
622 TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
624 fixed_queue_enqueue(btu_bta_alarm_queue, p_tle);
627 void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms) {
628 assert(p_tle != NULL);
630 // Get the alarm for this p_tle.
631 pthread_mutex_lock(&bta_alarm_lock);
632 if (!hash_map_has_key(bta_alarm_hash_map, p_tle)) {
633 hash_map_set(bta_alarm_hash_map, p_tle, alarm_new());
635 pthread_mutex_unlock(&bta_alarm_lock);
637 alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
639 LOG_ERROR(LOG_TAG, "%s unable to create alarm.", __func__);
644 p_tle->ticks = timeout_ms;
645 alarm_set(alarm, (period_ms_t)timeout_ms, bta_alarm_cb, p_tle);
648 bool hash_iter_ro_cb(hash_map_entry_t *hash_map_entry, void *context)
650 alarm_t *alarm = (alarm_t *)hash_map_entry->data;
651 period_ms_t *p_remaining_ms = (period_ms_t*)context;
652 *p_remaining_ms += alarm_get_remaining_ms(alarm);
656 UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle)
658 period_ms_t remaining_ms = 0;
659 pthread_mutex_lock(&bta_alarm_lock);
660 // Get the alarm for this p_tle
661 hash_map_foreach(bta_alarm_hash_map, hash_iter_ro_cb, &remaining_ms);
662 pthread_mutex_unlock(&bta_alarm_lock);
667 /*******************************************************************************
669 ** Function bta_sys_stop_timer
671 ** Description Stop a BTA timer.
675 *******************************************************************************/
676 void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle) {
677 assert(p_tle != NULL);
679 alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
681 LOG_DEBUG(LOG_TAG, "%s expected alarm was not in bta alarm hash map.", __func__);
687 /*******************************************************************************
689 ** Function bta_sys_disable
691 ** Description For each registered subsystem execute its disable function.
695 *******************************************************************************/
696 void bta_sys_disable(tBTA_SYS_HW_MODULE module)
701 APPL_TRACE_DEBUG("bta_sys_disable: module %i", module);
705 case BTA_SYS_HW_BLUETOOTH:
707 bta_id_max = BTA_ID_BLUETOOTH_MAX;
710 APPL_TRACE_WARNING("bta_sys_disable: unkown module");
714 for ( ; bta_id <= bta_id_max; bta_id++)
716 if (bta_sys_cb.reg[bta_id] != NULL)
718 if (bta_sys_cb.is_reg[bta_id] == TRUE && bta_sys_cb.reg[bta_id]->disable != NULL)
720 (*bta_sys_cb.reg[bta_id]->disable)();
726 /*******************************************************************************
728 ** Function bta_sys_set_trace_level
730 ** Description Set trace level for BTA
734 *******************************************************************************/
735 void bta_sys_set_trace_level(UINT8 level)
737 appl_trace_level = level;
740 /*******************************************************************************
742 ** Function bta_sys_get_sys_features
744 ** Description Returns sys_features to other BTA modules.
746 ** Returns sys_features
748 *******************************************************************************/
749 UINT16 bta_sys_get_sys_features (void)
751 return bta_sys_cb.sys_features;