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
39static 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)
43static bool stack_is_initialized;
44// If running, the stack is fully up and able to bluetooth.
45static bool stack_is_running;
46
47static void event_init_stack(void *context);
48static void event_start_up_stack(void *context);
49static void event_shut_down_stack(void *context);
50static void event_clean_up_stack(void *context);
51
52static void event_signal_stack_up(void *context);
53static void event_signal_stack_down(void *context);
54
55// Unvetted includes/imports, etc which should be removed or vetted in the future
56static future_t *hack_future;
57void bte_main_enable();
58void btif_thread_post(thread_fn func, void *context);
59// End unvetted section
60
61// Interface functions
62
63static 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
72static void start_up_stack_async(void) {
73  thread_post(management_thread, event_start_up_stack, NULL);
74}
75
76static void shut_down_stack_async(void) {
77  thread_post(management_thread, event_shut_down_stack, NULL);
78}
79
80static void clean_up_stack_async(void) {
81  thread_post(management_thread, event_clean_up_stack, NULL);
82}
83
84static bool get_stack_is_running(void) {
85  return stack_is_running;
86}
87
88// Internal functions
89
90// Synchronous function to initialize the stack
91static 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
109static 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
118static 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
145static 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
165static 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
173static 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
195static 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
202static void event_signal_stack_down(UNUSED_ATTR void *context) {
203  HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
204}
205
206static 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
217static 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
226const stack_manager_t *stack_manager_get_interface() {
227  ensure_manager_initialized();
228  return &interface;
229}
230
231future_t *stack_manager_get_hack_future() {
232  return hack_future;
233}
234