Home | History | Annotate | Download | only in src
      1 //
      2 //  Copyright (C) 2015 Google, Inc.
      3 //
      4 //  Licensed under the Apache License, Version 2.0 (the "License");
      5 //  you may not use this file except in compliance with the License.
      6 //  You may obtain a copy of the License at:
      7 //
      8 //  http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 //  Unless required by applicable law or agreed to in writing, software
     11 //  distributed under the License is distributed on an "AS IS" BASIS,
     12 //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 //  See the License for the specific language governing permissions and
     14 //  limitations under the License.
     15 //
     16 
     17 #define LOG_TAG "hal_util"
     18 
     19 #include <hardware/bluetooth.h>
     20 #include <hardware/hardware.h>
     21 
     22 #include <dlfcn.h>
     23 #include <errno.h>
     24 #include <string.h>
     25 
     26 #include "btcore/include/hal_util.h"
     27 #include "osi/include/log.h"
     28 
     29 #if defined(OS_GENERIC)
     30 
     31 // TODO(armansito): All logging macros should include __func__ by default (see
     32 // Bug: 22671731)
     33 #define HULOGERR(fmt, args...)                                          \
     34   LOG_ERROR(LOG_TAG, "[%s] failed to load the Bluetooth library: " fmt, \
     35             __func__, ##args)
     36 
     37 // TODO(armansito): It might be better to pass the library name in a more
     38 // generic manner as opposed to hard-coding it here.
     39 static const char kBluetoothLibraryName[] = "libbluetooth.default.so";
     40 
     41 static int load_bt_library(const struct hw_module_t** module) {
     42   const char* id = BT_STACK_MODULE_ID;
     43   const char* sym = HAL_MODULE_INFO_SYM_AS_STR;
     44   struct hw_module_t* hmi = nullptr;
     45 
     46   // Always try to load the default Bluetooth stack on GN builds.
     47   void* handle = dlopen(kBluetoothLibraryName, RTLD_NOW);
     48   if (!handle) {
     49     char const* err_str = dlerror();
     50     HULOGERR("%s", err_str ? err_str : "error unknown");
     51     goto error;
     52   }
     53 
     54   // Get the address of the struct hal_module_info.
     55   hmi = (struct hw_module_t*)dlsym(handle, sym);
     56   if (!hmi) {
     57     HULOGERR("%s", sym);
     58     goto error;
     59   }
     60 
     61   // Check that the id matches.
     62   if (strcmp(id, hmi->id) != 0) {
     63     HULOGERR("id=%s does not match HAL module ID: %s", id, hmi->id);
     64     goto error;
     65   }
     66 
     67   hmi->dso = handle;
     68 
     69   // Success.
     70   LOG_INFO(LOG_TAG, "[%s] loaded HAL id=%s path=%s hmi=%p handle=%p", __func__,
     71            id, kBluetoothLibraryName, hmi, handle);
     72 
     73   *module = hmi;
     74   return 0;
     75 
     76 error:
     77   *module = NULL;
     78   if (handle) dlclose(handle);
     79 
     80   return -EINVAL;
     81 }
     82 
     83 #endif  // defined(OS_GENERIC)
     84 
     85 int hal_util_load_bt_library(const struct hw_module_t** module) {
     86 #if defined(OS_GENERIC)
     87   return load_bt_library(module);
     88 #else  // !defined(OS_GENERIC)
     89   return hw_get_module(BT_STACK_MODULE_ID, module);
     90 #endif  // defined(OS_GENERIC)
     91 }
     92