Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2014 Google, Inc.
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #define LOG_TAG "bt_stack_manager"
     20 
     21 #include "stack_manager.h"
     22 
     23 #include <hardware/bluetooth.h>
     24 
     25 #include "btcore/include/module.h"
     26 #include "btcore/include/osi_module.h"
     27 #include "btif_api.h"
     28 #include "btif_common.h"
     29 #include "device/include/controller.h"
     30 #include "osi/include/log.h"
     31 #include "osi/include/osi.h"
     32 #include "osi/include/semaphore.h"
     33 #include "osi/include/thread.h"
     34 
     35 // Temp includes
     36 #include "btif_config.h"
     37 #include "btif_profile_queue.h"
     38 #include "bt_utils.h"
     39 
     40 static thread_t *management_thread;
     41 
     42 // If initialized, any of the bluetooth API functions can be called.
     43 // (e.g. turning logging on and off, enabling/disabling the stack, etc)
     44 static bool stack_is_initialized;
     45 // If running, the stack is fully up and able to bluetooth.
     46 static bool stack_is_running;
     47 
     48 static void event_init_stack(void *context);
     49 static void event_start_up_stack(void *context);
     50 static void event_shut_down_stack(void *context);
     51 static void event_clean_up_stack(void *context);
     52 
     53 static void event_signal_stack_up(void *context);
     54 static void event_signal_stack_down(void *context);
     55 
     56 // Unvetted includes/imports, etc which should be removed or vetted in the future
     57 static future_t *hack_future;
     58 void bte_main_enable();
     59 void btif_thread_post(thread_fn func, void *context);
     60 // End unvetted section
     61 
     62 // Interface functions
     63 
     64 static void init_stack(void) {
     65   // This is a synchronous process. Post it to the thread though, so
     66   // state modification only happens there. Using the thread to perform
     67   // all stack operations ensures that the operations are done serially
     68   // and do not overlap.
     69   semaphore_t *semaphore = semaphore_new(0);
     70   thread_post(management_thread, event_init_stack, semaphore);
     71   semaphore_wait(semaphore);
     72   semaphore_free(semaphore);
     73 }
     74 
     75 static void start_up_stack_async(void) {
     76   thread_post(management_thread, event_start_up_stack, NULL);
     77 }
     78 
     79 static void shut_down_stack_async(void) {
     80   thread_post(management_thread, event_shut_down_stack, NULL);
     81 }
     82 
     83 static void clean_up_stack(void) {
     84   // This is a synchronous process. Post it to the thread though, so
     85   // state modification only happens there.
     86   semaphore_t *semaphore = semaphore_new(0);
     87   thread_post(management_thread, event_clean_up_stack, semaphore);
     88   semaphore_wait(semaphore);
     89   semaphore_free(semaphore);
     90 }
     91 
     92 static bool get_stack_is_running(void) {
     93   return stack_is_running;
     94 }
     95 
     96 // Internal functions
     97 
     98 // Synchronous function to initialize the stack
     99 static void event_init_stack(void *context) {
    100   semaphore_t *semaphore = (semaphore_t *)context;
    101 
    102   LOG_INFO(LOG_TAG, "%s is initializing the stack", __func__);
    103 
    104  if (stack_is_initialized) {
    105    LOG_INFO(LOG_TAG, "%s found the stack already in initialized state",
    106             __func__);
    107  } else {
    108     module_management_start();
    109 
    110     module_init(get_module(OSI_MODULE));
    111     module_init(get_module(BT_UTILS_MODULE));
    112     module_init(get_module(BTIF_CONFIG_MODULE));
    113     btif_init_bluetooth();
    114 
    115     // stack init is synchronous, so no waiting necessary here
    116     stack_is_initialized = true;
    117   }
    118 
    119   LOG_INFO(LOG_TAG, "%s finished", __func__);
    120 
    121   if (semaphore)
    122     semaphore_post(semaphore);
    123 }
    124 
    125 static void ensure_stack_is_initialized(void) {
    126   if (!stack_is_initialized) {
    127     LOG_WARN(LOG_TAG, "%s found the stack was uninitialized. Initializing now.", __func__);
    128     // No semaphore needed since we are calling it directly
    129     event_init_stack(NULL);
    130   }
    131 }
    132 
    133 // Synchronous function to start up the stack
    134 static void event_start_up_stack(UNUSED_ATTR void *context) {
    135   if (stack_is_running) {
    136     LOG_INFO(LOG_TAG, "%s stack already brought up", __func__);
    137     return;
    138   }
    139 
    140   ensure_stack_is_initialized();
    141 
    142   LOG_INFO(LOG_TAG, "%s is bringing up the stack", __func__);
    143   future_t *local_hack_future = future_new();
    144   hack_future = local_hack_future;
    145 
    146   // Include this for now to put btif config into a shutdown-able state
    147   module_start_up(get_module(BTIF_CONFIG_MODULE));
    148   bte_main_enable();
    149 
    150   if (future_await(local_hack_future) != FUTURE_SUCCESS) {
    151     LOG_ERROR(LOG_TAG, "%s failed to start up the stack", __func__);
    152     stack_is_running = true; // So stack shutdown actually happens
    153     event_shut_down_stack(NULL);
    154     return;
    155   }
    156 
    157   stack_is_running = true;
    158   LOG_INFO(LOG_TAG, "%s finished", __func__);
    159   btif_thread_post(event_signal_stack_up, NULL);
    160 }
    161 
    162 // Synchronous function to shut down the stack
    163 static void event_shut_down_stack(UNUSED_ATTR void *context) {
    164   if (!stack_is_running) {
    165     LOG_INFO(LOG_TAG, "%s stack is already brought down", __func__);
    166     return;
    167   }
    168 
    169   LOG_INFO(LOG_TAG, "%s is bringing down the stack", __func__);
    170   future_t *local_hack_future = future_new();
    171   hack_future = local_hack_future;
    172   stack_is_running = false;
    173 
    174   btif_disable_bluetooth();
    175   module_shut_down(get_module(BTIF_CONFIG_MODULE));
    176 
    177   future_await(local_hack_future);
    178   module_shut_down(get_module(CONTROLLER_MODULE)); // Doesn't do any work, just puts it in a restartable state
    179 
    180   LOG_INFO(LOG_TAG, "%s finished", __func__);
    181   btif_thread_post(event_signal_stack_down, NULL);
    182 }
    183 
    184 static void ensure_stack_is_not_running(void) {
    185   if (stack_is_running) {
    186     LOG_WARN(LOG_TAG, "%s found the stack was still running. Bringing it down now.", __func__);
    187     event_shut_down_stack(NULL);
    188   }
    189 }
    190 
    191 // Synchronous function to clean up the stack
    192 static void event_clean_up_stack(void *context) {
    193   if (!stack_is_initialized) {
    194     LOG_INFO(LOG_TAG, "%s found the stack already in a clean state", __func__);
    195     goto cleanup;
    196   }
    197 
    198   ensure_stack_is_not_running();
    199 
    200   LOG_INFO(LOG_TAG, "%s is cleaning up the stack", __func__);
    201   future_t *local_hack_future = future_new();
    202   hack_future = local_hack_future;
    203   stack_is_initialized = false;
    204 
    205   btif_cleanup_bluetooth();
    206   module_clean_up(get_module(BTIF_CONFIG_MODULE));
    207   module_clean_up(get_module(BT_UTILS_MODULE));
    208   module_clean_up(get_module(OSI_MODULE));
    209   module_management_stop();
    210   LOG_INFO(LOG_TAG, "%s finished", __func__);
    211 
    212 cleanup:;
    213   semaphore_t *semaphore = (semaphore_t *)context;
    214   if (semaphore)
    215     semaphore_post(semaphore);
    216 }
    217 
    218 static void event_signal_stack_up(UNUSED_ATTR void *context) {
    219   // Notify BTIF connect queue that we've brought up the stack. It's
    220   // now time to dispatch all the pending profile connect requests.
    221   btif_queue_connect_next();
    222   HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);
    223 }
    224 
    225 static void event_signal_stack_down(UNUSED_ATTR void *context) {
    226   HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
    227 }
    228 
    229 static void ensure_manager_initialized(void) {
    230   if (management_thread)
    231     return;
    232 
    233   management_thread = thread_new("stack_manager");
    234   if (!management_thread) {
    235     LOG_ERROR(LOG_TAG, "%s unable to create stack management thread", __func__);
    236     return;
    237   }
    238 }
    239 
    240 static const stack_manager_t interface = {
    241   init_stack,
    242   start_up_stack_async,
    243   shut_down_stack_async,
    244   clean_up_stack,
    245 
    246   get_stack_is_running
    247 };
    248 
    249 const stack_manager_t *stack_manager_get_interface() {
    250   ensure_manager_initialized();
    251   return &interface;
    252 }
    253 
    254 future_t *stack_manager_get_hack_future() {
    255   return hack_future;
    256 }
    257