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