Adjust logging level
[platform/core/connectivity/smartcard-service.git] / server / ServerResource.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 #include <dlfcn.h>
21 #include <errno.h>
22 #include <dirent.h>
23
24 /* SLP library header */
25
26 /* local header */
27 #include "Debug.h"
28 #include "ServerResource.h"
29 #include "TerminalInterface.h"
30 #include "APDUHelper.h"
31 #include "SignatureHelper.h"
32 #include "GPSEACL.h"
33
34 #ifndef EXTERN_API
35 #define EXTERN_API __attribute__((visibility("default")))
36 #endif
37
38 namespace smartcard_service_api
39 {
40         unsigned int IntegerHandle::newHandle = 0;
41         set<unsigned int> IntegerHandle::setHandles;
42         PMutex IntegerHandle::mutexLock;
43
44         unsigned int IntegerHandle::assignHandle()
45         {
46                 SCOPE_LOCK(mutexLock)
47                 {
48                         pair<set<unsigned int>::iterator, bool> result;
49
50                         do
51                         {
52                                 newHandle++;
53                                 if (newHandle == (unsigned int)-1)
54                                 {
55                                         newHandle = 1;
56                                 }
57
58                                 result = setHandles.insert(newHandle);
59
60                         }
61                         while (!result.second);
62                 }
63
64                 _DBG("assign handle : newHandle [%d]", newHandle);
65
66                 return newHandle;
67         }
68
69         void IntegerHandle::releaseHandle(unsigned int handle)
70         {
71                 _DBG("will be released : Handle [%d]", handle);
72
73                 SCOPE_LOCK(mutexLock)
74                 {
75                         setHandles.erase(handle);
76                 }
77         }
78
79 #define OMAPI_SE_PATH "/usr/lib/se"
80
81         ServerResource::ServerResource()
82                 : mainLoop(NULL), seLoaded(false)
83         {
84                 _BEGIN();
85
86                 serverIPC = ServerIPC::getInstance();
87                 serverDispatcher = ServerDispatcher::getInstance();
88
89                 _END();
90         }
91
92         ServerResource::~ServerResource()
93         {
94         }
95
96         ServerResource &ServerResource::getInstance()
97         {
98                 static ServerResource serverResource;
99
100                 return serverResource;
101         }
102
103         bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
104         {
105                 bool result = false;
106
107                 if (getClient(socket) == NULL)
108                 {
109                         ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
110                         if (instance != NULL)
111                         {
112                                 mapClients.insert(make_pair(socket, instance));
113                                 result = true;
114                         }
115                         else
116                         {
117                                 _ERR("alloc failed");
118                         }
119                 }
120                 else
121                 {
122                         _ERR("client already exist [%d]", socket);
123                 }
124
125                 return result;
126         }
127
128         ClientInstance *ServerResource::getClient(int socket)
129         {
130                 ClientInstance *result = NULL;
131                 map<int, ClientInstance *>::iterator item;
132
133                 if ((item = mapClients.find(socket)) != mapClients.end())
134                 {
135                         result = item->second;
136                 }
137
138                 return result;
139         }
140
141         void ServerResource::setPID(int socket, int pid)
142         {
143                 map<int, ClientInstance *>::iterator item;
144
145                 if ((item = mapClients.find(socket)) != mapClients.end())
146                 {
147                         if (item->second->getPID() < 0)
148                                 item->second->setPID(pid);
149                 }
150         }
151
152         int ServerResource::getClientCount()
153         {
154                 return (int)mapClients.size();
155         }
156
157         void ServerResource::removeClient(int socket)
158         {
159                 map<int, ClientInstance *>::iterator item;
160
161                 if ((item = mapClients.find(socket)) != mapClients.end())
162                 {
163                         ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
164
165                         delete item->second;
166                         mapClients.erase(item);
167                 }
168                 else
169                 {
170                         _DBG("client removed already [%d]", socket);
171                 }
172         }
173
174         void ServerResource::removeClients()
175         {
176                 map<int, ClientInstance *>::iterator item;
177
178                 for (item = mapClients.begin(); item != mapClients.end(); item++)
179                 {
180                         ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
181
182                         delete item->second;
183                 }
184
185                 mapClients.clear();
186         }
187
188         ServiceInstance *ServerResource::createService(int socket, unsigned int context)
189         {
190                 ServiceInstance *result = NULL;
191                 ClientInstance *instance = NULL;
192
193                 if ((instance = getClient(socket)) != NULL)
194                 {
195                         if ((result = instance->getService(context)) == NULL)
196                         {
197                                 if ((result = instance->createService(context)) == NULL)
198                                 {
199                                         _ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
200                                 }
201                         }
202                 }
203                 else
204                 {
205                         _ERR("client doesn't exist [%d]", socket);
206                 }
207
208                 return result;
209         }
210
211         ServiceInstance *ServerResource::getService(int socket, unsigned int context)
212         {
213                 ServiceInstance *result = NULL;
214                 ClientInstance *instance = NULL;
215
216                 if ((instance = getClient(socket)) != NULL)
217                 {
218                         result = instance->getService(context);
219                 }
220                 else
221                 {
222                         _ERR("client doesn't exist [%d]", socket);
223                 }
224
225                 return result;
226         }
227
228         void ServerResource::removeService(int socket, unsigned int context)
229         {
230                 ClientInstance *instance = NULL;
231
232                 if ((instance = getClient(socket)) != NULL)
233                 {
234                         instance->removeService(context);
235                 }
236                 else
237                 {
238                         _ERR("client doesn't exist [%d]", socket);
239                 }
240         }
241
242         void ServerResource::removeServices(int socket)
243         {
244                 ClientInstance *instance = NULL;
245
246                 if ((instance = getClient(socket)) != NULL)
247                 {
248                         instance->removeServices();
249                 }
250                 else
251                 {
252                         _ERR("client doesn't exist [%d]", socket);
253                 }
254         }
255
256         Terminal *ServerResource::getTerminal(unsigned int terminalID)
257         {
258                 Terminal *result = NULL;
259                 map<unsigned int, Terminal *>::iterator item;
260
261                 if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
262                 {
263                         result = item->second;
264                 }
265                 else
266                 {
267                         _ERR("Terminal doesn't exist [%d]", terminalID);
268                 }
269
270                 return result;
271         }
272
273         Terminal *ServerResource::getTerminal(const char *name)
274         {
275                 Terminal *result = NULL;
276                 map<unsigned int, Terminal *>::iterator item;
277
278                 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
279                 {
280                         if (strncmp(name, item->second->getName(), strlen(name)) == 0)
281                         {
282                                 result = item->second;
283                                 break;
284                         }
285                 }
286
287                 return result;
288         }
289
290         Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
291         {
292                 Terminal *result = NULL;
293                 map<unsigned int, unsigned int>::iterator item;
294
295                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
296                 {
297                         result = getTerminal(item->second);
298                 }
299                 else
300                 {
301                         _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
302                 }
303
304                 return result;
305         }
306
307         unsigned int ServerResource::getTerminalID(const char *name)
308         {
309                 unsigned int result = IntegerHandle::INVALID_HANDLE;
310                 map<unsigned int, Terminal *>::iterator item;
311
312                 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
313                 {
314                         if (strncmp(name, item->second->getName(), strlen(name)) == 0)
315                         {
316                                 result = item->first;
317                                 break;
318                         }
319                 }
320
321                 return result;
322         }
323
324         unsigned int ServerResource::createSession(int socket, unsigned int context, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
325         {
326                 unsigned int result = -1;
327                 Terminal *temp = NULL;
328                 ServiceInstance *instance = NULL;
329
330                 if ((instance = getService(socket, context)) != NULL)
331                 {
332                         if ((temp = getTerminalByReaderID(readerID)) != NULL)
333                         {
334                                 result = instance->openSession(temp, certHashes, caller);
335                         }
336                 }
337                 else
338                 {
339                         _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
340                 }
341
342                 return result;
343         }
344
345         ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
346         {
347                 ServerSession *result = NULL;
348                 ServiceInstance *instance = NULL;
349
350                 if ((instance = getService(socket, context)) != NULL)
351                 {
352                         result = instance->getSession(sessionID);
353                 }
354                 else
355                 {
356                         _ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
357                 }
358
359                 return result;
360         }
361
362         unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
363         {
364                 unsigned int result = -1;
365                 ServiceInstance *instance = NULL;
366
367                 if ((instance = getService(socket, context)) != NULL)
368                 {
369                         result = instance->getChannelCountBySession(sessionID);
370                 }
371                 else
372                 {
373                         _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
374                 }
375
376                 return result;
377         }
378
379         void ServerResource::removeSession(int socket, unsigned int context, unsigned int sessionID)
380         {
381                 ServiceInstance *instance = NULL;
382
383                 if ((instance = getService(socket, context)) != NULL)
384                 {
385                         instance->closeSession(sessionID);
386                 }
387                 else
388                 {
389                         _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
390                 }
391         }
392
393         bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
394         {
395                 bool result = true;
396                 AccessControlList *acList = NULL;
397
398                 /* request open channel sequence */
399                 if ((acList = getAccessControlList(channel)) != NULL)
400                 {
401                         PKCS15 pkcs15(channel);
402
403                         acList->loadACL(channel);
404                         result = acList->isAuthorizedAccess(aid, hashes);
405                 }
406                 else
407                 {
408                         _ERR("acList is null");
409                         result = false;
410                 }
411
412                 return result;
413         }
414
415         int ServerResource::_openLogicalChannel(Terminal *terminal)
416         {
417                 int result = -1;
418                 int rv = 0;
419                 ByteArray command;
420                 ByteArray response;
421
422                 /* open channel */
423                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
424                 rv = terminal->transmitSync(command, response);
425                 if (rv == 0 && response.getLength() >= 2)
426                 {
427                         ResponseHelper resp(response);
428
429                         if (resp.getStatus() == 0)
430                         {
431                                 result = resp.getDataField()[0];
432                         }
433                         else
434                         {
435                                 _ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
436                                 if (0)
437                                 {
438                                         /* TODO : if there is no more channel, return error code */
439                                         _ERR("no more logical channel");
440                                         result = -2;
441                                 }
442                         }
443                 }
444                 else
445                 {
446                         _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
447                 }
448
449                 return result;
450         }
451
452         int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
453         {
454                 int result = -1;
455                 int rv = 0;
456                 ByteArray command;
457                 ByteArray response;
458
459                 /* open channel */
460                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
461                 rv = terminal->transmitSync(command, response);
462                 if (rv == 0 && response.getLength() >= 2)
463                 {
464                         ResponseHelper resp(response);
465
466                         if (resp.getStatus() == 0)
467                         {
468                                 _DBG("channel closed [%d]", channelNum);
469                                 result = 0;
470                         }
471                         else
472                         {
473                                 _ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
474                         }
475                 }
476                 else
477                 {
478                         _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
479                 }
480
481                 return result;
482         }
483
484         unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
485                 throw(ExceptionBase &)
486         {
487                 unsigned int result = IntegerHandle::INVALID_HANDLE;
488                 int channelNum = 0;
489                 ServerChannel *channel = NULL;
490
491                 /* open logical channel */
492                 if (channelType == 1)
493                 {
494                         channelNum = _openLogicalChannel(terminal);
495                         if (channelNum > 0)
496                         {
497                                 _DBG("channelNum [%d]", channelNum);
498                         }
499                         else
500                         {
501                                 _ERR("_openLogicalChannel failed [%d]", channelNum);
502                                 throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
503                         }
504                 }
505
506                 /* create channel instance */
507                 result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
508                 if (result == IntegerHandle::INVALID_HANDLE)
509                 {
510                         _ERR("channel is null.");
511
512                         /* close logical channel */
513                         if (channelNum > 0)
514                         {
515                                 _closeLogicalChannel(terminal, channelNum);
516                         }
517                         throw ExceptionBase(SCARD_ERROR_OUT_OF_MEMORY);
518                 }
519
520                 channel = service->getChannel(result);
521
522                 /* check */
523                 if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
524                                 aid, service->getParent()->getCertificationHashes()) == true)
525                 {
526                         int rv = 0;
527
528                         /* select aid */
529                         if (aid == PKCS15::PKCS15_AID)
530                         {
531                                 PKCS15 pkcs15(channel);
532
533                                 if (pkcs15.isClosed() == false)
534                                 {
535                                         /* remove privilege mode */
536                                         channel->unsetPrivilegeMode();
537                                 }
538                                 else
539                                 {
540                                         _ERR("select failed");
541
542                                         service->closeChannel(result);
543                                         throw ExceptionBase(SCARD_ERROR_IO_FAILED);
544                                 }
545                         }
546                         else
547                         {
548                                 FileObject file(channel);
549
550                                 rv = file.select(aid);
551                                 if (rv == FileObject::SUCCESS)
552                                 {
553                                         /* remove privilege mode */
554                                         channel->unsetPrivilegeMode();
555                                 }
556                                 else
557                                 {
558                                         _ERR("select failed [%d]", rv);
559
560                                         service->closeChannel(result);
561                                         throw ExceptionBase(SCARD_ERROR_IO_FAILED);
562                                 }
563                         }
564                 }
565                 else
566                 {
567                         _ERR("unauthorized access");
568
569                         service->closeChannel(result);
570                         throw ExceptionBase(SCARD_ERROR_SECURITY_NOT_ALLOWED);
571                 }
572
573                 return result;
574         }
575
576         unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
577                 throw(ExceptionBase &)
578         {
579                 unsigned int result = -1;
580                 ServiceInstance *service = NULL;
581
582                 if ((service = getService(socket, context)) != NULL)
583                 {
584                         if (service->isVaildSessionHandle(sessionID) == true)
585                         {
586                                 ServerSession *session = NULL;
587                                 Terminal *terminal = NULL;
588
589                                 terminal = service->getTerminal(sessionID);
590                                 session = service->getSession(sessionID);
591                                 if (terminal != NULL && session != NULL)
592                                 {
593                                         result = _createChannel(terminal, service, channelType, sessionID, aid);
594                                         if (result == IntegerHandle::INVALID_HANDLE)
595                                         {
596                                                 _ERR("create channel failed [%d]", sessionID);
597                                         }
598                                 }
599                                 else
600                                 {
601                                         _ERR("session is invalid [%d]", sessionID);
602                                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
603                                 }
604                         }
605                         else
606                         {
607                                 _ERR("session is invalid [%d]", sessionID);
608                                 throw ExceptionBase(SCARD_ERROR_ILLEGAL_PARAM);
609                         }
610                 }
611                 else
612                 {
613                         _ERR("getService is failed [%d] [%d]", socket, context);
614                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
615                 }
616
617                 return result;
618         }
619
620         Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
621         {
622                 Channel *result = NULL;
623                 ServiceInstance *instance = NULL;
624
625                 if ((instance = getService(socket, context)) != NULL)
626                 {
627                         result = instance->getChannel(channelID);
628                 }
629                 else
630                 {
631                         _ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
632                 }
633
634                 return result;
635         }
636
637         void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
638         {
639                 ServiceInstance *instance = NULL;
640
641                 if ((instance = getService(socket, context)) != NULL)
642                 {
643                         instance->closeChannel(channelID);
644                 }
645                 else
646                 {
647                         _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
648                 }
649         }
650
651         AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
652         {
653                 AccessControlList *result = NULL;
654                 map<Terminal *, AccessControlList *>::iterator item;
655
656                 if ((item = mapACL.find(terminal)) == mapACL.end())
657                 {
658                         /* load access control */
659                         result = new GPSEACL();
660                         if (result != NULL)
661                         {
662                                 mapACL.insert(make_pair(terminal, result));
663                         }
664                         else
665                         {
666                                 _ERR("alloc failed");
667                         }
668                 }
669                 else
670                 {
671                         result = item->second;
672                 }
673
674                 return result;
675         }
676
677         AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
678         {
679                 AccessControlList *result = NULL;
680                 map<Terminal *, AccessControlList *>::iterator item;
681
682                 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
683                 {
684                         /* load access control */
685                         result = new GPSEACL();
686                         if (result != NULL)
687                         {
688                                 mapACL.insert(make_pair(channel->getTerminal(), result));
689                         }
690                         else
691                         {
692                                 _ERR("alloc failed");
693                         }
694                 }
695                 else
696                 {
697                         result = item->second;
698                 }
699
700                 return result;
701         }
702
703         Terminal *ServerResource::createInstance(void *library)
704         {
705                 Terminal *terminal = NULL;
706                 terminal_create_instance_fn createInstance = NULL;
707
708                 /* create se instance */
709                 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
710                 if (createInstance != NULL)
711                 {
712                         terminal = (Terminal *)createInstance();
713                         if (terminal != NULL)
714                         {
715                                 _DBG("terminal [%p]", terminal);
716                         }
717                         else
718                         {
719                                 _ERR("terminal is null");
720                         }
721                 }
722                 else
723                 {
724                         _ERR("create_instance is null [%d]", errno);
725                 }
726
727                 return terminal;
728         }
729
730         bool ServerResource::appendSELibrary(char *library)
731         {
732                 void *libHandle = NULL;
733                 bool result = false;
734
735                 libHandle = dlopen(library, RTLD_LAZY);
736                 if (libHandle != NULL)
737                 {
738                         Terminal *terminal = NULL;
739
740                         terminal = createInstance(libHandle);
741                         if (terminal != NULL)
742                         {
743                                 unsigned int handle = IntegerHandle::assignHandle();
744
745                                 mapTerminals.insert(make_pair(handle, terminal));
746                                 libraries.push_back(libHandle);
747
748                                 terminal->setStatusCallback(&ServerResource::terminalCallback);
749
750                                 _DBG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
751
752                                 if (terminal->isSecureElementPresence() == true)
753                                 {
754                                         createReader(handle);
755                                 }
756
757                                 result = true;
758                         }
759                         else
760                         {
761                                 _ERR("terminal is null [%s]", library);
762
763                                 dlclose(libHandle);
764                         }
765                 }
766                 else
767                 {
768                         _ERR("it is not se file [%s] [%d]", library, errno);
769                 }
770
771                 return result;
772         }
773
774         int ServerResource::loadSecureElements()
775         {
776                 int result = 0;
777
778                 if (seLoaded == false)
779                 {
780                         DIR *dir;
781                         struct dirent *entry;
782
783                         if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
784                         {
785                                 while ((entry = readdir(dir)) != NULL)
786                                 {
787                                         if (strncmp(entry->d_name, ".", 1) != 0 &&
788                                                 strncmp(entry->d_name, "..", 2) != 0)
789                                         {
790                                                 char fullPath[1024];
791
792                                                 /* TODO : need additional name rule :) */
793
794                                                 /* append each files */
795                                                 snprintf(fullPath, sizeof(fullPath),
796                                                         "%s/%s", OMAPI_SE_PATH, entry->d_name);
797
798                                                 SCARD_DEBUG("se name [%s]", fullPath);
799
800                                                 result = appendSELibrary(fullPath);
801                                         }
802                                 }
803
804                                 closedir(dir);
805
806                                 seLoaded = true;
807                         }
808                         else
809                         {
810                                 result = -1;
811                         }
812                 }
813
814                 return result;
815         }
816
817         void ServerResource::unloadSecureElements()
818         {
819                 if (seLoaded == true)
820                 {
821                         size_t i;
822                         map<unsigned int, Terminal *>::iterator item;
823
824                         for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
825                         {
826                                 item->second->finalize();
827
828                                 IntegerHandle::releaseHandle(item->first);
829                         }
830
831                         mapTerminals.clear();
832
833                         for (i = 0; i < libraries.size(); i++)
834                         {
835                                 if (libraries[i] != NULL)
836                                         dlclose(libraries[i]);
837                         }
838
839                         libraries.clear();
840
841                         seLoaded = false;
842                 }
843         }
844
845         bool ServerResource::isValidReaderHandle(unsigned int reader)
846         {
847                 return (getTerminalByReaderID(reader) != NULL);
848         }
849
850         bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
851         {
852                 ServiceInstance *instance = NULL;
853
854                 return (((instance = getService(socket, context)) != NULL) && (instance->isVaildSessionHandle(session)));
855         }
856
857         int ServerResource::getReadersInformation(ByteArray &info)
858         {
859                 int result = 0;
860                 unsigned char *buffer = NULL;
861                 unsigned int length = 0;
862                 unsigned int offset = 0;
863                 unsigned int nameLen = 0;
864
865                 if (mapReaders.size() > 0)
866                 {
867                         Terminal *terminal = NULL;
868                         map<unsigned int, unsigned int>::iterator item;
869
870                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
871                         {
872                                 if (item->second != IntegerHandle::INVALID_HANDLE)
873                                 {
874                                         terminal = getTerminal(item->second);
875                                         if (terminal != NULL)
876                                         {
877                                                 if (terminal->isSecureElementPresence())
878                                                 {
879                                                         length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
880                                                         result++;
881                                                 }
882                                         }
883                                 }
884                         }
885
886                         buffer = new unsigned char[length];
887                         if (buffer != NULL)
888                         {
889                                 memset(buffer, 0, length);
890
891                                 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
892                                 {
893                                         if (item->second != IntegerHandle::INVALID_HANDLE)
894                                         {
895                                                 terminal = getTerminal(item->second);
896                                                 if (terminal != NULL)
897                                                 {
898                                                         if (terminal->isSecureElementPresence())
899                                                         {
900                                                                 nameLen = strlen(terminal->getName());
901
902                                                                 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
903                                                                 offset += sizeof(nameLen);
904
905                                                                 memcpy(buffer + offset, terminal->getName(), nameLen);
906                                                                 offset += nameLen;
907
908                                                                 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
909                                                                 offset += sizeof(unsigned int);
910                                                         }
911                                                 }
912                                         }
913                                 }
914
915                                 info.setBuffer(buffer, length);
916                                 delete []buffer;
917                         }
918                         else
919                         {
920                                 _ERR("alloc failed");
921                                 result = -1;
922                         }
923                 }
924                 else
925                 {
926                         _INFO("no secure element");
927                 }
928
929                 return result;
930         }
931
932         bool ServerResource::sendMessageToAllClients(Message &msg)
933         {
934                 bool result = true;
935                 map<int, ClientInstance *>::iterator item;
936
937                 for (item = mapClients.begin(); item != mapClients.end(); item++)
938                 {
939                         if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
940                                 result = false;
941                 }
942
943                 return result;
944         }
945
946         void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
947         {
948                 _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
949
950                 switch (event)
951                 {
952                 case Terminal::NOTIFY_SE_AVAILABLE :
953                         {
954                                 ServerResource &instance = ServerResource::getInstance();
955                                 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
956                                 Message msg;
957
958                                 _INFO("[NOTIFY_SE_AVAILABLE]");
959
960                                 terminalID = instance.getTerminalID((char *)terminal);
961                                 if (terminalID != IntegerHandle::INVALID_HANDLE)
962                                 {
963                                         /* send all client to refresh reader */
964                                         msg.message = msg.MSG_NOTIFY_SE_INSERTED;
965                                         msg.param1 = instance.createReader(terminalID);
966                                         msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
967
968                                         instance.sendMessageToAllClients(msg);
969                                 }
970                         }
971                         break;
972
973                 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
974                         {
975                                 ServerResource &instance = ServerResource::getInstance();
976                                 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
977                                 Message msg;
978
979                                 _INFO("[NOTIFY_SE_NOT_AVAILABLE]");
980
981                                 readerID = instance.getReaderID((char *)terminal);
982
983                                 /* send all client to refresh reader */
984                                 msg.message = msg.MSG_NOTIFY_SE_REMOVED;
985                                 msg.param1 = readerID;
986                                 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
987
988                                 instance.sendMessageToAllClients(msg);
989                                 instance.removeReader(readerID);
990                         }
991                         break;
992
993                 default :
994                         _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
995                         break;
996                 }
997         }
998
999         unsigned int ServerResource::createReader(unsigned int terminalID)
1000         {
1001                 unsigned int result = -1;
1002
1003                 result = IntegerHandle::assignHandle();
1004
1005                 mapReaders.insert(make_pair(result, terminalID));
1006
1007                 return result;
1008         }
1009
1010         unsigned int ServerResource::getReaderID(const char *name)
1011         {
1012                 unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
1013
1014                 terminalID = getTerminalID(name);
1015                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1016                 {
1017                         map<unsigned int, unsigned int>::iterator item;
1018
1019                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1020                         {
1021                                 if (item->second == terminalID)
1022                                 {
1023                                         result = item->first;
1024                                         break;
1025                                 }
1026                         }
1027                 }
1028
1029                 return result;
1030         }
1031
1032         void ServerResource::removeReader(unsigned int readerID)
1033         {
1034                 map<unsigned int, unsigned int>::iterator item;
1035
1036                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1037                 {
1038                         item->second = IntegerHandle::INVALID_HANDLE;
1039                 }
1040         }
1041
1042 } /* namespace smartcard_service_api */
1043
1044 using namespace smartcard_service_api;
1045
1046 EXTERN_API void server_resource_set_main_loop_instance(void *instance)
1047 {
1048         ServerResource::getInstance().setMainLoopInstance(instance);
1049 }