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