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 366bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson#include "bt_utils.h" 379b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson#include "btif_config.h" 38eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati#include "btif_profile_queue.h" 399b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson 406bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic 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 486bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_init_stack(void* context); 496bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_start_up_stack(void* context); 506bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_shut_down_stack(void* context); 516bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_clean_up_stack(void* context); 528df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 536bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_signal_stack_up(void* context); 546bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_signal_stack_down(void* context); 55efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson 566bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson// Unvetted includes/imports, etc which should be removed or vetted in the 576bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson// future 586bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic future_t* hack_future; 596bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonvoid 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. 696bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 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. 866bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson 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 926bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic bool get_stack_is_running(void) { return stack_is_running; } 93f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson 948df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Internal functions 958df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 968df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to initialize the stack 976bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_init_stack(void* context) { 986bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson semaphore_t* semaphore = (semaphore_t*)context; 998df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1008e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s is initializing the stack", __func__); 1018e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov 1026bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (stack_is_initialized) { 1036bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson LOG_INFO(LOG_TAG, "%s found the stack already in initialized state", 1046bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson __func__); 1056bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson } else { 10672f308ee6d3983ae2c0d67be3de2451f2dd72dcbZach Johnson module_management_start(); 10772f308ee6d3983ae2c0d67be3de2451f2dd72dcbZach Johnson 108592afafb911cccc8aaa7d74c54f638e6bfb0a62dPavlin Radoslavov module_init(get_module(OSI_MODULE)); 10996363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson module_init(get_module(BT_UTILS_MODULE)); 1109b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson module_init(get_module(BTIF_CONFIG_MODULE)); 1118df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson btif_init_bluetooth(); 1128df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1138df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson // stack init is synchronous, so no waiting necessary here 1148df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_initialized = true; 1158df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1168df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1178e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s finished", __func__); 1188e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov 1196bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (semaphore) semaphore_post(semaphore); 1208df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1218df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1228df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_stack_is_initialized(void) { 1238df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_initialized) { 1246bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson LOG_WARN(LOG_TAG, "%s found the stack was uninitialized. Initializing now.", 1256bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson __func__); 1268df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson // No semaphore needed since we are calling it directly 1278df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson event_init_stack(NULL); 1288df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1298df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1308df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1318df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to start up the stack 1326bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_start_up_stack(UNUSED_ATTR void* context) { 1338df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (stack_is_running) { 1348e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s stack already brought up", __func__); 1358df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 1368df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1378df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1388df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ensure_stack_is_initialized(); 1398df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1408e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s is bringing up the stack", __func__); 1416bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson future_t* local_hack_future = future_new(); 142c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov hack_future = local_hack_future; 1438ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 1449b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson // Include this for now to put btif config into a shutdown-able state 1459b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson module_start_up(get_module(BTIF_CONFIG_MODULE)); 146f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson bte_main_enable(); 1478ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 148c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov if (future_await(local_hack_future) != FUTURE_SUCCESS) { 1498e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_ERROR(LOG_TAG, "%s failed to start up the stack", __func__); 1506bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson stack_is_running = true; // So stack shutdown actually happens 1511924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson event_shut_down_stack(NULL); 1521924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson return; 1531924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson } 1541924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson 1551924dac3811575d594c11b76874b24ee0ad24e71Zach Johnson stack_is_running = true; 1568e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s finished", __func__); 157efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson btif_thread_post(event_signal_stack_up, NULL); 1588df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1598df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1608df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to shut down the stack 1616bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_shut_down_stack(UNUSED_ATTR void* context) { 1628df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_running) { 1638e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s stack is already brought down", __func__); 1648df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 1658df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1668df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1678e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s is bringing down the stack", __func__); 1686bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson future_t* local_hack_future = future_new(); 169c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov hack_future = local_hack_future; 1708df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_running = false; 1718ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 1728ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson btif_disable_bluetooth(); 1739b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson module_shut_down(get_module(BTIF_CONFIG_MODULE)); 1748ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 175c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov future_await(local_hack_future); 1766bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson module_shut_down(get_module(CONTROLLER_MODULE)); // Doesn't do any work, just 1776bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson // puts it in a restartable 1786bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson // state 179cae219fe70124f1fc39cd7a78c239c4870422d5dAndre Eisenbach 18016e112b1861d8f1147325372608c905627e00e88Gurpreet Ghai hack_future = future_new(); 181efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson btif_thread_post(event_signal_stack_down, NULL); 18216e112b1861d8f1147325372608c905627e00e88Gurpreet Ghai future_await(hack_future); 183137aa547f3d163929120d250a87e55dbf6c748abPavlin Radoslavov LOG_INFO(LOG_TAG, "%s finished", __func__); 1848df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1858df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1868df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_stack_is_not_running(void) { 1878df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (stack_is_running) { 1886bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson LOG_WARN(LOG_TAG, 1896bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson "%s found the stack was still running. Bringing it down now.", 1906bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson __func__); 1918df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson event_shut_down_stack(NULL); 1928df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1938df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1948df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1958df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to clean up the stack 1966bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_clean_up_stack(void* context) { 1976bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson future_t* local_hack_future; 198713993d1784ab7c23aee1fa3cf1ab8676cc0aa69Jakub Pawlowski 1998df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_initialized) { 2008e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s found the stack already in a clean state", __func__); 201c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker goto cleanup; 2028df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 2038df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2048df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ensure_stack_is_not_running(); 2058df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2068e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s is cleaning up the stack", __func__); 207713993d1784ab7c23aee1fa3cf1ab8676cc0aa69Jakub Pawlowski local_hack_future = future_new(); 208c3e8824f8d5266ee5d33be18c690b8de8f0562aaPavlin Radoslavov hack_future = local_hack_future; 2098df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_initialized = false; 2108ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 2111bd691cb8ae3c23ffe25b5ca1fcfd11b82a9fbdaPavlin Radoslavov btif_cleanup_bluetooth(); 2129b0fbce37260e69cb116be1cdcbceb1f43bf9346Zach Johnson module_clean_up(get_module(BTIF_CONFIG_MODULE)); 21396363ff2b78c10e2b2e106464f337b58ec1a616aZach Johnson module_clean_up(get_module(BT_UTILS_MODULE)); 2140933b4075e16589a073e85d8230677238b29b780Pavlin Radoslavov module_clean_up(get_module(OSI_MODULE)); 2158675d884479deca722ef5d7776a165241457dd75Zach Johnson module_management_stop(); 2168e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_INFO(LOG_TAG, "%s finished", __func__); 217c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panicker 218c28849aa58c10a4e57d6cb7e5f6d876cba4f8d99Ajay Panickercleanup:; 2196bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson semaphore_t* semaphore = (semaphore_t*)context; 2206bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (semaphore) semaphore_post(semaphore); 2218df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 2228df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2236bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_signal_stack_up(UNUSED_ATTR void* context) { 224eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati // Notify BTIF connect queue that we've brought up the stack. It's 225eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati // now time to dispatch all the pending profile connect requests. 226eacc69d09256ecaa7c01ea066cd70b0049edc23bSharvil Nanavati btif_queue_connect_next(); 227efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON); 228efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson} 229efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson 2306bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic void event_signal_stack_down(UNUSED_ATTR void* context) { 231efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF); 23216e112b1861d8f1147325372608c905627e00e88Gurpreet Ghai future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); 233efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson} 234efea7821780cdea2b30e944b08e418d1f2781878Zach Johnson 2358df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_manager_initialized(void) { 2366bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson if (management_thread) return; 2378df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2388df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson management_thread = thread_new("stack_manager"); 2398df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!management_thread) { 2408e7721573557c4ccb7918810349f8a80c2e49803Pavlin Radoslavov LOG_ERROR(LOG_TAG, "%s unable to create stack management thread", __func__); 2418df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 2428df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 2438df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 2448df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2456bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonstatic const stack_manager_t interface = {init_stack, start_up_stack_async, 2466bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson shut_down_stack_async, clean_up_stack, 247f450ba53dfd7b36989c1ea6ed9c6508c7a1b895eZach Johnson 2486bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watson get_stack_is_running}; 2498df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 2506bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonconst stack_manager_t* stack_manager_get_interface() { 2518df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ensure_manager_initialized(); 2528df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return &interface; 2538df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 2548ea8188a481504641fc6a72087704eb808d0bd87Zach Johnson 2556bd442f543972b072ef2cbbcf2f7c91202de1045Myles Watsonfuture_t* stack_manager_get_hack_future() { return hack_future; } 256