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