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