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