From cc7ba59cf0a268e4de76f995c23c3f965776da67 Mon Sep 17 00:00:00 2001 From: Jihoon Jung Date: Fri, 19 Jun 2015 14:48:06 +0900 Subject: [PATCH] Apply tizen 2.4 smartcard api Signed-off-by: Ji-hoon Jung Change-Id: I57a3587351f39bf486b5e1a7a0d75ff6b502edc7 --- AUTHORS | 1 + CMakeLists.txt | 78 +++ LICENSE.APLv2 | 206 ++++++++ NOTICE | 3 + capi-network-smartcard.manifest | 6 + capi-network-smartcard.pc.in | 15 + doc/mobile/smartcard_doc.h | 149 ++++++ doc/wearable/smartcard_doc.h | 149 ++++++ include/smartcard.h | 571 ++++++++++++++++++++++ include/smartcard_debug.h | 88 ++++ packaging/capi-network-smartcard.spec | 65 +++ src/smartcard.c | 894 ++++++++++++++++++++++++++++++++++ test/CMakeLists.txt | 18 + test/smartcard_unit_test.c | 854 ++++++++++++++++++++++++++++++++ 14 files changed, 3097 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 LICENSE.APLv2 create mode 100644 NOTICE create mode 100644 capi-network-smartcard.manifest create mode 100644 capi-network-smartcard.pc.in create mode 100644 doc/mobile/smartcard_doc.h create mode 100644 doc/wearable/smartcard_doc.h create mode 100644 include/smartcard.h create mode 100644 include/smartcard_debug.h create mode 100755 packaging/capi-network-smartcard.spec create mode 100644 src/smartcard.c create mode 100644 test/CMakeLists.txt create mode 100644 test/smartcard_unit_test.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..d8dcd77 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Jihoon Jung diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..dc1354b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,78 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# project +SET(project_prefix "capi") +SET(prefix "/usr") +SET(version "0.0.1") +SET(maintainer "Jihoon Jung ") +SET(description "A Smartcard library in Tizen Native API") +SET(service "network") +SET(submodule "smartcard") + +# for package file +SET(dependents "dlog glib-2.0 gio-2.0 capi-base-common smartcard-service smartcard-service-common capi-system-info") +SET(pc_dependents "capi-base-common") + +SET(fw_name "${project_prefix}-${service}-${submodule}") + +PROJECT(${fw_name}) + +SET(CMAKE_INSTALL_PREFIX ${prefix}) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(LIBDIR ${CMAKE_LIB_DIR}) +SET(VERSION ${version}) + +SET(INC_DIR include) +INCLUDE_DIRECTORIES(${INC_DIR}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_name} REQUIRED ${dependents}) +FOREACH(flag ${${fw_name}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DTIZEN_DEBUG") +IF(TIZEN_SMARTCARD_SUPPORT) + ADD_DEFINITIONS(-DTIZEN_SMARTCARD_SUPPORT) +ENDIF(TIZEN_SMARTCARD_SUPPORT) + + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIBDIR}") + +SET(SOURCES src/smartcard.c) + +ADD_LIBRARY(${fw_name} SHARED ${SOURCES}) + +TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS}) + +SET_TARGET_PROPERTIES(${fw_name} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 +) + +INSTALL(TARGETS ${fw_name} DESTINATION ${LIBDIR}) +INSTALL( + DIRECTORY ${INC_DIR}/ DESTINATION include + FILES_MATCHING + PATTERN "${INC_DIR}/*.h" + ) + +SET(PC_NAME ${fw_name}) +SET(PC_REQUIRED ${pc_dependents}) +SET(PC_LDFLAGS -l${fw_name}) + +CONFIGURE_FILE( + ${fw_name}.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc + @ONLY +) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIBDIR}/pkgconfig) + +ADD_SUBDIRECTORY(test) + diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..2e43946 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,206 @@ +Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + + diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..0e0f016 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License terms and conditions. diff --git a/capi-network-smartcard.manifest b/capi-network-smartcard.manifest new file mode 100644 index 0000000..ca37499 --- /dev/null +++ b/capi-network-smartcard.manifest @@ -0,0 +1,6 @@ + + + + + + diff --git a/capi-network-smartcard.pc.in b/capi-network-smartcard.pc.in new file mode 100644 index 0000000..837d86f --- /dev/null +++ b/capi-network-smartcard.pc.in @@ -0,0 +1,15 @@ + +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=/usr/lib +includedir=/usr/include/ + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: -I${includedir} + diff --git a/doc/mobile/smartcard_doc.h b/doc/mobile/smartcard_doc.h new file mode 100644 index 0000000..0fadb3d --- /dev/null +++ b/doc/mobile/smartcard_doc.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2011 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. + */ + + /** + * @file smartcard_doc.h + * @brief This file contains high level documentation the SMARTCARD API. + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_MODULE Smartcard + * @brief The SMARTCARD API provides application communication to SE applet method. + * @ingroup CAPI_NETWORK_FRAMEWORK + * + * @section CAPI_NETWORK_SMARTCARD_MODULE_HEADER Required Header + * \#include + + * @section CAPI_NETWORK_SMARTCARD_MODULE_OVERVIEW Overview + * The SMARTCARD API provides function to communication to SE. + * + * - set up se service\n + * - create reader from service\n + * - open session from reader\n + * - open channel from session\n + * - transmit apdu data to channel and get response\n + * + * @subsection CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_DESCRIPTION SE Service + * The SMARTCARD API provides functions to service framework\n + * - get specification version. \n + * - get readers \n + * + * @subsection CAPI_NETWORK_SMARTCARD_READER_MODULE_DESCRIPTION Reader + * The Reader api provides functions to about reader\n + * - get reader name\n + * - open / close session\n + * + * @subsection CAPI_NETWORK_SMARTCARD_SESSION_MODULE_DESCRIPTION Session + * The Session api provide functions to about session \n + * - open basic/logical channel\n + * - close channels + * - get atr (answer to reset) + * + * @subsection CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE_DESCRIPTION Channel + * The Channel api provide functions to about channel. + * - close channel\n + * - transmit apdu\n + * + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE SE Service + * @brief The SE Service API provides functions to service framework. + * @ingroup CAPI_NETWORK_SMARTCARD_MODULE + * + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_HEADER Required Header + * \#include + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/network.secure_element + * - http://tizen.org/feature/network.secure_element.ese + * - http://tizen.org/feature/network.secure_element.uicc + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a devrice supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_READER_MODULE Reader + * @brief The Reader API provides functions to reader. + * @ingroup CAPI_NETWORK_SMARTCARD_MODULE + * + * @section CAPI_NETWORK_SMARTCARD_READER_MODULE_HEADER Required Header + * \#include + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/network.secure_element + * - http://tizen.org/feature/network.secure_element.ese + * - http://tizen.org/feature/network.secure_element.uicc + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a devrice supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_SESSION_MODULE Session + * @brief The Session API provides functions to session. + * @ingroup CAPI_NETWORK_SMARTCARD_MODULE + * + * @section CAPI_NETWORK_SMARTCARD_SESSION_MODULE_HEADER Required Header + * \#include + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/network.secure_element + * - http://tizen.org/feature/network.secure_element.ese + * - http://tizen.org/feature/network.secure_element.uicc + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a devrice supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE Channel + * @brief The Channel API provides functions to channel. + * @ingroup CAPI_NETWORK_SMARTCARD_MODULE + * + * @section CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE_HEADER Required Header + * \#include + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/network.secure_element + * - http://tizen.org/feature/network.secure_element.ese + * - http://tizen.org/feature/network.secure_element.uicc + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a devrice supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ + diff --git a/doc/wearable/smartcard_doc.h b/doc/wearable/smartcard_doc.h new file mode 100644 index 0000000..0fadb3d --- /dev/null +++ b/doc/wearable/smartcard_doc.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2011 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. + */ + + /** + * @file smartcard_doc.h + * @brief This file contains high level documentation the SMARTCARD API. + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_MODULE Smartcard + * @brief The SMARTCARD API provides application communication to SE applet method. + * @ingroup CAPI_NETWORK_FRAMEWORK + * + * @section CAPI_NETWORK_SMARTCARD_MODULE_HEADER Required Header + * \#include + + * @section CAPI_NETWORK_SMARTCARD_MODULE_OVERVIEW Overview + * The SMARTCARD API provides function to communication to SE. + * + * - set up se service\n + * - create reader from service\n + * - open session from reader\n + * - open channel from session\n + * - transmit apdu data to channel and get response\n + * + * @subsection CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_DESCRIPTION SE Service + * The SMARTCARD API provides functions to service framework\n + * - get specification version. \n + * - get readers \n + * + * @subsection CAPI_NETWORK_SMARTCARD_READER_MODULE_DESCRIPTION Reader + * The Reader api provides functions to about reader\n + * - get reader name\n + * - open / close session\n + * + * @subsection CAPI_NETWORK_SMARTCARD_SESSION_MODULE_DESCRIPTION Session + * The Session api provide functions to about session \n + * - open basic/logical channel\n + * - close channels + * - get atr (answer to reset) + * + * @subsection CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE_DESCRIPTION Channel + * The Channel api provide functions to about channel. + * - close channel\n + * - transmit apdu\n + * + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE SE Service + * @brief The SE Service API provides functions to service framework. + * @ingroup CAPI_NETWORK_SMARTCARD_MODULE + * + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_HEADER Required Header + * \#include + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/network.secure_element + * - http://tizen.org/feature/network.secure_element.ese + * - http://tizen.org/feature/network.secure_element.uicc + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a devrice supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_READER_MODULE Reader + * @brief The Reader API provides functions to reader. + * @ingroup CAPI_NETWORK_SMARTCARD_MODULE + * + * @section CAPI_NETWORK_SMARTCARD_READER_MODULE_HEADER Required Header + * \#include + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/network.secure_element + * - http://tizen.org/feature/network.secure_element.ese + * - http://tizen.org/feature/network.secure_element.uicc + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a devrice supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_SESSION_MODULE Session + * @brief The Session API provides functions to session. + * @ingroup CAPI_NETWORK_SMARTCARD_MODULE + * + * @section CAPI_NETWORK_SMARTCARD_SESSION_MODULE_HEADER Required Header + * \#include + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/network.secure_element + * - http://tizen.org/feature/network.secure_element.ese + * - http://tizen.org/feature/network.secure_element.uicc + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a devrice supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ + + /** + * @defgroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE Channel + * @brief The Channel API provides functions to channel. + * @ingroup CAPI_NETWORK_SMARTCARD_MODULE + * + * @section CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE_HEADER Required Header + * \#include + * @section CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/network.secure_element + * - http://tizen.org/feature/network.secure_element.ese + * - http://tizen.org/feature/network.secure_element.uicc + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a devrice supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + */ + diff --git a/include/smartcard.h b/include/smartcard.h new file mode 100644 index 0000000..3806dc7 --- /dev/null +++ b/include/smartcard.h @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd. + * + * 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_h__ +#define __smartcard_h__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file smartcard.h + * @brief This file contains the smartcard api + * @since_tizen 2.3.1 + */ +#ifndef SMARTCARD_API +#define SMARTCARD_API +#endif + +#define SMARTCARD_ERROR_CLASS TIZEN_ERROR_SMARTCARD + +/** + * @brief Error codes reported by the smartcard API. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE + */ +typedef enum { + SMARTCARD_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + SMARTCARD_ERROR_GENERAL = SMARTCARD_ERROR_CLASS | 0x01, /**< A general error occurred */ + SMARTCARD_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ + SMARTCARD_ERROR_NO_SUCH_ELEMENT = SMARTCARD_ERROR_CLASS | 0x02, /**< No such element error */ + SMARTCARD_ERROR_ILLEGAL_STATE = SMARTCARD_ERROR_CLASS | 0x03, /**< Illegal state of execution error */ + SMARTCARD_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid function parameter */ + SMARTCARD_ERROR_ILLEGAL_REFERENCE = SMARTCARD_ERROR_CLASS | 0x04, /**< Illegal reference */ + SMARTCARD_ERROR_OPERATION_NOT_SUPPORTED = SMARTCARD_ERROR_CLASS | 0x05, /**< Operation not supported from SE */ + SMARTCARD_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + SMARTCARD_ERROR_CHANNEL_NOT_AVAILABLE = SMARTCARD_ERROR_CLASS | 0x06, /**< No channel available */ + SMARTCARD_ERROR_NOT_INITIALIZED = SMARTCARD_ERROR_CLASS | 0x07, /**< Smartcard service not initialized */ + SMARTCARD_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ +} smartcard_error_e; + +/** + * @brief Initializes smartcard service + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE + * + * @remarks This function must be called before proceeding any other smartcard function + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_deinitialize() + */ +SMARTCARD_API int smartcard_initialize(void); + +/** + * @brief Deinitializes smartcard service + * @details Releases all the resource of the smartcard service + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_initialize() + */ +SMARTCARD_API int smartcard_deinitialize(void); + +/** + * @brief Gets the list of available Secure Element readers. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_SE_SERVICE_MODULE + * + * @remarks readers must be released using free(). + * + * @param [out] readers List of readers + * @param [out] length The number of readers + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + */ +SMARTCARD_API int smartcard_get_readers(int **readers, int *length); + +/** + * @brief Returns the name of the given reader. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_READER_MODULE + * + * @remarks reader_name must be released using free(). + * @remarks If the reader is a SIM reader, then its name must be "SIM[Slot]" + * @remarks If the reader is a SD or micro SD reader, then its name must be "SD[slot]" + * @remarks If the reader is a embedded SE reader, then its name must be "eSE[slot]" + * + * @param [in] reader Handle to the reader + * @param [out] reader_name The name of reader + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + * @see smartcard_get_readers() + */ +SMARTCARD_API int smartcard_reader_get_name(int reader, char **reader_name); + +/** + * @brief Checks if a Secure Element is present in the given reader. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_READER_MODULE + * + * @param [in] reader Handle to the reader + * @param [out] is_present True or false depending whether a secure element is present in the +reader - undefined when an error is returned + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + * @see smartcard_get_readers() + */ +SMARTCARD_API int smartcard_reader_is_secure_element_present(int reader, bool *is_present); + +/** + * @brief Connects to a Secure Element in the given reader. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_READER_MODULE + * + * @param [in] reader Handle to the reader + * @param [out] session Handle to the session created for the given reader + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_IO_ERROR I/O error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_get_readers() + */ +SMARTCARD_API int smartcard_reader_open_session(int reader, int *session); + +/** + * @brief Closes all the sessions opened on the given reader. + * @details All the channels opened by all these sessions will be closed. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_READER_MODULE + * + * @param [in] reader Handle to the reader + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_IO_ERROR I/O error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_get_readers() + */ +SMARTCARD_API int smartcard_reader_close_sessions(int reader); + +/** + * @brief Gets the reader that provides the given session. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_SESSION_MODULE + * + * @param [in] session Handle to the session + * @param [out] reader Reader handle that provides the given session + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + * @see smartcard_reader_open_session() + */ +SMARTCARD_API int smartcard_session_get_reader(int session, int *reader); + +/** + * @brief Gets the Answer to Reset(ATR) of this Secure Element. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_SESSION_MODULE + * + * @remarks atr must be released using free(). + * @remarks If the Answer to Reset(ATR) for this Secure Element is not available the returned length is set to zero and return value is Success. + * + * @param [in] session Handle to the session + * @param [out] atr Byte array to retrieve the Answer to Reset(ATR) + * @param [out] length The length of atr + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_reader_open_session() + */ +SMARTCARD_API int smartcard_session_get_atr(int session, unsigned char **atr, int *length); + +/** + * @brief Closes the connection with the Secure Element. + * @details This will close any channels opened by this application with this Secure Element. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_SESSION_MODULE + * + * @param [in] session handle to the session + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_IO_ERROR I/O error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_reader_open_session() + */ +SMARTCARD_API int smartcard_session_close(int session); + +/** + * @brief Checks if the given session is closed. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_SESSION_MODULE + * + * @param [in] session Handle to the session + * @param [out] is_closed True or false depending on the session state + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + * @see smartcard_reader_open_session() + */ +SMARTCARD_API int smartcard_session_is_closed(int session, bool *is_closed); + +/** + * @brief Closes any channel opened on the given session. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_SESSION_MODULE + * + * @param [in] session Handle to the session + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_IO_ERROR I/O error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_reader_open_session() + */ +SMARTCARD_API int smartcard_session_close_channels(int session); + +/** + * @brief Gets an access to the basic channel, as defined in the ISO/IEC 7816-4 specification (the one that has number 0). + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_SESSION_MODULE + * + * @remarks ex) unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + * @remarks If the Application ID(AID) is null, it means no Applet is to be selected on this channel and the default Applet is used. + * @remarks Opening of the basic channel to a specific applet is NOT allowed for UICC. + * + * @param [in] session Handle to the session + * @param [in] aid Byte array containing the Application ID(AID) to be selected on the given channel + * @param [in] aid_len Size of byte array or 0 when no SELECT should be executed + * @param [in] P2 P2 byte of the SELECT command if executed + * @param [out] channel Handle of the basic channel + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_CHANNEL_NOT_AVAILABLE No channel available + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NO_SUCH_ELEMENT No such element error + * @retval #SMARTCARD_ERROR_IO_ERROR I/O error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_reader_open_session() + */ +SMARTCARD_API int smartcard_session_open_basic_channel(int session, unsigned char *aid, int aid_len, unsigned char P2, int *channel); + +/** + * @brief Open a logical channel with the Secure Element, selecting the Applet represented by the given Application ID(AID). + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_SESSION_MODULE + * + * @remarks ex) unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + * @remarks If the Application ID(AID) is null, it means no Applet is to be selected on this channel and the default Applet is used. + * + * @param [in] session Handle to the session + * @param [in] aid Byte array containing the Application ID(AID) to be selected on the given channel + * @param [in] aid_len Size of byte array or 0 when no SELECT should be executed + * @param [in] P2 P2 byte of the SELECT command if executed + * @param [out] channel Handle of the new logical channel + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_CHANNEL_NOT_AVAILABLE No channel available + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NO_SUCH_ELEMENT No such element error + * @retval #SMARTCARD_ERROR_IO_ERROR I/O error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_reader_open_session() + */ +SMARTCARD_API int smartcard_session_open_logical_channel(int session, unsigned char *aid, int aid_len, unsigned char P2, int *channel); + +/** + * @brief Closes the given channel to the Secure Element. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE + * + * @param [in] channel Handle to the channel + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_IO_ERROR I/O error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_session_open_basic_channel() + * @see smartcard_session_open_logical_channel() + */ +SMARTCARD_API int smartcard_channel_close(int channel); + +/** + * @brief Checks if the given channel is the basic channel. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE + * + * @param [in] channel Handle to the channel + * @param [out] is_basic_channel True or false depending on the channel type + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + * @see smartcard_session_open_basic_channel() + * @see smartcard_session_open_logical_channel() + */ +SMARTCARD_API int smartcard_channel_is_basic_channel(int channel, bool *is_basic_channel); + +/** + * @brief Checks if the given channel is closed. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE + * + * @param [in] channel Handle to the channel + * @param [out] is_closed True or false depending on the channel state + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + * @see smartcard_session_open_basic_channel() + * @see smartcard_session_open_logical_channel() + */ +SMARTCARD_API int smartcard_channel_is_closed(int channel, bool *is_closed); + +/** + * @brief Gets the response to the select command. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE + * + * @remarks select_resp must be released using free(). + * + * @param [in] channel Handle to the channel + * @param [out] select_resp Byte array to retrieve the SELECT response + * @param [out] length The length of select_resp + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + * @see smartcard_session_open_basic_channel() + * @see smartcard_session_open_logical_channel() + */ +SMARTCARD_API int smartcard_channel_get_select_response(int channel, unsigned char **select_resp, int *length); + +/** + * @brief Gets the session that has opened the given channel. + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE + * + * @param [in] channel Handle to the channel + * @param [out] session Session handle of the given channel + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + * @see smartcard_session_open_basic_channel() + * @see smartcard_session_open_logical_channel() + */ +SMARTCARD_API int smartcard_channel_get_session(int channel, int *session); + +/** + * @brief Transmits an APDU command (as per ISO/IEC 7816-4) to the Secure Element. + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE + * + * @remarks resp must be released using free(). + * @remarks MANAGE_CHANNEL commands are not allowed. + * @remarks SELECT by DF Name (P1=04) are not allowed. + * @remarks bytes with channel numbers are de-masked. + + * @param [in] channel Handle to the channel + * @param [in] cmd Command APDU to be send to the secure element + * @param [in] cmd_len Size of command APDU + * @param [out] resp Byte array for the response APDU plus status words + * @param [out] length The length of resp + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_ILLEGAL_STATE Illegal state of execution error + * @retval #SMARTCARD_ERROR_IO_ERROR I/O error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_session_open_basic_channel() + * @see smartcard_session_open_logical_channel() + */ +SMARTCARD_API int smartcard_channel_transmit(int channel, unsigned char *cmd, int cmd_len, unsigned char **resp, int *length); + +/** + * @brief Helper function to retrieves the response APDU of the previous transmit() call + * @since_tizen 2.3.1 + * @ingroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE + * + * @remarks resp must be released using free(). + * + * @param [in] channel Handle to the channel + * @param [out] resp Byte array for the response APDU plus status words + * @param [out] length The length of resp + * + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_ILLEGAL_STATE Illegal state of execution error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * + * @see smartcard_session_open_basic_channel() + * @see smartcard_session_open_logical_channel() + */ +SMARTCARD_API int smartcard_channel_transmit_retrieve_response(int channel, unsigned char **resp, int *length); + +/** + * @brief Performs a selection of the next Applet on the given channel that matches to the partial Application ID(AID) + * @since_tizen 2.3.1 + * @privlevel public + * @privilege %http://tizen.org/privilege/secureelement + * @ingroup CAPI_NETWORK_SMARTCARD_CHANNEL_MODULE + * + * @param [in] channel Handle to the channel + * @param [out] is_success True or false depending whether another applet with the partial Application ID(AID) +could be selected on the given channel + + * @return 0 on success, otherwise a negative error value. + * @retval #SMARTCARD_ERROR_NONE Successful + * @retval #SMARTCARD_ERROR_GENERAL A general error occurred + * @retval #SMARTCARD_ERROR_INVALID_PARAMETER Invalid function parameter + * @retval #SMARTCARD_ERROR_ILLEGAL_STATE Illegal state of execution error + * @retval #SMARTCARD_ERROR_OPERATION_NOT_SUPPORTED Operation not supported from SE + * @retval #SMARTCARD_ERROR_IO_ERROR I/O error + * @retval #SMARTCARD_ERROR_NOT_INITIALIZED Smartcard service not initialized + * @retval #SMARTCARD_ERROR_NOT_SUPPORTED Not supported + * @retval #SMARTCARD_ERROR_PERMISSION_DENIED Permission denied + * + * @see smartcard_session_open_basic_channel() + * @see smartcard_session_open_logical_channel() + */ +SMARTCARD_API int smartcard_channel_select_next(int channel, bool *is_success); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/smartcard_debug.h b/include/smartcard_debug.h new file mode 100644 index 0000000..1415da1 --- /dev/null +++ b/include/smartcard_debug.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd. + * + * 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_debug_h__ +#define __smartcard_debug_h__ + +#define COLOR_BLACK "\033[0;30m" +#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_GRAY "\033[0;37m" +#define COLOR_END "\033[0;m" + +#define _ERR(fmt, ...) \ + do \ + { \ + LOGE(COLOR_RED fmt COLOR_END, ##__VA_ARGS__); \ + } \ + while (0) + +#define _INFO(fmt, ...) \ + do \ + { \ + LOGI(COLOR_GREEN fmt COLOR_END, ##__VA_ARGS__); \ + } \ + while (0) + +#define _WARN(fmt, ...) \ + do \ + { \ + LOGI(COLOR_BROWN fmt COLOR_END, ##__VA_ARGS__); \ + } \ + while (0) + +#define _DBG(fmt, ...) \ + do \ + { \ + LOGD(fmt, ##__VA_ARGS__); \ + } \ + while (0) + +#define _BEGIN() \ + do \ + { \ + LOGD(COLOR_BLUE "BEGIN >>>>" COLOR_END); \ + } \ + while (0) + +#define _END() \ + do \ + { \ + LOGD(COLOR_BLUE "END <<<<" COLOR_END); \ + } \ + while (0) + +#define cond_expr_ret(expr, val) \ + do {\ + if (expr) { \ + _ERR("[precond fail] expr : %s, ret : %d\n", #expr, val); \ + return (val); \ + } \ + } while(0) + +#define cond_ret(val) \ + do {\ + if(val) { \ + _ERR("[precond fail] ret : %d\n", val); \ + return (val); \ + } \ + } while(0) + +#endif diff --git a/packaging/capi-network-smartcard.spec b/packaging/capi-network-smartcard.spec new file mode 100755 index 0000000..c3ba49d --- /dev/null +++ b/packaging/capi-network-smartcard.spec @@ -0,0 +1,65 @@ +Name: capi-network-smartcard +Summary: A Smartcard library in Native API +Version: 0.0.4 +Release: 1 +Group: Network & Connectivity/Smartcard +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gobject-2.0) +BuildRequires: pkgconfig(smartcard-service) +BuildRequires: pkgconfig(smartcard-service-common) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(capi-system-info) + +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description + +%package devel +Summary: A Smartcard library in Native API (Development) +Group: Network & Connectivity/Development +Requires: %{name} = %{version}-%{release} + +%description devel + +%prep +%setup -q + +%build +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` + +cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} \ + -DMAJORVER=${MAJORVER} -DCMAKE_LIB_DIR=%{_libdir} \ +%if "%{?tizen_profile_name}" == "mobile" + %ifarch %{arm} + -DTIZEN_SMARTCARD_SUPPORT=1 + %endif +%endif + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license/smartcard/ +cp -af %{_builddir}/%{name}-%{version}/LICENSE.APLv2 %{buildroot}/usr/share/license/smartcard/ + +%make_install + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + + +%files +%manifest capi-network-smartcard.manifest +%{_libdir}/libcapi-network-smartcard.so* +/usr/share/license/smartcard/LICENSE.APLv2 + +%files devel +%{_includedir}/*.h +%{_libdir}/pkgconfig/*.pc +%{_libdir}/libcapi-network-smartcard.so diff --git a/src/smartcard.c b/src/smartcard.c new file mode 100644 index 0000000..984fa72 --- /dev/null +++ b/src/smartcard.c @@ -0,0 +1,894 @@ +/* +* Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd. +* +* 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 +#include +#include +#include + +#include +#include + +#include "smartcard.h" +#include "smartcard_debug.h" + +#ifdef TIZEN_SMARTCARD_SUPPORT +#include "smartcard-service.h" + +#define SE_FEATURE "http://tizen.org/feature/network.secure_element" +#define SE_UICC_FEATURE "http://tizen.org/feature/network.secure_element.uicc" +#define SE_ESE_FEATURE "http://tizen.org/feature/network.secure_element.ese" + +#define SMARTCARD_LOCK \ +do { \ + pthread_mutex_lock(&mutex); \ +} while (0); + +#define SMARTCARD_UNLOCK \ +do { \ + pthread_mutex_unlock(&mutex); \ +} while (0); + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +int ref_count; +se_service_h se_service; +bool _is_initialize = false; + +GList *reader_list; +GList *session_list; +GList *channel_list; + +#define CHECK_SUPPORTED() \ +do { \ + { \ + if (_is_smartcard_supported() == false) { \ + return SMARTCARD_ERROR_NOT_SUPPORTED; \ + } \ + } \ +} while (0); + + +#define CHECK_INIT() \ +do { \ + SMARTCARD_LOCK; \ + { \ + if (_is_initialize == false) { \ + SMARTCARD_UNLOCK; \ + return SMARTCARD_ERROR_NOT_INITIALIZED; \ + } \ + } \ + SMARTCARD_UNLOCK; \ +} while (0); + +static bool _is_smartcard_supported() +{ + bool ret = false; + bool is_supported_se = false; + bool is_supported_se_uicc = false; + bool is_supported_se_ese = false; + + system_info_get_platform_bool(SE_FEATURE, &is_supported_se); + system_info_get_platform_bool(SE_UICC_FEATURE, &is_supported_se_uicc); + system_info_get_platform_bool(SE_ESE_FEATURE, &is_supported_se_ese); + + if (is_supported_se && (is_supported_se_uicc || is_supported_se_ese)) + ret = true; + + return ret; +} + +static int _check_precondition_reader(int handle) +{ + CHECK_INIT(); + + SMARTCARD_LOCK; + if (g_list_find(g_list_first(reader_list), GINT_TO_POINTER(handle)) == NULL) { + SMARTCARD_UNLOCK; + return SMARTCARD_ERROR_INVALID_PARAMETER; + } + SMARTCARD_UNLOCK; + + return SMARTCARD_ERROR_NONE; +} + +static int _check_precondition_session(int handle) +{ + CHECK_INIT(); + + SMARTCARD_LOCK; + if (g_list_find(g_list_first(session_list), GINT_TO_POINTER(handle)) == NULL) { + SMARTCARD_UNLOCK; + return SMARTCARD_ERROR_INVALID_PARAMETER; + } + SMARTCARD_UNLOCK; + + return SMARTCARD_ERROR_NONE; +} + +static int _check_precondition_channel(int handle) +{ + CHECK_INIT(); + + SMARTCARD_LOCK; + if (g_list_find(g_list_first(channel_list), GINT_TO_POINTER(handle)) == NULL) { + SMARTCARD_UNLOCK; + return SMARTCARD_ERROR_INVALID_PARAMETER; + } + SMARTCARD_UNLOCK; + + return SMARTCARD_ERROR_NONE; +} + +static smartcard_error_e _convert_error_code(const char *func, int native_error_code) +{ + smartcard_error_e error_code = SMARTCARD_ERROR_NONE; + char *errorstr = NULL; + + switch (native_error_code) { + case SCARD_ERROR_OK: + error_code = SMARTCARD_ERROR_NONE; + errorstr = "SMARTCARD_ERROR_NONE"; + break; + case SCARD_ERROR_NOT_SUPPORTED: + error_code = SMARTCARD_ERROR_OPERATION_NOT_SUPPORTED; + errorstr = "SMARTCARD_ERROR_OPERATION_NOT_SUPPORTED"; + break; + case SCARD_ERROR_UNAVAILABLE: + error_code = SMARTCARD_ERROR_CHANNEL_NOT_AVAILABLE; + errorstr = "SMARTCARD_ERROR_CHANNEL_NOT_AVAILABLE"; + break; + case SCARD_ERROR_IPC_FAILED: + case SCARD_ERROR_IO_FAILED: + error_code = SMARTCARD_ERROR_IO_ERROR; + errorstr = "SMARTCARD_ERROR_IO_ERROR"; + break; + case SCARD_ERROR_SECURITY_NOT_ALLOWED: + error_code = SMARTCARD_ERROR_PERMISSION_DENIED; + errorstr = "SMARTCARD_ERROR_PERMISSION_DENIED"; + break; + case SCARD_ERROR_ILLEGAL_STATE: + error_code = SMARTCARD_ERROR_ILLEGAL_STATE; + errorstr = "SMARTCARD_ERROR_ILLEGAL_STATE"; + break; + case SCARD_ERROR_ILLEGAL_PARAM: + error_code = SMARTCARD_ERROR_INVALID_PARAMETER; + errorstr = "SMARTCARD_ERROR_INVALID_PARAMETER"; + break; + case SCARD_ERROR_ILLEGAL_REFERENCE: + error_code = SMARTCARD_ERROR_ILLEGAL_REFERENCE; + errorstr = "SMARTCARD_ERROR_ILLEGAL_REFERENCE"; + break; + case SCARD_ERROR_NOT_INITIALIZED: + case SCARD_ERROR_SE_NOT_INITIALIZED: + case SCARD_ERROR_OPERATION_NOT_SUPPORTED: + case SCARD_ERROR_NEED_MORE_BUFFER: + case SCARD_ERROR_OPERATION_TIMEOUT: + case SCARD_ERROR_NOT_ENOUGH_RESOURCE: + case SCARD_ERROR_OUT_OF_MEMORY: + case SCARD_ERROR_UNKNOWN: + default: + error_code = SMARTCARD_ERROR_GENERAL; + errorstr = "SMARTCARD_ERROR_GENERAL"; + } + + _ERR("smartcard func : %s, %s(0x%08x)\n", func, errorstr, error_code); + + return error_code; +} +#endif + +/* managing apis : initaialize, deinitialize */ + +int smartcard_initialize(void) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + CHECK_SUPPORTED(); + + SMARTCARD_LOCK; + + if (se_service == NULL || ref_count > 0) { + /* create se service instance. */ + se_service = se_service_create_instance_sync(NULL, &ret); + if (se_service == NULL || ret != SCARD_ERROR_OK) { + SMARTCARD_UNLOCK; + if (ret == SCARD_ERROR_SECURITY_NOT_ALLOWED) + return SMARTCARD_ERROR_PERMISSION_DENIED; + + return SMARTCARD_ERROR_GENERAL; + } + + _is_initialize = true; + } + ref_count++; + + SMARTCARD_UNLOCK; + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_deinitialize(void) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + CHECK_SUPPORTED(); + + SMARTCARD_LOCK; + + if (ref_count > 0) { + ref_count--; + } else { + SMARTCARD_UNLOCK; + return SMARTCARD_ERROR_NOT_INITIALIZED; + } + + if (se_service != NULL && ref_count == 0) { + se_service_shutdown(se_service); + + /* destroy se service instance. */ + ret = se_service_destroy_instance(se_service); + if (ret != SCARD_ERROR_OK) { + SMARTCARD_UNLOCK; + return SMARTCARD_ERROR_GENERAL; + } + + se_service = NULL; + g_list_free(reader_list); + g_list_free(session_list); + g_list_free(channel_list); + reader_list = NULL; + session_list = NULL; + channel_list = NULL; + _is_initialize = false; + } + + SMARTCARD_UNLOCK; + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + + +/*----------------------------------*/ + +int smartcard_get_readers(int **readers, int *length) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int i; + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == readers, SMARTCARD_ERROR_INVALID_PARAMETER); + cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER); + + /* precondition check end */ + + SMARTCARD_LOCK; + + ret = se_service_get_readers(se_service, readers, length); + + SMARTCARD_UNLOCK; + + for (i = 0; i < *length; i++) { + SMARTCARD_LOCK; + + if (g_list_find(g_list_first(reader_list), GINT_TO_POINTER(*(readers[i]))) == NULL) + reader_list = g_list_append(reader_list, GINT_TO_POINTER(*(readers[i]))); + + SMARTCARD_UNLOCK; + } + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +/*----------------------------------*/ + +int smartcard_reader_get_name(int reader, char **reader_name) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == reader_name, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_reader(reader); + cond_ret(ret); + + /* precondition check end */ + + /* process */ + ret = reader_get_name((reader_h)reader, reader_name); + + if (ret != SCARD_ERROR_OK || strlen(*reader_name) == 0) + return SMARTCARD_ERROR_GENERAL; + + _END(); + + return SMARTCARD_ERROR_NONE; +#endif +} + +int smartcard_reader_is_secure_element_present(int reader, bool *is_present) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == is_present, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_reader(reader); + cond_ret(ret); + + /* precondition check end */ + + ret = reader_is_secure_element_present((reader_h)reader, is_present); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_reader_open_session(int reader, int *session) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + ret = _check_precondition_reader(reader); + cond_ret(ret); + + cond_expr_ret(NULL == session, SMARTCARD_ERROR_INVALID_PARAMETER); + + /* precondition check end */ + + ret = reader_open_session_sync((reader_h)reader, session); + + if (ret == SCARD_ERROR_OK) { + SMARTCARD_LOCK; + if (g_list_find(g_list_first(session_list), GINT_TO_POINTER(*session)) == NULL) + session_list = g_list_append(session_list, GINT_TO_POINTER(*session)); + SMARTCARD_UNLOCK; + } + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_reader_close_sessions(int reader) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + ret = _check_precondition_reader(reader); + cond_ret(ret); + + /* precondition check end */ + + ret = reader_close_sessions((reader_h)reader); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +/*----------------------------------*/ + +int smartcard_session_get_reader(int session, int *reader) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == reader, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_session(session); + cond_ret(ret); + + /* precondition check end */ + + ret = session_get_reader((session_h)session, reader); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_session_get_atr(int session, unsigned char **atr, int *length) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == atr, SMARTCARD_ERROR_INVALID_PARAMETER); + cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_session(session); + cond_ret(ret); + + *length = 0; + *atr = NULL; + + /* precondition check end */ + ret = session_get_atr_sync((session_h)session, atr, (unsigned int *)length); + + if (ret == SCARD_ERROR_OK) { + if (((*atr == NULL) && (*length != 0)) || + ((*atr != NULL) && (*length == 0))) { + return SMARTCARD_ERROR_GENERAL; + } + } + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_session_close(int session) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + ret = _check_precondition_session(session); + cond_ret(ret); + + /* precondition check end */ + + ret = session_close_sync((session_h)session); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_session_is_closed(int session, bool *is_closed) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == is_closed, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_session(session); + cond_ret(ret); + + /* precondition check end */ + + ret = session_is_closed((session_h)session, is_closed); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_session_close_channels(int session) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + ret = _check_precondition_session(session); + cond_ret(ret); + + /* precondition check end */ + + ret = session_close_channels((session_h)session); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_session_open_basic_channel(int session, unsigned char *aid, int aid_len, + unsigned char P2, int *channel) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == channel, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_session(session); + cond_ret(ret); + + /* precondition check end */ + + ret = session_open_basic_channel_sync((session_h)session, aid, aid_len, P2, channel); + + if (ret == SCARD_ERROR_OK) { + SMARTCARD_LOCK; + if (g_list_find(g_list_first(channel_list), GINT_TO_POINTER(*channel)) == NULL) + channel_list = g_list_append(channel_list, GINT_TO_POINTER(*channel)); + SMARTCARD_UNLOCK; + } + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_session_open_logical_channel(int session, unsigned char *aid, int aid_len, + unsigned char P2, int *channel) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == channel, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_session(session); + cond_ret(ret); + + /* precondition check end */ + + ret = session_open_logical_channel_sync((session_h)session, aid, aid_len, P2, channel); + + if (ret == SCARD_ERROR_OK) { + SMARTCARD_LOCK; + if (g_list_find(g_list_first(channel_list), GINT_TO_POINTER(*channel)) == NULL) + channel_list = g_list_append(channel_list, GINT_TO_POINTER(*channel)); + SMARTCARD_UNLOCK; + } + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +/*----------------------------------*/ + +int smartcard_channel_close(int channel) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + ret = _check_precondition_channel(channel); + cond_ret(ret); + + /* precondition check end */ + + ret = channel_close_sync((channel_h)channel); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_channel_is_basic_channel(int channel, bool *is_basic_channel) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == is_basic_channel, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_channel(channel); + cond_ret(ret); + + /* precondition check end */ + + ret = channel_is_basic_channel((channel_h)channel, is_basic_channel); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_channel_is_closed(int channel, bool *is_closed) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == is_closed, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_channel(channel); + cond_ret(ret); + + /* precondition check end */ + + ret = channel_is_closed((channel_h)channel, is_closed); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_channel_get_select_response(int channel, unsigned char **select_resp, + int *length) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + size_t s_length; + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == select_resp, SMARTCARD_ERROR_INVALID_PARAMETER); + cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_channel(channel); + cond_ret(ret); + + /* precondition check end */ + + ret = channel_get_select_response((channel_h)channel, select_resp, &s_length); + *length = (int)s_length; + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_channel_get_session(int channel, int *session) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == session, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_channel(channel); + cond_ret(ret); + + /* precondition check end */ + + ret = channel_get_session((channel_h)channel, session); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_channel_transmit(int channel, unsigned char *cmd, int cmd_len, + unsigned char **resp, int *length) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == resp, SMARTCARD_ERROR_INVALID_PARAMETER); + cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_channel(channel); + cond_ret(ret); + + /* precondition check end */ + + ret = channel_transmit_sync((channel_h)channel, cmd, cmd_len, resp, (unsigned int *)length); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_channel_transmit_retrieve_response(int channel, unsigned char **resp, int *length) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + size_t s_length; + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == resp, SMARTCARD_ERROR_INVALID_PARAMETER); + cond_expr_ret(NULL == length, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_channel(channel); + cond_ret(ret); + + /* precondition check end */ + + ret = channel_get_transmit_response((channel_h)channel, resp, &s_length); + *length = (int)s_length; + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} + +int smartcard_channel_select_next(int channel, bool *is_success) +{ +#ifndef TIZEN_SMARTCARD_SUPPORT + return SMARTCARD_ERROR_NOT_SUPPORTED; +#else + int ret = SMARTCARD_ERROR_NONE; + + _BEGIN(); + + /* precondition check start */ + CHECK_SUPPORTED(); + CHECK_INIT(); + + cond_expr_ret(NULL == is_success, SMARTCARD_ERROR_INVALID_PARAMETER); + + ret = _check_precondition_channel(channel); + cond_ret(ret); + + /* precondition check end */ + + ret = channel_select_next((channel_h)channel, is_success); + + _END(); + + return _convert_error_code(__func__, ret); +#endif +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..474d37d --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,18 @@ +SET(fw_test "${fw_name}-test") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_test} REQUIRED dlog glib-2.0) +FOREACH(flag ${${fw_test}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") + MESSAGE(${flag}) +ENDFOREACH() + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall") + +aux_source_directory(. sources) +FOREACH(src ${sources}) + GET_FILENAME_COMPONENT(src_name ${src} NAME_WE) + MESSAGE("${src_name}") + ADD_EXECUTABLE(${src_name} ${src}) + TARGET_LINK_LIBRARIES(${src_name} ${fw_name} ${${fw_test}_LDFLAGS}) +ENDFOREACH() diff --git a/test/smartcard_unit_test.c b/test/smartcard_unit_test.c new file mode 100644 index 0000000..1e18840 --- /dev/null +++ b/test/smartcard_unit_test.c @@ -0,0 +1,854 @@ +#include +#include +#include +#include + +#include + +#define BUFFER_LEN 10 +#define PRT(format, args...) printf("%s:%d() "format, __FUNCTION__, __LINE__, ##args) +#define TC_PRT(format, args...) PRT(format"\n", ##args) + + +GMainLoop *main_loop = NULL; + +typedef struct { + const char *tc_name; + int tc_code; +} tc_table_t; + +tc_table_t tc_table[] = { + /* manage api*/ + {"smartcard_initialize" ,1}, //OK + {"smartcard_deinitialize" ,2}, //OK + + /* service api */ + {"smartcard_get_readers" ,3},//OK + {"smartcard_get_version" ,4},//OK + + /* reader api */ + {"smartcard_reader_get_name" ,5},//OK + {"smartcard_reader_is_secure_element_present" ,6},//OK + {"smartcard_reader_open_session" ,7},//OK + {"smartcard_reader_close_sessions" ,8},//OK + + /* session api */ + {"smartcard_session_get_reader", 9},//OK + {"smartcard_session_get_atr", 10},//OK + {"smartcard_session_close", 11},//OK + {"smartcard_session_is_closed", 12},//OK + {"smartcard_session_close_channels", 13},//OK + {"smartcard_session_open_basic_channel", 14}, //good + {"smartcard_session_open_logical_channel", 15}, //good + + /* channel api */ + {"smartcard_channel_close", 16}, //good + {"smartcard_channel_is_basic_channel", 17}, //good + {"smartcard_channel_is_closed", 18}, // good + {"smartcard_channel_get_select_response", 19}, //good + {"smartcard_channel_get_session", 20}, //good + {"smartcard_channel_transmit", 21}, //good + {"smartcard_channel_transmit_get_response", 22}, //good + {"smartcard_channel_select_next", 23}, //not good + + /* -----------*/ + {"Finish" , 0x00ff}, + {NULL , 0x0000}, +}; + +void tc_usage_print(void) +{ + int i = 0; + + while (tc_table[i].tc_name) + { + if (tc_table[i].tc_code != 0x00ff) + { + TC_PRT("Key %d : usage %s", tc_table[i].tc_code, tc_table[i].tc_name); + } + else + { + TC_PRT("Key %d : usage %s\n\n", 0x00ff, tc_table[i].tc_name); + } + + i++; + } +} + +int test_input_callback(void *data) +{ + int ret = 0; + long test_id = (long)data; + + switch (test_id) { + case 0x00ff: + TC_PRT("Finished"); + g_main_loop_quit(main_loop); + break; + case 1: //smartcard_initialize + { + int ret; + ret = smartcard_initialize(); + + if(ret == SMARTCARD_ERROR_NONE) + TC_PRT("smartcard initialize success"); + else + TC_PRT("smartcard initialize failed"); + } + break; + case 2: //smartcard_deinitialize + { + int ret; + ret = smartcard_deinitialize(); + + if(ret == SMARTCARD_ERROR_NONE) + TC_PRT("smartcard deinitialize success"); + else + TC_PRT("smartcard deinitialize failed"); + } + break; + case 3: //smartcard_get_readers + { + int pLength; + int *phReaders = NULL; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_get_readers is success"); + TC_PRT("reader handle : %d", phReaders[0]); + TC_PRT("readers length : %d", pLength); + } + else + { + TC_PRT("smartcard_get_readers is failed : %d", ret); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 5: //smartcard_reader_get_name + { + int pLength; + int *phReaders = NULL; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + char * pReader = NULL; + + ret = smartcard_reader_get_name(phReaders[0], &pReader); + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_reader_get_name success"); + TC_PRT("reader name : %s", pReader); + } + else + { + TC_PRT("smartcard_reader_get_name failed : %d", ret); + } + + if(pReader != NULL) + free(pReader); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 6: //smartcard_reader_is_secure_element_present + { + int pLength; + int *phReaders = NULL; + bool is_present = false; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_is_secure_element_present(phReaders[0], &is_present); + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_reader_is_secure_element_present is success"); + TC_PRT("reader secure element present : %d", is_present); + } + else + { + TC_PRT("smartcard_reader_is_secure_element_present is failed : %d", ret); + } + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 7: //smartcard_reader_open_session + { + int pLength; + int *phReaders = NULL; + int session; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_reader_open_session is success"); + TC_PRT("session : %d", (int)session); + } + else + { + TC_PRT("smartcard_reader_open_session is failed : %d", ret); + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 8: //smartcard_reader_close_sessions + { + int pLength; + int *phReaders = NULL; + int session; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE) + { + ret = smartcard_reader_close_sessions(phReaders[0]); + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_reader_close_sessions success"); + } + else + { + TC_PRT("smartcard_reader_close_sessions failed : %d", ret); + } + } + else + { + TC_PRT("open session failed : %d", ret); + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 9: //smartcard_session_get_reader + { + int pLength; + int *phReaders = NULL; + int session; + int reader; + char * pReader = NULL; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + ret = smartcard_session_get_reader(session, &reader); + ret = smartcard_reader_get_name(reader, &pReader); + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_session_get_reader success"); + TC_PRT("reader name : %s", pReader); + } + else + { + TC_PRT("smartcard_session_get_reader failed"); + } + + if(pReader != NULL) + free(pReader); + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 10: //smartcard_session_get_atr + { + int i = 0; + int pLength; + int *phReaders = NULL; + int session; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + pLength = 0; + unsigned char * pAtr = NULL; + + ret = smartcard_session_get_atr(session, &pAtr, &pLength); + + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_serssion_get_atr success : %d", pLength); + g_print("response is "); + for(i = 0; i < pLength; i++) + g_print("%x ", (int)pAtr[i]); + g_print("\n"); + } + else + { + TC_PRT("smartcard_serssion_get_atr is failed"); + } + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 11: //smartcard_session_close + { + int pLength; + int *phReaders = NULL; + int session; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + ret = smartcard_session_close(session); + if(ret == SMARTCARD_ERROR_NONE) + TC_PRT("smartcard_session_close is success"); + else + TC_PRT("smartcard_session_close is failed"); + } + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 12: //smartcard_session_is_closed + { + int pLength; + int *phReaders = NULL; + int session; + bool is_closed = false; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + ret = smartcard_session_close(session); + ret = smartcard_session_is_closed(session, &is_closed); + if(ret == SMARTCARD_ERROR_NONE && is_closed == true) + TC_PRT("smartcard_session_is_closed is success"); + else + TC_PRT("smartcard_session_is_closed is failed"); + } + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 13: //smartcard_session_close_channels + { + int pLength; + int *phReaders = NULL; + int session; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + ret = smartcard_session_close_channels(session); + if(ret == SMARTCARD_ERROR_NONE) + TC_PRT("smartcard_session_close_channels is success"); + else + TC_PRT("smartcard_session_close_channels is failed"); + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 14: //smartcard_session_open_basic_channel + { + int pLength; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + ret = smartcard_session_open_basic_channel(session, aid, 12, 0x00, &channel); + if(ret == SMARTCARD_ERROR_NONE) + TC_PRT("smartcard_session_open_basic_channel is success : %d", (int)channel); + else + TC_PRT("smartcard_session_open_basic_channel is failed"); + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 15: //smartcard_session_open_logical_channel + { + int pLength; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + ret = smartcard_session_open_logical_channel(session, aid, 12, 0x04, &channel); + if(ret == SMARTCARD_ERROR_NONE) + TC_PRT("smartcard_session_open_basic_channel is success : %d", (int)channel); + else + TC_PRT("smartcard_session_open_basic_channel is failed : %d", ret); + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 16: //smartcard_channel_close + { + int pLength; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + ret = smartcard_session_open_logical_channel(session, aid, 12, 0x00, &channel); + + if(ret == SMARTCARD_ERROR_NONE) + { + ret = smartcard_channel_close(channel); + if(ret == SMARTCARD_ERROR_NONE) + TC_PRT("smartcard_channel_close is success"); + else + TC_PRT("smartcard_channel_close is failed : %d", ret); + } + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 17: //smartcard_channel_is_basic_channel + { + int pLength; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + bool is_basic = true; + ret = smartcard_session_open_logical_channel(session, aid, 12, 0x00, &channel); + + if(ret == SMARTCARD_ERROR_NONE) + { + ret = smartcard_channel_is_basic_channel(channel, &is_basic); + if(ret == SMARTCARD_ERROR_NONE && is_basic == false) + TC_PRT("smartcard_channel_is_basic_channel is success"); + else + TC_PRT("smartcard_channel_is_basic_channel is failed"); + } + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 18: //smartcard_channel_is_closed + { + int pLength; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + bool is_close = false; + ret = smartcard_session_open_logical_channel(session, aid, 12, 0x00, &channel); + if(ret == SMARTCARD_ERROR_NONE) + { + ret = smartcard_channel_close(channel); + + ret = smartcard_channel_is_closed(channel, &is_close); + if(ret == SMARTCARD_ERROR_NONE && is_close == true) + TC_PRT("smartcard_channel_is_closed is success"); + else + TC_PRT("smartcard_channel_is_closed is failed"); + } + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 19: //smartcard_channel_get_select_response + { + int pLength = 5; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + int i; + unsigned char * pSelectResponse; + + ret = smartcard_session_open_logical_channel(session, aid, 12, 0x00, &channel); + + if(ret == SMARTCARD_ERROR_NONE) + { + ret = smartcard_channel_get_select_response(channel, &pSelectResponse, &pLength); + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_channel_get_select_response is success"); + for(i = 0; i < pLength; i++) + g_print("%x ", (int)pSelectResponse[i]); + } + else + { + TC_PRT("smartcard_channel_get_select_response is failed"); + } + } + + if(pSelectResponse != NULL) + free(pSelectResponse); + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 20: // smartcard_channel_get_session + { + int pLength; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + int session_handle; + + ret = smartcard_session_open_logical_channel(session, aid, 12, 0x00, &channel); + if(ret == SMARTCARD_ERROR_NONE) + { + ret = smartcard_channel_get_session(channel, &session_handle); + + if(ret == SMARTCARD_ERROR_NONE) + TC_PRT("smartcard_channel_get_session is success: %d", session_handle); + else + TC_PRT("smartcard_channel_get_session is failed"); + } + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 21: + { + int i = 0; + int pLength; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + unsigned char command[] = { 0x00, 0x28, 0x00, 0x00 }; + unsigned char *response = NULL; + int resp_len = 50; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + ret = smartcard_session_open_logical_channel(session, aid, 12, 0x00, &channel); + + if(ret == SMARTCARD_ERROR_NONE) + { + ret = smartcard_channel_transmit(channel, command, 4, &response, &resp_len); + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_channel_transmit is success"); + + g_print("response is "); + for(i = 0; i < resp_len; i++) + g_print("%x ", (int)response[i]); + g_print("\n"); + } + else + { + TC_PRT("smartcard_channel_transmit is failed"); + } + } + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 22: + { + int pLength = 5; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + unsigned char command[] = { 0x00, 0x28, 0x00, 0x00 }; + unsigned char *response = NULL; + int resp_len = 50; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + int i; + unsigned char * ptransmitResponse; + + ret = smartcard_session_open_logical_channel(session, aid, 12, 0x00, &channel); + if(ret == SMARTCARD_ERROR_NONE) + { + ret = smartcard_channel_transmit(channel, command, 4, &response, &resp_len); + ret = smartcard_channel_transmit_retrieve_response(channel, &ptransmitResponse, &pLength); + + if(ret == SMARTCARD_ERROR_NONE) + { + TC_PRT("smartcard_channel_transmit_get_response is success"); + + g_print("response is "); + for(i = 0; i < pLength; i++) + g_print("%x ", (int)ptransmitResponse[i]); + g_print("\n"); + } + else + { + TC_PRT("smartcard_channel_transmit_get_response is failed"); + } + } + } + + ret = smartcard_session_close(session); + } + + if(phReaders != NULL) + free(phReaders); + } + break; + case 23: + { + int pLength = 5; + int *phReaders = NULL; + int session; + int channel; + unsigned char aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; + + ret = smartcard_get_readers(&phReaders, &pLength); + + if(ret == SMARTCARD_ERROR_NONE && pLength != 0) + { + ret = smartcard_reader_open_session(phReaders[0], &session); + + if(ret == SMARTCARD_ERROR_NONE && session != 0) + { + ret = smartcard_session_open_logical_channel(session, aid, 12, 0x00, &channel); + if(ret == SMARTCARD_ERROR_NONE) + { + bool is_next = true; + ret = smartcard_channel_select_next(channel, &is_next); + if(ret == SMARTCARD_ERROR_NONE && is_next == false) + TC_PRT("smartcard_channel_select_next is success"); + else + TC_PRT("smartcard_channel_select_next is failed"); + } + } + + ret = smartcard_session_close(session); + } + if(phReaders != NULL) + free(phReaders); + } + break; + default: + break; + } + + return 0; +} + +static gboolean key_event_cb(GIOChannel *chan, + GIOCondition cond, + gpointer data) +{ + char buf[BUFFER_LEN] = { 0 }; + + gsize len = 0; + long test_id; + + memset(buf, 0, sizeof(buf)); + + if (g_io_channel_read_chars(chan, buf, sizeof(buf), &len, NULL) == G_IO_STATUS_ERROR) + return FALSE; + + tc_usage_print(); + test_id = atoi(buf); + + if (test_id) + g_idle_add(test_input_callback, (void *)test_id); + + return TRUE; +} + + +int main(int argc, char ** argv) +{ + GIOChannel *key_io; + +//#if !GLIB_CHECK_VERSION(2,35,0) +// g_type_init(); +//#endif + + key_io = g_io_channel_unix_new(fileno(stdin)); + + g_io_channel_set_encoding(key_io, NULL, NULL); + g_io_channel_set_flags(key_io, G_IO_FLAG_NONBLOCK, NULL); + + g_io_add_watch(key_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + key_event_cb, NULL); + + g_io_channel_unref(key_io); + + main_loop = g_main_loop_new(NULL, FALSE); + + g_main_loop_run(main_loop); + + return 0; +} -- 2.7.4