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