2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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.
17 /* standard library header */
21 /* SLP library header */
25 #include "Exception.h"
26 #include "ServerDispatcher.h"
27 #include "ServerResource.h"
28 #include "ServerSEService.h"
29 #include "ServerChannel.h"
30 #include "ServerSession.h"
31 #include "ServerReader.h"
33 namespace smartcard_service_api
35 ServerDispatcher::ServerDispatcher():DispatcherHelper()
39 runDispatcherThread();
44 ServerDispatcher::~ServerDispatcher()
48 ServerDispatcher *ServerDispatcher::getInstance()
50 static ServerDispatcher instance;
55 void *ServerDispatcher::dispatcherThreadFunc(DispatcherMsg *msg, void *data)
58 ServerResource *resource = NULL;
62 SCARD_DEBUG_ERR("dispatcher instance is null");
68 SCARD_DEBUG_ERR("message is null");
72 resource = &ServerResource::getInstance();
73 socket = msg->getPeerSocket();
78 case Message::MSG_REQUEST_READERS :
80 SCARD_DEBUG("[MSG_REQUEST_READERS]");
83 Message response(*msg);
85 ClientInstance *instance = NULL;
90 /* load secure elements */
91 resource->loadSecureElements();
93 if ((instance = resource->getClient(socket)) != NULL)
95 /* update client PID */
96 if (instance->getPID() == -1)
98 instance->setPID(msg->error);
99 SCARD_DEBUG_ERR("update PID [%d]", msg->error);
101 /* generate certification hashes */
102 instance->generateCertificationHashes();
106 if (resource->createService(socket, (unsigned long)msg->userParam) != NULL)
108 response.error = SCARD_ERROR_OK;
110 if ((count = resource->getReadersInformation(info)) > 0)
112 response.param1 = count;
113 response.data = info;
117 SCARD_DEBUG("no secure elements");
122 SCARD_DEBUG_ERR("createClient failed");
124 response.error = SCARD_ERROR_UNAVAILABLE;
129 SCARD_DEBUG("client doesn't exist, socket [%d]", socket);
131 response.error = SCARD_ERROR_UNAVAILABLE;
134 /* response to client */
135 ServerIPC::getInstance()->sendMessage(socket, &response);
139 case Message::MSG_REQUEST_SHUTDOWN :
141 Message response(*msg);
143 SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
145 response.error = SCARD_ERROR_OK;
147 resource->removeService(socket, msg->error/* service context */);
149 /* response to client */
150 ServerIPC::getInstance()->sendMessage(socket, &response);
154 case Message::MSG_REQUEST_OPEN_SESSION :
156 Message response(*msg);
157 unsigned int handle = IntegerHandle::INVALID_HANDLE;
159 SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
161 if (resource->isValidReaderHandle(msg->param1))
163 vector<ByteArray> temp;
165 handle = resource->createSession(socket, msg->error/* service context */, msg->param1, temp, msg->caller);
166 if (handle != IntegerHandle::INVALID_HANDLE)
168 response.error = SCARD_ERROR_OK;
172 SCARD_DEBUG_ERR("createSession failed [%d]", handle);
173 response.error = SCARD_ERROR_OUT_OF_MEMORY;
178 SCARD_DEBUG_ERR("request invalid reader handle [%d]", msg->param1);
179 response.error = SCARD_ERROR_ILLEGAL_PARAM;
182 response.param1 = handle;
184 /* response to client */
185 ServerIPC::getInstance()->sendMessage(socket, &response);
189 case Message::MSG_REQUEST_CLOSE_SESSION :
191 Message response(*msg);
193 SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
196 response.error = SCARD_ERROR_OK;
198 if (resource->isValidSessionHandle(socket, msg->error/* service context */, msg->param1))
200 resource->removeSession(socket, msg->error/* service context */, msg->param1);
203 /* response to client */
204 ServerIPC::getInstance()->sendMessage(socket, &response);
208 case Message::MSG_REQUEST_OPEN_CHANNEL :
210 Message response(*msg);
212 SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
214 response.param1 = IntegerHandle::INVALID_HANDLE;
216 response.data.releaseBuffer();
220 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
222 channelID = resource->createChannel(socket, msg->error/* service context */, msg->param2, msg->param1, msg->data);
223 if (channelID != IntegerHandle::INVALID_HANDLE)
227 temp = (ServerChannel *)resource->getChannel(socket, msg->error/* service context */, channelID);
230 response.param1 = channelID;
231 response.param2 = temp->getChannelNumber();
232 response.error = SCARD_ERROR_OK;
233 response.data = temp->getSelectResponse();
237 SCARD_DEBUG_ERR("IS IT POSSIBLE??????????????????");
238 response.error = SCARD_ERROR_UNKNOWN;
243 SCARD_DEBUG_ERR("channel is null.");
245 /* set error value */
246 response.error = SCARD_ERROR_UNAVAILABLE;
249 catch (ExceptionBase &e)
251 response.error = e.getErrorCode();
254 /* response to client */
255 ServerIPC::getInstance()->sendMessage(socket, &response);
259 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
261 Message response(*msg);
263 SCARD_DEBUG("[MSG_REQUEST_GET_CHANNEL_COUNT]");
265 response.error = SCARD_ERROR_OK;
266 response.param1 = resource->getChannelCount(socket, msg->error/* service context */, msg->param1);
268 /* response to client */
269 ServerIPC::getInstance()->sendMessage(socket, &response);
273 case Message::MSG_REQUEST_CLOSE_CHANNEL :
275 Message response(*msg);
277 SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
279 response.error = SCARD_ERROR_OK;
281 if (resource->getChannel(socket, msg->error/* service context */, msg->param1) != NULL)
283 resource->removeChannel(socket, msg->error/* service context */, msg->param1);
286 /* response to client */
287 ServerIPC::getInstance()->sendMessage(socket, &response);
291 case Message::MSG_REQUEST_GET_ATR :
294 Message response(*msg);
296 ServiceInstance *client = NULL;
298 SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
300 if ((client = resource->getService(socket, msg->error/* service context */)) != NULL)
302 Terminal *terminal = NULL;
304 if ((terminal = client->getTerminal(msg->param1)) != NULL)
306 if ((rv = terminal->getATRSync(result)) == 0)
308 response.data = result;
309 response.error = SCARD_ERROR_OK;
313 SCARD_DEBUG_ERR("transmit failed [%d]", rv);
320 SCARD_DEBUG_ERR("getTerminal failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
321 response.error = SCARD_ERROR_UNAVAILABLE;
326 SCARD_DEBUG_ERR("getClient failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
327 response.error = SCARD_ERROR_UNAVAILABLE;
330 /* response to client */
331 ServerIPC::getInstance()->sendMessage(socket, &response);
335 case Message::MSG_REQUEST_TRANSMIT :
338 Message response(*msg);
340 Channel *channel = NULL;
342 SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
344 if ((channel = resource->getChannel(socket, msg->error/* service context */, msg->param1)) != NULL)
346 if ((rv = channel->transmitSync(msg->data, result)) == 0)
348 response.data = result;
349 response.error = SCARD_ERROR_OK;
353 SCARD_DEBUG_ERR("transmit failed [%d]", rv);
360 SCARD_DEBUG_ERR("invalid handle : socket [%d], context [%d], channel [%d]", socket, msg->error/* service context */, msg->param1);
361 response.error = SCARD_ERROR_UNAVAILABLE;
364 /* response to client */
365 ServerIPC::getInstance()->sendMessage(socket, &response);
369 case Message::MSG_OPERATION_RELEASE_CLIENT :
371 SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
373 resource->removeClient(msg->param1);
374 SCARD_DEBUG("remain client [%d]", resource->getClientCount());
377 if (resource->getClientCount() == 0)
379 SCARD_DEBUG("There is no client. shutting down service");
380 g_main_loop_quit((GMainLoop *)resource->getMainLoopInstance());
386 SCARD_DEBUG("unknown message [%s], socket [%d]", msg->toString(), socket);
393 } /* namespace smartcard_service_api */