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