stack_manager.cc revision 8e7721573557c4ccb7918810349f8a80c2e49803
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 2149a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "stack_manager.h" 2249a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen 238df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include <hardware/bluetooth.h> 248df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 25db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "btcore/include/module.h" 26db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "btcore/include/osi_module.h" 278df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include "btif_api.h" 281924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson#include "btif_common.h" 2979ecab5d0418fde77e9afcdd451bd713af73e180Chris Manton#include "device/include/controller.h" 3044802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h" 31db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "osi/include/osi.h" 320f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/semaphore.h" 330f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/thread.h" 348df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 359b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson// Temp includes 369b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson#include "btif_config.h" 37eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati#include "btif_profile_queue.h" 3896363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson#include "bt_utils.h" 399b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson 408df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic thread_t *management_thread; 418df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 428df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// If initialized, any of the bluetooth API functions can be called. 438df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// (e.g. turning logging on and off, enabling/disabling the stack, etc) 448df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic bool stack_is_initialized; 458df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// If running, the stack is fully up and able to bluetooth. 468df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic bool stack_is_running; 478df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 488df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_init_stack(void *context); 498df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_start_up_stack(void *context); 508df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_shut_down_stack(void *context); 518df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_clean_up_stack(void *context); 528df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 53efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonstatic void event_signal_stack_up(void *context); 54efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonstatic void event_signal_stack_down(void *context); 55efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson 56f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson// Unvetted includes/imports, etc which should be removed or vetted in the future 578ea8188a481504641fc6a72087704eb808d0bd87Zach Johnsonstatic future_t *hack_future; 58f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnsonvoid bte_main_enable(); 59efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonvoid btif_thread_post(thread_fn func, void *context); 60f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson// End unvetted section 618ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 628df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Interface functions 638df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 648df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void init_stack(void) { 658df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson // This is a synchronous process. Post it to the thread though, so 66c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker // state modification only happens there. Using the thread to perform 67c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker // all stack operations ensures that the operations are done serially 68c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker // and do not overlap. 698df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson semaphore_t *semaphore = semaphore_new(0); 708df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson thread_post(management_thread, event_init_stack, semaphore); 718df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson semaphore_wait(semaphore); 72f5153bf62b6cee3f3c740504e94360130c3a9186Sharvil Nanavati semaphore_free(semaphore); 738df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 748df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 758df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void start_up_stack_async(void) { 768df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson thread_post(management_thread, event_start_up_stack, NULL); 778df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 788df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 798df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void shut_down_stack_async(void) { 808df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson thread_post(management_thread, event_shut_down_stack, NULL); 818df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 828df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 83c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panickerstatic void clean_up_stack(void) { 84c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker // This is a synchronous process. Post it to the thread though, so 85c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker // state modification only happens there. 86c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker semaphore_t *semaphore = semaphore_new(0); 87c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker thread_post(management_thread, event_clean_up_stack, semaphore); 88c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker semaphore_wait(semaphore); 89c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker semaphore_free(semaphore); 908df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 918df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 92f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnsonstatic bool get_stack_is_running(void) { 93f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson return stack_is_running; 94f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson} 95f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson 968df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Internal functions 978df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 988df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to initialize the stack 998df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_init_stack(void *context) { 1008df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson semaphore_t *semaphore = (semaphore_t *)context; 1018df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1028e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s is initializing the stack", __func__); 1038e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov 1048e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov if (stack_is_initialized) { 1058e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s found the stack already in initialized state", 1068e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov __func__); 1078e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov } else { 10872f308ee6d3983ae2c0d67be3de2451f2dd72dcbZach Johnson module_management_start(); 10972f308ee6d3983ae2c0d67be3de2451f2dd72dcbZach Johnson 110592afafb911cccc8aaa7d74c54f638e6bfb0a62dPavlin Radoslavov module_init(get_module(OSI_MODULE)); 11196363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson module_init(get_module(BT_UTILS_MODULE)); 1129b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson module_init(get_module(BTIF_CONFIG_MODULE)); 1138df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson btif_init_bluetooth(); 1148df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1158df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson // stack init is synchronous, so no waiting necessary here 1168df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_initialized = true; 1178df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1188df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1198e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s finished", __func__); 1208e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov 1218df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (semaphore) 1228df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson semaphore_post(semaphore); 1238df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1248df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1258df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_stack_is_initialized(void) { 1268df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_initialized) { 127db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_WARN(LOG_TAG, "%s found the stack was uninitialized. Initializing now.", __func__); 1288df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson // No semaphore needed since we are calling it directly 1298df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson event_init_stack(NULL); 1308df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1318df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1328df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1338df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to start up the stack 1348df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_start_up_stack(UNUSED_ATTR void *context) { 1358df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (stack_is_running) { 1368e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s stack already brought up", __func__); 1378df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 1388df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1398df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1408df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ensure_stack_is_initialized(); 1418df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1428e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s is bringing up the stack", __func__); 143c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov future_t *local_hack_future = future_new(); 144c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov hack_future = local_hack_future; 1458ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 1469b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson // Include this for now to put btif config into a shutdown-able state 1479b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson module_start_up(get_module(BTIF_CONFIG_MODULE)); 148f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson bte_main_enable(); 1498ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 150c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov if (future_await(local_hack_future) != FUTURE_SUCCESS) { 1518e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_ERROR(LOG_TAG, "%s failed to start up the stack", __func__); 152efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson stack_is_running = true; // So stack shutdown actually happens 1531924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson event_shut_down_stack(NULL); 1541924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson return; 1551924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson } 1561924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson 1571924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson stack_is_running = true; 1588e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s finished", __func__); 159efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson btif_thread_post(event_signal_stack_up, NULL); 1608df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1618df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1628df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to shut down the stack 1638df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_shut_down_stack(UNUSED_ATTR void *context) { 1648df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_running) { 1658e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s stack is already brought down", __func__); 1668df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 1678df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1688df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1698e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s is bringing down the stack", __func__); 170c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov future_t *local_hack_future = future_new(); 171c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov hack_future = local_hack_future; 1728df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_running = false; 1738ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 1748ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson btif_disable_bluetooth(); 1759b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson module_shut_down(get_module(BTIF_CONFIG_MODULE)); 1768ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 177c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov future_await(local_hack_future); 17830e58068c1adaac7c5ccb3aa9cfb045d41d2a10eZach Johnson module_shut_down(get_module(CONTROLLER_MODULE)); // Doesn't do any work, just puts it in a restartable state 179cae219fe70124f1fc39cd7a78c239c4870422d5dAndre Eisenbach 1808e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s finished", __func__); 181efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson btif_thread_post(event_signal_stack_down, NULL); 1828df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1838df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1848df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_stack_is_not_running(void) { 1858df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (stack_is_running) { 186db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_WARN(LOG_TAG, "%s found the stack was still running. Bringing it down now.", __func__); 1878df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson event_shut_down_stack(NULL); 1888df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1898df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1908df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1918df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to clean up the stack 192c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panickerstatic void event_clean_up_stack(void *context) { 1938df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_initialized) { 1948e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s found the stack already in a clean state", __func__); 195c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker goto cleanup; 1968df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1978df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1988df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ensure_stack_is_not_running(); 1998df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2008e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s is cleaning up the stack", __func__); 201c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov future_t *local_hack_future = future_new(); 202c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov hack_future = local_hack_future; 2038df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_initialized = false; 2048ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 2058ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson btif_shutdown_bluetooth(); 2069b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson module_clean_up(get_module(BTIF_CONFIG_MODULE)); 20796363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson module_clean_up(get_module(BT_UTILS_MODULE)); 2088ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 209c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov future_await(local_hack_future); 2100933b4075e16589a073e85d8230677238b29b780Pavlin Radoslavov module_clean_up(get_module(OSI_MODULE)); 2118675d884479deca722ef5d7776a165241457dd75Zach Johnson module_management_stop(); 2128e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s finished", __func__); 213c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker 214c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panickercleanup:; 215c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker semaphore_t *semaphore = (semaphore_t *)context; 216c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker if (semaphore) 217c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker semaphore_post(semaphore); 2188df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 2198df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 220efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonstatic void event_signal_stack_up(UNUSED_ATTR void *context) { 221eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati // Notify BTIF connect queue that we've brought up the stack. It's 222eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati // now time to dispatch all the pending profile connect requests. 223eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati btif_queue_connect_next(); 224efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON); 225efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson} 226efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson 227efea7821780cdea2b30e944b08e418d1f2781878Zach Johnsonstatic void event_signal_stack_down(UNUSED_ATTR void *context) { 228efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF); 229efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson} 230efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson 2318df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_manager_initialized(void) { 2328df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (management_thread) 2338df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 2348df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2358df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson management_thread = thread_new("stack_manager"); 2368df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!management_thread) { 2378e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_ERROR(LOG_TAG, "%s unable to create stack management thread", __func__); 2388df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 2398df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 2408df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 2418df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2428df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic const stack_manager_t interface = { 2438df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson init_stack, 2448df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson start_up_stack_async, 2458df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson shut_down_stack_async, 246c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker clean_up_stack, 247f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson 248f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson get_stack_is_running 2498df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}; 2508df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2518df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonconst stack_manager_t *stack_manager_get_interface() { 2528df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ensure_manager_initialized(); 2538df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return &interface; 2548df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 2558ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 2568ea8188a481504641fc6a72087704eb808d0bd87Zach Johnsonfuture_t *stack_manager_get_hack_future() { 2578ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson return hack_future; 2588ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson} 259