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