1 /******************************************************************************
2 *
3 * Copyright 2014 Google, Inc.
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 #define LOG_TAG "bt_stack_manager"
20
21 #include <bluetooth/log.h>
22 #include <com_android_bluetooth_flags.h>
23 #include <hardware/bluetooth.h>
24
25 #include <cstdlib>
26 #include <cstring>
27
28 #include "bta/include/bta_ras_api.h"
29 #include "btcore/include/module.h"
30 #include "btcore/include/osi_module.h"
31 #include "btif/include/stack_manager_t.h"
32 #include "btif_api.h"
33 #include "btif_common.h"
34 #include "common/message_loop_thread.h"
35 #include "core_callbacks.h"
36 #include "main/shim/shim.h"
37 #include "os/log.h"
38 #include "stack/include/acl_api.h"
39 #include "stack/include/btm_client_interface.h"
40 #include "stack/include/main_thread.h"
41
42 // Temp includes
43 #include "bta/sys/bta_sys.h"
44 #include "btif_config.h"
45 #include "btif_profile_queue.h"
46 #include "device/include/device_iot_config.h"
47 #include "internal_include/bt_target.h"
48 #include "stack/include/gatt_api.h"
49 #include "stack/include/l2c_api.h"
50 #include "stack/include/port_api.h"
51 #include "stack/sdp/sdpint.h"
52 #if (BNEP_INCLUDED == TRUE)
53 #include "stack/include/bnep_api.h"
54 #endif
55 #include "stack/include/gap_api.h"
56 #if (PAN_INCLUDED == TRUE)
57 #include "stack/include/pan_api.h"
58 #endif
59 #if (HID_HOST_INCLUDED == TRUE)
60 #include "stack/include/hidh_api.h"
61 #endif
62 #include "bta/dm/bta_dm_int.h"
63 #include "device/include/interop.h"
64 #include "internal_include/stack_config.h"
65 #include "rust/src/core/ffi/module.h"
66 #include "stack/btm/btm_ble_int.h"
67 #include "stack/include/smp_api.h"
68
69 #ifndef BT_STACK_CLEANUP_WAIT_MS
70 #define BT_STACK_CLEANUP_WAIT_MS 1000
71 #endif
72
73 // Validate or respond to various conditional compilation flags
74
75 // Once BTA_PAN_INCLUDED is no longer exposed via bt_target.h
76 // this check and error statement may be removed.
77 static_assert(
78 BTA_PAN_INCLUDED,
79 "#define BTA_PAN_INCLUDED preprocessor compilation flag is unsupported"
80 " Pan profile is always included in the bluetooth stack"
81 "*** Conditional Compilation Directive error");
82
83 // Once PAN_SUPPORTS_ROLE_NAP is no longer exposed via bt_target.h
84 // this check and error statement may be removed.
85 static_assert(
86 PAN_SUPPORTS_ROLE_NAP,
87 "#define PAN_SUPPORTS_ROLE_NAP preprocessor compilation flag is unsupported"
88 " Pan profile always supports network access point in the bluetooth stack"
89 "*** Conditional Compilation Directive error");
90
91 // Once PAN_SUPPORTS_ROLE_PANU is no longer exposed via bt_target.h
92 // this check and error statement may be removed.
93 static_assert(
94 PAN_SUPPORTS_ROLE_PANU,
95 "#define PAN_SUPPORTS_ROLE_PANU preprocessor compilation flag is "
96 "unsupported"
97 " Pan profile always supports user as a client in the bluetooth stack"
98 "*** Conditional Compilation Directive error");
99
100 // Once BTA_HH_INCLUDED is no longer exposed via bt_target.h
101 // this check and error statement may be removed.
102 static_assert(
103 BTA_HH_INCLUDED,
104 "#define BTA_HH_INCLUDED preprocessor compilation flag is "
105 "unsupported"
106 " Host interface device profile is always enabled in the bluetooth stack"
107 "*** Conditional Compilation Directive error");
108
109 void BTA_dm_on_hw_on();
110 void BTA_dm_on_hw_off();
111
112 using bluetooth::common::MessageLoopThread;
113 using namespace bluetooth;
114
115 static MessageLoopThread management_thread("bt_stack_manager_thread");
116
117 // If initialized, any of the bluetooth API functions can be called.
118 // (e.g. turning logging on and off, enabling/disabling the stack, etc)
119 static bool stack_is_initialized;
120 // If running, the stack is fully up and able to bluetooth.
121 static bool stack_is_running;
122
123 static void event_init_stack(std::promise<void> promise,
124 bluetooth::core::CoreInterface* interface);
125 static void event_start_up_stack(bluetooth::core::CoreInterface* interface,
126 ProfileStartCallback startProfiles,
127 ProfileStopCallback stopProfiles);
128 static void event_shut_down_stack(ProfileStopCallback stopProfiles);
129 static void event_clean_up_stack(std::promise<void> promise,
130 ProfileStopCallback stopProfiles);
131
132 static void event_signal_stack_up(void* context);
133 static void event_signal_stack_down(void* context);
134
135 static bluetooth::core::CoreInterface* interfaceToProfiles;
136
GetInterfaceToProfiles()137 bluetooth::core::CoreInterface* GetInterfaceToProfiles() {
138 return interfaceToProfiles;
139 }
140
141 // Unvetted includes/imports, etc which should be removed or vetted in the
142 // future
143 static future_t* hack_future;
144 // End unvetted section
145
146 // Interface functions
147
init_stack(bluetooth::core::CoreInterface * interface)148 static void init_stack(bluetooth::core::CoreInterface* interface) {
149 // This is a synchronous process. Post it to the thread though, so
150 // state modification only happens there. Using the thread to perform
151 // all stack operations ensures that the operations are done serially
152 // and do not overlap.
153 std::promise<void> promise;
154 auto future = promise.get_future();
155 management_thread.DoInThread(
156 FROM_HERE, base::BindOnce(event_init_stack, std::move(promise),
157 base::Unretained(interface)));
158 future.wait();
159 }
160
start_up_stack_async(bluetooth::core::CoreInterface * interface,ProfileStartCallback startProfiles,ProfileStopCallback stopProfiles)161 static void start_up_stack_async(bluetooth::core::CoreInterface* interface,
162 ProfileStartCallback startProfiles,
163 ProfileStopCallback stopProfiles) {
164 management_thread.DoInThread(
165 FROM_HERE, base::BindOnce(event_start_up_stack, interface, startProfiles,
166 stopProfiles));
167 }
168
shut_down_stack_async(ProfileStopCallback stopProfiles)169 static void shut_down_stack_async(ProfileStopCallback stopProfiles) {
170 management_thread.DoInThread(
171 FROM_HERE, base::BindOnce(event_shut_down_stack, stopProfiles));
172 }
173
clean_up_stack(ProfileStopCallback stopProfiles)174 static void clean_up_stack(ProfileStopCallback stopProfiles) {
175 // This is a synchronous process. Post it to the thread though, so
176 // state modification only happens there.
177 std::promise<void> promise;
178 auto future = promise.get_future();
179 management_thread.DoInThread(
180 FROM_HERE,
181 base::BindOnce(event_clean_up_stack, std::move(promise), stopProfiles));
182
183 auto status =
184 future.wait_for(std::chrono::milliseconds(BT_STACK_CLEANUP_WAIT_MS));
185 if (status == std::future_status::ready) {
186 management_thread.ShutDown();
187 } else {
188 log::error("cleanup could not be completed in time, abandon it");
189 }
190 }
191
get_stack_is_running()192 static bool get_stack_is_running() { return stack_is_running; }
193
194 // Internal functions
195 extern const module_t bt_utils_module;
196 extern const module_t btif_config_module;
197 extern const module_t gd_shim_module;
198 extern const module_t interop_module;
199 extern const module_t osi_module;
200 extern const module_t rust_module;
201 extern const module_t stack_config_module;
202 extern const module_t device_iot_config_module;
203
204 struct module_lookup {
205 const char* name;
206 const module_t* module;
207 };
208
209 const struct module_lookup module_table[] = {
210 {BTIF_CONFIG_MODULE, &btif_config_module},
211 {GD_SHIM_MODULE, &gd_shim_module},
212 {INTEROP_MODULE, &interop_module},
213 {OSI_MODULE, &osi_module},
214 {RUST_MODULE, &rust_module},
215 {STACK_CONFIG_MODULE, &stack_config_module},
216 {DEVICE_IOT_CONFIG_MODULE, &device_iot_config_module},
217 {NULL, NULL},
218 };
219
get_local_module(const char * name)220 inline const module_t* get_local_module(const char* name) {
221 size_t len = strlen(name);
222
223 for (const struct module_lookup* l = module_table; l->module; l++) {
224 if (strncmp(l->name, name, len) == 0) {
225 return l->module;
226 }
227 }
228
229 log::fatal("Cannot find module {}, aborting", name);
230 return nullptr;
231 }
232
init_stack_internal(bluetooth::core::CoreInterface * interface)233 static void init_stack_internal(bluetooth::core::CoreInterface* interface) {
234 // all callbacks out of libbluetooth-core happen via this interface
235 interfaceToProfiles = interface;
236
237 module_management_start();
238
239 main_thread_start_up();
240
241 module_init(get_local_module(DEVICE_IOT_CONFIG_MODULE));
242 module_init(get_local_module(OSI_MODULE));
243 module_start_up(get_local_module(GD_SHIM_MODULE));
244 module_init(get_local_module(BTIF_CONFIG_MODULE));
245 btif_init_bluetooth();
246
247 module_init(get_local_module(INTEROP_MODULE));
248 module_init(get_local_module(STACK_CONFIG_MODULE));
249
250 // stack init is synchronous, so no waiting necessary here
251 stack_is_initialized = true;
252 }
253
254 // Synchronous function to initialize the stack
event_init_stack(std::promise<void> promise,bluetooth::core::CoreInterface * interface)255 static void event_init_stack(std::promise<void> promise,
256 bluetooth::core::CoreInterface* interface) {
257 log::info("is initializing the stack");
258
259 if (stack_is_initialized) {
260 log::info("found the stack already in initialized state");
261 } else {
262 init_stack_internal(interface);
263 }
264
265 log::info("finished");
266
267 promise.set_value();
268 }
269
ensure_stack_is_initialized(bluetooth::core::CoreInterface * interface)270 static void ensure_stack_is_initialized(
271 bluetooth::core::CoreInterface* interface) {
272 if (!stack_is_initialized) {
273 log::warn("found the stack was uninitialized. Initializing now.");
274 // No future needed since we are calling it directly
275 init_stack_internal(interface);
276 }
277 }
278
279 // Synchronous function to start up the stack
event_start_up_stack(bluetooth::core::CoreInterface * interface,ProfileStartCallback startProfiles,ProfileStopCallback stopProfiles)280 static void event_start_up_stack(bluetooth::core::CoreInterface* interface,
281 ProfileStartCallback startProfiles,
282 ProfileStopCallback stopProfiles) {
283 if (stack_is_running) {
284 log::info("stack already brought up");
285 return;
286 }
287
288 ensure_stack_is_initialized(interface);
289
290 log::info("is bringing up the stack");
291 future_t* local_hack_future = future_new();
292 hack_future = local_hack_future;
293
294 log::info("Gd shim module enabled");
295 get_btm_client_interface().lifecycle.btm_init();
296 module_start_up(get_local_module(BTIF_CONFIG_MODULE));
297
298 l2c_init();
299 sdp_init();
300 gatt_init();
301 SMP_Init(get_btm_client_interface().security.BTM_GetSecurityMode());
302 get_btm_client_interface().lifecycle.btm_ble_init();
303
304 RFCOMM_Init();
305 GAP_Init();
306
307 startProfiles();
308
309 bta_sys_init();
310
311 btif_init_ok();
312 BTA_dm_init();
313 bta_dm_enable(btif_dm_sec_evt, btif_dm_acl_evt);
314
315 btm_acl_device_down();
316 BTM_reset_complete();
317
318 BTA_dm_on_hw_on();
319
320 if (future_await(local_hack_future) != FUTURE_SUCCESS) {
321 log::error("failed to start up the stack");
322 stack_is_running = true; // So stack shutdown actually happens
323 event_shut_down_stack(stopProfiles);
324 return;
325 }
326
327 module_start_up(get_local_module(RUST_MODULE));
328 if (com::android::bluetooth::flags::channel_sounding_in_stack()) {
329 bluetooth::ras::GetRasServer()->Initialize();
330 bluetooth::ras::GetRasClient()->Initialize();
331 }
332
333 stack_is_running = true;
334 log::info("finished");
335 do_in_jni_thread(base::BindOnce(event_signal_stack_up, nullptr));
336 }
337
338 // Synchronous function to shut down the stack
event_shut_down_stack(ProfileStopCallback stopProfiles)339 static void event_shut_down_stack(ProfileStopCallback stopProfiles) {
340 if (!stack_is_running) {
341 log::info("stack is already brought down");
342 return;
343 }
344
345 log::info("is bringing down the stack");
346 future_t* local_hack_future = future_new();
347 hack_future = local_hack_future;
348 stack_is_running = false;
349
350 module_shut_down(get_local_module(RUST_MODULE));
351
352 do_in_main_thread(FROM_HERE, base::BindOnce(&btm_ble_scanner_cleanup));
353
354 btif_dm_on_disable();
355 stopProfiles();
356
357 do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_disable));
358
359 btif_dm_cleanup();
360
361 future_await(local_hack_future);
362 local_hack_future = future_new();
363 hack_future = local_hack_future;
364
365 bta_sys_disable();
366 BTA_dm_on_hw_off();
367
368 module_shut_down(get_local_module(BTIF_CONFIG_MODULE));
369 module_shut_down(get_local_module(DEVICE_IOT_CONFIG_MODULE));
370
371 future_await(local_hack_future);
372
373 gatt_free();
374 sdp_free();
375 l2c_free();
376 get_btm_client_interface().lifecycle.btm_ble_free();
377
378 get_btm_client_interface().lifecycle.btm_free();
379
380 hack_future = future_new();
381 do_in_jni_thread(base::BindOnce(event_signal_stack_down, nullptr));
382 future_await(hack_future);
383 log::info("finished");
384 }
385
ensure_stack_is_not_running(ProfileStopCallback stopProfiles)386 static void ensure_stack_is_not_running(ProfileStopCallback stopProfiles) {
387 if (stack_is_running) {
388 log::warn("found the stack was still running. Bringing it down now.");
389 event_shut_down_stack(stopProfiles);
390 }
391 }
392
393 // Synchronous function to clean up the stack
event_clean_up_stack(std::promise<void> promise,ProfileStopCallback stopProfiles)394 static void event_clean_up_stack(std::promise<void> promise,
395 ProfileStopCallback stopProfiles) {
396 if (!stack_is_initialized) {
397 log::info("found the stack already in a clean state");
398 goto cleanup;
399 }
400
401 ensure_stack_is_not_running(stopProfiles);
402
403 log::info("is cleaning up the stack");
404 stack_is_initialized = false;
405
406 btif_cleanup_bluetooth();
407
408 module_clean_up(get_local_module(STACK_CONFIG_MODULE));
409 module_clean_up(get_local_module(INTEROP_MODULE));
410
411 module_clean_up(get_local_module(BTIF_CONFIG_MODULE));
412 module_clean_up(get_local_module(DEVICE_IOT_CONFIG_MODULE));
413
414 module_clean_up(get_local_module(OSI_MODULE));
415 log::info("Gd shim module disabled");
416 module_shut_down(get_local_module(GD_SHIM_MODULE));
417
418 main_thread_shut_down();
419
420 module_management_stop();
421 log::info("finished");
422
423 cleanup:;
424 promise.set_value();
425 }
426
event_signal_stack_up(void *)427 static void event_signal_stack_up(void* /* context */) {
428 // Notify BTIF connect queue that we've brought up the stack. It's
429 // now time to dispatch all the pending profile connect requests.
430 btif_queue_connect_next();
431 GetInterfaceToProfiles()->events->invoke_adapter_state_changed_cb(
432 BT_STATE_ON);
433 }
434
event_signal_stack_down(void *)435 static void event_signal_stack_down(void* /* context */) {
436 GetInterfaceToProfiles()->events->invoke_adapter_state_changed_cb(
437 BT_STATE_OFF);
438 future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
439 }
440
ensure_manager_initialized()441 static void ensure_manager_initialized() {
442 if (management_thread.IsRunning()) return;
443
444 management_thread.StartUp();
445 if (!management_thread.IsRunning()) {
446 log::error("unable to start stack management thread");
447 return;
448 }
449 }
450
451 static const stack_manager_t interface = {init_stack, start_up_stack_async,
452 shut_down_stack_async, clean_up_stack,
453 get_stack_is_running};
454
stack_manager_get_interface()455 const stack_manager_t* stack_manager_get_interface() {
456 ensure_manager_initialized();
457 return &interface;
458 }
459
stack_manager_get_hack_future()460 future_t* stack_manager_get_hack_future() { return hack_future; }
461
462 namespace bluetooth {
463 namespace legacy {
464 namespace testing {
465
set_interface_to_profiles(bluetooth::core::CoreInterface * interfaceToProfiles)466 void set_interface_to_profiles(
467 bluetooth::core::CoreInterface* interfaceToProfiles) {
468 ::interfaceToProfiles = interfaceToProfiles;
469 }
470
471 } // namespace testing
472 } // namespace legacy
473 } // namespace bluetooth
474