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 "stack_manager.h"
22
23 #include <hardware/bluetooth.h>
24
25 #include "btcore/include/module.h"
26 #include "btcore/include/osi_module.h"
27 #include "btif_api.h"
28 #include "btif_common.h"
29 #include "common/message_loop_thread.h"
30 #include "device/include/controller.h"
31 #include "osi/include/log.h"
32 #include "osi/include/osi.h"
33 #include "osi/include/semaphore.h"
34
35 // Temp includes
36 #include "bt_utils.h"
37 #include "btif_config.h"
38 #include "btif_profile_queue.h"
39
40 using bluetooth::common::MessageLoopThread;
41
42 static MessageLoopThread management_thread("bt_stack_manager_thread");
43
44 // If initialized, any of the bluetooth API functions can be called.
45 // (e.g. turning logging on and off, enabling/disabling the stack, etc)
46 static bool stack_is_initialized;
47 // If running, the stack is fully up and able to bluetooth.
48 static bool stack_is_running;
49
50 static void event_init_stack(void* context);
51 static void event_start_up_stack(void* context);
52 static void event_shut_down_stack(void* context);
53 static void event_clean_up_stack(void* context);
54
55 static void event_signal_stack_up(void* context);
56 static void event_signal_stack_down(void* context);
57
58 // Unvetted includes/imports, etc which should be removed or vetted in the
59 // future
60 static future_t* hack_future;
61 // End unvetted section
62
63 // Interface functions
64
init_stack()65 static void init_stack() {
66 // This is a synchronous process. Post it to the thread though, so
67 // state modification only happens there. Using the thread to perform
68 // all stack operations ensures that the operations are done serially
69 // and do not overlap.
70 semaphore_t* semaphore = semaphore_new(0);
71 management_thread.DoInThread(FROM_HERE,
72 base::Bind(event_init_stack, semaphore));
73 semaphore_wait(semaphore);
74 semaphore_free(semaphore);
75 }
76
start_up_stack_async()77 static void start_up_stack_async() {
78 management_thread.DoInThread(FROM_HERE,
79 base::Bind(event_start_up_stack, nullptr));
80 }
81
shut_down_stack_async()82 static void shut_down_stack_async() {
83 management_thread.DoInThread(FROM_HERE,
84 base::Bind(event_shut_down_stack, nullptr));
85 }
86
clean_up_stack()87 static void clean_up_stack() {
88 // This is a synchronous process. Post it to the thread though, so
89 // state modification only happens there.
90 semaphore_t* semaphore = semaphore_new(0);
91 management_thread.DoInThread(FROM_HERE,
92 base::Bind(event_clean_up_stack, semaphore));
93 semaphore_wait(semaphore);
94 semaphore_free(semaphore);
95 management_thread.ShutDown();
96 }
97
get_stack_is_running()98 static bool get_stack_is_running() { return stack_is_running; }
99
100 // Internal functions
101
102 // Synchronous function to initialize the stack
event_init_stack(void * context)103 static void event_init_stack(void* context) {
104 semaphore_t* semaphore = (semaphore_t*)context;
105
106 LOG_INFO(LOG_TAG, "%s is initializing the stack", __func__);
107
108 if (stack_is_initialized) {
109 LOG_INFO(LOG_TAG, "%s found the stack already in initialized state",
110 __func__);
111 } else {
112 module_management_start();
113
114 module_init(get_module(OSI_MODULE));
115 module_init(get_module(BT_UTILS_MODULE));
116 module_init(get_module(BTIF_CONFIG_MODULE));
117 btif_init_bluetooth();
118
119 // stack init is synchronous, so no waiting necessary here
120 stack_is_initialized = true;
121 }
122
123 LOG_INFO(LOG_TAG, "%s finished", __func__);
124
125 if (semaphore) semaphore_post(semaphore);
126 }
127
ensure_stack_is_initialized()128 static void ensure_stack_is_initialized() {
129 if (!stack_is_initialized) {
130 LOG_WARN(LOG_TAG, "%s found the stack was uninitialized. Initializing now.",
131 __func__);
132 // No semaphore needed since we are calling it directly
133 event_init_stack(nullptr);
134 }
135 }
136
137 // Synchronous function to start up the stack
event_start_up_stack(UNUSED_ATTR void * context)138 static void event_start_up_stack(UNUSED_ATTR void* context) {
139 if (stack_is_running) {
140 LOG_INFO(LOG_TAG, "%s stack already brought up", __func__);
141 return;
142 }
143
144 ensure_stack_is_initialized();
145
146 LOG_INFO(LOG_TAG, "%s is bringing up the stack", __func__);
147 future_t* local_hack_future = future_new();
148 hack_future = local_hack_future;
149
150 // Include this for now to put btif config into a shutdown-able state
151 module_start_up(get_module(BTIF_CONFIG_MODULE));
152 bte_main_enable();
153
154 if (future_await(local_hack_future) != FUTURE_SUCCESS) {
155 LOG_ERROR(LOG_TAG, "%s failed to start up the stack", __func__);
156 stack_is_running = true; // So stack shutdown actually happens
157 event_shut_down_stack(nullptr);
158 return;
159 }
160
161 stack_is_running = true;
162 LOG_INFO(LOG_TAG, "%s finished", __func__);
163 do_in_jni_thread(FROM_HERE, base::Bind(event_signal_stack_up, nullptr));
164 }
165
166 // Synchronous function to shut down the stack
event_shut_down_stack(UNUSED_ATTR void * context)167 static void event_shut_down_stack(UNUSED_ATTR void* context) {
168 if (!stack_is_running) {
169 LOG_INFO(LOG_TAG, "%s stack is already brought down", __func__);
170 return;
171 }
172
173 LOG_INFO(LOG_TAG, "%s is bringing down the stack", __func__);
174 future_t* local_hack_future = future_new();
175 hack_future = local_hack_future;
176 stack_is_running = false;
177
178 btif_disable_bluetooth();
179 module_shut_down(get_module(BTIF_CONFIG_MODULE));
180
181 future_await(local_hack_future);
182 module_shut_down(get_module(CONTROLLER_MODULE)); // Doesn't do any work, just
183 // puts it in a restartable
184 // state
185
186 hack_future = future_new();
187 do_in_jni_thread(FROM_HERE, base::Bind(event_signal_stack_down, nullptr));
188 future_await(hack_future);
189 LOG_INFO(LOG_TAG, "%s finished", __func__);
190 }
191
ensure_stack_is_not_running()192 static void ensure_stack_is_not_running() {
193 if (stack_is_running) {
194 LOG_WARN(LOG_TAG,
195 "%s found the stack was still running. Bringing it down now.",
196 __func__);
197 event_shut_down_stack(nullptr);
198 }
199 }
200
201 // Synchronous function to clean up the stack
event_clean_up_stack(void * context)202 static void event_clean_up_stack(void* context) {
203 if (!stack_is_initialized) {
204 LOG_INFO(LOG_TAG, "%s found the stack already in a clean state", __func__);
205 goto cleanup;
206 }
207
208 ensure_stack_is_not_running();
209
210 LOG_INFO(LOG_TAG, "%s is cleaning up the stack", __func__);
211 stack_is_initialized = false;
212
213 btif_cleanup_bluetooth();
214 module_clean_up(get_module(BTIF_CONFIG_MODULE));
215 module_clean_up(get_module(BT_UTILS_MODULE));
216 module_clean_up(get_module(OSI_MODULE));
217 module_management_stop();
218 LOG_INFO(LOG_TAG, "%s finished", __func__);
219
220 cleanup:;
221 semaphore_t* semaphore = (semaphore_t*)context;
222 if (semaphore) semaphore_post(semaphore);
223 }
224
event_signal_stack_up(UNUSED_ATTR void * context)225 static void event_signal_stack_up(UNUSED_ATTR void* context) {
226 // Notify BTIF connect queue that we've brought up the stack. It's
227 // now time to dispatch all the pending profile connect requests.
228 btif_queue_connect_next();
229 HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);
230 }
231
event_signal_stack_down(UNUSED_ATTR void * context)232 static void event_signal_stack_down(UNUSED_ATTR void* context) {
233 HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
234 future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
235 }
236
ensure_manager_initialized()237 static void ensure_manager_initialized() {
238 if (management_thread.IsRunning()) return;
239
240 management_thread.StartUp();
241 if (!management_thread.IsRunning()) {
242 LOG_ERROR(LOG_TAG, "%s unable to start stack management thread", __func__);
243 return;
244 }
245 }
246
247 static const stack_manager_t interface = {init_stack, start_up_stack_async,
248 shut_down_stack_async, clean_up_stack,
249 get_stack_is_running};
250
stack_manager_get_interface()251 const stack_manager_t* stack_manager_get_interface() {
252 ensure_manager_initialized();
253 return &interface;
254 }
255
stack_manager_get_hack_future()256 future_t* stack_manager_get_hack_future() { return hack_future; }
257