Removed deprecated api g_module_build_path
[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 gchar* _g_module_build_path (const gchar *directory, const gchar *module_name)
36 {
37         if (directory && *directory) {
38                 if (strncmp(module_name, "lib", 3) == 0)
39                         return g_strconcat(directory, "/", module_name, NULL);
40         else
41                 return g_strconcat(directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL);
42         } else if (strncmp (module_name, "lib", 3) == 0)
43                 return g_strdup(module_name);
44         else
45                 return g_strconcat("lib", module_name, "." G_MODULE_SUFFIX, NULL);
46 }
47
48 static GMod *gmod_new(const char *module_name, gboolean is_resident)
49 {
50         if (!module_name)
51                 return NULL;
52
53         GMod *gmod = g_new0(GMod, 1);
54         gmod->name = g_strdup(module_name);
55         if (!gmod->name) {
56                 g_free(gmod);
57                 return NULL;
58         }
59
60         char *module_path = g_strndup(MODULE_PATH_PREFIX, strlen(MODULE_PATH_PREFIX)+1);
61         /* gmod->path = g_module_build_path(MODULE_PATH_PREFIX, gmod->name); */
62         gmod->path = _g_module_build_path(module_path, gmod->name);
63         g_free(module_path);
64         if (!gmod->path) {
65                 g_free(gmod->name);
66                 g_free(gmod);
67                 return NULL;
68         }
69
70         gmod->module = g_module_open(gmod->path, G_MODULE_BIND_LAZY);
71         if (!gmod->module) {
72                 g_free(gmod->name);
73                 g_free(gmod->path);
74                 g_free(gmod);
75                 return NULL;
76         }
77         if (is_resident)
78                 g_module_make_resident(gmod->module);
79
80         return gmod;
81 }
82
83 static void gmod_free(GMod *gmod)
84 {
85         if (gmod->name)
86                 g_free(gmod->name);
87         if (gmod->path)
88                 g_free(gmod->path);
89         if (gmod->module)
90                 g_module_close(gmod->module);
91         g_free(gmod);
92 }
93
94 static gboolean
95 gmod_find_sym(GMod *gmod, gpointer *init_func, gpointer *shutdown_func)
96 {
97         char sym[256];
98         g_stpcpy(sym, "init");
99         if (!g_module_symbol(gmod->module, sym, init_func)) {
100                 LOCATION_LOGW("symbol not found: %s", sym);
101                 return FALSE;
102         }
103         g_stpcpy(sym, "shutdown");
104         if (!g_module_symbol(gmod->module, sym, shutdown_func)) {
105                 LOCATION_LOGW("symbol not found: %s", sym);
106                 return FALSE;
107         }
108         return TRUE;
109 }
110
111 static gpointer mod_new(const char *module_name)
112 {
113         gpointer ret_mod = NULL;
114         if (!module_name)
115                 return NULL;
116
117         GMod *gmod = NULL;
118         gpointer init = NULL;
119         gpointer shutdown = NULL;
120         gmod = gmod_new(module_name, TRUE);
121         if (!gmod) {
122                 LOCATION_LOGW("module(%s) new failed", module_name);
123                 return NULL;
124         }
125         if (!gmod_find_sym(gmod, &init, &shutdown)) {
126                 LOCATION_LOGW("symbol (init, shutdown) finding failed");
127                 gmod_free(gmod);
128                 return NULL;
129         }
130         if (!init || !shutdown) {
131                 LOCATION_LOGW("init, shutdown symbol is NULL");
132                 gmod_free(gmod);
133                 return NULL;
134         }
135         if (g_str_has_prefix(module_name, "gps")) {
136                 LocationGpsMod *_mod = g_new0(LocationGpsMod, 1);
137                 _mod->gmod = gmod;
138                 _mod->init = init;
139                 _mod->shutdown = shutdown;
140                 _mod->handler = _mod->init(&(_mod->ops));
141                 if (!_mod->handler) {
142                         LOCATION_LOGW("module init failed : gps");
143                         gmod_free(_mod->gmod);
144                         ret_mod = NULL;
145                 } else
146                         ret_mod = (gpointer) _mod;
147         } else if (g_str_has_prefix(module_name, "wps")) {
148                 LocationWpsMod *_mod = g_new0(LocationWpsMod, 1);
149                 _mod->gmod = gmod;
150                 _mod->init = init;
151                 _mod->shutdown = shutdown;
152                 _mod->handler = _mod->init(&(_mod->ops));
153                 if (!_mod->handler) {
154                         LOCATION_LOGW("module init failed : wps");
155                         gmod_free(_mod->gmod);
156                         ret_mod = NULL;
157                 } else
158                         ret_mod = (gpointer) _mod;
159         } else if (g_str_has_prefix(module_name, "passive")) {
160                 LocationPassiveMod *_mod = g_new0(LocationPassiveMod, 1);
161                 _mod->gmod = gmod;
162                 _mod->init = init;
163                 _mod->shutdown = shutdown;
164                 _mod->handler = _mod->init(&(_mod->ops));
165                 if (!_mod->handler) {
166                         LOCATION_LOGW("module init failed : passive");
167                         gmod_free(_mod->gmod);
168                         ret_mod = NULL;
169                 } else
170                         ret_mod = (gpointer) _mod;
171         } else if (g_str_has_prefix(module_name, "fused")) {
172                 LocationFusedMod *_mod = g_new0(LocationFusedMod, 1);
173                 _mod->gmod = gmod;
174                 _mod->init = init;
175                 _mod->shutdown = shutdown;
176                 _mod->handler = _mod->init(&(_mod->ops));
177                 if (!_mod->handler) {
178                         LOCATION_LOGW("module init failed : fused");
179                         gmod_free(_mod->gmod);
180                         ret_mod = NULL;
181                 } else
182                         ret_mod = (gpointer) _mod;
183         } else {
184                 LOCATION_LOGW("module name (%s) is wrong", module_name);
185                 ret_mod = NULL;
186         }
187         return ret_mod;
188 }
189
190 static void mod_free(gpointer mod, const char *module_name)
191 {
192         if (!mod || !module_name)
193                 return;
194
195         if (0 == g_strcmp0(module_name, "gps")) {
196                 LocationGpsMod *_mod = (LocationGpsMod *) mod;
197                 if (_mod->shutdown && _mod->handler)
198                         _mod->shutdown(_mod->handler);
199
200                 _mod->handler = NULL;
201                 _mod->init = NULL;
202                 _mod->shutdown = NULL;
203                 gmod_free(_mod->gmod);
204                 _mod->gmod = NULL;
205         } else if (0 == g_strcmp0(module_name, "wps")) {
206                 LocationWpsMod *_mod = (LocationWpsMod *) mod;
207                 if (_mod->shutdown && _mod->handler)
208                         _mod->shutdown(_mod->handler);
209
210                 _mod->handler = NULL;
211                 _mod->init = NULL;
212                 _mod->shutdown = NULL;
213                 gmod_free(_mod->gmod);
214                 _mod->gmod = NULL;
215         } else if (0 == g_strcmp0(module_name, "passive")) {
216                 LocationPassiveMod *_mod = (LocationPassiveMod *)mod;
217                 if (_mod->shutdown && _mod->handler)
218                         _mod->shutdown(_mod->handler);
219
220                 _mod->handler = NULL;
221                 _mod->init = NULL;
222                 _mod->shutdown = NULL;
223                 gmod_free(_mod->gmod);
224                 _mod->gmod = NULL;
225         } else if (0 == g_strcmp0(module_name, "fused")) {
226                 LocationFusedMod *_mod = (LocationFusedMod *) mod;
227                 if (_mod->shutdown && _mod->handler)
228                         _mod->shutdown(_mod->handler);
229
230                 _mod->handler = NULL;
231                 _mod->init = NULL;
232                 _mod->shutdown = NULL;
233                 gmod_free(_mod->gmod);
234                 _mod->gmod = NULL;
235         } else {
236                 LOCATION_LOGW("module name (%s) is wrong", module_name);
237         }
238
239         g_free(mod);
240 }
241
242 static gboolean mod_is_supported(const char *module_name)
243 {
244         GMod *gmod = NULL;
245         gmod = gmod_new(module_name, FALSE);
246         if (!gmod)
247                 return FALSE;
248
249         gmod_free(gmod);
250
251         return TRUE;
252 }
253
254 gboolean module_init(void)
255 {
256         if (!g_module_supported()) {
257                 LOCATION_LOGW("module is not supported");
258                 return FALSE;
259         }
260         return TRUE;
261 }
262
263 void module_free(gpointer mod, const char *module_name)
264 {
265         if (!mod || !module_name)
266                 return;
267         mod_free(mod, module_name);
268 }
269
270 gpointer module_new(const char *module_name)
271 {
272         if (!module_name)
273                 return NULL;
274         char name[256];
275
276         gpointer mod = NULL;
277 #if 0
278         int index = 0;
279
280         for (index = -1; index < MAX_MODULE_INDEX; index++) {
281                 if (index >= 0) {
282                         if (0 >= g_snprintf(name, 256, "%s%d", module_name, index)) {
283                                 LOCATION_LOGW("module name(%s) is wrong", name);
284                                 continue;
285                         }
286                 } else {
287                         if (0 >= g_snprintf(name, 256, "%s", module_name)) {
288                                 LOCATION_LOGW("module name(%s) is wrong", name);
289                                 continue;
290                         }
291                 }
292                 mod = mod_new(name);
293                 if (mod) {
294                         LOCATION_LOGW("module (%s) open success", name);
295                         break;
296                 }
297                 LOCATION_LOGW("module (%s) open failed", name);
298         }
299 #endif
300         if (0 >= g_snprintf(name, 256, "%s", module_name)) {
301                         LOCATION_LOGW("module name(%s) is wrong", name);
302         } else {
303                 mod = mod_new(name);
304                 if (mod)
305                         LOCATION_LOGW("module (%s) open success", name);
306                 else
307                         LOCATION_LOGW("module (%s) open failed", name);
308         }
309         return mod;
310 }
311
312 gboolean module_is_supported(const char *module_name)
313 {
314         if (!module_name)
315                 return FALSE;
316
317         int index = 0;
318         gboolean ret = FALSE;
319         gboolean found = FALSE;
320
321         char name[256] = { 0, };
322
323         for (index = -1; index < MAX_MODULE_INDEX; index++) {
324                 if (index >= 0)
325                         g_snprintf(name, 256, "%s%d", module_name, index);
326                 else
327                         g_snprintf(name, 256, "%s", module_name);
328
329                 ret = mod_is_supported(name);
330                 if (ret == TRUE) {
331                         found = TRUE;
332                         LOCATION_LOGW("module name(%s) is found", name);
333                         break;
334                 }
335         }
336
337         return found;
338 }