a3c6c250013464c11fe32c0b814262e9b8f1849a
[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 "hal-common.h"
23 #include "hal-common-interface.h"
24
25 #include "common.h"
26 #include "hal-api-conf.h"
27 #include "hal-api-list.h"
28
29 static GHashTable *_module_hash = NULL;
30
31 static int _usage_count = 0;
32
33 __attribute__ ((visibility("default")))
34 void _destroy_module_info(gpointer data)
35 {
36 #define SAFE_FREE_AND_NULL(x) \
37 do { \
38         if (x) { \
39                 free(x); \
40                 x = NULL; \
41         } \
42 } while (0);
43
44         struct __hal_module_info *info = (struct __hal_module_info *)data;
45
46         if (info) {
47                 SAFE_FREE_AND_NULL(info->module_name);
48                 SAFE_FREE_AND_NULL(info->backend_module_name);
49                 SAFE_FREE_AND_NULL(info->library_name);
50                 SAFE_FREE_AND_NULL(info->library_name_64bit);
51                 SAFE_FREE_AND_NULL(info->symbol_name);
52                 SAFE_FREE_AND_NULL(info);
53         }
54 }
55
56 static struct __hal_module_info* _get_module_info(enum hal_module module)
57 {
58         return &g_hal_module_info[module];
59 }
60
61 static struct __hal_module_info* _get_module_info_with_library_name(enum hal_module module,
62                                                                 const char *library_name)
63 {
64         struct __hal_module_info *info = NULL, *new_info = NULL, *tmp_info = NULL;
65         const char *group_name = NULL;
66         const char *module_name = NULL;
67         char *library_name_prefix = NULL;
68         int ret;
69
70         if (!_module_hash || !library_name)
71                 return NULL;
72
73         tmp_info = _get_module_info(module);
74         if (tmp_info == NULL) {
75                 _E("Failed to get HAL module(%d) information\n", module);
76                 return NULL;
77         }
78
79         if (tmp_info->backend_module_name == NULL) {
80                 _E("Don't support HAL backend of HAL module(%s)\n",
81                                 tmp_info->module_name);
82                 return NULL;
83         }
84         library_name_prefix = g_strdup_printf("libhal-backend-%s",
85                                 tmp_info->backend_module_name);
86         if (!library_name_prefix) {
87                 _E("Failed to allocate library_name_prefix of HAL module(%s)\n",
88                                 tmp_info->module_name);
89                 return NULL;
90         }
91
92         if (!g_str_has_prefix(library_name, library_name_prefix)) {
93                 _E("Invalid library name(%s) of HAL module(%s)\n",
94                                 library_name, tmp_info->module_name);
95                 goto out;
96         }
97
98         /* Find module info with the passed library name */
99         info = (struct __hal_module_info*)g_hash_table_lookup(_module_hash,
100                                                 (gpointer)library_name);
101         if (info) {
102                 g_free(library_name_prefix);
103                 return info;
104         }
105
106         /* Create new module info with the passed library name */
107         info = tmp_info;
108
109         new_info = (struct __hal_module_info *)calloc(1,
110                                         sizeof(struct __hal_module_info));
111         if (new_info == NULL) {
112                 _E("Failed to allocate the memory\n");
113                 goto out;
114         }
115
116         new_info->usage_count = 0;
117         new_info->group = info->group;
118         new_info->module = info->module;
119         new_info->license = info->license;
120         new_info->module_name = g_strdup(info->module_name);
121 #if defined(__aarch64__)
122         new_info->library_name_64bit = g_strdup_printf("/hal/lib64/%s", library_name);
123 #else
124         new_info->library_name = g_strdup_printf("/hal/lib/%s", library_name);
125 #endif
126         new_info->symbol_name = g_strdup(info->symbol_name);
127         new_info->num_abi_versions = info->num_abi_versions;
128         new_info->abi_versions = info->abi_versions;
129         new_info->hal_api = info->hal_api;
130         new_info->hal_backend_extension = true;
131
132         g_hash_table_insert(_module_hash, (gpointer)library_name, new_info);
133
134 out:
135         g_free(library_name_prefix);
136
137         return new_info;
138 }
139
140 __attribute__ ((visibility("default")))
141 struct __hal_module_info* _hal_api_conf_get_module_info(enum hal_module module,
142                                                         const char *library_name)
143 {
144         if (!_module_hash)
145                 return NULL;
146
147         if (!library_name)
148                 return _get_module_info(module);
149         else
150                 return _get_module_info_with_library_name(module, library_name);
151 }
152
153
154 enum hal_abi_version _hal_api_conf_get_platform_abi_version(void)
155 {
156         return g_platform_curr_abi_version;
157 }
158
159 __attribute__ ((visibility("default")))
160 int _hal_api_conf_init(void)
161 {
162         if (_usage_count++ > 0)
163                 return 0;
164
165         _module_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, _destroy_module_info);
166
167         return 0;
168 }
169
170 __attribute__ ((visibility("default")))
171 void _hal_api_conf_exit(void)
172 {
173         _usage_count--;
174         if (_usage_count != 0)
175                 return;
176
177         if (_module_hash) {
178                 g_hash_table_remove_all(_module_hash);
179                 g_hash_table_unref(_module_hash);
180         }
181 }