stack_manager.cc revision 8df0d80f0227554d95ed51a443439ee9e7fe7e42
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 198df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#define LOG_TAG "bt_stack_manager" 208df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 218df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include <hardware/bluetooth.h> 228df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include <utils/Log.h> 238df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 248df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include "async_result.h" 258df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include "btif_api.h" 268df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include "bt_utils.h" 278df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include "osi.h" 288df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include "semaphore.h" 298df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include "stack_manager.h" 308df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson#include "thread.h" 318df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 328df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic thread_t *management_thread; 338df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 348df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// If initialized, any of the bluetooth API functions can be called. 358df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// (e.g. turning logging on and off, enabling/disabling the stack, etc) 368df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic bool stack_is_initialized; 378df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// If running, the stack is fully up and able to bluetooth. 388df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic bool stack_is_running; 398df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 408df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_init_stack(void *context); 418df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_start_up_stack(void *context); 428df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_shut_down_stack(void *context); 438df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_clean_up_stack(void *context); 448df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 458df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Interface functions 468df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 478df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void init_stack(void) { 488df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson // This is a synchronous process. Post it to the thread though, so 498df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson // state modification only happens there. 508df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson semaphore_t *semaphore = semaphore_new(0); 518df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson thread_post(management_thread, event_init_stack, semaphore); 528df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson semaphore_wait(semaphore); 538df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 548df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 558df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void start_up_stack_async(void) { 568df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson thread_post(management_thread, event_start_up_stack, NULL); 578df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 588df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 598df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void shut_down_stack_async(void) { 608df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson thread_post(management_thread, event_shut_down_stack, NULL); 618df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 628df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 638df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void clean_up_stack_async(void) { 648df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson thread_post(management_thread, event_clean_up_stack, NULL); 658df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 668df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 678df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Internal functions 688df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 698df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to initialize the stack 708df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_init_stack(void *context) { 718df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson semaphore_t *semaphore = (semaphore_t *)context; 728df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 738df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_initialized) { 748df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson bt_utils_init(); 758df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson btif_init_bluetooth(); 768df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 778df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson // stack init is synchronous, so no waiting necessary here 788df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_initialized = true; 798df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 808df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 818df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (semaphore) 828df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson semaphore_post(semaphore); 838df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 848df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 858df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_stack_is_initialized(void) { 868df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_initialized) { 878df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGW("%s found the stack was uninitialized. Initializing now.", __func__); 888df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson // No semaphore needed since we are calling it directly 898df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson event_init_stack(NULL); 908df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 918df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 928df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 938df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to start up the stack 948df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_start_up_stack(UNUSED_ATTR void *context) { 958df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (stack_is_running) { 968df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGD("%s stack already brought up.", __func__); 978df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 988df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 998df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1008df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ensure_stack_is_initialized(); 1018df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1028df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGD("%s is bringing up the stack.", __func__); 1038df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson btif_enable_bluetooth(); 1048df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_running = true; 1058df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGD("%s finished", __func__); 1068df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1078df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1088df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to shut down the stack 1098df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_shut_down_stack(UNUSED_ATTR void *context) { 1108df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_running) { 1118df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGD("%s stack is already brought down.", __func__); 1128df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 1138df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1148df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1158df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGD("%s is bringing down the stack.", __func__); 1168df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson btif_disable_bluetooth(); 1178df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_running = false; 1188df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGD("%s finished.", __func__); 1198df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1208df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1218df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_stack_is_not_running(void) { 1228df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (stack_is_running) { 1238df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGW("%s found the stack was still running. Bringing it down now.", __func__); 1248df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson event_shut_down_stack(NULL); 1258df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1268df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1278df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1288df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson// Synchronous function to clean up the stack 1298df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void event_clean_up_stack(UNUSED_ATTR void *context) { 1308df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!stack_is_initialized) { 1318df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGD("%s found the stack already in a clean state.", __func__); 1328df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 1338df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1348df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1358df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ensure_stack_is_not_running(); 1368df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1378df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGD("%s is bringing down the stack.", __func__); 1388df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson btif_shutdown_bluetooth(); 1398df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson stack_is_initialized = false; 1408df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGD("%s finished.", __func__); 1418df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1428df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1438df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic void ensure_manager_initialized(void) { 1448df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (management_thread) 1458df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 1468df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1478df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson management_thread = thread_new("stack_manager"); 1488df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson if (!management_thread) { 1498df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ALOGE("%s unable to create stack management thread.", __func__); 1508df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return; 1518df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson } 1528df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 1538df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1548df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonstatic const stack_manager_t interface = { 1558df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson init_stack, 1568df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson start_up_stack_async, 1578df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson shut_down_stack_async, 1588df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson clean_up_stack_async 1598df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson}; 1608df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson 1618df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnsonconst stack_manager_t *stack_manager_get_interface() { 1628df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson ensure_manager_initialized(); 1638df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson return &interface; 1648df0d80f0227554d95ed51a443439ee9e7fe7e42Zach Johnson} 165