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