Fix the Prevent problems
[platform/core/connectivity/smartcard-service.git] / server / ServerResource.cpp
index 232fcdf..1f093a0 100644 (file)
 #include "TerminalInterface.h"
 #include "APDUHelper.h"
 #include "SignatureHelper.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
+#include "PKCS15.h"
+#ifdef USE_GDBUS
+#include "ServerGDBus.h"
+#endif
+#include "smartcard-daemon.h"
 
 #ifndef EXTERN_API
 #define EXTERN_API __attribute__((visibility("default")))
 #endif
 
+using namespace std;
+
 namespace smartcard_service_api
 {
        unsigned int IntegerHandle::newHandle = 0;
@@ -78,14 +85,13 @@ namespace smartcard_service_api
 
 #define OMAPI_SE_PATH "/usr/lib/se"
 
-       ServerResource::ServerResource()
-               : mainLoop(NULL), seLoaded(false)
+       ServerResource::ServerResource() : seLoaded(false)
        {
                _BEGIN();
-
+#ifndef USE_GDBUS
                serverIPC = ServerIPC::getInstance();
                serverDispatcher = ServerDispatcher::getInstance();
-
+#endif
                _END();
        }
 
@@ -100,13 +106,310 @@ namespace smartcard_service_api
                return serverResource;
        }
 
-       bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
+#ifdef USE_GDBUS
+       bool ServerResource::createClient(const char *name, pid_t pid)
+       {
+               bool result = false;
+
+               if (getClient(name) == NULL)
+               {
+                       ClientInstance *instance = new ClientInstance(name, pid);
+                       if (instance != NULL)
+                       {
+                               mapClients.insert(make_pair(name, instance));
+                               result = true;
+                       }
+                       else
+                       {
+                               _ERR("alloc failed");
+                       }
+               }
+               else
+               {
+                       _ERR("client already exist, name [%s]", name);
+               }
+
+               return result;
+       }
+
+       ClientInstance *ServerResource::getClient(const char *name)
+       {
+               ClientInstance *result = NULL;
+               map<string, ClientInstance *>::iterator item;
+
+               if ((item = mapClients.find(name)) != mapClients.end())
+               {
+                       result = item->second;
+               }
+
+               return result;
+       }
+
+       void ServerResource::removeClient(const char *name)
+       {
+               map<string, ClientInstance *>::iterator item;
+
+               if ((item = mapClients.find(name)) != mapClients.end())
+               {
+                       delete item->second;
+                       mapClients.erase(item);
+               }
+               else
+               {
+                       _DBG("client removed already, name [%s]", name);
+               }
+       }
+
+       void ServerResource::removeClients()
+       {
+               map<string, ClientInstance *>::iterator item;
+
+               for (item = mapClients.begin(); item != mapClients.end(); item++)
+               {
+                       delete item->second;
+               }
+
+               mapClients.clear();
+       }
+
+       int ServerResource::getClientCount() const
+       {
+               return (int)mapClients.size();
+       }
+
+       ServiceInstance *ServerResource::createService(const char *name)
+       {
+               ServiceInstance *result = NULL;
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(name)) != NULL)
+               {
+                       if ((result = instance->createService()) == NULL)
+                       {
+                               _ERR("ClientInstance::createService failed [%d]", name);
+                       }
+               }
+               else
+               {
+                       _ERR("client doesn't exist, name [%s]", name);
+               }
+
+               return result;
+       }
+
+       ServiceInstance *ServerResource::getService(const char *name, unsigned int handle)
+       {
+               ServiceInstance *result = NULL;
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(name)) != NULL)
+               {
+                       result = instance->getService(handle);
+               }
+               else
+               {
+                       _ERR("client doesn't exist, name [%s]", name);
+               }
+
+               return result;
+       }
+
+       void ServerResource::removeService(const char *name, unsigned int handle)
+       {
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(name)) != NULL)
+               {
+                       instance->removeService(handle);
+                       if (instance->getServiceCounts() == 0) {
+
+                               /* remove client instance */
+                               removeClient(name);
+                       }
+               }
+               else
+               {
+                       _ERR("client doesn't exist, name [%s]", name);
+               }
+       }
+
+       void ServerResource::removeServices(const char *name)
+       {
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(name)) != NULL)
+               {
+                       instance->removeServices();
+
+                       /* remove client instance */
+                       removeClient(name);
+               }
+               else
+               {
+                       _ERR("client doesn't exist, name [%s]", name);
+               }
+       }
+
+       unsigned int ServerResource::createSession(const char *name, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
+       {
+               unsigned int result = -1;
+               Terminal *temp = NULL;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(name, handle)) != NULL)
+               {
+                       if ((temp = getTerminalByReaderID(readerID)) != NULL)
+                       {
+                               result = instance->openSession(temp, certHashes, caller);
+                       }
+               }
+               else
+               {
+                       _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+               }
+
+               return result;
+       }
+
+       ServerSession *ServerResource::getSession(const char *name, unsigned int handle, unsigned int sessionID)
+       {
+               ServerSession *result = NULL;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(name, handle)) != NULL)
+               {
+                       result = instance->getSession(sessionID);
+               }
+               else
+               {
+                       _ERR("Session doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, sessionID);
+               }
+
+               return result;
+       }
+
+       bool ServerResource::isValidSessionHandle(const char *name, unsigned int handle, unsigned int session)
+       {
+               ServiceInstance *instance = NULL;
+
+               return (((instance = getService(name, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
+       }
+
+       unsigned int ServerResource::getChannelCount(const char *name, unsigned int handle, unsigned int sessionID)
+       {
+               unsigned int result = -1;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(name, handle)) != NULL)
+               {
+                       result = instance->getChannelCountBySession(sessionID);
+               }
+               else
+               {
+                       _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+               }
+
+               return result;
+       }
+
+       void ServerResource::removeSession(const char *name, unsigned int handle, unsigned int sessionID)
+       {
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(name, handle)) != NULL)
+               {
+                       instance->closeSession(sessionID);
+               }
+               else
+               {
+                       _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+               }
+       }
+
+       unsigned int ServerResource::createChannel(const char *name, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
+               throw(ExceptionBase &)
+       {
+               unsigned int result = -1;
+               ServiceInstance *service = NULL;
+
+               if ((service = getService(name, handle)) != NULL)
+               {
+                       if (service->isVaildSessionHandle(sessionID) == true)
+                       {
+                               ServerSession *session = NULL;
+                               Terminal *terminal = NULL;
+
+                               terminal = service->getTerminal(sessionID);
+                               session = service->getSession(sessionID);
+                               if (terminal != NULL && session != NULL)
+                               {
+                                       result = _createChannel(terminal, service, channelType, sessionID, aid);
+                                       if (result == IntegerHandle::INVALID_HANDLE)
+                                       {
+                                               _ERR("create channel failed [%d]", sessionID);
+                                       }
+                               }
+                               else
+                               {
+                                       _ERR("session is invalid [%d]", sessionID);
+                                       throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
+                               }
+                       }
+                       else
+                       {
+                               _ERR("session is invalid [%d]", sessionID);
+                               throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
+                       }
+               }
+               else
+               {
+                       _ERR("getService is failed, name [%s], handle [%d]", name, handle);
+                       throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
+               }
+
+               return result;
+       }
+
+       Channel *ServerResource::getChannel(const char *name, unsigned int handle, unsigned int channelID)
+       {
+               Channel *result = NULL;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(name, handle)) != NULL)
+               {
+                       result = instance->getChannel(channelID);
+               }
+               else
+               {
+                       _ERR("Channel doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, channelID);
+               }
+
+               return result;
+       }
+
+       void ServerResource::removeChannel(const char *name, unsigned int handle, unsigned int channelID)
+       {
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(name, handle)) != NULL)
+               {
+                       instance->closeChannel(channelID);
+               }
+               else
+               {
+                       _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+               }
+       }
+#else
+       bool ServerResource::createClient(void *ioChannel, int socket,
+               int watchID, int state, int pid)
        {
                bool result = false;
 
                if (getClient(socket) == NULL)
                {
-                       ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
+                       ClientInstance *instance = new ClientInstance(ioChannel,
+                               socket, watchID, state, pid);
                        if (instance != NULL)
                        {
                                mapClients.insert(make_pair(socket, instance));
@@ -119,7 +422,32 @@ namespace smartcard_service_api
                }
                else
                {
-                       _ERR("client already exist [%d]", socket);
+                       _ERR("client already exist, socket[%d]", socket);
+               }
+
+               return result;
+       }
+
+       bool ServerResource::createClient(int pid)
+       {
+               bool result = false;
+
+               if (getClient(pid) == NULL)
+               {
+                       ClientInstance *instance = new ClientInstance(pid);
+                       if (instance != NULL)
+                       {
+                               mapClients.insert(make_pair(pid, instance));
+                               result = true;
+                       }
+                       else
+                       {
+                               _ERR("alloc failed");
+                       }
+               }
+               else
+               {
+                       _ERR("client already exist, pid[%d]", pid);
                }
 
                return result;
@@ -138,6 +466,19 @@ namespace smartcard_service_api
                return result;
        }
 
+       const ClientInstance *ServerResource::getClient(int socket) const
+       {
+               const ClientInstance *result = NULL;
+               map<int, ClientInstance *>::const_iterator item;
+
+               if ((item = mapClients.find(socket)) != mapClients.end())
+               {
+                       result = item->second;
+               }
+
+               return result;
+       }
+
        void ServerResource::setPID(int socket, int pid)
        {
                map<int, ClientInstance *>::iterator item;
@@ -149,19 +490,15 @@ namespace smartcard_service_api
                }
        }
 
-       int ServerResource::getClientCount()
-       {
-               return (int)mapClients.size();
-       }
-
        void ServerResource::removeClient(int socket)
        {
                map<int, ClientInstance *>::iterator item;
 
                if ((item = mapClients.find(socket)) != mapClients.end())
                {
+#ifndef USE_GDBUS
                        ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
-
+#endif
                        delete item->second;
                        mapClients.erase(item);
                }
@@ -177,86 +514,257 @@ namespace smartcard_service_api
 
                for (item = mapClients.begin(); item != mapClients.end(); item++)
                {
-                       ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
-
-                       delete item->second;
+#ifndef USE_GDBUS
+                       ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
+#endif
+                       delete item->second;
+               }
+
+               mapClients.clear();
+       }
+
+       int ServerResource::getClientCount() const
+       {
+               return (int)mapClients.size();
+       }
+
+       ServiceInstance *ServerResource::createService(int socket)
+       {
+               ServiceInstance *result = NULL;
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(socket)) != NULL)
+               {
+                       if ((result = instance->createService()) == NULL)
+                       {
+                               _ERR("ClientInstance::createService failed [%d]", socket);
+                       }
+               }
+               else
+               {
+                       _ERR("client doesn't exist [%d]", socket);
+               }
+
+               return result;
+       }
+
+       ServiceInstance *ServerResource::getService(int socket, unsigned int handle)
+       {
+               ServiceInstance *result = NULL;
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(socket)) != NULL)
+               {
+                       result = instance->getService(handle);
+               }
+               else
+               {
+                       _ERR("client doesn't exist [%d]", socket);
+               }
+
+               return result;
+       }
+
+       void ServerResource::removeService(int socket, unsigned int handle)
+       {
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(socket)) != NULL)
+               {
+                       instance->removeService(handle);
+               }
+               else
+               {
+                       _ERR("client doesn't exist [%d]", socket);
+               }
+       }
+
+       void ServerResource::removeServices(int socket)
+       {
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(socket)) != NULL)
+               {
+                       instance->removeServices();
+               }
+               else
+               {
+                       _ERR("client doesn't exist [%d]", socket);
+               }
+       }
+
+       unsigned int ServerResource::createSession(int socket, unsigned int handle, unsigned int readerID, const vector<ByteArray> &certHashes, void *caller)
+       {
+               unsigned int result = -1;
+               Terminal *temp = NULL;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(socket, handle)) != NULL)
+               {
+                       if ((temp = getTerminalByReaderID(readerID)) != NULL)
+                       {
+                               result = instance->openSession(temp, certHashes, caller);
+                       }
+               }
+               else
+               {
+                       _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
+               }
+
+               return result;
+       }
+
+       ServerSession *ServerResource::getSession(int socket, unsigned int handle, unsigned int sessionID)
+       {
+               ServerSession *result = NULL;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(socket, handle)) != NULL)
+               {
+                       result = instance->getSession(sessionID);
+               }
+               else
+               {
+                       _ERR("Session doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, sessionID);
+               }
+
+               return result;
+       }
+
+       bool ServerResource::isValidSessionHandle(int socket, unsigned int handle, unsigned int session)
+       {
+               ServiceInstance *instance = NULL;
+
+               return (((instance = getService(socket, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
+       }
+
+       unsigned int ServerResource::getChannelCount(int socket, unsigned int handle, unsigned int sessionID)
+       {
+               unsigned int result = -1;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(socket, handle)) != NULL)
+               {
+                       result = instance->getChannelCountBySession(sessionID);
+               }
+               else
+               {
+                       _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
+               }
+
+               return result;
+       }
+
+       void ServerResource::removeSession(int socket, unsigned int handle, unsigned int sessionID)
+       {
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(socket, handle)) != NULL)
+               {
+                       instance->closeSession(sessionID);
+               }
+               else
+               {
+                       _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
                }
-
-               mapClients.clear();
        }
 
-       ServiceInstance *ServerResource::createService(int socket, unsigned int context)
+       unsigned int ServerResource::createChannel(int socket, unsigned int handle, unsigned int sessionID, int channelType, const ByteArray &aid)
+               throw(ExceptionBase &)
        {
-               ServiceInstance *result = NULL;
-               ClientInstance *instance = NULL;
+               unsigned int result = -1;
+               ServiceInstance *service = NULL;
 
-               if ((instance = getClient(socket)) != NULL)
+               if ((service = getService(socket, handle)) != NULL)
                {
-                       if ((result = instance->getService(context)) == NULL)
+                       if (service->isVaildSessionHandle(sessionID) == true)
                        {
-                               if ((result = instance->createService(context)) == NULL)
+                               ServerSession *session = NULL;
+                               Terminal *terminal = NULL;
+
+                               terminal = service->getTerminal(sessionID);
+                               session = service->getSession(sessionID);
+                               if (terminal != NULL && session != NULL)
+                               {
+                                       result = _createChannel(terminal, service, channelType, sessionID, aid);
+                                       if (result == IntegerHandle::INVALID_HANDLE)
+                                       {
+                                               _ERR("create channel failed [%d]", sessionID);
+                                       }
+                               }
+                               else
                                {
-                                       _ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
+                                       _ERR("session is invalid [%d]", sessionID);
+                                       throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
                                }
                        }
+                       else
+                       {
+                               _ERR("session is invalid [%d]", sessionID);
+                               throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
+                       }
                }
                else
                {
-                       _ERR("client doesn't exist [%d]", socket);
+                       _ERR("getService is failed [%d] [%d]", socket, handle);
+                       throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
                }
 
                return result;
        }
 
-       ServiceInstance *ServerResource::getService(int socket, unsigned int context)
+       Channel *ServerResource::getChannel(int socket, unsigned int handle, unsigned int channelID)
        {
-               ServiceInstance *result = NULL;
-               ClientInstance *instance = NULL;
+               Channel *result = NULL;
+               ServiceInstance *instance = NULL;
 
-               if ((instance = getClient(socket)) != NULL)
+               if ((instance = getService(socket, handle)) != NULL)
                {
-                       result = instance->getService(context);
+                       result = instance->getChannel(channelID);
                }
                else
                {
-                       _ERR("client doesn't exist [%d]", socket);
+                       _ERR("Channel doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, channelID);
                }
 
                return result;
        }
 
-       void ServerResource::removeService(int socket, unsigned int context)
+       void ServerResource::removeChannel(int socket, unsigned int handle, unsigned int channelID)
        {
-               ClientInstance *instance = NULL;
+               ServiceInstance *instance = NULL;
 
-               if ((instance = getClient(socket)) != NULL)
+               if ((instance = getService(socket, handle)) != NULL)
                {
-                       instance->removeService(context);
+                       instance->closeChannel(channelID);
                }
                else
                {
-                       _ERR("client doesn't exist [%d]", socket);
+                       _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
                }
        }
-
-       void ServerResource::removeServices(int socket)
+#endif
+       Terminal *ServerResource::getTerminal(unsigned int terminalID)
        {
-               ClientInstance *instance = NULL;
+               Terminal *result = NULL;
+               map<unsigned int, Terminal *>::iterator item;
 
-               if ((instance = getClient(socket)) != NULL)
+               if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
                {
-                       instance->removeServices();
+                       result = item->second;
                }
                else
                {
-                       _ERR("client doesn't exist [%d]", socket);
+                       _ERR("Terminal doesn't exist [%d]", terminalID);
                }
+
+               return result;
        }
 
-       Terminal *ServerResource::getTerminal(unsigned int terminalID)
+       const Terminal *ServerResource::getTerminal(unsigned int terminalID) const
        {
-               Terminal *result = NULL;
-               map<unsigned int, Terminal *>::iterator item;
+               const Terminal *result = NULL;
+               map<unsigned int, Terminal *>::const_iterator item;
 
                if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
                {
@@ -304,110 +812,83 @@ namespace smartcard_service_api
                return result;
        }
 
-       unsigned int ServerResource::getTerminalID(const char *name)
+       const Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID) const
        {
-               unsigned int result = IntegerHandle::INVALID_HANDLE;
-               map<unsigned int, Terminal *>::iterator item;
-
-               for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
-               {
-                       if (strncmp(name, item->second->getName(), strlen(name)) == 0)
-                       {
-                               result = item->first;
-                               break;
-                       }
-               }
-
-               return result;
-       }
-
-       unsigned int ServerResource::createSession(int socket, unsigned int context, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
-       {
-               unsigned int result = -1;
-               Terminal *temp = NULL;
-               ServiceInstance *instance = NULL;
+               const Terminal *result = NULL;
+               map<unsigned int, unsigned int>::const_iterator item;
 
-               if ((instance = getService(socket, context)) != NULL)
+               if ((item = mapReaders.find(readerID)) != mapReaders.end())
                {
-                       if ((temp = getTerminalByReaderID(readerID)) != NULL)
-                       {
-                               result = instance->openSession(temp, certHashes, caller);
-                       }
+                       result = getTerminal(item->second);
                }
                else
                {
-                       _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+                       _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
                }
 
                return result;
        }
 
-       ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
+       unsigned int ServerResource::getTerminalID(const char *name) const
        {
-               ServerSession *result = NULL;
-               ServiceInstance *instance = NULL;
+               unsigned int result = IntegerHandle::INVALID_HANDLE;
+               map<unsigned int, Terminal *>::const_iterator item;
 
-               if ((instance = getService(socket, context)) != NULL)
-               {
-                       result = instance->getSession(sessionID);
-               }
-               else
+               for (item = mapTerminals.begin();
+                       item != mapTerminals.end(); item++)
                {
-                       _ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
+                       if (strncmp(name, item->second->getName(),
+                               strlen(name)) == 0)
+                       {
+                               result = item->first;
+                               break;
+                       }
                }
 
                return result;
        }
 
-       unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
+       bool ServerResource::_isAuthorizedAccess(ServerChannel *channel,
+               const ByteArray &aid, const vector<ByteArray> &hashes)
        {
-               unsigned int result = -1;
-               ServiceInstance *instance = NULL;
+               bool result = false;
+               AccessControlList *acList = NULL;
 
-               if ((instance = getService(socket, context)) != NULL)
-               {
-                       result = instance->getChannelCountBySession(sessionID);
-               }
-               else
+               /* request open channel sequence */
+               if ((acList = getAccessControlList(channel)) == NULL)
                {
-                       _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
-               }
-
-               return result;
-       }
-
-       void ServerResource::removeSession(int socket, unsigned int context, unsigned int sessionID)
-       {
-               ServiceInstance *instance = NULL;
+                       /* load access control defined by Global Platform */
+                       GPACE *acl = new GPACE();
+                       if (acl != NULL)
+                       {
+                               int ret;
 
-               if ((instance = getService(socket, context)) != NULL)
-               {
-                       instance->closeSession(sessionID);
+                               ret = acl->loadACL(channel);
+                               if (ret >= SCARD_ERROR_OK)
+                               {
+                                       acList = acl;
+                                       addAccessControlList(channel, acList);
+                               }
+                               else
+                               {
+                                       _ERR("unknown error, 0x%x", -ret);
+                                       delete acl;
+                               }
+                       }
+                       else
+                       {
+                               _ERR("alloc failed");
+                       }
                }
                else
                {
-                       _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+                       acList->loadACL(channel);
                }
-       }
-
-       bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
-       {
-               bool result = true;
-               AccessControlList *acList = NULL;
 
-               /* request open channel sequence */
-               if ((acList = getAccessControlList(channel)) != NULL)
+               if (acList != NULL)
                {
-                       PKCS15 pkcs15(channel);
-
-                       acList->loadACL(channel);
                        result = acList->isAuthorizedAccess(aid, hashes);
                }
-               else
-               {
-                       _ERR("acList is null");
-                       result = false;
-               }
 
                return result;
        }
@@ -422,7 +903,7 @@ namespace smartcard_service_api
                /* open channel */
                command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
                rv = terminal->transmitSync(command, response);
-               if (rv == 0 && response.getLength() >= 2)
+               if (rv == 0 && response.size() >= 2)
                {
                        ResponseHelper resp(response);
 
@@ -437,7 +918,7 @@ namespace smartcard_service_api
                }
                else
                {
-                       _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+                       _ERR("transmitSync failed, rv [%d], length [%d]", rv, response.size());
                }
 
                return result;
@@ -453,7 +934,7 @@ namespace smartcard_service_api
                /* open channel */
                command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
                rv = terminal->transmitSync(command, response);
-               if (rv == 0 && response.getLength() >= 2)
+               if (rv == 0 && response.size() >= 2)
                {
                        ResponseHelper resp(response);
 
@@ -469,13 +950,15 @@ namespace smartcard_service_api
                }
                else
                {
-                       _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+                       _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.size());
                }
 
                return result;
        }
 
-       unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
+       unsigned int ServerResource::_createChannel(Terminal *terminal,
+               ServiceInstance *service, int channelType,
+               unsigned int sessionID, const ByteArray &aid)
                throw(ExceptionBase &)
        {
                unsigned int result = IntegerHandle::INVALID_HANDLE;
@@ -514,8 +997,8 @@ namespace smartcard_service_api
                channel = service->getChannel(result);
 
                /* check */
-               if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
-                               aid, service->getParent()->getCertificationHashes()) == true)
+               if (_isAuthorizedAccess(channel, aid,
+                       service->getParent()->getCertificationHashes()) == true)
                {
                        int rv = 0;
 
@@ -524,14 +1007,16 @@ namespace smartcard_service_api
                        {
                                PKCS15 pkcs15(channel);
 
-                               if (pkcs15.isClosed() == false)
+                               rv = pkcs15.select();
+                               if (rv >= SCARD_ERROR_OK)
                                {
                                        /* remove privilege mode */
                                        channel->unsetPrivilegeMode();
+                                       channel->setSelectResponse(pkcs15.getSelectResponse());
                                }
                                else
                                {
-                                       _ERR("select failed");
+                                       _ERR("select failed, [%x]", -rv);
 
                                        service->closeChannel(result);
                                        throw ExceptionBase(SCARD_ERROR_IO_FAILED);
@@ -542,14 +1027,15 @@ namespace smartcard_service_api
                                FileObject file(channel);
 
                                rv = file.select(aid);
-                               if (rv >= 0)
+                               if (rv >= SCARD_ERROR_OK)
                                {
                                        /* remove privilege mode */
                                        channel->unsetPrivilegeMode();
+                                       channel->setSelectResponse(file.getSelectResponse());
                                }
                                else
                                {
-                                       _ERR("select failed [%d]", rv);
+                                       _ERR("select failed [%x]", -rv);
 
                                        service->closeChannel(result);
                                        throw ExceptionBase(SCARD_ERROR_IO_FAILED);
@@ -567,78 +1053,31 @@ namespace smartcard_service_api
                return result;
        }
 
-       unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
-               throw(ExceptionBase &)
-       {
-               unsigned int result = -1;
-               ServiceInstance *service = NULL;
-
-               if ((service = getService(socket, context)) != NULL)
-               {
-                       if (service->isVaildSessionHandle(sessionID) == true)
-                       {
-                               ServerSession *session = NULL;
-                               Terminal *terminal = NULL;
-
-                               terminal = service->getTerminal(sessionID);
-                               session = service->getSession(sessionID);
-                               if (terminal != NULL && session != NULL)
-                               {
-                                       result = _createChannel(terminal, service, channelType, sessionID, aid);
-                                       if (result == IntegerHandle::INVALID_HANDLE)
-                                       {
-                                               _ERR("create channel failed [%d]", sessionID);
-                                       }
-                               }
-                               else
-                               {
-                                       _ERR("session is invalid [%d]", sessionID);
-                                       throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
-                               }
-                       }
-                       else
-                       {
-                               _ERR("session is invalid [%d]", sessionID);
-                               throw ExceptionBase(SCARD_ERROR_ILLEGAL_PARAM);
-                       }
-               }
-               else
-               {
-                       _ERR("getService is failed [%d] [%d]", socket, context);
-                       throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
-               }
-
-               return result;
-       }
-
-       Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
+       void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
        {
-               Channel *result = NULL;
-               ServiceInstance *instance = NULL;
+               map<Terminal *, AccessControlList *>::iterator item;
 
-               if ((instance = getService(socket, context)) != NULL)
+               if ((item = mapACL.find(terminal)) == mapACL.end())
                {
-                       result = instance->getChannel(channelID);
+                       mapACL.insert(make_pair(terminal, acl));
                }
                else
                {
-                       _ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
+                       item->second = acl;
                }
-
-               return result;
        }
 
-       void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
+       void ServerResource::addAccessControlList(ServerChannel *channel, AccessControlList *acl)
        {
-               ServiceInstance *instance = NULL;
+               map<Terminal *, AccessControlList *>::iterator item;
 
-               if ((instance = getService(socket, context)) != NULL)
+               if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
                {
-                       instance->closeChannel(channelID);
+                       mapACL.insert(make_pair(channel->getTerminal(), acl));
                }
                else
                {
-                       _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+                       item->second = acl;
                }
        }
 
@@ -647,20 +1086,7 @@ namespace smartcard_service_api
                AccessControlList *result = NULL;
                map<Terminal *, AccessControlList *>::iterator item;
 
-               if ((item = mapACL.find(terminal)) == mapACL.end())
-               {
-                       /* load access control */
-                       result = new GPSEACL();
-                       if (result != NULL)
-                       {
-                               mapACL.insert(make_pair(terminal, result));
-                       }
-                       else
-                       {
-                               _ERR("alloc failed");
-                       }
-               }
-               else
+               if ((item = mapACL.find(terminal)) != mapACL.end())
                {
                        result = item->second;
                }
@@ -673,20 +1099,7 @@ namespace smartcard_service_api
                AccessControlList *result = NULL;
                map<Terminal *, AccessControlList *>::iterator item;
 
-               if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
-               {
-                       /* load access control */
-                       result = new GPSEACL();
-                       if (result != NULL)
-                       {
-                               mapACL.insert(make_pair(channel->getTerminal(), result));
-                       }
-                       else
-                       {
-                               _ERR("alloc failed");
-                       }
-               }
-               else
+               if ((item = mapACL.find(channel->getTerminal())) != mapACL.end())
                {
                        result = item->second;
                }
@@ -836,19 +1249,32 @@ namespace smartcard_service_api
                }
        }
 
-       bool ServerResource::isValidReaderHandle(unsigned int reader)
+       bool ServerResource::isValidReaderHandle(unsigned int reader) const
        {
                return (getTerminalByReaderID(reader) != NULL);
        }
 
-       bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
+       void ServerResource::getReaders(vector<pair<unsigned int, string> > &readers) const
        {
-               ServiceInstance *instance = NULL;
+               const Terminal *terminal;
+               map<unsigned int, unsigned int>::const_iterator item;
 
-               return (((instance = getService(socket, context)) != NULL) && (instance->isVaildSessionHandle(session)));
+               readers.clear();
+
+               for (item = mapReaders.begin(); item != mapReaders.end(); item++)
+               {
+                       if (item->second != IntegerHandle::INVALID_HANDLE)
+                       {
+                               terminal = getTerminal(item->second);
+                               if (terminal != NULL && terminal->isSecureElementPresence() == true)
+                               {
+                                       readers.push_back(make_pair(item->first, terminal->getName()));
+                               }
+                       }
+               }
        }
 
-       int ServerResource::getReadersInformation(ByteArray &info)
+       int ServerResource::getReadersInformation(ByteArray &info) const
        {
                int result = 0;
                unsigned char *buffer = NULL;
@@ -858,8 +1284,8 @@ namespace smartcard_service_api
 
                if (mapReaders.size() > 0)
                {
-                       Terminal *terminal = NULL;
-                       map<unsigned int, unsigned int>::iterator item;
+                       const Terminal *terminal = NULL;
+                       map<unsigned int, unsigned int>::const_iterator item;
 
                        for (item = mapReaders.begin(); item != mapReaders.end(); item++)
                        {
@@ -906,7 +1332,7 @@ namespace smartcard_service_api
                                        }
                                }
 
-                               info.setBuffer(buffer, length);
+                               info.assign(buffer, length);
                                delete []buffer;
                        }
                        else
@@ -923,21 +1349,27 @@ namespace smartcard_service_api
                return result;
        }
 
-       bool ServerResource::sendMessageToAllClients(Message &msg)
+#ifndef USE_GDBUS
+       bool ServerResource::sendMessageToAllClients(const Message &msg)
        {
                bool result = true;
-               map<int, ClientInstance *>::iterator item;
 
-               for (item = mapClients.begin(); item != mapClients.end(); item++)
+               map<int, ClientInstance *>::const_iterator item;
+
+               for (item = mapClients.begin();
+                       item != mapClients.end(); item++)
                {
-                       if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
+                       if (item->second->sendMessageToAllServices(
+                               item->second->getSocket(), msg) == false)
                                result = false;
                }
 
                return result;
        }
+#endif
 
-       void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
+       void ServerResource::terminalCallback(const void *terminal, int event,
+               int error, void *user_param)
        {
                _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
 
@@ -947,19 +1379,26 @@ namespace smartcard_service_api
                        {
                                ServerResource &instance = ServerResource::getInstance();
                                unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
-                               Message msg;
 
                                _INFO("[NOTIFY_SE_AVAILABLE]");
 
                                terminalID = instance.getTerminalID((char *)terminal);
                                if (terminalID != IntegerHandle::INVALID_HANDLE)
                                {
+                                       unsigned int readerID = instance.createReader(terminalID);
+#ifdef USE_GDBUS
+                                       ServerGDBus::getInstance().emitReaderInserted(readerID, (const char *)terminal);
+#else
+                                       Message msg;
+
                                        /* send all client to refresh reader */
                                        msg.message = msg.MSG_NOTIFY_SE_INSERTED;
-                                       msg.param1 = instance.createReader(terminalID);
-                                       msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+                                       msg.param1 = readerID;
+                                       msg.data.assign((uint8_t *)terminal,
+                                               strlen((char *)terminal) + 1);
 
                                        instance.sendMessageToAllClients(msg);
+#endif
                                }
                        }
                        break;
@@ -968,18 +1407,24 @@ namespace smartcard_service_api
                        {
                                ServerResource &instance = ServerResource::getInstance();
                                unsigned int readerID = IntegerHandle::INVALID_HANDLE;
-                               Message msg;
 
                                _INFO("[NOTIFY_SE_NOT_AVAILABLE]");
 
                                readerID = instance.getReaderID((char *)terminal);
+#ifdef USE_GDBUS
+                               ServerGDBus::getInstance().emitReaderRemoved(
+                                       readerID, (const char *)terminal);
+#else
+                               Message msg;
 
                                /* send all client to refresh reader */
                                msg.message = msg.MSG_NOTIFY_SE_REMOVED;
                                msg.param1 = readerID;
-                               msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+                               msg.data.assign((uint8_t *)terminal,
+                                       strlen((char *)terminal) + 1);
 
                                instance.sendMessageToAllClients(msg);
+#endif
                                instance.removeReader(readerID);
                        }
                        break;
@@ -1001,16 +1446,18 @@ namespace smartcard_service_api
                return result;
        }
 
-       unsigned int ServerResource::getReaderID(const char *name)
+       unsigned int ServerResource::getReaderID(const char *name) const
        {
-               unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
+               unsigned int result = IntegerHandle::INVALID_HANDLE,
+                       terminalID = IntegerHandle::INVALID_HANDLE;
 
                terminalID = getTerminalID(name);
                if (terminalID != IntegerHandle::INVALID_HANDLE)
                {
-                       map<unsigned int, unsigned int>::iterator item;
+                       map<unsigned int, unsigned int>::const_iterator item;
 
-                       for (item = mapReaders.begin(); item != mapReaders.end(); item++)
+                       for (item = mapReaders.begin();
+                               item != mapReaders.end(); item++)
                        {
                                if (item->second == terminalID)
                                {
@@ -1033,11 +1480,67 @@ namespace smartcard_service_api
                }
        }
 
-} /* namespace smartcard_service_api */
+       bool ServerResource::isAuthorizedNFCAccess(Terminal *terminal,
+               const ByteArray &aid, const vector<ByteArray> &hashes)
+       {
+               bool result = false;
 
-using namespace smartcard_service_api;
+               if (terminal == NULL) {
+                       return result;
+               }
 
-EXTERN_API void server_resource_set_main_loop_instance(void *instance)
-{
-       ServerResource::getInstance().setMainLoopInstance(instance);
-}
+               int num = _openLogicalChannel(terminal);
+               if (num > 0) {
+                       /* create channel instance */
+                       ServerChannel *channel = new ServerChannel(NULL, NULL, num, terminal);
+                       if (channel != NULL) {
+                               AccessControlList *acl = getAccessControlList(channel);
+                               if (acl == NULL) {
+
+                                       /* load access control defined by Global Platform */
+                                       acl = new GPACE();
+                                       if (acl != NULL) {
+                                               int ret;
+
+                                               ret = acl->loadACL(channel);
+                                               if (ret >= SCARD_ERROR_OK) {
+                                                       addAccessControlList(channel, acl);
+                                               } else {
+                                                       _ERR("unknown error, 0x%x", -ret);
+
+                                                       delete acl;
+                                                       acl = NULL;
+                                               }
+                                       } else {
+                                               _ERR("alloc failed");
+                                       }
+                               } else {
+                                       acl->updateACL(channel);
+                               }
+
+                               if (acl != NULL) {
+                                       result = acl->isAuthorizedNFCAccess(aid, hashes);
+                               } else {
+                                       _ERR("acl is null");
+                               }
+
+                               delete channel;
+                       } else {
+                               _ERR("alloc failed");
+                       }
+               } else {
+                       _ERR("_openLogicalChannel failed");
+               }
+
+               return result;
+       }
+
+       void ServerResource::finish()
+       {
+               if (getClientCount() == 0) {
+                       _INFO("no client connected. terminate server");
+
+                       smartcard_daemon_exit();
+               }
+       }
+} /* namespace smartcard_service_api */