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