From 5d2b552a3dea8299299fd153c2ea7f51d928ed1a Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 28 Dec 2020 13:43:47 +0900 Subject: [PATCH] halapi: common: Add hal_common_(get|put)_backend() function to handle backend data Following step is for getting the backend data which contains the function pointers for each HAL module. 1. get library name of HAL backend 2. dlopen with library name 3. get symbol name of HAL backend 4. dlsym with symbol name 5. Get the backend data via backend->init() In order to reduce the duplicate code on each HAL API packages, add hal_common_get_backend() helper function which contains the above steps to get the backend data. And add hal_common_put_backend() helper function to free the hal_backend instance and dlclose the shared library. Change-Id: Ic603d3e4f0ba1ff2aed9699b1eaf925cbd97c60c Signed-off-by: Chanwoo Choi --- CMakeLists.txt | 2 +- include/hal-common-interface.h | 8 ++++ include/hal-common.h | 16 +++++++ src/common.h | 6 ++- src/hal-api-common.c | 106 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 359496c..fc2b438 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ SET(SRCS src/hal-api-common.c) ADD_LIBRARY( ${PROJECT_NAME} SHARED ${SRCS}) -TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${pkgs_LDFLAGS} -Wl,-z,nodelete,--no-undefined) +TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${pkgs_LDFLAGS} -ldl -Wl,-z,nodelete,--no-undefined) SET_TARGET_PROPERTIES( ${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) SET_TARGET_PROPERTIES( ${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) diff --git a/include/hal-common-interface.h b/include/hal-common-interface.h index 40ef158..56b1c3c 100644 --- a/include/hal-common-interface.h +++ b/include/hal-common-interface.h @@ -29,6 +29,14 @@ enum hal_abi_version { HAL_ABI_VERSION_END, }; +typedef struct __hal_backend { + const char *name; + const char *vendor; + const unsigned int abi_version; + int (*init) (void **data); + void (*exit) (void *data); +} hal_backend; + #ifdef __cplusplus } #endif diff --git a/include/hal-common.h b/include/hal-common.h index 0be04a1..e6d025c 100644 --- a/include/hal-common.h +++ b/include/hal-common.h @@ -116,6 +116,22 @@ const char *hal_common_get_backend_library_name(enum hal_module handle); const char *hal_common_get_backend_symbol_name(enum hal_module handle); /** + * @brief Get the backend data according to the type of HAL module + * @param[in] HAL module id among enum hal_moudle + * @param[out] Data pointer where 'hal_backend_[module]_funcs' instance + * should be stored from HAL backend binary. + * @return @c 0 on success, otherwise a negative error value + */ +int hal_common_get_backend(enum hal_module handle, void **data); + +/** + * @brief Put the backend data according to the type of HAL module + * @param[in] HAL module id among enum hal_moudle + * @param[in] Data pointer where 'hal_backend_[module]_funcs' instance + */ +void hal_common_put_backend(enum hal_module handle, void *data); + +/** * @brief Check HAL ABI version whehter is suppored or not on current platform * @param[in] HAL module id among enum hal_moudle * @param[in] HAL ABI version of backend module among enum hal_abi_version diff --git a/src/common.h b/src/common.h index 022e8a1..39ab920 100644 --- a/src/common.h +++ b/src/common.h @@ -298,14 +298,18 @@ struct hal_abi_version_match { }, }; -static const struct __hal_module_info { +static struct __hal_module_info { enum hal_group group; enum hal_module module; enum hal_license license; char *module_name; + char *library_name; char *library_name_64bit; + void *library_handle; + hal_backend *library_backend; char *symbol_name; + unsigned int num_abi_versions; struct hal_abi_version_match *abi_versions; diff --git a/src/hal-api-common.c b/src/hal-api-common.c index 205ddd5..03cb953 100644 --- a/src/hal-api-common.c +++ b/src/hal-api-common.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "common.h" @@ -71,6 +72,111 @@ const char *hal_common_get_backend_symbol_name(enum hal_module module) } EXPORT +int hal_common_get_backend(enum hal_module module, void **data) +{ + void *handle = NULL; + hal_backend *backend; + const char *library_name, *symbol_name; + int ret = 0; + + /* Load module */ + library_name = hal_common_get_backend_library_name(HAL_MODULE_FOO); + if (!library_name) { + _E("Failed to get backend library name of %s\n", + hal_module_info[module].module_name); + return TIZEN_ERROR_INVALID_PARAMETER; + } + + handle = dlopen(library_name, RTLD_LAZY); + if (!handle) { + _E("Failed to load shared library (%s)\n", dlerror()); + return TIZEN_ERROR_INVALID_PARAMETER; + } + + symbol_name = hal_common_get_backend_symbol_name(HAL_MODULE_FOO); + if (!symbol_name) { + _E("Failed to get backend symbol name of %s\n", + hal_module_info[module].module_name); + ret = TIZEN_ERROR_INVALID_PARAMETER; + goto err; + } + + backend = dlsym(handle, symbol_name); + if (!backend) { + _E("Failed to find backend data (%s)\n", dlerror()); + ret = TIZEN_ERROR_INVALID_PARAMETER; + goto err; + } + + /* Print backend module and vendor name */ + + /* Check HAL ABI Version */ + ret = hal_common_check_backend_abi_version(HAL_MODULE_FOO, + backend->abi_version); + if (ret < 0) { + _E("Failed to check ABI version of %s\n", + hal_module_info[module].module_name); + ret = TIZEN_ERROR_INVALID_PARAMETER; + goto err; + } + + /* Get the backend module data */ + if (!backend->init) { + _E("hal_backend->init() is NULL for %s\n", + hal_module_info[module].module_name); + ret = TIZEN_ERROR_INVALID_PARAMETER; + goto err; + } + + ret = backend->init(data); + if (ret < 0) { + _E("Failed to initialize backend: name(%s)/vendor(%s)\n", + backend->name, backend->vendor); + ret = TIZEN_ERROR_INVALID_PARAMETER; + goto err; + } + + hal_module_info[module].library_backend = backend; + hal_module_info[module].library_handle = handle; + + _I("Get HAL backend: name(%s)/vendor(%s)\n", + backend->name, backend->vendor); + + return TIZEN_ERROR_NONE; +err: + dlclose(handle); + return ret; +} + +EXPORT +void hal_common_put_backend(enum hal_module module, void *data) +{ + hal_backend *backend = NULL; + void *handle = NULL; + int ret; + + /* Check parameter whether is valid or not */ + if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) { + _E("Invalid parameter of HAL module (%d)\n", module); + return; + } + + backend = hal_module_info[module].library_backend; + handle = hal_module_info[module].library_handle; + + if (backend) { + if (backend->exit) + backend->exit(data); + + _I("Put HAL backend: name(%s)/vendor(%s)\n", + backend->name, backend->vendor); + } + + if (handle) + dlclose(handle); +} + +EXPORT int hal_common_check_backend_abi_version(enum hal_module module, enum hal_abi_version abi_version) { -- 2.7.4