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