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