a8ddbd3e973b838bd40523758443cc5ccdb5756f
[platform/core/connectivity/smartcard-service.git] / server / smartcard-daemon.cpp
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /* standard library header */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <glib.h>
23 #include <glib-object.h>
24 #include <dirent.h>
25 #include <fcntl.h>
26 #include <sys/stat.h>
27 #include <signal.h>
28 #include <vector>
29 #if defined(USE_AUTOSTART) && !defined(USE_GDBUS)
30 #include <dbus/dbus-glib.h>
31 #include <dbus/dbus-glib-bindings.h>
32 #endif
33
34 /* SLP library header */
35
36 /* local header */
37 #include "Debug.h"
38 #include "ServerIPC.h"
39 #include "ServerResource.h"
40 #ifdef USE_GDBUS
41 #include "smartcard-service-gdbus.h"
42 #include "ServerGDBus.h"
43 #else
44 #ifdef USE_AUTOSTART
45 #include "SmartcardDbus.h"
46 #include "smartcard-service-binding.h"
47 #endif
48 #endif
49
50 /* definition */
51 using namespace std;
52 using namespace smartcard_service_api;
53
54 /* global variable */
55 GMainLoop *main_loop = NULL;
56 #if defined(USE_AUTOSTART) && !defined(USE_GDBUS)
57 GObject *object = NULL;
58 DBusGConnection *connection = NULL;
59 #endif
60
61 #ifndef USE_AUTOSTART
62 static void daemonize(void)
63 {
64         pid_t pid, sid;
65
66         /* already a daemon */
67         if (getppid() == 1)
68                 return;
69
70         /* Fork off the parent process */
71         pid = fork();
72         if (pid < 0)
73         {
74                 exit(EXIT_FAILURE);
75         }
76
77         if (pid > 0)
78         {
79                 exit(EXIT_SUCCESS); /*Killing the Parent Process*/
80         }
81
82         /* At this point we are executing as the child process */
83         umask(0);
84
85         /* Create a new SID for the child process */
86         sid = setsid();
87         if (sid < 0)
88         {
89                 exit(EXIT_FAILURE);
90         }
91
92         /* Change the current working directory. */
93         if ((chdir("/")) < 0)
94         {
95                 exit(EXIT_FAILURE);
96         }
97
98         close(STDIN_FILENO);
99         close(STDOUT_FILENO);
100         close(STDERR_FILENO);
101 }
102 #endif
103
104 #ifdef USE_GDBUS
105 static void _bus_acquired_cb(GDBusConnection *connection,
106         const gchar *path, gpointer user_data)
107 {
108         _DBG("bus path : %s", path);
109
110         ServerResource::getInstance();
111
112         ServerGDBus::getInstance().init();
113 }
114
115 static void _name_acquired_cb(GDBusConnection *connection,
116         const gchar *name, gpointer user_data)
117 {
118         _DBG("name : %s", name);
119 }
120
121 static void _name_lost_cb(GDBusConnection *connnection,
122         const gchar *name, gpointer user_data)
123 {
124         _DBG("name : %s", name);
125
126         ServerGDBus::getInstance().deinit();
127 }
128
129 #else
130 #ifdef USE_AUTOSTART
131 G_DEFINE_TYPE(Smartcard_Service, smartcard_service, G_TYPE_OBJECT)
132
133 /* Just Check the assert  and set the error message */
134 #define __G_ASSERT(test, return_val, error, domain, error_code)\
135 G_STMT_START\
136 {\
137         if G_LIKELY (!(test)) { \
138                 g_set_error (error, domain, error_code, #test); \
139                 return (return_val); \
140         }\
141 }\
142 G_STMT_END
143
144 GQuark smartcard_service_error_quark(void)
145 {
146         _DBG("smartcard_service_error_quark entered");
147
148         return g_quark_from_static_string("smartcard_service_error");
149 }
150
151 static void smartcard_service_init(Smartcard_Service *smartcard_service)
152 {
153         _DBG("smartcard_service_init entered");
154 }
155
156 static void smartcard_service_class_init(Smartcard_ServiceClass *smartcard_service_class)
157 {
158         _DBG("smartcard_service_class_init entered");
159
160         dbus_g_object_type_install_info(SMARTCARD_SERVICE_TYPE, &dbus_glib_smartcard_service_object_info);
161 }
162
163 gboolean smartcard_service_launch(Smartcard_Service *smartcard_service, guint *result_val, GError **error)
164 {
165         _DBG("smartcard_service_launch entered");
166
167         return TRUE;
168 }
169
170 static void _initialize_dbus()
171 {
172         GError *error = NULL;
173         DBusGProxy *proxy = NULL;
174         guint ret = 0;
175
176         _BEGIN();
177
178         g_type_init();
179
180         connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
181         if (error == NULL)
182         {
183                 object = (GObject *)g_object_new(SMARTCARD_SERVICE_TYPE, NULL);
184                 dbus_g_connection_register_g_object(connection, SMARTCARD_SERVICE_PATH, object);
185
186                 /* register service */
187                 proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
188                 if (proxy != NULL)
189                 {
190                         if (!org_freedesktop_DBus_request_name(proxy, SMARTCARD_SERVICE_NAME, 0, &ret, &error))
191                         {
192                                 _ERR("Unable to register service: %s", error->message);
193                                 g_error_free(error);
194                         }
195
196                         g_object_unref (proxy);
197                 }
198                 else
199                 {
200                         _ERR("dbus_g_proxy_new_for_name failed");
201                 }
202         }
203         else
204         {
205                 _ERR("ERROR: Can't get on system bus [%s]", error->message);
206                 g_error_free(error);
207         }
208
209         _END();
210 }
211
212 static void _finalize_dbus()
213 {
214         _BEGIN();
215
216         dbus_g_connection_unregister_g_object(connection, object);
217         g_object_unref(object);
218
219         _END();
220 }
221 #endif
222 #endif
223
224 static void __sighandler(int sig)
225 {
226         _DBG("signal!! [%d]", sig);
227
228 #ifdef USE_GDBUS
229 #else
230 #ifdef USE_AUTOSTART
231         _finalize_dbus();
232 #endif
233 #endif
234 }
235
236 int main(int argc, char *argv[])
237 {
238 #ifdef USE_GDBUS
239         guint id = 0;
240 #endif
241         signal(SIGTERM, &__sighandler);
242
243 #ifndef USE_AUTOSTART
244         daemonize();
245 #endif
246
247         if (!g_thread_supported()) {
248                 g_thread_init(NULL);
249         }
250
251         g_type_init();
252
253         main_loop = g_main_new(TRUE);
254
255 #ifdef USE_GDBUS
256         id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
257                         "org.tizen.SmartcardService",
258                         G_BUS_NAME_OWNER_FLAGS_NONE,
259                         _bus_acquired_cb,
260                         _name_acquired_cb,
261                         _name_lost_cb,
262                         NULL,
263                         NULL);
264 #else
265         ServerIPC::getInstance()->createListenSocket();
266 #ifdef USE_AUTOSTART
267         _initialize_dbus();
268 #endif
269 #endif
270         g_main_loop_run(main_loop);
271
272 #ifdef USE_GDBUS
273         if (id)
274                 g_bus_unown_name(id);
275 #else
276 #ifdef USE_AUTOSTART
277         _finalize_dbus();
278 #endif
279 #endif
280         /* release secure element.. (pure virtual function problem..) */
281         ServerResource::getInstance().unloadSecureElements();
282
283         return 0;
284 }
285
286 void smartcard_daemon_exit()
287 {
288         g_main_loop_quit(main_loop);
289 }