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