From 8736c8c1577b9c634b4eb2cdf250750c7c5de92e Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 8 Jan 2021 12:30:03 +0900 Subject: [PATCH 01/16] halapi: common: Fix bug by using the module parameter hal-api-common helper functions have been used the fixed hal module id such as HAL_MODULE_FOO. It is wrong usage. hal-api-common helper functions have to use the 'module' parameter. Change-Id: Ifa27e0e4df3c5b89ce96511802ef5a008cf2a279 Signed-off-by: Chanwoo Choi --- src/hal-api-common.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hal-api-common.c b/src/hal-api-common.c index 9be72fa..9f47636 100644 --- a/src/hal-api-common.c +++ b/src/hal-api-common.c @@ -80,7 +80,7 @@ int hal_common_get_backend(enum hal_module module, void **data) int ret = 0; /* Load module */ - library_name = hal_common_get_backend_library_name(HAL_MODULE_FOO); + library_name = hal_common_get_backend_library_name(module); if (!library_name) { _E("Failed to get backend library name of %s\n", hal_module_info[module].module_name); @@ -93,7 +93,7 @@ int hal_common_get_backend(enum hal_module module, void **data) return TIZEN_ERROR_INVALID_PARAMETER; } - symbol_name = hal_common_get_backend_symbol_name(HAL_MODULE_FOO); + symbol_name = hal_common_get_backend_symbol_name(module); if (!symbol_name) { _E("Failed to get backend symbol name of %s\n", hal_module_info[module].module_name); @@ -111,8 +111,7 @@ int hal_common_get_backend(enum hal_module module, void **data) /* Print backend module and vendor name */ /* Check HAL ABI Version */ - ret = hal_common_check_backend_abi_version(HAL_MODULE_FOO, - backend->abi_version); + ret = hal_common_check_backend_abi_version(module, backend->abi_version); if (ret < 0) { _E("Failed to check ABI version of %s\n", hal_module_info[module].module_name); -- 2.7.4 From 6c39b97c886d317b624d6f7d6d386cb48aae30dd Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Fri, 8 Jan 2021 12:46:15 +0900 Subject: [PATCH 02/16] halapi: common: Change the parameter name of helper functions for readability hal-api-common's helper functions have the 'enum hal_module' as first parameter. In order to improve the readability, replace parameter name from 'handle' to 'module'. Change-Id: I3baa384885d9e5225987f143d4b1951c4b6aedd6 Signed-off-by: Chanwoo Choi --- include/hal-common.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/hal-common.h b/include/hal-common.h index e25503b..9df3d31 100644 --- a/include/hal-common.h +++ b/include/hal-common.h @@ -105,7 +105,7 @@ enum hal_module { * @return @c backend library name on success and don't need to be freed * due to the global variable, otherwise NULL. */ -const char *hal_common_get_backend_library_name(enum hal_module handle); +const char *hal_common_get_backend_library_name(enum hal_module module); /** * @brief Get the backend symbol name according to the type of HAL module @@ -113,7 +113,7 @@ const char *hal_common_get_backend_library_name(enum hal_module handle); * @return @c backend library name on success and don't need to be freed * due to the global variable, otherwise NULL. */ -const char *hal_common_get_backend_symbol_name(enum hal_module handle); +const char *hal_common_get_backend_symbol_name(enum hal_module module); /** * @brief Get the backend data according to the type of HAL module @@ -122,7 +122,7 @@ const char *hal_common_get_backend_symbol_name(enum hal_module handle); * 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); +int hal_common_get_backend(enum hal_module module, void **data); /** * @brief Put the backend data according to the type of HAL module @@ -130,7 +130,7 @@ int hal_common_get_backend(enum hal_module handle, void **data); * @param[in] Data pointer where 'hal_backend_[module]_funcs' instance * @return @c 0 on success, otherwise a negative error value */ -int hal_common_put_backend(enum hal_module handle, void *data); +int hal_common_put_backend(enum hal_module module, void *data); /** * @brief Check HAL ABI version whehter is suppored or not on current platform @@ -138,7 +138,7 @@ int hal_common_put_backend(enum hal_module handle, void *data); * @param[in] HAL ABI version of backend module among enum hal_abi_version * @return @c 0 on success, otherwise a negative error value */ -int hal_common_check_backend_abi_version(enum hal_module handle, +int hal_common_check_backend_abi_version(enum hal_module module, enum hal_abi_version abi_version); #ifdef __cplusplus -- 2.7.4 From 415c591303fca1ea627f277b620b7f71914973b6 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Mon, 11 Jan 2021 08:03:47 +0900 Subject: [PATCH 03/16] halapi: common: Add hal_api_version_str array and an error message Add hal_api_version_str array to display as string after converting each enum value. It's easier to understand than using enum value. If abi version doesn't support about current version and compatible version, then it needs to notice about not supporting abi_version. Change-Id: I67f31423a4b9d911b269d8c7560c9907a6bafc8b Signed-off-by: Jaehoon Chung --- include/hal-common-interface.h | 5 +++++ src/hal-api-common.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/include/hal-common-interface.h b/include/hal-common-interface.h index 39831b9..dab26cb 100644 --- a/include/hal-common-interface.h +++ b/include/hal-common-interface.h @@ -29,6 +29,11 @@ enum hal_abi_version { HAL_ABI_VERSION_END, }; +static const char *const hal_abi_version_str[] = { + [HAL_ABI_VERSION_UNKNOWN] = "Unknown HAL ABI Version", + [HAL_ABI_VERSION_TIZEN_6_5] = "HAL_ABI_VERSION_TIZEN_6_5", +}; + typedef struct __hal_backend { const char *name; const char *vendor; diff --git a/src/hal-api-common.c b/src/hal-api-common.c index 9f47636..61ef60c 100644 --- a/src/hal-api-common.c +++ b/src/hal-api-common.c @@ -222,6 +222,12 @@ int hal_common_check_backend_abi_version(enum hal_module module, if (abi_version <= data->curr_version && abi_version >= data->compat_version) return TIZEN_ERROR_NONE; + + _E("%s doesn't support %s of HAL Backend\n", hal_abi_version_str[g_curr_hal_abi_version], + hal_abi_version_str[abi_version]); + _E("Must use the following ABI versions from %s to %s\n", + hal_abi_version_str[data->compat_version], + hal_abi_version_str[data->curr_version]); } return TIZEN_ERROR_INVALID_PARAMETER; -- 2.7.4 From b615b27655bbaae210b76483f3760cd1791a2a8c Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 11 Jan 2021 15:00:55 +0900 Subject: [PATCH 04/16] halapi: common: Change variable name for improving the readability Change the variable name for improving the readability because prior defined variable name is vague to pass the correct meaning of version. So that change the name as following in order to improve the readability and understanding. [Chagned variable names] - g_curr_hal_abi_version -> g_platform_curr_abi_version - current_version -> platform_abi_version - compat_version -> backend_min_abi_version Change-Id: I733b203a6c0fe058dedb6e9e26f832a0629ccc15 Signed-off-by: Chanwoo Choi --- src/common.h | 122 +++++++++++++++++++++++++-------------------------- src/hal-api-common.c | 12 ++--- 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/common.h b/src/common.h index 39ab920..7f9dadf 100644 --- a/src/common.h +++ b/src/common.h @@ -36,35 +36,35 @@ * and HAL backend package like hal-backend-audio-*.rpm which is included * in hal.img. In order to compare ABI version between two binary, * Tizen core platform always must maintain the current HAL ABI version. - * So that, define the below global variable (g_curr_hal_abi_version). + * So that, define the below global variable (g_platform_curr_abi_version). * - * 'g_curr_hal_abi_version' will be used for all HAL API modules, + * 'g_platform_curr_abi_version' will be used for all HAL API modules, * to check whether HAL backend ABI version of each module in hal.img * is supported or not with current Tizen core HAL ABI version. * - * 'g_curr_hal_abi_version' must be updated when Tizen platform will be released - * officially. + * 'g_platform_curr_abi_version' must be updated when Tizen platform + * will be released officially. */ /* FIXME: Need to be initialized by configuration file like xml */ -enum hal_abi_version g_curr_hal_abi_version = HAL_ABI_VERSION_TIZEN_6_5; +enum hal_abi_version g_platform_curr_abi_version = HAL_ABI_VERSION_TIZEN_6_5; struct hal_abi_version_match { - enum hal_abi_version curr_version; - enum hal_abi_version compat_version; + enum hal_abi_version platform_abi_version; + enum hal_abi_version backend_min_abi_version; } abi_version_match_data[HAL_MODULE_END][HAL_ABI_VERSION_MAX] = { /* HAL_GROUP_GRAPHICS */ [HAL_MODULE_TBM] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_TDM] = { /* FIXME: Need to be filled from configuration file. */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_COREGL] = { @@ -84,22 +84,22 @@ struct hal_abi_version_match { [HAL_MODULE_AUDIO] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_CAMERA] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_RADIO] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_CODEC] = { @@ -125,15 +125,15 @@ struct hal_abi_version_match { [HAL_MODULE_BLUETOOTH] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_WIFI] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_NAN] = { @@ -141,22 +141,22 @@ struct hal_abi_version_match { [HAL_MODULE_NFC] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_ZIGBEE] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_UWB] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_MTP] = { @@ -170,8 +170,8 @@ struct hal_abi_version_match { [HAL_MODULE_TELPEPHONY] = { /* FIXME: Need to be determined whehter support HAL API or not. */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, @@ -179,8 +179,8 @@ struct hal_abi_version_match { [HAL_MODULE_LOCATION] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, @@ -190,100 +190,100 @@ struct hal_abi_version_match { [HAL_MODULE_POWER] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_SENSOR] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_PERIPHERAL] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_BATTERY] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_BEZEL] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_DISPLAY] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_IR] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_TOUCHSCREEN] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_LED] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_BOARD] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_EXTERNAL_CONNECTION] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_THERMAL] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_USB_GADGET] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, [HAL_MODULE_DEVICE_HAPTIC] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, @@ -292,8 +292,8 @@ struct hal_abi_version_match { [HAL_MODULE_FOO] = { /* FIXME: Need to be initialized by configuration file like xml */ [0] = { - .curr_version = HAL_ABI_VERSION_TIZEN_6_5, - .compat_version = HAL_ABI_VERSION_TIZEN_6_5, + .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, + .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, }; diff --git a/src/hal-api-common.c b/src/hal-api-common.c index 61ef60c..896691c 100644 --- a/src/hal-api-common.c +++ b/src/hal-api-common.c @@ -216,18 +216,18 @@ int hal_common_check_backend_abi_version(enum hal_module module, struct hal_abi_version_match *data = &hal_module_info[module].abi_versions[i]; - if (g_curr_hal_abi_version != data->curr_version) + if (g_platform_curr_abi_version != data->platform_abi_version) continue; - if (abi_version <= data->curr_version - && abi_version >= data->compat_version) + if (abi_version <= data->platform_abi_version + && abi_version >= data->backend_min_abi_version) return TIZEN_ERROR_NONE; - _E("%s doesn't support %s of HAL Backend\n", hal_abi_version_str[g_curr_hal_abi_version], + _E("%s doesn't support %s of HAL Backend\n", hal_abi_version_str[g_platform_curr_abi_version], hal_abi_version_str[abi_version]); _E("Must use the following ABI versions from %s to %s\n", - hal_abi_version_str[data->compat_version], - hal_abi_version_str[data->curr_version]); + hal_abi_version_str[data->backend_min_abi_version], + hal_abi_version_str[data->platform_abi_version]); } return TIZEN_ERROR_INVALID_PARAMETER; -- 2.7.4 From b7115a417e172637844acb3e2229161d915bd989 Mon Sep 17 00:00:00 2001 From: Seungha Son Date: Tue, 12 Jan 2021 17:52:23 +0900 Subject: [PATCH 05/16] Fix wrong spelling HAL_MODULE_TELPEPHONY -> HAL_MODULE_TELEPHONY Change-Id: Ie3b77e9b3839de8306e2c49e10bdeb4b3fe91744 Signed-off-by: Seungha Son --- include/hal-common.h | 2 +- src/common.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/hal-common.h b/include/hal-common.h index 9df3d31..09df968 100644 --- a/include/hal-common.h +++ b/include/hal-common.h @@ -72,7 +72,7 @@ enum hal_module { HAL_MODULE_MTP, /* HAL_GROUP_TELEPHONY */ - HAL_MODULE_TELPEPHONY = 45, + HAL_MODULE_TELEPHONY = 45, /* HAL_GROUP_LOCATION */ HAL_MODULE_LOCATION = 50, diff --git a/src/common.h b/src/common.h index 7f9dadf..c8b263b 100644 --- a/src/common.h +++ b/src/common.h @@ -167,7 +167,7 @@ struct hal_abi_version_match { }, /* HAL_GROUP_TELEPHONY */ - [HAL_MODULE_TELPEPHONY] = { + [HAL_MODULE_TELEPHONY] = { /* FIXME: Need to be determined whehter support HAL API or not. */ [0] = { .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, @@ -526,9 +526,9 @@ static struct __hal_module_info { }, /* HAL_GROUP_TELEPHONY */ - [HAL_MODULE_TELPEPHONY] = { + [HAL_MODULE_TELEPHONY] = { .group = HAL_GROUP_TELEPHONY, - .module = HAL_MODULE_TELPEPHONY, + .module = HAL_MODULE_TELEPHONY, .license = HAL_LICENSE_APACHE_2_0, .module_name = "TELEPHONY", .library_name = NULL, -- 2.7.4 From 9b018a5842c4c37d479e2e820ea03b63b1455c69 Mon Sep 17 00:00:00 2001 From: Seungha Son Date: Fri, 8 Jan 2021 16:52:23 +0900 Subject: [PATCH 06/16] Add hal-api-common uniitest skeleton This test will run automatically when building gbs. The result can be checked by the developer and the side effect of the edited content can be checked. it is a test for the currently implemented operation, and a test for applying TDD in the future. Change-Id: I5af141dbb601524ff517b78e7cc970323ed138fc Signed-off-by: Seungha Son --- CMakeLists.txt | 4 +++- haltests/CMakeLists.txt | 30 ++++++++++++++++++++++++++++++ haltests/src/test_hal.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ haltests/src/test_main.cc | 37 +++++++++++++++++++++++++++++++++++++ packaging/hal-api-common.spec | 4 ++++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 haltests/CMakeLists.txt create mode 100644 haltests/src/test_hal.cc create mode 100644 haltests/src/test_main.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index fc2b438..060a688 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(hal-api-common C) +PROJECT(hal-api-common C CXX) SET(VERSION_MAJOR 0) SET(VERSION "${VERSION_MAJOR}.1.0") @@ -46,3 +46,5 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ FILES_MATCHING PATTERN "*.h") INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIBDIR}/pkgconfig) + +ADD_SUBDIRECTORY(haltests) diff --git a/haltests/CMakeLists.txt b/haltests/CMakeLists.txt new file mode 100644 index 0000000..30a7992 --- /dev/null +++ b/haltests/CMakeLists.txt @@ -0,0 +1,30 @@ +ENABLE_TESTING() +SET(HAL_COMMON_UNITTEST "common-unittest") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -g -Wall -Werror") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++14 -g -Wall -Werror") +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed,--gc-sections -pie") + +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src UNITTEST_SRCS) +ADD_EXECUTABLE(${HAL_COMMON_UNITTEST} ${UNITTEST_SRCS}) + +TARGET_INCLUDE_DIRECTORIES(${HAL_COMMON_UNITTEST} PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/../include" + "${CMAKE_CURRENT_SOURCE_DIR}/../src" +) + +INCLUDE(FindPkgConfig) +pkg_check_modules(hal_common_unittest_pkgs REQUIRED gmock) + +FOREACH(flag ${hal_common_unittest_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +TARGET_LINK_LIBRARIES(${HAL_COMMON_UNITTEST} ${hal_common_unittest_pkgs_LDFLAGS} hal-api-common) +SET_TARGET_PROPERTIES(${HAL_COMMON_UNITTEST} PROPERTIES COMPILE_FLAGS "-fPIE") +SET_TARGET_PROPERTIES(${HAL_COMMON_UNITTEST} PROPERTIES LINK_FLAGS "-pie") + +ADD_TEST( + NAME ${HAL_COMMON_UNITTEST} + COMMAND ${HAL_COMMON_UNITTEST} +) diff --git a/haltests/src/test_hal.cc b/haltests/src/test_hal.cc new file mode 100644 index 0000000..cb51371 --- /dev/null +++ b/haltests/src/test_hal.cc @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +#include "hal-common.h" +#include "hal-common-interface.h" + +using namespace std; + +class CommonHaltest : public testing::Test { + public: + CommonHaltest() {} + + virtual ~CommonHaltest() {} + + virtual void SetUp() {} + + virtual void TearDown() {} +}; + +TEST(CommonHaltest, get_backend_library_name_unknown) { + const char *ret = hal_common_get_backend_library_name(HAL_MODULE_UNKNOWN); + EXPECT_TRUE(ret == nullptr); +} diff --git a/haltests/src/test_main.cc b/haltests/src/test_main.cc new file mode 100644 index 0000000..c2eb730 --- /dev/null +++ b/haltests/src/test_main.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +int main(int argc, char** argv) { + int ret = -1; + + try { + testing::InitGoogleTest(&argc, argv); + } catch(...) { + std::cout << "Exception occurred" << std::endl; + } + + try { + ret = RUN_ALL_TESTS(); + } catch (const ::testing::internal::GoogleTestFailureException& e) { + ret = -1; + std::cout << "GoogleTestFailureException was thrown:" << e.what() << std::endl; + } + + return ret; +} diff --git a/packaging/hal-api-common.spec b/packaging/hal-api-common.spec index 9704ee6..b6e21ee 100644 --- a/packaging/hal-api-common.spec +++ b/packaging/hal-api-common.spec @@ -17,6 +17,7 @@ BuildRequires: cmake BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(gio-2.0) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gmock) %description %{name} interface @@ -40,6 +41,9 @@ cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DCMAKE_LIBDIR_PREFIX=%{_libdir}/ cp %{SOURCE1} . make %{?jobs:-j%jobs} +%check +(cd haltests && LD_LIBRARY_PATH=../ ctest -V) + %install rm -rf %{buildroot} %make_install -- 2.7.4 From 6735d5d11651e59b3b5d749b7af28fcec19302dd Mon Sep 17 00:00:00 2001 From: Seungha Son Date: Thu, 14 Jan 2021 18:57:06 +0900 Subject: [PATCH 07/16] halapi: Include stdbool header for common.h The stdbool.h file is required to use the bool data type. Change-Id: I0cc08f2a0229bfb64ddbcf46c1cd69da1a183c82 Signed-off-by: Seungha Son --- src/common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common.h b/src/common.h index c8b263b..4121c1b 100644 --- a/src/common.h +++ b/src/common.h @@ -17,6 +17,7 @@ #ifndef __COMMON_H__ #define __COMMON_H__ +#include #include #include "hal-common.h" -- 2.7.4 From 586e27a77f64145dcb5878c97b2fea211e26c846 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 18 Jan 2021 19:48:06 +0900 Subject: [PATCH 08/16] halapi: Fix fault by using backend instance before dlclose backend library When try to use backend->name, backend->vendor variables after dlclose(handle) of HAL backend shared library, segmentation fault happen. So that move dlclose(hanlde) at the end of hal_common_put_backend() to fix the segmentation fault. Change-Id: Icc89e26b0ff11706657f1bfdeff16eba17f255d9 Signed-off-by: Chanwoo Choi --- src/hal-api-common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hal-api-common.c b/src/hal-api-common.c index 896691c..b07765d 100644 --- a/src/hal-api-common.c +++ b/src/hal-api-common.c @@ -172,11 +172,14 @@ int hal_common_put_backend(enum hal_module module, void *data) } } + _I("Put HAL backend: name(%s)/vendor(%s)\n", + backend->name, backend->vendor); + if (handle) dlclose(handle); - _I("Put HAL backend: name(%s)/vendor(%s)\n", - backend->name, backend->vendor); + hal_module_info[module].library_backend = NULL; + hal_module_info[module].library_handle = NULL; return TIZEN_ERROR_NONE; } -- 2.7.4 From 3403d9e6b8ba05af3cf54f551797946fae4b2934 Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Tue, 19 Jan 2021 09:35:10 +0900 Subject: [PATCH 09/16] halapi: Add /etc/ld.so.conf.d/libhal-api.conf A ldd and ldconfig commands do not work. Example1) "ldd /usr/bin/deviced | grep libhal-api-common" Example2) "ldconfig -p | grep libhal-api-common" Change-Id: I42d0ece00df2ebd4ef36e4f215140a31204397b0 Signed-off-by: INSUN PYO --- packaging/hal-api-common.spec | 5 +++++ packaging/libhal-api.conf | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 packaging/libhal-api.conf diff --git a/packaging/hal-api-common.spec b/packaging/hal-api-common.spec index b6e21ee..1831a56 100644 --- a/packaging/hal-api-common.spec +++ b/packaging/hal-api-common.spec @@ -10,6 +10,7 @@ Group: Development/Libraries License: Apache-2.0 Source0: %{name}-%{version}.tar.gz Source1: %{name}.manifest +Source2: libhal-api.conf Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig @@ -48,6 +49,9 @@ make %{?jobs:-j%jobs} rm -rf %{buildroot} %make_install +mkdir -p %{buildroot}%{_sysconfdir}/ld.so.conf.d/ +install -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/ld.so.conf.d/ + %clean rm -rf %{buildroot} @@ -63,6 +67,7 @@ rm -rf %{buildroot} %manifest %{name}.manifest %defattr(-,root,root,-) %{_libdir}/hal/*.so* +%{_sysconfdir}/ld.so.conf.d/libhal-api.conf %files -n %{devel_name} %defattr(-,root,root,-) diff --git a/packaging/libhal-api.conf b/packaging/libhal-api.conf new file mode 100644 index 0000000..b275885 --- /dev/null +++ b/packaging/libhal-api.conf @@ -0,0 +1,2 @@ +/usr/lib/hal +/usr/lib64/hal -- 2.7.4 From e87d1e2372f7b69b3dc723c22e0ec824fbcc557b Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Wed, 20 Jan 2021 09:42:28 +0900 Subject: [PATCH 10/16] packaging: create hal directory to use backend packages If hal.img will be split from core image, it has to exist hal directory under root directory before mounting hal.img. Otherwise, it can't mount anywhere to use hal-backend. This patch is for preparing to use hal.img. - The mounting hal.img will be did in ramdisk. Change-Id: I8ef56c0e383e142269c4164d7cfeba9560fbb039 Signed-off-by: Jaehoon Chung --- packaging/hal-api-common.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/hal-api-common.spec b/packaging/hal-api-common.spec index 1831a56..edb494a 100644 --- a/packaging/hal-api-common.spec +++ b/packaging/hal-api-common.spec @@ -50,6 +50,7 @@ rm -rf %{buildroot} %make_install mkdir -p %{buildroot}%{_sysconfdir}/ld.so.conf.d/ +mkdir -p %{buildroot}/hal install -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}/ld.so.conf.d/ %clean @@ -68,6 +69,7 @@ rm -rf %{buildroot} %defattr(-,root,root,-) %{_libdir}/hal/*.so* %{_sysconfdir}/ld.so.conf.d/libhal-api.conf +/hal/ %files -n %{devel_name} %defattr(-,root,root,-) -- 2.7.4 From e4c687e484e1025a33c8e88dfef4a53780381a67 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 20 Jan 2021 13:42:47 +0900 Subject: [PATCH 11/16] packaging: Remove redundant separator The spec file has passed the redundant separator ('/') with %{_libdir}. It is not needed. So that remove it. Change-Id: I531f6a6449e6ab3defec82bb4383ecc22045dc20 Signed-off-by: Chanwoo Choi --- packaging/hal-api-common.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/hal-api-common.spec b/packaging/hal-api-common.spec index edb494a..9ec7b05 100644 --- a/packaging/hal-api-common.spec +++ b/packaging/hal-api-common.spec @@ -36,7 +36,7 @@ Requires: %{name} = %{version}-%{release} %prep %setup -q -cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DCMAKE_LIBDIR_PREFIX=%{_libdir}/ +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DCMAKE_LIBDIR_PREFIX=%{_libdir} %build cp %{SOURCE1} . -- 2.7.4 From 3cf50c793cfacd86070409222b851a718c885c80 Mon Sep 17 00:00:00 2001 From: Chang Joo Lee Date: Thu, 21 Jan 2021 13:11:18 +0900 Subject: [PATCH 12/16] halapi: Fix pkgconfig .pc file about libdir The commit e4c687e484e1 ("packaging: Remove redundant separator") has missed the update of .pc file. This patch fix the wrong path issue. Change-Id: I26847c506dcd801030ed616822fccca8595f97ef Fixes: e4c687e484e1 ("packaging: Remove redundant separator") Signed-off-by: Chang Joo Lee Signed-off-by: Chanwoo Choi --- hal-api-common.pc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hal-api-common.pc b/hal-api-common.pc index 5a281de..782a604 100644 --- a/hal-api-common.pc +++ b/hal-api-common.pc @@ -3,7 +3,7 @@ package_name=hal-api-common prefix=@PREFIX@ exec_prefix=@EXEC_PREFIX@/hal -libdir=@LIBDIR@hal +libdir=@LIBDIR@/hal includedir=@INCLUDEDIR@/hal Name: ${package_name} -- 2.7.4 From 4031522707edd041f57c1b149c018af0c4a60490 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Wed, 27 Jan 2021 09:27:40 +0900 Subject: [PATCH 13/16] halapi: fix wrong module's number about CODEC Fix wrong module's number about CODEC. It's not HAL_MODULE_UNKNOWN. Change-Id: I9cdc3d58ee2feb3bf5137d973972033741c8e352 Signed-off-by: Jaehoon Chung --- src/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 4121c1b..f07d7c6 100644 --- a/src/common.h +++ b/src/common.h @@ -405,7 +405,7 @@ static struct __hal_module_info { }, [HAL_MODULE_CODEC] = { .group = HAL_GROUP_MULTIMEDIA, - .module = HAL_MODULE_UNKNOWN, + .module = HAL_MODULE_CODEC, .license = HAL_LICENSE_APACHE_2_0, .module_name = "CODEC", .library_name = NULL, -- 2.7.4 From f0ab0f8bc72ecb9c2c27d0c46efcb93c97636a2d Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Fri, 29 Jan 2021 16:52:35 +0900 Subject: [PATCH 14/16] halapi: Ignore already fully put hal backend In hal_common_put_backend(), requested module backend can be already put fully. For the case, ignore the hal backend. Change-Id: I7eef57fa12273760d28b22738ee878ac423da651 Signed-off-by: Seung-Woo Kim --- src/hal-api-common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hal-api-common.c b/src/hal-api-common.c index b07765d..c4e2372 100644 --- a/src/hal-api-common.c +++ b/src/hal-api-common.c @@ -163,7 +163,12 @@ int hal_common_put_backend(enum hal_module module, void *data) backend = hal_module_info[module].library_backend; handle = hal_module_info[module].library_handle; - if (backend && backend->exit) { + if (!backend) { + _I("Already fully put for HAL module (%d)\n", module); + return TIZEN_ERROR_NONE; + } + + if (backend->exit) { ret = backend->exit(data); if (ret < 0) { _E("Failed to exit backend: name(%s)/vendor(%s)\n", -- 2.7.4 From 4dbcdebdac3dc54df2c4fe0efaa32cbccabbf4f8 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Fri, 29 Jan 2021 19:27:56 +0900 Subject: [PATCH 15/16] halapi: Check enum range for backend_abi_min_version To avoid out-of-bounds access of version str array, check value range for data->backend_abi_min_version always. Change-Id: I3fb05ab9a27394f817937b589ce7751da0467a69 Signed-off-by: Seung-Woo Kim --- src/hal-api-common.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hal-api-common.c b/src/hal-api-common.c index c4e2372..c476024 100644 --- a/src/hal-api-common.c +++ b/src/hal-api-common.c @@ -227,6 +227,13 @@ int hal_common_check_backend_abi_version(enum hal_module module, if (g_platform_curr_abi_version != data->platform_abi_version) continue; + if (data->backend_min_abi_version <= HAL_ABI_VERSION_UNKNOWN || + data->backend_min_abi_version >= HAL_ABI_VERSION_END) { + _E("wrong data in backend_min_abi_version %d\n", + data->backend_min_abi_version); + return TIZEN_ERROR_INVALID_PARAMETER; + } + if (abi_version <= data->platform_abi_version && abi_version >= data->backend_min_abi_version) return TIZEN_ERROR_NONE; -- 2.7.4 From 40f47d6fccef8f53e3e7be6d7d328fc024f6c5c5 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 2 Feb 2021 15:46:54 +0900 Subject: [PATCH 16/16] halapi: Fix cpp build issue when including hal-common.h If the defined enum value is not sequential, some build error happen as following. So that fix this issue by making enum hal_module sequential. And remove the temporary defined HAL_MODULE_FOO. [Build error message with cpp compiler] "sorry, unimplemented: non-trivial designated initializers not supported " Change-Id: I8dcd8c7c11807d8873d8e92413e4137ce84a3c6f Signed-off-by: Chanwoo Choi --- include/hal-common.h | 20 +++++++++++--------- src/common.h | 24 ------------------------ 2 files changed, 11 insertions(+), 33 deletions(-) diff --git a/include/hal-common.h b/include/hal-common.h index 09df968..daffd14 100644 --- a/include/hal-common.h +++ b/include/hal-common.h @@ -41,7 +41,6 @@ enum hal_group { HAL_GROUP_TELEPHONY, HAL_GROUP_LOCATION, HAL_GROUP_SYSTEM, - HAL_GROUP_MISCELLANEOUS, HAL_GROUP_END, }; @@ -49,13 +48,13 @@ enum hal_module { HAL_MODULE_UNKNOWN = 0, /* HAL_GROUP_GRAPHICS */ - HAL_MODULE_TBM = 1, + HAL_MODULE_TBM, HAL_MODULE_TDM, HAL_MODULE_COREGL, HAL_MODULE_INPUT, /* HAL_GROUP_MULTIMEDIA */ - HAL_MODULE_AUDIO = 15, + HAL_MODULE_AUDIO, HAL_MODULE_CAMERA, HAL_MODULE_RADIO, HAL_MODULE_CODEC, @@ -63,7 +62,7 @@ enum hal_module { HAL_MODULE_ALSAUCM, /* HAL_GROUP_CONNECTIVITY */ - HAL_MODULE_BLUETOOTH = 30, + HAL_MODULE_BLUETOOTH, HAL_MODULE_WIFI, HAL_MODULE_NAN, HAL_MODULE_NFC, @@ -72,13 +71,13 @@ enum hal_module { HAL_MODULE_MTP, /* HAL_GROUP_TELEPHONY */ - HAL_MODULE_TELEPHONY = 45, + HAL_MODULE_TELEPHONY, /* HAL_GROUP_LOCATION */ - HAL_MODULE_LOCATION = 50, + HAL_MODULE_LOCATION, /* HAL_GROUP_SYSTEM */ - HAL_MODULE_COMMON = 55, + HAL_MODULE_COMMON, HAL_MODULE_POWER, HAL_MODULE_SENSOR, HAL_MODULE_PERIPHERAL, @@ -94,8 +93,11 @@ enum hal_module { HAL_MODULE_DEVICE_USB_GADGET, HAL_MODULE_DEVICE_HAPTIC, - /* HAL_GROUP_MISCELLANEOUS */ - HAL_MODULE_FOO, /* FIXME: Add for test and will be removed */ + /* + * TODO: If need to add new module, have to add it below + * without modifying already defined module id. + */ + HAL_MODULE_END, }; diff --git a/src/common.h b/src/common.h index f07d7c6..af1a0f1 100644 --- a/src/common.h +++ b/src/common.h @@ -287,16 +287,6 @@ struct hal_abi_version_match { .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, }, }, - - /* FIXME: Add for test and will be removed */ - /* HAL_GROUP_MISCELLANEOUS */ - [HAL_MODULE_FOO] = { - /* FIXME: Need to be initialized by configuration file like xml */ - [0] = { - .platform_abi_version = HAL_ABI_VERSION_TIZEN_6_5, - .backend_min_abi_version = HAL_ABI_VERSION_TIZEN_6_5, - }, - }, }; static struct __hal_module_info { @@ -734,20 +724,6 @@ static struct __hal_module_info { .abi_versions = abi_version_match_data[HAL_MODULE_DEVICE_HAPTIC], .hal_api = true, }, - - /* HAL_GROUP_MISCELLANEOUS */ - [HAL_MODULE_FOO] = { /* FIXME: Add for test and will be removed */ - .group = HAL_GROUP_SYSTEM, - .module = HAL_MODULE_FOO, - .license = HAL_LICENSE_APACHE_2_0, - .module_name = "FOO", - .library_name = "/hal/lib/libhal-backend-foo.so", - .library_name_64bit = "/hal/lib64/libhal-backend-foo.so", - .symbol_name = "hal_backend_foo_data", - .num_abi_versions = ARRAY_SIZE(abi_version_match_data[HAL_MODULE_FOO]), - .abi_versions = abi_version_match_data[HAL_MODULE_FOO], - .hal_api = true, - }, }; #endif /* __COMMON_H__ */ -- 2.7.4