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 "bt_utils.h"
     37 #include "btif_config.h"
     38 #include "btif_profile_queue.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
     57 // future
     58 static future_t* hack_future;
     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) { return stack_is_running; }
     93 
     94 // Internal functions
     95 
     96 // Synchronous function to initialize the stack
     97 static void event_init_stack(void* context) {
     98   semaphore_t* semaphore = (semaphore_t*)context;
     99 
    100   LOG_INFO(LOG_TAG, "%s is initializing the stack", __func__);
    101 
    102   if (stack_is_initialized) {
    103     LOG_INFO(LOG_TAG, "%s found the stack already in initialized state",
    104              __func__);
    105   } else {
    106     module_management_start();
    107 
    108     module_init(get_module(OSI_MODULE));
    109     module_init(get_module(BT_UTILS_MODULE));
    110     module_init(get_module(BTIF_CONFIG_MODULE));
    111     btif_init_bluetooth();
    112 
    113     // stack init is synchronous, so no waiting necessary here
    114     stack_is_initialized = true;
    115   }
    116 
    117   LOG_INFO(LOG_TAG, "%s finished", __func__);
    118 
    119   if (semaphore) semaphore_post(semaphore);
    120 }
    121 
    122 static void ensure_stack_is_initialized(void) {
    123   if (!stack_is_initialized) {
    124     LOG_WARN(LOG_TAG, "%s found the stack was uninitialized. Initializing now.",
    125              __func__);
    126     // No semaphore needed since we are calling it directly
    127     event_init_stack(NULL);
    128   }
    129 }
    130 
    131 // Synchronous function to start up the stack
    132 static void event_start_up_stack(UNUSED_ATTR void* context) {
    133   if (stack_is_running) {
    134     LOG_INFO(LOG_TAG, "%s stack already brought up", __func__);
    135     return;
    136   }
    137 
    138   ensure_stack_is_initialized();
    139 
    140   LOG_INFO(LOG_TAG, "%s is bringing up the stack", __func__);
    141   future_t* local_hack_future = future_new();
    142   hack_future = local_hack_future;
    143 
    144   // Include this for now to put btif config into a shutdown-able state
    145   module_start_up(get_module(BTIF_CONFIG_MODULE));
    146   bte_main_enable();
    147 
    148   if (future_await(local_hack_future) != FUTURE_SUCCESS) {
    149     LOG_ERROR(LOG_TAG, "%s failed to start up the stack", __func__);
    150     stack_is_running = true;  // So stack shutdown actually happens
    151     event_shut_down_stack(NULL);
    152     return;
    153   }
    154 
    155   stack_is_running = true;
    156   LOG_INFO(LOG_TAG, "%s finished", __func__);
    157   btif_thread_post(event_signal_stack_up, NULL);
    158 }
    159 
    160 // Synchronous function to shut down the stack
    161 static void event_shut_down_stack(UNUSED_ATTR void* context) {
    162   if (!stack_is_running) {
    163     LOG_INFO(LOG_TAG, "%s stack is already brought down", __func__);
    164     return;
    165   }
    166 
    167   LOG_INFO(LOG_TAG, "%s is bringing down the stack", __func__);
    168   future_t* local_hack_future = future_new();
    169   hack_future = local_hack_future;
    170   stack_is_running = false;
    171 
    172   btif_disable_bluetooth();
    173   module_shut_down(get_module(BTIF_CONFIG_MODULE));
    174 
    175   future_await(local_hack_future);
    176   module_shut_down(get_module(CONTROLLER_MODULE));  // Doesn't do any work, just
    177                                                     // puts it in a restartable
    178                                                     // state
    179 
    180   LOG_INFO(LOG_TAG, "%s finished", __func__);
    181   hack_future = future_new();
    182   btif_thread_post(event_signal_stack_down, NULL);
    183   future_await(hack_future);
    184 }
    185 
    186 static void ensure_stack_is_not_running(void) {
    187   if (stack_is_running) {
    188     LOG_WARN(LOG_TAG,
    189              "%s found the stack was still running. Bringing it down now.",
    190              __func__);
    191     event_shut_down_stack(NULL);
    192   }
    193 }
    194 
    195 // Synchronous function to clean up the stack
    196 static void event_clean_up_stack(void* context) {
    197   future_t* local_hack_future;
    198 
    199   if (!stack_is_initialized) {
    200     LOG_INFO(LOG_TAG, "%s found the stack already in a clean state", __func__);
    201     goto cleanup;
    202   }
    203 
    204   ensure_stack_is_not_running();
    205 
    206   LOG_INFO(LOG_TAG, "%s is cleaning up the stack", __func__);
    207   local_hack_future = future_new();
    208   hack_future = local_hack_future;
    209   stack_is_initialized = false;
    210 
    211   btif_cleanup_bluetooth();
    212   module_clean_up(get_module(BTIF_CONFIG_MODULE));
    213   module_clean_up(get_module(BT_UTILS_MODULE));
    214   module_clean_up(get_module(OSI_MODULE));
    215   module_management_stop();
    216   LOG_INFO(LOG_TAG, "%s finished", __func__);
    217 
    218 cleanup:;
    219   semaphore_t* semaphore = (semaphore_t*)context;
    220   if (semaphore) semaphore_post(semaphore);
    221 }
    222 
    223 static void event_signal_stack_up(UNUSED_ATTR void* context) {
    224   // Notify BTIF connect queue that we've brought up the stack. It's
    225   // now time to dispatch all the pending profile connect requests.
    226   btif_queue_connect_next();
    227   HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);
    228 }
    229 
    230 static void event_signal_stack_down(UNUSED_ATTR void* context) {
    231   HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
    232   future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
    233 }
    234 
    235 static void ensure_manager_initialized(void) {
    236   if (management_thread) return;
    237 
    238   management_thread = thread_new("stack_manager");
    239   if (!management_thread) {
    240     LOG_ERROR(LOG_TAG, "%s unable to create stack management thread", __func__);
    241     return;
    242   }
    243 }
    244 
    245 static const stack_manager_t interface = {init_stack, start_up_stack_async,
    246                                           shut_down_stack_async, clean_up_stack,
    247 
    248                                           get_stack_is_running};
    249 
    250 const stack_manager_t* stack_manager_get_interface() {
    251   ensure_manager_initialized();
    252   return &interface;
    253 }
    254 
    255 future_t* stack_manager_get_hack_future() { return hack_future; }
    256