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 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 76error: 77 *module = NULL; 78 if (handle) dlclose(handle); 79 80 return -EINVAL; 81} 82 83#endif // defined(OS_GENERIC) 84 85int 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