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