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