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