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