2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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 "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 seService->dispatcherCallback(msg, msg->getPeerSocket());
86 Message response(*msg);
88 ClientInstance *instance = NULL;
90 if ((instance = resource->getClient(socket)) != NULL)
92 /* update client PID */
93 if (instance->getPID() == -1)
95 instance->setPID(msg->error);
96 SCARD_DEBUG_ERR("update PID [%d]", msg->error);
100 if (resource->getService(socket, (unsigned int)msg->userParam) == NULL)
102 if (resource->createService(socket, (unsigned int)msg->userParam) == true)
104 SCARD_DEBUG_ERR("client added : context [%d]", (unsigned int)msg->userParam);
108 SCARD_DEBUG_ERR("createClient failed");
113 /* response to client */
114 ServerIPC::getInstance()->sendMessage(socket, &response);
120 if ((count = resource->getReadersInformation(info)) > 0)
122 response.param1 = count;
125 response.data = info;
129 SCARD_DEBUG("no secure elements");
136 SCARD_DEBUG("client doesn't exist, socket [%d]", socket);
141 /* response to client */
142 ServerIPC::getInstance()->sendMessage(socket, &response);
147 case Message::MSG_REQUEST_SHUTDOWN :
150 Message response(*msg);
152 SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
154 if (msg->param1 != 0)
156 ServerChannel *channel = NULL;
158 channel = (ServerChannel *)msg->param1;
160 channel->closeSync();
163 /* response to client */
164 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
168 Message response(*msg);
170 SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
174 resource->removeService(socket, msg->error/* service context */);
176 /* response to client */
177 ServerIPC::getInstance()->sendMessage(socket, &response);
182 case Message::MSG_REQUEST_OPEN_SESSION :
185 Message response(*msg);
186 ServerReader *reader = NULL;
187 ServerSession *session = NULL;
189 SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
191 if (msg->param1 != 0)
193 reader = (ServerReader *)msg->param1;
195 session = reader->openSessionSync(msg->data, msg->caller);
198 /* TODO : attach atr??? */
199 response.param1 = (unsigned int)session;
201 /* response to client */
202 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
206 Message response(*msg);
207 unsigned int handle = -1;
209 SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
211 response.param1 = -1;
214 if (resource->isValidReaderHandle(msg->param1))
216 handle = resource->createSession(socket, msg->error/* service context */, msg->param1, msg->data, msg->caller);
217 if (handle != IntegerHandle::INVALID_HANDLE)
219 response.param1 = handle;
224 SCARD_DEBUG_ERR("createSession failed [%d]", handle);
229 SCARD_DEBUG_ERR("request invalid reader handle [%d]", msg->param1);
232 /* response to client */
233 ServerIPC::getInstance()->sendMessage(socket, &response);
238 case Message::MSG_REQUEST_CLOSE_SESSION :
241 Message response(*msg);
242 ServerSession *session = NULL;
244 SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
246 if (msg->param1 != 0)
248 session = (ServerSession *)msg->param1;
250 session->closeSync();
253 /* response to client */
254 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
258 Message response(*msg);
260 SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
262 response.param1 = -1;
265 if (resource->isValidSessionHandle(socket, msg->error/* service context */, msg->param1))
267 resource->removeSession(socket, msg->error/* service context */, msg->param1);
270 /* response to client */
271 ServerIPC::getInstance()->sendMessage(socket, &response);
276 case Message::MSG_REQUEST_OPEN_CHANNEL :
279 Message response(*msg);
280 ServerSession *session = NULL;
282 SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
284 if (/* check valid session handle */msg->param2 != 0)
286 ServerChannel *channel = NULL;
288 session = (ServerSession *)msg->param2;
290 if (msg->param1 == 0)
291 channel = (ServerChannel *)session->openBasicChannelSync(msg->data, msg->caller);
293 channel = (ServerChannel *)session->openLogicalChannelSync(msg->data, msg->caller);
297 response.param1 = (unsigned int)channel;
298 response.param2 = channel->getChannelID();
300 response.data = channel->getSelectResponse();
304 SCARD_DEBUG_ERR("channel is null.");
306 /* set error value */
310 response.data.releaseBuffer();
315 SCARD_DEBUG_ERR("session is invalid");
320 response.data.releaseBuffer();
323 /* response to client */
324 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
328 Message response(*msg);
329 unsigned int channelID = -1;
331 SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
336 response.data.releaseBuffer();
338 channelID = resource->createChannel(socket, msg->error/* service context */, msg->param2, msg->param1, msg->data);
339 if (channelID != IntegerHandle::INVALID_HANDLE)
341 ServerChannel *temp = (ServerChannel *)resource->getChannel(socket, msg->error/* service context */, channelID);
345 response.param1 = channelID;
346 response.param2 = temp->channelNum;
348 response.data = temp->selectResponse;
352 SCARD_DEBUG_ERR("IS IT POSSIBLE??????????????????");
357 SCARD_DEBUG_ERR("channel is null.");
359 /* set error value */
363 /* response to client */
364 ServerIPC::getInstance()->sendMessage(socket, &response);
369 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
371 Message response(*msg);
373 SCARD_DEBUG("[MSG_REQUEST_GET_CHANNEL_COUNT]");
377 response.param1 = resource->getChannelCount(socket, msg->error/* service context */, msg->param1);
379 /* response to client */
380 ServerIPC::getInstance()->sendMessage(socket, &response);
384 case Message::MSG_REQUEST_CLOSE_CHANNEL :
387 Message response(*msg);
389 SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
391 if (msg->param1 != 0)
393 ServerChannel *channel = NULL;
395 channel = (ServerChannel *)msg->param1;
397 channel->closeSync();
400 /* response to client */
401 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
405 Message response(*msg);
407 SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
411 if (resource->getChannel(socket, msg->error/* service context */, msg->param1) != NULL)
413 resource->removeChannel(socket, msg->error/* service context */, msg->param1);
416 /* response to client */
417 ServerIPC::getInstance()->sendMessage(socket, &response);
422 case Message::MSG_REQUEST_GET_ATR :
425 Message response(*msg);
427 SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
429 if (msg->param1 != 0)
431 ServerChannel *channel = NULL;
433 channel = (ServerChannel *)msg->param1;
435 channel->closeSync();
438 /* response to client */
439 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
444 Message response(*msg);
446 ServiceInstance *client = NULL;
448 SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
454 if ((client = resource->getService(socket, msg->error/* service context */)) != NULL)
456 Terminal *terminal = NULL;
458 if ((terminal = client->getTerminal(msg->param1)) != NULL)
460 if ((rv = terminal->getATRSync(result)) == 0)
462 response.data = result;
467 SCARD_DEBUG_ERR("transmit failed [%d]", rv);
474 SCARD_DEBUG_ERR("getTerminal failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
479 SCARD_DEBUG_ERR("getClient failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
482 /* response to client */
483 ServerIPC::getInstance()->sendMessage(socket, &response);
488 case Message::MSG_REQUEST_TRANSMIT :
491 Message response(*msg);
495 SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
497 if (msg->param1 != 0)
499 ServerChannel *channel = NULL;
501 channel = (ServerChannel *)msg->param1;
503 if ((rv = channel->transmitSync(msg->data, result)) == 0)
505 response.data = result;
509 SCARD_DEBUG_ERR("transmit failed [%d]", rv);
513 // if (resource->isValidChannelHandle((void *)msg->param1))
517 /* response to client */
518 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
523 Message response(*msg);
525 Channel *channel = NULL;
527 SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
533 if ((channel = resource->getChannel(socket, msg->error/* service context */, msg->param1)) != NULL)
535 if ((rv = channel->transmitSync(msg->data, result)) == 0)
537 response.data = result;
542 SCARD_DEBUG_ERR("transmit failed [%d]", rv);
549 SCARD_DEBUG_ERR("invalid handle : socket [%d], context [%d], channel [%d]", socket, msg->error/* service context */, msg->param1);
552 /* response to client */
553 ServerIPC::getInstance()->sendMessage(socket, &response);
558 case Message::MSG_OPERATION_RELEASE_CLIENT :
561 Message response(*msg);
563 SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
565 if (msg->param1 != 0)
567 ServerChannel *channel = NULL;
569 channel = (ServerChannel *)msg->param1;
571 channel->closeSync();
574 /* response to client */
575 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
579 SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
581 resource->removeClient(msg->param1);
587 SCARD_DEBUG("unknown message [%s], socket [%d]", msg->toString(), socket);
594 } /* namespace smartcard_service_api */