Fix pointer cast into int issue for 64 bit compatibility.
[platform/core/connectivity/smartcard-service.git] / server / ServerDispatcher.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 <string.h>
20
21 /* SLP library header */
22
23 /* local header */
24 #include "Debug.h"
25 #include "ServerDispatcher.h"
26 #include "ServerResource.h"
27 #include "ServerSEService.h"
28 #include "ServerChannel.h"
29 #include "ServerSession.h"
30 #include "ServerReader.h"
31
32 namespace smartcard_service_api
33 {
34         ServerDispatcher::ServerDispatcher():DispatcherHelper()
35         {
36                 SCARD_BEGIN();
37
38                 runDispatcherThread();
39
40                 SCARD_END();
41         }
42
43         ServerDispatcher::~ServerDispatcher()
44         {
45         }
46
47         ServerDispatcher *ServerDispatcher::getInstance()
48         {
49                 static ServerDispatcher instance;
50
51                 return &instance;
52         }
53
54         void *ServerDispatcher::dispatcherThreadFunc(DispatcherMsg *msg, void *data)
55         {
56                 int socket = -1;
57                 ServerResource *resource = NULL;
58
59                 if (data == NULL)
60                 {
61                         SCARD_DEBUG_ERR("dispatcher instance is null");
62                         return NULL;
63                 }
64
65                 if (msg == NULL)
66                 {
67                         SCARD_DEBUG_ERR("message is null");
68                         return NULL;
69                 }
70
71                 resource = &ServerResource::getInstance();
72                 socket = msg->getPeerSocket();
73
74                 switch (msg->message)
75                 {
76                 /* handle message */
77                 case Message::MSG_REQUEST_READERS :
78                         {
79                                 SCARD_DEBUG("[MSG_REQUEST_READERS]");
80
81 #if 0
82                                 seService->dispatcherCallback(msg, msg->getPeerSocket());
83 #else
84                                 int count = 0;
85                                 Message response(*msg);
86                                 ByteArray info;
87                                 ClientInstance *instance = NULL;
88
89                                 resource->loadSecureElements();
90
91                                 if ((instance = resource->getClient(socket)) != NULL)
92                                 {
93                                         /* update client PID */
94                                         if (instance->getPID() == -1)
95                                         {
96                                                 instance->setPID(msg->error);
97                                                 SCARD_DEBUG_ERR("update PID [%d]", msg->error);
98
99                                                 /* generate certification hashes */
100                                                 instance->generateCertificationHashes();
101                                         }
102
103                                         /* create service */
104                                         if (resource->getService(socket, (unsigned long)msg->userParam) == NULL)
105                                         {
106                                                 if (resource->createService(socket, (unsigned long)msg->userParam) == true)
107                                                 {
108                                                         SCARD_DEBUG_ERR("client added : context [%d]", (unsigned long)msg->userParam);
109                                                 }
110                                                 else
111                                                 {
112                                                         SCARD_DEBUG_ERR("createClient failed");
113
114                                                         response.param1 = 0;
115                                                         response.error = -1;
116
117                                                         /* response to client */
118                                                         ServerIPC::getInstance()->sendMessage(socket, &response);
119
120                                                         return NULL;
121                                                 }
122                                         }
123
124                                         if ((count = resource->getReadersInformation(info)) > 0)
125                                         {
126                                                 response.param1 = count;
127                                                 response.param2 = 0;
128                                                 response.error = 0;
129                                                 response.data = info;
130                                         }
131                                         else
132                                         {
133                                                 SCARD_DEBUG("no secure elements");
134
135                                                 response.error = -1;
136                                         }
137                                 }
138                                 else
139                                 {
140                                         SCARD_DEBUG("client doesn't exist, socket [%d]", socket);
141
142                                         response.error = -1;
143                                 }
144
145                                 /* response to client */
146                                 ServerIPC::getInstance()->sendMessage(socket, &response);
147 #endif
148                         }
149                         break;
150
151                 case Message::MSG_REQUEST_SHUTDOWN :
152 #if 0
153                         {
154                                 Message response(*msg);
155
156                                 SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
157
158                                 if (msg->param1 != 0)
159                                 {
160                                         ServerChannel *channel = NULL;
161
162                                         channel = (ServerChannel *)msg->param1;
163
164                                         channel->closeSync();
165                                 }
166
167                                 /* response to client */
168                                 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
169                         }
170 #else
171                         {
172                                 Message response(*msg);
173
174                                 SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
175
176                                 response.error = 0;
177
178                                 resource->removeService(socket, msg->error/* service context */);
179
180                                 /* response to client */
181                                 ServerIPC::getInstance()->sendMessage(socket, &response);
182                         }
183 #endif
184                         break;
185
186                 case Message::MSG_REQUEST_OPEN_SESSION :
187 #if 0
188                         {
189                                 Message response(*msg);
190                                 ServerReader *reader = NULL;
191                                 ServerSession *session = NULL;
192
193                                 SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
194
195                                 if (msg->param1 != 0)
196                                 {
197                                         reader = (ServerReader *)msg->param1;
198
199                                         session = reader->openSessionSync(msg->data, msg->caller);
200                                 }
201
202                                 /* TODO : attach atr??? */
203                                 response.param1 = (unsigned int)session;
204
205                                 /* response to client */
206                                 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
207                         }
208 #else
209                         {
210                                 Message response(*msg);
211                                 unsigned int handle = -1;
212
213                                 SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
214
215                                 response.param1 = -1;
216                                 response.error = -1;
217
218                                 if (resource->isValidReaderHandle(msg->param1))
219                                 {
220 #if 1
221                                         vector<ByteArray> temp;
222                                         handle = resource->createSession(socket, msg->error/* service context */, msg->param1, temp, msg->caller);
223 #else
224                                         handle = resource->createSession(socket, msg->error/* service context */, msg->param1, msg->data, msg->caller);
225 #endif
226                                         if (handle != IntegerHandle::INVALID_HANDLE)
227                                         {
228                                                 response.param1 = handle;
229                                                 response.error = 0;
230                                         }
231                                         else
232                                         {
233                                                 SCARD_DEBUG_ERR("createSession failed [%d]", handle);
234                                         }
235                                 }
236                                 else
237                                 {
238                                         SCARD_DEBUG_ERR("request invalid reader handle [%d]", msg->param1);
239                                 }
240
241                                 /* response to client */
242                                 ServerIPC::getInstance()->sendMessage(socket, &response);
243                         }
244 #endif
245                         break;
246
247                 case Message::MSG_REQUEST_CLOSE_SESSION :
248 #if 0
249                         {
250                                 Message response(*msg);
251                                 ServerSession *session = NULL;
252
253                                 SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
254
255                                 if (msg->param1 != 0)
256                                 {
257                                         session = (ServerSession *)msg->param1;
258
259                                         session->closeSync();
260                                 }
261
262                                 /* response to client */
263                                 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
264                         }
265 #else
266                         {
267                                 Message response(*msg);
268
269                                 SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
270
271                                 response.param1 = -1;
272                                 response.error = -1;
273
274                                 if (resource->isValidSessionHandle(socket, msg->error/* service context */, msg->param1))
275                                 {
276                                         resource->removeSession(socket, msg->error/* service context */, msg->param1);
277                                 }
278
279                                 /* response to client */
280                                 ServerIPC::getInstance()->sendMessage(socket, &response);
281                         }
282 #endif
283                         break;
284
285                 case Message::MSG_REQUEST_OPEN_CHANNEL :
286 #if 0
287                         {
288                                 Message response(*msg);
289                                 ServerSession *session = NULL;
290
291                                 SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
292
293                                 if (/* check valid session handle */msg->param2 != 0)
294                                 {
295                                         ServerChannel *channel = NULL;
296
297                                         session = (ServerSession *)msg->param2;
298
299                                         if (msg->param1 == 0)
300                                                 channel = (ServerChannel *)session->openBasicChannelSync(msg->data, msg->caller);
301                                         else
302                                                 channel = (ServerChannel *)session->openLogicalChannelSync(msg->data, msg->caller);
303
304                                         if (channel != NULL)
305                                         {
306                                                 response.param1 = (unsigned int)channel;
307                                                 response.param2 = channel->getChannelID();
308                                                 response.error = 0;
309                                                 response.data = channel->getSelectResponse();
310                                         }
311                                         else
312                                         {
313                                                 SCARD_DEBUG_ERR("channel is null.");
314
315                                                 /* set error value */
316                                                 response.param1 = 0;
317                                                 response.param2 = 0;
318                                                 response.error = -4;
319                                                 response.data.releaseBuffer();
320                                         }
321                                 }
322                                 else
323                                 {
324                                         SCARD_DEBUG_ERR("session is invalid");
325
326                                         response.param1 = 0;
327                                         response.param2 = 0;
328                                         response.error = -1;
329                                         response.data.releaseBuffer();
330                                 }
331
332                                 /* response to client */
333                                 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
334                         }
335 #else
336                         {
337                                 Message response(*msg);
338                                 unsigned int channelID = -1;
339
340                                 SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
341
342                                 response.param1 = 0;
343                                 response.param2 = 0;
344                                 response.error = -1;
345                                 response.data.releaseBuffer();
346
347                                 channelID = resource->createChannel(socket, msg->error/* service context */, msg->param2, msg->param1, msg->data);
348                                 if (channelID != IntegerHandle::INVALID_HANDLE)
349                                 {
350                                         ServerChannel *temp = (ServerChannel *)resource->getChannel(socket, msg->error/* service context */, channelID);
351
352                                         if (temp != NULL)
353                                         {
354                                                 response.param1 = channelID;
355                                                 response.param2 = temp->getChannelNumber();
356                                                 response.error = 0;
357                                                 response.data = temp->getSelectResponse();
358                                         }
359                                         else
360                                         {
361                                                 SCARD_DEBUG_ERR("IS IT POSSIBLE??????????????????");
362                                         }
363                                 }
364                                 else
365                                 {
366                                         SCARD_DEBUG_ERR("channel is null.");
367
368                                         /* set error value */
369                                         response.error = -4;
370                                 }
371
372                                 /* response to client */
373                                 ServerIPC::getInstance()->sendMessage(socket, &response);
374                         }
375 #endif
376                         break;
377
378                 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
379                         {
380                                 Message response(*msg);
381
382                                 SCARD_DEBUG("[MSG_REQUEST_GET_CHANNEL_COUNT]");
383
384                                 response.error = 0;
385
386                                 response.param1 = resource->getChannelCount(socket, msg->error/* service context */, msg->param1);
387
388                                 /* response to client */
389                                 ServerIPC::getInstance()->sendMessage(socket, &response);
390                         }
391                         break;
392
393                 case Message::MSG_REQUEST_CLOSE_CHANNEL :
394 #if 0
395                         {
396                                 Message response(*msg);
397
398                                 SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
399
400                                 if (msg->param1 != 0)
401                                 {
402                                         ServerChannel *channel = NULL;
403
404                                         channel = (ServerChannel *)msg->param1;
405
406                                         channel->closeSync();
407                                 }
408
409                                 /* response to client */
410                                 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
411                         }
412 #else
413                         {
414                                 Message response(*msg);
415
416                                 SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
417
418                                 response.error = 0;
419
420                                 if (resource->getChannel(socket, msg->error/* service context */, msg->param1) != NULL)
421                                 {
422                                         resource->removeChannel(socket, msg->error/* service context */, msg->param1);
423                                 }
424
425                                 /* response to client */
426                                 ServerIPC::getInstance()->sendMessage(socket, &response);
427                         }
428 #endif
429                         break;
430
431                 case Message::MSG_REQUEST_GET_ATR :
432 #if 0
433                         {
434                                 Message response(*msg);
435
436                                 SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
437
438                                 if (msg->param1 != 0)
439                                 {
440                                         ServerChannel *channel = NULL;
441
442                                         channel = (ServerChannel *)msg->param1;
443
444                                         channel->closeSync();
445                                 }
446
447                                 /* response to client */
448                                 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
449                         }
450 #else
451                         {
452                                 int rv;
453                                 Message response(*msg);
454                                 ByteArray result;
455                                 ServiceInstance *client = NULL;
456
457                                 SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
458
459                                 response.param1 = 0;
460                                 response.param2 = 0;
461                                 response.error = -1;
462
463                                 if ((client = resource->getService(socket, msg->error/* service context */)) != NULL)
464                                 {
465                                         Terminal *terminal = NULL;
466
467                                         if ((terminal = client->getTerminal(msg->param1)) != NULL)
468                                         {
469                                                 if ((rv = terminal->getATRSync(result)) == 0)
470                                                 {
471                                                         response.data = result;
472                                                         response.error = 0;
473                                                 }
474                                                 else
475                                                 {
476                                                         SCARD_DEBUG_ERR("transmit failed [%d]", rv);
477
478                                                         response.error = rv;
479                                                 }
480                                         }
481                                         else
482                                         {
483                                                 SCARD_DEBUG_ERR("getTerminal failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
484                                         }
485                                 }
486                                 else
487                                 {
488                                         SCARD_DEBUG_ERR("getClient failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
489                                 }
490
491                                 /* response to client */
492                                 ServerIPC::getInstance()->sendMessage(socket, &response);
493                         }
494 #endif
495                         break;
496
497                 case Message::MSG_REQUEST_TRANSMIT :
498 #if 0
499                         {
500                                 Message response(*msg);
501                                 ByteArray result;
502                                 int rv;
503
504                                 SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
505
506                                 if (msg->param1 != 0)
507                                 {
508                                         ServerChannel *channel = NULL;
509
510                                         channel = (ServerChannel *)msg->param1;
511
512                                         if ((rv = channel->transmitSync(msg->data, result)) == 0)
513                                         {
514                                                 response.data = result;
515                                         }
516                                         else
517                                         {
518                                                 SCARD_DEBUG_ERR("transmit failed [%d]", rv);
519                                         }
520                                 }
521
522 //                              if (resource->isValidChannelHandle((void *)msg->param1))
523 //                              {
524 //                              }
525
526                                 /* response to client */
527                                 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
528                         }
529 #else
530                         {
531                                 int rv;
532                                 Message response(*msg);
533                                 ByteArray result;
534                                 Channel *channel = NULL;
535
536                                 SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
537
538                                 response.param1 = 0;
539                                 response.param2 = 0;
540                                 response.error = -1;
541
542                                 if ((channel = resource->getChannel(socket, msg->error/* service context */, msg->param1)) != NULL)
543                                 {
544                                         if ((rv = channel->transmitSync(msg->data, result)) == 0)
545                                         {
546                                                 response.data = result;
547                                                 response.error = 0;
548                                         }
549                                         else
550                                         {
551                                                 SCARD_DEBUG_ERR("transmit failed [%d]", rv);
552
553                                                 response.error = rv;
554                                         }
555                                 }
556                                 else
557                                 {
558                                         SCARD_DEBUG_ERR("invalid handle : socket [%d], context [%d], channel [%d]", socket, msg->error/* service context */, msg->param1);
559                                 }
560
561                                 /* response to client */
562                                 ServerIPC::getInstance()->sendMessage(socket, &response);
563                         }
564 #endif
565                         break;
566
567                 case Message::MSG_OPERATION_RELEASE_CLIENT :
568 #if 0
569                         {
570                                 Message response(*msg);
571
572                                 SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
573
574                                 if (msg->param1 != 0)
575                                 {
576                                         ServerChannel *channel = NULL;
577
578                                         channel = (ServerChannel *)msg->param1;
579
580                                         channel->closeSync();
581                                 }
582
583                                 /* response to client */
584                                 ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
585                         }
586 #else
587                         {
588                                 SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
589
590                                 resource->removeClient(msg->param1);
591                                 SCARD_DEBUG("remain client [%d]", resource->getClientCount());
592                         }
593 #endif
594 #ifdef USE_AUTOSTART
595                         if (resource->getClientCount() == 0)
596                         {
597                                 SCARD_DEBUG("There is no client. shutting down service");
598                                 g_main_loop_quit((GMainLoop *)resource->getMainLoopInstance());
599                         }
600 #endif
601                         break;
602
603                 default :
604                         SCARD_DEBUG("unknown message [%s], socket [%d]", msg->toString(), socket);
605                         break;
606                 }
607
608                 return NULL;
609         }
610
611 } /* namespace smartcard_service_api */