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 <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