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