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 <cstring>
29
30 #include "bt_target.h" // Must be first to define build configuration
31
32 #include "bta/sys/bta_sys.h"
33 #include "bta/sys/bta_sys_int.h"
34 #include "include/hardware/bluetooth.h"
35 #include "osi/include/alarm.h"
36 #include "osi/include/allocator.h"
37 #include "osi/include/log.h"
38 #include "stack/include/bt_types.h"
39 #include "stack/include/btu.h" // do_in_main_thread
40
41 void BTIF_dm_on_hw_error();
42
43 /* system manager control block definition */
44 tBTA_SYS_CB bta_sys_cb;
45
46 /* trace level */
47 /* TODO Hard-coded trace levels - Needs to be configurable */
48 uint8_t appl_trace_level = APPL_INITIAL_TRACE_LEVEL;
49 uint8_t btif_trace_level = BT_TRACE_LEVEL_WARNING;
50
51 /*******************************************************************************
52 *
53 * Function bta_sys_init
54 *
55 * Description BTA initialization; called from task initialization.
56 *
57 *
58 * Returns void
59 *
60 ******************************************************************************/
bta_sys_init(void)61 void bta_sys_init(void) {
62 memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));
63 }
64
bta_set_forward_hw_failures(bool value)65 void bta_set_forward_hw_failures(bool value) {
66 bta_sys_cb.forward_hw_failures = value;
67 }
68
BTA_sys_signal_hw_error()69 void BTA_sys_signal_hw_error() {
70 if (bta_sys_cb.forward_hw_failures) {
71 BTIF_dm_on_hw_error();
72 }
73 }
74
75 /*******************************************************************************
76 *
77 * Function bta_sys_event
78 *
79 * Description BTA event handler; called from task event handler.
80 *
81 *
82 * Returns void
83 *
84 ******************************************************************************/
bta_sys_event(BT_HDR_RIGID * p_msg)85 static void bta_sys_event(BT_HDR_RIGID* p_msg) {
86 uint8_t id;
87 bool freebuf = true;
88
89 APPL_TRACE_EVENT("%s: Event 0x%x", __func__, p_msg->event);
90
91 /* get subsystem id from event */
92 id = (uint8_t)(p_msg->event >> 8);
93
94 /* verify id and call subsystem event handler */
95 if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) {
96 freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
97 } else {
98 LOG_INFO("Ignoring receipt of unregistered event id:%s",
99 BtaIdSysText(id).c_str());
100 }
101
102 if (freebuf) {
103 osi_free(p_msg);
104 }
105 }
106
107 /*******************************************************************************
108 *
109 * Function bta_sys_register
110 *
111 * Description Called by other BTA subsystems to register their event
112 * handler.
113 *
114 *
115 * Returns void
116 *
117 ******************************************************************************/
bta_sys_register(uint8_t id,const tBTA_SYS_REG * p_reg)118 void bta_sys_register(uint8_t id, const tBTA_SYS_REG* p_reg) {
119 bta_sys_cb.reg[id] = (tBTA_SYS_REG*)p_reg;
120 bta_sys_cb.is_reg[id] = true;
121 }
122
123 /*******************************************************************************
124 *
125 * Function bta_sys_deregister
126 *
127 * Description Called by other BTA subsystems to de-register
128 * handler.
129 *
130 *
131 * Returns void
132 *
133 ******************************************************************************/
bta_sys_deregister(uint8_t id)134 void bta_sys_deregister(uint8_t id) { bta_sys_cb.is_reg[id] = false; }
135
136 /*******************************************************************************
137 *
138 * Function bta_sys_is_register
139 *
140 * Description Called by other BTA subsystems to get registeration
141 * status.
142 *
143 *
144 * Returns void
145 *
146 ******************************************************************************/
bta_sys_is_register(uint8_t id)147 bool bta_sys_is_register(uint8_t id) { return bta_sys_cb.is_reg[id]; }
148
149 /*******************************************************************************
150 *
151 * Function bta_sys_sendmsg
152 *
153 * Description Send a GKI message to BTA. This function is designed to
154 * optimize sending of messages to BTA. It is called by BTA
155 * API functions and call-in functions.
156 *
157 * TODO (apanicke): Add location object as parameter for easier
158 * future debugging when doing alarm refactor
159 *
160 *
161 * Returns void
162 *
163 ******************************************************************************/
bta_sys_sendmsg(void * p_msg)164 void bta_sys_sendmsg(void* p_msg) {
165 if (do_in_main_thread(
166 FROM_HERE,
167 base::Bind(&bta_sys_event, static_cast<BT_HDR_RIGID*>(p_msg))) !=
168 BT_STATUS_SUCCESS) {
169 LOG(ERROR) << __func__ << ": do_in_main_thread failed";
170 }
171 }
172
bta_sys_sendmsg_delayed(void * p_msg,const base::TimeDelta & delay)173 void bta_sys_sendmsg_delayed(void* p_msg, const base::TimeDelta& delay) {
174 if (do_in_main_thread_delayed(
175 FROM_HERE,
176 base::Bind(&bta_sys_event, static_cast<BT_HDR_RIGID*>(p_msg)),
177 delay) != BT_STATUS_SUCCESS) {
178 LOG(ERROR) << __func__ << ": do_in_main_thread_delayed failed";
179 }
180 }
181
182 /*******************************************************************************
183 *
184 * Function bta_sys_start_timer
185 *
186 * Description Start a protocol timer for the specified amount
187 * of time in milliseconds.
188 *
189 * Returns void
190 *
191 ******************************************************************************/
bta_sys_start_timer(alarm_t * alarm,uint64_t interval_ms,uint16_t event,uint16_t layer_specific)192 void bta_sys_start_timer(alarm_t* alarm, uint64_t interval_ms, uint16_t event,
193 uint16_t layer_specific) {
194 BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID));
195
196 p_buf->event = event;
197 p_buf->layer_specific = layer_specific;
198
199 alarm_set_on_mloop(alarm, interval_ms, bta_sys_sendmsg, p_buf);
200 }
201
202 /*******************************************************************************
203 *
204 * Function bta_sys_disable
205 *
206 * Description For each registered subsystem execute its disable function.
207 *
208 * Returns void
209 *
210 ******************************************************************************/
bta_sys_disable()211 void bta_sys_disable() {
212 int bta_id = BTA_ID_DM_SEARCH;
213 int bta_id_max = BTA_ID_BLUETOOTH_MAX;
214
215 for (; bta_id <= bta_id_max; bta_id++) {
216 if (bta_sys_cb.reg[bta_id] != NULL) {
217 if (bta_sys_cb.is_reg[bta_id] &&
218 bta_sys_cb.reg[bta_id]->disable != NULL) {
219 (*bta_sys_cb.reg[bta_id]->disable)();
220 }
221 }
222 }
223 }
224