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