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