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