halapi: conf: Remove unused local variables
[platform/hal/api/common.git] / src / hal-api-conf.c
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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 #include <stdlib.h>
18
19 #include <gio/gio.h>
20 #include <glib-object.h>
21
22 #include <json-c/json.h>
23 #include <json-c/arraylist.h>
24
25 #include "hal-common.h"
26 #include "hal-common-interface.h"
27
28 #include "common.h"
29 #include "hal-api-conf.h"
30 #include "hal-api-list.h"
31
32 #ifdef HAL_API_CONF_JSON
33 static enum hal_abi_version _platform_abi_version = HAL_ABI_VERSION_END;
34
35 static json_object *_json_file_object = NULL;
36 #endif
37
38 static GHashTable *_module_hash = NULL;
39
40 static int _usage_count = 0;
41
42 __attribute__ ((visibility("default")))
43 void _destroy_module_info(gpointer data)
44 {
45 #define SAFE_FREE_AND_NULL(x) \
46 do { \
47         if (x) { \
48                 free(x); \
49                 x = NULL; \
50         } \
51 } while (0);
52
53         struct __hal_module_info *info = (struct __hal_module_info *)data;
54
55         if (info) {
56                 SAFE_FREE_AND_NULL(info->module_name);
57                 SAFE_FREE_AND_NULL(info->library_name);
58                 SAFE_FREE_AND_NULL(info->library_name_64bit);
59                 SAFE_FREE_AND_NULL(info->symbol_name);
60                 SAFE_FREE_AND_NULL(info->abi_versions);
61                 SAFE_FREE_AND_NULL(info);
62         }
63 }
64
65 #ifdef HAL_API_CONF_JSON
66 static enum hal_abi_version __convert_abi_version_str_to_enum(const char *abi_version) {
67         int version;
68         for (version = HAL_ABI_VERSION_UNKNOWN + 1; version < HAL_ABI_VERSION_END; version++){
69                 if (g_strcmp0(abi_version, hal_abi_version_str[version]) == 0)
70                         return (enum hal_abi_version)version;
71         }
72
73         return HAL_ABI_VERSION_UNKNOWN;
74 }
75
76 static const char *__convert_module_to_string(enum hal_module module)
77 {
78         return hal_module_string[module];
79 }
80
81 static enum hal_group __convert_group_str_to_enum(const char * group)
82 {
83         enum hal_group group_idx;
84
85         for (group_idx = HAL_GROUP_UNKNOWN + 1; group_idx < HAL_GROUP_END; group_idx++) {
86                 if (g_strcmp0(group, hal_group_string[group_idx]) == 0)
87                         return group_idx;
88         }
89
90         return HAL_GROUP_UNKNOWN;
91 }
92
93 static enum hal_license __convert_license_str_to_enum(const char *license)
94 {
95         if (g_strcmp0(license, "APACHE_2_0") == 0)
96                 return HAL_LICENSE_APACHE_2_0;
97
98         if (g_strcmp0(license, "FLORA") == 0)
99                 return HAL_LICENSE_FLORA;
100
101         if (g_strcmp0(license, "MIT") == 0)
102                 return HAL_LICENSE_MIT;
103
104         return HAL_LICENSE_UNKNOWN;
105 }
106
107 static const char * __get_json_object_string(json_object *object, const char *key)
108 {
109         json_object *temp_object = NULL;
110
111         json_object_object_get_ex(object, key, &temp_object);
112         return json_object_get_string(temp_object);
113 }
114
115 static struct __hal_module_info *__create_hal_module_info(enum hal_module module, json_object *object)
116 {
117         struct __hal_module_info *info;
118         GList *abi_list = NULL;
119         GList *iter_list = NULL;
120         int list_index = 0;
121         json_object *abi_versions_array;
122         json_object *tmp_object;
123         const char *tmp;
124
125         info = (struct __hal_module_info *)calloc(1, sizeof(struct __hal_module_info));
126         if (info == NULL) {
127                 _E("Out of Memory\n");
128                 return NULL;
129         }
130
131         info->module = module;
132         info->module_name = g_strdup(__convert_module_to_string(module));
133
134         tmp = __get_json_object_string(object, "group");
135         info->group = __convert_group_str_to_enum(tmp);
136
137         tmp = __get_json_object_string(object, "license");
138         info->license = __convert_license_str_to_enum(tmp);
139
140         info->library_name = g_strdup(__get_json_object_string(object, "library_name"));
141         info->library_name_64bit = g_strdup(__get_json_object_string(object, "library_name_64bit"));
142         info->symbol_name = g_strdup(__get_json_object_string(object, "symbol_name"));
143
144         if (info->library_name && info->library_name_64bit && info->symbol_name)
145                 info->hal_api = true;
146
147         json_object_object_get_ex(object, "abi_versions", &abi_versions_array);
148         if (json_object_get_type(abi_versions_array) != json_type_array)
149                 return info;
150
151         info->num_abi_versions = json_object_array_length(abi_versions_array);
152         if (info->num_abi_versions > 0) {
153                 info->abi_versions = (struct hal_abi_version_match*)calloc(info->num_abi_versions,
154                                 sizeof(struct hal_abi_version_match));
155                 if (info->abi_versions == NULL) {
156                         _E("Out of Memory\n");
157                         _destroy_module_info(info);
158                         return NULL;
159                 }
160
161                 for (int i = 0; i < info->num_abi_versions; i++) {
162                         json_object *abi_object = json_object_array_get_idx(abi_versions_array, i);
163
164                         tmp = __get_json_object_string(abi_object, "platform_abi_version");
165                         info->abi_versions[list_index].platform_abi_version =
166                                 __convert_abi_version_str_to_enum(tmp);
167
168                         tmp = __get_json_object_string(abi_object, "backend_min_abi_version");
169                         info->abi_versions[list_index].backend_min_abi_version =
170                                 __convert_abi_version_str_to_enum(tmp);
171                         list_index++;
172                 }
173         }
174
175         return info;
176 }
177
178 static struct __hal_module_info* _get_module_info(enum hal_module module)
179 {
180         struct __hal_module_info *info = NULL;
181         json_object *module_array_object = NULL;
182         const char *group_name = NULL;
183         const char *module_name = NULL;
184         int i;
185
186         if (!_json_file_object || !_module_hash)
187                 return NULL;
188
189         info = (struct __hal_module_info*)g_hash_table_lookup(_module_hash, GINT_TO_POINTER(module));
190         if (info != NULL)
191                 return info;
192
193         json_object_object_get_ex(_json_file_object, "MODULE_INFO", &module_array_object);
194         module_name = __convert_module_to_string(module);
195
196         for (i = 0; i < json_object_array_length(module_array_object); i++) {
197                 json_object *temp_object = json_object_array_get_idx(module_array_object, i);
198                 const char *value = __get_json_object_string(temp_object, "module");
199                 if (g_strcmp0(value, module_name) == 0) {
200                         info = __create_hal_module_info(module, temp_object);
201                         if (info == NULL)
202                                 _E("Failed to create hal module info\n");
203                         else
204                                 g_hash_table_insert(_module_hash, GINT_TO_POINTER(module), info);
205                         break;
206                 }
207         }
208
209         return info;
210 }
211 #else
212 static struct __hal_module_info* _get_module_info(enum hal_module module)
213 {
214         return &g_hal_module_info[module];
215 }
216 #endif
217
218 static struct __hal_module_info* _get_module_info_with_library_name(enum hal_module module,
219                                                                 const char *library_name)
220 {
221         struct __hal_module_info *info = NULL, *new_info = NULL;
222         json_object *module_array_object = NULL;
223         const char *group_name = NULL;
224         const char *module_name = NULL;
225         int ret;
226
227 #ifdef HAL_API_CONF_JSON
228         if (!_json_file_object)
229                 return NULL;
230 #endif
231
232         if (!_module_hash | !library_name)
233                 return NULL;
234
235         if (!g_str_has_prefix(library_name, "libhal-backend-")) {
236                 _E("Invalid library name(%s) of HAL module(%d)\n",
237                                 library_name, module);
238                 return NULL;
239         }
240
241         /* Find module info with the passed library name */
242         info = (struct __hal_module_info*)g_hash_table_lookup(_module_hash,
243                                                 (gpointer)library_name);
244         if (info)
245                 return info;
246
247         /* Create new module info with the passed library name */
248         info = _get_module_info(module);
249         if (info == NULL) {
250                 _E("Failed to get HAL module(%d) information\n", module);
251                 return NULL;
252         }
253
254         new_info = (struct __hal_module_info *)calloc(1,
255                                         sizeof(struct __hal_module_info));
256         if (new_info == NULL) {
257                 _E("Failed to allocate the memory\n");
258                 return NULL;
259         }
260
261         new_info->usage_count = 0;
262         new_info->group = info->group;
263         new_info->module = info->module;
264         new_info->license = info->license;
265         new_info->module_name = g_strdup(info->module_name);
266 #if defined(__aarch64__)
267         new_info->library_name_64bit = g_strdup_printf("/hal/lib64/%s", library_name);
268 #else
269         new_info->library_name = g_strdup_printf("/hal/lib/%s", library_name);
270 #endif
271         new_info->symbol_name = g_strdup(info->symbol_name);
272         new_info->num_abi_versions = info->num_abi_versions;
273         new_info->abi_versions = info->abi_versions;
274         new_info->hal_api = info->hal_api;
275         new_info->hal_backend_extension = true;
276
277         g_hash_table_insert(_module_hash, (gpointer)library_name, new_info);
278
279         return new_info;
280 }
281
282 __attribute__ ((visibility("default")))
283 struct __hal_module_info* _hal_api_conf_get_module_info(enum hal_module module,
284                                                         const char *library_name)
285 {
286 #ifdef HAL_API_CONF_JSON
287         if (!_json_file_object)
288                 return NULL;
289 #endif
290
291         if (!_module_hash)
292                 return NULL;
293
294         if (!library_name)
295                 return _get_module_info(module);
296         else
297                 return _get_module_info_with_library_name(module, library_name);
298 }
299
300
301 enum hal_abi_version _hal_api_conf_get_platform_abi_version(void)
302 {
303 #ifdef HAL_API_CONF_JSON
304         const char *abi_version = NULL;
305         bool ret_initialized;
306         json_object *platform_obj = NULL;
307
308         if (_platform_abi_version != HAL_ABI_VERSION_END)
309                 return _platform_abi_version;
310
311         if (!_json_file_object || !_module_hash)
312                 return HAL_ABI_VERSION_UNKNOWN;
313
314         abi_version = __get_json_object_string(_json_file_object, "PLATFORM_ABI_VERSION");
315         _platform_abi_version = __convert_abi_version_str_to_enum(abi_version);
316
317         return _platform_abi_version;
318 #else
319         return g_platform_curr_abi_version;
320 #endif
321 }
322
323 __attribute__ ((visibility("default")))
324 int _hal_api_conf_init(void)
325 {
326         if (_usage_count++ > 0)
327                 return 0;
328
329 #ifdef HAL_API_CONF_JSON
330         _json_file_object = json_object_from_file(HAL_CONFIGURATION_PATH);
331         if (_json_file_object == NULL) {
332                 _E("Failed to parsing json configuration file : %s\n", json_util_get_last_err());
333                 goto err;
334         }
335 #endif
336
337         _module_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, _destroy_module_info);
338
339         return 0;
340
341 #ifdef HAL_API_CONF_JSON
342 err:
343         _usage_count--;
344
345         if (_module_hash) {
346                 g_hash_table_remove_all(_module_hash);
347                 g_hash_table_unref(_module_hash);
348         }
349
350         return -EINVAL;
351 #endif
352 }
353
354 __attribute__ ((visibility("default")))
355 void _hal_api_conf_exit(void)
356 {
357         _usage_count--;
358         if (_usage_count != 0)
359                 return;
360
361 #ifdef HAL_API_CONF_JSON
362         if (_json_file_object) {
363                 json_object_put(_json_file_object);
364                 _json_file_object = NULL;
365         }
366 #endif
367
368         if (_module_hash) {
369                 g_hash_table_remove_all(_module_hash);
370                 g_hash_table_unref(_module_hash);
371         }
372 }