stack_manager.cc revision 49120dc867c7818511b5afec461dfc97d17eef58
18df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson/******************************************************************************
28df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *
38df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  Copyright (C) 2014 Google, Inc.
48df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *
58df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  Licensed under the Apache License, Version 2.0 (the "License");
68df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  you may not use this file except in compliance with the License.
78df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  You may obtain a copy of the License at:
88df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *
98df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  http://www.apache.org/licenses/LICENSE-2.0
108df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *
118df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  Unless required by applicable law or agreed to in writing, software
128df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  distributed under the License is distributed on an "AS IS" BASIS,
138df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  See the License for the specific language governing permissions and
158df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *  limitations under the License.
168df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson *
178df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ******************************************************************************/
188df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1949120dc867c7818511b5afec461dfc97d17eef58Marie Janssen#define LOG_TAG "bt_stack_manager"
2049120dc867c7818511b5afec461dfc97d17eef58Marie Janssen
218df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include <hardware/bluetooth.h>
228df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
23db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "btcore/include/module.h"
24db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "btcore/include/osi_module.h"
258df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include "btif_api.h"
261924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson#include "btif_common.h"
2779ecab5d0418fde77e9afcdd451bd713af73e180Chris Manton#include "device/include/controller.h"
2844802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h"
29db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "osi/include/osi.h"
300f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/semaphore.h"
310f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/thread.h"
32db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "stack_manager.h"
338df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
349b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson// Temp includes
359b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson#include "btif_config.h"
36eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati#include "btif_profile_queue.h"
3796363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson#include "bt_utils.h"
389b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson
398df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic thread_t *management_thread;
408df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
418df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// If initialized, any of the bluetooth API functions can be called.
428df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// (e.g. turning logging on and off, enabling/disabling the stack, etc)
438df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic bool stack_is_initialized;
448df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// If running, the stack is fully up and able to bluetooth.
458df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic bool stack_is_running;
468df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
478df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_init_stack(void *context);
488df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_start_up_stack(void *context);
498df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_shut_down_stack(void *context);
508df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_clean_up_stack(void *context);
518df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
52efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonstatic void event_signal_stack_up(void *context);
53efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonstatic void event_signal_stack_down(void *context);
54efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson
55f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson// Unvetted includes/imports, etc which should be removed or vetted in the future
568ea8188a481504641fc6a72087704eb808d0bd87Zach Johnsonstatic future_t *hack_future;
57f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnsonvoid bte_main_enable();
58efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonvoid btif_thread_post(thread_fn func, void *context);
59f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson// End unvetted section
608ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson
618df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Interface functions
628df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
638df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void init_stack(void) {
648df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  // This is a synchronous process. Post it to the thread though, so
658df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  // state modification only happens there.
668df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  semaphore_t *semaphore = semaphore_new(0);
678df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  thread_post(management_thread, event_init_stack, semaphore);
688df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  semaphore_wait(semaphore);
69f5153bf62b6cee3f3c740504e94360130c3a9186Sharvil Nanavati  semaphore_free(semaphore);
708df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
718df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
728df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void start_up_stack_async(void) {
738df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  thread_post(management_thread, event_start_up_stack, NULL);
748df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
758df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
768df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void shut_down_stack_async(void) {
778df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  thread_post(management_thread, event_shut_down_stack, NULL);
788df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
798df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
808df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void clean_up_stack_async(void) {
818df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  thread_post(management_thread, event_clean_up_stack, NULL);
828df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
838df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
84f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnsonstatic bool get_stack_is_running(void) {
85f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson  return stack_is_running;
86f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson}
87f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson
888df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Internal functions
898df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
908df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to initialize the stack
918df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_init_stack(void *context) {
928df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  semaphore_t *semaphore = (semaphore_t *)context;
938df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
948df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  if (!stack_is_initialized) {
9572f308ee6d3983ae2c0d67be3de2451f2dd72dcbZach Johnson    module_management_start();
9672f308ee6d3983ae2c0d67be3de2451f2dd72dcbZach Johnson
9796363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson    module_init(get_module(BT_UTILS_MODULE));
989b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson    module_init(get_module(BTIF_CONFIG_MODULE));
998df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    btif_init_bluetooth();
1008df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1018df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    // stack init is synchronous, so no waiting necessary here
1028df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    stack_is_initialized = true;
1038df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  }
1048df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1058df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  if (semaphore)
1068df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    semaphore_post(semaphore);
1078df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
1088df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1098df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_stack_is_initialized(void) {
1108df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  if (!stack_is_initialized) {
111db554581079863974af8e1289646f5deea6fc044Marie Janssen    LOG_WARN(LOG_TAG, "%s found the stack was uninitialized. Initializing now.", __func__);
1128df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    // No semaphore needed since we are calling it directly
1138df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    event_init_stack(NULL);
1148df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  }
1158df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
1168df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1178df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to start up the stack
1188df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_start_up_stack(UNUSED_ATTR void *context) {
1198df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  if (stack_is_running) {
120db554581079863974af8e1289646f5deea6fc044Marie Janssen    LOG_DEBUG(LOG_TAG, "%s stack already brought up.", __func__);
1218df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    return;
1228df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  }
1238df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1248df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  ensure_stack_is_initialized();
1258df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
126db554581079863974af8e1289646f5deea6fc044Marie Janssen  LOG_DEBUG(LOG_TAG, "%s is bringing up the stack.", __func__);
1278ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson  hack_future = future_new();
1288ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson
1299b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  // Include this for now to put btif config into a shutdown-able state
1309b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  module_start_up(get_module(BTIF_CONFIG_MODULE));
131f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson  bte_main_enable();
1328ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson
1331924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson  if (future_await(hack_future) != FUTURE_SUCCESS) {
134efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson    stack_is_running = true; // So stack shutdown actually happens
1351924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson    event_shut_down_stack(NULL);
1361924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson    return;
1371924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson  }
1381924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson
1391924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson  stack_is_running = true;
140db554581079863974af8e1289646f5deea6fc044Marie Janssen  LOG_DEBUG(LOG_TAG, "%s finished", __func__);
141efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson  btif_thread_post(event_signal_stack_up, NULL);
1428df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
1438df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1448df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to shut down the stack
1458df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_shut_down_stack(UNUSED_ATTR void *context) {
1468df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  if (!stack_is_running) {
147db554581079863974af8e1289646f5deea6fc044Marie Janssen    LOG_DEBUG(LOG_TAG, "%s stack is already brought down.", __func__);
1488df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    return;
1498df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  }
1508df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
151db554581079863974af8e1289646f5deea6fc044Marie Janssen  LOG_DEBUG(LOG_TAG, "%s is bringing down the stack.", __func__);
1528ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson  hack_future = future_new();
1538df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  stack_is_running = false;
1548ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson
1558ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson  btif_disable_bluetooth();
1569b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  module_shut_down(get_module(BTIF_CONFIG_MODULE));
1578ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson
1588ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson  future_await(hack_future);
15930e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson  module_shut_down(get_module(CONTROLLER_MODULE)); // Doesn't do any work, just puts it in a restartable state
160cae219fe70124f1fc39cd7a78c239c4870422d5dAndre Eisenbach
161db554581079863974af8e1289646f5deea6fc044Marie Janssen  LOG_DEBUG(LOG_TAG, "%s finished.", __func__);
162efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson  btif_thread_post(event_signal_stack_down, NULL);
1638df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
1648df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1658df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_stack_is_not_running(void) {
1668df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  if (stack_is_running) {
167db554581079863974af8e1289646f5deea6fc044Marie Janssen    LOG_WARN(LOG_TAG, "%s found the stack was still running. Bringing it down now.", __func__);
1688df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    event_shut_down_stack(NULL);
1698df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  }
1708df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
1718df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1728df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to clean up the stack
1738df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_clean_up_stack(UNUSED_ATTR void *context) {
1748df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  if (!stack_is_initialized) {
175db554581079863974af8e1289646f5deea6fc044Marie Janssen    LOG_DEBUG(LOG_TAG, "%s found the stack already in a clean state.", __func__);
1768df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    return;
1778df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  }
1788df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
1798df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  ensure_stack_is_not_running();
1808df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
181db554581079863974af8e1289646f5deea6fc044Marie Janssen  LOG_DEBUG(LOG_TAG, "%s is cleaning up the stack.", __func__);
1828ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson  hack_future = future_new();
1838df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  stack_is_initialized = false;
1848ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson
1858ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson  btif_shutdown_bluetooth();
1869b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson  module_clean_up(get_module(BTIF_CONFIG_MODULE));
18796363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson  module_clean_up(get_module(BT_UTILS_MODULE));
1888ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson
1898ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson  future_await(hack_future);
1900933b4075e16589a073e85d8230677238b29b780Pavlin Radoslavov  module_clean_up(get_module(OSI_MODULE));
1918675d884479deca722ef5d7776a165241457dd75Zach Johnson  module_management_stop();
192db554581079863974af8e1289646f5deea6fc044Marie Janssen  LOG_DEBUG(LOG_TAG, "%s finished.", __func__);
1938df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
1948df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
195efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonstatic void event_signal_stack_up(UNUSED_ATTR void *context) {
196eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati  // Notify BTIF connect queue that we've brought up the stack. It's
197eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati  // now time to dispatch all the pending profile connect requests.
198eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati  btif_queue_connect_next();
199efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson  HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);
200efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson}
201efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson
202efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonstatic void event_signal_stack_down(UNUSED_ATTR void *context) {
203efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson  HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
204efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson}
205efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson
2068df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_manager_initialized(void) {
2078df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  if (management_thread)
2088df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    return;
2098df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
2108df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  management_thread = thread_new("stack_manager");
2118df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  if (!management_thread) {
212db554581079863974af8e1289646f5deea6fc044Marie Janssen    LOG_ERROR(LOG_TAG, "%s unable to create stack management thread.", __func__);
2138df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson    return;
2148df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  }
2158df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
2168df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
2178df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic const stack_manager_t interface = {
2188df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  init_stack,
2198df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  start_up_stack_async,
2208df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  shut_down_stack_async,
221f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson  clean_up_stack_async,
222f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson
223f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson  get_stack_is_running
2248df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson};
2258df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson
2268df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonconst stack_manager_t *stack_manager_get_interface() {
2278df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  ensure_manager_initialized();
2288df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson  return &interface;
2298df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}
2308ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson
2318ea8188a481504641fc6a72087704eb808d0bd87Zach Johnsonfuture_t *stack_manager_get_hack_future() {
2328ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson  return hack_future;
2338ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson}
234