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