2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <glib-object.h>
22 #include <json-c/json.h>
23 #include <json-c/arraylist.h>
25 #include "hal-common.h"
26 #include "hal-common-interface.h"
29 #include "hal-api-conf.h"
30 #include "hal-api-list.h"
32 #ifdef HAL_API_CONF_JSON
33 static enum hal_abi_version _platform_abi_version = HAL_ABI_VERSION_END;
35 static json_object *_json_file_object = NULL;
38 static GHashTable *_module_hash = NULL;
40 static int _usage_count = 0;
42 __attribute__ ((visibility("default")))
43 void _destroy_module_info(gpointer data)
45 #define SAFE_FREE_AND_NULL(x) \
53 struct __hal_module_info *info = (struct __hal_module_info *)data;
56 SAFE_FREE_AND_NULL(info->module_name);
57 SAFE_FREE_AND_NULL(info->backend_module_name);
58 SAFE_FREE_AND_NULL(info->library_name);
59 SAFE_FREE_AND_NULL(info->library_name_64bit);
60 SAFE_FREE_AND_NULL(info->symbol_name);
61 SAFE_FREE_AND_NULL(info->abi_versions);
62 SAFE_FREE_AND_NULL(info);
66 #ifdef HAL_API_CONF_JSON
67 static enum hal_abi_version __convert_abi_version_str_to_enum(const char *abi_version) {
69 for (version = HAL_ABI_VERSION_UNKNOWN + 1; version < HAL_ABI_VERSION_END; version++){
70 if (g_strcmp0(abi_version, hal_abi_version_str[version]) == 0)
71 return (enum hal_abi_version)version;
74 return HAL_ABI_VERSION_UNKNOWN;
77 static const char *__convert_module_to_string(enum hal_module module)
79 return hal_module_string[module];
82 static enum hal_group __convert_group_str_to_enum(const char * group)
84 enum hal_group group_idx;
86 for (group_idx = HAL_GROUP_UNKNOWN + 1; group_idx < HAL_GROUP_END; group_idx++) {
87 if (g_strcmp0(group, hal_group_string[group_idx]) == 0)
91 return HAL_GROUP_UNKNOWN;
94 static enum hal_license __convert_license_str_to_enum(const char *license)
96 if (g_strcmp0(license, "APACHE_2_0") == 0)
97 return HAL_LICENSE_APACHE_2_0;
99 if (g_strcmp0(license, "FLORA") == 0)
100 return HAL_LICENSE_FLORA;
102 if (g_strcmp0(license, "MIT") == 0)
103 return HAL_LICENSE_MIT;
105 return HAL_LICENSE_UNKNOWN;
108 static const char * __get_json_object_string(json_object *object, const char *key)
110 json_object *temp_object = NULL;
112 json_object_object_get_ex(object, key, &temp_object);
113 return json_object_get_string(temp_object);
116 static struct __hal_module_info *__create_hal_module_info(enum hal_module module, json_object *object)
118 struct __hal_module_info *info;
119 GList *abi_list = NULL;
120 GList *iter_list = NULL;
122 json_object *abi_versions_array;
123 json_object *tmp_object;
126 info = (struct __hal_module_info *)calloc(1, sizeof(struct __hal_module_info));
128 _E("Out of Memory\n");
132 info->module = module;
133 info->module_name = g_strdup(__convert_module_to_string(module));
134 info->backend_module_name = g_strdup(__convert_module_to_string(backend_module));
136 tmp = __get_json_object_string(object, "group");
137 info->group = __convert_group_str_to_enum(tmp);
139 tmp = __get_json_object_string(object, "license");
140 info->license = __convert_license_str_to_enum(tmp);
142 info->library_name = g_strdup(__get_json_object_string(object, "library_name"));
143 info->library_name_64bit = g_strdup(__get_json_object_string(object, "library_name_64bit"));
144 info->symbol_name = g_strdup(__get_json_object_string(object, "symbol_name"));
146 if (info->library_name && info->library_name_64bit && info->symbol_name)
147 info->hal_api = true;
149 json_object_object_get_ex(object, "abi_versions", &abi_versions_array);
150 if (json_object_get_type(abi_versions_array) != json_type_array)
153 info->num_abi_versions = json_object_array_length(abi_versions_array);
154 if (info->num_abi_versions > 0) {
155 info->abi_versions = (struct hal_abi_version_match*)calloc(info->num_abi_versions,
156 sizeof(struct hal_abi_version_match));
157 if (info->abi_versions == NULL) {
158 _E("Out of Memory\n");
159 _destroy_module_info(info);
163 for (int i = 0; i < info->num_abi_versions; i++) {
164 json_object *abi_object = json_object_array_get_idx(abi_versions_array, i);
166 tmp = __get_json_object_string(abi_object, "platform_abi_version");
167 info->abi_versions[list_index].platform_abi_version =
168 __convert_abi_version_str_to_enum(tmp);
170 tmp = __get_json_object_string(abi_object, "backend_min_abi_version");
171 info->abi_versions[list_index].backend_min_abi_version =
172 __convert_abi_version_str_to_enum(tmp);
180 static struct __hal_module_info* _get_module_info(enum hal_module module)
182 struct __hal_module_info *info = NULL;
183 json_object *module_array_object = NULL;
184 const char *group_name = NULL;
185 const char *module_name = NULL;
188 if (!_json_file_object || !_module_hash)
191 info = (struct __hal_module_info*)g_hash_table_lookup(_module_hash, GINT_TO_POINTER(module));
195 json_object_object_get_ex(_json_file_object, "MODULE_INFO", &module_array_object);
196 module_name = __convert_module_to_string(module);
198 for (i = 0; i < json_object_array_length(module_array_object); i++) {
199 json_object *temp_object = json_object_array_get_idx(module_array_object, i);
200 const char *value = __get_json_object_string(temp_object, "module");
201 if (g_strcmp0(value, module_name) == 0) {
202 info = __create_hal_module_info(module, temp_object);
204 _E("Failed to create hal module info\n");
206 g_hash_table_insert(_module_hash, GINT_TO_POINTER(module), info);
214 static struct __hal_module_info* _get_module_info(enum hal_module module)
216 return &g_hal_module_info[module];
220 static struct __hal_module_info* _get_module_info_with_library_name(enum hal_module module,
221 const char *library_name)
223 struct __hal_module_info *info = NULL, *new_info = NULL, *tmp_info = NULL;
224 json_object *module_array_object = NULL;
225 const char *group_name = NULL;
226 const char *module_name = NULL;
227 char *library_name_prefix = NULL;
230 #ifdef HAL_API_CONF_JSON
231 if (!_json_file_object)
235 if (!_module_hash | !library_name)
238 tmp_info = _get_module_info(module);
239 if (tmp_info == NULL) {
240 _E("Failed to get HAL module(%d) information\n", module);
244 if (tmp_info->backend_module_name == NULL) {
245 _E("Don't support HAL backend of HAL module(%s)\n",
246 tmp_info->module_name);
249 library_name_prefix = g_strdup_printf("libhal-backend-%s",
250 tmp_info->backend_module_name);
251 if (!library_name_prefix) {
252 _E("Failed to allocate library_name_prefix of HAL module(%s)\n",
253 tmp_info->module_name);
257 if (!g_str_has_prefix(library_name, library_name_prefix)) {
258 _E("Invalid library name(%s) of HAL module(%s)\n",
259 library_name, tmp_info->module_name);
263 /* Find module info with the passed library name */
264 info = (struct __hal_module_info*)g_hash_table_lookup(_module_hash,
265 (gpointer)library_name);
267 g_free(library_name_prefix);
271 /* Create new module info with the passed library name */
274 new_info = (struct __hal_module_info *)calloc(1,
275 sizeof(struct __hal_module_info));
276 if (new_info == NULL) {
277 _E("Failed to allocate the memory\n");
281 new_info->usage_count = 0;
282 new_info->group = info->group;
283 new_info->module = info->module;
284 new_info->license = info->license;
285 new_info->module_name = g_strdup(info->module_name);
286 #if defined(__aarch64__)
287 new_info->library_name_64bit = g_strdup_printf("/hal/lib64/%s", library_name);
289 new_info->library_name = g_strdup_printf("/hal/lib/%s", library_name);
291 new_info->symbol_name = g_strdup(info->symbol_name);
292 new_info->num_abi_versions = info->num_abi_versions;
293 new_info->abi_versions = info->abi_versions;
294 new_info->hal_api = info->hal_api;
295 new_info->hal_backend_extension = true;
297 g_hash_table_insert(_module_hash, (gpointer)library_name, new_info);
300 g_free(library_name_prefix);
305 __attribute__ ((visibility("default")))
306 struct __hal_module_info* _hal_api_conf_get_module_info(enum hal_module module,
307 const char *library_name)
309 #ifdef HAL_API_CONF_JSON
310 if (!_json_file_object)
318 return _get_module_info(module);
320 return _get_module_info_with_library_name(module, library_name);
324 enum hal_abi_version _hal_api_conf_get_platform_abi_version(void)
326 #ifdef HAL_API_CONF_JSON
327 const char *abi_version = NULL;
328 bool ret_initialized;
329 json_object *platform_obj = NULL;
331 if (_platform_abi_version != HAL_ABI_VERSION_END)
332 return _platform_abi_version;
334 if (!_json_file_object || !_module_hash)
335 return HAL_ABI_VERSION_UNKNOWN;
337 abi_version = __get_json_object_string(_json_file_object, "PLATFORM_ABI_VERSION");
338 _platform_abi_version = __convert_abi_version_str_to_enum(abi_version);
340 return _platform_abi_version;
342 return g_platform_curr_abi_version;
346 __attribute__ ((visibility("default")))
347 int _hal_api_conf_init(void)
349 if (_usage_count++ > 0)
352 #ifdef HAL_API_CONF_JSON
353 _json_file_object = json_object_from_file(HAL_CONFIGURATION_PATH);
354 if (_json_file_object == NULL) {
355 _E("Failed to parsing json configuration file : %s\n", json_util_get_last_err());
360 _module_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, _destroy_module_info);
364 #ifdef HAL_API_CONF_JSON
369 g_hash_table_remove_all(_module_hash);
370 g_hash_table_unref(_module_hash);
377 __attribute__ ((visibility("default")))
378 void _hal_api_conf_exit(void)
381 if (_usage_count != 0)
384 #ifdef HAL_API_CONF_JSON
385 if (_json_file_object) {
386 json_object_put(_json_file_object);
387 _json_file_object = NULL;
392 g_hash_table_remove_all(_module_hash);
393 g_hash_table_unref(_module_hash);