• 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 "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