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.
18 /* standard library header */
22 /* SLP library header */
26 #include "Exception.h"
27 #include "ServerDispatcher.h"
28 #include "ServerIPC.h"
29 #include "ServerResource.h"
30 #include "ServerSEService.h"
31 #include "ServerChannel.h"
32 #include "ServerSession.h"
33 #include "ServerReader.h"
35 namespace smartcard_service_api
37 ServerDispatcher::ServerDispatcher():DispatcherHelper()
41 runDispatcherThread();
46 ServerDispatcher::~ServerDispatcher()
50 ServerDispatcher *ServerDispatcher::getInstance()
52 static ServerDispatcher instance;
57 void *ServerDispatcher::dispatcherThreadFunc(DispatcherMsg *msg, void *data)
60 ServerResource *resource = NULL;
64 _ERR("dispatcher instance is null");
70 _ERR("message is null");
74 resource = &ServerResource::getInstance();
75 socket = msg->getPeerSocket();
80 case Message::MSG_REQUEST_READERS :
82 _INFO("[MSG_REQUEST_READERS]");
85 Message response(*msg);
87 ClientInstance *instance = NULL;
88 ServiceInstance *service = NULL;
93 /* load secure elements */
94 resource->loadSecureElements();
96 if ((instance = resource->getClient(socket)) != NULL)
98 /* update client PID */
99 if (instance->getPID() == -1)
101 instance->setPID(msg->error);
102 _INFO("update PID [%d]", msg->error);
104 /* generate certification hashes */
105 instance->generateCertificationHashes();
109 if ((service = resource->createService(socket)) != NULL)
111 response.error = SCARD_ERROR_OK;
112 response.param2 = service->getHandle();
114 if ((count = resource->getReadersInformation(info)) > 0)
116 response.param1 = count;
117 response.data = info;
121 _INFO("no secure elements");
126 _ERR("createClient failed");
128 response.error = SCARD_ERROR_UNAVAILABLE;
133 _ERR("client doesn't exist, socket [%d]", socket);
135 response.error = SCARD_ERROR_UNAVAILABLE;
138 /* response to client */
139 ServerIPC::getInstance()->sendMessage(socket, response);
143 case Message::MSG_REQUEST_SHUTDOWN :
145 Message response(*msg);
147 _INFO("[MSG_REQUEST_SHUTDOWN]");
149 response.error = SCARD_ERROR_OK;
151 resource->removeService(socket, msg->param1);
153 /* response to client */
154 ServerIPC::getInstance()->sendMessage(socket, response);
158 case Message::MSG_REQUEST_OPEN_SESSION :
160 Message response(*msg);
161 unsigned int handle = IntegerHandle::INVALID_HANDLE;
163 _INFO("[MSG_REQUEST_OPEN_SESSION]");
165 if (resource->isValidReaderHandle(msg->param1))
167 vector<ByteArray> temp;
169 handle = resource->createSession(socket, msg->error/* service context */, msg->param1, temp, msg->caller);
170 if (handle != IntegerHandle::INVALID_HANDLE)
172 response.error = SCARD_ERROR_OK;
176 _ERR("createSession failed [%d]", handle);
177 response.error = SCARD_ERROR_OUT_OF_MEMORY;
182 _ERR("request invalid reader handle [%d]", msg->param1);
183 response.error = SCARD_ERROR_ILLEGAL_PARAM;
186 response.param1 = handle;
188 /* response to client */
189 ServerIPC::getInstance()->sendMessage(socket, response);
193 case Message::MSG_REQUEST_CLOSE_SESSION :
195 Message response(*msg);
197 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
200 response.error = SCARD_ERROR_OK;
202 if (resource->isValidSessionHandle(socket, msg->error/* service context */, msg->param1))
204 resource->removeSession(socket, msg->error/* service context */, msg->param1);
207 /* response to client */
208 ServerIPC::getInstance()->sendMessage(socket, response);
212 case Message::MSG_REQUEST_OPEN_CHANNEL :
214 Message response(*msg);
216 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
218 response.param1 = IntegerHandle::INVALID_HANDLE;
220 response.data.clear();
224 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
226 channelID = resource->createChannel(socket, msg->error/* service context */, msg->param2, msg->param1, msg->data);
227 if (channelID != IntegerHandle::INVALID_HANDLE)
231 temp = (ServerChannel *)resource->getChannel(socket, msg->error/* service context */, channelID);
234 response.param1 = channelID;
235 response.param2 = temp->getChannelNumber();
236 response.error = SCARD_ERROR_OK;
237 response.data = temp->getSelectResponse();
241 _ERR("IS IT POSSIBLE??????????????????");
242 response.error = SCARD_ERROR_UNKNOWN;
247 _ERR("channel is null.");
249 /* set error value */
250 response.error = SCARD_ERROR_UNAVAILABLE;
253 catch (ExceptionBase &e)
255 response.error = e.getErrorCode();
258 /* response to client */
259 ServerIPC::getInstance()->sendMessage(socket, response);
263 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
265 Message response(*msg);
267 _INFO("[MSG_REQUEST_GET_CHANNEL_COUNT]");
269 response.error = SCARD_ERROR_OK;
270 response.param1 = resource->getChannelCount(socket, msg->error/* service context */, msg->param1);
272 /* response to client */
273 ServerIPC::getInstance()->sendMessage(socket, response);
277 case Message::MSG_REQUEST_CLOSE_CHANNEL :
279 Message response(*msg);
281 _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
283 response.error = SCARD_ERROR_OK;
285 if (resource->getChannel(socket, msg->error/* service context */, msg->param1) != NULL)
287 resource->removeChannel(socket, msg->error/* service context */, msg->param1);
290 /* response to client */
291 ServerIPC::getInstance()->sendMessage(socket, response);
295 case Message::MSG_REQUEST_GET_ATR :
298 Message response(*msg);
300 ServiceInstance *client = NULL;
302 _INFO("[MSG_REQUEST_GET_ATR]");
304 if ((client = resource->getService(socket, msg->error/* service context */)) != NULL)
306 Terminal *terminal = NULL;
308 if ((terminal = client->getTerminal(msg->param1)) != NULL)
310 if ((rv = terminal->getATRSync(result)) == 0)
312 response.data = result;
313 response.error = SCARD_ERROR_OK;
317 _ERR("transmit failed [%d]", rv);
324 _ERR("getTerminal failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
325 response.error = SCARD_ERROR_UNAVAILABLE;
330 _ERR("getClient failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
331 response.error = SCARD_ERROR_UNAVAILABLE;
334 /* response to client */
335 ServerIPC::getInstance()->sendMessage(socket, response);
339 case Message::MSG_REQUEST_TRANSMIT :
342 Message response(*msg);
344 Channel *channel = NULL;
346 _INFO("[MSG_REQUEST_TRANSMIT]");
348 if ((channel = resource->getChannel(socket, msg->error/* service context */, msg->param1)) != NULL)
350 if ((rv = channel->transmitSync(msg->data, result)) == 0)
352 response.data = result;
353 response.error = SCARD_ERROR_OK;
357 _ERR("transmit failed [%d]", rv);
364 _ERR("invalid handle : socket [%d], context [%d], channel [%d]", socket, msg->error/* service context */, msg->param1);
365 response.error = SCARD_ERROR_UNAVAILABLE;
368 /* response to client */
369 ServerIPC::getInstance()->sendMessage(socket, response);
373 case Message::MSG_OPERATION_RELEASE_CLIENT :
375 _INFO("[MSG_OPERATION_RELEASE_CLIENT]");
377 resource->removeClient(msg->param1);
378 _DBG("remain client [%d]", resource->getClientCount());
381 if (resource->getClientCount() == 0)
383 _INFO("There is no client. shutting down service");
384 g_main_loop_quit((GMainLoop *)resource->getMainLoopInstance());
390 _DBG("unknown message [%s], socket [%d]", msg->toString().c_str(), socket);
397 } /* namespace smartcard_service_api */