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 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 72 static void start_up_stack_async(void) { 73 thread_post(management_thread, event_start_up_stack, NULL); 74 } 75 76 static void shut_down_stack_async(void) { 77 thread_post(management_thread, event_shut_down_stack, NULL); 78 } 79 80 static void clean_up_stack_async(void) { 81 thread_post(management_thread, event_clean_up_stack, NULL); 82 } 83 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 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 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 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 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 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 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 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 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 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 226 const stack_manager_t *stack_manager_get_interface() { 227 ensure_manager_initialized(); 228 return &interface; 229 } 230 231 future_t *stack_manager_get_hack_future() { 232 return hack_future; 233 } 234