Add changelog
[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 <dirent.h>
24 #include <fcntl.h>
25 #include <sys/stat.h>
26 #include <signal.h>
27 #ifdef __cplusplus
28 #include <vector>
29 #endif /* __cplusplus */
30 #ifdef USE_AUTOSTART
31 #include <dbus/dbus-glib.h>
32 #include <dbus/dbus-glib-bindings.h>
33 #endif
34
35 /* SLP library header */
36
37 /* local header */
38 #include "Debug.h"
39 #include "ServerIPC.h"
40 #include "ServerResource.h"
41 #ifdef USE_AUTOSTART
42 #include "SmartcardDbus.h"
43 #include "smartcard-service-binding.h"
44 #endif
45
46 /* definition */
47 #ifdef __cplusplus
48 using namespace std;
49 using namespace smartcard_service_api;
50 #endif /* __cplusplus */
51
52 /* global variable */
53 #ifdef USE_AUTOSTART
54 GObject *object = NULL;
55 DBusGConnection *connection = NULL;
56 #endif
57
58 #ifndef USE_AUTOSTART
59 static void daemonize(void)
60 {
61         pid_t pid, sid;
62
63         /* already a daemon */
64         if (getppid() == 1)
65                 return;
66
67         /* Fork off the parent process */
68         pid = fork();
69         if (pid < 0)
70         {
71                 exit(EXIT_FAILURE);
72         }
73
74         if (pid > 0)
75         {
76                 exit(EXIT_SUCCESS); /*Killing the Parent Process*/
77         }
78
79         /* At this point we are executing as the child process */
80         umask(0);
81
82         /* Create a new SID for the child process */
83         sid = setsid();
84         if (sid < 0)
85         {
86                 exit(EXIT_FAILURE);
87         }
88
89         /* Change the current working directory. */
90         if ((chdir("/")) < 0)
91         {
92                 exit(EXIT_FAILURE);
93         }
94
95         close(STDIN_FILENO);
96         close(STDOUT_FILENO);
97         close(STDERR_FILENO);
98 }
99 #endif
100
101 #ifdef USE_AUTOSTART
102 G_DEFINE_TYPE(Smartcard_Service, smartcard_service, G_TYPE_OBJECT)
103
104 /* Just Check the assert  and set the error message */
105 #define __G_ASSERT(test, return_val, error, domain, error_code)\
106 G_STMT_START\
107 {\
108         if G_LIKELY (!(test)) { \
109                 g_set_error (error, domain, error_code, #test); \
110                 return (return_val); \
111         }\
112 }\
113 G_STMT_END
114
115 GQuark smartcard_service_error_quark(void)
116 {
117         SCARD_DEBUG("smartcard_service_error_quark entered");
118
119         return g_quark_from_static_string("smartcard_service_error");
120 }
121
122 static void smartcard_service_init(Smartcard_Service *smartcard_service)
123 {
124         SCARD_DEBUG("smartcard_service_init entered");
125 }
126
127 static void smartcard_service_class_init(Smartcard_ServiceClass *smartcard_service_class)
128 {
129         SCARD_DEBUG("smartcard_service_class_init entered");
130
131         dbus_g_object_type_install_info(SMARTCARD_SERVICE_TYPE, &dbus_glib_smartcard_service_object_info);
132 }
133
134 gboolean smartcard_service_launch(Smartcard_Service *smartcard_service, guint *result_val, GError **error)
135 {
136         SCARD_DEBUG("smartcard_service_launch entered");
137
138         return TRUE;
139 }
140
141 static void _initialize_dbus()
142 {
143         GError *error = NULL;
144         DBusGProxy *proxy = NULL;
145         guint ret = 0;
146
147         SCARD_BEGIN();
148
149         g_type_init();
150
151         connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
152         if (error == NULL)
153         {
154                 object = (GObject *)g_object_new(SMARTCARD_SERVICE_TYPE, NULL);
155                 dbus_g_connection_register_g_object(connection, SMARTCARD_SERVICE_PATH, object);
156
157                 /* register service */
158                 proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
159                 if (proxy != NULL)
160                 {
161                         if (!org_freedesktop_DBus_request_name(proxy, SMARTCARD_SERVICE_NAME, 0, &ret, &error))
162                         {
163                                 SCARD_DEBUG_ERR("Unable to register service: %s", error->message);
164                                 g_error_free(error);
165                         }
166
167                         g_object_unref (proxy);
168                 }
169                 else
170                 {
171                         SCARD_DEBUG_ERR("dbus_g_proxy_new_for_name failed");
172                 }
173         }
174         else
175         {
176                 SCARD_DEBUG_ERR("ERROR: Can't get on system bus [%s]", error->message);
177                 g_error_free(error);
178         }
179
180         SCARD_END();
181 }
182
183 static void _finalize_dbus()
184 {
185         SCARD_BEGIN();
186
187         dbus_g_connection_unregister_g_object(connection, object);
188         g_object_unref(object);
189
190         SCARD_END();
191 }
192 #endif
193
194 static void __sighandler(int sig)
195 {
196         SCARD_DEBUG("signal!! [%d]", sig);
197
198 #ifdef USE_AUTOSTART
199         _finalize_dbus();
200 #endif
201 }
202
203 int main()
204 {
205         GMainLoop *loop = NULL;
206
207         signal(SIGTERM, &__sighandler);
208
209 #ifndef USE_AUTOSTART
210         daemonize();
211 #endif
212
213         if (!g_thread_supported())
214         {
215                 g_thread_init(NULL);
216         }
217
218         loop = g_main_new(TRUE);
219
220 #ifdef __cplusplus
221         ServerResource::getInstance().setMainLoopInstance(loop);
222         ServerIPC::getInstance()->createListenSocket();
223 #else /* __cplusplus */
224         server_resource_set_main_loop_instance(loop);
225         server_ipc_create_listen_socket();
226 #endif /* __cplusplus */
227
228 #ifdef USE_AUTOSTART
229         _initialize_dbus();
230 #endif
231         g_main_loop_run(loop);
232
233 #ifdef USE_AUTOSTART
234         _finalize_dbus();
235 #endif
236         /* release secure element.. (pure virtual function problem..) */
237         ServerResource::getInstance().unloadSecureElements();
238
239         return 0;
240 }