Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: Mart Somermaa <[email protected]>
  • Loading branch information
mrts committed Nov 6, 2020
1 parent 0edd30e commit 5064e12
Show file tree
Hide file tree
Showing 23 changed files with 2,612 additions and 0 deletions.
41 changes: 41 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
BasedOnStyle: WebKit

Standard: Cpp11
ColumnLimit: 100

# Disable reflow of qdoc comments: indentation rules are different.
# Translation comments are also excluded
CommentPragmas: "^!|^:"

# We want & and * to be attached to the type
PointerBindsToType: true

# We want long lines to break before the operators, but not before a '='
BreakBeforeBinaryOperators: NonAssignment

# Braces are usually attached, but not after functions or classes declaration
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false

AlignAfterOpenBracket: true
AlwaysBreakTemplateDeclarations: true
AllowShortFunctionsOnASingleLine: Inline
SpaceInEmptyBlock: false
FixNamespaceComments: true
Cpp11BracedListStyle: true
BreakConstructorInitializers: AfterColon

SortIncludes: false

ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
70 changes: 70 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Assures that line endings are consistently normalized.
#
# Comments:
# - use filter='...' to pass through external filters, e.g. clang-format

# --- Source files
*.c text
*.cc text
*.cpp text
*.cxx text
*.h text
*.hh text
*.hpp text
*.ipp text

*.js text
*.pl text
*.py text

# --- Resource files
*.rc text eol=crlf
*.rc2 text eol=crlf

# --- Windows and VS-specific files
*.bat text eol=crlf
*.cmd text eol=crlf
*.cpy text eol=crlf
*.ddf text eol=crlf
*.def text eol=crlf
*.inf text eol=crlf
*.msbuild text eol=crlf
*.sln text eol=crlf
*.vcproj text eol=crlf
*.vcxproj text eol=crlf

# --- Text files
*.htm text
*.html text
*.md text
*.properties text
*.rst text
*.txt text
*.xml text

# --- Binary files
*.bmp binary
*.dll binary
*.exe binary
*.gif binary
*.ico binary
*.jpg binary
*.lib binary
*.png binary

# --- git files
.gitignore text eol=lf
.gitattributes text eol=lf
.clang-format text eol=lf

# --- Makefiles
Makefile text eol=lf
Makefile.dep text eol=lf

# --- CMake files
CMakeLists.txt text

# --- Shell scripts, git hooks
*.sh text eol=lf
commit-msg text eol=lf
pre-commit text eol=lf
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.swp
tags
build/
.vscode/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "tests/lib/libpcsc-mock"]
path = tests/lib/libpcsc-mock
url = https://github.com/web-eid/libpcsc-mock
104 changes: 104 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
cmake_minimum_required(VERSION 3.8.0)
if(POLICY CMP0092)
cmake_policy(SET CMP0092 NEW)
endif()

project(pcsc-cpp)

# The libpcsc-cpp library itself.

add_library(${PROJECT_NAME}
STATIC
include/${PROJECT_NAME}/${PROJECT_NAME}.hpp
include/${PROJECT_NAME}/comp_winscard.hpp
include/flag-set-cpp/flag_set.hpp
include/magic_enum/magic_enum.hpp
src/Context.hpp
src/Reader.cpp
src/SCardCall.hpp
src/SmartCard.cpp
src/listReaders.cpp
src/utils.cpp
)

target_include_directories(${PROJECT_NAME}
PUBLIC
include
)

target_compile_features(${PROJECT_NAME}
PUBLIC
cxx_std_17
)

target_compile_options(${PROJECT_NAME} PUBLIC
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)

target_compile_definitions(${PROJECT_NAME} PUBLIC
$<$<CXX_COMPILER_ID:MSVC>:WIN32_LEAN_AND_MEAN;UNICODE>
)

target_link_libraries(${PROJECT_NAME} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:Ws2_32>
)

# Common compile options.

set(CMAKE_CXX_EXTENSIONS OFF)

# PC/SC API dependencies.

add_library(pcsc INTERFACE)
if(MSVC)
# no extra includes required
target_link_libraries(pcsc INTERFACE winscard)
elseif(APPLE)
# no extra includes required
target_link_libraries(pcsc INTERFACE "-framework PCSC")
else()
find_package(PkgConfig)
pkg_check_modules(PCSC libpcsclite)
target_include_directories(${PROJECT_NAME} PRIVATE ${PCSC_INCLUDE_DIRS})
target_link_libraries(pcsc INTERFACE ${PCSC_LIBRARIES})
endif()

# Common testing options.

enable_testing()

find_package(GTest REQUIRED)

# Mock tests that use libpcsc-mock to mock PC/SC API calls.

set(MOCK_TEST_EXE lib${PROJECT_NAME}-test-mock)

add_subdirectory(tests/lib/libpcsc-mock)

add_executable(${MOCK_TEST_EXE}
tests/mock/test-select-card-reader-and-card.cpp
tests/mock/test-connect-to-card-transmit-apdus.cpp
)

target_link_libraries(${MOCK_TEST_EXE}
${PROJECT_NAME}
pcsc-mock
GTest::Main
)

add_test(${MOCK_TEST_EXE} ${MOCK_TEST_EXE})

# Integration tests that use the real operating system PC/SC service.

set(INTEGRATION_TEST_EXE lib${PROJECT_NAME}-test-integration)

add_executable(${INTEGRATION_TEST_EXE}
tests/integration/test-${PROJECT_NAME}.cpp
)

target_link_libraries(${INTEGRATION_TEST_EXE}
${PROJECT_NAME}
pcsc
GTest::Main
)
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# libpcsc-cpp

C++ library for accessing smart cards using the PC/SC API.

## Usage

Example how to list available readers, connect to the smart card in first
reader and transmit an APDU:

auto readers = listReaders();
auto card = readers[0].connectToCard();
auto command = CommandApdu::fromBytes({0x2, 0x1, 0x3, 0x4});

auto transactionGuard = card->beginTransaction();
auto response = card->transmit(command);

See more examples in [tests](tests).

## Building

In Ubuntu:

apt install build-essential pkg-config cmake libgtest-dev valgrind libpcsclite-dev
sudo bash -c 'cd /usr/src/googletest && cmake . && cmake --build . --target install'

cd build
cmake .. # optionally with -DCMAKE_BUILD_TYPE=Debug
cmake --build . # optionally with VERBOSE=1

## Testing

Build as described above, then, inside the `build` directory, run:

ctest # or 'valgrind --leak-check=full ctest'

`ctest` runs tests that use the _libscard-mock_ library to mock PC/SC API calls.

There are also integration tests that use the real operating system PC/SC
service, run them inside `build` directory with:

./libpcsc-cpp-test-integration

## Development guidelines

- Format code with `scripts/clang-format.sh` before committing
- See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)
8 changes: 8 additions & 0 deletions docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
TODO:

- coding conventions - Qt coding style and conventions
- gtest and winscard-mock usage
- API
- architecture
- technical design
- describe PIMPL (we don't want to leak `winscard.h` to clients)
Loading

0 comments on commit 5064e12

Please sign in to comment.