Remove tv profile dependency for cynara
[platform/core/location/lbs-location.git] / location / module / module-internal.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <glib.h>
24 #include <stdio.h>
25 #include <limits.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "module-internal.h"
29 #include "location-log.h"
30
31 #define MAX_MODULE_INDEX 4
32
33 #define MODULE_PATH_PREFIX LIBDIR"/location/module"
34
35 static GMod *gmod_new(const char *module_name, gboolean is_resident)
36 {
37         if (!module_name)
38                 return NULL;
39
40         GMod *gmod = g_new0(GMod, 1);
41         gmod->name = g_strdup(module_name);
42         if (!gmod->name) {
43                 g_free(gmod);
44                 return NULL;
45         }
46
47         char *module_path = g_strndup(MODULE_PATH_PREFIX, strlen(MODULE_PATH_PREFIX)+1);
48         /* gmod->path = g_module_build_path(MODULE_PATH_PREFIX, gmod->name); */
49         gmod->path = g_module_build_path(module_path, gmod->name);
50         g_free(module_path);
51         if (!gmod->path) {
52                 g_free(gmod->name);
53                 g_free(gmod);
54                 return NULL;
55         }
56
57         gmod->module = g_module_open(gmod->path, G_MODULE_BIND_LAZY);
58         if (!gmod->module) {
59                 g_free(gmod->name);
60                 g_free(gmod->path);
61                 g_free(gmod);
62                 return NULL;
63         }
64         if (is_resident)
65                 g_module_make_resident(gmod->module);
66
67         return gmod;
68 }
69
70 static void gmod_free(GMod *gmod)
71 {
72         if (gmod->name)
73                 g_free(gmod->name);
74         if (gmod->path)
75                 g_free(gmod->path);
76         if (gmod->module)
77                 g_module_close(gmod->module);
78         g_free(gmod);
79 }
80
81 static gboolean
82 gmod_find_sym(GMod *gmod, gpointer *init_func, gpointer *shutdown_func)
83 {
84         char sym[256];
85         g_stpcpy(sym, "init");
86         if (!g_module_symbol(gmod->module, sym, init_func)) {
87                 LOCATION_LOGW("symbol not found: %s", sym);
88                 return FALSE;
89         }
90         g_stpcpy(sym, "shutdown");
91         if (!g_module_symbol(gmod->module, sym, shutdown_func)) {
92                 LOCATION_LOGW("symbol not found: %s", sym);
93                 return FALSE;
94         }
95         return TRUE;
96 }
97
98 static gpointer mod_new(const char *module_name)
99 {
100         gpointer ret_mod = NULL;
101         if (!module_name)
102                 return NULL;
103
104         GMod *gmod = NULL;
105         gpointer init = NULL;
106         gpointer shutdown = NULL;
107         gmod = gmod_new(module_name, TRUE);
108         if (!gmod) {
109                 LOCATION_LOGW("module(%s) new failed", module_name);
110                 return NULL;
111         }
112         if (!gmod_find_sym(gmod, &init, &shutdown)) {
113                 LOCATION_LOGW("symbol (init, shutdown) finding failed");
114                 gmod_free(gmod);
115                 return NULL;
116         }
117         if (!init || !shutdown) {
118                 LOCATION_LOGW("init, shutdown symbol is NULL");
119                 gmod_free(gmod);
120                 return NULL;
121         }
122         if (g_str_has_prefix(module_name, "gps")) {
123                 LocationGpsMod *_mod = g_new0(LocationGpsMod, 1);
124                 _mod->gmod = gmod;
125                 _mod->init = init;
126                 _mod->shutdown = shutdown;
127                 _mod->handler = _mod->init(&(_mod->ops));
128                 if (!_mod->handler) {
129                         LOCATION_LOGW("module init failed : gps");
130                         gmod_free(_mod->gmod);
131                         ret_mod = NULL;
132                 } else
133                         ret_mod = (gpointer) _mod;
134         } else if (g_str_has_prefix(module_name, "wps")) {
135                 LocationWpsMod *_mod = g_new0(LocationWpsMod, 1);
136                 _mod->gmod = gmod;
137                 _mod->init = init;
138                 _mod->shutdown = shutdown;
139                 _mod->handler = _mod->init(&(_mod->ops));
140                 if (!_mod->handler) {
141                         LOCATION_LOGW("module init failed : wps");
142                         gmod_free(_mod->gmod);
143                         ret_mod = NULL;
144                 } else
145                         ret_mod = (gpointer) _mod;
146         } else if (g_str_has_prefix(module_name, "passive")) {
147                 LocationPassiveMod *_mod = g_new0(LocationPassiveMod, 1);
148                 _mod->gmod = gmod;
149                 _mod->init = init;
150                 _mod->shutdown = shutdown;
151                 _mod->handler = _mod->init(&(_mod->ops));
152                 if (!_mod->handler) {
153                         LOCATION_LOGW("module init failed : passive");
154                         gmod_free(_mod->gmod);
155                         ret_mod = NULL;
156                 } else
157                         ret_mod = (gpointer) _mod;
158         } else if (g_str_has_prefix(module_name, "fused")) {
159                 LocationFusedMod *_mod = g_new0(LocationFusedMod, 1);
160                 _mod->gmod = gmod;
161                 _mod->init = init;
162                 _mod->shutdown = shutdown;
163                 _mod->handler = _mod->init(&(_mod->ops));
164                 if (!_mod->handler) {
165                         LOCATION_LOGW("module init failed : fused");
166                         gmod_free(_mod->gmod);
167                         ret_mod = NULL;
168                 } else
169                         ret_mod = (gpointer) _mod;
170         } else {
171                 LOCATION_LOGW("module name (%s) is wrong", module_name);
172                 ret_mod = NULL;
173         }
174         return ret_mod;
175 }
176
177 static void mod_free(gpointer mod, const char *module_name)
178 {
179         if (!mod || !module_name)
180                 return;
181
182         if (0 == g_strcmp0(module_name, "gps")) {
183                 LocationGpsMod *_mod = (LocationGpsMod *) mod;
184                 if (_mod->shutdown && _mod->handler)
185                         _mod->shutdown(_mod->handler);
186
187                 _mod->handler = NULL;
188                 _mod->init = NULL;
189                 _mod->shutdown = NULL;
190                 gmod_free(_mod->gmod);
191                 _mod->gmod = NULL;
192         } else if (0 == g_strcmp0(module_name, "wps")) {
193                 LocationWpsMod *_mod = (LocationWpsMod *) mod;
194                 if (_mod->shutdown && _mod->handler)
195                         _mod->shutdown(_mod->handler);
196
197                 _mod->handler = NULL;
198                 _mod->init = NULL;
199                 _mod->shutdown = NULL;
200                 gmod_free(_mod->gmod);
201                 _mod->gmod = NULL;
202         } else if (0 == g_strcmp0(module_name, "passive")) {
203                 LocationPassiveMod *_mod = (LocationPassiveMod *)mod;
204                 if (_mod->shutdown && _mod->handler)
205                         _mod->shutdown(_mod->handler);
206
207                 _mod->handler = NULL;
208                 _mod->init = NULL;
209                 _mod->shutdown = NULL;
210                 gmod_free(_mod->gmod);
211                 _mod->gmod = NULL;
212         } else if (0 == g_strcmp0(module_name, "fused")) {
213                 LocationFusedMod *_mod = (LocationFusedMod *) mod;
214                 if (_mod->shutdown && _mod->handler)
215                         _mod->shutdown(_mod->handler);
216
217                 _mod->handler = NULL;
218                 _mod->init = NULL;
219                 _mod->shutdown = NULL;
220                 gmod_free(_mod->gmod);
221                 _mod->gmod = NULL;
222         } else {
223                 LOCATION_LOGW("module name (%s) is wrong", module_name);
224         }
225
226         g_free(mod);
227 }
228
229 static gboolean mod_is_supported(const char *module_name)
230 {
231         GMod *gmod = NULL;
232         gmod = gmod_new(module_name, FALSE);
233         if (!gmod)
234                 return FALSE;
235
236         gmod_free(gmod);
237
238         return TRUE;
239 }
240
241 gboolean module_init(void)
242 {
243         if (!g_module_supported()) {
244                 LOCATION_LOGW("module is not supported");
245                 return FALSE;
246         }
247         return TRUE;
248 }
249
250 void module_free(gpointer mod, const char *module_name)
251 {
252         if (!mod || !module_name)
253                 return;
254         mod_free(mod, module_name);
255 }
256
257 gpointer module_new(const char *module_name)
258 {
259         if (!module_name)
260                 return NULL;
261         char name[256];
262
263         gpointer mod = NULL;
264 #if 0
265         int index = 0;
266
267         for (index = -1; index < MAX_MODULE_INDEX; index++) {
268                 if (index >= 0) {
269                         if (0 >= g_snprintf(name, 256, "%s%d", module_name, index)) {
270                                 LOCATION_LOGW("module name(%s) is wrong", name);
271                                 continue;
272                         }
273                 } else {
274                         if (0 >= g_snprintf(name, 256, "%s", module_name)) {
275                                 LOCATION_LOGW("module name(%s) is wrong", name);
276                                 continue;
277                         }
278                 }
279                 mod = mod_new(name);
280                 if (mod) {
281                         LOCATION_LOGW("module (%s) open success", name);
282                         break;
283                 }
284                 LOCATION_LOGW("module (%s) open failed", name);
285         }
286 #endif
287         if (0 >= g_snprintf(name, 256, "%s", module_name)) {
288                         LOCATION_LOGW("module name(%s) is wrong", name);
289         } else {
290                 mod = mod_new(name);
291                 if (mod)
292                         LOCATION_LOGW("module (%s) open success", name);
293                 else
294                         LOCATION_LOGW("module (%s) open failed", name);
295         }
296         return mod;
297 }
298
299 gboolean module_is_supported(const char *module_name)
300 {
301         if (!module_name)
302                 return FALSE;
303
304         int index = 0;
305         gboolean ret = FALSE;
306         gboolean found = FALSE;
307
308         char name[256] = { 0, };
309
310         for (index = -1; index < MAX_MODULE_INDEX; index++) {
311                 if (index >= 0)
312                         g_snprintf(name, 256, "%s%d", module_name, index);
313                 else
314                         g_snprintf(name, 256, "%s", module_name);
315
316                 ret = mod_is_supported(name);
317                 if (ret == TRUE) {
318                         found = TRUE;
319                         LOCATION_LOGW("module name(%s) is found", name);
320                         break;
321                 }
322         }
323
324         return found;
325 }
326
327 gchar *mod_get_realpath(const gchar *module_name)
328 {
329         gchar origin_path[PATH_MAX] = { 0, };
330         gchar link_path[PATH_MAX] = { 0, };
331         gchar *path = NULL;
332
333         snprintf(link_path, PATH_MAX, "%s/lib%s.so", MODULE_PATH_PREFIX, module_name);
334
335         if (realpath(link_path, origin_path) == NULL || strlen(origin_path) == 0) {
336                 LOCATION_LOGE("Fail to get real path of [%s]", module_name);
337                 return NULL;
338         }
339
340         path = strrchr(origin_path, '/');
341         if (!path)
342                 return NULL;
343
344         return g_strdup(path);
345 }