1 /* Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "maps_util.h"
19 #include <glib/gstdio.h>
22 #include "command_queue.h"
23 #include "empty_module.h"
25 extern const char *MAPS_PLUGINS_PATH_PREFIX;
27 plugin::scope_mutex::scope_mutex(GMutex *m) : mutex(m)
32 plugin::scope_mutex::~scope_mutex()
34 g_mutex_unlock(mutex);
37 plugin::binary_extractor::binary_extractor()
41 plugin::provider_info plugin::binary_extractor::get_plugin_info(const
42 string &file_name) const
45 if (file_name.empty())
46 return provider_info::empty_instance;
48 /* 1.Initialize plugin */
49 GMod *plugin = gmod_new(file_name, FALSE);
51 return provider_info::empty_instance;
55 /* 2. Get plugin info */
56 maps_plugin_get_info_f func =
57 (maps_plugin_get_info_f) gmod_find_sym(plugin,
58 "maps_plugin_get_info");
61 if (func(&i) == MAPS_ERROR_NONE) {
62 char *provider_name = NULL;
63 maps_plugin_info_get_provider_name(i, &provider_name);
65 /* Convert plugin info to provider info */
66 info.construct(string(provider_name), file_name);
68 g_free(provider_name);
70 maps_plugin_info_destroy(i);
73 /* 3. shutdown plugin */
79 maps_plugin_h plugin::binary_extractor::init(const provider_info &info,
82 /* 1.Initialize plugin */
83 if (info.file.empty() || !init_error)
86 *init_error = MAPS_ERROR_NONE;
88 GMod *plugin = gmod_new(info.file, TRUE);
90 MAPS_LOGE("Open Module Failed: %s", info.file.c_str());
95 /* 2.1 Create new plugin interface */
96 plugin_s* new_plugin = g_slice_new0(plugin_s);
98 /* 2. Perform steps to completely initialize a plugin */
102 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)",
103 MAPS_ERROR_OUT_OF_MEMORY);
107 /* 2.1 Set plugin module handle */
108 new_plugin->module = plugin;
110 /* 2.2 Set plugin interface */
111 new_plugin->interface = get_empty_interface();
113 /* Plugin dedicated functions */
114 new_plugin->interface.maps_plugin_init =
115 (maps_plugin_init_f) gmod_find_sym(plugin,
117 new_plugin->interface.maps_plugin_shutdown =
118 (maps_plugin_shutdown_f) gmod_find_sym(plugin,
119 "maps_plugin_shutdown");
120 new_plugin->interface.maps_plugin_get_info =
121 (maps_plugin_get_info_f) gmod_find_sym(plugin,
122 "maps_plugin_get_info");
124 /* Maps Provider access key, preference and capabilities */
125 new_plugin->interface.maps_plugin_set_provider_key =
126 (maps_plugin_set_provider_key_f) gmod_find_sym(plugin,
127 "maps_plugin_set_provider_key");
128 new_plugin->interface.maps_plugin_get_provider_key =
129 (maps_plugin_get_provider_key_f) gmod_find_sym(plugin,
130 "maps_plugin_get_provider_key");
131 new_plugin->interface.maps_plugin_set_preference =
132 (maps_plugin_set_preference_f) gmod_find_sym(plugin,
133 "maps_plugin_set_preference");
134 new_plugin->interface.maps_plugin_get_preference =
135 (maps_plugin_get_preference_f) gmod_find_sym(plugin,
136 "maps_plugin_get_preference");
137 new_plugin->interface.maps_plugin_is_service_supported =
138 (maps_plugin_is_service_supported_f)
139 gmod_find_sym(plugin,
140 "maps_plugin_is_service_supported");
141 new_plugin->interface.maps_plugin_is_data_supported =
142 (maps_plugin_is_data_supported_f) gmod_find_sym(plugin,
143 "maps_plugin_is_data_supported");
146 new_plugin->interface.maps_plugin_geocode =
147 (maps_plugin_geocode_f) gmod_find_sym(plugin,
148 "maps_plugin_geocode");
149 new_plugin->interface.maps_plugin_geocode_inside_area =
150 (maps_plugin_geocode_inside_area_f)
151 gmod_find_sym(plugin,
152 "maps_plugin_geocode_inside_area");
153 new_plugin->interface.
154 maps_plugin_geocode_by_structured_address =
155 (maps_plugin_geocode_by_structured_address_f)
156 gmod_find_sym(plugin,
157 "maps_plugin_geocode_by_structured_address");
158 new_plugin->interface.maps_plugin_reverse_geocode =
159 (maps_plugin_reverse_geocode_f) gmod_find_sym(plugin,
160 "maps_plugin_reverse_geocode");
163 new_plugin->interface.maps_plugin_search_place =
164 (maps_plugin_search_place_f) gmod_find_sym(plugin,
165 "maps_plugin_search_place");
166 new_plugin->interface.maps_plugin_search_place_by_area =
167 (maps_plugin_search_place_by_area_f)
168 gmod_find_sym(plugin,
169 "maps_plugin_search_place_by_area");
170 new_plugin->interface.maps_plugin_search_place_by_address =
171 (maps_plugin_search_place_by_address_f)
172 gmod_find_sym(plugin,
173 "maps_plugin_search_place_by_address");
176 new_plugin->interface.maps_plugin_search_route =
177 (maps_plugin_search_route_f) gmod_find_sym(plugin,
178 "maps_plugin_search_route");
179 new_plugin->interface.maps_plugin_search_route_waypoints =
180 (maps_plugin_search_route_waypoints_f)
181 gmod_find_sym(plugin,
182 "maps_plugin_search_route_waypoints");
185 new_plugin->interface.maps_plugin_cancel_request =
186 (maps_plugin_cancel_request_f) gmod_find_sym(plugin,
187 "maps_plugin_cancel_request");
189 /* 2.3 Check whether the plugin init function is valid */
190 if (!new_plugin->interface.maps_plugin_init) {
191 MAPS_LOGE("ERROR! Plugin initialization function is "
196 /* 2.4 Call a plugin to initialize itself, send to the plugin
199 new_plugin->interface.
200 maps_plugin_init((maps_plugin_h *) (&new_plugin));
201 *init_error = ret; /* Remember the error of plugin init */
202 if (ret != MAPS_ERROR_NONE) {
203 MAPS_LOGE("ERROR! Plugin initialization function "
208 if (!new_plugin->interface.maps_plugin_set_provider_key) {
209 MAPS_LOGE("ERROR! Plugin set_provider_key function "
214 if (!new_plugin->interface.maps_plugin_get_provider_key) {
215 MAPS_LOGE("ERROR! Plugin set_provider_key function is "
220 if (!new_plugin->interface.maps_plugin_set_preference) {
221 MAPS_LOGE("ERROR! Plugin set_preference function is "
226 if (!new_plugin->interface.maps_plugin_get_preference) {
227 MAPS_LOGE("ERROR! Plugin get_preference function is "
232 if (!new_plugin->interface.maps_plugin_is_data_supported) {
233 MAPS_LOGE("ERROR! Plugin support_is_data_supported "
234 "function is NULL: %d", ret);
238 if (!new_plugin->interface.maps_plugin_is_service_supported) {
239 MAPS_LOGE("ERROR! Plugin support_is_service_supported "
240 "function is NULL: %d", ret);
244 /* 2.7 Create a queue with asynchronous requests to plugin */
245 if (session::command_queue::is_async())
246 new_plugin->request_queue = g_async_queue_new();
248 /* 2.8 Initialize the mutex for the map of pending requests */
249 new_plugin->pending_request_maps =
250 g_hash_table_new_full(g_int_hash, g_int_equal, g_free,
251 session::command_handler::destroy);
252 if (!new_plugin->pending_request_maps) {
253 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)",
254 MAPS_ERROR_OUT_OF_MEMORY);
257 g_mutex_init(&new_plugin->pending_request_mutex);
260 trace_dbg(new_plugin);
262 /* 2.5 Return newly initialized plugin */
267 MAPS_LOGE("Shut down the plugin because of error");
269 /* 3. shutdown plugin in case of problem */
270 shutdown(new_plugin);
274 void plugin::binary_extractor::shutdown(maps_plugin_h plugin_h)
279 plugin_s *plugin = (plugin_s *) plugin_h;
280 g_return_if_fail(plugin->module);
282 /* 0. shutdown plugin */
283 if (plugin->interface.maps_plugin_shutdown)
284 plugin->interface.maps_plugin_shutdown(plugin);
286 /* 1. Stop the thread, processing the request queue */
287 session::thread().stop(plugin);
289 /* 2. Destroy the request queue */
290 if (plugin->request_queue)
291 g_async_queue_unref(plugin->request_queue);
293 /* 3. Destroy the map of pending requests */
294 if (plugin->pending_request_maps) {
295 g_hash_table_unref(plugin->pending_request_maps);
297 /* Clear the mutex for the map of pending requests */
298 g_mutex_clear(&plugin->pending_request_mutex);
301 /* 4. Unload plugin from memory */
302 gmod_free((GMod *) plugin->module);
304 /* 5. Destroying the table with plugin capabilities */
305 /*maps_string_hashtable_destroy(plugin->capabilities); */
307 /* 6. Release memory used by plugin structure */
308 g_slice_free(plugin_s, plugin);
311 /* Open the binary (which contains a plugin) */
312 plugin::GMod *plugin::binary_extractor::gmod_new(const string &module_file,
313 gboolean is_resident) const
316 if (!g_module_supported()) {
317 MAPS_LOGE("ERROR! g_module_supported is false\n\n");
321 if (module_file.empty())
324 GMod *gmod = g_new0(GMod, 1);
326 gmod->name = g_strdup(module_file.c_str());
332 /*gmod->path = g_module_build_path(MAPS_PLUGINS_PATH_PREFIX,
334 gmod->path = g_strnfill(100, 0);
335 g_sprintf(gmod->path, "%s/%s", MAPS_PLUGINS_PATH_PREFIX, gmod->name);
342 gmod->module = g_module_open(gmod->path, G_MODULE_BIND_LAZY);
344 MAPS_LOGE("module path not found: %s", gmod->path);
346 const gchar *last_error = g_module_error();
347 MAPS_LOGE("last module error: %s", last_error);
354 MAPS_LOGD("open module");
356 g_module_make_resident(gmod->module);*/
361 /* Close the binary (which contains a plugin) */
362 void plugin::binary_extractor::gmod_free(GMod *gmod) const
364 /*g_return_if_fail(gmod); */
373 g_module_close(gmod->module);
376 MAPS_LOGD("close module");
377 MAPS_LOGD("last module error: %s", g_module_error());
380 /* Find the address of a function in a binary (which contains a plugin) */
381 gpointer plugin::binary_extractor::gmod_find_sym(GMod *gmod,
382 const gchar *func_name) const
384 g_return_val_if_fail(gmod, NULL);
385 g_return_val_if_fail(func_name, NULL);
387 gpointer func_ptr = NULL;
388 if (!g_module_symbol(gmod->module, func_name, &func_ptr)) {
389 MAPS_LOGE("function symbol not found");
390 MAPS_LOGE("%s", g_module_error());
396 void plugin::binary_extractor::trace_dbg(const plugin_s *plugin) const
399 MAPS_LOGD("*********************************************");
400 MAPS_LOGD("PLUGIN INFO");
402 MAPS_LOGD("PLUGIN is NULL");
403 MAPS_LOGD("*********************************************");
407 const GMod *mod = (const GMod *) plugin->module;
409 MAPS_LOGD("PLUGIN module is NULL");
412 MAPS_LOGD("module address:\t\t\t%p", mod->module);
413 MAPS_LOGD("module name:\t\t\t%s", mod->name);
414 MAPS_LOGD("module path:\t\t\t%s", mod->path);
417 if (!plugin->request_queue) {
418 MAPS_LOGD("PLUGIN request queue is NULL");
421 MAPS_LOGD("plugin request queue:\t\t\t%p",
422 plugin->request_queue);
425 const interface_s *itf = &plugin->interface;
426 MAPS_LOGD("maps_plugin_init:\t\t\t%p", itf->maps_plugin_init);
427 MAPS_LOGD("maps_plugin_shutdown:\t\t\t%p", itf->maps_plugin_shutdown);
428 MAPS_LOGD("maps_plugin_get_info:\t\t\t%p", itf->maps_plugin_get_info);
430 /* Maps Provider access key */
431 MAPS_LOGD("maps_plugin_set_provider_key:\t\t%p",
432 itf->maps_plugin_set_provider_key);
433 MAPS_LOGD("maps_plugin_get_provider_key:\t\t%p",
434 itf->maps_plugin_get_provider_key);
435 MAPS_LOGD("maps_plugin_is_service_supported:\t%p",
436 itf->maps_plugin_is_service_supported);
437 MAPS_LOGD("maps_plugin_is_data_supported:\t\t%p",
438 itf->maps_plugin_is_data_supported);
440 MAPS_LOGD("maps_plugin_geocode:\t\t\t%p", itf->maps_plugin_geocode);
441 MAPS_LOGD("maps_plugin_geocode_inside_area:\t%p",
442 itf->maps_plugin_geocode_inside_area);
443 MAPS_LOGD("maps_plugin_geocode_by_structured_address: %p",
444 itf->maps_plugin_geocode_by_structured_address);
445 MAPS_LOGD("maps_plugin_reverse_geocode:\t\t%p",
446 itf->maps_plugin_reverse_geocode);
448 MAPS_LOGD("maps_plugin_search_place:\t\t%p",
449 itf->maps_plugin_search_place);
450 MAPS_LOGD("maps_plugin_search_place_by_area:\t%p",
451 itf->maps_plugin_search_place_by_area);
452 MAPS_LOGD("maps_plugin_search_place_by_address:\t%p",
453 itf->maps_plugin_search_place_by_address);
455 MAPS_LOGD("maps_plugin_search_route:\t\t%p",
456 itf->maps_plugin_search_route);
457 MAPS_LOGD("maps_plugin_search_route_waypoints:\t%p",
458 itf->maps_plugin_search_route_waypoints);
460 MAPS_LOGD("maps_plugin_cancel_request:\t\t%p",
461 itf->maps_plugin_cancel_request);
462 MAPS_LOGD("*********************************************");