OSDN Git Service

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