update the latest source 2.0alpha master 2.0_alpha accepted/tizen/20130520.103000 submit/master/20120920.151113 submit/tizen/20130517.015828
authorSungjae Lim <neueziel.lim>
Wed, 22 Aug 2012 12:36:29 +0000 (21:36 +0900)
committerSungjae Lim <neueziel.lim>
Wed, 22 Aug 2012 12:36:29 +0000 (21:36 +0900)
125 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
client/CMakeLists.txt [new file with mode: 0644]
client/ClientChannel.cpp [new file with mode: 0644]
client/ClientDispatcher.cpp [new file with mode: 0644]
client/ClientIPC.cpp [new file with mode: 0644]
client/Reader.cpp [new file with mode: 0644]
client/SEService.cpp [new file with mode: 0644]
client/Session.cpp [new file with mode: 0644]
client/include/ClientChannel.h [new file with mode: 0644]
client/include/ClientDispatcher.h [new file with mode: 0644]
client/include/ClientIPC.h [new file with mode: 0644]
client/include/Reader.h [new file with mode: 0644]
client/include/SEService.h [new file with mode: 0644]
client/include/SEServiceListener.h [new file with mode: 0644]
client/include/Session.h [new file with mode: 0644]
client/smartcard-service.pc [new file with mode: 0644]
common/APDUHelper.cpp [new file with mode: 0644]
common/AccessCondition.cpp [new file with mode: 0644]
common/AccessControlList.cpp [new file with mode: 0644]
common/ByteArray.cpp [new file with mode: 0644]
common/CMakeLists.txt [new file with mode: 0644]
common/DispatcherHelper.cpp [new file with mode: 0644]
common/FCI.cpp [new file with mode: 0644]
common/FileObject.cpp [new file with mode: 0644]
common/GPSEACL.cpp [new file with mode: 0644]
common/IPCHelper.cpp [new file with mode: 0644]
common/ISO7816BERTLV.cpp [new file with mode: 0644]
common/Message.cpp [new file with mode: 0644]
common/NumberStream.cpp [new file with mode: 0644]
common/OpensslHelper.cpp [new file with mode: 0644]
common/PKCS15.cpp [new file with mode: 0644]
common/PKCS15DODF.cpp [new file with mode: 0644]
common/PKCS15ODF.cpp [new file with mode: 0644]
common/PKCS15OID.cpp [new file with mode: 0644]
common/PKCS15Object.cpp [new file with mode: 0644]
common/PKCS15Path.cpp [new file with mode: 0644]
common/PKCS15TokenInfo.cpp [new file with mode: 0644]
common/ProviderHelper.cpp [new file with mode: 0644]
common/ReaderHelper.cpp [new file with mode: 0644]
common/Record.cpp [new file with mode: 0644]
common/SEServiceHelper.cpp [new file with mode: 0644]
common/Serializable.cpp [new file with mode: 0644]
common/SessionHelper.cpp [new file with mode: 0644]
common/SignatureHelper.cpp [new file with mode: 0644]
common/SimpleTLV.cpp [new file with mode: 0644]
common/Synchronous.cpp [new file with mode: 0644]
common/TLVHelper.cpp [new file with mode: 0644]
common/include/APDUHelper.h [new file with mode: 0644]
common/include/AccessCondition.h [new file with mode: 0644]
common/include/AccessControlList.h [new file with mode: 0644]
common/include/ByteArray.h [new file with mode: 0644]
common/include/Channel.h [new file with mode: 0644]
common/include/Debug.h [new file with mode: 0644]
common/include/DispatcherHelper.h [new file with mode: 0644]
common/include/DispatcherMsg.h [new file with mode: 0644]
common/include/FCI.h [new file with mode: 0644]
common/include/FileObject.h [new file with mode: 0644]
common/include/GPSEACL.h [new file with mode: 0644]
common/include/IPCHelper.h [new file with mode: 0644]
common/include/ISO7816BERTLV.h [new file with mode: 0644]
common/include/Lock.h [new file with mode: 0644]
common/include/Message.h [new file with mode: 0644]
common/include/NumberStream.h [new file with mode: 0644]
common/include/OpensslHelper.h [new file with mode: 0644]
common/include/PKCS15.h [new file with mode: 0644]
common/include/PKCS15DODF.h [new file with mode: 0644]
common/include/PKCS15ODF.h [new file with mode: 0644]
common/include/PKCS15OID.h [new file with mode: 0644]
common/include/PKCS15Object.h [new file with mode: 0644]
common/include/PKCS15Path.h [new file with mode: 0644]
common/include/PKCS15TokenInfo.h [new file with mode: 0644]
common/include/ProviderHelper.h [new file with mode: 0644]
common/include/ReaderHelper.h [new file with mode: 0644]
common/include/Record.h [new file with mode: 0644]
common/include/SEServiceHelper.h [new file with mode: 0644]
common/include/Serializable.h [new file with mode: 0644]
common/include/SessionHelper.h [new file with mode: 0644]
common/include/SignatureHelper.h [new file with mode: 0644]
common/include/SimpleTLV.h [new file with mode: 0644]
common/include/Synchronous.h [new file with mode: 0644]
common/include/TLVHelper.h [new file with mode: 0644]
common/include/Terminal.h [new file with mode: 0644]
common/include/TerminalInterface.h [new file with mode: 0644]
common/include/smartcard-types.h [new file with mode: 0644]
common/smartcard-service-common.pc [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/smartcard-service-common-dev.dirs [new file with mode: 0644]
debian/smartcard-service-common-dev.install [new file with mode: 0644]
debian/smartcard-service-common.dirs [new file with mode: 0644]
debian/smartcard-service-common.install [new file with mode: 0644]
debian/smartcard-service-dev.dirs [new file with mode: 0644]
debian/smartcard-service-dev.install [new file with mode: 0644]
debian/smartcard-service-server.dirs [new file with mode: 0644]
debian/smartcard-service-server.init [new file with mode: 0755]
debian/smartcard-service-server.install [new file with mode: 0644]
debian/smartcard-service.dirs [new file with mode: 0644]
debian/smartcard-service.install [new file with mode: 0644]
packaging/smartcard-service-server.init [new file with mode: 0755]
packaging/smartcard-service.spec [new file with mode: 0644]
server/CMakeLists.txt [new file with mode: 0644]
server/ClientInstance.cpp [new file with mode: 0644]
server/ServerChannel.cpp [new file with mode: 0644]
server/ServerDispatcher.cpp [new file with mode: 0644]
server/ServerIPC.cpp [new file with mode: 0644]
server/ServerReader.cpp [new file with mode: 0644]
server/ServerResource.cpp [new file with mode: 0644]
server/ServerSEService.cpp [new file with mode: 0644]
server/ServerSession.cpp [new file with mode: 0644]
server/ServiceInstance.cpp [new file with mode: 0644]
server/include/ClientInstance.h [new file with mode: 0644]
server/include/ServerChannel.h [new file with mode: 0644]
server/include/ServerDispatcher.h [new file with mode: 0644]
server/include/ServerIPC.h [new file with mode: 0644]
server/include/ServerReader.h [new file with mode: 0644]
server/include/ServerResource.h [new file with mode: 0644]
server/include/ServerSEService.h [new file with mode: 0644]
server/include/ServerSession.h [new file with mode: 0644]
server/include/ServiceInstance.h [new file with mode: 0644]
server/smartcard-daemon.cpp [new file with mode: 0644]
test-client/CMakeLists.txt [new file with mode: 0644]
test-client/test-client.cpp [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..728b215
--- /dev/null
@@ -0,0 +1,11 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+MESSAGE("build smartcard-service")
+
+SET(CMAKE_VERBOSE_MAKEFILE OFF)
+
+ADD_SUBDIRECTORY(common)
+ADD_SUBDIRECTORY(server)
+ADD_SUBDIRECTORY(client)
+ADD_SUBDIRECTORY(test-client)
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..ec68963
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,206 @@
+Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+                                 Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      "License" shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      "Licensor" shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      "Legal Entity" shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      "control" means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      "You" (or "Your") shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      "Source" form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      "Object" form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      "Work" shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      "Derivative Works" shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      "Contribution" shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, "submitted"\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+      "Contributor" shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a "NOTICE" text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets "[]"\r
+      replaced with your own identifying information. (Don't include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same "printed page" as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+\r
+\r
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
new file mode 100644 (file)
index 0000000..20c8782
--- /dev/null
@@ -0,0 +1,89 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(smartcard-service CXX)
+
+SET(LIB_NAME "smartcard-service")
+SET(VERSION_MAJOR 1)
+SET(VERSION ${VERSION_MAJOR}.0.0)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SRCS)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+        SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_client REQUIRED gthread-2.0 dlog)
+
+MESSAGE("${LIB_NAME} ld flag : ${pkgs_client_LDFLAGS}")
+
+FOREACH(flag ${pkgs_client_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${pkgs_client_CFLAGS})
+       SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+
+#SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -finstrument-functions")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+#SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+#SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+#SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -finstrument-functions")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+#SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+#SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+MESSAGE("CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DSLP_DEBUG")
+
+ADD_DEFINITIONS("-DLOG_TAG=\"SCARD_CLIENT\"")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES VERSION ${VERSION})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_client_LDFLAGS})
+
+SET(EXPORT_HEADER 
+       ../common/include/smartcard-types.h
+       ../common/include/ByteArray.h
+       ../common/include/Debug.h
+       ../common/include/Synchronous.h
+       ../common/include/APDUHelper.h
+       ../common/include/Channel.h
+       ../common/include/Serializable.h
+       ../common/include/SEServiceHelper.h
+       ../common/include/ReaderHelper.h
+       ../common/include/SessionHelper.h
+#      ../common/include/FCI.h
+#      ../common/include/
+       include/SEServiceListener.h
+       include/SEService.h
+       include/Reader.h
+       include/Session.h
+       include/ClientChannel.h
+#      include/
+)
+
+#CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc DESTINATION lib/pkgconfig)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
+FOREACH(hfile ${EXPORT_HEADER})
+        INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
+ENDFOREACH(hfile)
diff --git a/client/ClientChannel.cpp b/client/ClientChannel.cpp
new file mode 100644 (file)
index 0000000..68680fe
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <unistd.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Message.h"
+#include "ClientIPC.h"
+#include "ClientChannel.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+       ClientChannel::ClientChannel(void *context, Session *session, int channelNum, ByteArray selectResponse, void *handle):Channel(session)
+       {
+               this->channelNum = -1;
+               this->handle = NULL;
+               this->context = NULL;
+
+               if (handle == NULL)
+               {
+                       SCARD_DEBUG_ERR("ClientIPC::getInstance() failed");
+
+                       return;
+               }
+
+               this->channelNum = channelNum;
+               this->handle = handle;
+               this->selectResponse = selectResponse;
+               this->context = context;
+       }
+
+       ClientChannel::~ClientChannel()
+       {
+               close(NULL, this);
+       }
+
+       void ClientChannel::closeSync()
+       {
+               Message msg;
+               int rv;
+
+               if (isClosed() == false)
+               {
+                       /* send message to server */
+                       msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
+                       msg.param1 = (int)handle;
+                       msg.error = (unsigned int)context; /* using error to context */
+                       msg.caller = (void *)this;
+                       msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+                       ClientIPC::getInstance().sendMessage(&msg);
+
+                       syncLock();
+                       rv = waitTimedCondition(0);
+                       syncUnlock();
+
+                       if (rv < 0)
+                       {
+                               SCARD_DEBUG_ERR("closeSync failed [%d]", rv);
+                       }
+
+                       channelNum = -1;
+               }
+       }
+
+       int ClientChannel::close(closeCallback callback, void *userParam)
+       {
+               Message msg;
+
+               if (isClosed() == false)
+               {
+                       channelNum = -1;
+
+                       /* send message to server */
+                       msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
+                       msg.param1 = (int)handle;
+                       msg.error = (unsigned int)context; /* using error to context */
+                       msg.caller = (void *)this;
+                       msg.callback = (void *)callback;
+                       msg.userParam = userParam;
+
+                       ClientIPC::getInstance().sendMessage(&msg);
+               }
+
+               return 0;
+       }
+
+       int ClientChannel::transmitSync(ByteArray command, ByteArray &result)
+       {
+               Message msg;
+               int rv;
+
+               /* send message to server */
+               msg.message = Message::MSG_REQUEST_TRANSMIT;
+               msg.param1 = (int)handle;
+               msg.param2 = 0;
+               msg.data = command;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               syncLock();
+               rv = waitTimedCondition(0);
+               syncUnlock();
+
+               if (rv < 0)
+               {
+                       SCARD_DEBUG_ERR("clientIPC is null");
+
+                       return -1;
+               }
+
+               result = response;
+
+               return 0;
+       }
+
+       int ClientChannel::transmit(ByteArray command, transmitCallback callback, void *userParam)
+       {
+               Message msg;
+
+               /* send message to server */
+               msg.message = Message::MSG_REQUEST_TRANSMIT;
+               msg.param1 = (int)handle;
+               msg.param2 = 0;
+               msg.data = command;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)callback;
+               msg.userParam = userParam;
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               return 0;
+       }
+
+       bool ClientChannel::dispatcherCallback(void *message)
+       {
+               Message *msg = (Message *)message;
+               ClientChannel *channel = NULL;
+               bool result = false;
+
+               if (msg == NULL)
+               {
+                       SCARD_DEBUG_ERR("message is null");
+                       return result;
+               }
+
+               channel = (ClientChannel *)msg->caller;
+
+               switch (msg->message)
+               {
+               case Message::MSG_REQUEST_TRANSMIT :
+                       {
+                               /* transmit result */
+                               SCARD_DEBUG("MSG_REQUEST_TRANSMIT");
+
+                               if (msg->callback == (void *)channel) /* synchronized call */
+                               {
+                                       /* sync call */
+                                       channel->syncLock();
+
+                                       /* copy result */
+                                       channel->error = msg->error;
+                                       channel->response = msg->data;
+
+                                       channel->signalCondition();
+                                       channel->syncUnlock();
+                               }
+                               else if (msg->callback != NULL)
+                               {
+                                       transmitCallback cb = (transmitCallback)msg->callback;
+
+                                       /* async call */
+                                       cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
+                               }
+                       }
+                       break;
+
+               case Message::MSG_REQUEST_CLOSE_CHANNEL :
+                       {
+                               SCARD_DEBUG("MSG_REQUEST_CLOSE_CHANNEL");
+
+                               if (msg->callback == (void *)channel) /* synchronized call */
+                               {
+                                       /* sync call */
+                                       channel->syncLock();
+
+                                       channel->error = msg->error;
+
+                                       channel->signalCondition();
+                                       channel->syncUnlock();
+                               }
+                               else if (msg->callback != NULL)
+                               {
+                                       closeCallback cb = (closeCallback)msg->callback;
+
+                                       /* async call */
+                                       cb(msg->error, msg->userParam);
+                               }
+                       }
+                       break;
+
+               default:
+                       SCARD_DEBUG("unknwon message : %s", msg->toString());
+                       break;
+               }
+
+               delete msg;
+
+               return result;
+       }
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define CHANNEL_EXTERN_BEGIN \
+       if (handle != NULL) \
+       { \
+               ClientChannel *channel = (ClientChannel *)handle;
+
+#define CHANNEL_EXTERN_END \
+       } \
+       else \
+       { \
+               SCARD_DEBUG_ERR("Invalid param"); \
+       }
+
+using namespace smartcard_service_api;
+
+EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
+{
+       int result = -1;
+
+       CHANNEL_EXTERN_BEGIN;
+       result = channel->close((closeCallback)callback, userParam);
+       CHANNEL_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API int channel_transmit(channel_h handle, unsigned char *command, unsigned int length, channel_transmit_cb callback, void *userParam)
+{
+       int result = -1;
+
+       CHANNEL_EXTERN_BEGIN;
+       ByteArray temp;
+
+       temp.setBuffer(command, length);
+       result = channel->transmit(temp, (transmitCallback)callback, userParam);
+       CHANNEL_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API bool channel_is_basic_channel(channel_h handle)
+{
+       bool result = false;
+
+       CHANNEL_EXTERN_BEGIN;
+       result = channel->isBasicChannel();
+       CHANNEL_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API bool channel_is_closed(channel_h handle)
+{
+       bool result = false;
+
+       CHANNEL_EXTERN_BEGIN;
+       result = channel->isClosed();
+       CHANNEL_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API unsigned int channel_get_select_response_length(channel_h handle)
+{
+       unsigned int result = 0;
+
+       CHANNEL_EXTERN_BEGIN;
+       result = channel->getSelectResponse().getLength();
+       CHANNEL_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API bool channel_get_select_response(channel_h handle, unsigned char *buffer, unsigned int length)
+{
+       bool result = false;
+
+       if (buffer == NULL || length == 0)
+       {
+               return result;
+       }
+
+       CHANNEL_EXTERN_BEGIN;
+       ByteArray response;
+
+       response = channel->getSelectResponse();
+       if (response.getLength() > 0)
+       {
+               memcpy(buffer, response.getBuffer(), MIN(length, response.getLength()));
+               result = true;
+       }
+       CHANNEL_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API session_h channel_get_session(channel_h handle)
+{
+       session_h session = NULL;
+
+       CHANNEL_EXTERN_BEGIN;
+       session = channel->getSession();
+       CHANNEL_EXTERN_END;
+
+       return session;
+}
+
+EXTERN_API void channel_destroy_instance(channel_h handle)
+{
+       CHANNEL_EXTERN_BEGIN;
+       delete channel;
+       CHANNEL_EXTERN_END;
+}
diff --git a/client/ClientDispatcher.cpp b/client/ClientDispatcher.cpp
new file mode 100644 (file)
index 0000000..84bbf4f
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <glib.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ClientDispatcher.h"
+#include "SEService.h"
+#include "Reader.h"
+#include "Session.h"
+#include "ClientChannel.h"
+
+namespace smartcard_service_api
+{
+       ClientDispatcher::ClientDispatcher()
+       {
+       }
+
+       ClientDispatcher::~ClientDispatcher()
+       {
+               mapSESerivces.clear();
+       }
+
+       ClientDispatcher &ClientDispatcher::getInstance()
+       {
+               static ClientDispatcher clientDispatcher;
+
+               return clientDispatcher;
+       }
+
+       bool ClientDispatcher::addSEService(void *context, SEService *service)
+       {
+               bool result = true;
+               map<void *, SEService *>::iterator item;
+
+               SCARD_BEGIN();
+
+               if ((item = mapSESerivces.find(context)) == mapSESerivces.end())
+               {
+                       mapSESerivces.insert(make_pair(context, service));
+               }
+               else
+               {
+                       SCARD_DEBUG("SEService [%p] exists", context);
+               }
+
+               SCARD_END();
+
+               return result;
+       }
+
+       void ClientDispatcher::removeSEService(void *context)
+       {
+               map<void *, SEService *>::iterator item;
+
+               SCARD_BEGIN();
+
+               if ((item = mapSESerivces.find(context)) != mapSESerivces.end())
+               {
+                       mapSESerivces.erase(item);
+               }
+               else
+               {
+                       SCARD_DEBUG("SEService doesn't exist");
+               }
+
+               SCARD_END();
+       }
+
+       void *ClientDispatcher::dispatcherThreadFunc(DispatcherMsg *msg, void *data)
+       {
+               SCARD_BEGIN();
+
+               if (msg == NULL)
+                       return NULL;
+
+               /* this messages are response from server */
+               switch (msg->message)
+               {
+               /* SE Service requests */
+               case Message::MSG_REQUEST_READERS :
+                       {
+                               DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+                               g_idle_add((GSourceFunc)&SEService::dispatcherCallback, (gpointer)tempMsg);
+                       }
+                       break;
+
+                       /* Reader requests */
+               case Message::MSG_REQUEST_OPEN_SESSION :
+                       {
+                               DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+                               g_idle_add((GSourceFunc)&Reader::dispatcherCallback, (gpointer)tempMsg);
+                       }
+                       break;
+
+               /* Session requests */
+               case Message::MSG_REQUEST_OPEN_CHANNEL :
+               case Message::MSG_REQUEST_GET_ATR :
+               case Message::MSG_REQUEST_CLOSE_SESSION :
+               case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
+                       {
+                               DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+                               g_idle_add((GSourceFunc)&Session::dispatcherCallback, (gpointer)tempMsg);
+                       }
+                       break;
+
+               /* ClientChannel requests */
+               case Message::MSG_REQUEST_TRANSMIT :
+               case Message::MSG_REQUEST_CLOSE_CHANNEL :
+                       {
+                               DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+                               g_idle_add((GSourceFunc)&ClientChannel::dispatcherCallback, (gpointer)tempMsg);
+                       }
+                       break;
+
+               case Message::MSG_NOTIFY_SE_INSERTED :
+               case Message::MSG_NOTIFY_SE_REMOVED :
+                       {
+                               map<void *, SEService *>::iterator item;
+
+                               for (item = mapSESerivces.begin(); item != mapSESerivces.end(); item++)
+                               {
+                                       DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+                                       tempMsg->caller = item->second;
+
+                                       g_idle_add((GSourceFunc)&SEService::dispatcherCallback, (gpointer)tempMsg);
+                               }
+                       }
+                       break;
+
+               case Message::MSG_OPERATION_RELEASE_CLIENT :
+                       {
+                               map<void *, SEService *>::iterator item;
+
+                               for (item = mapSESerivces.begin(); item != mapSESerivces.end(); item++)
+                               {
+                                       DispatcherMsg *tempMsg = new DispatcherMsg(msg);
+
+                                       tempMsg->caller = item->second;
+                                       tempMsg->error = -1;
+
+                                       g_idle_add((GSourceFunc)&SEService::dispatcherCallback, (gpointer)tempMsg);
+                               }
+                       }
+                       break;
+
+               default :
+                       break;
+               }
+
+               SCARD_END();
+
+               return NULL;
+       }
+
+} /* namespace open_mobile_api */
+
diff --git a/client/ClientIPC.cpp b/client/ClientIPC.cpp
new file mode 100644 (file)
index 0000000..314d987
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <sys/socket.h>
+#include <unistd.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ClientIPC.h"
+#include "DispatcherMsg.h"
+
+namespace smartcard_service_api
+{
+       ClientIPC::ClientIPC():IPCHelper()
+       {
+       }
+
+       ClientIPC::~ClientIPC()
+       {
+       }
+
+       ClientIPC &ClientIPC::getInstance()
+       {
+               static ClientIPC clientIPC;
+
+               return clientIPC;
+       }
+
+       int ClientIPC::handleIOErrorCondition(void *channel, GIOCondition condition)
+       {
+               SCARD_BEGIN();
+
+               /* finalize context */
+               if (watchId != 0)
+               {
+                       g_source_remove(watchId);
+                       watchId = 0;
+               }
+
+               if (ioChannel != NULL)
+               {
+                       g_io_channel_unref(ioChannel);
+                       ioChannel = NULL;
+               }
+
+               if (ipcSocket != -1)
+               {
+                       shutdown(ipcSocket, SHUT_RDWR);
+                       close(ipcSocket);
+
+                       ipcSocket = -1;
+               }
+
+               /* push disconnect message */
+               DispatcherMsg *dispMsg = new DispatcherMsg();
+
+               dispMsg->message = Message::MSG_OPERATION_RELEASE_CLIENT;
+               dispMsg->error = -1;
+
+               if (dispatcher != NULL)
+                       dispatcher->pushMessage(dispMsg);
+
+               SCARD_END();
+
+               return FALSE;
+       }
+
+       int ClientIPC::handleInvalidSocketCondition(void *channel, GIOCondition condition)
+       {
+               SCARD_BEGIN();
+
+               /* finalize context */
+
+               SCARD_END();
+
+               return FALSE;
+       }
+
+       int ClientIPC::handleIncomingCondition(void *channel, GIOCondition condition)
+       {
+               int result = FALSE;
+
+               SCARD_BEGIN();
+
+               if (channel == ioChannel)
+               {
+                       Message *msg = NULL;
+
+                       SCARD_DEBUG("message from server to client socket");
+
+                       /* read message */
+                       msg = retrieveMessage();
+                       if (msg != NULL)
+                       {
+                               DispatcherMsg *dispMsg = new DispatcherMsg(msg);
+
+                               /* set peer socket */
+                               dispMsg->setPeerSocket(ipcSocket);
+
+                               /* push to dispatcher */
+                               if (dispatcher != NULL)
+                                       dispatcher->pushMessage(dispMsg);
+
+                               result = TRUE;
+                       }
+                       else
+                       {
+                               /* clear client connection */
+                       }
+
+                       delete msg;
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("Unknown channel event [%p]", channel);
+               }
+
+               SCARD_END();
+
+               return result;
+       }
+
+} /* namespace open_mobile_api */
diff --git a/client/Reader.cpp b/client/Reader.cpp
new file mode 100644 (file)
index 0000000..aca37ed
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Message.h"
+#include "ClientIPC.h"
+#include "Reader.h"
+#include "Session.h"
+#include "SignatureHelper.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+       Reader::Reader(void *context, char *name, void *handle):ReaderHelper()
+       {
+               unsigned int length = 0;
+
+               SCARD_BEGIN();
+
+               this->context = NULL;
+               this->handle = NULL;
+
+               if (context == NULL || name == NULL || strlen(name) == 0 || handle == NULL)
+               {
+                       SCARD_DEBUG_ERR("invalid param");
+
+                       return;
+               }
+
+               this->handle = handle;
+               this->context = context;
+
+               length = strlen(name);
+               length = (length < sizeof(this->name)) ? length : sizeof(this->name);
+               memcpy(this->name, name, length);
+
+               getPackageCert();
+
+               SCARD_END();
+       }
+
+       Reader::~Reader()
+       {
+               closeSessions();
+       }
+
+       void Reader::closeSessions()
+       {
+               size_t i;
+
+               for (i = 0; i < sessions.size(); i++)
+               {
+                       sessions[i]->close(NULL, this);
+               }
+
+               sessions.clear();
+       }
+
+       void Reader::getPackageCert()
+       {
+               packageCert = SignatureHelper::getCertificationHash(getpid());
+       }
+
+       SessionHelper *Reader::openSessionSync()
+       {
+               Message msg;
+               int rv;
+
+               /* request channel handle from server */
+               msg.message = Message::MSG_REQUEST_OPEN_SESSION;
+               msg.param1 = (unsigned int)handle;
+               msg.data = packageCert;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               syncLock();
+               rv = waitTimedCondition(0);
+               syncUnlock();
+
+               if (rv != 0)
+               {
+                       SCARD_DEBUG_ERR("time over");
+
+                       return NULL;
+               }
+
+               return (Session *)openedSession;
+       }
+
+       int Reader::openSession(openSessionCallback callback, void *userData)
+       {
+               Message msg;
+
+               /* request channel handle from server */
+               msg.message = Message::MSG_REQUEST_OPEN_SESSION;
+               msg.param1 = (unsigned int)handle;
+               msg.data = packageCert;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)callback;
+               msg.userParam = userData;
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               return 0;
+       }
+
+       bool Reader::dispatcherCallback(void *message)
+       {
+               Message *msg = (Message *)message;
+               Reader *reader = NULL;
+               bool result = false;
+
+               SCARD_BEGIN();
+
+               if (msg == NULL)
+               {
+                       SCARD_DEBUG_ERR("message is null");
+                       return result;
+               }
+
+               reader = (Reader *)msg->caller;
+
+               switch (msg->message)
+               {
+               case Message::MSG_REQUEST_OPEN_SESSION :
+                       {
+                               Session *session = NULL;
+
+                               SCARD_DEBUG("MSG_REQUEST_OPEN_SESSION");
+
+                               if (msg->param1 != 0)
+                               {
+                                       /* create new instance of channel */
+                                       session = new Session(reader->context, reader, (void *)msg->param1);
+                                       if (session == NULL)
+                                       {
+                                               SCARD_DEBUG_ERR("Session creating instance failed");
+
+                                               return session;
+                                       }
+
+                                       reader->sessions.push_back(session);
+                               }
+
+                               if (msg->callback == (void *)reader) /* synchronized call */
+                               {
+                                       /* sync call */
+                                       reader->syncLock();
+
+                                       /* copy result */
+                                       reader->error = msg->error;
+                                       reader->openedSession = session;
+                                       reader->signalCondition();
+
+                                       reader->syncUnlock();
+                               }
+                               else if (msg->callback != NULL)
+                               {
+                                       openSessionCallback cb = (openSessionCallback)msg->callback;
+
+                                       /* async call */
+                                       cb(session, msg->error, msg->userParam);
+                               }
+                       }
+                       break;
+
+               default:
+                       SCARD_DEBUG("unknown [%s]", msg->toString());
+                       break;
+               }
+
+               delete msg;
+
+               SCARD_END();
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define READER_EXTERN_BEGIN \
+       if (handle != NULL) \
+       { \
+               Reader *reader = (Reader *)handle;
+
+#define READER_EXTERN_END \
+       } \
+       else \
+       { \
+               SCARD_DEBUG_ERR("Invalid param"); \
+       }
+
+using namespace smartcard_service_api;
+
+EXTERN_API const char *reader_get_name(reader_h handle)
+{
+       const char *name = NULL;
+
+       READER_EXTERN_BEGIN;
+       name = reader->getName();
+       READER_EXTERN_END;
+
+       return name;
+}
+
+EXTERN_API se_service_h reader_get_se_service(reader_h handle)
+{
+       se_service_h service = NULL;
+
+       READER_EXTERN_BEGIN;
+       service = (se_service_h)reader->getSEService();
+       READER_EXTERN_END;
+
+       return service;
+}
+
+EXTERN_API bool reader_is_secure_element_present(reader_h handle)
+{
+       bool result = false;
+
+       READER_EXTERN_BEGIN;
+       result = reader->isSecureElementPresent();
+       READER_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData)
+{
+       int result = -1;
+
+       READER_EXTERN_BEGIN;
+       result = reader->openSession((openSessionCallback)callback, userData);
+       READER_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API void reader_close_sessions(reader_h handle)
+{
+       READER_EXTERN_BEGIN;
+       reader->closeSessions();
+       READER_EXTERN_END;
+}
+
+EXTERN_API void reader_destroy_instance(reader_h handle)
+{
+       READER_EXTERN_BEGIN;
+       delete reader;
+       READER_EXTERN_END;
+}
diff --git a/client/SEService.cpp b/client/SEService.cpp
new file mode 100644 (file)
index 0000000..52c6642
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <unistd.h>
+#include <string.h>
+#include <glib.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ClientIPC.h"
+#include "ClientDispatcher.h"
+#include "SEService.h"
+#include "Reader.h"
+#include "Message.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+       SEService::SEService():SEServiceHelper()
+       {
+               pid = -1;
+               this->context = NULL;
+               this->handler = NULL;
+               this->listener = NULL;
+               connected = false;
+
+               pid = getpid();
+       }
+
+       SEService::SEService(void *user_data, serviceConnected handler):SEServiceHelper()
+       {
+               pid = -1;
+               this->context = NULL;
+               this->handler = NULL;
+               this->listener = NULL;
+               connected = false;
+
+               pid = getpid();
+
+               initialize(user_data, handler);
+       }
+
+       SEService::SEService(void *user_data, SEServiceListener *listener):SEServiceHelper()
+       {
+               pid = -1;
+               this->context = NULL;
+               this->handler = NULL;
+               this->listener = NULL;
+               connected = false;
+
+               pid = getpid();
+
+               initialize(user_data, listener);
+       }
+
+       SEService::~SEService()
+       {
+       }
+
+       void SEService::shutdown()
+       {
+               ClientDispatcher::getInstance().removeSEService(context);
+       }
+
+       bool SEService::_initialize()
+       {
+               bool result = false;
+#ifdef SECURITY_SERVER
+               int cookies_size;
+               char *cookies = NULL;
+#endif
+               ClientIPC *clientIPC = NULL;
+               ClientDispatcher *clientDispatcher = NULL;
+
+               SCARD_BEGIN();
+
+               /* initialize client */
+               if (!g_thread_supported())
+               {
+                       g_thread_init(NULL);
+               }
+
+#ifdef SECURITY_SERVER
+               if ((cookies_size = security_server_get_cookie_size()) != 0)
+               {
+                       _net_nfc_client_util_alloc_mem(cookies, cookies_size);
+                       int error = 0;
+                       if ((error = security_server_request_cookie(cookies, cookies_size)) != SECURITY_SERVER_API_SUCCESS)
+                       {
+                               DEBUG_CLIENT_MSG("security server request cookies error = [%d]", error);
+                               _net_nfc_client_util_free_mem(cookies);
+                       }
+                       else
+                       {
+                               char printf_buff[BUFFER_LENGTH_MAX] = { 0, };
+                               int buff_count = BUFFER_LENGTH_MAX;
+                               int i = 0;
+
+                               for (; i < cookies_size; i++)
+                               {
+                                       buff_count -= snprintf((char *)(printf_buff + BUFFER_LENGTH_MAX - buff_count), buff_count, " %02X", cookies[i]);
+                               }
+                               DEBUG_CLIENT_MSG("client send cookies >>>> %s \n", printf_buff);
+
+                               _net_nfc_client_set_cookies(cookies, cookies_size);
+                       }
+               }
+#endif
+
+               clientDispatcher = &ClientDispatcher::getInstance();
+               clientIPC = &ClientIPC::getInstance();
+
+               clientIPC->setDispatcher(clientDispatcher);
+
+               if (clientDispatcher->runDispatcherThread() == false)
+               {
+                       SCARD_DEBUG_ERR("clientDispatcher->runDispatcherThread() failed");
+
+                       return result;
+               }
+
+               if (clientIPC->createConnectSocket() == false)
+               {
+                       SCARD_DEBUG_ERR("clientIPC->createConnectSocket() failed");
+
+                       return result;
+               }
+
+               clientDispatcher->addSEService(context, this);
+
+               {
+                       /* send message to load se */
+                       Message msg;
+
+                       msg.message = Message::MSG_REQUEST_READERS;
+                       msg.error = pid; /* using error to pid */
+                       msg.caller = (void *)this;
+                       msg.userParam = context;
+
+                       result = clientIPC->sendMessage(&msg);
+               }
+
+               SCARD_END();
+
+               return result;
+       }
+
+       bool SEService::initialize(void *context, serviceConnected handler)
+       {
+               if (context == NULL)
+               {
+                       SCARD_DEBUG_ERR("invalid param");
+                       return false;
+               }
+
+               this->context = context;
+               this->handler = handler;
+
+               return _initialize();
+       }
+
+       bool SEService::initialize(void *context, SEServiceListener *listener)
+       {
+               if (context == NULL)
+               {
+                       SCARD_DEBUG_ERR("invalid param");
+                       return false;
+               }
+
+               this->context = context;
+               this->listener = listener;
+
+               return _initialize();
+       }
+
+       bool SEService::parseReaderInformation(unsigned int count, ByteArray data)
+       {
+               size_t i;
+               unsigned int offset = 0;
+               unsigned int len = 0;
+               void *handle = NULL;
+               Reader *reader = NULL;
+               char name[100];
+
+               for (i = 0; i < count && offset < data.getLength(); i++)
+               {
+                       memset(name, 0, sizeof(name));
+
+                       memcpy(&len, data.getBuffer(offset), sizeof(len));
+                       offset += sizeof(len);
+
+                       memcpy(name, data.getBuffer(offset), len);
+                       offset += len;
+
+                       memcpy(&handle, data.getBuffer(offset), sizeof(handle));
+                       offset += sizeof(handle);
+
+                       SCARD_DEBUG("Reader [%d] : name [%s], handle [%p]", i, name, handle);
+
+                       /* add readers */
+                       reader = new Reader(context, name, handle);
+                       if (reader == NULL)
+                       {
+                               SCARD_DEBUG_ERR("alloc failed");
+                               continue;
+                       }
+
+                       readers.push_back(reader);
+               }
+
+               return true;
+       }
+
+       bool SEService::dispatcherCallback(void *message)
+       {
+               Message *msg = (Message *)message;
+               SEService *service = NULL;
+               bool result = false;
+
+               SCARD_BEGIN();
+
+               if (msg == NULL)
+               {
+                       SCARD_DEBUG_ERR("message is null");
+                       return result;
+               }
+
+               service = (SEService *)msg->caller;
+
+               switch (msg->message)
+               {
+               case Message::MSG_REQUEST_READERS :
+                       SCARD_DEBUG("[MSG_REQUEST_READERS]");
+
+                       /* parse message data */
+                       service->parseReaderInformation(msg->param1, msg->data);
+
+                       /* call callback function */
+                       if (service->listener != NULL)
+                       {
+                               service->listener->serviceConnected(service, service->context);
+                       }
+                       else if (service->handler != NULL)
+                       {
+                               service->handler(service, service->context);
+                       }
+                       break;
+
+               case Message::MSG_NOTIFY_SE_INSERTED :
+                       SCARD_DEBUG("[MSG_NOTIFY_SE_INSERTED]");
+
+                       if (service->listener != NULL)
+                       {
+                               service->listener->eventHandler(service, (char *)msg->data.getBuffer(), 1, service->context);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("service->listener is null");
+                       }
+                       break;
+
+               case Message::MSG_NOTIFY_SE_REMOVED :
+                       SCARD_DEBUG("[MSG_NOTIFY_SE_REMOVED]");
+
+                       if (service->listener != NULL)
+                       {
+                               service->listener->eventHandler(service, (char *)msg->data.getBuffer(), 2, service->context);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("service->listener is null");
+                       }
+                       break;
+
+               case Message::MSG_OPERATION_RELEASE_CLIENT :
+                       SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
+
+                       if (service->listener != NULL)
+                       {
+                               service->listener->errorHandler(service, msg->error, service->context);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("service->listener is null");
+                       }
+                       break;
+
+               default:
+                       SCARD_DEBUG("unknown message [%s]", msg->toString());
+                       break;
+               }
+
+               delete msg;
+
+               SCARD_END();
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define SE_SERVICE_EXTERN_BEGIN \
+       if (handle != NULL) \
+       { \
+               SEService *service = (SEService *)handle;
+
+#define SE_SERVICE_EXTERN_END \
+       } \
+       else \
+       { \
+               SCARD_DEBUG_ERR("Invalid param"); \
+       }
+
+using namespace smartcard_service_api;
+
+EXTERN_API se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback)
+{
+       SEService *service = new SEService(user_data, (serviceConnected)callback);
+
+       return (se_service_h)service;
+}
+
+EXTERN_API se_service_h se_service_create_instance_with_event_callback(void *user_data, se_service_connected_cb connected, se_service_event_cb event, se_sesrvice_error_cb error)
+{
+       SEService *service = new SEService(user_data, (serviceConnected)connected);
+
+       return (se_service_h)service;
+}
+
+EXTERN_API int se_service_get_readers_count(se_service_h handle)
+{
+       int count = 0;
+
+       SE_SERVICE_EXTERN_BEGIN;
+       vector<ReaderHelper *> temp_readers;
+
+       temp_readers = service->getReaders();
+       count = temp_readers.size();
+       SE_SERVICE_EXTERN_END;
+
+       return count;
+}
+
+EXTERN_API bool se_service_get_readers(se_service_h handle, reader_h *readers, int count)
+{
+       bool result = false;
+
+       SE_SERVICE_EXTERN_BEGIN;
+       vector<ReaderHelper *> temp_readers;
+       size_t i;
+
+       temp_readers = service->getReaders();
+
+       for (i = 0; i < temp_readers.size() && i < (size_t)count; i++)
+       {
+               readers[i] = (reader_h)temp_readers[i];
+       }
+       SE_SERVICE_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API bool se_service_is_connected(se_service_h handle)
+{
+       bool result = false;
+
+       SE_SERVICE_EXTERN_BEGIN;
+       result = service->isConnected();
+       SE_SERVICE_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API void se_service_shutdown(se_service_h handle)
+{
+       SE_SERVICE_EXTERN_BEGIN;
+       service->shutdown();
+       SE_SERVICE_EXTERN_END;
+}
+
+EXTERN_API void se_service_destroy_instance(se_service_h handle)
+{
+       SE_SERVICE_EXTERN_BEGIN;
+       delete service;
+       SE_SERVICE_EXTERN_END;
+}
diff --git a/client/Session.cpp b/client/Session.cpp
new file mode 100644 (file)
index 0000000..79531b1
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <unistd.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Session.h"
+#include "Reader.h"
+#include "ClientChannel.h"
+#include "ClientIPC.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+       Session::Session(void *context, Reader *reader, void *handle):SessionHelper(reader)
+       {
+               this->context = NULL;
+
+               if (context == NULL || handle == NULL)
+               {
+                       SCARD_DEBUG_ERR("handle is null");
+
+                       return;
+               }
+
+               this->context = context;
+               this->handle = handle;
+               closed = false;
+       }
+
+       Session::~Session()
+       {
+               close(NULL, this);
+       }
+
+       void Session::closeChannels()
+       {
+               size_t i;
+
+               for (i = 0; i < channels.size(); i++)
+               {
+                       channels[i]->close(NULL, this);
+               }
+
+               channels.clear();
+       }
+
+       ByteArray Session::getATRSync()
+       {
+               Message msg;
+               int rv;
+
+               /* request channel handle from server */
+               msg.message = Message::MSG_REQUEST_GET_ATR;
+               msg.param1 = (unsigned int)handle;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               syncLock();
+               rv = waitTimedCondition(0);
+               syncUnlock();
+
+               if (rv != 0)
+               {
+                       SCARD_DEBUG_ERR("time over");
+
+                       atr.releaseBuffer();
+               }
+
+               return atr;
+       }
+
+       int Session::getATR(getATRCallback callback, void *userData)
+       {
+               Message msg;
+
+               /* request channel handle from server */
+               msg.message = Message::MSG_REQUEST_GET_ATR;
+               msg.param1 = (unsigned int)handle;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)callback;
+               msg.userParam = userData;
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               return 0;
+       }
+
+       void Session::closeSync()
+       {
+               Message msg;
+               int rv;
+
+               if (isClosed() == false)
+               {
+                       closed = true;
+                       closeChannels();
+
+                       /* request channel handle from server */
+                       msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
+                       msg.param1 = (unsigned int)handle;
+                       msg.error = (unsigned int)context; /* using error to context */
+                       msg.caller = (void *)this;
+                       msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+                       ClientIPC::getInstance().sendMessage(&msg);
+
+                       syncLock();
+                       rv = waitTimedCondition(0);
+                       syncUnlock();
+
+                       if (rv != 0)
+                       {
+                               SCARD_DEBUG_ERR("time over");
+                       }
+               }
+       }
+
+       int Session::close(closeSessionCallback callback, void *userData)
+       {
+               Message msg;
+
+               if (isClosed() == false)
+               {
+                       closed = true;
+                       closeChannels();
+
+                       /* request channel handle from server */
+                       msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
+                       msg.param1 = (unsigned int)handle;
+                       msg.error = (unsigned int)context; /* using error to context */
+                       msg.caller = (void *)this;
+                       msg.callback = (void *)callback;
+                       msg.userParam = userData;
+
+                       ClientIPC::getInstance().sendMessage(&msg);
+               }
+
+               return 0;
+       }
+
+       unsigned int Session::getChannelCount(getChannelCountCallback callback, void *userData)
+       {
+               Message msg;
+
+               msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
+               msg.param1 = (unsigned int)handle;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)callback;
+               msg.userParam = userData;
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               return 0;
+       }
+
+       unsigned int Session::getChannelCountSync()
+       {
+               Message msg;
+               int rv;
+
+               /* request channel handle from server */
+               msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
+               msg.param1 = (unsigned int)handle;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               syncLock();
+               rv = waitTimedCondition(0);
+               syncUnlock();
+
+               if (rv != 0)
+               {
+                       SCARD_DEBUG_ERR("time over");
+
+                       return -1;
+               }
+
+               return channelCount;
+       }
+
+       Channel *Session::openChannelSync(int id, ByteArray aid)
+       {
+               Message msg;
+               int rv;
+
+               /* request channel handle from server */
+               msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
+               msg.param1 = id;
+               msg.param2 = (unsigned int)handle;
+               msg.data = aid;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               syncLock();
+               rv = waitTimedCondition(0);
+               syncUnlock();
+
+               if (rv != 0)
+               {
+                       SCARD_DEBUG_ERR("time over");
+
+                       return NULL;
+               }
+
+               return (Channel *)openedChannel;
+       }
+
+       int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
+       {
+               Message msg;
+
+               /* request channel handle from server */
+               msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
+               msg.param1 = id;
+               msg.param2 = (unsigned int)handle;
+               msg.data = aid;
+               msg.error = (unsigned int)context; /* using error to context */
+               msg.caller = (void *)this;
+               msg.callback = (void *)callback;
+               msg.userParam = userData;
+
+               ClientIPC::getInstance().sendMessage(&msg);
+
+               return 0;
+       }
+
+       Channel *Session::openBasicChannelSync(ByteArray aid)
+       {
+               return openChannelSync(0, aid);
+       }
+
+       Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
+       {
+               return openBasicChannelSync(ByteArray(aid, length));
+       }
+
+       int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
+       {
+               return openChannel(0, aid, callback, userData);
+       }
+
+       int Session::openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
+       {
+               return openBasicChannel(ByteArray(aid, length), callback, userData);
+       }
+
+       Channel *Session::openLogicalChannelSync(ByteArray aid)
+       {
+               return openChannelSync(1, aid);
+       }
+
+       Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
+       {
+               return openLogicalChannelSync(ByteArray(aid, length));
+       }
+
+       int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
+       {
+               return openChannel(1, aid, callback, userData);
+       }
+
+       int Session::openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
+       {
+               return openLogicalChannel(ByteArray(aid, length), callback, userData);
+       }
+
+       bool Session::dispatcherCallback(void *message)
+       {
+               Message *msg = (Message *)message;
+               Session *session = NULL;
+               bool result = false;
+
+               if (msg == NULL)
+               {
+                       SCARD_DEBUG_ERR("message is null");
+                       return result;
+               }
+
+               session = (Session *)msg->caller;
+
+               switch (msg->message)
+               {
+               case Message::MSG_REQUEST_OPEN_CHANNEL :
+                       {
+                               Channel *channel = NULL;
+
+                               SCARD_DEBUG("MSG_REQUEST_OPEN_CHANNEL");
+
+                               if (msg->param1 != 0)
+                               {
+                                       /* create new instance of channel */
+                                       channel = new ClientChannel(session->context, session, msg->param2, msg->data, (void *)msg->param1);
+                                       if (channel != NULL)
+                                       {
+                                               session->channels.push_back(channel);
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("alloc failed");
+
+                                               msg->error = -1;
+                                       }
+                               }
+
+                               if (msg->callback == (void *)session) /* synchronized call */
+                               {
+                                       /* sync call */
+                                       session->syncLock();
+
+                                       /* copy result */
+                                       session->error = msg->error;
+                                       session->openedChannel = channel;
+
+                                       session->signalCondition();
+                                       session->syncUnlock();
+                               }
+                               else if (msg->callback != NULL)
+                               {
+                                       openChannelCallback cb = (openChannelCallback)msg->callback;
+
+                                       /* async call */
+                                       cb(channel, msg->error, msg->userParam);
+                               }
+                       }
+                       break;
+
+               case Message::MSG_REQUEST_GET_ATR :
+                       {
+                               SCARD_DEBUG("MSG_REQUEST_GET_ATR");
+
+                               if (msg->callback == (void *)session) /* synchronized call */
+                               {
+                                       /* sync call */
+                                       session->syncLock();
+
+                                       session->error = msg->error;
+                                       session->atr = msg->data;
+
+                                       session->signalCondition();
+                                       session->syncUnlock();
+                               }
+                               else if (msg->callback != NULL)
+                               {
+                                       getATRCallback cb = (getATRCallback)msg->callback;
+
+                                       /* async call */
+                                       cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
+                               }
+                       }
+                       break;
+
+               case Message::MSG_REQUEST_CLOSE_SESSION :
+                       {
+                               SCARD_DEBUG("MSG_REQUEST_CLOSE_SESSION");
+
+                               if (msg->callback == (void *)session) /* synchronized call */
+                               {
+                                       /* sync call */
+                                       session->syncLock();
+
+                                       session->error = msg->error;
+
+                                       session->signalCondition();
+                                       session->syncUnlock();
+                               }
+                               else if (msg->callback != NULL)
+                               {
+                                       closeSessionCallback cb = (closeSessionCallback)msg->callback;
+
+                                       /* async call */
+                                       cb(msg->error, msg->userParam);
+                               }
+                       }
+                       break;
+
+               case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
+                       {
+                               SCARD_DEBUG("MSG_REQUEST_GET_CHANNEL_COUNT");
+
+                               if (msg->callback == (void *)session) /* synchronized call */
+                               {
+                                       /* sync call */
+                                       session->syncLock();
+
+                                       session->error = msg->error;
+                                       session->channelCount = msg->param1;
+
+                                       session->signalCondition();
+                                       session->syncUnlock();
+                               }
+                               else if (msg->callback != NULL)
+                               {
+                                       getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
+
+                                       /* async call */
+                                       cb(msg->param1, msg->error, msg->userParam);
+                               }
+                       }
+                       break;
+
+               default:
+                       SCARD_DEBUG("unknown message : %s", msg->toString());
+                       break;
+               }
+
+               delete msg;
+
+               return result;
+       }
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define SESSION_EXTERN_BEGIN \
+       if (handle != NULL) \
+       { \
+               Session *session = (Session *)handle;
+
+#define SESSION_EXTERN_END \
+       } \
+       else \
+       { \
+               SCARD_DEBUG_ERR("Invalid param"); \
+       }
+
+using namespace smartcard_service_api;
+
+EXTERN_API reader_h session_get_reader(session_h handle)
+{
+       reader_h reader = NULL;
+
+       SESSION_EXTERN_BEGIN;
+       reader = session->getReader();
+       SESSION_EXTERN_END;
+
+       return reader;
+}
+
+EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
+{
+       int result = -1;
+
+       SESSION_EXTERN_BEGIN;
+       result = session->getATR((getATRCallback)callback, userData);
+       SESSION_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
+{
+       int result = -1;
+
+       SESSION_EXTERN_BEGIN;
+       result = session->close((closeSessionCallback)callback, userData);
+       SESSION_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API bool session_is_closed(session_h handle)
+{
+       bool result = false;
+
+       SESSION_EXTERN_BEGIN;
+       result = session->isClosed();
+       SESSION_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API void session_close_channels(session_h handle)
+{
+       SESSION_EXTERN_BEGIN;
+       session->closeChannels();
+       SESSION_EXTERN_END;
+}
+
+EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
+{
+       int result = -1;
+
+       SESSION_EXTERN_BEGIN;
+       result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
+       SESSION_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
+{
+       int result = -1;
+
+       SESSION_EXTERN_BEGIN;
+       result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
+       SESSION_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API unsigned int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
+{
+       unsigned int result = 0;
+
+       SESSION_EXTERN_BEGIN;
+       result = session->getChannelCount((getChannelCountCallback)callback, userData);
+       SESSION_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API void session_destroy_instance(session_h handle)
+{
+       SESSION_EXTERN_BEGIN;
+       delete session;
+       SESSION_EXTERN_END;
+}
diff --git a/client/include/ClientChannel.h b/client/include/ClientChannel.h
new file mode 100644 (file)
index 0000000..902265c
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef CLIENTCHANNEL_H_
+#define CLIENTCHANNEL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "Channel.h"
+#include "Session.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+       class ClientChannel: public Channel
+       {
+       private:
+               void *context;
+               void *handle;
+               /* temporary data for sync function */
+               int error;
+               ByteArray response;
+
+               ClientChannel(void *context, Session *session, int channelNum, ByteArray selectResponse, void *handle);
+
+               static bool dispatcherCallback(void *message);
+
+               void closeSync();
+               int transmitSync(ByteArray command, ByteArray &result);
+
+       public:
+               ~ClientChannel();
+
+               int close(closeCallback callback, void *userParam);
+               int transmit(ByteArray command, transmitCallback callback, void *userParam);
+
+               friend class ClientDispatcher;
+               friend class Session;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+int channel_close(channel_h handle, channel_close_cb callback, void *userParam);
+int channel_transmit(channel_h handle, unsigned char *command, unsigned int length, channel_transmit_cb callback, void *userParam);
+bool channel_is_basic_channel(channel_h handle);
+bool channel_is_closed(channel_h handle);
+
+unsigned int channel_get_select_response_length(channel_h handle);
+bool channel_get_select_response(channel_h handle, unsigned char *buffer, unsigned int length);
+session_h channel_get_session(channel_h handle);
+void channel_destroy_instance(channel_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CLIENTCHANNEL_H_ */
diff --git a/client/include/ClientDispatcher.h b/client/include/ClientDispatcher.h
new file mode 100644 (file)
index 0000000..7dc42c5
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef CLIENTDISPATCHER_H_
+#define CLIENTDISPATCHER_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "DispatcherHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class SEService;
+
+       class ClientDispatcher: public DispatcherHelper
+       {
+       private:
+               map<void *, SEService *> mapSESerivces;
+
+               ClientDispatcher();
+               ~ClientDispatcher();
+
+               void *dispatcherThreadFunc(DispatcherMsg *msg, void *data);
+
+       public:
+               static ClientDispatcher &getInstance();
+
+               bool addSEService(void *context, SEService *service);
+               void removeSEService(void *context);
+       };
+
+} /* namespace open_mobile_api */
+#endif /* CLIENTDISPATCHER_H_ */
diff --git a/client/include/ClientIPC.h b/client/include/ClientIPC.h
new file mode 100644 (file)
index 0000000..5635897
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef CLIENTIPC_H_
+#define CLIENTIPC_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "IPCHelper.h"
+#include "SEServiceListener.h"
+
+namespace smartcard_service_api
+{
+       class ClientIPC: public IPCHelper
+       {
+       private:
+               ClientIPC();
+               ~ClientIPC();
+
+               int handleIOErrorCondition(void *channel, GIOCondition condition);
+               int handleInvalidSocketCondition(void *channel, GIOCondition condition);
+               int handleIncomingCondition(void *channel, GIOCondition condition);
+
+       public:
+               static ClientIPC &getInstance();
+       };
+
+} /* namespace open_mobile_api */
+#endif /* CLIENTIPC_H_ */
diff --git a/client/include/Reader.h b/client/include/Reader.h
new file mode 100644 (file)
index 0000000..fc7306e
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef READER_H_
+#define READER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "ReaderHelper.h"
+#include "Session.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+       class Reader: public ReaderHelper
+       {
+       private:
+               void *context;
+               void *handle;
+               ByteArray packageCert;
+               /* temporary data for sync function */
+               int error;
+               Session *openedSession;
+
+               Reader(void *context, char *name, void *handle);
+
+               SessionHelper *openSessionSync();
+               static bool dispatcherCallback(void *message);
+               void getPackageCert();
+
+       public:
+               ~Reader();
+
+               int openSession(openSessionCallback callback, void *userData);
+               void closeSessions();
+
+               friend class SEService;
+               friend class ClientDispatcher;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+const char *reader_get_name(reader_h handle);
+se_service_h reader_get_se_service(reader_h handle);
+bool reader_is_secure_element_present(reader_h handle);
+int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData);
+void reader_close_sessions(reader_h handle);
+void reader_destroy_instance(reader_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* READER_H_ */
diff --git a/client/include/SEService.h b/client/include/SEService.h
new file mode 100644 (file)
index 0000000..2a6989e
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SESERVICE_H_
+#define SESERVICE_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "SEServiceListener.h"
+#include "SEServiceHelper.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+using namespace std;
+
+namespace smartcard_service_api
+{
+       typedef void (*serviceConnected)(SEServiceHelper *service, void *context);
+
+       class SEService: public SEServiceHelper
+       {
+       private:
+               int pid;
+               void *context;
+               serviceConnected handler;
+               SEServiceListener *listener;
+
+               SEService();
+
+               static bool dispatcherCallback(void *message);
+               bool parseReaderInformation(unsigned int count, ByteArray data);
+
+               bool _initialize();
+               bool initialize(void *context, serviceConnected handler);
+               bool initialize(void *context, SEServiceListener *listener);
+               SEService *initializeSync(void *context, serviceConnected handler);
+
+       public:
+               SEService(void *user_data, serviceConnected handler);
+               SEService(void *user_data, SEServiceListener *listener);
+               ~SEService();
+
+               void shutdown();
+
+               friend class ClientDispatcher;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+se_service_h se_service_create_instance(void *user_data, se_service_connected_cb callback);
+se_service_h se_service_create_instance_with_event_callback(void *user_data, se_service_connected_cb connected, se_service_event_cb event, se_sesrvice_error_cb error);
+int se_service_get_readers_count(se_service_h handle);
+bool se_service_get_readers(se_service_h handle, reader_h *readers, int count);
+bool se_service_is_connected(se_service_h handle);
+void se_service_shutdown(se_service_h handle);
+void se_service_destroy_instance(se_service_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SESERVICE_H_ */
diff --git a/client/include/SEServiceListener.h b/client/include/SEServiceListener.h
new file mode 100644 (file)
index 0000000..3f40165
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef SESERVICELISTENER_H_
+#define SESERVICELISTENER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+
+namespace smartcard_service_api
+{
+       class SEServiceHelper;
+
+       class SEServiceListener
+       {
+       public:
+               virtual void serviceConnected(SEServiceHelper *service, void *context) = 0;
+               virtual void eventHandler(SEServiceHelper *service, char *seName, int event, void *context) = 0;
+               virtual void errorHandler(SEServiceHelper *service, int error, void *context) = 0;
+       };
+
+} /* namespace open_mobile_api */
+#endif /* SESERVICELISTENER_H_ */
diff --git a/client/include/Session.h b/client/include/Session.h
new file mode 100644 (file)
index 0000000..9ec499e
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SESSION_H_
+#define SESSION_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "SessionHelper.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+       class Reader;
+
+       class Session: public SessionHelper
+       {
+       private:
+               void *context;
+               void *handle;
+               /* temporary data for sync function */
+               int error;
+               Channel *openedChannel;
+               unsigned int channelCount;
+
+               Session(void *context, Reader *reader, void *handle);
+
+               int openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData);
+               static bool dispatcherCallback(void *message);
+
+               Channel *openChannelSync(int id, ByteArray aid);
+
+               ByteArray getATRSync();
+               void closeSync();
+
+               Channel *openBasicChannelSync(ByteArray aid);
+               Channel *openBasicChannelSync(unsigned char *aid, unsigned int length);
+               Channel *openLogicalChannelSync(ByteArray aid);
+               Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length);
+               unsigned int getChannelCountSync();
+
+       public:
+               ~Session();
+
+               int getATR(getATRCallback callback, void *userData);
+               int close(closeSessionCallback callback, void *userData);
+
+               void closeChannels();
+
+               int openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData);
+               int openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
+               int openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData);
+               int openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
+               unsigned int getChannelCount(getChannelCountCallback callback, void * userData);
+
+               friend class ClientDispatcher;
+               friend class Reader;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+reader_h session_get_reader(session_h handle);
+int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData);
+int session_close(session_h handle, session_close_session_cb callback, void *userData);
+bool session_is_closed(session_h handle);
+void session_close_channels(session_h handle);
+
+int session_open_basic_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData);
+int session_open_logical_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData);
+unsigned int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData);
+void session_destroy_instance(session_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SESSION_H_ */
diff --git a/client/smartcard-service.pc b/client/smartcard-service.pc
new file mode 100644 (file)
index 0000000..a58f2e7
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=${prefix}/bin
+includedir=${prefix}/include
+libdir=${prefix}/lib
+
+Name: smartcard-service
+Description: Make flags of Common library of Smartcard service
+Version: 1.0
+Requires: 
+Libs: -L${libdir} -lsmartcard-service
+Cflags: -I${includedir}/smartcard-service
\ No newline at end of file
diff --git a/common/APDUHelper.cpp b/common/APDUHelper.cpp
new file mode 100644 (file)
index 0000000..8dc2b41
--- /dev/null
@@ -0,0 +1,519 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "APDUHelper.h"
+
+namespace smartcard_service_api
+{
+       /* ResponseHelper class */
+       ResponseHelper::ResponseHelper()
+       {
+       }
+
+       ResponseHelper::ResponseHelper(const ByteArray &response)
+       {
+               setResponse(response);
+       }
+
+       ResponseHelper::~ResponseHelper()
+       {
+       }
+
+       bool ResponseHelper::setResponse(const ByteArray &response)
+       {
+               bool result = false;
+               status = 0;
+               dataField.releaseBuffer();
+
+               this->response = response;
+
+               if (response.getLength() >= 2)
+               {
+                       sw[0] = response.getReverseAt(1);
+                       sw[1] = response.getReverseAt(0);
+
+                       status = parseStatusWord(sw);
+
+                       if (response.getLength() > 2)
+                       {
+                               dataField.setBuffer(response.getBuffer(), response.getLength() - 2);
+                       }
+
+                       result = true;
+               }
+
+               return result;
+       }
+
+       int ResponseHelper::parseStatusWord(unsigned char *sw)
+       {
+               int result = 0;
+
+               switch (sw[0])
+               {
+               /* Normal processing */
+               case (unsigned char)0x90 : /* SW2:00, No further qulification */
+                       break;
+
+               case (unsigned char)0x91 : /* extra information */
+                       break;
+
+               case (unsigned char)0x61 : /* SW2 encodes the number of data bytes still available */
+                       break;
+
+               /* Warning processing */
+               case (unsigned char)0x62 : /* State of non-volatile memory is unchanged (further qualification in SW2) */
+                       break;
+
+               case (unsigned char)0x63 : /* State of non-volatile memory has changed (further qualification in SW2) */
+                       break;
+
+               /* Execution error */
+               case (unsigned char)0x64 : /* State of non-volatile memory is unchanged (further qualification in SW2) */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x65 : /* State of non-volatile memory has changed (further qualification in SW2) */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x66 : /* Security-related issues */
+                       result = -1;
+                       break;
+
+               /* Checking error */
+               case (unsigned char)0x67 : /* SW2:00, Wrong length; no further indication */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x68 : /* Functions in CLA not supported (further qualification in SW2) */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x69 : /* Command not allowed (further qualification in SW2) */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x6A : /* Wrong parameters P1-P2 (further qualification in SW2) */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x6B : /* SW2:00, Wrong parameters P1-P2 */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x6C : /* Wrong Le field; SW2 encodes the exact number of available data bytes */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x6D : /* SW2:00, Instruction code not supported or invalid */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x6E : /* SW2:00, Class not supported */
+                       result = -1;
+                       break;
+
+               case (unsigned char)0x6F : /* SW2:00, No precise diagnosis */
+                       result = -1;
+                       break;
+
+               default :
+                       result = -1;
+                       break;
+               }
+
+               return result;
+       }
+
+       int ResponseHelper::getStatus()
+       {
+               return status;
+       }
+
+       int ResponseHelper::getStatus(const ByteArray &response)
+       {
+               int status = 0;
+
+               if (response.getLength() >= 2)
+               {
+                       status = ResponseHelper::parseStatusWord(response.getBuffer((response.getLength() - 2)));
+               }
+
+               return status;
+       }
+
+       ByteArray ResponseHelper::getDataField()
+       {
+               return dataField;
+       }
+
+       ByteArray ResponseHelper::getDataField(const ByteArray &response)
+       {
+               ByteArray result;
+
+               if (response.getLength() > 2)
+               {
+                       result.setBuffer(response.getBuffer(), response.getLength() - 2);
+               }
+
+               return result;
+       }
+
+       /* APDUCommand class */
+       APDUCommand::APDUCommand()
+       {
+               maxResponseSize = 0;
+               isExtendedLength = false;
+               memset(&header, 0, sizeof(header));
+       }
+
+       APDUCommand::~APDUCommand()
+       {
+       }
+
+       bool APDUCommand::setCommand(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, ByteArray commandData, unsigned int maxResponseSize)
+       {
+               setCLA(cla);
+               setINS(ins);
+               setP1(p1);
+               setP2(p2);
+               setCommandData(commandData);
+               setMaxResponseSize(maxResponseSize);
+
+               return true;
+       }
+
+       bool APDUCommand::setCommand(const ByteArray &command)
+       {
+               bool result = false;
+               uint32_t offset = 0;
+               uint32_t lengthSize = 1;
+
+               if (command.getLength() < sizeof(header))
+               {
+                       return false;
+               }
+
+               memcpy(&header, command.getBuffer(offset), sizeof(header));
+               offset += sizeof(header);
+
+               if (isExtendedLength)
+               {
+                       lengthSize = 2;
+               }
+
+               if (command.getLength() - offset > lengthSize)
+               {
+                       unsigned int length = 0;
+
+                       /* data exist */
+                       if (isExtendedLength)
+                       {
+                               /* TODO */
+                               offset += 2;
+                       }
+                       else
+                       {
+                               length = command.getAt(offset);
+                               offset += 1;
+                       }
+
+                       setCommandData(ByteArray(command.getBuffer(offset), length));
+                       offset += length;
+               }
+
+               if (command.getLength() - offset == lengthSize)
+               {
+                       if (isExtendedLength)
+                       {
+                               /* TODO */
+                               offset += 2;
+                       }
+                       else
+                       {
+                               setMaxResponseSize(command.getAt(offset));
+                               offset += 1;
+                       }
+               }
+
+               if (command.getLength() == offset)
+               {
+                       result = true;
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("command stream is not correct, command.getLength() [%d], offset [%d]", command.getLength(), offset);
+               }
+
+               return result;
+       }
+
+       bool APDUCommand::setChannel(int type, int channelNum)
+       {
+               bool result = false;
+
+               if (channelNum != 0)
+               {
+                       switch (type)
+                       {
+                       case 0 :
+                               if (channelNum > 0 && channelNum < 4)
+                               {
+                                       unsigned char temp;
+
+                                       temp = getCLA();
+                                       temp &= ~0x03;
+                                       temp |= (channelNum & 0x03);
+                                       setCLA(temp);
+
+                                       result = true;
+                               }
+                               break;
+
+                       default :
+                               break;
+                       }
+               }
+
+               return result;
+       }
+
+       void APDUCommand::setCLA(unsigned char cla)
+       {
+               /* check criteria */
+               if (cla == 0xFF)
+                       return;
+
+               header.cla = cla;
+       }
+
+       unsigned char APDUCommand::getCLA()
+       {
+               return header.cla;
+       }
+
+       void APDUCommand::setINS(unsigned char ins)
+       {
+               /* check criteria */
+               if ((ins & 0xF0) == 0x60 || (ins & 0xF0) == 0x90)
+                       return;
+
+               header.ins = ins;
+       }
+
+       unsigned char APDUCommand::getINS()
+       {
+               return header.ins;
+       }
+
+       void APDUCommand::setP1(unsigned char p1)
+       {
+               /* check criteria */
+               header.param[0] = p1;
+       }
+
+       unsigned char APDUCommand::getP1()
+       {
+               return header.param[0];
+       }
+
+       void APDUCommand::setP2(unsigned char p2)
+       {
+               /* check criteria */
+               header.param[1] = p2;
+       }
+
+       unsigned char APDUCommand::getP2()
+       {
+               return header.param[1];
+       }
+
+       void APDUCommand::setCommandData(const ByteArray &data)
+       {
+               commandData = data;
+       }
+
+       ByteArray APDUCommand::getCommandData()
+       {
+               return commandData;
+       }
+
+       void APDUCommand::setMaxResponseSize(unsigned int maxResponseSize)
+       {
+               this->maxResponseSize = maxResponseSize;
+       }
+
+       unsigned int APDUCommand::setMaxResponseSize()
+       {
+               return maxResponseSize;
+       }
+
+       bool APDUCommand::getBuffer(ByteArray &array)
+       {
+               unsigned char *temp_buffer = NULL;
+               unsigned int temp_len = 0;
+               unsigned char lc[3] = { 0, };
+               unsigned int lc_len = 0;
+               unsigned char le[3] = { 0, };
+               unsigned int le_len = 0;
+               unsigned int offset = 0;
+
+               /* */
+               temp_len += sizeof(header);
+
+               /* calculate lc length */
+               if (commandData.getLength() > 0)
+               {
+                       if (isExtendedLength/*commandData.getLength() > 255*/)
+                       {
+                               lc[1] = (commandData.getLength() >> 8) & 0x000000FF;
+                               lc[2] = commandData.getLength() & 0x000000FF;
+
+                               lc_len = 3;
+                       }
+                       else
+                       {
+                               lc[0] = commandData.getLength() & 0x000000FF;
+
+                               lc_len = 1;
+                       }
+               }
+
+               temp_len += lc_len;
+
+               /* add command data length */
+               temp_len += commandData.getLength();
+
+               /* calculate le length */
+               if (maxResponseSize > 0)
+               {
+                       if (isExtendedLength/*commandData.getLength() > 255*/)
+                       {
+                               if (maxResponseSize < 65536)
+                               {
+                                       le[1] = (maxResponseSize >> 8) & 0x000000FF;
+                                       le[2] = maxResponseSize & 0x000000FF;
+
+                                       le_len = 3;
+                               }
+                               else if (maxResponseSize == 65536)
+                               {
+                                       le_len = 2;
+                               }
+                       }
+                       else
+                       {
+                               if (maxResponseSize != 256)
+                                       le[0] = maxResponseSize & 0x000000FF;
+
+                               le_len = 1;
+                       }
+               }
+
+               temp_len += le_len;
+
+               temp_buffer = new unsigned char[temp_len];
+               if (temp_buffer == NULL)
+                       return false;
+
+               /* fill data */
+               offset = 0;
+
+               memcpy(temp_buffer + offset, &header, sizeof(header));
+               offset += sizeof(header);
+
+               if (commandData.getLength() > 0)
+               {
+                       memcpy(temp_buffer + offset, &lc, lc_len);
+                       offset += lc_len;
+
+                       memcpy(temp_buffer + offset, commandData.getBuffer(), commandData.getLength());
+                       offset += commandData.getLength();
+               }
+
+               if (maxResponseSize > 0)
+               {
+                       memcpy(temp_buffer + offset, &le, le_len);
+                       offset += le_len;
+               }
+
+               array.setBuffer(temp_buffer, temp_len);
+               delete []temp_buffer;
+
+               return true;
+       }
+
+       /* APDUHelper class */
+       ByteArray APDUHelper::generateAPDU(int command, int channel, ByteArray data)
+       {
+               ByteArray result;
+               APDUCommand apdu;
+
+               switch (command)
+               {
+               case COMMAND_OPEN_LOGICAL_CHANNEL :
+                       apdu.setCommand(0, APDUCommand::INS_MANAGE_CHANNEL, 0, 0, ByteArray::EMPTY, 1);
+                       apdu.getBuffer(result);
+                       break;
+
+               case COMMAND_CLOSE_LOGICAL_CHANNEL :
+                       apdu.setCommand(0, APDUCommand::INS_MANAGE_CHANNEL, 0x80, channel, ByteArray::EMPTY, 0);
+                       apdu.getBuffer(result);
+                       break;
+
+               case COMMAND_SELECT_BY_ID :
+                       apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_ID, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+                       apdu.getBuffer(result);
+                       break;
+
+               case COMMAND_SELECT_PARENT_DF :
+                       apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_PARENT_DF, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+                       apdu.getBuffer(result);
+                       break;
+
+               case COMMAND_SELECT_BY_DF_NAME :
+                       apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_DF_NAME, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+                       apdu.getBuffer(result);
+                       break;
+
+               case COMMAND_SELECT_BY_PATH :
+                       apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_PATH, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+                       apdu.getBuffer(result);
+                       break;
+
+               case COMMAND_SELECT_BY_PATH_FROM_CURRENT_DF :
+                       apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_PATH_FROM_CURRENT_DF, APDUCommand::P2_SELECT_GET_FCP, data, 0);
+                       apdu.getBuffer(result);
+                       break;
+
+               default :
+                       break;
+               }
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/AccessCondition.cpp b/common/AccessCondition.cpp
new file mode 100644 (file)
index 0000000..b6e2c4f
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "SimpleTLV.h"
+#include "AccessCondition.h"
+
+namespace smartcard_service_api
+{
+       void APDUAccessRule::loadAPDUAccessRule(const ByteArray &data)
+       {
+               SimpleTLV tlv(data);
+
+               if (tlv.decodeTLV() == true)
+               {
+                       switch (tlv.getTag())
+                       {
+                       case 0xA0 : /* CHOICE 0 : APDUPermission */
+                               permission = SimpleTLV::getBoolean(tlv.getValue());
+                               break;
+
+                       case 0xA1 : /* CHOICE 1 : APDUFilters */
+                               tlv.enterToValueTLV();
+                               while (tlv.decodeTLV() == true)
+                               {
+                                       if (tlv.getTag() == 0x04) /* OCTET STRING */
+                                       {
+                                               ByteArray apdu, mask, value;
+
+                                               value = tlv.getValue();
+
+                                               SCARD_DEBUG("APDU rule : %s", value.toString());
+
+                                               if (value.getLength() == 8) /* apdu 4 bytes + mask 4 bytes */
+                                               {
+                                                       apdu.setBuffer(value.getBuffer(), 4);
+                                                       mask.setBuffer(value.getBuffer(4), 4);
+
+                                                       pair<ByteArray, ByteArray> newItem(apdu, mask);
+
+                                                       mapApduFilters.insert(newItem);
+                                               }
+                                               else
+                                               {
+                                                       SCARD_DEBUG_ERR("Invalid APDU rule : %s", value.toString());
+                                               }
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+                                       }
+                               }
+                               tlv.returnToParentTLV();
+                               break;
+
+                       default :
+                               SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+                               break;
+                       }
+               }
+       }
+
+       bool APDUAccessRule::isAuthorizedAccess(const ByteArray &command)
+       {
+               bool result = false;
+
+               if (mapApduFilters.size() > 0)
+               {
+                       /* TODO : search command and check validity */
+               }
+               else
+               {
+                       /* no filter entry. if permission is true, all access will be granted, if not, all access will be denied */
+                       result = permission;
+               }
+
+               return result;
+       }
+
+       void APDUAccessRule::printAPDUAccessRules()
+       {
+               SCARD_DEBUG("  +-- APDU Access Rule");
+
+               if (mapApduFilters.size() > 0)
+               {
+                       map<ByteArray, ByteArray>::iterator iterMap;
+
+                       for (iterMap = mapApduFilters.begin(); iterMap != mapApduFilters.end(); iterMap++)
+                       {
+                               SCARD_DEBUG("  +--- APDU : %s, Mask : %s", ((ByteArray)(iterMap->first)).toString(), iterMap->second.toString());
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG("  +--- permission : %s", permission ? "granted all" : "denied all");
+               }
+       }
+
+       void NFCAccessRule::loadNFCAccessRule(const ByteArray &data)
+       {
+               permission = SimpleTLV::getBoolean(data);
+       }
+
+       bool NFCAccessRule::isAuthorizedAccess(void)
+       {
+               bool result = false;
+
+               result = permission;
+
+               return result;
+       }
+
+       void NFCAccessRule::printNFCAccessRules()
+       {
+               SCARD_DEBUG("   +-- NFC Access Rule");
+               SCARD_DEBUG("   +--- permission : %s", permission ? "granted all" : "denied all");
+       }
+
+       void AccessCondition::loadAccessCondition(ByteArray &aid, ByteArray &data)
+       {
+               if (data.getLength() > 0)
+               {
+                       SimpleTLV tlv(data);
+
+                       while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE */
+                       {
+                               if (tlv.getLength() > 0)
+                               {
+                                       /* access granted for specific applications */
+                                       tlv.enterToValueTLV();
+                                       if (tlv.decodeTLV())
+                                       {
+                                               switch (tlv.getTag())
+                                               {
+                                               case 0x04 : /* OCTET STRING : CertHash */
+                                                       SCARD_DEBUG("aid : %s, hash : %s", aid.toString(), tlv.getValue().toString());
+
+                                                       hashes.push_back(tlv.getValue());
+                                                       break;
+
+                                               case 0xA0 : /* CHOICE 0 : AccessRules */
+                                                       tlv.enterToValueTLV();
+                                                       if (tlv.decodeTLV())
+                                                       {
+                                                               switch (tlv.getTag())
+                                                               {
+                                                               case 0xA0 : /* CHOICE 0 : APDUAccessRule */
+                                                                       apduRule.loadAPDUAccessRule(tlv.getValue());
+                                                                       break;
+
+                                                               case 0xA1 : /* CHOICE 1 : NFCAccessRule */
+                                                                       nfcRule.loadNFCAccessRule(tlv.getValue());
+                                                                       break;
+
+                                                               default :
+                                                                       SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+                                                                       break;
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               SCARD_DEBUG_ERR("tlv.decodeTLV failed");
+                                                       }
+                                                       tlv.returnToParentTLV();
+                                                       break;
+
+                                               default :
+                                                       SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+                                                       break;
+                                               }
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("tlv.decodeTLV failed");
+                                       }
+                                       tlv.returnToParentTLV();
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG("access granted for all applications, aid : %s", aid.toString());
+
+                                       permission = true;
+                                       break;
+                               }
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG("access denied for all applications, aid : %s", aid.toString());
+
+                       permission = false;
+               }
+       }
+
+       bool AccessCondition::isAuthorizedAccess(ByteArray &certHash)
+       {
+               bool result = false;
+
+               if (hashes.size() > 0)
+               {
+                       size_t i;
+
+                       for (i = 0; i < hashes.size(); i++)
+                       {
+                               if (certHash == hashes[i])
+                               {
+                                       result = true;
+                                       break;
+                               }
+                       }
+               }
+               else
+               {
+                       result = permission;
+               }
+
+               return result;
+       }
+
+       bool AccessCondition::isAuthorizedAPDUAccess(ByteArray &command)
+       {
+               bool result = false;
+
+               result = apduRule.isAuthorizedAccess(command);
+
+               return result;
+       }
+
+       bool AccessCondition::isAuthorizedNFCAccess()
+       {
+               bool result = false;
+
+               result = nfcRule.isAuthorizedAccess();
+
+               return result;
+       }
+
+       void AccessCondition::printAccessConditions()
+       {
+               SCARD_DEBUG(" +-- Access Condition");
+
+               if (hashes.size() > 0)
+               {
+                       size_t i;
+
+                       for (i = 0; i < hashes.size(); i++)
+                       {
+                               SCARD_DEBUG(" +--- hash : %s", hashes[i].toString());
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG(" +--- permission : %s", permission ? "granted all" : "denied all");
+               }
+       }
+} /* namespace smartcard_service_api */
diff --git a/common/AccessControlList.cpp b/common/AccessControlList.cpp
new file mode 100644 (file)
index 0000000..6cd2540
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "AccessControlList.h"
+#include "PKCS15.h"
+#include "AccessCondition.h"
+
+namespace smartcard_service_api
+{
+       const unsigned char aid_all[] = { 0x00, 0x00 };
+       const unsigned char aid_default[] = { 0x00, 0x01 };
+
+       ByteArray AccessControlList::AID_ALL(ARRAY_AND_SIZE(aid_all));
+       ByteArray AccessControlList::AID_DEFAULT(ARRAY_AND_SIZE(aid_default));
+
+       AccessControlList::AccessControlList()
+       {
+               channel = NULL;
+               terminal = NULL;
+       }
+
+       AccessControlList::AccessControlList(Channel *channel)
+       {
+               channel = NULL;
+               terminal = NULL;
+
+               setChannel(channel);
+       }
+
+       AccessControlList::AccessControlList(Terminal *terminal)
+       {
+               channel = NULL;
+               terminal = NULL;
+
+               setTerminal(terminal);
+       }
+
+       AccessControlList::~AccessControlList()
+       {
+               releaseACL();
+
+               if (terminal != NULL && channel != NULL)
+               {
+                       delete channel;
+               }
+       }
+
+       int AccessControlList::setChannel(Channel *channel)
+       {
+               this->channel = channel;
+
+               return 0;
+       }
+
+       int AccessControlList::updateACL()
+       {
+               releaseACL();
+
+               return loadACL();
+       }
+
+       void AccessControlList::releaseACL()
+       {
+               mapConditions.clear();
+       }
+
+       bool AccessControlList::isAuthorizedAccess(ByteArray aid, ByteArray certHash)
+       {
+               bool result = false;
+               map<ByteArray, AccessCondition>::iterator iterMap;
+
+               SCARD_DEBUG("aid : %s", aid.toString());
+               SCARD_DEBUG("hash : %s", certHash.toString());
+
+               /* null aid means default applet */
+               if (aid.isEmpty() == true)
+               {
+                       aid = AID_DEFAULT;
+               }
+
+               /* first.. find hashes matched with aid */
+               if ((iterMap = mapConditions.find(aid)) != mapConditions.end())
+               {
+                       result = iterMap->second.isAuthorizedAccess(certHash);
+               }
+               /* finally.. find hashes in 'all' list */
+               else if ((iterMap = mapConditions.find(AID_ALL)) != mapConditions.end())
+               {
+                       result = iterMap->second.isAuthorizedAccess(certHash);
+               }
+
+               return result;
+       }
+
+       bool AccessControlList::isAuthorizedAccess(unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength)
+       {
+               return isAuthorizedAccess(ByteArray(aidBuffer, aidLength), ByteArray(certHashBuffer, certHashLength));
+       }
+
+       void AccessControlList::printAccessControlList()
+       {
+               ByteArray temp;
+
+               /* release map and vector */
+               map<ByteArray, AccessCondition>::iterator iterMap;
+
+               SCARD_DEBUG("================ Certification Hashes ==================");
+               for (iterMap = mapConditions.begin(); iterMap != mapConditions.end(); iterMap++)
+               {
+                       temp = iterMap->first;
+
+                       SCARD_DEBUG("+ aid : %s", (temp == AID_DEFAULT) ? "DEFAULT" : (temp == AID_ALL) ? "ALL" : temp.toString());
+
+                       iterMap->second.printAccessConditions();
+               }
+               SCARD_DEBUG("========================================================");
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/ByteArray.cpp b/common/ByteArray.cpp
new file mode 100644 (file)
index 0000000..ee2acf0
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       ByteArray ByteArray::EMPTY = ByteArray();
+
+       ByteArray::ByteArray()
+       {
+               buffer = NULL;
+               length = 0;
+       }
+
+       ByteArray::ByteArray(uint8_t *array, uint32_t bufferLen)
+       {
+               buffer = NULL;
+               length = 0;
+
+               setBuffer(array, bufferLen);
+       }
+
+       ByteArray::ByteArray(const ByteArray &T)
+       {
+               buffer = NULL;
+               length = 0;
+
+               setBuffer(T.buffer, T.length);
+       }
+
+       ByteArray::~ByteArray()
+       {
+               releaseBuffer();
+       }
+
+       bool ByteArray::setBuffer(uint8_t *array, uint32_t bufferLen)
+       {
+               if (array == NULL || bufferLen == 0)
+               {
+                       return false;
+               }
+
+               releaseBuffer();
+
+               buffer = new uint8_t[bufferLen];
+               if (buffer == NULL)
+               {
+                       SCARD_DEBUG_ERR("alloc failed");
+                       return false;
+               }
+
+               memcpy(buffer, array, bufferLen);
+               length = bufferLen;
+
+               return true;
+       }
+
+       bool ByteArray::_setBuffer(uint8_t *array, uint32_t bufferLen)
+       {
+               if (array == NULL || bufferLen == 0)
+               {
+                       return false;
+               }
+
+               releaseBuffer();
+
+               buffer = array;
+               length = bufferLen;
+
+               return true;
+       }
+
+       uint32_t ByteArray::getLength() const
+       {
+               return length;
+       }
+
+       uint8_t *ByteArray::getBuffer() const
+       {
+               return getBuffer(0);
+       }
+
+       uint8_t *ByteArray::getBuffer(uint32_t offset) const
+       {
+               if (length == 0)
+                       return NULL;
+
+               if (offset >= length)
+               {
+                       SCARD_DEBUG_ERR("buffer overflow, offset [%d], length [%d]", offset, length);
+                       return NULL;
+               }
+
+               return buffer + offset;
+       }
+
+       uint8_t ByteArray::getAt(uint32_t index) const
+       {
+               if (index >= length)
+               {
+                       SCARD_DEBUG_ERR("buffer overflow, index [%d], length [%d]", index, length);
+                       return buffer[length -1];
+               }
+
+               return buffer[index];
+       }
+
+       uint8_t ByteArray::getReverseAt(uint32_t index) const
+       {
+               if (index >= length)
+               {
+                       SCARD_DEBUG_ERR("buffer underflow, index [%d], length [%d]", index, length);
+                       return buffer[0];
+               }
+
+               return buffer[length - index - 1];
+       }
+
+       uint32_t ByteArray::copyFromArray(uint8_t *array, uint32_t bufferLen) const
+       {
+               uint32_t min_len = 0;
+
+               if (array == NULL || bufferLen == 0)
+               {
+                       SCARD_DEBUG_ERR("invaild param");
+                       return false;
+               }
+
+               min_len = (bufferLen < length) ? bufferLen : length;
+
+               memcpy(array, buffer, min_len);
+
+               return min_len;
+       }
+
+       void ByteArray::releaseBuffer()
+       {
+               if (buffer != NULL)
+               {
+                       delete []buffer;
+                       buffer = NULL;
+               }
+               length = 0;
+       }
+
+       /* operator overloading */
+       ByteArray ByteArray::operator +(const ByteArray &T)
+       {
+               uint32_t newLen;
+               uint8_t *newBuffer;
+               ByteArray newArray;
+
+               if (length == 0)
+               {
+                       SCARD_DEBUG("length is zero");
+
+                       return T;
+               }
+
+               newLen = T.length;
+
+               if (newLen == 0)
+                       return *this;
+
+               newLen += length;
+
+               newBuffer = new uint8_t[newLen];
+               if (newBuffer == NULL)
+               {
+                       /* assert.... */
+                       SCARD_DEBUG_ERR("alloc failed");
+
+                       return *this;
+               }
+
+               memcpy(newBuffer, buffer, length);
+               memcpy(newBuffer + length, T.buffer, T.length);
+
+               newArray._setBuffer(newBuffer, newLen);
+
+               return newArray;
+       }
+
+       ByteArray &ByteArray::operator =(const ByteArray &T)
+       {
+               if (this != &T)
+               {
+                       setBuffer(T.buffer, T.length);
+               }
+
+               return *this;
+       }
+
+       ByteArray &ByteArray::operator +=(const ByteArray &T)
+       {
+               *this = *this + T;
+
+               return *this;
+       }
+
+       bool ByteArray::operator ==(const ByteArray &T) const
+       {
+               if (length != T.length)
+                       return false;
+
+               return (memcmp(buffer, T.buffer, length) == 0);
+       }
+
+       bool ByteArray::operator !=(const ByteArray &T) const
+       {
+               return !(*this == T);
+       }
+
+       bool ByteArray::operator <(const ByteArray &T) const
+       {
+               return (memcmp(buffer, T.buffer, (length < T.length) ? length : T.length) < 0);
+       }
+
+       bool ByteArray::operator >(const ByteArray &T) const
+       {
+               return (memcmp(buffer, T.buffer, (length < T.length) ? length : T.length) > 0);
+       }
+
+       uint8_t &ByteArray::operator [](uint32_t index) const
+       {
+               if (index >= length)
+               {
+                       SCARD_DEBUG_ERR("buffer overflow, index [%d], length [%d]", index, length);
+                       return buffer[length -1];
+               }
+
+               return buffer[index];
+       }
+
+       const char *ByteArray::toString()
+       {
+               memset(strBuffer, 0, sizeof(strBuffer));
+
+               if (length == 0)
+               {
+                       snprintf(strBuffer, sizeof(strBuffer), "buffer is empty");
+               }
+               else
+               {
+                       int count;
+                       int i, offset = 0;
+                       bool ellipsis = false;
+
+                       count = length;
+                       if (count > 20)
+                       {
+                               count = 20;
+                               ellipsis = true;
+                       }
+
+                       snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "{ ");
+                       offset += 2;
+
+                       for (i = 0; i < count; i++)
+                       {
+                               snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "%02X ", buffer[i]);
+                               offset += 3;
+                       }
+
+                       if (ellipsis)
+                       {
+                               snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "... }");
+                       }
+                       else
+                       {
+                               snprintf(strBuffer + offset, sizeof(strBuffer) - offset, "}");
+                       }
+               }
+
+               return (const char *)strBuffer;
+       }
+
+       void ByteArray::save(const char *filePath)
+       {
+               FILE *file = NULL;
+
+               if (filePath == NULL || buffer == NULL || length == 0)
+                       return;
+
+               if ((file = fopen(filePath, "w")) != NULL)
+               {
+                       fwrite(buffer, 1, length, file);
+                       fflush(file);
+
+                       fclose(file);
+                       SCARD_DEBUG("file has written, file [%s], length[%d]", filePath, length);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("file open failed, [%d]", errno);
+               }
+       }
+
+} /* namespace smartcard_service_api */
+
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a32d420
--- /dev/null
@@ -0,0 +1,84 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(smartcard-service-common CXX)
+
+SET(LIB_NAME "smartcard-service-common")
+SET(VERSION_MAJOR 1)
+SET(VERSION ${VERSION_MAJOR}.0.0)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SRCS)
+
+#IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+#        SET(CMAKE_BUILD_TYPE "Debug")
+#ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+#MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_common REQUIRED dlog glib-2.0 gthread-2.0 dpl-wrt-dao-ro aul libssl)
+
+MESSAGE("${LIB_NAME} ld flag : ${pkgs_common_LDFLAGS}")
+
+FOREACH(flag ${pkgs_common_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${pkgs_common_CFLAGS})
+       SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+#SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -finstrument-functions")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+#SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+#SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+#SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -finstrument-functions")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+#SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+#SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+MESSAGE("CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DSLP_DEBUG")
+ADD_DEFINITIONS("-DUSE_UNIX_DOMAIN")
+
+ADD_DEFINITIONS("-DLOG_TAG=\"SCARD_COMMON\"")
+
+# Temporary add #############
+ADD_DEFINITIONS("-std=c++0x")
+#############################
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES VERSION ${VERSION})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_common_LDFLAGS})
+
+SET(EXPORT_HEADER 
+       include/Debug.h
+       include/ByteArray.h
+       include/Lock.h
+       include/Synchronous.h   
+       include/TerminalInterface.h
+       include/Terminal.h
+       include/SignatureHelper.h
+       include/GPSEACL.h
+)
+
+#CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc DESTINATION lib/pkgconfig)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
+FOREACH(hfile ${EXPORT_HEADER})
+        INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
+ENDFOREACH(hfile)
diff --git a/common/DispatcherHelper.cpp b/common/DispatcherHelper.cpp
new file mode 100644 (file)
index 0000000..8c955f2
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "DispatcherHelper.h"
+
+namespace smartcard_service_api
+{
+       DispatcherHelper::DispatcherHelper()
+       {
+               dispatcherThread = 0;
+       }
+
+       DispatcherHelper::~DispatcherHelper()
+       {
+               stopDispatcherThread();
+       }
+
+       DispatcherMsg *DispatcherHelper::fetchMessage()
+       {
+               DispatcherMsg *result = NULL;
+
+               if (messageQ.size() > 0)
+               {
+                       result = messageQ.front();
+                       messageQ.pop();
+               }
+
+               return result;
+       }
+
+       void DispatcherHelper::clearQueue()
+       {
+               DispatcherMsg *temp = NULL;
+
+               while (messageQ.size() > 0)
+               {
+                       temp = fetchMessage();
+                       delete temp;
+               }
+       }
+
+       void DispatcherHelper::pushMessage(DispatcherMsg *msg)
+       {
+               syncLock();
+
+               messageQ.push(msg);
+
+               signalCondition();
+               syncUnlock();
+       }
+
+       void *DispatcherHelper::_dispatcherThreadFunc(void *data)
+       {
+               DispatcherMsg *msg = NULL;
+               DispatcherHelper *helper = (DispatcherHelper *)data;
+
+               while (1)
+               {
+                       helper->syncLock();
+                       if ((msg = helper->fetchMessage()) == NULL)
+                       {
+                               helper->waitTimedCondition(0);
+                               helper->syncUnlock();
+                               continue;
+                       }
+                       helper->syncUnlock();
+
+                       /* process message */
+                       helper->dispatcherThreadFunc(msg, data);
+
+                       delete msg;
+               }
+
+               return (void *)NULL;
+       }
+
+       bool DispatcherHelper::runDispatcherThread()
+       {
+               bool result = false;
+               pthread_attr_t attr;
+
+               if (dispatcherThread == 0)
+               {
+                       int ret;
+
+                       pthread_attr_init(&attr);
+                       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+                       if ((ret = pthread_create(&dispatcherThread, &attr, &DispatcherHelper::_dispatcherThreadFunc, this)) != 0)
+                       {
+                               SCARD_DEBUG_ERR("pthread_create failed [%d]", ret);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG("pthread_create success");
+                               result = true;
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG("thread already start");
+                       result = true;
+               }
+
+               return result;
+       }
+
+       void DispatcherHelper::stopDispatcherThread()
+       {
+               if (dispatcherThread != 0)
+               {
+                       pthread_cancel(dispatcherThread);
+                       dispatcherThread = 0;
+               }
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/FCI.cpp b/common/FCI.cpp
new file mode 100644 (file)
index 0000000..5093f2c
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "FCI.h"
+#include "SimpleTLV.h"
+//#include "ISO7816BERTLV.h"
+#include "NumberStream.h"
+
+namespace smartcard_service_api
+{
+       /* FCP class method */
+       FCP::FCP()
+       {
+               resetMemberVar();
+       }
+
+       FCP::FCP(ByteArray &array)
+       {
+               resetMemberVar();
+
+               setFCP(array);
+       }
+
+       FCP::~FCP()
+       {
+       }
+
+       void FCP::resetMemberVar()
+       {
+               fileSize = FCI::INFO_NOT_AVAILABLE;
+               totalFileSize = FCI::INFO_NOT_AVAILABLE;
+               fid = FCI::INFO_NOT_AVAILABLE;
+               sfi = FCI::INFO_NOT_AVAILABLE;
+               maxRecordSize = FCI::INFO_NOT_AVAILABLE;
+               numberOfRecord = FCI::INFO_NOT_AVAILABLE;
+               fileType = FCI::INFO_NOT_AVAILABLE;
+               fileStructure = FCI::INFO_NOT_AVAILABLE;
+               lcs = FCI::INFO_NOT_AVAILABLE;
+       }
+
+       bool FCP::setFCP(ByteArray array)
+       {
+               bool result = false;
+               SimpleTLV tlv;
+
+               SCARD_BEGIN();
+
+               releaseFCP();
+
+               if (array.getLength() == 0)
+                       return false;
+
+               fcpBuffer = array;
+
+               if (fcpBuffer[0] != 0x62)
+               {
+                       SCARD_DEBUG_ERR("it is not FCP response [%02X]", fcpBuffer[0]);
+                       return false;
+               }
+
+               /* parse... */
+               tlv.setTLVBuffer(fcpBuffer.getBuffer(), fcpBuffer.getLength());
+
+               if (tlv.decodeTLV())
+               {
+                       tlv.enterToValueTLV();
+
+                       while (tlv.decodeTLV())
+                       {
+                               switch (tlv.getTag())
+                               {
+                               case 0x80 : /* file length without sturctural inforamtion */
+                                       {
+                                               SCARD_DEBUG("0x%02X : file length without sturctural inforamtion : %s", tlv.getTag(), tlv.getValue().toString());
+                                               if (tlv.getLength() > 0)
+                                               {
+                                                       fileSize = NumberStream::getBigEndianNumber(tlv.getValue());
+                                               }
+                                       }
+                                       break;
+
+                               case 0x81 : /* file length with sturctural inforamtion */
+                                       {
+                                               SCARD_DEBUG("0x%02X : file length with sturctural inforamtion : %s", tlv.getTag(), tlv.getValue().toString());
+                                               if (tlv.getLength() > 0)
+                                               {
+                                                       maxRecordSize = NumberStream::getBigEndianNumber(tlv.getValue());
+                                               }
+                                       }
+                                       break;
+
+                               case 0x82 : /* file descriptor bytes */
+                                       {
+                                               SCARD_DEBUG("0x%02X : file descriptor bytes : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0x83 : /* file identifier */
+                                       {
+                                               SCARD_DEBUG("0x%02X : file identifier : %s", tlv.getTag(), tlv.getValue().toString());
+                                               if (tlv.getLength() > 0)
+                                               {
+                                                       ByteArray value = tlv.getValue();
+
+                                                       fid = 0;
+
+                                                       memcpy(&fid, value.getBuffer(), value.getLength());
+                                               }
+                                       }
+                                       break;
+
+                               case 0x84 : /* DF name */
+                                       {
+                                               SCARD_DEBUG("0x%02X : DF name : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0x85 : /* proprietary information not encoded in BER-TLV */
+                                       {
+                                               SCARD_DEBUG("0x%02X : proprietary information not encoded in BER-TLV : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0x86 : /* Security attribute in proprietary format */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Security attribute in proprietary format : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0x87 : /* Identifier of an EF containing an extension of the file control information */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Identifier of an EF containing an extension of the file control information : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0x88 : /* Short EF identifier */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Short EF identifier : %s", tlv.getTag(), tlv.getValue().toString());
+
+                                               if (tlv.getLength() > 0)
+                                               {
+                                                       ByteArray value = tlv.getValue();
+
+                                                       sfi = 0;
+
+                                                       memcpy(&sfi, value.getBuffer(), value.getLength());
+                                               }
+                                       }
+                                       break;
+
+                               case 0x8A : /* life cycle status byte */
+                                       {
+                                               SCARD_DEBUG("0x%02X : life cycle status byte : %s", tlv.getTag(), tlv.getValue().toString());
+                                               if (tlv.getLength() > 0)
+                                               {
+                                                       ByteArray value = tlv.getValue();
+
+                                                       lcs = 0;
+
+                                                       memcpy(&lcs, value.getBuffer(), value.getLength());
+                                               }
+                                       }
+                                       break;
+
+                               case 0x8B : /* Security attribute referencing the expanded format */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Security attribute referencing the expanded format : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0x8C : /* Security attribute in compact format */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Security attribute in compact format : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0x8D : /* Identifier of an EF containing security environment templates */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Identifier of an EF containing security environment templates : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0x8E : /* Channel security attribute */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Channel security attribute : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0xA0 : /* Security attribute template for data objects */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Security attribute template for data objects : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0xA1 : /* Security attribute template in proprietary format */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Security attribute template in proprietary format : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0xA2 : /* Template consisting of one or more pairs of data objects */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Template consisting of one or more pairs of data objects : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0xA5 : /* proprietary information encoded in BER-TLV */
+                                       {
+                                               SCARD_DEBUG("0x%02X : proprietary information encoded in BER-TLV : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0xAB : /* Security attribute template in expanded format */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Security attribute template in expanded format : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0xAC : /* Cryptographic mechanism identifier template */
+                                       {
+                                               SCARD_DEBUG("0x%02X : Cryptographic mechanism identifier template : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               case 0xC6 : /* PIN status template DO */
+                                       {
+                                               SCARD_DEBUG("0x%02X : PIN status template DO : %s", tlv.getTag(), tlv.getValue().toString());
+       //                                      ByteArray value = tlv.getValue();
+                                       }
+                                       break;
+
+                               default :
+                                       {
+                                               SCARD_DEBUG("0x%02X : unknown : %s", tlv.getTag(), tlv.getValue().toString());
+                                       }
+                                       break;
+                               }
+                       }
+                       tlv.returnToParentTLV();
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("tlv.decodeTLV failed");
+               }
+
+               SCARD_END();
+
+               return result;
+       }
+
+       ByteArray FCP::getFCP()
+       {
+               return fcpBuffer;
+       }
+
+       void FCP::releaseFCP()
+       {
+               fcpBuffer.releaseBuffer();
+
+               resetMemberVar();
+       }
+
+       unsigned int FCP::getFileSize()
+       {
+               return fileSize;
+       }
+
+       unsigned int FCP::getTotalFileSize()
+       {
+               return totalFileSize;
+       }
+
+       unsigned int FCP::getFID()
+       {
+               return fid;
+       }
+
+       unsigned int FCP::getSFI()
+       {
+               return sfi;
+       }
+
+       unsigned int FCP::getMaxRecordSize()
+       {
+               return maxRecordSize;
+       }
+
+       unsigned int FCP::getNumberOfRecord()
+       {
+               return numberOfRecord;
+       }
+
+       unsigned int FCP::getFileType()
+       {
+               return fileType;
+       }
+
+       unsigned int FCP::getFileStructure()
+       {
+               return fileStructure;
+       }
+
+       unsigned int FCP::getLCS()
+       {
+               return lcs;
+       }
+
+       const char *FCP::toString()
+       {
+               memset(strBuffer, 0, sizeof(strBuffer));
+
+               snprintf(strBuffer, sizeof(strBuffer), "size [%d], total size [%d], fid [%x], sfi [%x], max rec [%d], n of rec [%d], type [%d], struct [%d], lcs [%d]",
+                       getFileSize(), getTotalFileSize(), getFID(), getSFI(), getMaxRecordSize(), getNumberOfRecord(), getFileType(), getFileStructure(), getLCS());
+
+               return (const char *)strBuffer;
+       }
+
+
+       /* FCM class method */
+       FCM::FCM()
+       {
+       }
+
+       FCM::~FCM()
+       {
+       }
+
+
+       /* FCI class method */
+       FCI::FCI()
+       {
+       }
+
+       FCI::~FCI()
+       {
+       }
+
+       bool FCI::setFCIBuffer(ByteArray array)
+       {
+               bool result = false;
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/FileObject.cpp b/common/FileObject.cpp
new file mode 100644 (file)
index 0000000..204808b
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "FileObject.h"
+#include "APDUHelper.h"
+
+namespace smartcard_service_api
+{
+       FileObject::FileObject(Channel *channel):ProviderHelper(channel)
+       {
+       }
+
+       FileObject::FileObject(Channel *channel, ByteArray selectResponse):ProviderHelper(channel)
+       {
+               setSelectResponse(selectResponse);
+       }
+
+       FileObject::~FileObject()
+       {
+       }
+
+       bool FileObject::setSelectResponse(ByteArray response)
+       {
+               bool result = false;
+
+               selectResponse = response;
+
+               if (selectResponse.getLength() > 2)
+               {
+                       ResponseHelper resp(selectResponse);
+
+                       fcp.setFCP(resp.getDataField());
+
+                       result = true;
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("invalid response : %s", selectResponse.toString());
+               }
+
+               return result;
+       }
+
+       int FileObject::select(ByteArray aid)
+       {
+               int ret = ERROR_ILLEGAL_STATE;
+               ByteArray command, result;
+               APDUHelper apdu;
+
+               if (channel == NULL || channel->isClosed())
+               {
+                       SCARD_DEBUG_ERR("channel is not open");
+
+                       return ret;
+               }
+
+               /* make apdu command */
+               command = apdu.generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, 0, aid);
+               SCARD_DEBUG("command : %s", command.toString());
+               ret = channel->transmitSync(command, result);
+
+               if (ret == 0 && result.getLength() >= 2)
+               {
+                       ResponseHelper resp(result);
+                       this->selectResponse = result;
+
+                       if (resp.getStatus() == 0)
+                       {
+                               SCARD_DEBUG("response [%d] : %s", result.getLength(), result.toString());
+
+                               fcp.releaseFCP();
+
+                               if (result.getLength() > 2)
+                               {
+                                       fcp.setFCP(resp.getDataField());
+
+                                       SCARD_DEBUG("FCP : %s", fcp.toString());
+                               }
+
+                               ret = SUCCESS;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, result.getLength());
+               }
+
+               return ret;
+       }
+
+       int FileObject::select(ByteArray path, bool fromCurrentDF)
+       {
+               int ret = ERROR_ILLEGAL_STATE;
+               ByteArray command, result;
+               APDUHelper apdu;
+
+               if (channel == NULL || channel->isClosed())
+               {
+                       SCARD_DEBUG_ERR("channel is not open");
+
+                       return ret;
+               }
+
+               /* make apdu command */
+               if (fromCurrentDF == true)
+               {
+                       command = apdu.generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH_FROM_CURRENT_DF, 0, path);
+               }
+               else
+               {
+                       command = apdu.generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH, 0, path);
+               }
+               SCARD_DEBUG("command : %s", command.toString());
+
+               ret = channel->transmitSync(command, result);
+
+               if (ret == 0 && result.getLength() >= 2)
+               {
+                       ResponseHelper resp(result);
+                       this->selectResponse = result;
+
+                       if (resp.getStatus() == 0)
+                       {
+                               SCARD_DEBUG("response [%d] : %s", result.getLength(), result.toString());
+
+                               fcp.releaseFCP();
+
+                               if (result.getLength() > 2)
+                               {
+                                       fcp.setFCP(resp.getDataField());
+
+                                       SCARD_DEBUG("FCP : %s", fcp.toString());
+                               }
+
+                               ret = SUCCESS;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, result.getLength());
+               }
+
+               return ret;
+       }
+
+       int FileObject::select(unsigned int fid)
+       {
+               int ret = ERROR_ILLEGAL_STATE;
+               ByteArray command, result, fidData((unsigned char *)&fid, 2);
+
+               if (channel == NULL || channel->isClosed())
+               {
+                       SCARD_DEBUG_ERR("channel is not open");
+
+                       return ret;
+               }
+
+               /* make apdu command */
+               command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, fidData);
+               ret = channel->transmitSync(command, result);
+
+               if (ret == 0 && result.getLength() >= 2)
+               {
+                       ResponseHelper resp(result);
+                       this->selectResponse = result;
+
+                       if (resp.getStatus() == 0)
+                       {
+                               SCARD_DEBUG("response [%d] : %s", result.getLength(), result.toString());
+
+                               fcp.releaseFCP();
+
+                               if (result.getLength() > 2)
+                               {
+                                       fcp.setFCP(resp.getDataField());
+
+                                       SCARD_DEBUG("FCP : %s", fcp.toString());
+                               }
+
+                               ret = SUCCESS;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, result.getLength());
+               }
+
+               return ret;
+       }
+
+       int FileObject::selectParent()
+       {
+               int ret = ERROR_ILLEGAL_STATE;
+               ByteArray command, result;
+               APDUHelper apdu;
+
+               if (channel == NULL || channel->isClosed())
+               {
+                       SCARD_DEBUG_ERR("channel is not open");
+
+                       return ret;
+               }
+
+               /* make apdu command */
+               command = apdu.generateAPDU(APDUHelper::COMMAND_SELECT_PARENT_DF, 0, ByteArray::EMPTY);
+               SCARD_DEBUG("command : %s", command.toString());
+
+               ret = channel->transmitSync(command, result);
+
+               if (ret == 0 && result.getLength() >= 2)
+               {
+                       ResponseHelper resp(result);
+                       this->selectResponse = result;
+
+                       if (resp.getStatus() == 0)
+                       {
+                               SCARD_DEBUG("response [%d] : %s", result.getLength(), result.toString());
+
+                               fcp.releaseFCP();
+
+                               if (result.getLength() > 2)
+                               {
+                                       fcp.setFCP(resp.getDataField());
+
+                                       SCARD_DEBUG("FCP : %s", fcp.toString());
+                               }
+
+                               ret = SUCCESS;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, result.getLength());
+               }
+
+               return ret;
+       }
+
+       FCI *FileObject::getFCI()
+       {
+               return NULL;
+       }
+
+       FCP *FileObject::getFCP()
+       {
+               return &fcp;
+       }
+
+       int FileObject::readRecord(unsigned int sfi, unsigned int recordId, Record &result)
+       {
+               ByteArray command, response;
+               APDUCommand apdu;
+               int ret;
+
+               apdu.setCommand(0, APDUCommand::INS_READ_RECORD, recordId, 4, ByteArray::EMPTY, 0);
+               apdu.getBuffer(command);
+               SCARD_DEBUG("command : %s", command.toString());
+
+               ret = channel->transmitSync(command, response);
+               if (ret == 0 && response.getLength() >= 2)
+               {
+                       ResponseHelper resp(response);
+
+                       if (resp.getStatus() == 0)
+                       {
+                               SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString());
+
+//                             result = resp.getDataField();
+
+                               ret = SUCCESS;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), response[response.getLength() - 2], response[response.getLength() - 1]);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, response.getLength());
+               }
+
+               return ret;
+       }
+
+       int FileObject::writeRecord(unsigned int sfi, Record record)
+       {
+               return 0;
+       }
+
+       int FileObject::searchRecord(unsigned int sfi, ByteArray searchParam, vector<int> &result)
+       {
+               return 0;
+       }
+
+       int FileObject::readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result)
+       {
+               ByteArray command, response;
+               APDUCommand apdu;
+               int ret;
+
+               apdu.setCommand(0, APDUCommand::INS_READ_BINARY, offset, 0, ByteArray::EMPTY, length);
+               apdu.getBuffer(command);
+               SCARD_DEBUG("command : %s", command.toString());
+
+               ret = channel->transmitSync(command, response);
+               if (ret == 0 && response.getLength() >= 2)
+               {
+                       ResponseHelper resp(response);
+
+                       if (resp.getStatus() == 0)
+                       {
+                               SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString());
+
+                               result = resp.getDataField();
+
+                               ret = SUCCESS;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), response[response.getLength() - 2], response[response.getLength() - 1]);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, response.getLength());
+               }
+
+               return ret;
+       }
+
+       int FileObject::writeBinary(unsigned int sfi, ByteArray data, unsigned int offset, unsigned int length)
+       {
+               ByteArray command, response;
+               APDUCommand apdu;
+               int ret;
+
+               apdu.setCommand(0, APDUCommand::INS_WRITE_BINARY, offset, 0, data, 0);
+               apdu.getBuffer(command);
+               SCARD_DEBUG("command : %s", command.toString());
+
+               ret = channel->transmitSync(command, response);
+               if (ret == 0 && response.getLength() >= 2)
+               {
+                       ResponseHelper resp(response);
+
+                       if (resp.getStatus() == 0)
+                       {
+                               SCARD_DEBUG("response [%d] : %s", response.getLength(), response.toString());
+
+                               ret = SUCCESS;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), response[response.getLength() - 2], response[response.getLength() - 1]);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", ret, response.getLength());
+               }
+
+               return ret;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/GPSEACL.cpp b/common/GPSEACL.cpp
new file mode 100644 (file)
index 0000000..775d88e
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "GPSEACL.h"
+#include "PKCS15ODF.h"
+#include "PKCS15DODF.h"
+#include "NumberStream.h"
+#include "SimpleTLV.h"
+#include "AccessCondition.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+       static unsigned char oid_globalplatform[] = { 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x81, 0x48, 0x01, 0x01 };
+       ByteArray GPSEACL::OID_GLOBALPLATFORM(ARRAY_AND_SIZE(oid_globalplatform));
+
+       GPSEACL::GPSEACL(Channel *channel):AccessControlList(channel)
+       {
+               this->channel = channel;
+
+               if (channel->getSelectResponse().isEmpty() == true)
+               {
+                       pkcs15 = new PKCS15(channel);
+               }
+               else
+               {
+                       pkcs15 = new PKCS15(channel, channel->getSelectResponse());
+               }
+       }
+
+       GPSEACL::~GPSEACL()
+       {
+               if (pkcs15 != NULL)
+               {
+                       delete pkcs15;
+               }
+       }
+
+       int GPSEACL::loadACL()
+       {
+               ByteArray aid, certHash;
+               PKCS15ODF *odf;
+
+               if ((odf = pkcs15->getODF()) != NULL)
+               {
+                       PKCS15DODF *dodf;
+
+                       if ((dodf = odf->getDODF()) != NULL)
+                       {
+                               loadAccessControl(dodf);
+
+                               printAccessControlList();
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("dodf null");
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("odf null");
+               }
+
+               return 0;
+       }
+
+       int GPSEACL::loadAccessControl(PKCS15DODF *dodf)
+       {
+               ByteArray path;
+
+               if (dodf->searchOID(OID_GLOBALPLATFORM, path) == 0)
+               {
+                       ByteArray data;
+                       FileObject file(channel);
+
+                       SCARD_DEBUG("oid path : %s", path.toString());
+
+                       file.select(NumberStream::getLittleEndianNumber(path));
+                       file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
+
+                       SCARD_DEBUG("data : %s", data.toString());
+
+                       SimpleTLV tlv(data);
+
+                       if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : AccessControlMainFile */
+                       {
+                               tlv.enterToValueTLV();
+
+                               /* refresh Tag */
+                               ByteArray refreshTag;
+
+                               refreshTag = SimpleTLV::getOctetString(tlv);
+                               SCARD_DEBUG("current refresh tag : %s", refreshTag.toString());
+
+                               if (this->refreshTag != refreshTag) /* need to update access control list */
+                               {
+                                       this->refreshTag = refreshTag;
+
+                                       releaseACL();
+
+                                       /* access control rule path */
+                                       if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
+                                       {
+                                               /* TODO : parse path */
+                                               ByteArray path;
+
+                                               /* OCTET STRING */
+                                               path = SimpleTLV::getOctetString(tlv.getValue());
+                                               SCARD_DEBUG("access control rule path : %s", path.toString());
+
+                                               if (loadRules(path) == 0)
+                                               {
+                                                       SCARD_DEBUG("loadRules success");
+                                               }
+                                               else
+                                               {
+                                                       SCARD_DEBUG_ERR("loadRules failed");
+                                               }
+                                       }
+                               }
+                               tlv.returnToParentTLV();
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("tlv.decodeTLV failed");
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("search failed");
+               }
+
+               return 0;
+       }
+
+       int GPSEACL::loadRules(ByteArray path)
+       {
+               FileObject file(channel);
+               ByteArray data, aid;
+
+               file.select(NumberStream::getLittleEndianNumber(path));
+               file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
+
+               SCARD_DEBUG("data : %s", data.toString());
+
+               SimpleTLV tlv(data);
+
+               while (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Rule */
+               {
+                       tlv.enterToValueTLV();
+                       if (tlv.decodeTLV() == true)
+                       {
+                               /* target */
+                               switch (tlv.getTag())
+                               {
+                               case 0xA0 : /* CHOICE 0 : EXPLICIT AID */
+                                       /* OCTET STRING */
+                                       aid = SimpleTLV::getOctetString(tlv.getValue());
+                                       break;
+
+                               case 0x81 : /* CHOICE 1?? : default */
+                                       aid = AccessControlList::AID_DEFAULT;
+                                       break;
+
+                               case 0x82 : /* CHOICE 2?? : any application */
+                                       aid = AccessControlList::AID_ALL;
+                                       break;
+                               }
+
+                               SCARD_DEBUG("aid : %s", aid.toString());
+
+                               /* access condition path */
+                               if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE : Path */
+                               {
+                                       ByteArray path;
+
+                                       /* OCTET STRING */
+                                       path = SimpleTLV::getOctetString(tlv.getValue());
+                                       SCARD_DEBUG("path : %s", path.toString());
+
+                                       if (loadAccessConditions(aid, path) == 0)
+                                       {
+                                               SCARD_DEBUG("loadCertHashes success");
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("loadCertHashes failed");
+                                       }
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("decodeTLV failed");
+                               }
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("decodeTLV failed");
+                       }
+                       tlv.returnToParentTLV();
+               }
+
+               return 0;
+       }
+
+       int GPSEACL::loadAccessConditions(ByteArray aid, ByteArray path)
+       {
+               FileObject file(channel);
+               ByteArray data;
+
+               file.select(NumberStream::getLittleEndianNumber(path));
+               file.readBinary(0, 0, file.getFCP()->getFileSize(), data);
+
+               SCARD_DEBUG("data : %s", data.toString());
+
+               AccessCondition condition;
+
+               condition.loadAccessCondition(aid, data);
+
+               pair<ByteArray, AccessCondition> newItem(aid, condition);
+
+               mapConditions.insert(newItem);
+
+               return 0;
+       }
+
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define GP_SE_ACL_EXTERN_BEGIN \
+       if (handle != NULL) \
+       { \
+               GPSEACL *acl = (GPSEACL *)handle;
+
+#define GP_SE_ACL_EXTERN_END \
+       } \
+       else \
+       { \
+               SCARD_DEBUG_ERR("Invalid param"); \
+       }
+
+using namespace smartcard_service_api;
+
+EXTERN_API gp_se_acl_h gp_se_acl_create_instance(channel_h channel)
+{
+       GPSEACL *acl = new GPSEACL((Channel *)channel);
+
+       return (gp_se_acl_h)acl;
+}
+
+EXTERN_API int gp_se_acl_load_acl(gp_se_acl_h handle)
+{
+       int result = -1;
+
+       GP_SE_ACL_EXTERN_BEGIN;
+       result = acl->loadACL();
+       GP_SE_ACL_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API int gp_se_acl_update_acl(gp_se_acl_h handle)
+{
+       int result = -1;
+
+       GP_SE_ACL_EXTERN_BEGIN;
+       acl->updateACL();
+       GP_SE_ACL_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API void gp_se_acl_release_acl(gp_se_acl_h handle)
+{
+       GP_SE_ACL_EXTERN_BEGIN;
+       acl->releaseACL();
+       GP_SE_ACL_EXTERN_END;
+}
+
+EXTERN_API bool gp_se_acl_is_authorized_access(gp_se_acl_h handle, unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength)
+{
+       bool result = false;
+
+       GP_SE_ACL_EXTERN_BEGIN;
+       result = acl->isAuthorizedAccess(aidBuffer, aidLength, certHashBuffer, certHashLength);
+       GP_SE_ACL_EXTERN_END;
+
+       return result;
+}
+
+EXTERN_API void gp_se_acl_destroy_instance(gp_se_acl_h handle)
+{
+       GP_SE_ACL_EXTERN_BEGIN;
+       delete acl;
+       GP_SE_ACL_EXTERN_END;
+}
diff --git a/common/IPCHelper.cpp b/common/IPCHelper.cpp
new file mode 100644 (file)
index 0000000..e006b29
--- /dev/null
@@ -0,0 +1,430 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/socket.h>
+#ifdef USE_UNIX_DOMAIN
+#include <sys/un.h>
+#include <sys/stat.h>
+#else /* USE_UNIX_DOMAIN */
+#include <netinet/in.h>
+#endif /* USE_UNIX_DOMAIN */
+#include <fcntl.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "IPCHelper.h"
+
+#ifdef USE_UNIX_DOMAIN
+#define OMAPI_SERVER_DOMAIN "/tmp/omapi-server-domain"
+#endif /* USE_UNIX_DOMAIN */
+
+static void setNonBlockSocket(int socket)
+{
+       int flags;
+
+       flags = fcntl(socket, F_GETFL);
+
+       flags |= O_NONBLOCK;
+
+       if (fcntl(socket, F_SETFL, flags) < 0)
+       {
+               /* SCARD_DEBUG_ERR("fcntl, executing nonblock error"); */
+       }
+}
+
+namespace smartcard_service_api
+{
+       IPCHelper::IPCHelper()
+       {
+               ipcSocket = -1;
+               ioChannel = NULL;
+               watchId = 0;
+               memset(&ipcLock, 0, sizeof(ipcLock));
+               dispatcher = NULL;
+       }
+
+       IPCHelper::~IPCHelper()
+       {
+       }
+
+       gboolean IPCHelper::channelCallbackFunc(GIOChannel* channel, GIOCondition condition, gpointer data)
+       {
+               IPCHelper *helper = (IPCHelper *)data;
+               gboolean result = FALSE;
+
+               SCARD_DEBUG("channel [%p], condition [%d], data [%p]", channel, condition, data);
+
+               if (helper == NULL)
+               {
+                       SCARD_DEBUG_ERR("ipchelper is null");
+                       return result;
+               }
+
+               if ((G_IO_ERR & condition) || (G_IO_HUP & condition))
+               {
+                       result = helper->handleIOErrorCondition(channel, condition);
+               }
+               else if (G_IO_NVAL & condition)
+               {
+                       result = helper->handleInvalidSocketCondition(channel, condition);
+               }
+               else if (G_IO_IN & condition)
+               {
+                       result = helper->handleIncomingCondition(channel, condition);
+               }
+
+               return result;
+       }
+
+       bool IPCHelper::createListenSocket()
+       {
+               GIOCondition condition = (GIOCondition)(G_IO_ERR | G_IO_HUP | G_IO_IN);
+               struct sockaddr_un saddrun_rv;
+
+               if (ipcSocket >= 0)
+                       return true;
+
+               memset(&saddrun_rv, 0, sizeof(struct sockaddr_un));
+
+               unlink(OMAPI_SERVER_DOMAIN);
+
+               ipcSocket = socket(AF_UNIX, SOCK_STREAM, 0);
+               if (ipcSocket == -1)
+               {
+                       SCARD_DEBUG_ERR("get socket is failed");
+                       return false;
+               }
+
+               ::setNonBlockSocket(ipcSocket);
+
+               saddrun_rv.sun_family = AF_UNIX;
+               strncpy(saddrun_rv.sun_path, OMAPI_SERVER_DOMAIN, sizeof(saddrun_rv.sun_path) - 1);
+
+               if (bind(ipcSocket, (struct sockaddr *)&saddrun_rv, sizeof(saddrun_rv)) < 0)
+               {
+                       SCARD_DEBUG_ERR("bind is failed \n");
+                       goto ERROR;
+               }
+
+               if (chmod(OMAPI_SERVER_DOMAIN, 0777) < 0)
+               {
+                       SCARD_DEBUG_ERR("can not change permission of UNIX DOMAIN file");
+                       goto ERROR;
+               }
+
+               if (listen(ipcSocket, IPC_SERVER_MAX_CLIENT) < 0)
+               {
+                       SCARD_DEBUG_ERR("listen is failed \n");
+                       goto ERROR;
+               }
+
+               if ((ioChannel = g_io_channel_unix_new(ipcSocket)) != NULL)
+               {
+                       if ((watchId = g_io_add_watch(ioChannel, condition, &IPCHelper::channelCallbackFunc, this)) < 1)
+                       {
+                               SCARD_DEBUG_ERR(" g_io_add_watch is failed \n");
+                               goto ERROR;
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR(" g_io_channel_unix_new is failed \n");
+                       goto ERROR;
+               }
+
+#ifdef SECURITY_SERVER
+               gid = security_server_get_gid(NET_NFC_MANAGER_OBJECT);
+               if(gid == 0)
+               {
+                       SCARD_DEBUG("get gid from security server is failed. this object is not allowed by security server");
+                       goto ERROR;
+               }
+
+               if((cookies_size = security_server_get_cookie_size()) != 0)
+               {
+                       if((cookies = (char *)calloc(1, cookies_size)) == NULL)
+                       {
+                               goto ERROR;
+                       }
+               }
+#endif
+
+               SCARD_DEBUG("server ipc is initialized");
+
+               return true;
+ERROR :
+               if (watchId != (uint32_t)-1)
+               {
+                       g_source_remove(watchId);
+                       watchId = -1;
+               }
+
+               if (ioChannel != NULL)
+               {
+                       g_io_channel_unref(ioChannel);
+                       ioChannel = NULL;
+               }
+
+               if (ipcSocket != -1)
+               {
+                       shutdown(ipcSocket, SHUT_RDWR);
+                       close(ipcSocket);
+
+                       ipcSocket = -1;
+               }
+
+               return false;
+       }
+
+       bool IPCHelper::createConnectSocket()
+       {
+               GIOCondition condition = (GIOCondition) (G_IO_ERR | G_IO_HUP | G_IO_IN);
+
+               SCARD_BEGIN();
+
+               if (ipcSocket >= 0)
+                       return true;
+
+               pthread_mutex_lock(&ipcLock);
+
+               struct sockaddr_un saddrun_rv;
+               socklen_t len_saddr = 0;
+
+               memset(&saddrun_rv, 0, sizeof(struct sockaddr_un));
+
+               ipcSocket = socket(AF_UNIX, SOCK_STREAM, 0);
+               if (ipcSocket == -1)
+               {
+                       SCARD_DEBUG_ERR("get socket is failed \n");
+                       pthread_mutex_unlock(&ipcLock);
+
+                       SCARD_END();
+
+                       return false;
+               }
+
+               SCARD_DEBUG("socket is created");
+
+               ::setNonBlockSocket(ipcSocket);
+
+               saddrun_rv.sun_family = AF_UNIX;
+               strncpy(saddrun_rv.sun_path, OMAPI_SERVER_DOMAIN, sizeof(saddrun_rv.sun_path) - 1);
+
+               len_saddr = sizeof(saddrun_rv.sun_family) + strlen(OMAPI_SERVER_DOMAIN);
+
+               if ((connect(ipcSocket, (struct sockaddr *)&saddrun_rv, len_saddr)) < 0)
+               {
+                       SCARD_DEBUG_ERR("error is occured");
+                       pthread_mutex_unlock(&ipcLock);
+                       goto ERROR;
+               }
+
+               pthread_mutex_unlock(&ipcLock);
+
+               if ((ioChannel = g_io_channel_unix_new(ipcSocket)) != NULL)
+               {
+                       if ((watchId = g_io_add_watch(ioChannel, condition, &IPCHelper::channelCallbackFunc, this)) < 1)
+                       {
+                               SCARD_DEBUG_ERR(" g_io_add_watch is failed \n");
+                               goto ERROR;
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR(" g_io_channel_unix_new is failed \n");
+                       goto ERROR;
+               }
+
+               SCARD_DEBUG("socket and g io channel is binded");
+
+               SCARD_END();
+
+               return true;
+
+ERROR :
+               SCARD_DEBUG_ERR("error while initializing client ipc");
+
+               if(watchId != 0)
+               {
+                       g_source_remove(watchId);
+                       watchId = 0;
+               }
+
+               if(ioChannel != NULL)
+               {
+                       g_io_channel_unref(ioChannel);
+                       ioChannel = NULL;
+               }
+
+               if (ipcSocket != -1)
+               {
+                       shutdown(ipcSocket, SHUT_RDWR);
+                       close(ipcSocket);
+                       ipcSocket = -1;
+               }
+
+               SCARD_END();
+
+               return false;
+       }
+
+       bool IPCHelper::sendMessage(Message *msg)
+       {
+               if (ipcSocket == -1)
+                       return false;
+
+               return sendMessage(ipcSocket, msg);
+       }
+
+       bool IPCHelper::sendMessage(int socket, Message *msg)
+       {
+               bool result = false;
+               ByteArray stream;
+               unsigned int length = 0;
+
+               stream = msg->serialize();
+               length = stream.getLength();
+
+               SCARD_DEBUG(">>>[SEND]>>> socket [%d], msg [%d], length [%d]", socket, msg->message, length);
+
+               if (length > 0)
+               {
+                       int sentBytes = 0;
+
+                       /* send 4 bytes (length) */
+                       pthread_mutex_lock(&ipcLock);
+                       sentBytes = send(socket, &length, sizeof(length), 0);
+                       pthread_mutex_unlock(&ipcLock);
+                       if (sentBytes == sizeof(length))
+                       {
+                               unsigned int current = 0;
+
+                               /* send message */
+                               pthread_mutex_lock(&ipcLock);
+                               do
+                               {
+                                       sentBytes = send(socket, stream.getBuffer(current), length - current, 0);
+                                       if (sentBytes > 0)
+                                               current += sentBytes;
+                               }
+                               while (current < length);
+                               pthread_mutex_unlock(&ipcLock);
+
+                               result = true;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("send failed, sentBytes [%d]", sentBytes);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("stream length is zero");
+               }
+
+               return result;
+       }
+
+       Message *IPCHelper::retrieveMessage()
+       {
+               return retrieveMessage(ipcSocket);
+       }
+
+       Message *IPCHelper::retrieveMessage(int socket)
+       {
+               Message *msg = NULL;
+               unsigned int length = 0;
+               int readBytes = 0;
+
+               SCARD_BEGIN();
+
+               /* read 4 bytes (length) */
+               pthread_mutex_lock(&ipcLock);
+               readBytes = recv(socket, &length, sizeof(length), 0);
+               pthread_mutex_unlock(&ipcLock);
+               if (readBytes == sizeof(length))
+               {
+                       if (length > 0)
+                       {
+                               unsigned char *buffer = NULL;
+
+                               /* prepare buffer */
+                               buffer = new unsigned char[length];
+                               if (buffer != NULL)
+                               {
+                                       int retry = 0;
+                                       unsigned int current = 0;
+
+                                       /* read message */
+                                       pthread_mutex_lock(&ipcLock);
+                                       do
+                                       {
+                                               readBytes = recv(socket, buffer + current, length - current, 0);
+                                               if (readBytes > 0)
+                                                       current += readBytes;
+                                               retry++;
+                                       }
+                                       while (current < length);
+                                       pthread_mutex_unlock(&ipcLock);
+
+                                       msg = new Message();
+                                       if (msg != NULL)
+                                       {
+                                               msg->deserialize(buffer, length);
+
+                                               SCARD_DEBUG("<<<[RETRIEVE]<<< socket [%d], msg_length [%d]", socket, length);
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("alloc failed");
+                                       }
+
+                                       delete []buffer;
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("allocation failed");
+                               }
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("invalid length, socket = [%d], msg_length = [%d]", socket, length);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("failed to recv length, socket = [%d], readBytes [%d]", socket, readBytes);
+               }
+
+
+               SCARD_END();
+
+               return msg;
+       }
+
+       void IPCHelper::setDispatcher(DispatcherHelper *dispatcher)
+       {
+               this->dispatcher = dispatcher;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/ISO7816BERTLV.cpp b/common/ISO7816BERTLV.cpp
new file mode 100644 (file)
index 0000000..eb60ab6
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "ISO7816BERTLV.h"
+
+namespace smartcard_service_api
+{
+       ISO7816BERTLV::ISO7816BERTLV():TLVHelper()
+       {
+               tagClass = 0;
+               encoding = 0;
+       }
+
+       ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent):TLVHelper(parent)
+       {
+               parentTLV = parent;
+
+               tagClass = 0;
+               encoding = 0;
+       }
+
+       ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array):TLVHelper(array)
+       {
+               tagClass = 0;
+               encoding = 0;
+       }
+
+       ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent):TLVHelper(array, parent)
+       {
+               parentTLV = parent;
+
+               tagClass = 0;
+               encoding = 0;
+       }
+
+       ISO7816BERTLV::~ISO7816BERTLV()
+       {
+               if (childTLV != NULL)
+               {
+                       delete childTLV;
+                       childTLV = NULL;
+               }
+       }
+
+       int ISO7816BERTLV::decodeTag(unsigned char *buffer)
+       {
+               /* 0x00 is invalid tag value */
+               if (buffer[0] == 0x00)
+               {
+                       return -1;
+               }
+
+               /* first byte */
+               tagClass = (buffer[0] & 0xE0) >> 6;
+               encoding = (buffer[0] & 0x20) >> 5;
+
+               currentT = buffer[0];
+
+               if ((buffer[0] & 0x1F) < 0x1F)
+               {
+                       return 1;
+               }
+
+               /* second byte */
+               currentT = (currentT << 8) | buffer[1];
+               if (buffer[1] & 0x80)
+               {
+                       /* third byte */
+                       if (buffer[2] & 0x80)
+                       {
+                               return -1;
+                       }
+
+                       currentT = (currentT << 8) | buffer[2];
+
+                       return 3;
+               }
+
+               return 2;
+       }
+
+       int ISO7816BERTLV::decodeLength(unsigned char *buffer)
+       {
+               if (buffer[0] & 0x80)
+               {
+                       uint8_t count = (buffer[0] & 0x7F);
+                       uint8_t i;
+
+                       /* count will be less than 5 */
+                       if (count > 4)
+                               return -1;
+
+                       count++; /* increse count and increase i value, too */
+
+                       for (i = 1; i < count; i++)
+                       {
+                               /* if big endian */
+                               currentL = (currentL << 8) | buffer[i];
+
+                               /* if little endian */
+                               /* currentL = currentL | (buffer[i] << (8 * (i - 1))); */
+                       }
+
+                       return count;
+               }
+               else
+               {
+                       currentL = buffer[0];
+
+                       return 1;
+               }
+       }
+
+       int ISO7816BERTLV::decodeValue(unsigned char *buffer)
+       {
+               if (currentL == 0)
+                       return 0;
+
+               currentV.setBuffer(buffer, currentL);
+
+               return currentL;
+       }
+
+       unsigned int ISO7816BERTLV::getClass()
+       {
+               return tagClass;
+       }
+
+       unsigned int ISO7816BERTLV::getEncoding()
+       {
+               return encoding;
+       }
+
+       ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, ByteArray buffer)
+       {
+               unsigned char temp_tag[3] = { 0, };
+               unsigned char temp_tag_len = 0;
+               unsigned char temp_len[5] = { 0, };
+               unsigned char temp_len_len = 0;
+               ByteArray result;
+               unsigned int total_len = 0;
+               unsigned int current = 0;
+               unsigned char *temp_buffer = NULL;
+
+               /* add tag's length */
+               if (tag > 0x7FFF)
+                       return result;
+
+               temp_tag[0] = (tagClass << 6) | (encoding << 5);
+
+               if (tag < 0x1F)
+               {
+                       temp_tag[0] |= tag;
+                       temp_tag_len = 1;
+               }
+               else
+               {
+                       temp_tag[0] |= 0x1F;
+
+                       if (tag < 0x80)
+                       {
+                               temp_tag[1] = tag;
+
+                               temp_tag_len = 2;
+                       }
+                       else
+                       {
+                               temp_tag[1] = (tag & 0x000000FF);
+                               temp_tag[2] = (tag & 0x0000FF00);
+
+                               temp_tag_len = 3;
+                       }
+               }
+
+               total_len += temp_tag_len;
+
+               /* add length's length */
+               if (buffer.getLength() < 128)
+               {
+                       temp_len[0] = buffer.getLength();
+
+                       temp_len_len = 1;
+               }
+               else
+               {
+                       temp_len[0] = 0x80;
+                       temp_len_len = 1;
+
+                       if (buffer.getLength() > 0x00FFFFFF)
+                       {
+                               temp_len[4] = (buffer.getLength() & 0xFF000000) >> 24;
+                               temp_len_len++;
+                       }
+
+                       if (buffer.getLength() > 0x0000FFFF)
+                       {
+                               temp_len[3] = (buffer.getLength() & 0x00FF0000) >> 16;
+                               temp_len_len++;
+                       }
+
+                       if (buffer.getLength() > 0x000000FF)
+                       {
+                               temp_len[2] = (buffer.getLength() & 0x0000FF00) >> 8;
+                               temp_len_len++;
+                       }
+
+                       temp_len[1] = buffer.getLength() & 0x000000FF;
+                       temp_len_len++;
+
+                       temp_len[0] |= temp_len_len;
+               }
+
+               /* add buffer's length */
+               total_len += buffer.getLength();
+
+               /* alloc new buffer */
+               temp_buffer = new unsigned char[total_len];
+               if (temp_buffer == NULL)
+               {
+                       return result;
+               }
+               memset(temp_buffer, 0, total_len);
+
+               /* fill tag */
+               memcpy(temp_buffer + current, temp_tag, temp_tag_len);
+               current += temp_tag_len;
+
+               /* fill length */
+               memcpy(temp_buffer + current, temp_len, temp_len_len);
+               current += temp_len_len;
+
+               /* fill value */
+               if (buffer.getLength() > 0)
+                       memcpy(temp_buffer + current, buffer.getBuffer(), buffer.getLength());
+
+               result.setBuffer(temp_buffer, total_len);
+
+               delete []temp_buffer;
+
+               return result;
+       }
+
+       ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length)
+       {
+               return encode(tagClass, encoding, tag, ByteArray(buffer, length));
+       }
+
+       TLVHelper *ISO7816BERTLV::getChildTLV(ByteArray data)
+       {
+               if (childTLV != NULL)
+               {
+                       delete childTLV;
+                       childTLV = NULL;
+               }
+               childTLV = new ISO7816BERTLV(data, this);
+
+               return (TLVHelper *)childTLV;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/Message.cpp b/common/Message.cpp
new file mode 100644 (file)
index 0000000..f54fbbf
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Message.h"
+
+namespace smartcard_service_api
+{
+       Message::Message()
+       {
+               message = 0;
+               param1 = 0;
+               param2 = 0;
+               error = 0;
+               caller = NULL;
+               callback = NULL;
+               userParam = NULL;
+       }
+
+       Message::~Message()
+       {
+       }
+
+       ByteArray Message::serialize()
+       {
+               ByteArray result;
+               unsigned int length = 0;
+               unsigned int dataLength = 0;
+               unsigned char *buffer = NULL;
+
+               length = sizeof(message) + sizeof(param1) + sizeof(param2) + sizeof(error) + sizeof(caller) + sizeof(callback) + sizeof(userParam);
+               if (data.getLength() > 0)
+               {
+                       dataLength = data.getLength();
+                       length += sizeof(dataLength) + data.getLength();
+               }
+
+               buffer = new unsigned char[length];
+               if (buffer != NULL)
+               {
+                       unsigned int current = 0;
+
+                       memset(buffer, 0, length);
+
+                       memcpy(buffer + current, &message, sizeof(message));
+                       current += sizeof(message);
+
+                       memcpy(buffer + current, &param1, sizeof(param1));
+                       current += sizeof(param1);
+
+                       memcpy(buffer + current, &param2, sizeof(param2));
+                       current += sizeof(param2);
+
+                       memcpy(buffer + current, &error, sizeof(error));
+                       current += sizeof(error);
+
+                       memcpy(buffer + current, &caller, sizeof(caller));
+                       current += sizeof(caller);
+
+                       memcpy(buffer + current, &callback, sizeof(callback));
+                       current += sizeof(callback);
+
+                       memcpy(buffer + current, &userParam, sizeof(userParam));
+                       current += sizeof(userParam);
+
+                       if (data.getLength() > 0)
+                       {
+                               memcpy(buffer + current, &dataLength, sizeof(dataLength));
+                               current += sizeof(dataLength);
+
+                               memcpy(buffer + current, data.getBuffer(), dataLength);
+                               current += data.getLength();
+                       }
+
+                       result.setBuffer(buffer, length);
+
+                       delete []buffer;
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("allocation failed");
+               }
+
+               return result;
+       }
+
+       void Message::deserialize(ByteArray buffer)
+       {
+               deserialize(buffer.getBuffer(), buffer.getLength());
+       }
+
+       void Message::deserialize(unsigned char *buffer, unsigned int length)
+       {
+               unsigned int current = 0;
+               unsigned int dataLength = 0;
+
+//             SCARD_DEBUG("buffer [%p], length [%d]", buffer, length);
+
+               memcpy(&message, buffer + current, sizeof(message));
+               current += sizeof(message);
+
+//             SCARD_DEBUG("message [%d]", message);
+
+               memcpy(&param1, buffer + current, sizeof(param1));
+               current += sizeof(param1);
+
+//             SCARD_DEBUG("param1 [%d]", param1);
+
+               memcpy(&param2, buffer + current, sizeof(param2));
+               current += sizeof(param2);
+
+//             SCARD_DEBUG("param2 [%d]", param2);
+
+               memcpy(&error, buffer + current, sizeof(error));
+               current += sizeof(error);
+
+               memcpy(&caller, buffer + current, sizeof(caller));
+               current += sizeof(caller);
+
+               memcpy(&callback, buffer + current, sizeof(callback));
+               current += sizeof(callback);
+
+               memcpy(&userParam, buffer + current, sizeof(userParam));
+               current += sizeof(userParam);
+
+//             SCARD_DEBUG("userContext [%p]", userContext);
+
+               if (current + sizeof(dataLength) < length)
+               {
+                       memcpy(&dataLength, buffer + current, sizeof(dataLength));
+                       current += sizeof(dataLength);
+
+//                     SCARD_DEBUG("dataLength [%d]", dataLength);
+
+                       data.setBuffer(buffer + current, dataLength);
+                       current += dataLength;
+               }
+       }
+
+       const char *Message::toString()
+       {
+               const char *msg = NULL;
+
+               memset(&text, 0, sizeof(text));
+
+               switch (message)
+               {
+               case MSG_REQUEST_READERS :
+                       msg = "MSG_REQUEST_READERS";
+                       break;
+
+//             case MSG_REQUEST_READER_NAME :
+//                     msg = "MSG_REQUEST_READER_NAME";
+//                     break;
+//
+               case MSG_REQUEST_OPEN_SESSION :
+                       msg = "MSG_REQUEST_OPEN_SESSION";
+                       break;
+
+               case MSG_REQUEST_CLOSE_SESSION :
+                       msg = "MSG_REQUEST_CLOSE_CHANNEL";
+                       break;
+
+               case MSG_REQUEST_OPEN_CHANNEL :
+                       msg = "MSG_REQUEST_OPEN_CHANNEL";
+                       break;
+
+               case MSG_REQUEST_CLOSE_CHANNEL :
+                       msg = "MSG_REQUEST_CLOSE_CHANNEL";
+                       break;
+
+               case MSG_REQUEST_GET_ATR :
+                       msg = "MSG_REQUEST_GET_ATR";
+                       break;
+
+               case MSG_REQUEST_TRANSMIT :
+                       msg = "MSG_REQUEST_TRANSMIT";
+                       break;
+
+               case MSG_REQUEST_GET_CHANNEL_COUNT :
+                       msg = "MSG_REQUEST_GET_CHANNEL_COUNT";
+                       break;
+
+               default :
+                       msg = "Unknown";
+                       break;
+               }
+
+               snprintf(text, sizeof(text), "Message [%s, %d], param1 [%d], param2 [%d], error [%d], caller [%p], callback [%p], userParam [%p], data length [%d]", msg, message, param1, param2, error, caller, callback, userParam, data.getLength());
+
+               return (const char *)text;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/NumberStream.cpp b/common/NumberStream.cpp
new file mode 100644 (file)
index 0000000..3246b15
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "NumberStream.h"
+
+namespace smartcard_service_api
+{
+       NumberStream::NumberStream(const ByteArray &T)
+       {
+               setBuffer(T.getBuffer(), T.getLength());
+       }
+
+       unsigned int NumberStream::getBigEndianNumber()
+       {
+               return getBigEndianNumber(*this);
+       }
+
+       unsigned int NumberStream::getLittleEndianNumber()
+       {
+               return getLittleEndianNumber(*this);
+       }
+
+       NumberStream &NumberStream::operator =(const ByteArray &T)
+       {
+               if (this != &T)
+               {
+                       setBuffer(T.getBuffer(), T.getLength());
+               }
+
+               return *this;
+       }
+
+       NumberStream &NumberStream::operator =(const NumberStream &T)
+       {
+               if (this != &T)
+               {
+                       setBuffer(T.getBuffer(), T.getLength());
+               }
+
+               return *this;
+       }
+
+       unsigned int NumberStream::getBigEndianNumber(const ByteArray &T)
+       {
+               int i, len;
+               unsigned int result = 0;
+
+               len = (T.getLength() < 4) ? T.getLength() : 4;
+
+               for (i = 0; i < len; i++)
+               {
+                       result = (result << 8) | T.getAt(i);
+               }
+
+               return result;
+       }
+
+       unsigned int NumberStream::getLittleEndianNumber(const ByteArray &T)
+       {
+               int i, len;
+               unsigned int result = 0;
+
+               len = (T.getLength() < 4) ? T.getLength() : 4;
+
+               for (i = 0; i < len; i++)
+               {
+                       result = result | (T.getAt(i) << (i * 8));
+               }
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/OpensslHelper.cpp b/common/OpensslHelper.cpp
new file mode 100644 (file)
index 0000000..5241bad
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ByteArray.h"
+#include "OpensslHelper.h"
+
+namespace smartcard_service_api
+{
+       bool OpensslHelper::encodeBase64String(const ByteArray &buffer, ByteArray &result, bool newLineChar)
+       {
+               bool ret = false;
+               BUF_MEM *bptr;
+               BIO *b64, *bmem;
+
+               if (buffer.getLength() == 0)
+               {
+                       return ret;
+               }
+
+               b64 = BIO_new(BIO_f_base64());
+               bmem = BIO_new(BIO_s_mem());
+
+               if (newLineChar == false)
+                       BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+
+               b64 = BIO_push(b64, bmem);
+
+               BIO_write(b64, buffer.getBuffer(), buffer.getLength());
+               BIO_flush(b64);
+               BIO_get_mem_ptr(b64, &bptr);
+
+               result.setBuffer((unsigned char *)bptr->data, bptr->length);
+
+               BIO_free_all(b64);
+
+               ret = true;
+
+               return ret;
+       }
+
+       bool OpensslHelper::decodeBase64String(const char *buffer, ByteArray &result, bool newLineChar)
+       {
+               ByteArray temp;
+
+               temp.setBuffer((unsigned char *)buffer, strlen(buffer));
+
+               return decodeBase64String(temp, result, newLineChar);
+       }
+
+       bool OpensslHelper::decodeBase64String(const ByteArray &buffer, ByteArray &result, bool newLineChar)
+       {
+               bool ret = false;
+               unsigned int length = 0;
+               char *temp;
+
+               if (buffer.getBuffer() == NULL || buffer.getLength() == 0)
+               {
+                       return ret;
+               }
+
+               length = buffer.getLength();
+
+               temp = new char[length];
+               if (temp != NULL)
+               {
+                       BIO *b64, *bmem;
+
+                       memset(temp, 0, length);
+
+                       b64 = BIO_new(BIO_f_base64());
+                       bmem = BIO_new_mem_buf(buffer.getBuffer(), length);
+                       if (newLineChar == false)
+                               BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+                       bmem = BIO_push(b64, bmem);
+
+                       length = BIO_read(bmem, temp, length);
+
+                       BIO_free_all(bmem);
+
+                       result.setBuffer((unsigned char *)temp, length);
+
+                       delete []temp;
+
+                       ret = true;
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("alloc failed");
+               }
+
+               return ret;
+       }
+
+       bool OpensslHelper::digestBuffer(const char *algorithm, const uint8_t *buffer, const uint32_t length, ByteArray &result)
+       {
+               ByteArray temp((uint8_t *)buffer, (uint32_t)length);
+
+               return digestBuffer(algorithm, temp, result);
+       }
+
+       bool OpensslHelper::digestBuffer(const char *algorithm, const ByteArray &buffer, ByteArray &result)
+       {
+               const EVP_MD *md;
+               unsigned char *temp;
+               bool ret = false;
+
+               if (algorithm == NULL || buffer.getLength() == 0)
+               {
+                       return ret;
+               }
+
+               OpenSSL_add_all_digests();
+
+               if ((md = EVP_get_digestbyname(algorithm)) != NULL)
+               {
+                       temp = new unsigned char[EVP_MAX_MD_SIZE];
+                       if (temp != NULL)
+                       {
+                               EVP_MD_CTX mdCtx;
+                               unsigned int resultLen = 0;
+
+                               memset(temp, 0, EVP_MAX_MD_SIZE);
+
+                               EVP_DigestInit(&mdCtx, md);
+                               EVP_DigestUpdate(&mdCtx, buffer.getBuffer(), buffer.getLength());
+                               EVP_DigestFinal(&mdCtx, temp, &resultLen);
+
+                               result.setBuffer(temp, resultLen);
+
+                               delete []temp;
+
+                               ret = true;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("alloc failed");
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("EVP_get_digestbyname(\"%s\") returns NULL", algorithm);
+               }
+
+               return ret;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/PKCS15.cpp b/common/PKCS15.cpp
new file mode 100644 (file)
index 0000000..ae13de5
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "PKCS15.h"
+
+namespace smartcard_service_api
+{
+       static unsigned char aid[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
+       ByteArray PKCS15::PKCS15_AID(ARRAY_AND_SIZE(aid));
+
+       PKCS15::PKCS15(Channel *channel):PKCS15Object(channel), odf(NULL)
+       {
+               int ret = 0;
+
+               if ((ret = select(PKCS15::PKCS15_AID)) == 0)
+               {
+                       SCARD_DEBUG("response : %s", selectResponse.toString());
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select failed, [%d]", ret);
+               }
+       }
+
+       PKCS15::PKCS15(Channel *channel, ByteArray selectResponse):PKCS15Object(channel, selectResponse), odf(NULL)
+       {
+       }
+
+       PKCS15::~PKCS15()
+       {
+               if (odf != NULL)
+               {
+                       delete odf;
+                       odf = NULL;
+               }
+       }
+
+       PKCS15ODF *PKCS15::getODF()
+       {
+               if (odf == NULL)
+               {
+                       odf = new PKCS15ODF(channel);
+               }
+
+               SCARD_DEBUG("odf [%p]", odf);
+
+               return odf;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/PKCS15DODF.cpp b/common/PKCS15DODF.cpp
new file mode 100644 (file)
index 0000000..61af800
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "PKCS15DODF.h"
+#include "SimpleTLV.h"
+
+namespace smartcard_service_api
+{
+//     PKCS15DODF::PKCS15DODF():PKCS15Object()
+//     {
+//
+//     }
+
+       PKCS15DODF::PKCS15DODF(unsigned int fid, Channel *channel):PKCS15Object(channel)
+       {
+               int ret = 0;
+
+               if ((ret = select(fid)) == 0)
+               {
+                       ByteArray dodfData, extra;
+
+                       SCARD_DEBUG("response : %s", selectResponse.toString());
+
+                       if ((ret = readBinary(0, 0, getFCP()->getFileSize(), dodfData)) == 0)
+                       {
+                               SCARD_DEBUG("odfData : %s", dodfData.toString());
+
+                               parseData(dodfData);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select failed, [%d]", ret);
+               }
+       }
+
+       PKCS15DODF::PKCS15DODF(ByteArray path, Channel *channel):PKCS15Object(channel)
+       {
+               int ret = 0;
+
+               if ((ret = select(path)) == 0)
+               {
+                       ByteArray dodfData, extra;
+
+                       SCARD_DEBUG("response : %s", selectResponse.toString());
+
+                       if ((ret = readBinary(0, 0, getFCP()->getFileSize(), dodfData)) == 0)
+                       {
+                               SCARD_DEBUG("dodfData : %s", dodfData.toString());
+
+                               parseData(dodfData);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select failed, [%d]", ret);
+               }
+       }
+
+       PKCS15DODF::~PKCS15DODF()
+       {
+       }
+
+       bool PKCS15DODF::parseData(ByteArray data)
+       {
+               bool result = false;
+               SimpleTLV tlv(data);
+
+               while (tlv.decodeTLV())
+               {
+                       switch (tlv.getTag())
+                       {
+                       case (unsigned int)0xA1 : /* CHOICE 1 : OidDO */
+                               {
+                                       PKCS15OID oid(tlv.getValue());
+
+                                       SCARD_DEBUG("OID DataObject");
+
+                                       pair<ByteArray, PKCS15OID> newPair(oid.getOID(), oid);
+                                       mapOID.insert(newPair);
+                               }
+                               break;
+
+                       default :
+                               SCARD_DEBUG("Unknown tlv : t [%X], l [%d], v %s", tlv.getTag(), tlv.getLength(), tlv.getValue().toString());
+                               break;
+                       }
+               }
+
+               SCARD_DEBUG("dataList.size() = %d", mapOID.size());
+
+               return result;
+       }
+
+       int PKCS15DODF::searchOID(ByteArray oid, ByteArray &data)
+       {
+               int result = -1;
+               map<ByteArray, PKCS15OID>::iterator item;
+
+               item = mapOID.find(oid);
+               if (item != mapOID.end())
+               {
+                       data = item->second.getPath();
+                       result = 0;
+               }
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/PKCS15ODF.cpp b/common/PKCS15ODF.cpp
new file mode 100644 (file)
index 0000000..0710e65
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "PKCS15ODF.h"
+#include "SimpleTLV.h"
+#include "NumberStream.h"
+
+namespace smartcard_service_api
+{
+//     PKCS15ODF::PKCS15ODF():PKCS15Object()
+//     {
+//
+//     }
+
+       PKCS15ODF::PKCS15ODF(Channel *channel):PKCS15Object(channel), dodf(NULL)
+       {
+               int ret = 0;
+
+               if ((ret = select(PKCS15ODF::ODF_FID)) == 0)
+               {
+                       ByteArray odfData, extra;
+
+                       SCARD_DEBUG("response : %s", selectResponse.toString());
+
+                       if ((ret = readBinary(0, 0, getFCP()->getFileSize(), odfData)) == 0)
+                       {
+                               SCARD_DEBUG("odfData : %s", odfData.toString());
+
+                               parseData(odfData);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select failed, [%d]", ret);
+               }
+       }
+
+       PKCS15ODF::PKCS15ODF(Channel *channel, ByteArray selectResponse):PKCS15Object(channel, selectResponse), dodf(NULL)
+       {
+               int ret = 0;
+               ByteArray odfData;
+
+               if ((ret = readBinary(0, 0, 0, odfData)) == 0)
+               {
+                       SCARD_DEBUG("odfData : %s", odfData.toString());
+
+                       parseData(odfData);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("readBinary failed, [%d]", ret);
+               }
+       }
+
+       PKCS15ODF::~PKCS15ODF()
+       {
+               if (dodf != NULL)
+               {
+                       delete dodf;
+                       dodf = NULL;
+               }
+       }
+
+       bool PKCS15ODF::parseData(ByteArray data)
+       {
+               bool result = false;
+               SimpleTLV tlv(data);
+
+               while (tlv.decodeTLV())
+               {
+                       switch (tlv.getTag())
+                       {
+                       case (unsigned int)0xA7 ://PKCS15ODF::TAG_DODF :
+                               {
+                                       ByteArray dodf;
+
+                                       SCARD_DEBUG("TAG_DODF");
+
+                                       dodf = PKCS15Object::getOctetStream(tlv.getValue());
+
+                                       SCARD_DEBUG("path : %s", dodf.toString());
+
+                                       pair<unsigned int, ByteArray> newPair(tlv.getTag(), dodf);
+                                       dataList.insert(newPair);
+                               }
+                               break;
+
+                       case (unsigned int)0xA5 ://PKCS15ODF::TAG_TOKENINFO :
+                               {
+                                       ByteArray tokeninfo;
+
+                                       SCARD_DEBUG("TAG_TOKENINFO");
+
+                                       tokeninfo = PKCS15Object::getOctetStream(tlv.getValue());
+
+                                       SCARD_DEBUG("path : %s", tokeninfo.toString());
+
+                                       pair<unsigned int, ByteArray> newPair(tlv.getTag(), tokeninfo);
+                                       dataList.insert(newPair);
+                               }
+                               break;
+
+                       default :
+                               SCARD_DEBUG("Unknown tlv : t [%X], l [%d], v %s", tlv.getTag(), tlv.getLength(), tlv.getValue().toString());
+                               break;
+                       }
+
+               }
+
+               SCARD_DEBUG("dataList.size() = %d", dataList.size());
+
+               return result;
+       }
+
+       PKCS15DODF *PKCS15ODF::getDODF()
+       {
+               map<unsigned int, ByteArray>::iterator item;
+
+               if (dodf == NULL)
+               {
+                       item = dataList.find((unsigned int)0xA7/*PKCS15ODF::TAG_DODF*/);
+                       if (item != dataList.end())
+                       {
+                               NumberStream num(item->second);
+                               unsigned int fid = num.getLittleEndianNumber();
+
+                               SCARD_DEBUG("fid [%X]", fid);
+
+                               dodf = new PKCS15DODF(fid, channel);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("[%02X] is not found. total [%d]", TAG_DODF, dataList.size());
+                       }
+               }
+
+               SCARD_DEBUG("dodf [%p]", dodf);
+
+               return dodf;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/PKCS15OID.cpp b/common/PKCS15OID.cpp
new file mode 100644 (file)
index 0000000..645796f
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "PKCS15.h"
+#include "PKCS15OID.h"
+#include "SimpleTLV.h"
+
+namespace smartcard_service_api
+{
+       PKCS15OID::PKCS15OID(ByteArray data)
+       {
+               parseOID(data);
+       }
+
+       PKCS15OID::~PKCS15OID()
+       {
+       }
+
+       bool PKCS15OID::parseOID(ByteArray data)
+       {
+               bool result = false;
+               SimpleTLV tlv(data);
+
+               SCARD_BEGIN();
+
+               while (tlv.decodeTLV() == true)
+               {
+                       switch (tlv.getTag())
+                       {
+                       case PKCS15::TAG_SEQUENCE :
+                               if (tlv.getLength() > 0)
+                               {
+                                       /* common object attribute */
+                                       tlv.enterToValueTLV();
+                                       if (tlv.decodeTLV() == true && tlv.getTag() == 0x0C) /* ?? */
+                                       {
+                                               name = tlv.getValue();
+                                               SCARD_DEBUG("name : %s", name.toString());
+                                       }
+                                       tlv.returnToParentTLV();
+                               }
+                               else
+                               {
+                                       /* common object attribute */
+                                       /* if you want to use this value, add member variable and parse here */
+//                                     SCARD_DEBUG_ERR("common object attribute is empty");
+                               }
+                               break;
+
+                       case 0xA0 : /* CHOICE 0 : External Oid??? */
+                               SCARD_DEBUG_ERR("oid doesn't exist");
+                               break;
+
+                       case 0xA1 : /* CHOICE 1 : OidDO */
+                               tlv.enterToValueTLV();
+
+                               /* attribute */
+                               if (tlv.decodeTLV() == true && tlv.getTag() == PKCS15::TAG_SEQUENCE)
+                               {
+                                       tlv.enterToValueTLV();
+
+                                       /* oid */
+                                       if (tlv.decodeTLV() == true && tlv.getTag() == (unsigned int)0x06) /* ?? */
+                                       {
+                                               oid = tlv.getValue();
+
+                                               SCARD_DEBUG("oid : %s", oid.toString());
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("oid is empty");
+                                       }
+
+                                       /* path */
+                                       if (tlv.decodeTLV() == true && tlv.getTag() == PKCS15::TAG_SEQUENCE)
+                                       {
+                                               path = SimpleTLV::getOctetString(tlv.getValue());
+
+                                               SCARD_DEBUG("path : %s", path.toString());
+
+                                               result = true;
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("sequence is empty");
+                                       }
+
+                                       tlv.returnToParentTLV();
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("common dataobject attribute is empty");
+                               }
+                               tlv.returnToParentTLV();
+
+                               break;
+
+                       default :
+                               SCARD_DEBUG_ERR("Unknown tag : 0x%02X", tlv.getTag());
+                               break;
+                       }
+               }
+
+               SCARD_END();
+
+               return result;
+       }
+
+       ByteArray PKCS15OID::getOID()
+       {
+               return oid;
+       }
+
+       ByteArray PKCS15OID::getName()
+       {
+               return name;
+       }
+
+       ByteArray PKCS15OID::getPath()
+       {
+               return path;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/PKCS15Object.cpp b/common/PKCS15Object.cpp
new file mode 100644 (file)
index 0000000..ee2d57e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "SimpleTLV.h"
+#include "PKCS15Object.h"
+
+namespace smartcard_service_api
+{
+//     PKCS15Object::PKCS15Object():FileObject()
+//     {
+//     }
+
+       PKCS15Object::PKCS15Object(Channel *channel):FileObject(channel)
+       {
+       }
+
+       PKCS15Object::PKCS15Object(Channel *channel, ByteArray selectResponse):FileObject(channel, selectResponse)
+       {
+       }
+
+       PKCS15Object::~PKCS15Object()
+       {
+       }
+
+       ByteArray PKCS15Object::getOctetStream(const ByteArray &data)
+       {
+               ByteArray result;
+               SimpleTLV tlv(data);
+
+               if (tlv.decodeTLV() && tlv.getTag() == TAG_SEQUENCE)
+               {
+                       tlv.enterToValueTLV();
+
+                       if (tlv.decodeTLV() && tlv.getTag() == TAG_OCTET_STREAM)
+                       {
+                               result = tlv.getValue();
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("TAG_OCTET_STREAM not found");
+                       }
+                       tlv.returnToParentTLV();
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("TAG_SEQUENCE not found");
+               }
+
+               return result;
+       }
+
+
+} /* namespace smartcard_service_api */
diff --git a/common/PKCS15Path.cpp b/common/PKCS15Path.cpp
new file mode 100644 (file)
index 0000000..4ee65a1
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "PKCS15Path.h"
+
+namespace smartcard_service_api
+{
+       PKCS15Path::PKCS15Path()
+       {
+       }
+
+       PKCS15Path::~PKCS15Path()
+       {
+       }
+
+//     PKCS15Path(ByteArray &data);
+//     PKCS15Path(ByteArray path, int index);
+//     PKCS15Path(unsigned char *path, unsigned int length, int index);
+//     ~PKCS15Path();
+//
+//     bool PKCS15Path::parseData(ByteArray &data)
+//     {
+//             SimpleTLV tlv(data);
+//
+//             if (tlv.decodeTLV() == true && tlv.getTag() == 0x30) /* SEQUENCE */
+//             {
+//                     /* get path */
+//                     path = tlv.getOctetString();
+//
+//                     if (tlv.decodeTLV())
+//                     index = t
+//
+//             }
+//     }
+//
+//     int getPath(ByteArray &path);
+//     bool hasIndexLength();
+//     int getIndex();
+//     unsigned int getLength();
+//     int encode(ByteArray &result);
+
+} /* namespace smartcard_service_api */
diff --git a/common/PKCS15TokenInfo.cpp b/common/PKCS15TokenInfo.cpp
new file mode 100644 (file)
index 0000000..1022347
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "PKCS15TokenInfo.h"
+
+namespace smartcard_service_api
+{
+       PKCS15TokenInfo::PKCS15TokenInfo(Channel *channel):PKCS15Object(channel)
+       {
+       }
+
+       PKCS15TokenInfo::~PKCS15TokenInfo()
+       {
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/ProviderHelper.cpp b/common/ProviderHelper.cpp
new file mode 100644 (file)
index 0000000..61161eb
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ProviderHelper.h"
+
+namespace smartcard_service_api
+{
+//     ProviderHelper::ProviderHelper()
+//     {
+//     }
+
+       ProviderHelper::ProviderHelper(Channel *channel)
+       {
+               this->channel = NULL;
+
+               if (channel == NULL)
+               {
+                       SCARD_DEBUG_ERR("invalid channel");
+                       return;
+               }
+
+               this->channel = channel;
+       }
+
+       ProviderHelper::~ProviderHelper()
+       {
+       }
+
+       Channel *ProviderHelper::getChannel()
+       {
+               return channel;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/ReaderHelper.cpp b/common/ReaderHelper.cpp
new file mode 100644 (file)
index 0000000..aed14c3
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ReaderHelper.h"
+
+namespace smartcard_service_api
+{
+       ReaderHelper::ReaderHelper()
+       {
+               memset(name, 0, sizeof(name));
+               seService = NULL;
+       }
+
+       ReaderHelper::~ReaderHelper()
+       {
+       }
+
+       const char *ReaderHelper::getName()
+       {
+               return (const char *)name;
+       }
+
+       SEServiceHelper *ReaderHelper::getSEService()
+       {
+               return seService;
+       }
+
+       bool ReaderHelper::isSecureElementPresent()
+       {
+               /* get checkse() symbol of se library (dlsym) */
+               /* invoke checkse() and return result */
+
+               return true /* checkse() */;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/Record.cpp b/common/Record.cpp
new file mode 100644 (file)
index 0000000..e31cd98
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Record.h"
+
+namespace smartcard_service_api
+{
+       Record::Record()
+       {
+       }
+
+       Record::~Record()
+       {
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/SEServiceHelper.cpp b/common/SEServiceHelper.cpp
new file mode 100644 (file)
index 0000000..9bab511
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "SEServiceHelper.h"
+
+namespace smartcard_service_api
+{
+       SEServiceHelper::SEServiceHelper()
+       {
+               connected = false;
+       }
+
+       SEServiceHelper::~SEServiceHelper()
+       {
+               shutdown();
+       }
+
+       vector<ReaderHelper *> SEServiceHelper::getReaders()
+       {
+               return readers;
+       }
+
+       bool SEServiceHelper::isConnected()
+       {
+               return (readers.size() > 0);
+       }
+
+       void SEServiceHelper::shutdown()
+       {
+               uint32_t i;
+
+               for (i = 0; i < readers.size(); i++)
+               {
+                       readers[i]->closeSessions();
+               }
+
+               readers.clear();
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/Serializable.cpp b/common/Serializable.cpp
new file mode 100644 (file)
index 0000000..2920264
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Serializable.h"
+
+namespace smartcard_service_api
+{
+} /* namespace smartcard_service_api */
diff --git a/common/SessionHelper.cpp b/common/SessionHelper.cpp
new file mode 100644 (file)
index 0000000..08fb34d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "SessionHelper.h"
+#include "ReaderHelper.h"
+
+namespace smartcard_service_api
+{
+       SessionHelper::SessionHelper(ReaderHelper *reader)
+       {
+               closed = true;
+
+               if (reader == NULL)
+                       return;
+
+               this->reader = reader;
+       }
+
+       SessionHelper::~SessionHelper()
+       {
+       }
+
+       ReaderHelper *SessionHelper::getReader()
+       {
+               return reader;
+       }
+
+//     ByteArray SessionHelper::getATR()
+//     {
+//             return atr;
+//     }
+
+       bool SessionHelper::isClosed()
+       {
+               return closed;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/SignatureHelper.cpp b/common/SignatureHelper.cpp
new file mode 100644 (file)
index 0000000..58262b6
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <list>
+#include <string>
+
+/* SLP library header */
+#include "dpl/wrt-dao-ro/WrtDatabase.h"
+#include "dpl/wrt-dao-ro/widget_dao_read_only.h"
+#include "dpl/wrt-dao-ro/wrt_db_types.h"
+#include "dpl/db/sql_connection.h"
+#include "aul.h"
+
+/* local header */
+#include "Debug.h"
+#include "SignatureHelper.h"
+#include "OpensslHelper.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+using namespace WrtDB;
+using namespace std;
+
+namespace smartcard_service_api
+{
+       int SignatureHelper::getProcessName(int pid, char *processName, uint32_t length)
+       {
+               int ret = -1;
+               FILE *file = NULL;
+               char filename[1024] = { 0, };
+
+               if (pid < 0 || processName == NULL || length == 0)
+                       return ret;
+
+               snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
+               SCARD_DEBUG("pid : %d, file name : %s", pid, filename);
+
+               if ((file = fopen(filename, "r")) != NULL)
+               {
+                       char *name = NULL;
+                       ByteArray hash, result;
+                       size_t len;
+
+                       memset(filename, 0, sizeof(filename));
+                       len = fread(filename, 1, sizeof(filename) - 1, file);
+                       fclose(file);
+
+                       name = basename(filename);
+                       SCARD_DEBUG("file name : %s", name);
+
+                       OpensslHelper::digestBuffer("sha256", (uint8_t *)name, strlen(name), hash);
+                       SCARD_DEBUG("digest [%d] : %s", hash.getLength(), hash.toString());
+
+                       OpensslHelper::encodeBase64String(hash, result, false);
+
+                       memset(processName, 0, length);
+                       memcpy(processName, result.getBuffer(), (result.getLength() < length - 1) ? result.getLength() : length - 1);
+
+                       ret = 0;
+               }
+               else
+               {
+
+               }
+
+               return ret;
+       }
+
+       ByteArray SignatureHelper::getCertificationHash(const char *packageName)
+       {
+               ByteArray result;
+               list<string>::iterator item;
+               CertificateChainList certList;
+
+               SCARD_DEBUG("package name : %s", packageName);
+
+               try
+               {
+                       WrtDatabase::attachToThreadRO();
+
+                       int handle = WidgetDAOReadOnly::getHandle(DPL::FromUTF8String(packageName));
+                       WidgetDAOReadOnly widget(handle);
+                       certList = widget.getWidgetCertificate();
+
+                       SCARD_DEBUG("certList.size [%d]", certList.size());
+
+                       WrtDatabase::detachFromThread();
+               }
+               catch(...)
+               {
+                       SCARD_DEBUG_ERR("exception occurs!!!");
+                       return result;
+               }
+
+               if (certList.size() > 0)
+               {
+                       string certString;
+                       ByteArray certArray;
+
+#if 0
+                       for (item = certList.begin(); item != certList.end(); item++)
+                       {
+                               SCARD_DEBUG("certList : %s", item->data());
+                       }
+#endif
+                       certString = certList.back();
+                       SCARD_DEBUG("certString[%d] :\n%s", certString.size(), certString.data());
+
+                       /* base64 decoding */
+                       if (OpensslHelper::decodeBase64String(certString.data(), certArray) == true)
+                       {
+                               int count = 0, offset = 0, length;
+//                             int i;
+                               ByteArray cert;
+
+                               SCARD_DEBUG("decoded[%d] : %s", certArray.getLength(), certArray.toString());
+
+                               /* get count */
+                               count = *(int *)certArray.getBuffer();
+                               offset += sizeof(int);
+                               SCARD_DEBUG("certificate count [%d]", count);
+
+//                             for (i = 0; i < count; i++)
+                               if (count > 0)
+                               {
+                                       /* certificate length */
+                                       length = *(int *)certArray.getBuffer(offset);
+                                       offset += sizeof(int);
+                                       SCARD_DEBUG("certificate length [%d]", length);
+
+                                       /* certificate byte stream */
+                                       cert.setBuffer(certArray.getBuffer(offset), length);
+                                       offset += length;
+
+                                       SCARD_DEBUG("certificate buffer [%d] : %s", cert.getLength(), cert.toString());
+
+                                       /* sha1 digest */
+                                       if (OpensslHelper::digestBuffer("sha1", cert, result) == true)
+                                       {
+                                               SCARD_DEBUG("digest[%d] : %s", result.getLength(), result.toString());
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("digestBuffer failed");
+                                       }
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("invalid certificate count [%d]", count);
+                               }
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("decodeBase64String failed");
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("certList.size is zero");
+               }
+
+               return result;
+       }
+
+       ByteArray SignatureHelper::getCertificationHash(int pid)
+       {
+               ByteArray result;
+               int error = 0;
+               char pkgName[256] = { 0, };
+
+               if ((error = aul_app_get_pkgname_bypid(pid, pkgName, sizeof(pkgName))) == 0)
+               {
+                       result = getCertificationHash(pkgName);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("aul_app_get_pkgname_bypid failed [%d]", error);
+               }
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
+
+/* export C API */
+using namespace smartcard_service_api;
+
+EXTERN_API int signature_helper_get_certificate_hash(const char *packageName, uint8_t *hash, uint32_t *length)
+{
+       int ret = -1;
+       ByteArray result;
+
+       if (packageName == NULL || strlen(packageName) == 0 || hash == NULL || length == NULL || *length < 20)
+               return ret;
+
+       result = SignatureHelper::getCertificationHash(packageName);
+
+       if (result.isEmpty() == false)
+       {
+               memcpy(hash, result.getBuffer(), (result.getLength() < *length) ? result.getLength() : *length);
+               *length = result.getLength();
+
+               ret = 0;
+       }
+       else
+       {
+               ret = -1;
+       }
+
+       return ret;
+}
+
+EXTERN_API int signature_helper_get_certificate_hash_by_pid(int pid, uint8_t *hash, uint32_t *length)
+{
+       int ret = -1;
+       ByteArray result;
+
+       if (pid < 0 || hash == NULL || length == NULL || *length < 20)
+               return ret;
+
+       result = SignatureHelper::getCertificationHash(pid);
+
+       if (result.isEmpty() == false && result.getLength() < *length)
+       {
+               memcpy(hash, result.getBuffer(), result.getLength());
+               *length = result.getLength();
+
+               ret = 0;
+       }
+       else
+       {
+               ret = -1;
+       }
+
+       return ret;
+}
+
+EXTERN_API int signature_helper_get_process_name(int pid, char *processName, uint32_t length)
+{
+       int ret = -1;
+
+       if (pid < 0 || processName == NULL || length == 0)
+               return ret;
+
+       ret = SignatureHelper::getProcessName(pid, processName, length);
+
+       return ret;
+}
+
diff --git a/common/SimpleTLV.cpp b/common/SimpleTLV.cpp
new file mode 100644 (file)
index 0000000..84da755
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "SimpleTLV.h"
+
+namespace smartcard_service_api
+{
+       SimpleTLV::SimpleTLV():TLVHelper()
+       {
+       }
+
+       SimpleTLV::SimpleTLV(TLVHelper *parent):TLVHelper(parent)
+       {
+               parentTLV = parent;
+       }
+
+       SimpleTLV::SimpleTLV(const ByteArray &array):TLVHelper(array)
+       {
+       }
+
+       SimpleTLV::SimpleTLV(const ByteArray &array, TLVHelper *parent):TLVHelper(array, parent)
+       {
+               parentTLV = parent;
+       }
+
+       SimpleTLV::~SimpleTLV()
+       {
+               if (childTLV != NULL)
+               {
+                       delete childTLV;
+                       childTLV = NULL;
+               }
+       }
+
+       int SimpleTLV::decodeTag(unsigned char *buffer)
+       {
+               /* 0x00 or 0xFF is invalid tag value */
+               if (buffer[0] == 0x00 || buffer[0] == 0xFF)
+               {
+                       return -1;
+               }
+
+               currentT = buffer[0];
+
+               return 1;
+       }
+
+       int SimpleTLV::decodeLength(unsigned char *buffer)
+       {
+               int count = 0;
+
+               if (buffer[0] == 0xFF)
+               {
+                       /* 3 bytes length */
+                       currentL = (buffer[1] << 8) | buffer[2];
+                       count = 3;
+               }
+               else
+               {
+                       /* 1 byte length */
+                       currentL = buffer[0];
+                       count = 1;
+               }
+
+               return count;
+       }
+
+       int SimpleTLV::decodeValue(unsigned char *buffer)
+       {
+               if (currentL == 0)
+                       return 0;
+
+               currentV.setBuffer(buffer, currentL);
+
+               return currentL;
+       }
+
+       ByteArray SimpleTLV::encode(unsigned int tag, ByteArray buffer)
+       {
+               bool isLongBuffer = false;
+               ByteArray result;
+               unsigned int total_len = 0;
+               unsigned int current = 0;
+               unsigned char *temp_buffer = NULL;
+
+               /* add tag's length */
+               total_len += 1;
+
+               /* add length's length */
+               if (buffer.getLength() < 255)
+               {
+                       total_len += 1;
+               }
+               else if (buffer.getLength() < 65536)
+               {
+                       total_len += 3;
+                       isLongBuffer = true;
+               }
+               else
+               {
+                       return result;
+               }
+
+               /* add buffer's length */
+               total_len += buffer.getLength();
+
+               /* alloc new buffer */
+               temp_buffer = new unsigned char[total_len];
+               if (temp_buffer == NULL)
+               {
+                       return result;
+               }
+               memset(temp_buffer, 0, total_len);
+
+               /* fill tag */
+               temp_buffer[current++] = (unsigned char)tag;
+
+               /* fill length */
+               if (isLongBuffer == true)
+               {
+                       temp_buffer[current++] = (unsigned char)(0xFF);
+                       temp_buffer[current++] = (unsigned char)(buffer.getLength() >> 8);
+                       temp_buffer[current++] = (unsigned char)(buffer.getLength());
+               }
+               else
+               {
+                       temp_buffer[current++] = (unsigned char)(buffer.getLength());
+               }
+
+               /* fill value */
+               if (buffer.getLength() > 0)
+                       memcpy(temp_buffer + current, buffer.getBuffer(), buffer.getLength());
+
+               result.setBuffer(temp_buffer, total_len);
+
+               delete []temp_buffer;
+
+               return result;
+       }
+
+       ByteArray SimpleTLV::encode(unsigned int tag, unsigned char *buffer, unsigned int length)
+       {
+               return encode(tag, ByteArray(buffer, length));
+       }
+
+       TLVHelper *SimpleTLV::getChildTLV(ByteArray data)
+       {
+               if (childTLV != NULL)
+               {
+                       delete childTLV;
+                       childTLV = NULL;
+               }
+               childTLV = new SimpleTLV(data, this);
+
+               return (TLVHelper *)childTLV;
+       }
+
+       ByteArray SimpleTLV::getOctetString(const ByteArray &array)
+       {
+               SimpleTLV tlv(array);
+
+               return SimpleTLV::getOctetString(tlv);
+       }
+
+       ByteArray SimpleTLV::getOctetString(SimpleTLV &tlv)
+       {
+               ByteArray result;
+
+               if (tlv.decodeTLV() == true && tlv.getTag() == 0x04) /* OCTET STRING */
+               {
+                       result = tlv.getValue();
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("getOctetString failed (0x%02X)", tlv.getTag());
+               }
+
+               return result;
+       }
+
+       bool SimpleTLV::getBoolean(const ByteArray &array)
+       {
+               SimpleTLV tlv(array);
+
+               return SimpleTLV::getBoolean(tlv);
+       }
+
+       bool SimpleTLV::getBoolean(SimpleTLV &tlv)
+       {
+               bool result = false;
+
+               if (tlv.decodeTLV() == true && tlv.getTag() == 0x80) /* BOOLEAN */
+               {
+                       if (tlv.getValue().getAt(0) == 0)
+                               result = false;
+                       else
+                               result = true;
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("getBoolean failed (0x%02X)", tlv.getTag());
+               }
+
+               return result;
+       }
+
+       int SimpleTLV::getInteger(const ByteArray &array)
+       {
+               SimpleTLV tlv(array);
+
+               return SimpleTLV::getInteger(tlv);
+       }
+
+       int SimpleTLV::getInteger(SimpleTLV &tlv)
+       {
+               int result = 0;
+
+               if (tlv.decodeTLV() == true && tlv.getTag() == 0x80) /* TODO : INTEGER */
+               {
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("getInteger failed (0x%02X)", tlv.getTag());
+               }
+
+               return result;
+       }
+} /* namespace smartcard_service_api */
diff --git a/common/Synchronous.cpp b/common/Synchronous.cpp
new file mode 100644 (file)
index 0000000..3a6d027
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <sys/time.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+
+namespace smartcard_service_api
+{
+       Synchronous::Synchronous()
+       {
+               pthread_mutex_init(&syncMutex, NULL);
+               pthread_cond_init(&syncCondition, NULL);
+       }
+
+       void Synchronous::syncLock()
+       {
+               pthread_mutex_lock(&syncMutex);
+       }
+
+       void Synchronous::syncUnlock()
+       {
+               pthread_mutex_unlock(&syncMutex);
+       }
+
+       int Synchronous::waitTimedCondition(int second)
+       {
+               struct timeval now;
+               struct timespec ts;
+               int result;
+
+               if (second > 0)
+               {
+                       gettimeofday(&now, NULL);
+                       ts.tv_sec = now.tv_sec + second;
+                       ts.tv_nsec = now.tv_usec * 1000;
+
+                       result = pthread_cond_timedwait(&syncCondition, &syncMutex, &ts);
+               }
+               else
+               {
+                       result = pthread_cond_wait(&syncCondition, &syncMutex);
+               }
+
+               return result;
+       }
+
+       void Synchronous::signalCondition()
+       {
+               pthread_cond_signal(&syncCondition);
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/TLVHelper.cpp b/common/TLVHelper.cpp
new file mode 100644 (file)
index 0000000..87fb650
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "TLVHelper.h"
+
+namespace smartcard_service_api
+{
+       void TLVHelper::initialize(TLVHelper *parent)
+       {
+               parentTLV = parent;
+               childTLV = NULL;
+               currentTLV = this;
+               offset = 0;
+               currentT = 0;
+               currentL = 0;
+       }
+
+       TLVHelper::TLVHelper()
+       {
+               initialize();
+       }
+
+       TLVHelper::TLVHelper(TLVHelper *parent)
+       {
+               initialize(parent);
+       }
+
+       TLVHelper::TLVHelper(const ByteArray &array)
+       {
+               setTLVBuffer(array);
+       }
+
+       TLVHelper::TLVHelper(const ByteArray &array, TLVHelper *parent)
+       {
+               setTLVBuffer(array, parent);
+       }
+
+       TLVHelper::~TLVHelper()
+       {
+       }
+
+       bool TLVHelper::setTLVBuffer(const ByteArray &array, TLVHelper *parent)
+       {
+               initialize(parent);
+
+               if (array.getLength() == 0)
+                       return false;
+
+               tlvBuffer = array;
+
+               return true;
+       }
+
+       bool TLVHelper::setTLVBuffer(unsigned char *buffer, unsigned int length, TLVHelper *parent)
+       {
+               return setTLVBuffer(ByteArray(buffer, length), parent);
+       }
+
+       bool TLVHelper::_decodeTLV()
+       {
+               int result;
+
+               currentT = 0;
+               currentL = 0;
+               currentV.releaseBuffer();
+
+               if (isEndOfBuffer())
+                       return false;
+
+               /* T */
+               if ((result = decodeTag(tlvBuffer.getBuffer(offset))) < 0)
+                       return false;
+
+               offset += result;
+
+               /* L */
+               if ((result = decodeLength(tlvBuffer.getBuffer(offset))) < 0)
+                       return false;
+
+               offset += result;
+
+               if (currentL > 0)
+               {
+                       /* V */
+                       if ((result = decodeValue(tlvBuffer.getBuffer(offset))) < 0)
+                               return false;
+
+                       offset += result;
+               }
+
+               return true;
+       }
+
+       const char *TLVHelper::toString()
+       {
+               memset(strBuffer, 0, sizeof(strBuffer));
+
+               if (currentL == 0)
+               {
+                       snprintf(strBuffer, sizeof(strBuffer), "T [%X], L [%d]", getTag(), getLength());
+               }
+               else
+               {
+                       snprintf(strBuffer, sizeof(strBuffer), "T [%X], L [%d], V %s", getTag(), getLength(), getValue().toString());
+               }
+
+               return strBuffer;
+       }
+
+       TLVHelper *TLVHelper::getParentTLV()
+       {
+               return parentTLV;
+       }
+
+       bool TLVHelper::enterToValueTLV()
+       {
+               bool result = false;
+               TLVHelper *temp = NULL;
+
+               if (getLength() >= 2)
+               {
+                       temp = currentTLV->getChildTLV(getValue());
+
+                       if (temp != NULL)
+                       {
+                               currentTLV = temp;
+                               result = true;
+                       }
+               }
+
+               return result;
+       }
+
+       bool TLVHelper::returnToParentTLV()
+       {
+               bool result = true;
+
+//             SCARD_DEBUG("current [%p], parent [%p]", currentTLV, currentTLV->getParentTLV());
+
+               if (currentTLV->getParentTLV() != NULL)
+               {
+                       currentTLV = currentTLV->getParentTLV();
+               }
+               else
+               {
+                       /* top tlv */
+               }
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/common/include/APDUHelper.h b/common/include/APDUHelper.h
new file mode 100644 (file)
index 0000000..b1aa404
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef APDUHELPER_H_
+#define APDUHELPER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       class ResponseHelper
+       {
+       private:
+               ByteArray response;
+               unsigned char sw[2];
+               int status;
+               ByteArray dataField;
+
+               static int parseStatusWord(unsigned char *sw);
+       public:
+               ResponseHelper();
+               ResponseHelper(const ByteArray &response);
+               ~ResponseHelper();
+
+               bool setResponse(const ByteArray &response);
+               int getStatus();
+//             char *getErrorString();
+               ByteArray getDataField();
+
+               static int getStatus(const ByteArray &response);
+               static ByteArray getDataField(const ByteArray &response);
+//             static char *getErrorString();
+       };
+
+       class APDUCommand
+       {
+       private:
+               typedef struct _command_header_t
+               {
+                       unsigned char cla;
+                       unsigned char ins;
+                       unsigned char param[2];
+               } command_header_t;
+
+               command_header_t header;
+               ByteArray commandData;
+               unsigned int maxResponseSize;
+               bool isExtendedLength;
+
+       public:
+               static const unsigned char INS_DEACTIVATE_FILE = (unsigned char)0x04;
+               static const unsigned char INS_TERMINAL_PROFILE = (unsigned char)0x10;
+               static const unsigned char INS_TERMINAL_RESPONSE = (unsigned char)0x14;
+               static const unsigned char INS_VERIFY = (unsigned char)0x20;
+               static const unsigned char INS_CHANGE_PIN = (unsigned char)0x24;
+               static const unsigned char INS_DISABLE_PIN = (unsigned char)0x26;
+               static const unsigned char INS_ENABLE_PIN = (unsigned char)0x28;
+               static const unsigned char INS_UNBLOCK_PIN = (unsigned char)0x2C;
+               static const unsigned char INS_INCREASE = (unsigned char)0x32;
+               static const unsigned char INS_ACTIVATE_FILE = (unsigned char)0x44;
+               static const unsigned char INS_GET_CHALLENGE = (unsigned char)0x84;
+               static const unsigned char INS_AUTHENTICATE = (unsigned char)0x88;
+               static const unsigned char INS_AUTHENTICATE2 = (unsigned char)0x89;
+               static const unsigned char INS_MANAGE_CHANNEL = (unsigned char)0x70;
+               static const unsigned char INS_SEARCH_RECORD = (unsigned char)0xA2;
+               static const unsigned char INS_SELECT_FILE = (unsigned char)0xA4;
+               static const unsigned char INS_TERMINAL_CAPABILITY = (unsigned char)0xAA;
+               static const unsigned char INS_READ_BINARY = (unsigned char)0xB0;
+               static const unsigned char INS_READ_RECORD = (unsigned char)0xB2;
+               static const unsigned char INS_GET_RESPONSE = (unsigned char)0xC0;
+               static const unsigned char INS_RETRIEVE_DATA = (unsigned char)0xCB;
+               static const unsigned char INS_WRITE_BINARY = (unsigned char)0xD0;
+               static const unsigned char INS_UPDATE_BINARY = (unsigned char)0xD6;
+               static const unsigned char INS_UPDATE_RECORD = (unsigned char)0xDC;
+               static const unsigned char INS_SET_DATA = (unsigned char)0xDB;
+               static const unsigned char INS_CREATE_FILE = (unsigned char)0xE0;
+               static const unsigned char INS_APPEND_RECORD = (unsigned char)0xE2;
+               static const unsigned char INS_DELETE_FILE = (unsigned char)0xE4;
+               static const unsigned char INS_STATUS = (unsigned char)0xF2;
+//             static const unsigned char INS_ = (unsigned char)0x;
+
+               static const unsigned char P1_SELECT_BY_ID = (unsigned char)0x00;
+               static const unsigned char P1_SELECT_PARENT_DF = (unsigned char)0x03;
+               static const unsigned char P1_SELECT_BY_DF_NAME = (unsigned char)0x04;
+               static const unsigned char P1_SELECT_BY_PATH = (unsigned char)0x08;
+               static const unsigned char P1_SELECT_BY_PATH_FROM_CURRENT_DF = (unsigned char)0x09;
+//             static const unsigned char P1_ = (unsigned char)0x;
+
+               static const unsigned char P2_SELECT_GET_FCP = (unsigned char)0x04;
+//             static const unsigned char P2_ = (unsigned char)0x;
+
+               APDUCommand();
+               ~APDUCommand();
+
+               bool setCommand(unsigned char cla, unsigned char ins, unsigned char p1, unsigned char p2, ByteArray commandData, unsigned int maxResponseSize);
+               bool setCommand(const ByteArray &command);
+
+               bool setChannel(int type, int channelNum);
+
+               void setCLA(unsigned char cla);
+               unsigned char getCLA();
+
+               void setINS(unsigned char ins);
+               unsigned char getINS();
+
+               void setP1(unsigned char p1);
+               unsigned char getP1();
+
+               void setP2(unsigned char p2);
+               unsigned char getP2();
+
+               void setCommandData(const ByteArray &data);
+               ByteArray getCommandData();
+
+               void setMaxResponseSize(unsigned int maxResponseSize);
+               unsigned int setMaxResponseSize();
+
+               bool getBuffer(ByteArray &array);
+       };
+
+       class APDUHelper
+       {
+       public:
+               static const int COMMAND_OPEN_LOGICAL_CHANNEL = 1;
+               static const int COMMAND_CLOSE_LOGICAL_CHANNEL = 2;
+               static const int COMMAND_SELECT_BY_ID = 3;
+               static const int COMMAND_SELECT_PARENT_DF = 4;
+               static const int COMMAND_SELECT_BY_DF_NAME = 5;
+               static const int COMMAND_SELECT_BY_PATH = 6;
+               static const int COMMAND_SELECT_BY_PATH_FROM_CURRENT_DF = 7;
+               static const int COMMAND_READ_BINARY = 8;
+               static const int COMMAND_READ_RECORD = 9;
+               static const int COMMAND_WRITE_BINARY = 10;
+               static const int COMMAND_WRITE_RECORD = 11;
+
+               static ByteArray generateAPDU(int command, int channel, ByteArray data);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* APDUHELPER_H_ */
diff --git a/common/include/AccessCondition.h b/common/include/AccessCondition.h
new file mode 100644 (file)
index 0000000..35f38de
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef ACCESSCONDITION_H_
+#define ACCESSCONDITION_H_
+
+/* standard library header */
+#include <vector>
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class APDUAccessRule
+       {
+       private :
+               bool permission;
+               map<ByteArray, ByteArray> mapApduFilters;
+
+       public :
+               APDUAccessRule()
+               {
+                       permission = true;
+               }
+
+               void loadAPDUAccessRule(const ByteArray &data);
+               bool isAuthorizedAccess(const ByteArray &command);
+
+               void printAPDUAccessRules();
+       };
+
+       class NFCAccessRule
+       {
+       private :
+               bool permission;
+
+       public :
+               NFCAccessRule()
+               {
+                       permission = true;
+               }
+
+               void loadNFCAccessRule(const ByteArray &data);
+               bool isAuthorizedAccess(void);
+
+               void printNFCAccessRules();
+       };
+
+       class AccessCondition
+       {
+       private :
+               bool permission;
+               ByteArray aid;
+               vector<ByteArray> hashes;
+               APDUAccessRule apduRule;
+               NFCAccessRule nfcRule;
+
+       public :
+               AccessCondition() : permission(false)
+               {
+               }
+
+               void loadAccessCondition(ByteArray &aid, ByteArray &data);
+               bool isAuthorizedAccess(ByteArray &certHash);
+               bool isAuthorizedAPDUAccess(ByteArray &command);
+               bool isAuthorizedNFCAccess();
+
+               void printAccessConditions();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* ACCESSCONDITION_H_ */
diff --git a/common/include/AccessControlList.h b/common/include/AccessControlList.h
new file mode 100644 (file)
index 0000000..e13d08a
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef ACCESSCONTROLLIST_H_
+#define ACCESSCONTROLLIST_H_
+
+/* standard library header */
+#include <vector>
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "Channel.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class Terminal;
+       class AccessCondition;
+
+       class AccessControlList
+       {
+       protected:
+               map<ByteArray, AccessCondition> mapConditions;
+               Channel *channel;
+               Terminal *terminal;
+
+               void printAccessControlList();
+
+       public:
+               static ByteArray AID_ALL;
+               static ByteArray AID_DEFAULT;
+
+               AccessControlList();
+               AccessControlList(Channel *channel);
+               AccessControlList(Terminal *terminal);
+               ~AccessControlList();
+
+               int setChannel(Channel *channel);
+               virtual int setTerminal(Terminal *terminal) { this->terminal = terminal; return 0; }
+
+               virtual int loadACL() = 0;
+
+               int updateACL();
+               void releaseACL();
+
+               bool isAuthorizedAccess(ByteArray aid, ByteArray certHash);
+               bool isAuthorizedAccess(unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* ACCESSCONTROLLIST_H_ */
diff --git a/common/include/ByteArray.h b/common/include/ByteArray.h
new file mode 100644 (file)
index 0000000..66fe588
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef BYTEARRAY_H_
+#define BYTEARRAY_H_
+
+/* standard library header */
+#include <stdint.h>
+
+/* SLP library header */
+
+/* local header */
+//#include "Serializable.h"
+
+#define ARRAY_AND_SIZE(x) (uint8_t *)(&x), sizeof(x)
+
+namespace smartcard_service_api
+{
+       class ByteArray //: public Serializable
+       {
+       protected:
+               uint8_t *buffer;
+               uint32_t length;
+               char strBuffer[100];
+
+               bool _setBuffer(uint8_t *array, uint32_t bufferLen);
+               void save(const char *filePath);
+
+       public:
+               static ByteArray EMPTY;
+
+               ByteArray();
+               ByteArray(uint8_t *array, uint32_t bufferLen);
+               ByteArray(const ByteArray &T);
+               ~ByteArray();
+
+//             ByteArray serialize();
+//             void deserialize(ByteArray buffer);
+
+               bool setBuffer(uint8_t *array, uint32_t bufferLen);
+               void releaseBuffer();
+
+               uint32_t getLength() const;
+               uint8_t *getBuffer() const;
+               uint8_t *getBuffer(uint32_t offset) const;
+
+               uint8_t getAt(uint32_t index) const;
+               uint8_t getReverseAt(uint32_t index) const;
+
+               uint32_t copyFromArray(uint8_t *array, uint32_t bufferLen) const;
+
+               /* operator overloading */
+               ByteArray &operator =(const ByteArray &T);
+               ByteArray operator +(const ByteArray &T);
+               ByteArray &operator +=(const ByteArray &T);
+               bool operator ==(const ByteArray &T) const;
+               bool operator !=(const ByteArray &T) const;
+               bool operator <(const ByteArray &T) const;
+               bool operator >(const ByteArray &T) const;
+               uint8_t &operator [](uint32_t index) const;
+
+               inline bool isEmpty() { return (buffer == (void *)0 || length == 0); }
+               const char *toString();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* BYTEARRAY_H_ */
diff --git a/common/include/Channel.h b/common/include/Channel.h
new file mode 100644 (file)
index 0000000..e4c29ba
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef CHANNEL_H_
+#define CHANNEL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       class SessionHelper;    /* explicit declaration */
+
+       typedef void (*transmitCallback)(unsigned char *buffer, unsigned int length, int error, void *userParam);
+       typedef void (*closeCallback)(int error, void *userParam);
+
+       class Channel : public Synchronous
+       {
+       protected:
+               ByteArray selectResponse;
+               SessionHelper *session;
+               int channelNum;
+
+               Channel() : Synchronous()
+               {
+                       channelNum = -1;
+               }
+               Channel(SessionHelper *session) : Synchronous()
+               {
+                       this->session = session;
+               }
+
+               virtual void closeSync() = 0;
+               virtual int transmitSync(ByteArray command, ByteArray &result) = 0;
+
+       public:
+               virtual ~Channel() {}
+
+               virtual int close(closeCallback callback, void *userParam) = 0;
+               inline bool isBasicChannel() const { return (channelNum == 0); }
+               inline bool isClosed() const { return (channelNum < 0); }
+
+               inline ByteArray getSelectResponse() const { return selectResponse; }
+               inline SessionHelper *getSession() const { return session; }
+               virtual int transmit(ByteArray command, transmitCallback callback, void *userData) = 0;
+
+               friend class FileObject;
+               friend class ServerSession;
+               friend class ServerChannel;
+               friend class ServerDispatcher;
+               friend class ServerResource;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* CHANNEL_H_ */
diff --git a/common/include/Debug.h b/common/include/Debug.h
new file mode 100644 (file)
index 0000000..c5e2a77
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef DEBUG_H_
+#define DEBUG_H_
+
+/* standard library header */
+
+/* SLP library header */
+#include "dlog.h"
+
+/* local header */
+
+#define COLOR_RED              "\033[0;31m"
+#define COLOR_GREEN    "\033[0;32m"
+#define COLOR_BROWN    "\033[0;33m"
+#define COLOR_BLUE             "\033[0;34m"
+#define COLOR_PURPLE   "\033[0;35m"
+#define COLOR_CYAN             "\033[0;36m"
+#define COLOR_LIGHTBLUE "\033[0;37m"
+#define COLOR_END              "\033[0;m"
+
+#define SCARD_DEBUG(fmt, ...)\
+       do\
+       {\
+               LOGD("[%s(): %d] " fmt, __FUNCTION__, __LINE__,##__VA_ARGS__);\
+       } while (0)
+
+#define SCARD_DEBUG_ERR(fmt, ...)\
+       do\
+       {\
+               LOGE(COLOR_RED"[%s(): %d] " fmt COLOR_END, __FUNCTION__, __LINE__,##__VA_ARGS__);\
+       }while (0)
+
+#define SCARD_BEGIN() \
+       do\
+    {\
+               LOGD(COLOR_BLUE"[%s(): %d] BEGIN >>>>"COLOR_END, __FUNCTION__ ,__LINE__);\
+    } while( 0 )
+
+#define SCARD_END() \
+       do\
+    {\
+               LOGD(COLOR_BLUE"[%s(): %d] END <<<<"COLOR_END, __FUNCTION__,__LINE__ );\
+    } \
+    while( 0 )
+
+#endif /* DEBUG_H_ */
diff --git a/common/include/DispatcherHelper.h b/common/include/DispatcherHelper.h
new file mode 100644 (file)
index 0000000..7d8a81f
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef DISPATCHERHELPER_H_
+#define DISPATCHERHELPER_H_
+
+/* standard library header */
+#include <queue>
+#include <pthread.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "DispatcherMsg.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class DispatcherHelper : public Synchronous
+       {
+       private:
+               pthread_t dispatcherThread;
+
+               queue<DispatcherMsg *> messageQ;
+
+               static void *_dispatcherThreadFunc(void *data);
+
+               DispatcherMsg *fetchMessage();
+
+       protected:
+               virtual void *dispatcherThreadFunc(DispatcherMsg *msg, void *data) = 0;
+
+       public:
+               DispatcherHelper();
+               ~DispatcherHelper();
+
+               void clearQueue();
+
+               void pushMessage(DispatcherMsg *msg);
+
+               bool runDispatcherThread();
+               void stopDispatcherThread();
+
+               friend void *_dispatcherThreadFunc(void *data);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* DISPATCHERHELPER_H_ */
diff --git a/common/include/DispatcherMsg.h b/common/include/DispatcherMsg.h
new file mode 100644 (file)
index 0000000..426f31f
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef DISPATCHERMSG_H_
+#define DISPATCHERMSG_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Message.h"
+
+namespace smartcard_service_api
+{
+       class DispatcherMsg: public Message
+       {
+       private:
+               int peerSocket;
+
+       public:
+               DispatcherMsg():Message()
+               {
+                       peerSocket = -1;
+               }
+
+               DispatcherMsg(Message *msg):Message()
+               {
+                       peerSocket = -1;
+                       message = msg->message;
+                       param1 = msg->param1;
+                       param2 = msg->param2;
+                       error = msg->error;
+                       data = msg->data;
+                       caller = msg->caller;
+                       callback = msg->callback;
+                       userParam = msg->userParam;
+               }
+
+               DispatcherMsg(Message *msg, int socket):Message()
+               {
+                       peerSocket = socket;
+                       message = msg->message;
+                       param1 = msg->param1;
+                       param2 = msg->param2;
+                       error = msg->error;
+                       data = msg->data;
+                       caller = msg->caller;
+                       callback = msg->callback;
+                       userParam = msg->userParam;
+               }
+
+               ~DispatcherMsg() {}
+
+               inline int getPeerSocket() { return peerSocket; }
+               inline void setPeerSocket(int socket) { peerSocket = socket; }
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* DISPATCHERMSG_H_ */
diff --git a/common/include/FCI.h b/common/include/FCI.h
new file mode 100644 (file)
index 0000000..8fea754
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef FCI_H_
+#define FCI_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       class FCP
+       {
+       private:
+               ByteArray fcpBuffer;
+
+               char strBuffer[400];
+
+               unsigned int fileSize;
+               unsigned int totalFileSize;
+               unsigned int fid;
+               unsigned int sfi;
+               unsigned int maxRecordSize;
+               unsigned int numberOfRecord;
+               unsigned int fileType;
+               unsigned int fileStructure;
+               unsigned int lcs;
+
+               void resetMemberVar();
+
+       public:
+               FCP();
+               FCP(ByteArray &array);
+               ~FCP();
+
+               bool setFCP(ByteArray array);
+               ByteArray getFCP();
+               void releaseFCP();
+
+               unsigned int getFileSize();
+               unsigned int getTotalFileSize();
+               unsigned int getFID();
+               unsigned int getSFI();
+               unsigned int getMaxRecordSize();
+               unsigned int getNumberOfRecord();
+               unsigned int getFileType();
+               unsigned int getFileStructure();
+               unsigned int getLCS();
+
+               const char *toString();
+       };
+
+       class FCM
+       {
+       private:
+               ByteArray fcmBuffer;
+
+       public:
+               FCM();
+               virtual ~FCM();
+       };
+
+       class FCI
+       {
+       private:
+               ByteArray fciBuffer;
+               FCP fcp;
+               FCM fcm;
+
+       public:
+               static const int INFO_NOT_AVAILABLE = -1;
+
+               static const int FT_DF = 0;
+               static const int FT_EF = 1;
+
+               static const int FS_NO_EF = 0;
+               static const int FS_TRANSPARENT = 1;
+               static const int FS_LINEAR_FIXED = 2;
+               static const int FS_LINEAR_VARIABLE = 3;
+               static const int FS_CYCLIC = 4;
+
+               static const int LCS_NO_INFORMATION_GIVEN = 0;
+               static const int LCS_CREATION_STATE = 1;
+               static const int LCS_INITIALISATION_STATE = 3;
+               static const int LCS_OPERATION_STATE_ACTIVATED = 5;
+               static const int LCS_OPERATION_STATE_DEACTIVATED = 4;
+               static const int LCS_TERMINATION_STATE = 6;
+
+               FCI();
+               ~FCI();
+
+               bool setFCIBuffer(ByteArray array);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* FCI_H_ */
diff --git a/common/include/FileObject.h b/common/include/FileObject.h
new file mode 100644 (file)
index 0000000..15f4254
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef FILEOBJECT_H_
+#define FILEOBJECT_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "ProviderHelper.h"
+#include "ByteArray.h"
+#include "FCI.h"
+#include "Record.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class FileObject : public ProviderHelper
+       {
+       private:
+               FCI fci;
+               FCP fcp;
+
+       protected:
+               ByteArray selectResponse;
+               bool setSelectResponse(ByteArray response);
+
+       public:
+               static const int SUCCESS = 0;
+               static const int ERROR_ILLEGAL_STATE = -1;
+               static const int ERROR_ILLEGAL_REFERENCE = -2;
+               static const int ERROR_ILLEGAL_PARAMETER = -3;
+               static const int ERROR_SECURITY = -4;
+               static const int ERROR_OPERATION_NOT_SUPPORT = -5;
+               static const int ERROR_IO = -6;
+               static const int ERROR_UNKNOWN = -99;
+
+               FileObject(Channel *channel);
+               FileObject(Channel *channel, ByteArray selectResponse);
+               ~FileObject();
+
+               int select(ByteArray aid);
+               int select(ByteArray path, bool fromCurrentDF);
+               int select(unsigned int fid);
+               int selectParent();
+
+               FCI *getFCI();
+               FCP *getFCP();
+
+               int readRecord(unsigned int sfi, unsigned int recordId, Record &result);
+               int writeRecord(unsigned int sfi, Record record);
+
+               int searchRecord(unsigned int sfi, ByteArray searchParam, vector<int> &result);
+
+               int readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result);
+               int writeBinary(unsigned int sfi, ByteArray data, unsigned int offset, unsigned int length);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* FILEOBJECT_H_ */
diff --git a/common/include/GPSEACL.h b/common/include/GPSEACL.h
new file mode 100644 (file)
index 0000000..efde39e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef GPSEACL_H_
+#define GPSEACL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "AccessControlList.h"
+#include "PKCS15.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+       class GPSEACL: public AccessControlList
+       {
+       private:
+               PKCS15 *pkcs15;
+               ByteArray refreshTag;
+
+               static ByteArray OID_GLOBALPLATFORM;
+
+               int loadAccessControl(PKCS15DODF *dodf);
+               int loadRules(ByteArray path);
+               int loadAccessConditions(ByteArray aid, ByteArray path);
+
+       public:
+               GPSEACL(Channel *channel);
+               ~GPSEACL();
+
+               int loadACL();
+
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+typedef void *gp_se_acl_h;
+
+gp_se_acl_h gp_se_acl_create_instance(channel_h channel);
+int gp_se_acl_load_acl(gp_se_acl_h handle);
+int gp_se_acl_update_acl(gp_se_acl_h handle);
+void gp_se_acl_release_acl(gp_se_acl_h handle);
+bool gp_se_acl_is_authorized_access(gp_se_acl_h handle, unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength);
+void gp_se_acl_destroy_instance(gp_se_acl_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GPSEACL_H_ */
diff --git a/common/include/IPCHelper.h b/common/include/IPCHelper.h
new file mode 100644 (file)
index 0000000..b038a35
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef IPCHELPER_H_
+#define IPCHELPER_H_
+
+/* standard library header */
+#include <glib.h>
+#include <pthread.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Message.h"
+#include "DispatcherHelper.h"
+
+namespace smartcard_service_api
+{
+       class IPCHelper
+       {
+       protected:
+               static const int IPC_SERVER_PORT = 8989;
+               static const int IPC_SERVER_MAX_CLIENT = 10;
+
+               int ipcSocket;
+               unsigned int watchId;
+               GIOChannel *ioChannel;
+               pthread_mutex_t ipcLock;
+               DispatcherHelper *dispatcher;
+
+               static gboolean channelCallbackFunc(GIOChannel* channel, GIOCondition condition, gpointer data);
+
+               virtual int handleIOErrorCondition(void *channel, GIOCondition condition) = 0;
+               virtual int handleInvalidSocketCondition(void *channel, GIOCondition condition) = 0;
+               virtual int handleIncomingCondition(void *channel, GIOCondition condition) = 0;
+
+       public:
+               IPCHelper();
+               ~IPCHelper();
+
+               bool createListenSocket();
+               bool createConnectSocket();
+
+               bool sendMessage(Message *msg);
+               bool sendMessage(int socket, Message *msg);
+               Message *retrieveMessage();
+               Message *retrieveMessage(int socket);
+
+               void setDispatcher(DispatcherHelper *dispatcher);
+
+               friend gboolean channelCallbackFunc(GIOChannel* channel, GIOCondition condition, gpointer data);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* IPCHELPER_H_ */
diff --git a/common/include/ISO7816BERTLV.h b/common/include/ISO7816BERTLV.h
new file mode 100644 (file)
index 0000000..29ca561
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef ISO7816BERTLV_H_
+#define ISO7816BERTLV_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "TLVHelper.h"
+
+namespace smartcard_service_api
+{
+       class ISO7816BERTLV: public TLVHelper
+       {
+       private:
+//             ISO7816BERTLV child;
+
+               unsigned char firstByte;
+               unsigned int tagClass;
+               unsigned int encoding;
+
+               ISO7816BERTLV(TLVHelper *parent);
+               ISO7816BERTLV(const ByteArray &array, TLVHelper *parent);
+
+               int decodeTag(unsigned char *buffer);
+               int decodeLength(unsigned char *buffer);
+               int decodeValue(unsigned char *buffer);
+
+               TLVHelper *getChildTLV(ByteArray data);
+
+       public:
+               ISO7816BERTLV();
+               ISO7816BERTLV(const ByteArray &array);
+               ~ISO7816BERTLV();
+
+               unsigned int getClass();
+               unsigned int getEncoding();
+
+               static ByteArray encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, ByteArray buffer);
+               static ByteArray encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* ISO7816BERTLV_H_ */
diff --git a/common/include/Lock.h b/common/include/Lock.h
new file mode 100644 (file)
index 0000000..89a2aff
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef LOCK_H_
+#define LOCK_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "pthread.h"
+
+namespace smartcard_service_api
+{
+       class Lock
+       {
+       public:
+               virtual ~Lock() {};
+               virtual void lock() = 0;
+               virtual void unlock() = 0;
+       };
+
+       class PMutex : public Lock
+       {
+       private:
+               pthread_mutex_t mutex;
+
+       public:
+               PMutex() { pthread_mutex_init(&mutex, NULL); }
+               ~PMutex() { pthread_mutex_destroy(&mutex); }
+
+               inline void lock() { pthread_mutex_lock(&mutex); }
+               inline void unlock() { pthread_mutex_unlock(&mutex); }
+       };
+#define TOKENPASTE(x, y) x ## y
+#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
+#define SCOPE_LOCK(X) \
+       if (const AutoLockHelper& TOKENPASTE2(lock_, __LINE__) = makeAutoLock(X))
+
+       class AutoLockHelper
+       {
+       public:
+               inline operator bool() const
+               {
+                       return true;
+               }
+       };
+
+       template<typename T>
+       class AutoLock : public AutoLockHelper
+       {
+       private:
+               T *lock;
+
+       public:
+               AutoLock(const AutoLock &_lock) { lock = _lock.lock; }
+               AutoLock(T& _lock) : lock(&_lock) { lock->lock(); }
+               ~AutoLock() { lock->unlock(); }
+       };
+
+       template<typename T>
+       inline AutoLock<T> makeAutoLock(T& lock)
+       {
+               return AutoLock<T>(lock);
+       }
+
+} /* namespace smartcard_service_api */
+#endif /* SCOPELOCK_H_ */
diff --git a/common/include/Message.h b/common/include/Message.h
new file mode 100644 (file)
index 0000000..26bcdcf
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef MESSAGE_H_
+#define MESSAGE_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Serializable.h"
+
+namespace smartcard_service_api
+{
+       class Message: public Serializable
+       {
+       private:
+               char text[200];
+
+       public:
+               static const int MSG_REQUEST_READERS = 0x80;
+               static const int MSG_REQUEST_SHUTDOWN = 0x81;
+               static const int MSG_REQUEST_OPEN_SESSION = 0x82;
+               static const int MSG_REQUEST_CLOSE_SESSION = 0x83;
+               static const int MSG_REQUEST_OPEN_CHANNEL = 0x84;
+               static const int MSG_REQUEST_CLOSE_CHANNEL = 0x85;
+               static const int MSG_REQUEST_GET_ATR = 0x86;
+               static const int MSG_REQUEST_TRANSMIT = 0x87;
+               static const int MSG_REQUEST_GET_CHANNEL_COUNT = 0x88;
+
+               static const int MSG_NOTIFY_SE_REMOVED = 0x90;
+               static const int MSG_NOTIFY_SE_INSERTED = 0x91;
+
+               static const int MSG_OPERATION_RELEASE_CLIENT = 0xC0;
+
+               unsigned int message;
+               unsigned int param1;
+               unsigned int param2;
+               ByteArray data;
+               int error;
+               void *caller;
+               void *callback;
+               void *userParam;
+
+               Message();
+               ~Message();
+
+               ByteArray serialize();
+               void deserialize(unsigned char *buffer, unsigned int length);
+               void deserialize(ByteArray buffer);
+
+               const char *toString();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* MESSAGE_H_ */
diff --git a/common/include/NumberStream.h b/common/include/NumberStream.h
new file mode 100644 (file)
index 0000000..7812027
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef NUMBERSTREAM_H_
+#define NUMBERSTREAM_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       class NumberStream: public ByteArray
+       {
+       public:
+               NumberStream(const ByteArray &T);
+
+               unsigned int getBigEndianNumber();
+               unsigned int getLittleEndianNumber();
+
+               static unsigned int getBigEndianNumber(const ByteArray &T);
+               static unsigned int getLittleEndianNumber(const ByteArray &T);
+
+               NumberStream &operator =(const ByteArray &T);
+               NumberStream &operator =(const NumberStream &T);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* NUMBERSTREAM_H_ */
diff --git a/common/include/OpensslHelper.h b/common/include/OpensslHelper.h
new file mode 100644 (file)
index 0000000..0688020
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+#include <stdint.h>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+#ifndef OPENSSLHELPER_H_
+#define OPENSSLHELPER_H_
+
+namespace smartcard_service_api
+{
+       class OpensslHelper
+       {
+       public:
+               /* base64 method */
+               static bool encodeBase64String(const ByteArray &buffer, ByteArray &result, bool newLineChar = false);
+               static bool decodeBase64String(const char *buffer, ByteArray &result, bool newLineChar = true);
+               static bool decodeBase64String(const ByteArray &buffer, ByteArray &result, bool newLineChar = true);
+
+               /* digest method */
+               static bool digestBuffer(const char *algorithm, const uint8_t *buffer, const uint32_t length, ByteArray &result);
+               static bool digestBuffer(const char *algorithm, const ByteArray &buffer, ByteArray &result);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* OPENSSLHELPER_H_ */
diff --git a/common/include/PKCS15.h b/common/include/PKCS15.h
new file mode 100644 (file)
index 0000000..5119246
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef PKCS15_H_
+#define PKCS15_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "PKCS15Object.h"
+#include "PKCS15ODF.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class PKCS15: public PKCS15Object
+       {
+       private:
+               map<unsigned int, ByteArray> recordElement;
+               PKCS15ODF *odf;
+
+       public:
+               static ByteArray PKCS15_AID;
+
+               PKCS15(Channel *channel);
+               PKCS15(Channel *channel, ByteArray selectResponse);
+               ~PKCS15();
+
+               PKCS15ODF *getODF();
+               int getTokenInfo(ByteArray &path);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15_H_ */
diff --git a/common/include/PKCS15DODF.h b/common/include/PKCS15DODF.h
new file mode 100644 (file)
index 0000000..dff03f1
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef PKCS15DODF_H_
+#define PKCS15DODF_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "PKCS15Object.h"
+#include "PKCS15OID.h"
+
+namespace smartcard_service_api
+{
+       class PKCS15DODF: public PKCS15Object
+       {
+       private:
+               map<ByteArray, PKCS15OID> mapOID;
+
+               bool parseData(ByteArray data);
+
+       public:
+               PKCS15DODF();
+               PKCS15DODF(unsigned int fid, Channel *channel);
+               PKCS15DODF(ByteArray path, Channel *channel);
+               ~PKCS15DODF();
+
+               int searchOID(ByteArray oid, ByteArray &data);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15DODF_H_ */
diff --git a/common/include/PKCS15ODF.h b/common/include/PKCS15ODF.h
new file mode 100644 (file)
index 0000000..9a1021c
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef PKCS15ODF_H_
+#define PKCS15ODF_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "FileObject.h"
+#include "PKCS15DODF.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class PKCS15ODF: public PKCS15Object
+       {
+       private:
+               bool parseData(ByteArray data);
+               PKCS15DODF *dodf;
+
+       public:
+               static const unsigned int ODF_FID = 0x3150;
+
+               static const unsigned int TAG_DODF = (unsigned int)0xA7;
+               static const unsigned int TAG_TOKENINFO = (unsigned int)0xA5;
+
+//             PKCS15ODF();
+               PKCS15ODF(Channel *channel);
+               PKCS15ODF(Channel *channel, ByteArray selectResponse);
+               ~PKCS15ODF();
+
+               int getPuKDFPath(ByteArray &path);
+               int getPrKDFPath(ByteArray &path);
+               int getAODFPath(ByteArray &path);
+               int getCDFFPath(ByteArray &path);
+               int getDODFPath(ByteArray &path);
+
+               PKCS15DODF *getDODF();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15ODF_H_ */
diff --git a/common/include/PKCS15OID.h b/common/include/PKCS15OID.h
new file mode 100644 (file)
index 0000000..234cd19
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef PKCS15OID_H_
+#define PKCS15OID_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       class PKCS15OID
+       {
+       private:
+               ByteArray oid;
+               ByteArray name;
+               ByteArray path;
+
+               bool parseOID(ByteArray data);
+
+       public:
+               PKCS15OID(ByteArray data);
+               ~PKCS15OID();
+
+               ByteArray getOID();
+               ByteArray getName();
+               ByteArray getPath();
+
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15OID_H_ */
diff --git a/common/include/PKCS15Object.h b/common/include/PKCS15Object.h
new file mode 100644 (file)
index 0000000..e5a1963
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef PKCS15OBJECT_H_
+#define PKCS15OBJECT_H_
+
+/* standard library header */
+#include <map>
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "FileObject.h"
+#include "PKCS15Path.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class PKCS15Object: public FileObject
+       {
+       protected:
+               map<unsigned int, ByteArray> dataList;
+
+       public:
+               /* TODO : encapsulate below to asn class */
+               static const unsigned int TAG_SEQUENCE = (unsigned int)0x30;
+               static const unsigned int TAG_OCTET_STREAM = (unsigned int)0x04;
+
+//             PKCS15Object();
+               PKCS15Object(Channel *channel);
+               PKCS15Object(Channel *channel, ByteArray selectResponse);
+               ~PKCS15Object();
+
+               int decodePath(ByteArray path, PKCS15Path &result);
+               int getPath(unsigned int type, PKCS15Path &result);
+               int getPaths(vector<PKCS15Path> &paths);
+
+               static ByteArray getOctetStream(const ByteArray &data);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15OBJECT_H_ */
diff --git a/common/include/PKCS15Path.h b/common/include/PKCS15Path.h
new file mode 100644 (file)
index 0000000..9c5dbf6
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef PKCS15Path_H_
+#define PKCS15Path_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       class PKCS15Path
+       {
+       private :
+               ByteArray path;
+               int index;
+               int length;
+
+               bool parseData(ByteArray &data);
+
+       public:
+               PKCS15Path();
+               PKCS15Path(ByteArray &data);
+               PKCS15Path(ByteArray path, int index);
+               PKCS15Path(unsigned char *path, unsigned int length, int index);
+               ~PKCS15Path();
+
+               int getPath(ByteArray &path);
+               bool hasIndexLength();
+               int getIndex();
+               unsigned int getLength();
+               int encode(ByteArray &result);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15Path_H_ */
diff --git a/common/include/PKCS15TokenInfo.h b/common/include/PKCS15TokenInfo.h
new file mode 100644 (file)
index 0000000..71f8083
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef PKCS15TOKENINFO_H_
+#define PKCS15TOKENINFO_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "PKCS15Object.h"
+
+namespace smartcard_service_api
+{
+       class PKCS15TokenInfo: public PKCS15Object
+       {
+       public:
+               PKCS15TokenInfo(Channel *channel);
+               ~PKCS15TokenInfo();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* PKCS15TOKENINFO_H_ */
diff --git a/common/include/ProviderHelper.h b/common/include/ProviderHelper.h
new file mode 100644 (file)
index 0000000..2ad87a6
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef PROVIDERHELPER_H_
+#define PROVIDERHELPER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Channel.h"
+
+namespace smartcard_service_api
+{
+       class ProviderHelper
+       {
+       protected:
+               Channel *channel;
+
+//             ProviderHelper();
+
+       public:
+               ProviderHelper(Channel *channel);
+               ~ProviderHelper();
+
+               Channel *getChannel();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* PROVIDERHELPER_H_ */
diff --git a/common/include/ReaderHelper.h b/common/include/ReaderHelper.h
new file mode 100644 (file)
index 0000000..50e6a17
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef READERHELPER_H_
+#define READERHELPER_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "SessionHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class SEServiceHelper;
+
+       typedef void (*openSessionCallback)(SessionHelper *session, int error, void *userData);
+
+       class ReaderHelper : public Synchronous
+       {
+       protected:
+               char name[30];
+               vector<SessionHelper *> sessions;
+               SEServiceHelper *seService;
+
+               ReaderHelper();
+
+               virtual SessionHelper *openSessionSync() = 0;
+
+       public:
+               ~ReaderHelper();
+
+               const char *getName();
+               SEServiceHelper *getSEService();
+               bool isSecureElementPresent();
+               virtual int openSession(openSessionCallback callback, void *userData) = 0;
+               virtual void closeSessions() = 0;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* READERHELPER_H_ */
diff --git a/common/include/Record.h b/common/include/Record.h
new file mode 100644 (file)
index 0000000..29ef734
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef RECORD_H_
+#define RECORD_H_
+
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       class Record
+       {
+       private:
+               ByteArray data;
+               unsigned int id;
+
+       public:
+               Record();
+               Record(unsigned int id, ByteArray buffer);
+               ~Record();
+
+               unsigned int getID();
+               int getData(ByteArray &buffer);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* RECORD_H_ */
diff --git a/common/include/SEServiceHelper.h b/common/include/SEServiceHelper.h
new file mode 100644 (file)
index 0000000..de40eca
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SESERVICEHELPER_H_
+#define SESERVICEHELPER_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "ReaderHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class SEServiceHelper : public Synchronous
+       {
+       protected:
+               bool connected;
+               vector<ReaderHelper *> readers;
+
+       public:
+               SEServiceHelper();
+               ~SEServiceHelper();
+
+               vector<ReaderHelper *> getReaders();
+               bool isConnected();
+               void shutdown();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SESERVICEHELPER_H_ */
diff --git a/common/include/Serializable.h b/common/include/Serializable.h
new file mode 100644 (file)
index 0000000..af1fe3d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SERIALIZABLE_H_
+#define SERIALIZABLE_H_
+
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       class Serializable
+       {
+               virtual ByteArray serialize() = 0;
+               virtual void deserialize(ByteArray buffer) = 0;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SERIALIZABLE_H_ */
diff --git a/common/include/SessionHelper.h b/common/include/SessionHelper.h
new file mode 100644 (file)
index 0000000..3aed778
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SESSIONHELPER_H_
+#define SESSIONHELPER_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "Synchronous.h"
+#include "ByteArray.h"
+#include "Channel.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class ReaderHelper;
+
+       typedef void (*openChannelCallback)(Channel *channel, int error, void *userData);
+       typedef void (*getATRCallback)(unsigned char *atr, unsigned int length, int error, void *userData);
+       typedef void (*closeSessionCallback)(int error, void *userData);
+       typedef void (*getChannelCountCallback)(unsigned count, int error, void *userData);
+
+       class SessionHelper : public Synchronous
+       {
+       protected:
+               ReaderHelper *reader;
+               vector<Channel *> channels;
+               ByteArray atr;
+               bool closed;
+
+               virtual ByteArray getATRSync() = 0;
+               virtual void closeSync() = 0;
+
+               virtual Channel *openBasicChannelSync(ByteArray aid) = 0;
+               virtual Channel *openBasicChannelSync(unsigned char *aid, unsigned int length) = 0;
+               virtual Channel *openLogicalChannelSync(ByteArray aid) = 0;
+               virtual Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length) = 0;
+
+       public:
+               SessionHelper(ReaderHelper *reader);
+               virtual ~SessionHelper();
+
+               ReaderHelper *getReader();
+               virtual int getATR(getATRCallback callback, void *userData) = 0;
+               virtual int close(closeSessionCallback callback, void *userData) = 0;
+               bool isClosed();
+               virtual void closeChannels() = 0;
+
+               virtual int openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData) = 0;
+               virtual int openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData) = 0;
+               virtual int openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData) = 0;
+               virtual int openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData) = 0;
+
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SESSIONHELPER_H_ */
diff --git a/common/include/SignatureHelper.h b/common/include/SignatureHelper.h
new file mode 100644 (file)
index 0000000..a2c0923
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SIGNATUREHELPER_H_
+#define SIGNATUREHELPER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "ByteArray.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+       class SignatureHelper
+       {
+       public:
+               static int getProcessName(int pid, char *processName, uint32_t length);
+               static ByteArray getCertificationHash(const char *packageName);
+               static ByteArray getCertificationHash(int pid);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+int signature_helper_get_process_name(int pid, char *processName, uint32_t length);
+int signature_helper_get_certificate_hash(const char *packageName, uint8_t *hash, uint32_t *length);
+int signature_helper_get_certificate_hash_by_pid(int pid, uint8_t *hash, uint32_t *length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SIGNATUREHELPER_H_ */
diff --git a/common/include/SimpleTLV.h b/common/include/SimpleTLV.h
new file mode 100644 (file)
index 0000000..de35eb8
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SIMPLETLV_H_
+#define SIMPLETLV_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "TLVHelper.h"
+
+namespace smartcard_service_api
+{
+       class SimpleTLV : public TLVHelper
+       {
+       private:
+               SimpleTLV(TLVHelper *parent);
+               SimpleTLV(const ByteArray &array, TLVHelper *parent);
+
+               int decodeTag(unsigned char *buffer);
+               int decodeLength(unsigned char *buffer);
+               int decodeValue(unsigned char *buffer);
+
+               TLVHelper *getChildTLV(ByteArray data);
+
+       public:
+               SimpleTLV();
+               SimpleTLV(const ByteArray &array);
+               ~SimpleTLV();
+
+               static ByteArray getOctetString(const ByteArray &array);
+               static bool getBoolean(const ByteArray &array);
+               static int getInteger(const ByteArray &array);
+
+               static ByteArray getOctetString(SimpleTLV &tlv);
+               static bool getBoolean(SimpleTLV &tlv);
+               static int getInteger(SimpleTLV &tlv);
+
+               static ByteArray encode(unsigned int tag, ByteArray buffer);
+               static ByteArray encode(unsigned int tag, unsigned char *buffer, unsigned int length);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SIMPLETLV_H_ */
diff --git a/common/include/Synchronous.h b/common/include/Synchronous.h
new file mode 100644 (file)
index 0000000..d2aec51
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SYNCHRONOUS_H_
+#define SYNCHRONOUS_H_
+
+/* standard library header */
+#include <pthread.h>
+
+/* SLP library header */
+
+/* local header */
+
+namespace smartcard_service_api
+{
+       class Synchronous
+       {
+       protected:
+               pthread_mutex_t syncMutex;
+               pthread_cond_t syncCondition;
+
+               void syncLock();
+               void syncUnlock();
+               int waitTimedCondition(int second);
+               void signalCondition();
+
+       public:
+               Synchronous();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SYNCHRONOUS_H_ */
diff --git a/common/include/TLVHelper.h b/common/include/TLVHelper.h
new file mode 100644 (file)
index 0000000..a48dc05
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef TLVHELPER_H_
+#define TLVHELPER_H_
+
+/* standard library header */
+#include <stddef.h>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+       class TLVHelper
+       {
+       protected:
+               TLVHelper *currentTLV;
+               TLVHelper *parentTLV;
+               TLVHelper *childTLV;
+
+               char strBuffer[200];
+               ByteArray tlvBuffer;
+               unsigned int offset;
+
+               unsigned int currentT;
+               unsigned int currentL;
+               ByteArray currentV;
+
+               void initialize(TLVHelper *parent = NULL);
+               TLVHelper(TLVHelper *parent);
+               TLVHelper(const ByteArray &array, TLVHelper *parent);
+
+               virtual int decodeTag(unsigned char *buffer) = 0;
+               virtual int decodeLength(unsigned char *buffer) = 0;
+               virtual int decodeValue(unsigned char *buffer) = 0;
+
+               virtual TLVHelper *getChildTLV(ByteArray data) = 0;
+               TLVHelper *getParentTLV();
+
+               bool setTLVBuffer(const ByteArray &array, TLVHelper *parent);
+               bool setTLVBuffer(unsigned char *buffer, unsigned int length, TLVHelper *parent);
+
+               bool _isEndOfBuffer() { return offset >= tlvBuffer.getLength(); }
+               bool _decodeTLV();
+
+               unsigned int _getTag() { return currentT; }
+               unsigned int _getLength() { return currentL; }
+               ByteArray _getValue() { return currentV; }
+
+       public:
+               TLVHelper();
+               TLVHelper(const ByteArray &array);
+               ~TLVHelper();
+
+               bool setTLVBuffer(const ByteArray &array) { return setTLVBuffer(array, NULL); }
+               bool setTLVBuffer(unsigned char *buffer, unsigned int length) { return setTLVBuffer(buffer, length, NULL); }
+
+               bool isEndOfBuffer() { return currentTLV->_isEndOfBuffer(); }
+               bool decodeTLV() { return currentTLV->_decodeTLV(); }
+
+               unsigned int getTag() { return currentTLV->_getTag(); }
+               unsigned int getLength() { return currentTLV->_getLength(); }
+               ByteArray getValue() { return currentTLV->_getValue(); }
+
+               const char *toString();
+
+               bool enterToValueTLV();
+               bool returnToParentTLV();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* TLVHELPER_H_ */
diff --git a/common/include/Terminal.h b/common/include/Terminal.h
new file mode 100644 (file)
index 0000000..2cc8c6a
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef TERMINAL_H_
+#define TERMINAL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "Synchronous.h"
+
+namespace smartcard_service_api
+{
+       typedef void (*terminalNotificationCallback)(void *terminal, int event, int error, void *user_param);
+
+       typedef void (*terminalTransmitCallback)(unsigned char *buffer, unsigned int length, int error, void *userParam);
+       typedef void (*terminalGetATRCallback)(unsigned char *buffer, unsigned int length, int error, void *userParam);
+
+       class Terminal : public Synchronous
+       {
+       protected:
+               terminalNotificationCallback statusCallback;
+               bool initialized;
+               char *name;
+
+       public:
+               static const int NOTIFY_SE_AVAILABLE = 1;
+               static const int NOTIFY_SE_NOT_AVAILABLE = -1;
+
+               Terminal()
+               {
+                       statusCallback = NULL;
+                       initialized = false;
+                       name = NULL;
+               }
+               virtual ~Terminal() {}
+
+               virtual bool initialize() = 0;
+               virtual void finalize() = 0;
+               inline bool isInitialized() { return initialized; }
+
+               inline char *getName() { return name; }
+               inline void setStatusCallback(terminalNotificationCallback callback) { statusCallback = callback; }
+
+               virtual bool isSecureElementPresence() = 0;
+
+               virtual int transmitSync(ByteArray command, ByteArray &result) = 0;
+               virtual int getATRSync(ByteArray &atr) = 0;
+
+               virtual int transmit(ByteArray command, terminalTransmitCallback callback, void *userData) = 0;
+               virtual int getATR(terminalGetATRCallback callback, void *userData) = 0;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* TERMINAL_H_ */
diff --git a/common/include/TerminalInterface.h b/common/include/TerminalInterface.h
new file mode 100644 (file)
index 0000000..441082f
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef TERMINALINTERFACE_H_
+#define TERMINALINTERFACE_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+
+//typedef unsigned int terminal_handle_h;
+//
+//typedef enum
+//{
+//     TERMINAL_SUCCESS = 0,
+//
+//     TERMINAL_ERROR_UNKNOWN = -1,
+//     /* TERMINAL_ERROR_ = -, */
+//} terminal_result_e;
+//
+//typedef char *(*terminal_get_name_fn)();
+//typedef terminal_result_e (*terminal_initialize_fn)(int param1, char *param2);
+//typedef terminal_result_e (*terminal_finalize_fn)(int param1, char *param2);
+//typedef terminal_result_e (*terminal_open_fn)(int param1, char *param2, terminal_handle_h *handle);
+//typedef terminal_result_e (*terminal_close_fn)(terminal_handle_h handle);
+//typedef terminal_result_e (*terminal_transmit_fn)(terminal_handle_h handle, unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int *resp_len);
+//typedef terminal_result_e (*terminal_get_atr_fn)(terminal_handle_h handle, unsigned char *atr, unsigned int *atr_len);
+//
+//typedef struct _terminal_interfaces_t
+//{
+//     terminal_get_name_fn api_get_name;
+//     terminal_initialize_fn api_initialize;
+//     terminal_finalize_fn api_finalize;
+//     terminal_open_fn api_open;
+//     terminal_close_fn api_close;
+//     terminal_transmit_fn api_transmit;
+//     terminal_get_atr_fn api_get_atr;
+//} terminal_interfaces_t;
+//
+//typedef int (*terminal_get_interfaces_fn)(terminal_interfaces_t *apis);
+
+typedef const char *(*terminal_get_name_fn)();
+typedef void *(*terminal_create_instance_fn)();
+typedef void (*terminal_destroy_instance_fn)(void *);
+
+#endif /* TERMINALINTERFACE_H_ */
diff --git a/common/include/smartcard-types.h b/common/include/smartcard-types.h
new file mode 100644 (file)
index 0000000..15c7c5e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SMARTCARD_TYPES_H_
+#define SMARTCARD_TYPES_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef void *se_service_h;
+typedef void *reader_h;
+typedef void *session_h;
+typedef void *channel_h;
+
+typedef void (*se_service_connected_cb)(se_service_h handle, void *context);
+typedef void (*se_service_event_cb)(se_service_h handle, char *se_name, int event, void *context);
+typedef void (*se_sesrvice_error_cb)(se_service_h handle, int error, void *context);
+
+typedef void (*reader_open_session_cb)(session_h session, int error, void *user_data);
+
+typedef void (*session_open_channel_cb)(channel_h channel, int error, void *user_data);
+typedef void (*session_get_atr_cb)(unsigned char *atr, unsigned int length, int error, void *user_data);
+typedef void (*session_close_session_cb)(int error, void *user_data);
+typedef void (*session_get_channel_count_cb)(unsigned count, int error, void *user_data);
+
+typedef void (*channel_transmit_cb)(unsigned char *buffer, unsigned int length, int error, void *user_data);
+typedef void (*channel_close_cb)(int error, void *user_data);
+
+#endif /* SMARTCARD_TYPES_H_ */
diff --git a/common/smartcard-service-common.pc b/common/smartcard-service-common.pc
new file mode 100644 (file)
index 0000000..36ea9c9
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=${prefix}/bin
+includedir=${prefix}/include
+libdir=${prefix}/lib
+
+Name: smartcard-service-common
+Description: Make flags of Common library of Smartcard service
+Version: 1.0
+Requires: 
+Libs: -L${libdir} -lsmartcard-service-common
+Cflags: -I${includedir}/smartcard-service-common
\ No newline at end of file
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..c7c2e9a
--- /dev/null
@@ -0,0 +1,55 @@
+smartcard-service (0.1.0-3) unstable; urgency=low
+
+  * add an exceptional case when is openning client channel (nfc-manager)
+  * Git: slp/pkgs/s/smartcard-service
+  * Tag: smartcard-service_0.1.0-3
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com>  Fri, 20 Apr 2012 11:00:00 +0900
+
+smartcard-service (0.1.0-2) unstable; urgency=low
+
+  * add helpers for openssl and package signature
+  * Git: slp/pkgs/s/smartcard-service
+  * Tag: smartcard-service_0.1.0-2
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com>  Fri, 23 Mar 2012 12:40:00 +0900
+
+smartcard-service (0.1.0-1) unstable; urgency=low
+
+  * Upload package
+  * Git: slp/pkgs/s/smartcard-service
+  * Tag: smartcard-service_0.1.0-1
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com>  Wed, 14 Mar 2012 13:30:00 +0900
+
+smartcard-service (0.0.0-4) unstable; urgency=low
+
+  * Upload package
+  * Git: slp/pkgs/s/smartcard-service
+  * Tag: smartcard-service_0.0.0-4
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com>  Tue, 13 Mar 2012 13:10:00 +0900
+
+smartcard-service (0.0.0-3) unstable; urgency=low
+
+  * namespace and macro name change
+  * Git: slp/pkgs/s/smartcard-service
+  * Tag: smartcard-service_0.0.0-3
+
+ -- Sangsoo Lee <constant.lee@samsung.com>  Wed, 07 Mar 2012 19:26:46 +0900
+
+smartcard-service (0.0.0-2) unstable; urgency=low
+
+  * getChannelCount api add
+  * Git: slp/pkgs/s/smartcard-service
+  * Tag: smartcard-service_0.0.0-2
+
+ -- Sangsoo Lee <constant.lee@samsung.com>  Thu, 23 Feb 2012 21:10:42 +0900
+
+smartcard-service (0.0.0-1) unstable; urgency=low
+
+  * Initial release
+  * Git: slp/pkgs/s/smartcard-service
+  * Tag: smartcard-service_0.0.0-1
+
+ -- Wonkyu Kwon <wonkyu.kwon@samsung.com>  Thu, 31 Jan 2012 00:00:00 +0900
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..45a4fb7
--- /dev/null
@@ -0,0 +1 @@
+8
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..f0eabd9
--- /dev/null
@@ -0,0 +1,65 @@
+Source: smartcard-service
+Priority: extra
+Maintainer: Wonkyu Kwon <wonkyu.kwon@samsung.com>, Sangsoo Lee <constant.lee@samsung.com>, Sungjae Lim <sungjae.lim@samsung.com>, Junyong Sim <junyong.sim@samsung.com>, Sechang Sohn <sc.sohn@samsung.com>
+Build-Depends: debhelper (>= 8.0.0), libglib2.0-dev, libvconf-dev, libsecurity-server-client-dev, dlog-dev, wrt-commons-dev, libaul-1-dev, libssl-dev
+#Build-Depends: debhelper (>= 8.0.0), libglib2.0-dev, libvconf-dev, libsecurity-server-client-dev, dlog-dev, libpkcs11-helper1-dev, wrt-commons, libaul-dev, libssl-dev
+#Standards-Version: 3.9.2
+Section: mixed
+Homepage: <insert the upstream URL, if relevant>
+#Vcs-Git: git://git.debian.org/collab-maint/smartcard-service.git
+#Vcs-Browser: http://git.debian.org/?p=collab-maint/smartcard-service.git;a=summary
+
+Package: smartcard-service-common
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Common library of Smart card service
+ Common library of Smart card service
+
+Package: smartcard-service-common-dev
+Section: libdevel
+Architecture: any
+Depends: smartcard-service-common (= ${binary:Version})
+Description: Common library of Smart card service
+ Common library of Smart card service
+
+Package: smartcard-service-common-dbg
+Section: debug
+Architecture: any
+Depends: smartcard-service-common (= ${binary:Version})
+Description: Common library of Smart card service (unstripped)
+ Common library of Smart card service (unstripped)
+
+Package: smartcard-service-server
+Architecture: any
+Depends: smartcard-service-common-dev (= ${binary:Version})
+Description: Main process of Smart card service
+ Main process of Smart card service
+
+Package: smartcard-service-server-dbg
+Section: debug
+Architecture: any
+Depends: smartcard-service-server (= ${binary:Version})
+Description: Main process of Smart card service (unstripped)
+ Main process of Smart card service (unstripped)
+
+Package: smartcard-service
+Section: libs
+Architecture: any
+Depends: smartcard-service-common-dev (= ${binary:Version})
+Description: User library of Smart card service 
+ User library of Smart card service
+
+Package: smartcard-service-dev
+Section: libdevel
+Architecture: any
+Depends: smartcard-service (= ${binary:Version})
+Description: User library of Smart card service
+ User library of Smart card service
+
+Package: smartcard-service-dbg
+Section: debug
+Architecture: any
+Depends: smartcard-service (= ${binary:Version})
+Description: User library of Smart card service (unstripped)
+ User library of Smart card service (unstripped)
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..d6ef688
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+override_dh_auto_build:
+
+       cd $(CMAKE_BINARY_DIR)
+       dh_auto_build
+
+override_dh_install:
+       
+       mkdir -p $(CURDIR)/debian/tmp/etc/init.d
+       mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/
+       mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/
+       
+       cp -af $(CURDIR)/debian/smartcard-service-server.init $(CURDIR)/debian/tmp/etc/init.d/smartcard-service-server
+       ln -s ../init.d/smartcard-service-server $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S79smartcard-service-server
+       ln -s ../init.d/smartcard-service-server $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/S79smartcard-service-server
+       
+       dh_install
+       
+override_dh_installinit:
+
+%:
+       dh $@ 
+
diff --git a/debian/smartcard-service-common-dev.dirs b/debian/smartcard-service-common-dev.dirs
new file mode 100644 (file)
index 0000000..4418816
--- /dev/null
@@ -0,0 +1,2 @@
+usr/lib
+usr/include
diff --git a/debian/smartcard-service-common-dev.install b/debian/smartcard-service-common-dev.install
new file mode 100644 (file)
index 0000000..2d332a5
--- /dev/null
@@ -0,0 +1,5 @@
+usr/include/smartcard-service-common/*
+#usr/lib/lib*.a
+usr/lib/libsmartcard-service-common.so
+usr/lib/pkgconfig/smartcard-service-common.pc
+#usr/share/pkgconfig/*
diff --git a/debian/smartcard-service-common.dirs b/debian/smartcard-service-common.dirs
new file mode 100644 (file)
index 0000000..6845771
--- /dev/null
@@ -0,0 +1 @@
+usr/lib
diff --git a/debian/smartcard-service-common.install b/debian/smartcard-service-common.install
new file mode 100644 (file)
index 0000000..3b87046
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/libsmartcard-service-common.so.*
diff --git a/debian/smartcard-service-dev.dirs b/debian/smartcard-service-dev.dirs
new file mode 100644 (file)
index 0000000..4418816
--- /dev/null
@@ -0,0 +1,2 @@
+usr/lib
+usr/include
diff --git a/debian/smartcard-service-dev.install b/debian/smartcard-service-dev.install
new file mode 100644 (file)
index 0000000..a547e24
--- /dev/null
@@ -0,0 +1,5 @@
+usr/include/smartcard-service/*
+#usr/lib/lib*.a
+usr/lib/libsmartcard-service.so
+usr/lib/pkgconfig/smartcard-service.pc
+#usr/share/pkgconfig/*
diff --git a/debian/smartcard-service-server.dirs b/debian/smartcard-service-server.dirs
new file mode 100644 (file)
index 0000000..2d445a0
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin
+etc
\ No newline at end of file
diff --git a/debian/smartcard-service-server.init b/debian/smartcard-service-server.init
new file mode 100755 (executable)
index 0000000..ffc409b
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides:          smartcard-service-server
+# Required-Start:    $network $local_fs
+# Required-Stop:
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: <Enter a short description of the sortware>
+# Description:       <Enter a long description of the software>
+#                    <...>
+#                    <...>
+### END INIT INFO
+
+# Author: Wonkyu Kwon <wonkyu.kwon@samsung.com>
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/usr/bin
+DESC=smartcard-daemon      # Introduce a short description here
+NAME=smartcard-daemon      # Introduce the short server's name here
+DAEMON=/usr/bin/smartcard-daemon # Introduce the server's location here
+DAEMON_ARGS=""             # Arguments to run the daemon with
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+
+# Exit if the package is not installed
+[ -x $DAEMON ] || exit 0
+
+$DAEMON $DAEMON_ARGS &
\ No newline at end of file
diff --git a/debian/smartcard-service-server.install b/debian/smartcard-service-server.install
new file mode 100644 (file)
index 0000000..8a71c41
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin/smartcard-daemon
+etc/*
\ No newline at end of file
diff --git a/debian/smartcard-service.dirs b/debian/smartcard-service.dirs
new file mode 100644 (file)
index 0000000..6845771
--- /dev/null
@@ -0,0 +1 @@
+usr/lib
diff --git a/debian/smartcard-service.install b/debian/smartcard-service.install
new file mode 100644 (file)
index 0000000..05b76e3
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/libsmartcard-service.so.*
diff --git a/packaging/smartcard-service-server.init b/packaging/smartcard-service-server.init
new file mode 100755 (executable)
index 0000000..ffc409b
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides:          smartcard-service-server
+# Required-Start:    $network $local_fs
+# Required-Stop:
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: <Enter a short description of the sortware>
+# Description:       <Enter a long description of the software>
+#                    <...>
+#                    <...>
+### END INIT INFO
+
+# Author: Wonkyu Kwon <wonkyu.kwon@samsung.com>
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/usr/bin
+DESC=smartcard-daemon      # Introduce a short description here
+NAME=smartcard-daemon      # Introduce the short server's name here
+DAEMON=/usr/bin/smartcard-daemon # Introduce the server's location here
+DAEMON_ARGS=""             # Arguments to run the daemon with
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+
+# Exit if the package is not installed
+[ -x $DAEMON ] || exit 0
+
+$DAEMON $DAEMON_ARGS &
\ No newline at end of file
diff --git a/packaging/smartcard-service.spec b/packaging/smartcard-service.spec
new file mode 100644 (file)
index 0000000..d889a43
--- /dev/null
@@ -0,0 +1,117 @@
+Name:       smartcard-service
+Summary:    Smartcard Service FW
+Version:    0.1.0
+Release:    8
+Group:      libs
+License:    Samsung Proprietary License
+Source0:    %{name}-%{version}.tar.gz
+Source1:    smartcard-service-server.init
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(security-server)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(libssl)
+BuildRequires: pkgconfig(aul)
+BuildRequires: pkgconfig(dpl-wrt-dao-ro)
+BuildRequires: cmake
+BuildRequires: gettext-tools
+Requires(post):   /sbin/ldconfig
+Requires(post):   /usr/bin/vconftool
+requires(postun): /sbin/ldconfig
+
+%description
+Smartcard Service FW.
+
+%prep
+%setup -q
+
+%package    devel
+Summary:    smartcard service
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+smartcard service.
+
+%package -n smartcard-service-common
+Summary:    common smartcard service
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+
+%description -n smartcard-service-common
+common smartcard service.
+
+%package -n smartcard-service-common-devel
+Summary:    common smartcard service
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+
+%description -n smartcard-service-common-devel
+common smartcard service.
+
+%package -n smartcard-service-server
+Summary:    server smartcard service
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+
+%description -n smartcard-service-server
+smartcard service.
+
+%build
+mkdir obj-arm-limux-qnueabi
+cd obj-arm-limux-qnueabi
+cmake .. -DCMAKE_INSTALL_PREFIX=%{_prefix}
+#make %{?jobs:-j%jobs}
+
+%install
+cd obj-arm-limux-qnueabi
+%make_install
+%__mkdir -p  %{buildroot}/etc/init.d/
+%__mkdir -p  %{buildroot}/etc/rc.d/rc3.d/
+%__mkdir -p  %{buildroot}/etc/rc.d/rc5.d/
+%__cp -af %SOURCE1 %{buildroot}/etc/init.d/smartcard-service-server
+chmod 755 %{buildroot}/etc/init.d/smartcard-service-server
+
+%post
+/sbin/ldconfig
+
+ln -sf /etc/init.d/smartcard-service-server /etc/rc.d/rc3.d/S79smartcard-service-server
+ln -sf /etc/init.d/smartcard-service-server /etc/rc.d/rc5.d/S79smartcard-service-server
+
+%postun
+/sbin/ldconfig
+
+rm -f /etc/rc.d/rc3.d/S79smartcard-service-server
+rm -f /etc/rc.d/rc5.d/S79smartcard-service-server
+
+#%post
+# -n nfc-common-lib -p /sbin/ldconfig
+
+#%postun
+# -n nfc-common-lib -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+/usr/lib/libsmartcard-service.so.*
+
+%files  devel
+%defattr(-,root,root,-)
+/usr/include/smartcard-service/*
+/usr/lib/libsmartcard-service.so
+/usr/lib/pkgconfig/smartcard-service.pc
+
+%files -n smartcard-service-common
+%defattr(-,root,root,-)
+/usr/lib/libsmartcard-service-common.so.*
+
+%files -n smartcard-service-common-devel
+%defattr(-,root,root,-)
+/usr/include/smartcard-service-common/*
+/usr/lib/libsmartcard-service-common.so
+/usr/lib/pkgconfig/smartcard-service-common.pc
+
+%files -n smartcard-service-server
+%defattr(-,root,root,-)
+/usr/bin/smartcard-daemon
+#/usr/bin/smartcard-test-client
+/etc/init.d/smartcard-service-server
diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b80eb8e
--- /dev/null
@@ -0,0 +1,48 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(smartcard-daemon CXX)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ SRCS)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+       SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_server REQUIRED glib-2.0 gobject-2.0 security-server vconf dlog)
+
+FOREACH(flag ${pkgs_server_CFLAGS})
+       SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+MESSAGE("CHECK MODULE in ${PROJECT_NAME} ${pkgs_server_LDFLAGS}")
+
+# this for NFC flag
+
+SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -pipe -fomit-frame-pointer -Wall -Wno-trigraphs  -fno-strict-aliasing -Wl,-zdefs -fvisibility=hidden")
+
+SET(ARM_CXXFLAGS "${ARM_CXXLAGS} -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -msoft-float -Uarm -fno-common -fpic")
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+       SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM_CXXFLAGS}")
+ENDIF()
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DLOG_TAG=\"SCARD_SERVER\"")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_server_LDFLAGS} "-L../common" "-lsmartcard-service-common" "-pie -ldl")
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/server/ClientInstance.cpp b/server/ClientInstance.cpp
new file mode 100644 (file)
index 0000000..779883b
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <pthread.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ClientInstance.h"
+#include "ServerResource.h"
+#include "SignatureHelper.h"
+
+namespace smartcard_service_api
+{
+       void ClientInstance::setPID(int pid)
+       {
+               this->pid = pid;
+
+#if 0
+               if (pid > 0)
+               {
+                       certHash = SignatureHelper::getCertificationHash(pid);
+               }
+#endif
+       }
+
+       bool ClientInstance::createService(unsigned int context)
+       {
+               bool result = false;
+
+               if (getService(context) == NULL)
+               {
+                       ServiceInstance *instance = new ServiceInstance(this, context);
+                       if (instance != NULL)
+                       {
+                               mapServices.insert(make_pair(context, instance));
+                               result = true;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("alloc failed");
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("service already exist [%d]", context);
+               }
+
+               return result;
+       }
+
+       ServiceInstance *ClientInstance::getService(unsigned int context)
+       {
+               ServiceInstance *result = NULL;
+               map<unsigned int, ServiceInstance *>::iterator item;
+
+               if ((item = mapServices.find(context)) != mapServices.end())
+               {
+                       result = item->second;
+               }
+
+               return result;
+       }
+
+       void ClientInstance::removeService(unsigned int context)
+       {
+               map<unsigned int, ServiceInstance *>::iterator item;
+
+               if ((item = mapServices.find(context)) != mapServices.end())
+               {
+                       delete item->second;
+                       mapServices.erase(item);
+               }
+       }
+
+       void ClientInstance::removeServices()
+       {
+               map<unsigned int, ServiceInstance *>::iterator item;
+
+               for (item = mapServices.begin(); item != mapServices.end(); item++)
+               {
+                       delete item->second;
+               }
+
+               mapServices.clear();
+       }
+
+       bool ClientInstance::sendMessageToAllServices(int socket, Message &msg)
+       {
+               bool result = true;
+               map<unsigned int, ServiceInstance *>::iterator item;
+
+               for (item = mapServices.begin(); item != mapServices.end(); item++)
+               {
+                       if (ServerIPC::getInstance()->sendMessage(socket, &msg) == false)
+                               result = false;
+               }
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/server/ServerChannel.cpp b/server/ServerChannel.cpp
new file mode 100644 (file)
index 0000000..2ead32c
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerChannel.h"
+#include "APDUHelper.h"
+
+namespace smartcard_service_api
+{
+       ServerChannel::ServerChannel(ServerSession *session, void *caller, int channelNum, Terminal *terminal):Channel(session)
+       {
+               this->terminal = terminal;
+               this->caller = caller;
+               this->channelNum = channelNum;
+       }
+
+       ServerChannel::~ServerChannel()
+       {
+               if (isClosed() == false)
+               {
+                       closeSync();
+               }
+       }
+
+       void ServerChannel::closeSync()
+       {
+               ByteArray command, result;
+               APDUHelper apdu;
+               int rv;
+
+               if (isBasicChannel() == false)
+               {
+                       /* close channel */
+                       command = apdu.generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
+                       rv = terminal->transmitSync(command, result);
+
+                       if (rv == 0 && result.getLength() >= 2)
+                       {
+                               ResponseHelper resp(result);
+
+                               if (resp.getStatus() == 0)
+                               {
+                                       SCARD_DEBUG("close success");
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+                               }
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
+                       }
+               }
+
+               channelNum = -1;
+       }
+
+       int ServerChannel::getChannelNumber()
+       {
+               return channelNum;
+       }
+
+       int ServerChannel::transmitSync(ByteArray command, ByteArray &result)
+       {
+               APDUCommand helper;
+
+               if (session != NULL) /* admin channel */
+               {
+                       helper.setCommand(command);
+
+                       /* filter command */
+                       if ((helper.getINS() == APDUCommand::INS_SELECT_FILE && helper.getP1() == APDUCommand::P1_SELECT_BY_DF_NAME) ||
+                               (helper.getINS() == APDUCommand::INS_MANAGE_CHANNEL))
+                       {
+                               return -4; /* security reason */
+                       }
+
+                       /* insert channel ID */
+                       helper.setChannel(0, channelNum);
+
+                       helper.getBuffer(command);
+               }
+
+               SCARD_DEBUG("command [%d] : %s", command.getLength(), command.toString());
+
+               return terminal->transmitSync(command, result);
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/server/ServerDispatcher.cpp b/server/ServerDispatcher.cpp
new file mode 100644 (file)
index 0000000..48d003d
--- /dev/null
@@ -0,0 +1,594 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerDispatcher.h"
+#include "ServerResource.h"
+#include "ServerSEService.h"
+#include "ServerChannel.h"
+#include "ServerSession.h"
+#include "ServerReader.h"
+
+namespace smartcard_service_api
+{
+       ServerDispatcher::ServerDispatcher():DispatcherHelper()
+       {
+               SCARD_BEGIN();
+
+               runDispatcherThread();
+
+               SCARD_END();
+       }
+
+       ServerDispatcher::~ServerDispatcher()
+       {
+       }
+
+       ServerDispatcher *ServerDispatcher::getInstance()
+       {
+               static ServerDispatcher instance;
+
+               return &instance;
+       }
+
+       void *ServerDispatcher::dispatcherThreadFunc(DispatcherMsg *msg, void *data)
+       {
+               int socket = -1;
+               ServerResource *resource = NULL;
+
+               if (data == NULL)
+               {
+                       SCARD_DEBUG_ERR("dispatcher instance is null");
+                       return NULL;
+               }
+
+               if (msg == NULL)
+               {
+                       SCARD_DEBUG_ERR("message is null");
+                       return NULL;
+               }
+
+               resource = &ServerResource::getInstance();
+               socket = msg->getPeerSocket();
+
+               switch (msg->message)
+               {
+               /* handle message */
+               case Message::MSG_REQUEST_READERS :
+                       {
+                               SCARD_DEBUG("[MSG_REQUEST_READERS]");
+
+#if 0
+                               seService->dispatcherCallback(msg, msg->getPeerSocket());
+#else
+                               int count = 0;
+                               Message response(*msg);
+                               ByteArray info;
+                               ClientInstance *instance = NULL;
+
+                               if ((instance = resource->getClient(socket)) != NULL)
+                               {
+                                       /* update client PID */
+                                       if (instance->getPID() == -1)
+                                       {
+                                               instance->setPID(msg->error);
+                                               SCARD_DEBUG_ERR("update PID [%d]", msg->error);
+                                       }
+
+                                       /* create service */
+                                       if (resource->getService(socket, (unsigned int)msg->userParam) == NULL)
+                                       {
+                                               if (resource->createService(socket, (unsigned int)msg->userParam) == true)
+                                               {
+                                                       SCARD_DEBUG_ERR("client added : context [%d]", (unsigned int)msg->userParam);
+                                               }
+                                               else
+                                               {
+                                                       SCARD_DEBUG_ERR("createClient failed");
+
+                                                       response.param1 = 0;
+                                                       response.error = -1;
+
+                                                       /* response to client */
+                                                       ServerIPC::getInstance()->sendMessage(socket, &response);
+
+                                                       return NULL;
+                                               }
+                                       }
+
+                                       if ((count = resource->getReadersInformation(info)) > 0)
+                                       {
+                                               response.param1 = count;
+                                               response.param2 = 0;
+                                               response.error = 0;
+                                               response.data = info;
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG("no secure elements");
+
+                                               response.error = -1;
+                                       }
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG("client doesn't exist, socket [%d]", socket);
+
+                                       response.error = -1;
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+#endif
+                       }
+                       break;
+
+               case Message::MSG_REQUEST_SHUTDOWN :
+#if 0
+                       {
+                               Message response(*msg);
+
+                               SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
+
+                               if (msg->param1 != 0)
+                               {
+                                       ServerChannel *channel = NULL;
+
+                                       channel = (ServerChannel *)msg->param1;
+
+                                       channel->closeSync();
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+                       }
+#else
+                       {
+                               Message response(*msg);
+
+                               SCARD_DEBUG("[MSG_REQUEST_SHUTDOWN]");
+
+                               response.error = 0;
+
+                               resource->removeService(socket, msg->error/* service context */);
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+                       }
+#endif
+                       break;
+
+               case Message::MSG_REQUEST_OPEN_SESSION :
+#if 0
+                       {
+                               Message response(*msg);
+                               ServerReader *reader = NULL;
+                               ServerSession *session = NULL;
+
+                               SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
+
+                               if (msg->param1 != 0)
+                               {
+                                       reader = (ServerReader *)msg->param1;
+
+                                       session = reader->openSessionSync(msg->data, msg->caller);
+                               }
+
+                               /* TODO : attach atr??? */
+                               response.param1 = (unsigned int)session;
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+                       }
+#else
+                       {
+                               Message response(*msg);
+                               unsigned int handle = -1;
+
+                               SCARD_DEBUG("[MSG_REQUEST_OPEN_SESSION]");
+
+                               response.param1 = -1;
+                               response.error = -1;
+
+                               if (resource->isValidReaderHandle(msg->param1))
+                               {
+                                       handle = resource->createSession(socket, msg->error/* service context */, msg->param1, msg->data, msg->caller);
+                                       if (handle != IntegerHandle::INVALID_HANDLE)
+                                       {
+                                               response.param1 = handle;
+                                               response.error = 0;
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("createSession failed [%d]", handle);
+                                       }
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("request invalid reader handle [%d]", msg->param1);
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+                       }
+#endif
+                       break;
+
+               case Message::MSG_REQUEST_CLOSE_SESSION :
+#if 0
+                       {
+                               Message response(*msg);
+                               ServerSession *session = NULL;
+
+                               SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
+
+                               if (msg->param1 != 0)
+                               {
+                                       session = (ServerSession *)msg->param1;
+
+                                       session->closeSync();
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+                       }
+#else
+                       {
+                               Message response(*msg);
+
+                               SCARD_DEBUG("[MSG_REQUEST_CLOSE_SESSION]");
+
+                               response.param1 = -1;
+                               response.error = -1;
+
+                               if (resource->isValidSessionHandle(socket, msg->error/* service context */, msg->param1))
+                               {
+                                       resource->removeSession(socket, msg->error/* service context */, msg->param1);
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+                       }
+#endif
+                       break;
+
+               case Message::MSG_REQUEST_OPEN_CHANNEL :
+#if 0
+                       {
+                               Message response(*msg);
+                               ServerSession *session = NULL;
+
+                               SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
+
+                               if (/* check valid session handle */msg->param2 != 0)
+                               {
+                                       ServerChannel *channel = NULL;
+
+                                       session = (ServerSession *)msg->param2;
+
+                                       if (msg->param1 == 0)
+                                               channel = (ServerChannel *)session->openBasicChannelSync(msg->data, msg->caller);
+                                       else
+                                               channel = (ServerChannel *)session->openLogicalChannelSync(msg->data, msg->caller);
+
+                                       if (channel != NULL)
+                                       {
+                                               response.param1 = (unsigned int)channel;
+                                               response.param2 = channel->getChannelID();
+                                               response.error = 0;
+                                               response.data = channel->getSelectResponse();
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("channel is null.");
+
+                                               /* set error value */
+                                               response.param1 = 0;
+                                               response.param2 = 0;
+                                               response.error = -4;
+                                               response.data.releaseBuffer();
+                                       }
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("session is invalid");
+
+                                       response.param1 = 0;
+                                       response.param2 = 0;
+                                       response.error = -1;
+                                       response.data.releaseBuffer();
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+                       }
+#else
+                       {
+                               Message response(*msg);
+                               unsigned int channelID = -1;
+
+                               SCARD_DEBUG("[MSG_REQUEST_OPEN_CHANNEL]");
+
+                               response.param1 = 0;
+                               response.param2 = 0;
+                               response.error = -1;
+                               response.data.releaseBuffer();
+
+                               channelID = resource->createChannel(socket, msg->error/* service context */, msg->param2, msg->param1, msg->data);
+                               if (channelID != IntegerHandle::INVALID_HANDLE)
+                               {
+                                       ServerChannel *temp = (ServerChannel *)resource->getChannel(socket, msg->error/* service context */, channelID);
+
+                                       if (temp != NULL)
+                                       {
+                                               response.param1 = channelID;
+                                               response.param2 = temp->channelNum;
+                                               response.error = 0;
+                                               response.data = temp->selectResponse;
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("IS IT POSSIBLE??????????????????");
+                                       }
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("channel is null.");
+
+                                       /* set error value */
+                                       response.error = -4;
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+                       }
+#endif
+                       break;
+
+               case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
+                       {
+                               Message response(*msg);
+
+                               SCARD_DEBUG("[MSG_REQUEST_GET_CHANNEL_COUNT]");
+
+                               response.error = 0;
+
+                               response.param1 = resource->getChannelCount(socket, msg->error/* service context */, msg->param1);
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+                       }
+                       break;
+
+               case Message::MSG_REQUEST_CLOSE_CHANNEL :
+#if 0
+                       {
+                               Message response(*msg);
+
+                               SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
+
+                               if (msg->param1 != 0)
+                               {
+                                       ServerChannel *channel = NULL;
+
+                                       channel = (ServerChannel *)msg->param1;
+
+                                       channel->closeSync();
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+                       }
+#else
+                       {
+                               Message response(*msg);
+
+                               SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
+
+                               response.error = 0;
+
+                               if (resource->getChannel(socket, msg->error/* service context */, msg->param1) != NULL)
+                               {
+                                       resource->removeChannel(socket, msg->error/* service context */, msg->param1);
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+                       }
+#endif
+                       break;
+
+               case Message::MSG_REQUEST_GET_ATR :
+#if 0
+                       {
+                               Message response(*msg);
+
+                               SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
+
+                               if (msg->param1 != 0)
+                               {
+                                       ServerChannel *channel = NULL;
+
+                                       channel = (ServerChannel *)msg->param1;
+
+                                       channel->closeSync();
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+                       }
+#else
+                       {
+                               int rv;
+                               Message response(*msg);
+                               ByteArray result;
+                               ServiceInstance *client = NULL;
+
+                               SCARD_DEBUG("[MSG_REQUEST_GET_ATR]");
+
+                               response.param1 = 0;
+                               response.param2 = 0;
+                               response.error = -1;
+
+                               if ((client = resource->getService(socket, msg->error/* service context */)) != NULL)
+                               {
+                                       Terminal *terminal = NULL;
+
+                                       if ((terminal = client->getTerminal(msg->param1)) != NULL)
+                                       {
+                                               if ((rv = terminal->getATRSync(result)) == 0)
+                                               {
+                                                       response.data = result;
+                                                       response.error = 0;
+                                               }
+                                               else
+                                               {
+                                                       SCARD_DEBUG_ERR("transmit failed [%d]", rv);
+
+                                                       response.error = rv;
+                                               }
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("getTerminal failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
+                                       }
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("getClient failed : socket [%d], context [%d], session [%d]", socket, msg->error/* service context */, msg->param1);
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+                       }
+#endif
+                       break;
+
+               case Message::MSG_REQUEST_TRANSMIT :
+#if 0
+                       {
+                               Message response(*msg);
+                               ByteArray result;
+                               int rv;
+
+                               SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
+
+                               if (msg->param1 != 0)
+                               {
+                                       ServerChannel *channel = NULL;
+
+                                       channel = (ServerChannel *)msg->param1;
+
+                                       if ((rv = channel->transmitSync(msg->data, result)) == 0)
+                                       {
+                                               response.data = result;
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("transmit failed [%d]", rv);
+                                       }
+                               }
+
+//                             if (resource->isValidChannelHandle((void *)msg->param1))
+//                             {
+//                             }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+                       }
+#else
+                       {
+                               int rv;
+                               Message response(*msg);
+                               ByteArray result;
+                               Channel *channel = NULL;
+
+                               SCARD_DEBUG("[MSG_REQUEST_TRANSMIT]");
+
+                               response.param1 = 0;
+                               response.param2 = 0;
+                               response.error = -1;
+
+                               if ((channel = resource->getChannel(socket, msg->error/* service context */, msg->param1)) != NULL)
+                               {
+                                       if ((rv = channel->transmitSync(msg->data, result)) == 0)
+                                       {
+                                               response.data = result;
+                                               response.error = 0;
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("transmit failed [%d]", rv);
+
+                                               response.error = rv;
+                                       }
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("invalid handle : socket [%d], context [%d], channel [%d]", socket, msg->error/* service context */, msg->param1);
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+                       }
+#endif
+                       break;
+
+               case Message::MSG_OPERATION_RELEASE_CLIENT :
+#if 0
+                       {
+                               Message response(*msg);
+
+                               SCARD_DEBUG("[MSG_REQUEST_CLOSE_CHANNEL]");
+
+                               if (msg->param1 != 0)
+                               {
+                                       ServerChannel *channel = NULL;
+
+                                       channel = (ServerChannel *)msg->param1;
+
+                                       channel->closeSync();
+                               }
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(msg->getPeerSocket(), &response);
+                       }
+#else
+                       {
+                               SCARD_DEBUG("[MSG_OPERATION_RELEASE_CLIENT]");
+
+                               resource->removeClient(msg->param1);
+                       }
+#endif
+                       break;
+
+               default :
+                       SCARD_DEBUG("unknown message [%s], socket [%d]", msg->toString(), socket);
+                       break;
+               }
+
+               return NULL;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/server/ServerIPC.cpp b/server/ServerIPC.cpp
new file mode 100644 (file)
index 0000000..d44784e
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerIPC.h"
+#include "ServerResource.h"
+#include "ServerDispatcher.h"
+
+namespace smartcard_service_api
+{
+       ServerIPC::ServerIPC():IPCHelper()
+       {
+               SCARD_BEGIN();
+
+               setDispatcher(ServerDispatcher::getInstance());
+
+               SCARD_END();
+       }
+
+       ServerIPC::~ServerIPC()
+       {
+       }
+
+       ServerIPC *ServerIPC::getInstance()
+       {
+               static ServerIPC instance;
+
+               return &instance;
+       }
+
+       bool ServerIPC::acceptClient()
+       {
+               GIOCondition condition = (GIOCondition)(G_IO_ERR | G_IO_HUP | G_IO_IN);
+               socklen_t addrlen = 0;
+               int client_sock_fd = 0;
+               GIOChannel *client_channel = NULL;
+               int client_src_id;
+
+               SCARD_DEBUG("client is trying to connect to server");
+
+               pthread_mutex_lock(&ipcLock);
+               client_sock_fd = accept(ipcSocket, NULL, &addrlen);
+               pthread_mutex_unlock(&ipcLock);
+
+               if (client_sock_fd < 0)
+               {
+                       SCARD_DEBUG_ERR("can not accept client");
+                       goto ERROR;
+               }
+
+               SCARD_DEBUG("client is accepted by server");
+
+               if ((client_channel = g_io_channel_unix_new(client_sock_fd)) == NULL)
+               {
+                       SCARD_DEBUG_ERR("create new g io channel is failed");
+                       goto ERROR;
+               }
+
+               if ((client_src_id = g_io_add_watch(client_channel, condition, &IPCHelper::channelCallbackFunc, this)) < 1)
+               {
+                       SCARD_DEBUG_ERR("add io callback is failed");
+                       goto ERROR;
+               }
+
+               SCARD_DEBUG("client socket is bound with g_io_channel");
+
+               if (ServerResource::getInstance().createClient(client_channel, client_sock_fd, client_src_id, 0, -1) == false)
+               {
+                       SCARD_DEBUG_ERR("failed to add client");
+               }
+
+               return true;
+
+ERROR :
+               if (client_channel != NULL)
+               {
+                       g_io_channel_unref(client_channel);
+               }
+
+               if (client_sock_fd != -1)
+               {
+                       shutdown(client_sock_fd, SHUT_RDWR);
+                       close(client_sock_fd);
+               }
+
+               return false;
+       }
+
+       void ServerIPC::restartServerIPC()
+       {
+               if (watchId != 0)
+               {
+                       g_source_remove(watchId);
+                       watchId = 0;
+               }
+
+               if (ioChannel != NULL)
+               {
+                       g_io_channel_unref(ioChannel);
+                       ioChannel = NULL;
+               }
+
+               if (ipcSocket != -1)
+               {
+                       shutdown(ipcSocket, SHUT_RDWR);
+                       close(ipcSocket);
+
+                       ipcSocket = -1;
+               }
+
+               createListenSocket();
+       }
+
+       void ServerIPC::releaseClient(void *channel, int socket, int watchID)
+       {
+               if (watchID != 0)
+               {
+                       g_source_remove(watchID);
+               }
+
+               if (channel != NULL)
+               {
+                       g_io_channel_unref((GIOChannel *)channel);
+               }
+
+               if (socket >= 0)
+               {
+                       shutdown(socket, SHUT_RDWR);
+                       close(socket);
+               }
+       }
+
+       int ServerIPC::handleIOErrorCondition(void *channel, GIOCondition condition)
+       {
+               SCARD_BEGIN();
+
+               if(channel == ioChannel)
+               {
+                       SCARD_DEBUG("server socket is closed");
+                       restartServerIPC();
+               }
+               else
+               {
+                       DispatcherMsg *dispMsg = NULL;
+                       int peerSocket = g_io_channel_unix_get_fd((GIOChannel *)channel);
+
+                       SCARD_DEBUG("client socket is closed, socket [%d]", peerSocket);
+
+                       /* push messsage to dispatcher */
+                       dispMsg = new DispatcherMsg();
+
+                       dispMsg->message = Message::MSG_OPERATION_RELEASE_CLIENT;
+                       dispMsg->param1 = peerSocket;
+                       dispMsg->setPeerSocket(peerSocket);
+
+                       /* push to dispatcher */
+                       ServerDispatcher::getInstance()->pushMessage(dispMsg);
+               }
+
+               SCARD_END();
+
+               return FALSE;
+       }
+
+       int ServerIPC::handleInvalidSocketCondition(void *channel, GIOCondition condition)
+       {
+               SCARD_BEGIN();
+               SCARD_END();
+
+               return FALSE;
+       }
+
+       int ServerIPC::handleIncomingCondition(void *channel, GIOCondition condition)
+       {
+               int result = FALSE;
+
+               SCARD_BEGIN();
+
+               if(channel == ioChannel)
+               {
+                       /* connect state. should accept */
+                       SCARD_DEBUG("new client connected");
+
+                       result = acceptClient();
+               }
+               else
+               {
+                       int peerSocket = g_io_channel_unix_get_fd((GIOChannel *)channel);
+
+                       SCARD_DEBUG("data incomming from [%d]", peerSocket);
+
+                       if (peerSocket >= 0)
+                       {
+                               Message *msg = NULL;
+
+                               /* read message */
+                               if ((msg = retrieveMessage(peerSocket)) != NULL)
+                               {
+                                       DispatcherMsg *dispMsg = new DispatcherMsg(msg, peerSocket);
+
+                                       /* push to dispatcher */
+                                       ServerDispatcher::getInstance()->pushMessage(dispMsg);
+
+                                       result = TRUE;
+
+                                       delete msg;
+                               }
+                               else
+                               {
+                                       /* clear client connection */
+                                       SCARD_DEBUG_ERR("retrieve message failed, socket [%d]", peerSocket);
+                               }
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("client context doesn't exist, socket [%d]", peerSocket);
+                       }
+               }
+
+               SCARD_END();
+
+               return result;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/server/ServerReader.cpp b/server/ServerReader.cpp
new file mode 100644 (file)
index 0000000..7529b7f
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerSEService.h"
+#include "ServerReader.h"
+#include "GPSEACL.h"
+
+namespace smartcard_service_api
+{
+       ServerReader::ServerReader(ServerSEService *seService, char *name, Terminal *terminal):ReaderHelper()
+       {
+               unsigned int length = 0;
+
+               acList = NULL;
+
+               if (seService == NULL || name == NULL || strlen(name) == 0 || terminal == NULL)
+               {
+                       SCARD_DEBUG_ERR("invalid param");
+
+                       return;
+               }
+
+               this->terminal = terminal;
+               this->seService = seService;
+
+               length = strlen(name);
+               length = (length < sizeof(this->name)) ? length : sizeof(this->name);
+               memcpy(this->name, name, length);
+
+               /* open admin channel */
+               adminChannel = new ServerChannel(NULL, NULL, 0, terminal);
+               if (adminChannel == NULL)
+               {
+                       SCARD_DEBUG_ERR("alloc failed");
+               }
+       }
+
+       ServerReader::~ServerReader()
+       {
+               closeSessions();
+
+               if (acList != NULL)
+               {
+                       delete acList;
+                       acList = NULL;
+               }
+
+               if (adminChannel != NULL)
+               {
+                       delete adminChannel;
+                       adminChannel = NULL;
+               }
+       }
+
+       void ServerReader::closeSessions()
+       {
+               size_t i;
+
+               for (i = 0; i < sessions.size(); i++)
+               {
+                       if (sessions[i] != NULL)
+                               ((ServerSession *)sessions[i])->closeSync();
+               }
+
+               sessions.clear();
+       }
+
+       AccessControlList *ServerReader::getAccessControlList()
+       {
+               if (acList == NULL)
+               {
+                       /* load access control */
+                       acList = new GPSEACL(adminChannel);
+                       if (acList != NULL)
+                       {
+                               acList->loadACL();
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("alloc failed");
+                       }
+               }
+
+               return acList;
+       }
+
+       ServerSession *ServerReader::openSessionSync()
+       {
+               return openSessionSync(ByteArray::EMPTY, NULL);
+       }
+
+       ServerSession *ServerReader::openSessionSync(ByteArray packageCert, void *caller)
+       {
+               ServerSession *session = NULL;
+
+               session = new ServerSession(this, packageCert, caller, terminal);
+               if (session == NULL)
+                       return session;
+
+               sessions.push_back(session);
+
+               return session;
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/server/ServerResource.cpp b/server/ServerResource.cpp
new file mode 100644 (file)
index 0000000..f8ad898
--- /dev/null
@@ -0,0 +1,816 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <dirent.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerResource.h"
+#include "TerminalInterface.h"
+#include "APDUHelper.h"
+#include "SignatureHelper.h"
+#include "GPSEACL.h"
+
+namespace smartcard_service_api
+{
+       unsigned int IntegerHandle::newHandle = 0;
+       set<unsigned int> IntegerHandle::setHandles;
+       PMutex IntegerHandle::mutexLock;
+
+       unsigned int IntegerHandle::assignHandle()
+       {
+               SCOPE_LOCK(mutexLock)
+               {
+                       pair<set<unsigned int>::iterator, bool> result;
+
+                       do
+                       {
+                               newHandle++;
+                               if (newHandle == (unsigned int)-1)
+                               {
+                                       newHandle = 1;
+                               }
+
+                               result = setHandles.insert(newHandle);
+
+                       }
+                       while (!result.second);
+               }
+
+               SCARD_DEBUG("assign handle : newHandle [%d]", newHandle);
+
+               return newHandle;
+       }
+
+       void IntegerHandle::releaseHandle(unsigned int handle)
+       {
+               SCARD_DEBUG("will be released : Handle [%d]", handle);
+
+               SCOPE_LOCK(mutexLock)
+               {
+                       setHandles.erase(handle);
+               }
+       }
+
+#define OMAPI_SE_PATH "/usr/lib/se"
+
+       ServerResource::ServerResource()
+       {
+               SCARD_BEGIN();
+
+               serverIPC = ServerIPC::getInstance();
+               serverDispatcher = ServerDispatcher::getInstance();
+
+#if 1
+               loadSecureElements();
+#endif
+               SCARD_END();
+       }
+
+       ServerResource::~ServerResource()
+       {
+       }
+
+       ServerResource &ServerResource::getInstance()
+       {
+               static ServerResource serverResource;
+
+               return serverResource;
+       }
+
+       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);
+                       if (instance != NULL)
+                       {
+                               mapClients.insert(make_pair(socket, instance));
+                               result = true;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("alloc failed");
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("client already exist [%d]", socket);
+               }
+
+               return result;
+       }
+
+       ClientInstance *ServerResource::getClient(int socket)
+       {
+               ClientInstance *result = NULL;
+               map<int, ClientInstance *>::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;
+
+               if ((item = mapClients.find(socket)) != mapClients.end())
+               {
+                       if (item->second->getPID() < 0)
+                               item->second->setPID(pid);
+               }
+       }
+
+       void ServerResource::removeClient(int socket)
+       {
+               map<int, ClientInstance *>::iterator item;
+
+               if ((item = mapClients.find(socket)) != mapClients.end())
+               {
+                       ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
+
+                       delete item->second;
+                       mapClients.erase(item);
+               }
+               else
+               {
+                       SCARD_DEBUG("client exists already [%d]", socket);
+               }
+       }
+
+       void ServerResource::removeClients()
+       {
+               map<int, ClientInstance *>::iterator item;
+
+               for (item = mapClients.begin(); item != mapClients.end(); item++)
+               {
+                       ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
+
+                       delete item->second;
+               }
+
+               mapClients.clear();
+       }
+
+       bool ServerResource::createService(int socket, unsigned int context)
+       {
+               bool result = false;
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(socket)) != NULL)
+               {
+                       if ((result = instance->createService(context)) == false)
+                       {
+                               SCARD_DEBUG_ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+               }
+
+               return result;
+       }
+
+       ServiceInstance *ServerResource::getService(int socket, unsigned int context)
+       {
+               ServiceInstance *result = NULL;
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(socket)) != NULL)
+               {
+                       result = instance->getService(context);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+               }
+
+               return result;
+       }
+
+       void ServerResource::removeService(int socket, unsigned int context)
+       {
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(socket)) != NULL)
+               {
+                       instance->removeService(context);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+               }
+       }
+
+       void ServerResource::removeServices(int socket)
+       {
+               ClientInstance *instance = NULL;
+
+               if ((instance = getClient(socket)) != NULL)
+               {
+                       instance->removeServices();
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
+               }
+       }
+
+       Terminal *ServerResource::getTerminal(unsigned int terminalID)
+       {
+               Terminal *result = NULL;
+               map<unsigned int, Terminal *>::iterator item;
+
+               if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
+               {
+                       result = item->second;
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("Terminal doesn't exist [%d]", terminalID);
+               }
+
+               return result;
+       }
+
+       Terminal *ServerResource::getTerminal(const char *name)
+       {
+               Terminal *result = NULL;
+               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->second;
+                               break;
+                       }
+               }
+
+               return result;
+       }
+
+       unsigned int ServerResource::createSession(int socket, unsigned int context, unsigned int terminalID, ByteArray packageCert, void *caller)
+       {
+               unsigned int result = -1;
+               Terminal *temp = NULL;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(socket, context)) != NULL)
+               {
+                       if ((temp = getTerminal(terminalID)) != NULL)
+                       {
+                               result = instance->openSession(temp, packageCert, caller);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+               }
+
+               return result;
+       }
+
+       ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
+       {
+               ServerSession *result = NULL;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(socket, context)) != NULL)
+               {
+                       result = instance->getSession(sessionID);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
+               }
+
+               return result;
+       }
+
+       unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
+       {
+               unsigned int result = -1;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(socket, context)) != NULL)
+               {
+                       result = instance->getChannelCountBySession(sessionID);
+               }
+               else
+               {
+                       SCARD_DEBUG_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;
+
+               if ((instance = getService(socket, context)) != NULL)
+               {
+                       instance->closeSession(sessionID);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+               }
+       }
+
+       unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
+       {
+               unsigned int result = -1;
+               ServiceInstance *client = NULL;
+
+               if ((client = getService(socket, context)) != NULL)
+               {
+                       if (client->isVaildSessionHandle(sessionID) == true)
+                       {
+                               AccessControlList *acList = NULL;
+                               ServerSession *session = NULL;
+                               Terminal *terminal = NULL;
+
+                               terminal = client->getTerminal(sessionID);
+                               session = client->getSession(sessionID);
+                               if (terminal != NULL && session != NULL)
+                               {
+                                       int rv = 0;
+                                       int channelNum = 0;
+                                       ByteArray certHash;
+                                       ByteArray selectResponse;
+                                       ByteArray command;
+                                       char filename[1024] = { 0, };
+
+                                       /* check exceptional case */
+                                       SignatureHelper::getProcessName(client->getParent()->getPID(), filename, sizeof(filename));
+                                       if (strncmp(filename, "ozD3Dw1MZruTDKHWGgYaDib2B2LV4/nfT+8b/g1Vsk8=", sizeof(filename)) != 0)
+                                       {
+#if 1
+                                               certHash = session->packageCert;
+#else
+                                               certHash = client->getParent()->getCertificationHash();
+#endif
+                                               /* request open channel sequence */
+                                               if ((acList = getAccessControlList(terminal)) == NULL)
+                                               {
+                                                       SCARD_DEBUG_ERR("acList is null");
+
+                                                       return result;
+                                               }
+
+                                               if (acList->isAuthorizedAccess(aid, certHash) == false)
+                                               {
+                                                       SCARD_DEBUG_ERR("unauthorized access, aid %s, hash %s", aid.toString(), certHash.toString());
+
+                                                       return result;
+                                               }
+                                       }
+
+                                       if (channelType == 1)
+                                       {
+                                               ByteArray response;
+
+                                               /* open channel */
+                                               command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
+                                               rv = terminal->transmitSync(command, response);
+
+                                               if (rv == 0 && response.getLength() >= 2)
+                                               {
+                                                       ResponseHelper resp(response);
+
+                                                       if (resp.getStatus() == 0)
+                                                       {
+                                                               channelNum = resp.getDataField()[0];
+
+                                                               SCARD_DEBUG("channelNum [%d]", channelNum);
+                                                       }
+                                                       else
+                                                       {
+                                                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), response[response.getLength() - 2], response[response.getLength() - 1]);
+
+                                                               return result;
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+
+                                                       return result;
+                                               }
+                                       }
+
+                                       /* select aid */
+                                       command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelNum, aid);
+                                       rv = terminal->transmitSync(command, selectResponse);
+                                       if (rv == 0 && selectResponse.getLength() >= 2)
+                                       {
+                                               ResponseHelper resp(selectResponse);
+
+                                               if (resp.getStatus() == 0)
+                                               {
+                                                       result = client->openChannel(sessionID, channelNum);
+                                                       if (result != IntegerHandle::INVALID_HANDLE)
+                                                       {
+                                                               ServerChannel *temp = (ServerChannel *)client->getChannel(result);
+                                                               if (temp != NULL)
+                                                               {
+                                                                       /* set select response */
+                                                                       temp->selectResponse = selectResponse;
+                                                               }
+                                                               else
+                                                               {
+                                                                       SCARD_DEBUG_ERR("IS IT POSSIBLE??????????????????");
+                                                               }
+                                                       }
+                                                       else
+                                                       {
+                                                               SCARD_DEBUG_ERR("channel is null.");
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), selectResponse[selectResponse.getLength() - 2], selectResponse[selectResponse.getLength() - 1]);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, selectResponse.getLength());
+                                       }
+
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
+                               }
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("getClient is failed [%d] [%d]", socket, context);
+               }
+
+               return result;
+       }
+
+       Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
+       {
+               Channel *result = NULL;
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(socket, context)) != NULL)
+               {
+                       result = instance->getChannel(channelID);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
+               }
+
+               return result;
+       }
+
+       void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
+       {
+               ServiceInstance *instance = NULL;
+
+               if ((instance = getService(socket, context)) != NULL)
+               {
+                       instance->closeChannel(channelID);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+               }
+       }
+
+       AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
+       {
+               AccessControlList *result = NULL;
+               map<Terminal *, AccessControlList *>::iterator item;
+
+               if ((item = mapACL.find(terminal)) == mapACL.end())
+               {
+                       ServerChannel *channel = new ServerChannel(NULL, NULL, 0, terminal);
+                       if (channel != NULL)
+                       {
+                               /* load access control */
+                               result = new GPSEACL(channel);
+                               if (result != NULL)
+                               {
+                                       result->loadACL();
+
+                                       mapACL.insert(make_pair(terminal, result));
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("alloc failed");
+                               }
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("alloc failed");
+                       }
+               }
+               else
+               {
+                       result = item->second;
+               }
+
+               return result;
+       }
+
+       Terminal *ServerResource::createInstance(void *library)
+       {
+               Terminal *terminal = NULL;
+               terminal_create_instance_fn createInstance = NULL;
+
+               /* create se instance */
+               createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
+               if (createInstance != NULL)
+               {
+                       terminal = (Terminal *)createInstance();
+                       if (terminal != NULL)
+                       {
+                               SCARD_DEBUG("terminal [%p]", terminal);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("terminal is null");
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
+               }
+
+               return terminal;
+       }
+
+       bool ServerResource::appendSELibrary(char *library)
+       {
+               void *libHandle = NULL;
+               bool result = false;
+
+               libHandle = dlopen(library, RTLD_LAZY);
+               if (libHandle != NULL)
+               {
+                       Terminal *terminal = NULL;
+
+                       terminal = createInstance(libHandle);
+                       if (terminal != NULL)
+                       {
+                               unsigned int handle = IntegerHandle::assignHandle();
+
+                               mapTerminals.insert(make_pair(handle, terminal));
+                               libraries.push_back(libHandle);
+
+                               terminal->setStatusCallback(&ServerResource::terminalCallback);
+
+                               SCARD_DEBUG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
+
+                               result = true;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("terminal is null [%s]", library);
+
+                               dlclose(libHandle);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
+               }
+
+               return result;
+       }
+
+       int ServerResource::loadSecureElements()
+       {
+               int result;
+               void *libHandle;
+               DIR *dir = NULL;
+               struct dirent *entry = NULL;
+
+               if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
+               {
+                       while ((entry = readdir(dir)) != NULL)
+                       {
+                               if (strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
+                               {
+                                       char fullPath[1024] = { 0, };
+
+                                       /* TODO : need additional name rule :) */
+
+                                       /* open each files */
+                                       libHandle = NULL;
+
+                                       snprintf(fullPath, sizeof(fullPath), "%s/%s", OMAPI_SE_PATH, entry->d_name);
+
+                                       SCARD_DEBUG("se name [%s]", fullPath);
+
+                                       result = appendSELibrary(fullPath);
+                               }
+                       }
+
+                       closedir(dir);
+
+                       result = 0;
+               }
+               else
+               {
+                       result = -1;
+               }
+
+               return result;
+       }
+
+       void ServerResource::unloadSecureElements()
+       {
+               size_t i;
+               map<unsigned int, Terminal *>::iterator item;
+
+               for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
+               {
+                       item->second->finalize();
+
+                       IntegerHandle::releaseHandle(item->first);
+               }
+
+               mapTerminals.clear();
+
+               for (i = 0; i < libraries.size(); i++)
+               {
+                       if (libraries[i] != NULL)
+                               dlclose(libraries[i]);
+               }
+
+               libraries.clear();
+       }
+
+       bool ServerResource::isValidReaderHandle(unsigned int reader)
+       {
+               return (getTerminal(reader) != NULL);
+       }
+
+       bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
+       {
+               ServiceInstance *instance = NULL;
+
+               return (((instance = getService(socket, context)) != NULL) && (getService(socket, context)->isVaildSessionHandle(session)));
+       }
+
+       int ServerResource::getReadersInformation(ByteArray &info)
+       {
+               int result = 0;
+               unsigned char *buffer = NULL;
+               unsigned int length = 0;
+               unsigned int offset = 0;
+               unsigned int nameLen = 0;
+
+               if (mapTerminals.size() > 0)
+               {
+                       map<unsigned int, Terminal *>::iterator item;
+
+                       for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
+                       {
+                               if (item->second->isSecureElementPresence())
+                               {
+                                       length += sizeof(nameLen) + strlen(item->second->getName()) + sizeof(unsigned int);
+                                       result++;
+                               }
+                       }
+
+                       buffer = new unsigned char[length];
+                       if (buffer != NULL)
+                       {
+                               memset(buffer, 0, length);
+
+                               for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
+                               {
+                                       if (item->second->isSecureElementPresence())
+                                       {
+                                               nameLen = strlen(item->second->getName());
+
+                                               memcpy(buffer + offset, &nameLen, sizeof(nameLen));
+                                               offset += sizeof(nameLen);
+
+                                               memcpy(buffer + offset, item->second->getName(), nameLen);
+                                               offset += nameLen;
+
+                                               memcpy(buffer + offset, &item->first, sizeof(unsigned int));
+                                               offset += sizeof(unsigned int);
+                                       }
+                               }
+
+                               info.setBuffer(buffer, length);
+                               delete []buffer;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("alloc failed");
+                               result = -1;
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG("no secure element");
+               }
+
+               return result;
+       }
+
+       bool ServerResource::sendMessageToAllClients(Message &msg)
+       {
+               bool result = true;
+               map<int, ClientInstance *>::iterator item;
+
+               for (item = mapClients.begin(); item != mapClients.end(); item++)
+               {
+                       if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
+                               result = false;
+               }
+
+               return result;
+       }
+
+       void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
+       {
+               SCARD_BEGIN();
+
+               switch (event)
+               {
+               case Terminal::NOTIFY_SE_AVAILABLE :
+                       {
+                               Message msg;
+
+                               SCARD_DEBUG("[NOTIFY_SE_AVAILABLE]");
+
+                               SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
+
+                               /* send all client to refresh reader */
+                               msg.message = msg.MSG_NOTIFY_SE_INSERTED;
+                               msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+
+                               ServerResource::getInstance().sendMessageToAllClients(msg);
+                       }
+                       break;
+
+               case Terminal::NOTIFY_SE_NOT_AVAILABLE :
+                       {
+                               Message msg;
+
+                               SCARD_DEBUG("[NOTIFY_SE_NOT_AVAILABLE]");
+
+                               SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
+
+                               /* send all client to refresh reader */
+                               msg.message = msg.MSG_NOTIFY_SE_REMOVED;
+                               msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+
+                               ServerResource::getInstance().sendMessageToAllClients(msg);
+                       }
+                       break;
+
+               default :
+                       break;
+               }
+
+               SCARD_END();
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/server/ServerSEService.cpp b/server/ServerSEService.cpp
new file mode 100644 (file)
index 0000000..0de9769
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <errno.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Message.h"
+#include "TerminalInterface.h"
+#include "ServerSEService.h"
+#include "ServerResource.h"
+
+namespace smartcard_service_api
+{
+#define OMAPI_SE_PATH "/usr/lib/se"
+
+       ServerSEService::ServerSEService():SEServiceHelper()
+       {
+#if 0
+               openSELibraries();
+#endif
+       }
+
+       ServerSEService::~ServerSEService()
+       {
+#if 0
+               closeSELibraries();
+#endif
+       }
+
+       ServerSEService &ServerSEService::getInstance()
+       {
+               static ServerSEService seService;
+
+               return seService;
+       }
+
+       Terminal *ServerSEService::createInstance(void *library)
+       {
+               Terminal *terminal = NULL;
+               terminal_create_instance_fn createInstance = NULL;
+
+               /* create se instance */
+               createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
+               if (createInstance != NULL)
+               {
+                       terminal = (Terminal *)createInstance();
+                       if (terminal != NULL)
+                       {
+                               SCARD_DEBUG("terminal [%p]", terminal);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("terminal is null");
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
+               }
+
+               return terminal;
+       }
+
+       bool ServerSEService::appendSELibrary(char *library)
+       {
+               void *libHandle = NULL;
+               bool result = false;
+
+               libHandle = dlopen(library, RTLD_LAZY);
+               if (libHandle != NULL)
+               {
+                       Terminal *terminal = NULL;
+
+                       terminal = createInstance(libHandle);
+                       if (terminal != NULL)
+                       {
+                               SCARD_DEBUG("SE info : [%s] [%s]", library, terminal->getName());
+
+                               libraries.push_back(libHandle);
+
+                               pair<char *, Terminal *> newPair(terminal->getName(), terminal);
+                               mapTerminals.insert(newPair);
+
+                               if (terminal->isSecureElementPresence() == true)
+                               {
+                                       ServerReader *reader = new ServerReader(this, terminal->getName(), terminal);
+                                       if (reader != NULL)
+                                       {
+                                               SCARD_DEBUG("register success [%s]", terminal->getName());
+
+                                               readers.push_back(reader);
+                                       }
+                                       else
+                                       {
+                                               SCARD_DEBUG_ERR("ServerReader alloc failed [%s]", terminal->getName());
+                                               /* throw exception */
+                                       }
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG("SE is not ready [%s]", terminal->getName());
+                               }
+
+                               result = true;
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("createInstance failed [%s]", library);
+
+                               dlclose(libHandle);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
+               }
+
+               return result;
+       }
+
+       int ServerSEService::openSELibraries()
+       {
+               int result;
+               void *libHandle;
+               DIR *dir = NULL;
+               struct dirent *entry = NULL;
+
+               if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
+               {
+                       while ((entry = readdir(dir)) != NULL)
+                       {
+                               if (strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
+                               {
+                                       char fullPath[1024] = { 0, };
+
+                                       /* need additional name rule :) */
+                                       /* open each files */
+                                       libHandle = NULL;
+
+                                       snprintf(fullPath, sizeof(fullPath), "%s/%s", OMAPI_SE_PATH, entry->d_name);
+
+                                       SCARD_DEBUG("se name [%s]", fullPath);
+
+                                       result = appendSELibrary(fullPath);
+                               }
+                       }
+
+                       closedir(dir);
+
+                       result = 0;
+               }
+               else
+               {
+                       result = -1;
+               }
+
+               return result;
+       }
+
+       void ServerSEService::closeSELibraries()
+       {
+               if (libraries.size() > 0)
+               {
+                       size_t i;
+
+                       for (i = 0; i < libraries.size(); i++)
+                       {
+                               if (libraries[i] != NULL)
+                                       dlclose(libraries[i]);
+                       }
+               }
+       }
+
+#if 0
+       bool ServerSEService::isValidReaderHandle(void *handle)
+       {
+               bool result = false;
+               size_t i;
+
+               for (i = 0; i < readers.size(); i++)
+               {
+                       if ((void *)readers[i] == handle)
+                       {
+                               result =  true;
+                               break;
+                       }
+               }
+
+               return false;
+       }
+#endif
+
+#if 0
+       bool ServerSEService::dispatcherCallback(void *message, int socket)
+       {
+               unsigned char *buffer = NULL;
+               unsigned int length = 0;
+               unsigned int offset = 0;
+               unsigned int nameLen = 0;
+
+               ByteArray result;
+               vector<ReaderHelper *> readers;
+               Message response(*(Message *)message);
+
+//             response.param1 = resource->getSECount();
+//             response.data = resource->getReadersInformation();
+
+               readers = ServerSEService::getInstance().getReaders();
+               if (readers.size() > 0)
+               {
+                       size_t i;
+                       ServerReader *reader;
+
+                       for (i = 0; i < readers.size(); i++)
+                       {
+                               reader = (ServerReader *)readers[i];
+
+                               /* check se existance */
+                               if (reader->isSecureElementPresent() == true)
+                               {
+                                       length += sizeof(nameLen) + strlen(reader->getName()) + sizeof(reader);
+                               }
+                       }
+
+                       if (length > 0)
+                       {
+                               buffer = new unsigned char[length];
+                               if (buffer == NULL)
+                               {
+                                       SCARD_DEBUG_ERR("alloc failed");
+
+                                       return false;
+                               }
+                               memset(buffer, 0, length);
+
+                               for (i = 0; i < readers.size(); i++)
+                               {
+                                       reader = (ServerReader *)readers[i];
+
+                                       /* check se existance */
+                                       if (reader->isSecureElementPresent() == true)
+                                       {
+                                               nameLen = strlen(reader->getName());
+
+                                               memcpy(buffer + offset, &nameLen, sizeof(nameLen));
+                                               offset += sizeof(nameLen);
+
+                                               memcpy(buffer + offset, reader->getName(), nameLen);
+                                               offset += nameLen;
+
+                                               memcpy(buffer + offset, &reader, sizeof(reader));
+                                               offset += sizeof(reader);
+                                       }
+                               }
+
+                               result.setBuffer(buffer, length);
+                       }
+               }
+
+               response.param1 = readers.size();
+               response.data = result;
+
+               /* response to client */
+               ServerIPC::getInstance()->sendMessage(socket, &response);
+
+               return true;
+       }
+#else
+       bool ServerSEService::dispatcherCallback(void *message, int socket)
+       {
+               int count = 0;
+               ByteArray info;
+               Message *msg = (Message *)message;
+               Message response(*msg);
+               ServerResource &resource = ServerResource::getInstance();
+
+               if (resource.getService(socket, msg->error) == NULL)
+               {
+                       if (resource.createService(socket, msg->error) == true)
+                       {
+                               SCARD_DEBUG_ERR("client added : pid [%d]", msg->error);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("createClient failed");
+
+                               response.param1 = 0;
+                               response.error = -1;
+
+                               /* response to client */
+                               ServerIPC::getInstance()->sendMessage(socket, &response);
+
+                               return false;
+                       }
+               }
+
+               if ((count = resource.getReadersInformation(info)) > 0)
+               {
+                       response.param1 = count;
+                       response.param2 = 0;
+                       response.error = 0;
+                       response.data = info;
+               }
+               else
+               {
+                       SCARD_DEBUG("no secure elements");
+
+                       response.error = -1;
+               }
+
+               /* response to client */
+               ServerIPC::getInstance()->sendMessage(socket, &response);
+
+               return false;
+       }
+#endif
+
+       void ServerSEService::terminalCallback(void *terminal, int event, int error, void *user_param)
+       {
+               Message msg;
+//             Terminal *term = NULL;
+
+               switch (event)
+               {
+               case Terminal::NOTIFY_SE_AVAILABLE :
+                       {
+                               /* add right se reader */
+//                             if ((term = ServerResource::getInstance().getTerminal((char *)terminal)) != NULL)
+//                             {
+//                                     SCARD_DEBUG("terminal : [%s]", (char *)terminal);
+//
+//                                     term->initialize();
+//                             }
+//                             else
+//                             {
+//                                     SCARD_DEBUG("unknown terminal : [%s]", (char *)terminal);
+//                             }
+
+                               /* send all client to refresh reader */
+                               msg.message = msg.MSG_NOTIFY_SE_INSERTED;
+                               msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+
+                               ServerResource::getInstance().sendMessageToAllClients(msg);
+                       }
+                       break;
+
+               case Terminal::NOTIFY_SE_NOT_AVAILABLE :
+                       {
+                               /* remove right se reader */
+//                             if ((term = ServerResource::getInstance().getTerminal((char *)terminal)) != NULL)
+//                             {
+//                                     SCARD_DEBUG("terminal : [%s]", (char *)terminal);
+//
+//                                     term->finalize();
+//                             }
+//                             else
+//                             {
+//                                     SCARD_DEBUG("unknown terminal : [%s]", (char *)terminal);
+//                             }
+
+                               /* send all client to refresh reader */
+                               msg.message = msg.MSG_NOTIFY_SE_REMOVED;
+                               msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+
+                               ServerResource::getInstance().sendMessageToAllClients(msg);
+                       }
+                       break;
+
+               default :
+                       break;
+               }
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/server/ServerSession.cpp b/server/ServerSession.cpp
new file mode 100644 (file)
index 0000000..8c11e68
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/* standard library header */
+#include <stdio.h>
+#include <dlfcn.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServerSession.h"
+#include "ServerReader.h"
+#include "ServerChannel.h"
+#include "APDUHelper.h"
+#include "GPSEACL.h"
+
+namespace smartcard_service_api
+{
+       ServerSession::ServerSession(ServerReader *reader, ByteArray packageCert, void *caller, Terminal *terminal):SessionHelper(reader)
+       {
+               this->caller = NULL;
+               this->terminal = NULL;
+
+               if (caller == NULL || terminal == NULL)
+               {
+                       SCARD_DEBUG_ERR("invalid param");
+
+                       return;
+               }
+
+               this->caller = caller;
+               this->terminal = terminal;
+               this->packageCert = packageCert;
+       }
+
+       ServerSession::~ServerSession()
+       {
+               if (isClosed() == false)
+                       closeSync();
+       }
+
+       ByteArray ServerSession::getATRSync()
+       {
+               /* call get atr to terminal */
+               return atr;
+       }
+
+       void ServerSession::closeSync()
+       {
+               if (isClosed() == false)
+               {
+                       closed = true;
+                       closeChannels();
+               }
+       }
+
+       void ServerSession::closeChannels()
+       {
+               size_t i;
+
+               for (i = 0; i < channels.size(); i++)
+               {
+                       if (channels[i] != NULL)
+                               channels[i]->closeSync();
+               }
+
+               channels.clear();
+       }
+
+       Channel *ServerSession::openBasicChannelSync(ByteArray aid)
+       {
+               return openBasicChannelSync(aid, NULL);
+       }
+
+       Channel *ServerSession::openBasicChannelSync(ByteArray aid, void *caller)
+       {
+               ServerChannel *channel = NULL;
+               AccessControlList *acList = NULL;
+               ByteArray command, result;
+               int channelID = 0;
+               int rv = 0;
+
+               SCARD_BEGIN();
+
+               acList = ((ServerReader *)reader)->getAccessControlList();
+               if (acList == NULL)
+               {
+                       SCARD_DEBUG_ERR("acList is null");
+
+                       return channel;
+               }
+
+               if (acList->isAuthorizedAccess(aid, packageCert) == false)
+               {
+                       SCARD_DEBUG_ERR("unauthorized access, aid %s, hash %s", aid.toString(), packageCert.toString());
+
+                       return channel;
+               }
+
+               /* select aid */
+               command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelID, aid);
+               rv = terminal->transmitSync(command, result);
+               if (rv == 0 && result.getLength() >= 2)
+               {
+                       ResponseHelper resp(result);
+
+                       if (resp.getStatus() == 0)
+                       {
+                               channel = new ServerChannel(this, caller, channelID, terminal);
+                               if (channel != NULL)
+                               {
+                                       channel->selectResponse = result;
+
+                                       channels.push_back(channel);
+                               }
+                               else
+                               {
+                                       SCARD_DEBUG_ERR("alloc failed");
+                               }
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
+               }
+
+               return channel;
+       }
+
+       Channel *ServerSession::openBasicChannelSync(unsigned char *aid, unsigned int length)
+       {
+               return openBasicChannelSync(ByteArray(aid, length));
+       }
+
+       Channel *ServerSession::openBasicChannelSync(unsigned char *aid, unsigned int length, void *caller)
+       {
+               return openBasicChannelSync(ByteArray(aid, length), caller);
+       }
+
+       Channel *ServerSession::openLogicalChannelSync(ByteArray aid)
+       {
+               return openLogicalChannelSync(aid, NULL);
+       }
+
+       Channel *ServerSession::openLogicalChannelSync(ByteArray aid, void *caller)
+       {
+               ServerChannel *channel = NULL;
+               AccessControlList *acList = NULL;
+               ByteArray command, result;
+               int channelID = 1;
+               int rv;
+
+               acList = ((ServerReader *)reader)->getAccessControlList();
+               if (acList == NULL)
+               {
+                       SCARD_DEBUG_ERR("unauthorized access, aid %s, hash %s");
+
+                       return channel;
+               }
+
+               if (acList->isAuthorizedAccess(aid, packageCert) == false)
+               {
+                       SCARD_DEBUG_ERR("unauthorized access, aid %s, hash %s", aid.toString(), packageCert.toString());
+
+                       return channel;
+               }
+
+               /* open channel */
+               command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
+               rv = terminal->transmitSync(command, result);
+
+               if (rv == 0 && result.getLength() >= 2)
+               {
+                       ResponseHelper resp(result);
+
+                       if (resp.getStatus() == 0)
+                       {
+                               channelID = resp.getDataField()[0];
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+
+                               return channel;
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
+
+                       return channel;
+               }
+
+               /* select aid */
+               command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelID, aid);
+               rv = terminal->transmitSync(command, result);
+
+               if (rv == 0 && result.getLength() >= 2)
+               {
+                       ResponseHelper resp(result);
+
+                       if (resp.getStatus() == 0)
+                       {
+                               channel = new ServerChannel(this, caller, channelID, terminal);
+                               if (channel == NULL)
+                               {
+                                       SCARD_DEBUG_ERR("alloc failed");
+
+                                       return NULL;
+                               }
+
+                               channel->selectResponse = result;
+
+                               channels.push_back(channel);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), result[result.getLength() - 2], result[result.getLength() - 1]);
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
+               }
+
+               return channel;
+       }
+
+       Channel *ServerSession::openLogicalChannelSync(unsigned char *aid, unsigned int length)
+       {
+               return openLogicalChannelSync(ByteArray(aid, length), NULL);
+       }
+
+       Channel *ServerSession::openLogicalChannelSync(unsigned char *aid, unsigned int length, void *caller)
+       {
+               return openLogicalChannelSync(ByteArray(aid, length), caller);
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/server/ServiceInstance.cpp b/server/ServiceInstance.cpp
new file mode 100644 (file)
index 0000000..618b17e
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ServiceInstance.h"
+#include "ClientInstance.h"
+#include "ServerResource.h"
+
+namespace smartcard_service_api
+{
+       unsigned int ServiceInstance::openSession(Terminal *terminal, ByteArray packageCert, void *caller)
+       {
+               unsigned int handle = IntegerHandle::assignHandle();
+
+               ServerSession *session = new ServerSession((ServerReader *)0, packageCert, caller, terminal);
+
+               mapSessions.insert(make_pair(handle, make_pair(session, terminal)));
+
+               return handle;
+       }
+
+       ServerSession *ServiceInstance::getSession(unsigned int session)
+       {
+               ServerSession *result = NULL;
+               map<unsigned int, pair<ServerSession *, Terminal *> >::iterator item;
+
+               if ((item = mapSessions.find(session)) != mapSessions.end())
+               {
+                       /*if (item->second.first == session)*/
+                               result = item->second.first;
+               }
+
+               return result;
+       }
+
+       Terminal *ServiceInstance::getTerminal(unsigned int session)
+       {
+               Terminal *result = NULL;
+               map<unsigned int, pair<ServerSession *, Terminal *> >::iterator item;
+
+               if ((item = mapSessions.find(session)) != mapSessions.end())
+               {
+                       result = item->second.second;
+               }
+
+               return result;
+       }
+
+       void ServiceInstance::closeSession(unsigned int session)
+       {
+               map<unsigned int, pair<ServerSession *, Terminal *> >::iterator item;
+
+               if ((item = mapSessions.find(session)) != mapSessions.end())
+               {
+                       closeChannelsBySession(session);
+
+                       item->second.first->closeSync();
+
+                       mapSessions.erase(item);
+
+                       IntegerHandle::releaseHandle(session);
+               }
+       }
+
+       void ServiceInstance::closeSessions()
+       {
+               map<unsigned int, pair<ServerSession *, Terminal *> >::iterator item;
+
+               closeChannels();
+
+               for (item = mapSessions.begin(); item != mapSessions.end(); item++)
+               {
+                       item->second.first->closeSync();
+
+                       IntegerHandle::releaseHandle(item->first);
+               }
+
+               mapSessions.clear();
+       }
+
+       unsigned int ServiceInstance::openChannel(unsigned int session, int channelNum)
+       {
+               Terminal *terminal = getTerminal(session);
+               ServerChannel *channel = NULL;
+               unsigned int handle = -1;
+
+               /* create ServerChannel */
+               channel = new ServerChannel((ServerSession *)session, (void *)parent->getPID(), channelNum, terminal);
+               if (channel != NULL)
+               {
+                       handle = IntegerHandle::assignHandle();
+                       mapChannels.insert(make_pair(handle, make_pair(session, channel)));
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("alloc failed");
+               }
+
+               return handle;
+       }
+
+       ServerChannel *ServiceInstance::getChannel(/*unsigned int session, */unsigned int channel)
+       {
+               ServerChannel *result = NULL;
+               map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+               if ((item = mapChannels.find(channel)) != mapChannels.end())
+               {
+                       /*if (item->second.first == session)*/
+                               result = item->second.second;
+               }
+
+               return result;
+       }
+
+       unsigned int ServiceInstance::getChannelCountBySession(unsigned int session)
+       {
+               unsigned int channelCount = 0;
+               map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+               for (item = mapChannels.begin(); item != mapChannels.end(); item++)
+               {
+                       if (item->second.first == session)
+                               channelCount++;
+               }
+
+               return channelCount;
+       }
+
+       void ServiceInstance::closeChannel(unsigned int channel)
+       {
+               map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+               if ((item = mapChannels.find(channel)) != mapChannels.end())
+               {
+                       /* destroy ServerChannel */
+                       delete item->second.second;
+
+                       mapChannels.erase(item);
+
+                       IntegerHandle::releaseHandle(channel);
+               }
+       }
+
+       void ServiceInstance::closeChannelsBySession(unsigned int session)
+       {
+               size_t i;
+               vector<unsigned int> list;
+               map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+               for (item = mapChannels.begin(); item != mapChannels.end(); item++)
+               {
+                       if (item->second.first == session)
+                               list.push_back(item->second.first);
+               }
+
+               for (i = 0; i < list.size(); i++)
+               {
+                       closeChannel(list[i]);
+               }
+       }
+
+       void ServiceInstance::closeChannels()
+       {
+               map<unsigned int, pair<unsigned int, ServerChannel *> >::iterator item;
+
+               for (item = mapChannels.begin(); item != mapChannels.end(); item++)
+               {
+                       /* destroy ServerChannel */
+                       delete item->second.second;
+
+                       IntegerHandle::releaseHandle(item->first);
+               }
+
+               mapChannels.clear();
+       }
+
+} /* namespace smartcard_service_api */
diff --git a/server/include/ClientInstance.h b/server/include/ClientInstance.h
new file mode 100644 (file)
index 0000000..3475c7c
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef CLIENTINSTANCE_H_
+#define CLIENTINSTANCE_H_
+
+/* standard library header */
+#include <map>
+//#include <hash_map>
+
+/* SLP library header */
+
+/* local header */
+#include "Message.h"
+#include "ServiceInstance.h"
+
+namespace smartcard_service_api
+{
+       class ClientInstance
+       {
+       private:
+               void *ioChannel;
+               int socket;
+               int watchID;
+               int state;
+               int pid;
+               ByteArray certHash;
+
+               map<unsigned int, ServiceInstance *> mapServices;
+
+               inline ByteArray getCertificationHash() { return certHash; }
+
+       public:
+               ClientInstance(void *ioChannel, int socket, int watchID, int state, int pid)
+               {
+                       this->ioChannel = ioChannel;
+                       this->socket = socket;
+                       this->watchID = watchID;
+                       this->state = state;
+                       this->pid = pid;
+               }
+               ~ClientInstance() { removeServices(); }
+
+               inline bool operator ==(const int &socket) const { return (this->socket == socket); }
+
+               inline void *getIOChannel() { return ioChannel; }
+               inline int getSocket() { return socket; }
+               inline int getWatchID() { return watchID; }
+               inline int getState() { return state; }
+
+               void setPID(int pid);
+               inline int getPID() { return pid; }
+
+
+               bool createService(unsigned int context);
+               ServiceInstance *getService(unsigned int context);
+               void removeService(unsigned int context);
+               void removeServices();
+
+               bool sendMessageToAllServices(int socket, Message &msg);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* CLIENTINSTANCE_H_ */
diff --git a/server/include/ServerChannel.h b/server/include/ServerChannel.h
new file mode 100644 (file)
index 0000000..3c3a260
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SERVERCHANNEL_H_
+#define SERVERCHANNEL_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "Channel.h"
+#include "Terminal.h"
+#include "ServerSession.h"
+
+namespace smartcard_service_api
+{
+       class ServerChannel: public Channel
+       {
+       private:
+               Terminal *terminal;
+               void *caller;
+
+               ServerChannel(ServerSession *session, void *caller, int channelNum, Terminal *terminal);
+
+       protected:
+               void closeSync();
+               int transmitSync(ByteArray command, ByteArray &result);
+
+       public:
+               ~ServerChannel();
+
+               int getChannelNumber();
+
+               int close(closeCallback callback, void *userParam) { return -1; }
+               int transmit(ByteArray command, transmitCallback callback, void *userParam) { return -1; };
+
+               friend class ServerReader;
+               friend class ServerSession;
+               friend class ServiceInstance;
+               friend class ServerResource;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERCHANNEL_H_ */
diff --git a/server/include/ServerDispatcher.h b/server/include/ServerDispatcher.h
new file mode 100644 (file)
index 0000000..153c3c6
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SERVERDISPATCHER_H_
+#define SERVERDISPATCHER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+#include "DispatcherHelper.h"
+
+namespace smartcard_service_api
+{
+       class ServerIPC;
+
+       class ServerDispatcher: public DispatcherHelper
+       {
+       private:
+               ServerDispatcher();
+               ~ServerDispatcher();
+
+               void *dispatcherThreadFunc(DispatcherMsg *msg, void *data);
+
+       public:
+
+               static ServerDispatcher *getInstance();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERDISPATCHER_H_ */
diff --git a/server/include/ServerIPC.h b/server/include/ServerIPC.h
new file mode 100644 (file)
index 0000000..2cd9fd4
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef SERVERIPC_H_
+#define SERVERIPC_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "IPCHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class ServerIPC: public IPCHelper
+       {
+       private:
+               ServerIPC();
+               ~ServerIPC();
+
+               bool acceptClient();
+               void restartServerIPC();
+               void releaseClient(void *channel, int socket, int watchID);
+
+               int handleIOErrorCondition(void *channel, GIOCondition condition);
+               int handleInvalidSocketCondition(void *channel, GIOCondition condition);
+               int handleIncomingCondition(void *channel, GIOCondition condition);
+
+       public:
+               static ServerIPC *getInstance();
+
+               friend class ServerResource;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERIPC_H_ */
diff --git a/server/include/ServerReader.h b/server/include/ServerReader.h
new file mode 100644 (file)
index 0000000..99f558e
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SERVERREADER_H_
+#define SERVERREADER_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "Terminal.h"
+#include "ReaderHelper.h"
+#include "ServerSession.h"
+#include "ServerChannel.h"
+#include "AccessControlList.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class ServerSEService;
+
+       class ServerReader : public ReaderHelper
+       {
+       private:
+               Terminal *terminal;
+               ServerChannel *adminChannel;
+               AccessControlList *acList;
+
+               ServerReader(ServerSEService *seService, char *name, Terminal *terminal);
+
+               int openSession(openSessionCallback callback, void *userData) { return -1; }
+               int openSession(void *caller, openSessionCallback callback, void *userData) { return -1; }
+
+       public:
+               ~ServerReader();
+
+               void closeSessions();
+
+               AccessControlList *getAccessControlList();
+
+               ServerSession *openSessionSync();
+               ServerSession *openSessionSync(ByteArray packageCert, void *caller);
+
+               friend class ServerSEService;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERREADER_H_ */
diff --git a/server/include/ServerResource.h b/server/include/ServerResource.h
new file mode 100644 (file)
index 0000000..e01d35e
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SERVERRESOURCE_H_
+#define SERVERRESOURCE_H_
+
+/* standard library header */
+#include <map>
+#include <vector>
+#include <set>
+
+/* SLP library header */
+
+/* local header */
+#include "Terminal.h"
+#include "Lock.h"
+#include "ServerIPC.h"
+#include "ServerDispatcher.h"
+#include "ServerReader.h"
+#include "ServerSession.h"
+#include "ClientInstance.h"
+#include "ServiceInstance.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class IntegerHandle
+       {
+       private:
+               static unsigned int newHandle;
+               static set<unsigned int> setHandles;
+               static PMutex mutexLock;
+
+       public:
+               static const unsigned int INVALID_HANDLE = (unsigned int)-1;
+
+               static unsigned int assignHandle();
+               static void releaseHandle(unsigned int);
+       };
+
+       class ServerResource
+       {
+       private:
+               /* non-static member */
+               vector<void *> libraries;
+               map<unsigned int, Terminal *> mapTerminals; /* unique id <-> terminal instance map */
+               map<int, ClientInstance *> mapClients; /* client pid <-> client instance map */
+               map<Terminal *, AccessControlList *> mapACL; /* terminal instance <-> access control instance map */
+
+               ServerIPC *serverIPC;
+               ServerDispatcher *serverDispatcher;
+
+               ServerResource();
+               ~ServerResource();
+
+               Terminal *createInstance(void *library);
+               bool appendSELibrary(char *library);
+               void clearSELibraries();
+
+               static void terminalCallback(void *terminal, int event, int error, void *user_param);
+
+       public:
+               /* static member */
+               static ServerResource &getInstance();
+
+               /* non-static member */
+               int loadSecureElements();
+               void unloadSecureElements();
+
+               Terminal *getTerminal(unsigned int terminalID);
+               Terminal *getTerminal(const char *name);
+               int getReadersInformation(ByteArray &info);
+               bool isValidReaderHandle(unsigned int reader);
+
+               bool createClient(void *ioChannel, int socket, int watchID, int state, int pid);
+               ClientInstance *getClient(int socket);
+               void setPID(int socket, int pid);
+               void removeClient(int socket);
+               void removeClients();
+
+               bool createService(int socket, unsigned int context);
+               ServiceInstance *getService(int socket, unsigned int context);
+               void removeService(int socket, unsigned int context);
+               void removeServices(int socket);
+
+               unsigned int createSession(int socket, unsigned int context, unsigned int terminalID, ByteArray packageCert, void *caller);
+               ServerSession *getSession(int socket, unsigned int context, unsigned int sessionID);
+               unsigned int getChannelCount(int socket, unsigned int context, unsigned int sessionID);
+               void removeSession(int socket, unsigned int context, unsigned int session);
+               bool isValidSessionHandle(int socket, unsigned int context, unsigned int sessionID);
+
+               unsigned int createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid);
+               Channel *getChannel(int socket, unsigned int context, unsigned int channelID);
+               void removeChannel(int socket, unsigned int context, unsigned int channelID);
+
+               AccessControlList *getAccessControlList(Terminal *terminal);
+
+               bool sendMessageToAllClients(Message &msg);
+
+               friend void terminalCallback(void *terminal, int event, int error, void *user_param);
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERRESOURCE_H_ */
diff --git a/server/include/ServerSEService.h b/server/include/ServerSEService.h
new file mode 100644 (file)
index 0000000..2df4816
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef SERVERSESERVICE_H_
+#define SERVERSESERVICE_H_
+
+/* standard library header */
+#include <vector>
+
+/* SLP library header */
+
+/* local header */
+#include "SEServiceHelper.h"
+#include "Terminal.h"
+#include "ServerReader.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class ServerSEService : public SEServiceHelper
+       {
+       private:
+               vector<void *> libraries;
+               map<char *, Terminal *> mapTerminals;
+
+               ServerSEService();
+               ~ServerSEService();
+
+               Terminal *createInstance(void *library);
+               bool appendSELibrary(char *library);
+
+               int openSELibraries();
+               void closeSELibraries();
+
+               static void terminalCallback(void *terminal, int event, int error, void *user_param);
+               static bool dispatcherCallback(void *message, int socket);
+
+       public:
+               static ServerSEService &getInstance();
+
+#if 0
+               bool isValidReaderHandle(void *handle);
+#endif
+               friend void terminalCallback(char *name, int event, int error, void *user_param);
+               friend bool dispatcherCallback(void *message, int socket);
+               friend class ServerDispatcher;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERSESERVICE_H_ */
diff --git a/server/include/ServerSession.h b/server/include/ServerSession.h
new file mode 100644 (file)
index 0000000..9ba8041
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SERVERSESSION_H_
+#define SERVERSESSION_H_
+
+/* standard library header */
+#include <vector>
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "ByteArray.h"
+#include "Channel.h"
+#include "Terminal.h"
+#include "SessionHelper.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       class ServerReader;
+
+       class ServerSession : public SessionHelper
+       {
+       private:
+               void *caller;
+               Terminal *terminal;
+               ByteArray packageCert;
+
+               ServerSession(ServerReader *reader, ByteArray packageCert, void *caller, Terminal *terminal);
+
+               int getATR(getATRCallback callback, void *userData){ return -1; }
+               int close(closeSessionCallback callback, void *userData){ return -1; }
+
+               int openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData){ return -1; }
+               int openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData){ return -1; }
+               int openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData){ return -1; }
+               int openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData){ return -1; }
+       public:
+               ~ServerSession();
+
+               ByteArray getATRSync();
+               void closeSync();
+
+               void closeChannels();
+
+               Channel *openBasicChannelSync(ByteArray aid);
+               Channel *openBasicChannelSync(unsigned char *aid, unsigned int length);
+               Channel *openBasicChannelSync(ByteArray aid, void *caller);
+               Channel *openBasicChannelSync(unsigned char *aid, unsigned int length, void *caller);
+
+               Channel *openLogicalChannelSync(ByteArray aid);
+               Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length);
+               Channel *openLogicalChannelSync(ByteArray aid, void *caller);
+               Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length, void *caller);
+
+               friend class ServerReader;
+               friend class ServerResource;
+               friend class ServiceInstance;
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVERSESSION_H_ */
diff --git a/server/include/ServiceInstance.h b/server/include/ServiceInstance.h
new file mode 100644 (file)
index 0000000..8e45468
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef SERVICEINSTANCE_H_
+#define SERVICEINSTANCE_H_
+
+/* standard library header */
+#include <map>
+
+/* SLP library header */
+
+/* local header */
+#include "Terminal.h"
+#include "ServerChannel.h"
+#include "ServerSession.h"
+
+namespace smartcard_service_api
+{
+       class ClientInstance;
+
+       class ServiceInstance
+       {
+       private:
+               unsigned int context;
+               ClientInstance *parent;
+               map<unsigned int, pair<ServerSession *, Terminal *> > mapSessions; /* session unique id <-> terminal instance map */
+               map<unsigned int, pair<unsigned int, ServerChannel *> > mapChannels; /* channel unique id <-> (session unique id, channel instance) map */
+
+       public:
+               ServiceInstance(ClientInstance *parent, unsigned int context)
+               {
+                       this->parent = parent;
+                       this->context = context;
+               }
+               ~ServiceInstance() { closeSessions(); };
+
+               inline bool operator ==(const unsigned int &context) const { return (this->context == context); }
+               inline bool isVaildSessionHandle(unsigned int handle) { return (mapSessions.find(handle) != mapSessions.end()); }
+               inline bool isVaildChannelHandle(unsigned int handle) { return (mapChannels.find(handle) != mapChannels.end()); }
+               inline ClientInstance *getParent() { return parent; }
+
+               unsigned int openSession(Terminal *terminal, ByteArray packageCert, void *caller);
+               ServerSession *getSession(unsigned int session);
+               void closeSession(unsigned int session);
+               void closeSessions();
+
+               Terminal *getTerminal(unsigned int session);
+
+               unsigned int openChannel(unsigned int session, int channelNum);
+               ServerChannel *getChannel(/*unsigned int session, */unsigned int channel);
+               unsigned int getChannelCountBySession(unsigned int session);
+               void closeChannel(unsigned int channel);
+               void closeChannelsBySession(unsigned int session);
+               void closeChannels();
+       };
+
+} /* namespace smartcard_service_api */
+#endif /* SERVICEINSTANCE_H_ */
diff --git a/server/smartcard-daemon.cpp b/server/smartcard-daemon.cpp
new file mode 100644 (file)
index 0000000..ef55087
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+/* standard library header */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <glib.h>
+#include <vector>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Channel.h"
+#include "ServerResource.h"
+#include "ServerSEService.h"
+
+/* definition */
+using namespace std;
+using namespace smartcard_service_api;
+
+/* global variable */
+
+ServerResource *serverResource = NULL;
+
+static void daemonize(void)
+{
+       pid_t pid, sid;
+
+       /* already a daemon */
+       if (getppid() == 1)
+               return;
+
+       /* Fork off the parent process */
+       pid = fork();
+       if (pid < 0)
+       {
+               exit(EXIT_FAILURE);
+       }
+
+       if (pid > 0)
+       {
+               exit(EXIT_SUCCESS); /*Killing the Parent Process*/
+       }
+
+       /* At this point we are executing as the child process */
+       umask(0);
+
+       /* Create a new SID for the child process */
+       sid = setsid();
+       if (sid < 0)
+       {
+               exit(EXIT_FAILURE);
+       }
+
+       /* Change the current working directory. */
+       if ((chdir("/")) < 0)
+       {
+               exit(EXIT_FAILURE);
+       }
+
+       close(STDIN_FILENO);
+       close(STDOUT_FILENO);
+       close(STDERR_FILENO);
+}
+
+int main()
+{
+       GMainLoop* loop = NULL;
+
+       daemonize();
+
+       if (!g_thread_supported())
+       {
+               g_thread_init(NULL);
+       }
+
+       serverResource = &ServerResource::getInstance();
+       ServerIPC::getInstance()->createListenSocket();
+
+       loop = g_main_new(TRUE);
+       g_main_loop_run(loop);
+
+       return 0;
+}
diff --git a/test-client/CMakeLists.txt b/test-client/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8fe03d8
--- /dev/null
@@ -0,0 +1,51 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(smartcard-test-client CXX)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../client/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ SRCS)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+       SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs_test_client REQUIRED glib-2.0 gthread-2.0 gobject-2.0 security-server vconf dlog)
+
+FOREACH(flag ${pkgs_test_client_CFLAGS})
+       SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+MESSAGE("CHECK MODULE in ${PROJECT_NAME} ${pkgs_test_client_LDFLAGS}")
+
+# this for NFC flag
+
+SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -pipe -fomit-frame-pointer -Wall -Wno-trigraphs  -fno-strict-aliasing -Wl,-zdefs -fvisibility=hidden")
+
+SET(ARM_CXXFLAGS "${ARM_CXXLAGS} -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -msoft-float -Uarm -fno-common -fpic")
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" MATCHES "^arm.*")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+       SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM_CXXFLAGS}")
+ENDIF()
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+#ADD_DEFINITIONS("-DSLP_DEBUG")
+
+ADD_DEFINITIONS("-DLOG_TAG=\"SCARD_TEST\"")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_test_client_LDFLAGS} "-L../common" "-lsmartcard-service-common" "-L../client" "-lsmartcard-service" "-pie -ldl")
+
+#INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/test-client/test-client.cpp b/test-client/test-client.cpp
new file mode 100644 (file)
index 0000000..b0137fc
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+
+#include "Debug.h"
+#include "SEService.h"
+#include "Reader.h"
+#include "Session.h"
+#include "APDUHelper.h"
+
+using namespace smartcard_service_api;
+
+typedef struct _user_context_t
+{
+       Session *clientSession;
+       SEServiceHelper *clientService;
+       Channel *clientChannel;
+}
+user_context_t;
+
+/* global variable */
+GMainLoop *loop = NULL;
+user_context_t user_context = { 0, };
+
+void testCloseCallback(int error, void *userData);
+void testTransmitCallback(unsigned char *buffer, unsigned int length, int error, void *userData);
+void testOpenChannelCallback(Channel *channel, int error, void *userData);
+void testGetATRCallback(unsigned char *atr, unsigned int length, int error, void *userData);
+void testCloseSessionCallback(int error, void *userData);
+void testOpenSessionCallback(SessionHelper *session, int error, void *userData);
+void testConnectedCallback(SEServiceHelper *service, void *context);
+
+class TestEventHandler : public SEServiceListener
+{
+       void serviceConnected(SEServiceHelper *service, void *userData)
+       {
+               SCARD_BEGIN();
+               testConnectedCallback(service, userData);
+               SCARD_END();
+       }
+
+       void eventHandler(SEServiceHelper *service, char *seName, int event, void *userData)
+       {
+               SCARD_BEGIN();
+
+               SCARD_DEBUG("event occured service [%p], seName[%p], event [%d]", service, seName, event);
+
+               SCARD_END();
+       }
+
+       void errorHandler(SEServiceHelper *service, int error, void *userData)
+       {
+               SCARD_BEGIN();
+
+               SCARD_DEBUG("error occured service [%p], error [%d]", service, error);
+
+               SCARD_END();
+       }
+};
+
+TestEventHandler testEventHandler;
+
+void testCloseCallback(int error, void *userData)
+{
+       user_context_t *context = (user_context_t *)userData;
+
+       SCARD_DEBUG("result [%d], userData [%p]", error, userData);
+
+       context->clientService->shutdown();
+}
+
+void testTransmitCallback(unsigned char *buffer, unsigned int length, int error, void *userData)
+{
+       ByteArray response(buffer, length);
+       user_context_t *context = (user_context_t *)userData;
+
+       SCARD_DEBUG("buffer [%p], length [%d], error [%d], userData [%p]", buffer, length, error, userData);
+
+       context->clientChannel->close(testCloseCallback, userData);
+}
+
+void testOpenChannelCallback(Channel *channel, int error, void *userData)
+{
+       SCARD_DEBUG("channel [%p]", channel);
+
+       if (error == 0 && channel != NULL)
+       {
+               ByteArray response;
+               ByteArray data, command;
+               int fid = 0x00003150;
+               user_context_t *context = (user_context_t *)userData;
+
+               context->clientChannel = channel;
+
+               response = channel->getSelectResponse();
+
+               SCARD_DEBUG("response : %s", response.toString());
+
+               SCARD_DEBUG("isBasicChannel() = %s", channel->isBasicChannel() ? "Basic" : "Logical");
+               SCARD_DEBUG("isClosed() = %s", channel->isClosed() ? "Closed" : "Opened");
+
+               data.setBuffer((unsigned char *)&fid, 2);
+               command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, data);
+               context->clientChannel->transmit(command, testTransmitCallback, userData);
+       }
+       else
+       {
+               SCARD_DEBUG_ERR("openBasicChannel failed");
+       }
+}
+
+void testGetATRCallback(unsigned char *atr, unsigned int length, int error, void *userData)
+{
+//     unsigned char MF[] = { 0x3F, 0x00 };
+       unsigned char MF[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
+       ByteArray aid, result(atr, length);
+       user_context_t *context = (user_context_t *)userData;
+
+       SCARD_DEBUG("atr[%d] : %s", result.getLength(), result.toString());
+
+       aid.setBuffer(MF, sizeof(MF));
+       context->clientSession->openLogicalChannel(aid, testOpenChannelCallback, userData);
+}
+
+void testCloseSessionCallback(int error, void *userData)
+{
+
+}
+
+void testOpenSessionCallback(SessionHelper *session, int error, void *userData)
+{
+       SCARD_DEBUG("session [%p]", session);
+
+       if (session != NULL)
+       {
+               user_context_t *context = (user_context_t *)userData;
+
+               context->clientSession = (Session *)session;
+               context->clientSession->getATR(testGetATRCallback, userData);
+       }
+       else
+       {
+               SCARD_DEBUG_ERR("openSession failed");
+       }
+}
+
+void testConnectedCallback(SEServiceHelper *service, void *userData)
+{
+       vector<ReaderHelper *> readers;
+       user_context_t *context = (user_context_t *)userData;
+
+       SCARD_BEGIN();
+
+       if (service != NULL)
+       {
+               SCARD_DEBUG("callback called, service [%p]", service);
+
+               context->clientService = service;
+
+               readers = service->getReaders();
+
+               if (readers.size() > 0)
+               {
+                       Reader *reader = NULL;
+
+                       reader = (Reader *)readers[0];
+
+                       SCARD_DEBUG("reader [%p]", reader);
+
+                       reader->openSession(testOpenSessionCallback, userData);
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("reader is empty");
+               }
+       }
+       else
+       {
+               SCARD_DEBUG_ERR("service is NULL");
+       }
+
+       SCARD_END();
+}
+
+int main(int argv, char *args[])
+{
+       SEService *service = new SEService((void *)&user_context, &testEventHandler);
+
+       loop = g_main_new(TRUE);
+       g_main_loop_run(loop);
+
+       if (service != NULL)
+               delete service;
+
+       return 0;
+}