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