Fix a crash after changes that velocity is updated before position
[platform/core/location/lbs-location.git] / location / module / module-internal.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.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 3
35 const char* MODULE_PATH_PREFIX = "/usr/lib/location/module";
36
37 static GMod*
38 gmod_new (const char* module_name, gboolean is_resident)
39 {
40         if(!module_name)
41                 return NULL;
42
43         GMod* gmod = g_new0(GMod, 1);
44         gmod->name = g_strdup(module_name);
45         if(!gmod->name) {
46                 g_free(gmod);
47                 return NULL;
48         }
49         gmod->path = g_module_build_path (MODULE_PATH_PREFIX, gmod->name);
50         if(!gmod->path){
51                 g_free(gmod->name);
52                 g_free(gmod);
53                 gmod->name = NULL;
54                 return NULL;
55         }
56         gmod->module = g_module_open(gmod->path, G_MODULE_BIND_LAZY);
57         if(!gmod->module){
58                 g_free(gmod->name);
59                 g_free(gmod->path);
60                 g_free(gmod);
61                 gmod->name = NULL;
62                 gmod->path = NULL;
63
64                 return NULL;
65         }
66         if(is_resident)
67                 g_module_make_resident(gmod->module);
68
69         return gmod;
70 }
71
72 static void
73 gmod_free (GMod* gmod)
74 {
75         if(gmod->name)
76                 g_free(gmod->name);
77         if(gmod->path)
78                 g_free(gmod->path);
79         if(gmod->module)
80                 g_module_close(gmod->module);
81         g_free(gmod);
82 }
83
84 static gboolean
85 gmod_find_sym (GMod* gmod,
86         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
103 mod_new (const char* module_name)
104 {
105         gpointer ret_mod = NULL;
106         if(!module_name)
107                 return NULL;
108
109         GMod* gmod = NULL;
110         gpointer init = NULL;
111         gpointer shutdown = NULL;
112         gmod = gmod_new(module_name, TRUE);
113         if(!gmod){
114                 LOCATION_LOGW("module(%s) new failed", module_name);
115                 return NULL;
116         }
117         if( !gmod_find_sym(gmod, &init, &shutdown) ){
118                 LOCATION_LOGW("symbol (init, shutdown) finding failed");
119                 gmod_free(gmod);
120                 return NULL;
121         }
122         if(!init || !shutdown){
123                 LOCATION_LOGW("init, shutdown symbol is NULL");
124                 gmod_free(gmod);
125                 return NULL;
126         }
127         if(g_str_has_prefix(module_name, "map-service")){
128                 LocationServiceMod* _mod = g_new0(LocationServiceMod, 1);
129                 _mod->gmod = gmod;
130                 _mod->init = init;
131                 _mod->shutdown= shutdown;
132                 _mod->handler= _mod->init(&(_mod->ops));
133                 if(!_mod->handler){
134                         LOCATION_LOGW("module init failed");
135                         gmod_free(_mod->gmod);
136                         ret_mod = NULL;
137                 }else
138                         ret_mod = (gpointer)_mod;
139         }else if(g_str_has_prefix(module_name, "gps")){
140                 LocationGpsMod* _mod = g_new0(LocationGpsMod, 1);
141                 _mod->gmod = gmod;
142                 _mod->init = init;
143                 _mod->shutdown= shutdown;
144                 _mod->handler= _mod->init(&(_mod->ops));
145                 if(!_mod->handler){
146                         LOCATION_LOGW("module init failed");
147                         gmod_free(_mod->gmod);
148                         ret_mod = NULL;
149                 }else
150                         ret_mod = (gpointer)_mod;
151         }else if(g_str_has_prefix(module_name, "wps")){
152                 LocationWpsMod* _mod = g_new0(LocationWpsMod, 1);
153                 _mod->gmod = gmod;
154                 _mod->init = init;
155                 _mod->shutdown= shutdown;
156                 _mod->handler= _mod->init(&(_mod->ops));
157                 if(!_mod->handler){
158                         LOCATION_LOGW("module init failed");
159                         gmod_free(_mod->gmod);
160                         ret_mod = NULL;
161                 }else
162                         ret_mod = (gpointer)_mod;
163         }else if(g_str_has_prefix(module_name, "cps")){
164                 LocationCpsMod* _mod = g_new0(LocationCpsMod, 1);
165                 _mod->gmod = gmod;
166                 _mod->init = init;
167                 _mod->shutdown= shutdown;
168                 _mod->handler= _mod->init(&(_mod->ops));
169                 if(!_mod->handler){
170                         LOCATION_LOGW("module init failed");
171                         gmod_free(_mod->gmod);
172                         ret_mod = NULL;
173                 }else
174                         ret_mod = (gpointer)_mod;
175         }else{
176                 LOCATION_LOGW("module name (%s) is wrong", module_name);
177                 ret_mod = NULL;
178         }
179         return ret_mod;
180 }
181
182
183 static void
184 mod_free (gpointer mod,
185         const char* module_name)
186 {
187         if(!mod || !module_name)
188                 return;
189
190         if(g_str_has_prefix(module_name, "map-service")){
191                 LocationServiceMod* _mod = (LocationServiceMod*)mod;
192                 if(_mod->shutdown && _mod->handler){
193                         _mod->shutdown(_mod->handler);
194                 }
195                 _mod->handler = NULL;
196                 _mod->init = NULL;
197                 _mod->shutdown= NULL;
198                 gmod_free(_mod->gmod);
199                 _mod->gmod = NULL;
200         }else if(0 == g_strcmp0(module_name, "gps")){
201                 LocationGpsMod* _mod = (LocationGpsMod*)mod;
202                 if(_mod->shutdown && _mod->handler){
203                         _mod->shutdown(_mod->handler);
204                 }
205                 _mod->handler = NULL;
206                 _mod->init = NULL;
207                 _mod->shutdown= NULL;
208                 gmod_free(_mod->gmod);
209                 _mod->gmod = NULL;
210         }else if(0 == g_strcmp0(module_name, "wps")){
211                 LocationWpsMod* _mod = (LocationWpsMod*)mod;
212                 if(_mod->shutdown && _mod->handler){
213                         _mod->shutdown(_mod->handler);
214                 }
215                 _mod->handler = NULL;
216                 _mod->init = NULL;
217                 _mod->shutdown= NULL;
218                 gmod_free(_mod->gmod);
219                 _mod->gmod = NULL;
220         }else if(0 == g_strcmp0(module_name, "cps")){
221                 LocationCpsMod* _mod = (LocationCpsMod*)mod;
222                 if(_mod->shutdown && _mod->handler){
223                         _mod->shutdown(_mod->handler);
224                 }
225                 _mod->handler = NULL;
226                 _mod->init = NULL;
227                 _mod->shutdown= NULL;
228                 gmod_free(_mod->gmod);
229                 _mod->gmod = NULL;
230         }else
231                 LOCATION_LOGW("module name (%s) is wrong", module_name);
232
233         g_free(mod);
234 }
235
236 static gboolean
237 mod_is_supported(const char *module_name)
238 {
239         GMod * gmod = NULL;
240         gmod = gmod_new(module_name, FALSE);
241         if(!gmod) {
242                 return FALSE;
243         }
244         gmod_free(gmod);
245
246         return TRUE;
247 }
248
249 gboolean module_init (void)
250 {
251         if (!g_module_supported()) {
252                 LOCATION_LOGW("module is not supported");
253                 return FALSE;
254         }
255         return TRUE;
256 }
257
258 void
259 module_free (gpointer mod,
260         const char* module_name)
261 {
262         if(!mod || !module_name)
263                 return;
264         mod_free(mod, module_name);
265 }
266
267 gpointer
268 module_new (const char* module_name)
269 {
270         if(!module_name)
271                 return NULL;
272         int index = 0;
273         char name[256];
274
275         gpointer mod = NULL;
276         for(index = -1 ; index < MAX_MODULE_INDEX ; index++){
277                 if(index >= 0){
278                         if( 0 >= g_snprintf(name, 256, "%s%d", module_name, index)){
279                                 LOCATION_LOGW("module name(%s) is wrong", name);
280                                 continue;
281                         }
282                 }else{
283                         if( 0 >= g_snprintf(name, 256, "%s", module_name)){
284                                 LOCATION_LOGW("module name(%s) is wrong", name);
285                                 continue;
286                         }
287                 }
288                 mod = mod_new(name);
289                 if(mod){
290                         LOCATION_LOGW("module (%s) open success", name);
291                         break;
292                 }
293                 LOCATION_LOGW("module (%s) open failed", name);
294         }
295         return mod;
296 }
297
298 gboolean
299 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
317                 ret = mod_is_supported(name);
318                 if(ret == TRUE) {
319                         found = TRUE;
320                         LOCATION_LOGW("module name(%s) is found", name);
321                         break;
322                 }
323         }
324
325         return found;
326 }
327
328 gchar *
329 mod_get_realpath (const gchar *module_name)
330 {
331         gchar origin_path[PATH_MAX] = {0, };
332         gchar link_path[PATH_MAX] = {0, };
333         gchar *path = NULL;
334
335         snprintf (link_path, PATH_MAX, "%s/lib%s.so", MODULE_PATH_PREFIX, module_name);
336
337         realpath (link_path, origin_path);
338
339         if (!origin_path) {
340                 LOCATION_LOGE ("Fail to get real path of [%s]", module_name);
341                 return NULL;
342         }
343
344         path = strrchr(origin_path, '/');
345         if (!path) return NULL;
346
347         return g_strdup (path);
348 }