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