4 * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <glib-object.h>
22 #include <glib-unix.h>
26 #include "service_adaptor_internal.h"
30 #include "sal_contact.h"
31 #include "sal_storage.h"
32 #include "sal_resource.h"
33 #include "sal_observer.h"
34 #include "sal_ipc_server.h"
35 #include "sal_service_provider.h"
37 #include "service_discovery.h"
38 #include "service_federation.h"
40 //******************************************************************************
41 //* Global variables and defines
42 //******************************************************************************
43 #define FILE_PATH_LEN 256
45 static sal_h g_service_adaptor = NULL;
47 //******************************************************************************
49 //******************************************************************************
51 //******************************************************************************
52 //* Private interface definition
53 //******************************************************************************
56 * @brief callback of app control
60 static bool _app_control_extra_data_cb(app_control_h app_control, const char *key, void *user_data)
64 app_control_get_extra_data(app_control, key, &value);
65 SAL_INFO("PLUGIN Key (%s): %s", key, value);
67 g_hash_table_insert((GHashTable *) user_data, (char *) key, value);
73 * @brief callback of plugin connection
77 static void _provider_connect_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data)
81 RET_IF(APP_CONTROL_RESULT_FAILED == result);
83 sal_h sal = sal_get_handle();
84 RETM_IF(NULL == sal, "sal_get_handle() Fail");
86 GHashTable *service = g_hash_table_new(g_str_hash, g_str_equal);
87 app_control_foreach_extra_data(reply, _app_control_extra_data_cb, (void *) service);
89 provider_user_data_h provider_user_data = (provider_user_data_h) user_data;
92 gpointer iter_key, iter_value;
94 g_hash_table_iter_init(&iter, service);
95 while (g_hash_table_iter_next(&iter, &iter_key, &iter_value))
97 if (0 == strcmp(iter_key, PLUGIN_KEY_AUTH))
99 auth_plugin_h plugin = NULL;
100 auth_adaptor_create_plugin(provider_user_data->uri, provider_user_data->name, provider_user_data->package, &plugin);
101 auth_adaptor_register_plugin_service(plugin, service);
102 auth_adaptor_add_plugin(sal->auth, plugin);
104 else if (0 == strcmp(iter_key, PLUGIN_KEY_STORAGE))
106 storage_plugin_h plugin = NULL;
107 storage_adaptor_create_plugin(provider_user_data->uri, provider_user_data->name, provider_user_data->package, &plugin);
108 storage_adaptor_register_plugin_service(plugin, service);
109 storage_adaptor_add_plugin(sal->storage, plugin);
113 g_hash_table_destroy(service);
119 * @brief callback of plugin disconnection
123 static void _provider_disconnect_cb(app_control_h request, app_control_h reply, app_control_result_e result, void *user_data)
127 RET_IF(APP_CONTROL_RESULT_FAILED == result);
129 sal_h sal = sal_get_handle();
130 RETM_IF(NULL == sal, "sal_get_handle() Fail");
132 char *uri = (char *) user_data;
134 auth_plugin_h plugin = auth_adaptor_get_plugin(sal->auth, uri);
135 auth_adaptor_remove_plugin(sal->auth, plugin);
136 auth_adaptor_unregister_plugin_service(plugin);
137 auth_adaptor_destroy_plugin(plugin);
139 // TODO: destroy plugin of other adaptor
145 * @brief create spec file
149 static service_adaptor_error_e _sal_create_spec_file(sal_h sal)
154 RETV_IF(NULL == sal, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
160 * @brief destroy spec file
164 static service_adaptor_error_e _sal_destroy_spec_file(sal_h sal)
169 RETV_IF(NULL == sal, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
175 * @brief start service adaptor
179 static service_adaptor_error_e _sal_start(sal_h sal)
184 RETV_IF(NULL == sal, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
186 ret = auth_adaptor_start(sal->auth);
187 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_INTERNAL, "auth_adaptor_start() Fail(%d)", ret);
189 ret = contact_adaptor_start(sal->contact);
190 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_INTERNAL, "contact_adaptor_start() Fail(%d)", ret);
192 ret = storage_adaptor_start(sal->storage);
193 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_INTERNAL, "storage_adaptor_start() Fail(%d)", ret);
195 ret = resource_adaptor_start(sal->resource);
196 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_INTERNAL, "resource_adaptor_start() Fail(%d)", ret);
198 ret = sal_observer_register_existed_plugin();
199 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, ret, "sal_observer_register_existed_plugin() Fail(%d)", ret);
201 g_mutex_lock(&sal->mutex);
202 sal->start = sal->start + 1;
203 g_cond_signal(&sal->cond);
204 g_mutex_unlock(&sal->mutex);
210 * @brief stop service adaptor
214 static service_adaptor_error_e _sal_stop(sal_h sal)
219 RETV_IF(NULL == sal, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
220 RETVM_IF(0 == sal->start, SERVICE_ADAPTOR_ERROR_INTERNAL, "could not start service adaptor");
222 ret += auth_adaptor_stop(sal->auth);
223 ret += contact_adaptor_stop(sal->contact);
224 ret += storage_adaptor_stop(sal->storage);
225 ret += resource_adaptor_stop(sal->resource);
226 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_INTERNAL, "could not stop service adaptor(%d)", ret);
234 * @brief create service adaptor
238 static sal_h _sal_create()
244 // 1) create auth adaptor handle
245 auth_adaptor_h auth = auth_adaptor_create();
246 TRYM_IF(NULL == auth, "sal_auth_create_handle() Fail");
248 // 2) create contact adaptor handle
249 contact_adaptor_h contact = contact_adaptor_create();
250 TRYM_IF(NULL == contact, "sal_contact_create_handle() Fail");
252 // 3) create storage adaptor handle
253 storage_adaptor_h storage = storage_adaptor_create();
254 TRYM_IF(NULL == storage, "sal_storage_create_handle() Fail");
256 // 4) create resource adaptor handle
257 resource_adaptor_h resource = resource_adaptor_create();
258 TRYM_IF(NULL == resource, "sal_resource_create_handle() Fail");
260 // 5) register auth adaptor listener
261 auth_adaptor_listener_h auth_listener = sal_auth_register_listener(auth);
262 TRYM_IF(NULL == auth_listener, "sal_auth_register_listener() Fail");
264 // 6) register contact adaptor listener
265 contact_adaptor_listener_h contact_listener = sal_contact_register_listener(contact);
266 TRYM_IF(NULL == contact_listener, "sal_contact_register_listener() Fail");
268 // 7) register storage adaptor listener
269 storage_adaptor_listener_h storage_listener = sal_storage_register_listener(storage);
270 TRYM_IF(NULL == storage_listener, "sal_storage_register_listener() Fail");
272 // 8) register resource adaptor listener
273 resource_adaptor_listener_h resource_listener = sal_resource_register_listener(resource);
274 TRYM_IF(NULL == resource_listener, "sal_resource_register_listener() Fail");
276 // 9) create service adaptor
277 sal = (sal_h) g_malloc0(sizeof(sal_s));
278 TRYM_IF(NULL == sal, "could not create service adaptor");
281 sal->contact = contact;
282 sal->storage = storage;
283 sal->resource = resource;
285 g_mutex_init(&sal->mutex);
286 g_cond_init(&sal->cond);
295 * @brief destroy service adaptor
299 static void _sal_destroy(sal_h sal)
305 // 1) destroy service list
306 if (NULL != sal->svc_list)
308 g_list_free(sal->svc_list);
309 sal->svc_list = NULL;
312 // 2) free service adaptor handle
319 * @brief init service adaptor
323 static service_adaptor_error_e _sal_init()
326 int ret = SERVICE_ADAPTOR_ERROR_NONE;
328 // 1) create adaptor (memory allocation)
329 sal_h sal = _sal_create();
330 RETVM_IF(NULL == sal, SERVICE_ADAPTOR_ERROR_INTERNAL, "_sal_create() Fail");
332 // 2) start adaptor (plugin loading)
333 ret = _sal_start(sal);
334 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_INTERNAL, "_sal_start() Fail(%d)", ret);
336 // 3) start adaptor (spec file creation)
337 ret = _sal_create_spec_file(sal);
338 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_INTERNAL, "_sal_create_spec_file() Fail(%d)", ret);
340 // 4) init dbus server
341 ret = sal_ipc_server_init();
342 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_IPC_UNSTABLE, "sal_ipc_server_init() Fail(%d)", ret);
344 // 5) assign to global service adaptor handle
345 g_service_adaptor = sal;
347 // 6) register callback for package event
348 ret = sal_observer_start();
349 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, ret, "sal_observer_start() Fail(%d)", ret);
351 // 7) create service discovery
352 ret = service_discovery_create();
353 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, ret, "service_discovery_create() Fail(%d)", ret);
355 // 8) create service federation
356 ret = service_federation_create();
357 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, ret, "service_federation_create() Fail(%d)", ret);
363 * @brief deinit service adaptor
365 * @param[in] service_adaptor specifies handle of service adaptor
368 static void _sal_deinit(sal_h sal)
374 sal_ipc_server_deinit();
376 _sal_destroy_spec_file(sal);
389 * @brief main signal function
391 * @param[in] data specifies user data passed by main function
394 static gint _sigterm_callback(void *data)
396 g_main_loop_quit((GMainLoop*)data);
402 * @brief main function
404 * @param[in] argc specifies count of arguments
405 * @param[in] argv specifies value list of arguments
408 int main(int argc, char *argv[])
410 int ret = SERVICE_ADAPTOR_ERROR_NONE;
411 GMainLoop *loop = NULL;
413 #if !GLIB_CHECK_VERSION(2,32,0)
416 #if !GLIB_CHECK_VERSION(2,35,0)
421 RETVM_IF(SERVICE_ADAPTOR_ERROR_NONE != ret, 0, "_sal_init() Fail(%d)", ret);
423 // mainloop of main thread
424 loop = g_main_loop_new(NULL, FALSE);
426 // installing signal handlers
427 g_unix_signal_add_full(G_PRIORITY_HIGH, SIGINT,
428 _sigterm_callback, loop, NULL );
429 g_unix_signal_add_full(G_PRIORITY_HIGH, SIGTERM,
430 _sigterm_callback, loop, NULL );
432 // start application's main loop
433 g_main_loop_run(loop);
435 // cleanup after mainloop
436 g_main_loop_unref(loop);
438 sal_h sal = sal_get_handle();
444 //******************************************************************************
445 //* Public interface definition
446 //******************************************************************************
448 API sal_h sal_get_handle()
452 return g_service_adaptor;
455 API char *sal_get_root_path()
459 char *root_path = NULL;
460 char tnfs_root_path[FILE_PATH_LEN] = {0,};
462 // TODO: tmp -> need to use get_path APIs of TNFS
463 snprintf(tnfs_root_path, FILE_PATH_LEN, "%s", "/opt/storage/tnfs");
464 root_path = strdup(tnfs_root_path);
469 API service_adaptor_error_e sal_adaptor_connect(const char *uri)
473 RETV_IF(NULL == uri, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
475 SAL_INFO("uri: %s", uri);
477 return SERVICE_ADAPTOR_ERROR_NONE;
480 API service_adaptor_error_e sal_adaptor_disconnect(const char *uri)
484 RETV_IF(NULL == uri, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
486 SAL_INFO("uri: %s", uri);
488 return SERVICE_ADAPTOR_ERROR_NONE;
491 API service_adaptor_error_e sal_adaptor_get_plugins(char ***plugins, int *plugins_size)
495 RETV_IF(NULL == g_service_adaptor, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
496 RETV_IF(NULL == g_service_adaptor->auth, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
498 int size = g_list_length(g_service_adaptor->auth->plugins);
499 RETV_IF(0 == size, SERVICE_ADAPTOR_ERROR_NO_DATA);
502 char **uri = (char **) g_malloc0(sizeof(char *) * size);
504 for (GList *list = g_list_first(g_service_adaptor->auth->plugins); list != NULL; list = list->next)
506 auth_plugin_h this = (auth_plugin_h) list->data;
508 uri[i] = strdup(this->uri);
512 *plugins_size = size;
514 return SERVICE_ADAPTOR_ERROR_NONE;
517 API service_adaptor_error_e sal_provider_connect(const char *uri, const char *name, const char *package)
521 RETV_IF(NULL == uri, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
523 app_control_h request;
524 app_control_create(&request);
526 app_control_set_app_id(request, uri);
527 app_control_set_operation(request, PLUGIN_CONNECT_URI);
529 provider_user_data_h provider_user_data = (provider_user_data_h) g_malloc0(sizeof(provider_user_data_s));
530 provider_user_data->uri = strdup(uri);
531 provider_user_data->name = strdup(name);
532 provider_user_data->package = strdup(package);
534 int ret = app_control_send_launch_request(request, _provider_connect_cb, provider_user_data);
536 RETVM_IF(APP_CONTROL_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_SYSTEM, "app_control_send_launch_request() Fail(%d)", ret);
538 app_control_destroy(request);
540 return SERVICE_ADAPTOR_ERROR_NONE;
543 API service_adaptor_error_e sal_provider_disconnect(const char *uri)
547 RETV_IF(NULL == uri, SERVICE_ADAPTOR_ERROR_INVALID_PARAMETER);
549 app_control_h request;
550 app_control_create(&request);
552 app_control_set_app_id(request, uri);
553 app_control_set_operation(request, PLUGIN_DISCONNECT_URI);
555 int ret = app_control_send_launch_request(request, _provider_disconnect_cb, (void *) uri);
557 RETVM_IF(APP_CONTROL_ERROR_NONE != ret, SERVICE_ADAPTOR_ERROR_SYSTEM, "app_control_send_launch_request() Fail(%d)", ret);
559 app_control_destroy(request);
561 return SERVICE_ADAPTOR_ERROR_NONE;
564 API char *sal_provider_get_uri(const char *package)
568 RETV_IF(NULL == package, NULL);
570 sal_h sal = sal_get_handle();
571 RETVM_IF(NULL == sal, NULL, "sal_get_handle() Fail");
573 char *uri = auth_adaptor_get_uri(sal->auth, package);