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