de28bba961a0998aaac1b88d8aad687bb0cc39d2
[framework/system/smartcard-service.git] / client / ClientIPC.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 <sys/socket.h>
19 #include <unistd.h>
20
21 /* SLP library header */
22 #ifdef SECURITY_SERVER
23 #include "security-server.h"
24 #endif
25
26 /* local header */
27 #include "Debug.h"
28 #include "ClientIPC.h"
29 #include "DispatcherMsg.h"
30
31 namespace smartcard_service_api
32 {
33         ClientIPC::ClientIPC():IPCHelper()
34         {
35 #ifdef USE_AUTOSTART
36                 _launch_daemon();
37 #endif
38 #ifdef SECURITY_SERVER
39                 int length;
40
41                 if ((length = security_server_get_cookie_size()) > 0)
42                 {
43                         uint8_t *buffer = NULL;
44
45                         buffer = new uint8_t[length];
46                         if (buffer != NULL)
47                         {
48                                 int error;
49
50                                 if ((error = security_server_request_cookie(buffer, length))
51                                         == SECURITY_SERVER_API_SUCCESS)
52                                 {
53                                         cookie.setBuffer(buffer, length);
54
55                                         SCARD_DEBUG("cookie : %s", cookie.toString());
56                                 }
57                                 else
58                                 {
59                                         SCARD_DEBUG_ERR("security_server_request_cookie failed [%d]", error);
60                                 }
61
62                                 delete []buffer;
63                         }
64                 }
65                 else
66                 {
67                         SCARD_DEBUG_ERR("security_server_get_cookie_size failed");
68                 }
69 #endif
70         }
71
72         ClientIPC::~ClientIPC()
73         {
74         }
75
76         ClientIPC &ClientIPC::getInstance()
77         {
78                 static ClientIPC clientIPC;
79
80                 return clientIPC;
81         }
82
83 #ifdef USE_AUTOSTART
84         void ClientIPC::_launch_daemon()
85         {
86                 DBusGConnection *connection;
87                 GError *error = NULL;
88
89                 SCARD_BEGIN();
90
91                 dbus_g_thread_init();
92
93                 g_type_init();
94
95                 connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
96                 if (error == NULL)
97                 {
98                         DBusGProxy *proxy;
99
100                         proxy = dbus_g_proxy_new_for_name(connection, "org.tizen.smartcard_service",
101                                 "/org/tizen/smartcard_service", "org.tizen.smartcard_service");
102                         if (proxy != NULL)
103                         {
104                                 gint result = 0;
105
106                                 if (dbus_g_proxy_call(proxy, "launch", &error, G_TYPE_INVALID,
107                                         G_TYPE_INT, &result, G_TYPE_INVALID) == false)
108                                 {
109                                         SCARD_DEBUG_ERR("org_tizen_smartcard_service_launch failed");
110                                         if (error != NULL)
111                                         {
112                                                 SCARD_DEBUG_ERR("message : [%s]", error->message);
113                                                 g_error_free(error);
114                                         }
115                                 }
116
117                                 g_object_unref(proxy);
118                         }
119                         else
120                         {
121                                 SCARD_DEBUG_ERR("ERROR: Can't make dbus proxy");
122                         }
123                 }
124                 else
125                 {
126                         SCARD_DEBUG_ERR("ERROR: Can't get on system bus [%s]", error->message);
127                         g_error_free(error);
128                 }
129
130                 SCARD_END();
131         }
132 #endif
133
134         bool ClientIPC::sendMessage(Message *msg)
135         {
136                 ByteArray stream;
137                 unsigned int length;
138
139                 if (ipcSocket == -1)
140                         return false;
141
142 #ifdef SECURITY_SERVER
143                 stream = cookie + msg->serialize();
144 #else
145                 stream = msg->serialize();
146 #endif
147                 length = stream.getLength();
148
149                 SCARD_DEBUG(">>>[SEND]>>> socket [%d], msg [%d], length [%d]",
150                         ipcSocket, msg->message, stream.getLength());
151
152                 return IPCHelper::sendMessage(ipcSocket, stream);
153         }
154
155         int ClientIPC::handleIOErrorCondition(void *channel, GIOCondition condition)
156         {
157                 SCARD_BEGIN();
158
159                 if (dispatcher != NULL)
160                 {
161                         DispatcherMsg dispMsg;
162
163                         /* push or process disconnect message */
164                         dispMsg.message = Message::MSG_OPERATION_RELEASE_CLIENT;
165                         dispMsg.error = -1;
166
167 #ifdef CLIENT_IPC_THREAD
168                         dispatcher->processMessage(&dispMsg);
169 #else
170                         dispatcher->pushMessage(&dispMsg);
171 #endif
172                 }
173
174                 SCARD_END();
175
176                 return FALSE;
177         }
178
179         int ClientIPC::handleInvalidSocketCondition(void *channel, GIOCondition condition)
180         {
181                 SCARD_BEGIN();
182
183                 /* finalize context */
184                 destroyConnectSocket();
185
186                 SCARD_END();
187
188                 return FALSE;
189         }
190
191         int ClientIPC::handleIncomingCondition(void *channel, GIOCondition condition)
192         {
193                 int result = FALSE;
194
195                 SCARD_BEGIN();
196
197 #ifndef CLIENT_IPC_THREAD
198                 if (channel == ioChannel)
199                 {
200 #endif
201                         Message *msg = NULL;
202
203                         SCARD_DEBUG("message from server to client socket");
204
205                         /* read message */
206                         msg = retrieveMessage();
207                         if (msg != NULL)
208                         {
209                                 DispatcherMsg dispMsg(msg);
210
211                                 /* set peer socket */
212                                 dispMsg.setPeerSocket(ipcSocket);
213
214                                 /* push to dispatcher */
215                                 if (dispatcher != NULL)
216                                 {
217 #ifdef CLIENT_IPC_THREAD
218                                         dispatcher->processMessage(&dispMsg);
219 #else
220                                         dispatcher->pushMessage(&dispMsg);
221 #endif
222                                 }
223
224                                 delete msg;
225                         }
226                         else
227                         {
228                                 /* clear client connection */
229 #ifdef CLIENT_IPC_THREAD
230                                 handleIOErrorCondition(channel, condition);
231                                 result = -1;
232 #endif
233                         }
234
235 #ifndef CLIENT_IPC_THREAD
236                 }
237                 else
238                 {
239                         SCARD_DEBUG_ERR("Unknown channel event [%p]", channel);
240                 }
241 #endif
242
243                 SCARD_END();
244
245                 return result;
246         }
247
248 } /* namespace open_mobile_api */