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. 39static const char kBluetoothLibraryName[] = "libbluetooth.default.so"; 40 41static int load_bt_library(const struct hw_module_t **module) { 42 const char *id = BT_STACK_MODULE_ID; 43 44 // Always try to load the default Bluetooth stack on GN builds. 45 void *handle = dlopen(kBluetoothLibraryName, RTLD_NOW); 46 if (!handle) { 47 char const *err_str = dlerror(); 48 HULOGERR("%s", err_str ? err_str : "error unknown"); 49 goto error; 50 } 51 52 // Get the address of the struct hal_module_info. 53 const char *sym = HAL_MODULE_INFO_SYM_AS_STR; 54 struct hw_module_t *hmi = (struct hw_module_t *)dlsym(handle, sym); 55 if (!hmi) { 56 HULOGERR("%s", sym); 57 goto error; 58 } 59 60 // Check that the id matches. 61 if (strcmp(id, hmi->id) != 0) { 62 HULOGERR("id=%s does not match HAL module ID: %s", id, hmi->id); 63 goto error; 64 } 65 66 hmi->dso = handle; 67 68 // Success. 69 LOG_INFO( 70 LOG_TAG, "[%s] loaded HAL id=%s path=%s hmi=%p handle=%p", 71 __func__, id, kBluetoothLibraryName, hmi, handle); 72 73 *module = hmi; 74 return 0; 75 76error: 77 *module = NULL; 78 if (handle) 79 dlclose(handle); 80 81 return -EINVAL; 82} 83 84#endif // defined(OS_GENERIC) 85 86int hal_util_load_bt_library(const struct hw_module_t **module) { 87#if defined(OS_GENERIC) 88 return load_bt_library(module); 89#else // !defined(OS_GENERIC) 90 return hw_get_module(BT_STACK_MODULE_ID, module); 91#endif // defined(OS_GENERIC) 92} 93