Browse Source

reinit

master
Robin Thoni 6 years ago
parent
commit
431f502d30
46 changed files with 3961 additions and 0 deletions
  1. 40
    0
      CMakeLists.txt
  2. 66
    0
      README.md
  3. 20
    0
      cli/CMakeLists.txt
  4. 100
    0
      cli/DBO/CommandLineOption.cpp
  5. 70
    0
      cli/DBO/CommandLineOption.h
  6. 98
    0
      cli/cli/CommandLineParser.cpp
  7. 32
    0
      cli/cli/CommandLineParser.h
  8. 452
    0
      cli/cli/MainClass.cpp
  9. 72
    0
      cli/cli/MainClass.h
  10. 7
    0
      cli/main.cpp
  11. 31
    0
      gui/CMakeLists.txt
  12. 17
    0
      gui/Core/LibNfcOperation.cpp
  13. 38
    0
      gui/Core/LibNfcOperation.h
  14. 30
    0
      gui/Core/LibNfcOperation.hxx
  15. 66
    0
      gui/UI/MainWindow.cpp
  16. 36
    0
      gui/UI/MainWindow.h
  17. 122
    0
      gui/UI/MainWindow.ui
  18. 17
    0
      gui/main.cpp
  19. 45
    0
      libnfc_cpptools/CMakeLists.txt
  20. 27
    0
      libnfc_cpptools/inc/libnfc_cpptools/ArrayUtils.h
  21. 70
    0
      libnfc_cpptools/inc/libnfc_cpptools/FreeFareAccessBits.h
  22. 34
    0
      libnfc_cpptools/inc/libnfc_cpptools/FreeFareDevice.h
  23. 66
    0
      libnfc_cpptools/inc/libnfc_cpptools/FreeFareSector.h
  24. 74
    0
      libnfc_cpptools/inc/libnfc_cpptools/FreeFareTag.h
  25. 44
    0
      libnfc_cpptools/inc/libnfc_cpptools/LibNfc.h
  26. 42
    0
      libnfc_cpptools/inc/libnfc_cpptools/NfcDevice.h
  27. 158
    0
      libnfc_cpptools/inc/libnfc_cpptools/Result.h
  28. 51
    0
      libnfc_cpptools/inc/libnfc_cpptools/StringUtils.h
  29. 219
    0
      libnfc_cpptools/src/freefare/FreeFareAccessBits.cpp
  30. 37
    0
      libnfc_cpptools/src/freefare/FreeFareDevice.cpp
  31. 31
    0
      libnfc_cpptools/src/freefare/FreeFareDeviceInternal.cpp
  32. 32
    0
      libnfc_cpptools/src/freefare/FreeFareDeviceInternal.h
  33. 117
    0
      libnfc_cpptools/src/freefare/FreeFareSector.cpp
  34. 335
    0
      libnfc_cpptools/src/freefare/FreeFareTag.cpp
  35. 109
    0
      libnfc_cpptools/src/freefare/FreeFareTagInternal.cpp
  36. 53
    0
      libnfc_cpptools/src/freefare/FreeFareTagInternal.h
  37. 83
    0
      libnfc_cpptools/src/libnfc/LibNfc.cpp
  38. 64
    0
      libnfc_cpptools/src/libnfc/LibNfcInternal.cpp
  39. 43
    0
      libnfc_cpptools/src/libnfc/LibNfcInternal.h
  40. 49
    0
      libnfc_cpptools/src/libnfc/NfcDevice.cpp
  41. 50
    0
      libnfc_cpptools/src/libnfc/NfcDeviceInternal.cpp
  42. 46
    0
      libnfc_cpptools/src/libnfc/NfcDeviceInternal.h
  43. 44
    0
      libnfc_cpptools/src/utils/ArrayUtils.cpp
  44. 168
    0
      libnfc_cpptools/src/utils/StringUtils.cpp
  45. 14
    0
      tests/CMakeLists.txt
  46. 542
    0
      tests/test-main.cpp

+ 40
- 0
CMakeLists.txt View File

@@ -0,0 +1,40 @@
1
+cmake_minimum_required(VERSION 2.8)
2
+
3
+# git current hash
4
+execute_process(COMMAND git log --pretty=format:%h -n 1
5
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
6
+        OUTPUT_VARIABLE GIT_SHA1)
7
+
8
+execute_process(COMMAND git symbolic-ref -q --short HEAD
9
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
10
+        OUTPUT_VARIABLE GIT_REF_NAME)
11
+if ("${GIT_REF_NAME}" EQUAL "")
12
+    execute_process(COMMAND git describe --tags --exact-match
13
+            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
14
+            OUTPUT_VARIABLE GIT_REF_NAME)
15
+endif()
16
+string(STRIP "${GIT_REF_NAME}" GIT_REF_NAME)
17
+string(STRIP "${GIT_SHA1}" GIT_SHA1)
18
+add_definitions(-DGIT_SHA1=${GIT_SHA1} -DGIT_REF_NAME=${GIT_REF_NAME})
19
+
20
+
21
+set(PROJECT_NAME nfc_cpptools)
22
+project(${PROJECT_NAME})
23
+
24
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
25
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
26
+    message(STATUS "Debug build")
27
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -g3")
28
+else()
29
+    message(STATUS "Release build")
30
+endif()
31
+
32
+add_subdirectory(libnfc_cpptools)
33
+add_subdirectory(cli)
34
+#add_subdirectory(gui)
35
+
36
+find_package(GTest)
37
+if (GTEST_FOUND)
38
+    enable_testing()
39
+    add_subdirectory(tests)
40
+endif (GTEST_FOUND)

+ 66
- 0
README.md View File

@@ -0,0 +1,66 @@
1
+Mifare-Tools
2
+============
3
+
4
+Library and command line tools for Mifare classic 1K NFC tags.
5
+It can:
6
+- List NFC devices
7
+- List NFC tags
8
+- Read a Mifare Classic 1K tag
9
+- Write a Mifare Classic 1K tag
10
+
11
+Usage
12
+=====
13
+
14
+List devices:
15
+```shell
16
+nfc_cpptools-cli --devices
17
+```
18
+
19
+List tags:
20
+```shell
21
+nfc_cpptools-cli --tags
22
+```
23
+
24
+Read a tag with some command line keys:
25
+```shell
26
+nfc_cpptools-cli --read --key ffffffffffff --key a1a2a3a4a5a6
27
+```
28
+
29
+Read a tag with a key file and save dump to a file:
30
+```shell
31
+nfc_cpptools-cli --read --key-file ~/my_key_file --output ~/my_dump
32
+```
33
+
34
+Write a tag with a command line key, from stdin:
35
+```shell
36
+cat ~/my_dump | nfc_cpptools-cli --write --key-file ffffffffffff
37
+```
38
+
39
+Write a tag with a command line key, from a file:
40
+```shell
41
+nfc_cpptools-cli --write --key-file ffffffffffff --input ~/my_dump
42
+```
43
+
44
+Write a tag with a key file, from a file, on a specified device, on a specified tag:
45
+```shell
46
+nfc_cpptools-cli --write --key-file ffffffffffff --input ~/my_dump --device pn53x_usb:003:008 --tag a1a2a3
47
+```
48
+
49
+Build and Install
50
+=================
51
+Requirements
52
+------------
53
+Libnfc          https://github.com/nfc-tools/libnfc
54
+Libfreefare     https://github.com/nfc-tools/libfreefare
55
+
56
+Build and Install
57
+-----------------
58
+```shell
59
+git clone https://git.rthoni.com/robin.thoni/mifare-tools
60
+cd mifare-tools
61
+mkdir build
62
+cd build
63
+cmake ..
64
+make
65
+sudo make install
66
+```

+ 20
- 0
cli/CMakeLists.txt View File

@@ -0,0 +1,20 @@
1
+include_directories(
2
+        .
3
+        ${LIBNFC_CPPTOOLS_INCLUDE_PATH}
4
+)
5
+
6
+set(SOURCE_FILES
7
+        main.cpp
8
+        cli/MainClass.cpp
9
+        cli/MainClass.h
10
+        cli/CommandLineParser.cpp
11
+        cli/CommandLineParser.h
12
+        DBO/CommandLineOption.cpp
13
+        DBO/CommandLineOption.h
14
+        )
15
+
16
+add_executable(${PROJECT_NAME}-cli ${SOURCE_FILES})
17
+target_link_libraries(${PROJECT_NAME}-cli ${PROJECT_NAME})
18
+
19
+install(TARGETS ${PROJECT_NAME}-cli
20
+        RUNTIME DESTINATION bin)

+ 100
- 0
cli/DBO/CommandLineOption.cpp View File

@@ -0,0 +1,100 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#include "CommandLineOption.h"
6
+
7
+CommandLineOption::CommandLineOption(CommandLineParser* parser, const std::string &longName, char shortName,
8
+                                     const std::string &description, const std::string &valueName,
9
+                                     const std::string &defaultValue)
10
+    : _longName(longName)
11
+    , _shortName(shortName)
12
+    , _description(description)
13
+    , _valueName(valueName)
14
+    , _defaultValue(defaultValue)
15
+    , _isSet(false)
16
+{
17
+    parser->addOption(this);
18
+}
19
+
20
+const std::string &CommandLineOption::getLongName() const
21
+{
22
+    return _longName;
23
+}
24
+
25
+void CommandLineOption::setLongName(const std::string &longName)
26
+{
27
+    _longName = longName;
28
+}
29
+
30
+char CommandLineOption::getShortName() const
31
+{
32
+    return _shortName;
33
+}
34
+
35
+void CommandLineOption::setShortName(char shortName)
36
+{
37
+    _shortName = shortName;
38
+}
39
+
40
+const std::string &CommandLineOption::getDescription() const
41
+{
42
+    return _description;
43
+}
44
+
45
+void CommandLineOption::setDescription(const std::string &description)
46
+{
47
+    _description = description;
48
+}
49
+
50
+const std::string &CommandLineOption::getValueName() const
51
+{
52
+    return _valueName;
53
+}
54
+
55
+void CommandLineOption::setValueName(const std::string &valueName)
56
+{
57
+    _valueName = valueName;
58
+}
59
+
60
+const std::string &CommandLineOption::getDefaultValue() const
61
+{
62
+    return _defaultValue;
63
+}
64
+
65
+void CommandLineOption::setDefaultValue(const std::string &defaultValue)
66
+{
67
+    _defaultValue = defaultValue;
68
+}
69
+
70
+const std::vector<std::string> &CommandLineOption::getValues() const
71
+{
72
+    return _values;
73
+}
74
+
75
+void CommandLineOption::addValue(const std::string &value)
76
+{
77
+    _values.push_back(value);
78
+}
79
+
80
+bool CommandLineOption::isSet() const
81
+{
82
+    return _isSet;
83
+}
84
+
85
+void CommandLineOption::setIsSet(bool isSet)
86
+{
87
+    _isSet = isSet;
88
+}
89
+
90
+bool CommandLineOption::hasValue() const
91
+{
92
+    return !_valueName.empty();
93
+}
94
+
95
+const std::string &CommandLineOption::getValue() const
96
+{
97
+    if (_values.empty())
98
+        return _defaultValue;
99
+    return _values[_values.size() - 1];
100
+}

+ 70
- 0
cli/DBO/CommandLineOption.h View File

@@ -0,0 +1,70 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#ifndef PDNS_SLAVE_COMMANDLINEOPTION_H
6
+#define PDNS_SLAVE_COMMANDLINEOPTION_H
7
+
8
+# include <string>
9
+# include <vector>
10
+#include <cli/CommandLineParser.h>
11
+
12
+class CommandLineParser;
13
+
14
+class CommandLineOption
15
+{
16
+public:
17
+    CommandLineOption(CommandLineParser* parser, const std::string& longName, char shortName,
18
+                      const std::string& description, const std::string& valueName = "",
19
+                      const std::string& defaultValue = "");
20
+
21
+    const std::string &getLongName() const;
22
+
23
+    void setLongName(const std::string &longName);
24
+
25
+    char getShortName() const;
26
+
27
+    void setShortName(char shortName);
28
+
29
+    const std::string &getDescription() const;
30
+
31
+    void setDescription(const std::string &description);
32
+
33
+    const std::string &getValueName() const;
34
+
35
+    void setValueName(const std::string &valueName);
36
+
37
+    const std::string &getDefaultValue() const;
38
+
39
+    void setDefaultValue(const std::string &defaultValue);
40
+
41
+    const std::vector<std::string> &getValues() const;
42
+
43
+    const std::string &getValue() const;
44
+
45
+    void addValue(const std::string &value);
46
+
47
+    bool isSet() const;
48
+
49
+    void setIsSet(bool isSet);
50
+
51
+    bool hasValue() const;
52
+
53
+private:
54
+    std::string _longName;
55
+
56
+    char _shortName;
57
+
58
+    std::string _description;
59
+
60
+    std::string _valueName;
61
+
62
+    std::string _defaultValue;
63
+
64
+    std::vector<std::string> _values;
65
+
66
+    bool _isSet;
67
+};
68
+
69
+
70
+#endif //PDNS_SLAVE_COMMANDLINEOPTION_H

+ 98
- 0
cli/cli/CommandLineParser.cpp View File

@@ -0,0 +1,98 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#include <getopt.h>
6
+#include <iostream>
7
+#include "CommandLineParser.h"
8
+
9
+CommandLineParser::CommandLineParser(int argc, char **argv)
10
+    : _argc(argc)
11
+    , _argv(argv)
12
+{
13
+}
14
+
15
+bool CommandLineParser::parse()
16
+{
17
+    std::string shortOpts;
18
+    option opts[_options.size() + 1];
19
+    for (unsigned i = 0; i < _options.size(); ++i)
20
+    {
21
+        auto opt = _options[i];
22
+        shortOpts += opt->getShortName();
23
+        if (opt->hasValue())
24
+            shortOpts += ":";
25
+        opts[i].name = opt->getLongName().c_str();
26
+        opts[i].has_arg = opt->hasValue();
27
+        opts[i].flag = 0;
28
+        opts[i].val = opt->getShortName();
29
+    }
30
+    opts[_options.size()] = {0, 0, 0, 0};
31
+    int option;
32
+    extern int optind;
33
+    extern char* optarg;
34
+    bool valid = true;
35
+    while ((option = getopt_long(_argc, _argv, shortOpts.c_str(), opts, 0)) != -1)
36
+    {
37
+        bool optValid = false;
38
+        for (unsigned i = 0; i < _options.size(); ++i)
39
+        {
40
+            auto opt = _options[i];
41
+            if (opt->getShortName() == option)
42
+            {
43
+                optValid = true;
44
+                opt->setIsSet(true);
45
+                if (opt->hasValue())
46
+                    opt->addValue(optarg);
47
+            }
48
+        }
49
+        if (!optValid)
50
+            valid = false;
51
+    }
52
+    return optind == _argc && valid;
53
+}
54
+
55
+void CommandLineParser::addOption(CommandLineOption* opt)
56
+{
57
+    _options.push_back(opt);
58
+}
59
+
60
+int CommandLineParser::showHelp(int status, bool stdErr)
61
+{
62
+    auto& out = stdErr ? std::cerr : std::cout;
63
+    int longestName = 0;
64
+    int longestValue = 0;
65
+    for (auto opt : _options) {
66
+        if (opt->getLongName().length() > longestName) {
67
+            longestName = opt->getLongName().length();
68
+        }
69
+        std::string value = "<" + opt->getValueName();
70
+        if (!opt->getDefaultValue().empty()) {
71
+            value += "=" + opt->getDefaultValue();
72
+        }
73
+        value += ">";
74
+        if (value.length() > longestValue) {
75
+            longestValue = value.length();
76
+        }
77
+    }
78
+    out << "Options:" << std::endl;
79
+    for (auto opt : _options)
80
+    {
81
+        out << "  -" << opt->getShortName() << ", --" << opt->getLongName();
82
+        out << std::string(longestName - opt->getLongName().length() + 2, ' ');
83
+        if (opt->hasValue())
84
+        {
85
+            std::string value = "<" + opt->getValueName();
86
+            if (!opt->getDefaultValue().empty()) {
87
+                value += "=" + opt->getDefaultValue();
88
+            }
89
+            value += ">";
90
+            out << value << std::string(longestValue - value.length() + 2, ' ');
91
+        }
92
+        else {
93
+            out << std::string(longestValue + 2, ' ');
94
+        }
95
+        out << opt->getDescription() << std::endl;
96
+    }
97
+    return status;
98
+}

+ 32
- 0
cli/cli/CommandLineParser.h View File

@@ -0,0 +1,32 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#ifndef PDNS_SLAVE_COMMANDLINEPARSER_H
6
+#define PDNS_SLAVE_COMMANDLINEPARSER_H
7
+
8
+# include "../DBO/CommandLineOption.h"
9
+
10
+class CommandLineOption;
11
+
12
+class CommandLineParser
13
+{
14
+public:
15
+    CommandLineParser(int argc, char** argv);
16
+
17
+    bool parse();
18
+
19
+    int showHelp(int status = 0, bool stdErr = true);
20
+
21
+    void addOption(CommandLineOption* opt);
22
+
23
+private:
24
+    int _argc;
25
+
26
+    char** _argv;
27
+
28
+    std::vector<CommandLineOption*> _options;
29
+};
30
+
31
+
32
+#endif //PDNS_SLAVE_COMMANDLINEPARSER_H

+ 452
- 0
cli/cli/MainClass.cpp View File

@@ -0,0 +1,452 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#include <iostream>
6
+#include <sysexits.h>
7
+#include <iomanip>
8
+#include <fstream>
9
+#include <libnfc_cpptools/StringUtils.h>
10
+#include <libnfc_cpptools/FreeFareDevice.h>
11
+#include <libnfc_cpptools/Result.h>
12
+#include <libnfc_cpptools/LibNfc.h>
13
+#include "CommandLineParser.h"
14
+#include "MainClass.h"
15
+
16
+#define EX_OUTPUT_ERROR 1
17
+#define EX_INPUT_ERROR 2
18
+#define EX_KEY_ERROR 10
19
+#define EX_LIB_NFC_ERROR 12
20
+#define EX_NFC_DEVICE_NOT_FOUND 13
21
+#define EX_NFC_TAG_NOT_FOUND 14
22
+#define EX_MAP_KEYS_ERROR 15
23
+#define EX_READ_ERROR 16
24
+#define EX_WRITE_ERROR 17
25
+
26
+MainClass::MainClass(int argc, char *argv[])
27
+    : _argc(argc)
28
+    , _argv(argv)
29
+{
30
+}
31
+
32
+int MainClass::main()
33
+{
34
+    CommandLineParser parser(_argc, _argv);
35
+    CommandLineOption optionVersion(&parser, "version", 'v', "Show libnfc and mifare-tools versions");
36
+    CommandLineOption optionHelp(&parser, "help", 'h', "Show this help");
37
+
38
+    CommandLineOption optionMap(&parser, "map", 'm', "Map keys for the tag");
39
+    CommandLineOption optionRead(&parser, "read", 'r', "Read the tag");
40
+    CommandLineOption optionWrite(&parser, "write", 'w', "Write the tag");
41
+    CommandLineOption optionDevices(&parser, "devices", 'd', "List NFC devices");
42
+    CommandLineOption optionTags(&parser, "tags", 't', "List NFC tags");
43
+
44
+    CommandLineOption optionDevice(&parser, "device", 'e', "Use the device DEVICE", "DEVICE");
45
+    CommandLineOption optionTag(&parser, "tag", 'u', "Use the UID tag", "UID");
46
+
47
+    CommandLineOption optionKeyFile(&parser, "key-file", 'f', "Path to a file containing keys", "FILE");
48
+    CommandLineOption optionKey(&parser, "key", 'k', "Key to use to authenticate", "KEY");
49
+
50
+    CommandLineOption optionOutput(&parser, "output", 'o', "Redirect output to FILE. '-' to use stdout", "FILE", "-");
51
+    CommandLineOption optionInput(&parser, "input", 'i', "Read input from FILE. '-' to use stdin", "FILE", "-");
52
+
53
+    if (!parser.parse()) {
54
+        return parser.showHelp(EX_USAGE);
55
+    }
56
+    std::string outputFile = optionOutput.getDefaultValue();
57
+    if (optionOutput.isSet()) {
58
+        outputFile = optionOutput.getValue();
59
+    }
60
+
61
+    if (outputFile != "-" && !outputFile.empty()) {
62
+        std::shared_ptr<std::ofstream> fileCout = std::make_shared<std::ofstream>();
63
+        fileCout->open(outputFile);
64
+        if (!*fileCout) {
65
+            std::cerr << "Failed to redirect output: " << strerror(errno) << std::endl;
66
+            return EX_OUTPUT_ERROR;
67
+        }
68
+        _outputStream = fileCout;
69
+    }
70
+
71
+    std::string inputFile = optionInput.getDefaultValue();
72
+    if (optionInput.isSet()) {
73
+        inputFile = optionInput.getValue();
74
+    }
75
+    if (inputFile != "-" && !inputFile.empty()) {
76
+        std::shared_ptr<std::ifstream> fileCin = std::make_shared<std::ifstream>();
77
+        fileCin->open(inputFile);
78
+        if (!*fileCin) {
79
+            std::cerr << "Failed to open input file: " << strerror(errno) << std::endl;
80
+            return EX_INPUT_ERROR;
81
+        }
82
+        _inputStream = fileCin;
83
+    }
84
+
85
+    if (optionVersion.isSet()) {
86
+        printVersion();
87
+        return EX_OK;
88
+    }
89
+    if (optionHelp.isSet()) {
90
+        return parser.showHelp(EX_OK, false);
91
+    }
92
+
93
+    std::string deviceName = optionDevice.getDefaultValue();
94
+    if (optionDevice.isSet()) {
95
+        deviceName = optionDevice.getValue();
96
+    }
97
+
98
+    std::string tagUid = optionTag.getDefaultValue();
99
+    if (optionTag.isSet()) {
100
+        tagUid = optionTag.getValue();
101
+    }
102
+
103
+    std::vector<std::string> keys;
104
+    if (optionKeyFile.isSet()) {
105
+        for (auto filePath : optionKeyFile.getValues()) {
106
+            auto keysResult = readFile(filePath);
107
+            if (!keysResult) {
108
+                keysResult.print();
109
+                return EX_KEY_ERROR;
110
+            }
111
+            auto fileKeys = keysResult.getData();
112
+            keys.insert(keys.end(), fileKeys.begin(), fileKeys.end());
113
+        }
114
+    }
115
+    if (optionKey.isSet()) {
116
+        for (auto key : optionKey.getValues()) {
117
+            auto keyResult = LibNfc::Utils::StringUtils::humanToRaw(key);
118
+            key = keyResult.getData();
119
+            if (!keyResult || key.length() != 6) {
120
+                std::cerr << "Invalid key" << std::endl;
121
+                return EX_KEY_ERROR;
122
+            }
123
+            keys.push_back(key);
124
+        }
125
+    }
126
+
127
+    std::string inputData = "";
128
+
129
+    int res = EX_OK;
130
+    Actions action;
131
+    if (optionRead.isSet()) {
132
+        action = Read;
133
+    }
134
+    else if (optionMap.isSet()) {
135
+        action = Map;
136
+    }
137
+    else if (optionWrite.isSet()) {
138
+        auto readResult = readStream(cin());
139
+        if (!readResult) {
140
+            readResult.print();
141
+            return EX_INPUT_ERROR;
142
+        }
143
+        for (auto data : readResult.getData()) {
144
+            inputData += data;
145
+        }
146
+        action = Write;
147
+    }
148
+    else if (optionDevices.isSet()) {
149
+        action = Devices;
150
+    }
151
+    else if (optionTags.isSet()) {
152
+        action = Tags;
153
+    }
154
+    else {
155
+        std::cerr << "Must select an action (map|read|write|devices|tags)" << std::endl;
156
+        return EX_USAGE;
157
+    }
158
+
159
+    LibNfc::Core::LibNfcContext libNfc;
160
+    auto init = libNfc.init();
161
+    if (!init) {
162
+        init.print();
163
+        res = EX_LIB_NFC_ERROR;
164
+    }
165
+    else
166
+    {
167
+        auto devicesResult = libNfc.getDevices();
168
+        if (!devicesResult)
169
+        {
170
+            devicesResult.print();
171
+            res = EX_LIB_NFC_ERROR;
172
+        }
173
+        else
174
+        {
175
+            auto devices = devicesResult.getData();
176
+
177
+            if (action == Devices)
178
+            {
179
+                for (auto device : devices) {
180
+                    cout() << device->getConnStr() << std::endl;
181
+                }
182
+            }
183
+            else
184
+            {
185
+                auto device = getDevice(deviceName, devices);
186
+                if (device == 0)
187
+                {
188
+                    std::cerr << "NFC device not found" << std::endl;
189
+                    res = EX_NFC_DEVICE_NOT_FOUND;
190
+                }
191
+                else {
192
+                    auto open = device->open();
193
+                    if (!open) {
194
+                        open.print();
195
+                        res = EX_LIB_NFC_ERROR;
196
+                    }
197
+                    else {
198
+
199
+                        LibNfc::FreeFare::FreeFareDevice freeFareDevice(device);
200
+                        auto tagsResult = freeFareDevice.getTags();
201
+                        if (!tagsResult) {
202
+                            tagsResult.print();
203
+                            res = EX_LIB_NFC_ERROR;
204
+                        }
205
+
206
+                        auto tags = tagsResult.getData();
207
+
208
+                        if (action == Tags) {
209
+                            for (auto tag : tags) {
210
+                                cout() << "UID=" << tag->getUid() << " \tType="
211
+                                       << LibNfc::FreeFare::FreeFareTag::getTagTypeString(tag->getType()) << std::endl;
212
+                            }
213
+                        }
214
+                        else {
215
+                            auto tag = getTag(tagUid, tags);
216
+                            if (tag == 0) {
217
+                                std::cerr << "Tag not found" << std::endl;
218
+                                res = EX_NFC_TAG_NOT_FOUND;
219
+                            }
220
+                            else {
221
+                                if (action == Read) {
222
+                                    res = read(tag, keys);
223
+                                }
224
+                                else if (action == Map) {
225
+                                    res = mapKeys(tag, keys);
226
+                                }
227
+                                else if (action == Write) {
228
+                                    res = write(tag, keys, inputData);
229
+                                }
230
+                            }
231
+                        }
232
+                    }
233
+                    device->close();
234
+                }
235
+            }
236
+        }
237
+        libNfc.clean();
238
+    }
239
+
240
+    if (_outputStream != 0) {
241
+        _outputStream->close();
242
+    }
243
+    if (_inputStream != 0) {
244
+        _inputStream->close();
245
+    }
246
+    return res;
247
+}
248
+
249
+int MainClass::mapKeys(std::shared_ptr<LibNfc::FreeFare::FreeFareTag> tag, std::vector<std::string> keys)
250
+{
251
+    auto mappedKeysResult = tag->mapKeys(keys, printPercentMapKeys);
252
+    if (!mappedKeysResult) {
253
+        mappedKeysResult.print();
254
+        return EX_MAP_KEYS_ERROR;
255
+    }
256
+    else {
257
+        auto mappedKeys = mappedKeysResult.getData();
258
+        for (int s = 0; s < mappedKeys.size(); ++s) {
259
+            auto sectorKey = mappedKeys[s];
260
+            cout() << "+Sector: " << s << std::endl;
261
+            for (int b = 0; b < 4; ++b) {
262
+                cout() << "+Block: " << b << std::endl;
263
+                cout() << "+Key: A" << std::endl << (!sectorKey.first.empty() ? LibNfc::Utils::StringUtils::rawToHuman(sectorKey.first) : std::string(12, '-')) << std::endl;
264
+                cout() << "+Key: B" << std::endl << (!sectorKey.second.empty() ? LibNfc::Utils::StringUtils::rawToHuman(sectorKey.second) : std::string(12, '-')) << std::endl;
265
+            }
266
+        }
267
+    }
268
+    return EX_OK;
269
+}
270
+
271
+int MainClass::read(std::shared_ptr<LibNfc::FreeFare::FreeFareTag> tag, std::vector<std::string> keys)
272
+{
273
+    auto readResult = tag->read(keys, printPercentMapKeys, printPercentDump);
274
+    if (!readResult) {
275
+        readResult.print();
276
+        return EX_READ_ERROR;
277
+    }
278
+    auto read = readResult.getData();
279
+    printSectors(read);
280
+    return EX_OK;
281
+}
282
+
283
+int MainClass::write(std::shared_ptr<LibNfc::FreeFare::FreeFareTag> tag, std::vector<std::string> keys, const std::string &data)
284
+{
285
+    auto writeResult = tag->write(keys, data, false, printPercentMapKeys, printPercentWrite);
286
+    if (!writeResult) {
287
+        writeResult.print();
288
+        return EX_WRITE_ERROR;
289
+    }
290
+//    std::vector<LibNfc::FreeFare::FreeFareSector> sectors;
291
+//    std::string d = LibNfc::Utils::StringUtils::ensureSize(data, 1024);
292
+//    for (int i = 0; i < 16; ++i) {
293
+//        LibNfc::FreeFare::FreeFareSector LibNfc::FreeFare::FreeFareSector(d.substr(i * 64, 64));
294
+//        sectors.push_back(LibNfc::FreeFare::FreeFareSector);
295
+//    }
296
+//    printSectors(sectors);
297
+    return EX_OK;
298
+}
299
+
300
+void MainClass::printSectors(const std::vector<LibNfc::FreeFare::FreeFareSector> &sectors)
301
+{
302
+    for(int s = 0; s < sectors.size(); ++s) {
303
+        cout() << "+Sector: " << s << std::endl;
304
+        auto sector = sectors[s];
305
+        for (int b = 0; b < 3; ++b) {
306
+            cout() << (sector.hasBlock(b) ? LibNfc::Utils::StringUtils::rawToHuman(sector.getBlock(b)) : std::string(32, '-')) << std::endl;
307
+        }
308
+        cout() << (sector.hasKeyA() ? LibNfc::Utils::StringUtils::rawToHuman(sector.getKeyA()) : std::string(12, '-'))
309
+        << (sector.hasAccessBits() ? LibNfc::Utils::StringUtils::rawToHuman(sector.getAccessBits()) : std::string(8, '-'))
310
+        << (sector.hasKeyB() ? LibNfc::Utils::StringUtils::rawToHuman(sector.getKeyB()) : std::string(12, '-')) << std::endl;
311
+
312
+
313
+        cout() << "+Trailer key A: " << (sector.hasKeyA() ? LibNfc::Utils::StringUtils::rawToHuman(sector.getKeyA()) : std::string(12, '-'))
314
+        << "\t AC bits: " << (sector.hasAccessBits() ? LibNfc::Utils::StringUtils::rawToHuman(sector.getAccessBits()) : std::string(8, '-'))
315
+        << "\t key B: " << (sector.hasKeyB() ? LibNfc::Utils::StringUtils::rawToHuman(sector.getKeyB()) : std::string(12, '-')) << std::endl;
316
+        LibNfc::FreeFare::FreeFareAccessBits accessBitsDbo = sector.getAccessBitsDbo();
317
+        for (int b = 0; b < 3; ++b) {
318
+            cout() << "+Block: " << b << " ";
319
+            printBlockAccessBits(accessBitsDbo, b);
320
+        }
321
+        cout() << "+Block: 3 ";
322
+        printTrailerAccessBits(accessBitsDbo);
323
+    }
324
+}
325
+
326
+void MainClass::printBlockAccessBits(const LibNfc::FreeFare::FreeFareAccessBits &accessBits, int block)
327
+{
328
+    cout() << "read: " << (accessBits.canKeyAReadBlock(block) ? "A" : " ") << (accessBits.canKeyBReadBlock(block) ? "B" : " ");
329
+    cout() << "\t write: " << (accessBits.canKeyAWriteBlock(block) ? "A" : " ") << (accessBits.canKeyBWriteBlock(block) ? "B" : " ");
330
+    cout() << "\t increment: " << (accessBits.canKeyAIncrementBlock(block) ? "A" : " ") << (accessBits.canKeyBIncrementBlock(block) ? "B" : " ");
331
+    cout() << "\t decrement: " << (accessBits.canKeyADecrementBlock(block) ? "A" : " ") << (accessBits.canKeyBDecrementBlock(block) ? "B" : " ") << std::endl;
332
+}
333
+
334
+void MainClass::printTrailerAccessBits(const LibNfc::FreeFare::FreeFareAccessBits &accessBits)
335
+{
336
+    cout() << "key A read: " << (accessBits.canKeyAReadKeyATrailer() ? "A" : " ") << (accessBits.canKeyBReadKeyATrailer() ? "B" : " ");
337
+    cout() << "\t key A write: " << (accessBits.canKeyAWriteKeyATrailer() ? "A" : " ") << (accessBits.canKeyBWriteKeyATrailer() ? "B" : " ");
338
+
339
+    cout() << "\t AC bits read: " << (accessBits.canKeyAReadAccessBitsTrailer() ? "A" : " ") << (accessBits.canKeyBReadAccessBitsTrailer() ? "B" : " ");
340
+    cout() << "\t AC bits write: " << (accessBits.canKeyAWriteAccessBitsTrailer() ? "A" : " ") << (accessBits.canKeyBWriteAccessBitsTrailer() ? "B" : " ");
341
+
342
+    cout() << "\t key B read: " << (accessBits.canKeyAReadKeyBTrailer() ? "A" : " ") << (accessBits.canKeyBReadKeyBTrailer() ? "B" : " ");
343
+    cout() << "\t key B write: " << (accessBits.canKeyAWriteKeyBTrailer() ? "A" : " ") << (accessBits.canKeyBWriteKeyBTrailer() ? "B" : " ") << std::endl;;
344
+}
345
+
346
+void MainClass::printPercent(int done, int total, const std::string& header)
347
+{
348
+    if (isatty(fileno(stdout))) {
349
+        std::cout << "\r\033[2K" << header << ": " << std::fixed << std::setprecision(1)
350
+        << ((float) done / (float) total * 100.0) << "%" << std::flush;
351
+        if (done == total) {
352
+            std::cout << std::endl;
353
+        }
354
+    }
355
+}
356
+
357
+void MainClass::printPercentMapKeys(int done, int total)
358
+{
359
+    printPercent(done, total, "Mapping keys");
360
+}
361
+
362
+void MainClass::printPercentDump(int done, int total)
363
+{
364
+    printPercent(done, total, "Dumping");
365
+}
366
+
367
+void MainClass::printPercentWrite(int done, int total)
368
+{
369
+    printPercent(done, total, "Writing");
370
+}
371
+
372
+void MainClass::printVersion()
373
+{
374
+    cout() << "LibNfc version: " << LibNfc::Core::LibNfcContext::getLibNfcVersion() << std::endl;
375
+    cout() << "Mifare-tools version: " << LibNfc::Core::LibNfcContext::getMifareToolsVersion() << std::endl;
376
+}
377
+
378
+std::shared_ptr<LibNfc::Core::NfcDevice> MainClass::getDevice(const std::string &deviceName, std::vector<std::shared_ptr<LibNfc::Core::NfcDevice>> devices)
379
+{
380
+    if (deviceName.empty()) {
381
+        if (devices.size() > 0) {
382
+            return devices[0];
383
+        }
384
+    }
385
+    else {
386
+        for (auto d : devices) {
387
+            if (d->getConnStr() == deviceName) {
388
+                return d;
389
+            }
390
+        }
391
+    }
392
+    return 0;
393
+}
394
+
395
+std::shared_ptr<LibNfc::FreeFare::FreeFareTag> MainClass::getTag(const std::string &tagUid,
396
+                                                       std::vector<std::shared_ptr<LibNfc::FreeFare::FreeFareTag>> tags)
397
+{
398
+    if (tagUid.empty()) {
399
+        if (tags.size() > 0) {
400
+            return tags[0];
401
+        }
402
+    }
403
+    else {
404
+        for (auto t : tags) {
405
+            if (t->getUid() == tagUid) {
406
+                return t;
407
+            }
408
+        }
409
+    }
410
+    return 0;
411
+}
412
+
413
+LibNfc::Utils::Result<std::vector<std::string>> MainClass::readFile(const std::string &filePath)
414
+{
415
+    std::ifstream fileInput(filePath);
416
+    if (fileInput) {
417
+        return readStream(fileInput);
418
+    }
419
+    else {
420
+        return LibNfc::Utils::Result<std::vector<std::string>>::error("Failed to open file: " + std::string(strerror(errno)));
421
+    }
422
+}
423
+
424
+LibNfc::Utils::Result<std::vector<std::string>> MainClass::readStream(std::istream &stream)
425
+{
426
+    std::vector<std::string> lines;
427
+    while (!stream.eof()) {
428
+        std::string line;
429
+        std::getline(stream, line);
430
+        line = LibNfc::Utils::StringUtils::removeSpaces(line);
431
+        if (line.compare(0, 1, "#") != 0 && line.compare(0, 1, "+") != 0) {
432
+            std::replace(line.begin(), line.end(), '-', '0');
433
+            auto keyResult = LibNfc::Utils::StringUtils::humanToRaw(line);
434
+            if (!keyResult) {
435
+                return LibNfc::Utils::Result<std::vector<std::string>>::error("Invalid data");
436
+            }
437
+            line = keyResult.getData();
438
+            lines.push_back(line);
439
+        }
440
+    }
441
+    return LibNfc::Utils::Result<std::vector<std::string>>::ok(lines);
442
+}
443
+
444
+std::ostream &MainClass::cout()
445
+{
446
+    return _outputStream == 0 ? std::cout : *_outputStream;
447
+}
448
+
449
+std::istream &MainClass::cin()
450
+{
451
+    return _inputStream == 0 ? std::cin : *_inputStream;
452
+}

+ 72
- 0
cli/cli/MainClass.h View File

@@ -0,0 +1,72 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#ifndef PDNS_SLAVE_MAINCLASS_H
6
+#define PDNS_SLAVE_MAINCLASS_H
7
+
8
+#include <memory>
9
+#include <libnfc_cpptools/FreeFareTag.h>
10
+#include <libnfc_cpptools/NfcDevice.h>
11
+
12
+class MainClass {
13
+public:
14
+    enum Actions {
15
+        Read,
16
+        Write,
17
+        Map,
18
+        Devices,
19
+        Tags
20
+    };
21
+
22
+    MainClass(int argc, char* argv[]);
23
+
24
+    int main();
25
+
26
+    std::shared_ptr<LibNfc::Core::NfcDevice> getDevice(const std::string& deviceName, std::vector<std::shared_ptr<LibNfc::Core::NfcDevice>> devices);
27
+
28
+    std::shared_ptr<LibNfc::FreeFare::FreeFareTag> getTag(const std::string& tagUid, std::vector<std::shared_ptr<LibNfc::FreeFare::FreeFareTag>> tags);
29
+
30
+    int mapKeys(std::shared_ptr<LibNfc::FreeFare::FreeFareTag> tag, std::vector<std::string> keys);
31
+
32
+    int read(std::shared_ptr<LibNfc::FreeFare::FreeFareTag> tag, std::vector<std::string> keys);
33
+
34
+    int write(std::shared_ptr<LibNfc::FreeFare::FreeFareTag> tag, std::vector<std::string> keys, const std::string& data);
35
+
36
+    LibNfc::Utils::Result<std::vector<std::string>> readFile(const std::string& filePath);
37
+
38
+    LibNfc::Utils::Result<std::vector<std::string>> readStream(std::istream& stream);
39
+
40
+    void printSectors(const std::vector<LibNfc::FreeFare::FreeFareSector>& sectors);
41
+
42
+    void printBlockAccessBits(const LibNfc::FreeFare::FreeFareAccessBits& accessBits, int block);
43
+
44
+    void printTrailerAccessBits(const LibNfc::FreeFare::FreeFareAccessBits& accessBits);
45
+
46
+    void printVersion();
47
+
48
+    std::ostream& cout();
49
+
50
+    std::istream& cin();
51
+
52
+    static void printPercent(int done, int total, const std::string& header);
53
+
54
+    static void printPercentMapKeys(int done, int total);
55
+
56
+    static void printPercentDump(int done, int total);
57
+
58
+    static void printPercentWrite(int done, int total);
59
+
60
+private:
61
+    int _argc;
62
+
63
+    char** _argv;
64
+
65
+    std::shared_ptr<std::ofstream> _outputStream;
66
+
67
+    std::shared_ptr<std::ifstream> _inputStream;
68
+
69
+};
70
+
71
+
72
+#endif //PDNS_SLAVE_MAINCLASS_H

+ 7
- 0
cli/main.cpp View File

@@ -0,0 +1,7 @@
1
+#include "cli/MainClass.h"
2
+
3
+int main(int argc, char* argv[])
4
+{
5
+    MainClass m(argc, argv);
6
+    return m.main();
7
+}

+ 31
- 0
gui/CMakeLists.txt View File

@@ -0,0 +1,31 @@
1
+include_directories(.)
2
+include_directories(. ../libnfc_cpptools)
3
+
4
+# Find includes in corresponding build directories
5
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
6
+# Instruct CMake to run moc automatically when needed.
7
+set(CMAKE_AUTOMOC ON)
8
+
9
+# Find the QtWidgets library
10
+find_package(Qt5Widgets)
11
+
12
+qt5_wrap_ui(UI_HEADERS UI/MainWindow.ui)
13
+
14
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -ggdb -g3 ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
15
+
16
+# Tell CMake to create the helloworld executable
17
+add_executable(${PROJECT_NAME}-gui
18
+        main.cpp
19
+        UI/MainWindow.cpp
20
+        UI/MainWindow.h
21
+        ${UI_HEADERS}
22
+        Core/LibNfcOperation.cpp
23
+        Core/LibNfcOperation.hxx
24
+        Core/LibNfcOperation.h
25
+        )
26
+
27
+# Use the Widgets module from Qt 5.
28
+target_link_libraries(${PROJECT_NAME}-gui Qt5::Widgets ${PROJECT_NAME})
29
+
30
+install(TARGETS ${PROJECT_NAME}-gui
31
+        RUNTIME DESTINATION bin)

+ 17
- 0
gui/Core/LibNfcOperation.cpp View File

@@ -0,0 +1,17 @@
1
+//
2
+// Created by robin on 10/1/17.
3
+//
4
+
5
+#include "LibNfcOperation.h"
6
+
7
+LibNfcOperation::LibNfcOperation(QSharedPointer<LibNfcBusiness>& libNfc,
8
+                                 std::function<void(QSharedPointer<LibNfcBusiness>)> operation)
9
+        : m_pLibNfc(libNfc)
10
+        , m_operation(operation)
11
+{
12
+}
13
+
14
+void LibNfcOperation::run()
15
+{
16
+    m_operation(m_pLibNfc);
17
+}

+ 38
- 0
gui/Core/LibNfcOperation.h View File

@@ -0,0 +1,38 @@
1
+//
2
+// Created by robin on 10/1/17.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_LIBNFCOPERATION_H
6
+#define MIFARE_TOOLS_LIBNFCOPERATION_H
7
+
8
+
9
+#include <QtCore/QThread>
10
+#include <QtCore/QSharedPointer>
11
+
12
+#include <Business/LibNfcBusiness.h>
13
+
14
+class LibNfcOperation : public QThread
15
+{
16
+    Q_OBJECT
17
+public:
18
+    template<typename T>
19
+    static void runOperation(QSharedPointer<LibNfcBusiness> libNfc,
20
+                    std::function<Result<T>(QSharedPointer<LibNfcBusiness>)> operation,
21
+                    std::function<void(Result<T>)> callback);
22
+
23
+protected:
24
+    void run() override;
25
+
26
+//signals:
27
+//    void operationFinished(Result<T> result);
28
+
29
+private:
30
+    explicit LibNfcOperation(QSharedPointer<LibNfcBusiness>& libNfc,
31
+                             std::function<void(QSharedPointer<LibNfcBusiness>)> operation);
32
+
33
+    QSharedPointer<LibNfcBusiness> m_pLibNfc;
34
+
35
+    std::function<void(QSharedPointer<LibNfcBusiness>)> m_operation;
36
+};
37
+
38
+#endif //MIFARE_TOOLS_LIBNFCOPERATION_H

+ 30
- 0
gui/Core/LibNfcOperation.hxx View File

@@ -0,0 +1,30 @@
1
+//
2
+// Created by robin on 10/1/17.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_LIBNFCOPERATION_HXX
6
+#define MIFARE_TOOLS_LIBNFCOPERATION_HXX
7
+
8
+#include "LibNfcOperation.h"
9
+
10
+template<typename T>
11
+void LibNfcOperation::runOperation(QSharedPointer<LibNfcBusiness> libNfc,
12
+                          std::function<Result<T>(QSharedPointer<LibNfcBusiness>)> operation,
13
+                          std::function<void(Result<T>)> callback)
14
+{
15
+    Result<T>* result = new Result<T>();
16
+    auto nfcOperation = new LibNfcOperation(libNfc, [result, operation](QSharedPointer<LibNfcBusiness> libNfc)
17
+    {
18
+        auto res = operation(libNfc);
19
+        *result = res;
20
+    });
21
+    connect(nfcOperation, &LibNfcOperation::finished, [result, nfcOperation, callback]()
22
+    {
23
+        nfcOperation->deleteLater();
24
+        callback(*result);
25
+        delete result;
26
+    });
27
+    nfcOperation->start();
28
+}
29
+
30
+#endif //MIFARE_TOOLS_LIBNFCOPERATION_HXX

+ 66
- 0
gui/UI/MainWindow.cpp View File

@@ -0,0 +1,66 @@
1
+//
2
+// Created by robin on 10/1/17.
3
+//
4
+
5
+#include "MainWindow.h"
6
+#include <QMessageBox>
7
+#include <Core/LibNfcOperation.hxx>
8
+
9
+MainWindow::MainWindow(QWidget *parent)
10
+        : QMainWindow(parent)
11
+        , m_pUi(new Ui_MainWindow())
12
+{
13
+    m_pUi->setupUi(this);
14
+
15
+    refreshReaders();
16
+}
17
+
18
+bool MainWindow::initLibNfc()
19
+{
20
+    if (!m_pLibNfc) {
21
+        m_pLibNfc.reset(new LibNfcBusiness());
22
+        auto initResult = m_pLibNfc->init();
23
+        if (!initResult) {
24
+            showError(initResult);
25
+            return false;
26
+        }
27
+    }
28
+    return true;
29
+}
30
+
31
+void MainWindow::refreshReaders()
32
+{
33
+    if (!initLibNfc()) {
34
+        return;
35
+    }
36
+    m_pUi->pComboReaders->clear();
37
+
38
+    LibNfcOperation::runOperation<std::vector<std::shared_ptr<NfcDeviceBusiness>>>(m_pLibNfc, [](QSharedPointer<LibNfcBusiness> libNfc)
39
+                         {
40
+                             return (Result<std::vector<std::shared_ptr<NfcDeviceBusiness>>>) libNfc->getDevices();
41
+                         }, [this](Result<std::vector<std::shared_ptr<NfcDeviceBusiness>>> devicesResult)
42
+    {
43
+        m_devices = devicesResult.getData();
44
+        for (auto& device : m_devices) {
45
+            m_pUi->pComboReaders->addItem(device->getConnStr().c_str());
46
+        }
47
+    });
48
+
49
+//    auto devicesResult = m_pLibNfc->getDevices();
50
+//    if (!devicesResult) {
51
+//        showError(devicesResult);
52
+//        return;
53
+//    }
54
+//
55
+//    m_devices = devicesResult.getData();
56
+//    for (auto& device : m_devices) {
57
+//        m_pUi->pComboReaders->addItem(device->getConnStr().c_str());
58
+//    }
59
+}
60
+
61
+template<typename T>
62
+void MainWindow::showError(Result<T> result)
63
+{
64
+    result.print();
65
+    QMessageBox::critical(this, "LibNfc Error", QString("LibNfc error: %1").arg(result.getError().c_str()));
66
+}

+ 36
- 0
gui/UI/MainWindow.h View File

@@ -0,0 +1,36 @@
1
+//
2
+// Created by robin on 10/1/17.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_MAINWINDOW_H
6
+#define MIFARE_TOOLS_MAINWINDOW_H
7
+
8
+
9
+#include <QtWidgets/QMainWindow>
10
+#include <Business/LibNfcBusiness.h>
11
+
12
+#include "ui_MainWindow.h"
13
+
14
+class MainWindow : public QMainWindow
15
+{
16
+Q_OBJECT
17
+public:
18
+    explicit MainWindow(QWidget* parent = nullptr);
19
+    ~MainWindow() override = default;
20
+
21
+    bool initLibNfc();
22
+
23
+    void refreshReaders();
24
+
25
+    template<typename T> void showError(Result<T> result);
26
+
27
+private:
28
+    QScopedPointer<Ui_MainWindow> m_pUi;
29
+
30
+    QSharedPointer<LibNfcBusiness> m_pLibNfc;
31
+
32
+    std::vector<std::shared_ptr<NfcDeviceBusiness>> m_devices;
33
+};
34
+
35
+
36
+#endif //MIFARE_TOOLS_MAINWINDOW_H

+ 122
- 0
gui/UI/MainWindow.ui View File

@@ -0,0 +1,122 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<ui version="4.0">
3
+ <class>MainWindow</class>
4
+ <widget class="QMainWindow" name="MainWindow">
5
+  <property name="geometry">
6
+   <rect>
7
+    <x>0</x>
8
+    <y>0</y>
9
+    <width>800</width>
10
+    <height>600</height>
11
+   </rect>
12
+  </property>
13
+  <property name="windowTitle">
14
+   <string>MainWindow</string>
15
+  </property>
16
+  <widget class="QWidget" name="centralwidget">
17
+   <layout class="QVBoxLayout" name="verticalLayout">
18
+    <item>
19
+     <widget class="QWidget" name="widget" native="true">
20
+      <layout class="QHBoxLayout" name="horizontalLayout">
21
+       <item>
22
+        <widget class="QLabel" name="pLblReaders">
23
+         <property name="sizePolicy">
24
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
25
+           <horstretch>0</horstretch>
26
+           <verstretch>0</verstretch>
27
+          </sizepolicy>
28
+         </property>
29
+         <property name="text">
30
+          <string>Reader:</string>
31
+         </property>
32
+        </widget>
33
+       </item>
34
+       <item>
35
+        <widget class="QComboBox" name="pComboReaders">
36
+         <property name="sizePolicy">
37
+          <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
38
+           <horstretch>0</horstretch>
39
+           <verstretch>0</verstretch>
40
+          </sizepolicy>
41
+         </property>
42
+        </widget>
43
+       </item>
44
+       <item>
45
+        <widget class="QPushButton" name="pBtnReadersRefresh">
46
+         <property name="text">
47
+          <string>Refresh</string>
48
+         </property>
49
+        </widget>
50
+       </item>
51
+       <item>
52
+        <widget class="QPushButton" name="pBtnReadersConnect">
53
+         <property name="text">
54
+          <string>Connect</string>
55
+         </property>
56
+        </widget>
57
+       </item>
58
+       <item>
59
+        <spacer name="horizontalSpacer">
60
+         <property name="orientation">
61
+          <enum>Qt::Horizontal</enum>
62
+         </property>
63
+         <property name="sizeHint" stdset="0">
64
+          <size>
65
+           <width>40</width>
66
+           <height>20</height>
67
+          </size>
68
+         </property>
69
+        </spacer>
70
+       </item>
71
+      </layout>
72
+     </widget>
73
+    </item>
74
+    <item>
75
+     <widget class="QTabWidget" name="tabWidget">
76
+      <property name="currentIndex">
77
+       <number>0</number>
78
+      </property>
79
+      <widget class="QWidget" name="tab">
80
+       <attribute name="title">
81
+        <string>Visual</string>
82
+       </attribute>
83
+      </widget>
84
+      <widget class="QWidget" name="tab_2">
85
+       <attribute name="title">
86
+        <string>Raw</string>
87
+       </attribute>
88
+      </widget>
89
+     </widget>
90
+    </item>
91
+   </layout>
92
+  </widget>
93
+  <widget class="QMenuBar" name="menubar">
94
+   <property name="geometry">
95
+    <rect>
96
+     <x>0</x>
97
+     <y>0</y>
98
+     <width>800</width>
99
+     <height>24</height>
100
+    </rect>
101
+   </property>
102
+   <widget class="QMenu" name="menuFile">
103
+    <property name="title">
104
+     <string>File</string>
105
+    </property>
106
+    <addaction name="actionOpen"/>
107
+   </widget>
108
+   <addaction name="menuFile"/>
109
+  </widget>
110
+  <widget class="QStatusBar" name="statusbar"/>
111
+  <action name="actionOpen">
112
+   <property name="text">
113
+    <string>Open</string>
114
+   </property>
115
+   <property name="shortcut">
116
+    <string>Ctrl+O</string>
117
+   </property>
118
+  </action>
119
+ </widget>
120
+ <resources/>
121
+ <connections/>
122
+</ui>

+ 17
- 0
gui/main.cpp View File

@@ -0,0 +1,17 @@
1
+//
2
+// Created by robin on 10/1/17.
3
+//
4
+
5
+#include <QApplication>
6
+#include <UI/MainWindow.h>
7
+
8
+int main(int argc, char* argv[])
9
+{
10
+    QApplication app(argc, argv);
11
+
12
+    MainWindow mainWindow;
13
+
14
+    mainWindow.show();
15
+
16
+    return app.exec();
17
+}

+ 45
- 0
libnfc_cpptools/CMakeLists.txt View File

@@ -0,0 +1,45 @@
1
+include_directories(
2
+        src/freefare
3
+        src/libnfc
4
+        src/utils
5
+        inc
6
+)
7
+
8
+set(SOURCE_FILES
9
+        inc/libnfc_cpptools/Result.h
10
+        src/libnfc/LibNfcInternal.cpp
11
+        src/libnfc/LibNfcInternal.h
12
+        src/libnfc/NfcDeviceInternal.cpp
13
+        src/libnfc/NfcDeviceInternal.h
14
+        src/freefare/FreeFareDeviceInternal.cpp
15
+        src/freefare/FreeFareDeviceInternal.h
16
+        src/freefare/FreeFareTagInternal.cpp
17
+        src/freefare/FreeFareTagInternal.h
18
+        src/utils/StringUtils.cpp
19
+        inc/libnfc_cpptools/StringUtils.h
20
+        src/freefare/FreeFareAccessBits.cpp
21
+        inc/libnfc_cpptools/FreeFareAccessBits.h
22
+        src/libnfc/LibNfc.cpp
23
+        inc/libnfc_cpptools/LibNfc.h
24
+        src/libnfc/NfcDevice.cpp
25
+        inc/libnfc_cpptools/NfcDevice.h
26
+        src/freefare/FreeFareDevice.cpp
27
+        inc/libnfc_cpptools/FreeFareDevice.h
28
+        src/freefare/FreeFareTag.cpp
29
+        inc/libnfc_cpptools/FreeFareTag.h
30
+        src/freefare/FreeFareSector.cpp
31
+        inc/libnfc_cpptools/FreeFareSector.h
32
+        src/utils/ArrayUtils.cpp
33
+        inc/libnfc_cpptools/ArrayUtils.h
34
+        )
35
+
36
+add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
37
+target_link_libraries(${PROJECT_NAME}
38
+        nfc
39
+        freefare
40
+        )
41
+
42
+install(TARGETS ${PROJECT_NAME}
43
+        LIBRARY DESTINATION lib)
44
+
45
+set(LIBNFC_CPPTOOLS_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/inc PARENT_SCOPE)

+ 27
- 0
libnfc_cpptools/inc/libnfc_cpptools/ArrayUtils.h View File

@@ -0,0 +1,27 @@
1
+//
2
+// Created by robin on 7/23/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_ARRAYUTILS_H
6
+#define MIFARE_TOOLS_ARRAYUTILS_H
7
+
8
+
9
+namespace LibNfc
10
+{
11
+namespace Utils
12
+{
13
+
14
+class ArrayUtils
15
+{
16
+public:
17
+    static void setArrayBit(char *buf, const char &bitPosition, const bool &value);
18
+    static void setArrayBit(unsigned char *buf, const char &bitPosition, const bool &value);
19
+    static bool getArrayBit(const char *buf, const char &bitPosition);
20
+    static bool getArrayBit(const unsigned char *buf, const char &bitPosition);
21
+
22
+};
23
+
24
+}; // Utils
25
+}; // LibNfc
26
+
27
+#endif //MIFARE_TOOLS_ARRAYUTILS_H

+ 70
- 0
libnfc_cpptools/inc/libnfc_cpptools/FreeFareAccessBits.h View File

@@ -0,0 +1,70 @@
1
+//
2
+// Created by robin on 7/21/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_ACCESSBITSDBO_H
6
+#define MIFARE_TOOLS_ACCESSBITSDBO_H
7
+
8
+
9
+#include <string>
10
+
11
+namespace LibNfc
12
+{
13
+namespace FreeFare
14
+{
15
+
16
+class FreeFareAccessBits
17
+{
18
+public:
19
+
20
+    static const char nonInvertedBitPosition[4][4];
21
+    static const char invertedBitPosition[4][4];
22
+
23
+    FreeFareAccessBits();
24
+    FreeFareAccessBits(const std::string& bits);
25
+
26
+    char getUserData() const;
27
+    void setUserData(const char& data);
28
+
29
+    void setBit(int i, int j, const bool& value);
30
+    bool getBit(int i, int j) const;
31
+    std::string getBits() const;
32
+
33
+    bool canKeyAReadBlock(int block) const;
34
+    bool canKeyBReadBlock(int block) const;
35
+
36
+    bool canKeyAWriteBlock(int block) const;
37
+    bool canKeyBWriteBlock(int block) const;
38
+
39
+    bool canKeyAIncrementBlock(int block) const;
40
+    bool canKeyBIncrementBlock(int block) const;
41
+
42
+    bool canKeyADecrementBlock(int block) const;
43
+    bool canKeyBDecrementBlock(int block) const;
44
+
45
+    bool canKeyAReadKeyATrailer() const;
46
+    bool canKeyBReadKeyATrailer() const;
47
+
48
+    bool canKeyAWriteKeyATrailer() const;
49
+    bool canKeyBWriteKeyATrailer() const;
50
+
51
+    bool canKeyAReadAccessBitsTrailer() const;
52
+    bool canKeyBReadAccessBitsTrailer() const;
53
+
54
+    bool canKeyAWriteAccessBitsTrailer() const;
55
+    bool canKeyBWriteAccessBitsTrailer() const;
56
+
57
+    bool canKeyAReadKeyBTrailer() const;
58
+    bool canKeyBReadKeyBTrailer() const;
59
+
60
+    bool canKeyAWriteKeyBTrailer() const;
61
+    bool canKeyBWriteKeyBTrailer() const;
62
+
63
+private:
64
+    std::string _bits;
65
+};
66
+
67
+}; // FreeFare
68
+}; // LibNfc
69
+
70
+#endif //MIFARE_TOOLS_ACCESSBITSDBO_H

+ 34
- 0
libnfc_cpptools/inc/libnfc_cpptools/FreeFareDevice.h View File

@@ -0,0 +1,34 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_FREEFAREDEVICEBUSINESS_H
6
+#define MIFARE_TOOLS_FREEFAREDEVICEBUSINESS_H
7
+
8
+#include "NfcDevice.h"
9
+#include "FreeFareTag.h"
10
+
11
+namespace LibNfc
12
+{
13
+namespace FreeFare
14
+{
15
+
16
+class FreeFareDeviceInternal;
17
+
18
+class FreeFareDevice
19
+{
20
+public:
21
+    FreeFareDevice(std::shared_ptr<LibNfc::Core::NfcDevice> device);
22
+
23
+    LibNfc::Utils::Result<std::vector<std::shared_ptr<FreeFareTag>>> getTags() const;
24
+
25
+protected:
26
+    std::shared_ptr<LibNfc::Core::NfcDevice> _device;
27
+
28
+    std::shared_ptr<FreeFareDeviceInternal> _freeFareDevice;
29
+};
30
+
31
+}; // FreeFare
32
+}; // LibNfc
33
+
34
+#endif //MIFARE_TOOLS_FREEFAREDEVICEBUSINESS_H

+ 66
- 0
libnfc_cpptools/inc/libnfc_cpptools/FreeFareSector.h View File

@@ -0,0 +1,66 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_SECTORDBO_H
6
+#define MIFARE_TOOLS_SECTORDBO_H
7
+
8
+
9
+#include <string>
10
+#include <libnfc_cpptools/Result.h>
11
+#include <libnfc_cpptools/FreeFareAccessBits.h>
12
+
13
+namespace LibNfc
14
+{
15
+namespace FreeFare
16
+{
17
+
18
+class FreeFareSector
19
+{
20
+public:
21
+    FreeFareSector(const std::string& data = "");
22
+
23
+    const std::string& getBlock(int block) const;
24
+
25
+    std::string getKeyA() const;
26
+
27
+    std::string getKeyB() const;
28
+
29
+    std::string getAccessBits() const;
30
+
31
+    FreeFareAccessBits getAccessBitsDbo() const;
32
+
33
+    void setBlock(int block, const std::string& data);
34
+
35
+    void setKeyA(const std::string& key);
36
+
37
+    void setKeyB(const std::string& key);
38
+
39
+    void setAccessBits(const std::string& accessBits);
40
+
41
+    void setAccessBits(const FreeFareAccessBits& accessBits);
42
+
43
+    bool hasBlock(int block) const;
44
+
45
+    bool hasKeyA() const;
46
+
47
+    bool hasKeyB() const;
48
+
49
+    bool hasAccessBits() const;
50
+
51
+protected:
52
+    std::string _blocks[4];
53
+
54
+    bool _haveBlocks[4];
55
+
56
+    bool _hasKeyA;
57
+
58
+    bool _hasKeyB;
59
+
60
+    bool _hasAccessBits;
61
+};
62
+
63
+}; // FreeFare
64
+}; // LibNfc
65
+
66
+#endif //MIFARE_TOOLS_SECTORDBO_H

+ 74
- 0
libnfc_cpptools/inc/libnfc_cpptools/FreeFareTag.h View File

@@ -0,0 +1,74 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_FREEFARETAGBUSINESS_H
6
+#define MIFARE_TOOLS_FREEFARETAGBUSINESS_H
7
+
8
+
9
+#include <boost/shared_ptr.hpp>
10
+#include <libnfc_cpptools/FreeFareSector.h>
11
+
12
+namespace LibNfc
13
+{
14
+namespace FreeFare
15
+{
16
+
17
+class FreeFareTagInternal;
18
+
19
+typedef std::vector<std::pair<std::string, std::string>> MappedKeys;
20
+
21
+class FreeFareTag
22
+{
23
+public:
24
+    enum FreeFareTagType {
25
+        UNKNOWN,
26
+        FELICA,
27
+        MIFARE_MINI,
28
+        MIFARE_CLASSIC_1K,
29
+        MIFARE_CLASSIC_4K,
30
+        MIFARE_DESFIRE,
31
+        MIFARE_ULTRALIGHT,
32
+        MIFARE_ULTRALIGHT_C
33
+    };
34
+
35
+    static std::string getTagTypeString(FreeFareTagType type);
36
+
37
+    FreeFareTag(std::shared_ptr<FreeFareTagInternal> tag);
38
+
39
+    LibNfc::Utils::ResultBool authenticate(int sector, std::string key, int keyType);
40
+
41
+    LibNfc::Utils::Result<MappedKeys> mapKeys(std::vector<std::string> keys, std::function<void(int, int)> cb = 0);
42
+
43
+    LibNfc::Utils::ResultString readBlock(int sector, int block, std::string key, int keyType);
44
+
45
+    LibNfc::Utils::Result<FreeFareSector> readSector(int sector, std::string key, int keyType);
46
+
47
+    LibNfc::Utils::Result<std::vector<FreeFareSector>> read(MappedKeys keys, std::function<void(int, int)> cb = 0);
48
+
49
+    LibNfc::Utils::Result<std::vector<FreeFareSector>> read(std::vector<std::string> keys, std::function<void(int, int)> mapCb = 0,
50
+                                        std::function<void(int, int)> readCb = 0);
51
+
52
+    LibNfc::Utils::ResultBool writeBlock(int sector, int block, std::string key, int keyType, const std::string& data);
53
+
54
+    LibNfc::Utils::ResultBool writeSector(int sector, std::string key, int keyType, const std::string& data);
55
+
56
+    LibNfc::Utils::ResultBool write(MappedKeys keys, const std::string& data, bool writeSector0, std::function<void(int, int)> cb = 0);
57
+
58
+    LibNfc::Utils::ResultBool write(std::vector<std::string> keys, const std::string& data, bool writeSector0,
59
+                     std::function<void(int, int)> mapCb = 0, std::function<void(int, int)> writeCb = 0);
60
+
61
+    const std::string& getUid() const;
62
+
63
+    FreeFareTagType getType() const;
64
+
65
+    std::shared_ptr<FreeFareTagInternal> getTag() const;
66
+
67
+protected:
68
+    std::shared_ptr<FreeFareTagInternal> _tag;
69
+};
70
+
71
+}; // FreeFare
72
+}; // LibNfc
73
+
74
+#endif //MIFARE_TOOLS_FREEFARETAGBUSINESS_H

+ 44
- 0
libnfc_cpptools/inc/libnfc_cpptools/LibNfc.h View File

@@ -0,0 +1,44 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_LIBNFCBUSINESS_H
6
+#define MIFARE_TOOLS_LIBNFCBUSINESS_H
7
+
8
+
9
+#include <libnfc_cpptools/Result.h>
10
+#include <libnfc_cpptools/NfcDevice.h>
11
+
12
+namespace LibNfc
13
+{
14
+namespace Core
15
+{
16
+
17
+class LibNfcInternal;
18
+
19
+class LibNfcContext
20
+{
21
+public:
22
+    LibNfcContext();
23
+    virtual ~LibNfcContext();
24
+
25
+    LibNfc::Utils::ResultBool init();
26
+
27
+    void clean();
28
+
29
+    bool isInitialized() const;
30
+
31
+    LibNfc::Utils::Result<std::vector<std::shared_ptr<NfcDevice>>> getDevices() const;
32
+
33
+    static std::string getLibNfcVersion();
34
+
35
+    static std::string getMifareToolsVersion();
36
+
37
+protected:
38
+    std::shared_ptr<LibNfcInternal> _libNfc;
39
+};
40
+
41
+}; // Core
42
+}; // LibNfc
43
+
44
+#endif //MIFARE_TOOLS_LIBNFCBUSINESS_H

+ 42
- 0
libnfc_cpptools/inc/libnfc_cpptools/NfcDevice.h View File

@@ -0,0 +1,42 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_NFCDEVICEBUSINESS_H
6
+#define MIFARE_TOOLS_NFCDEVICEBUSINESS_H
7
+
8
+#include <string>
9
+#include <memory>
10
+
11
+#include <libnfc_cpptools/Result.h>
12
+
13
+namespace LibNfc
14
+{
15
+namespace Core
16
+{
17
+
18
+class NfcDeviceInternal;
19
+
20
+class NfcDevice
21
+{
22
+public:
23
+    NfcDevice(std::shared_ptr<NfcDeviceInternal> device);
24
+
25
+    LibNfc::Utils::ResultBool open();
26
+
27
+    void close();
28
+
29
+    bool isOpened() const;
30
+
31
+    const std::string & getConnStr() const;
32
+
33
+    std::shared_ptr<NfcDeviceInternal> getDevice() const;
34
+
35
+protected:
36
+    std::shared_ptr<NfcDeviceInternal> _device;
37
+};
38
+
39
+}; // Core
40
+}; // LibNfc
41
+
42
+#endif //MIFARE_TOOLS_NFCDEVICEBUSINESS_H

+ 158
- 0
libnfc_cpptools/inc/libnfc_cpptools/Result.h View File

@@ -0,0 +1,158 @@
1
+//
2
+// Created by robin on 8/9/15.
3
+//
4
+
5
+#ifndef RESULT_H
6
+#define RESULT_H
7
+
8
+#include <string>
9
+#include <vector>
10
+#include <iostream>
11
+#include <errno.h>
12
+#include <string.h>
13
+
14
+namespace LibNfc
15
+{
16
+namespace Utils
17
+{
18
+
19
+template <class T> class Result
20
+{
21
+public:
22
+    static const Result<T> ok(const T& data);
23
+    static const Result<T> strerror();
24
+    static const Result<T> error(const std::string& error);
25
+    template <class U> static const Result<T> error(const Result<U>& other);
26
+
27
+    T& getData();
28
+    const bool isSuccess() const;
29
+    const std::string& getError() const;
30
+
31
+    bool operator !() const;
32
+    operator bool() const;
33
+
34
+    template<class U>
35
+    friend std::ostream& operator<<(std::ostream& os, const Result<U>& res);
36
+
37
+    const Result<T>& print() const;
38
+
39
+private:
40
+    Result();
41
+
42
+    T _data;
43
+
44
+    std::string _error;
45
+
46
+    bool _success;
47
+};
48
+
49
+typedef Result<bool> ResultBool;
50
+
51
+typedef Result<int> ResultInt;
52
+
53
+typedef Result<long> ResultLong;
54
+
55
+typedef Result<float> ResultFloat;
56
+
57
+typedef Result<double> ResultDouble;
58
+
59
+typedef Result<char> ResultChar;
60
+
61
+typedef Result<std::string> ResultString;
62
+
63
+
64
+template<class T>
65
+Result<T>::Result()
66
+{
67
+}
68
+
69
+template<class T>
70
+const Result<T> Result<T>::ok(const T& data)
71
+{
72
+    Result<T> r;
73
+    r._success = true;
74
+    r._data = data;
75
+    return r;
76
+}
77
+
78
+template<class T>
79
+const Result<T> Result<T>::strerror()
80
+{
81
+    Result<T> r;
82
+    r._success = false;
83
+    r._error = ::strerror(errno);
84
+    return r;
85
+}
86
+
87
+template<class T>
88
+const Result<T> Result<T>::error(const std::string& error)
89
+{
90
+    Result<T> r;
91
+    r._success = false;
92
+    r._error = error;
93
+    return r;
94
+}
95
+
96
+template<class T>
97
+template<class U>
98
+const Result<T> Result<T>::error(const Result<U>& other)
99
+{
100
+    Result<T> r;
101
+    r._success = false;
102
+    r.error(other.getError());
103
+    return r;
104
+}
105
+
106
+template<class T>
107
+T &Result<T>::getData()
108
+{
109
+    return _data;
110
+}
111
+
112
+template<class T>
113
+const bool Result<T>::isSuccess() const
114
+{
115
+    return _success;
116
+}
117
+
118
+template<class T>
119
+bool Result<T>::operator!() const
120
+{
121
+    return !isSuccess();
122
+}
123
+
124
+template<class T>
125
+Result<T>::operator bool() const
126
+{
127
+    return isSuccess();
128
+}
129
+
130
+template<class T>
131
+const std::string &Result<T>::getError() const
132
+{
133
+    return _error;
134
+}
135
+
136
+template<class U>
137
+std::ostream& operator<<(std::ostream& os, const Result<U>& res)
138
+{
139
+    if (res._success) {
140
+        os << "Success";// << res._data;
141
+    }
142
+    else {
143
+        os << "Error: " << (res._error.empty() ? "Unknown error" : res._error);
144
+    }
145
+    return os;
146
+}
147
+
148
+template<class T>
149
+const Result<T>& Result<T>::print() const
150
+{
151
+    (_success ? std::cout : std::cerr) << *this << std::endl;
152
+    return *this;
153
+}
154
+
155
+}; // Utils
156
+}; // LibNfc
157
+
158
+#endif //RESULT_H

+ 51
- 0
libnfc_cpptools/inc/libnfc_cpptools/StringUtils.h View File

@@ -0,0 +1,51 @@
1
+//
2
+// Created by robin on 6/20/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_HEX_H
6
+#define MIFARE_TOOLS_HEX_H
7
+
8
+
9
+#include <string>
10
+#include <libnfc_cpptools/Result.h>
11
+
12
+namespace LibNfc
13
+{
14
+namespace Utils
15
+{
16
+
17
+class StringUtils
18
+{
19
+public:
20
+    static const std::string hex;
21
+
22
+    static std::string rawToHuman(uint8_t c);
23
+    static std::string rawToHuman(int8_t c);
24
+    static std::string rawToHuman(uint16_t c);
25
+    static std::string rawToHuman(int16_t c);
26
+    static std::string rawToHuman(uint32_t c);
27
+    static std::string rawToHuman(int32_t c);
28
+    static std::string rawToHuman(uint64_t c);
29
+    static std::string rawToHuman(int64_t c);
30
+    static std::string rawToHuman(const std::string& raw);
31
+
32
+    static ResultString humanToRaw(const std::string& human);
33
+
34
+    static std::string toLower(const std::string& str);
35
+    static char toLower(char c);
36
+
37
+    static std::string toUpper(const std::string& str);
38
+    static char toUpper(char c);
39
+
40
+    static std::string ensureSize(const std::string& data, int size);
41
+
42
+    static std::string ltrim(const std::string& s);
43
+    static std::string rtrim(const std::string& s);
44
+    static std::string trim(const std::string& s);
45
+    static std::string removeSpaces(const std::string& s);
46
+};
47
+
48
+}; // Utils
49
+}; // LibNfc
50
+
51
+#endif //MIFARE_TOOLS_HEX_H

+ 219
- 0
libnfc_cpptools/src/freefare/FreeFareAccessBits.cpp View File

@@ -0,0 +1,219 @@
1
+//
2
+// Created by robin on 7/21/16.
3
+//
4
+
5
+#include <cstring>
6
+#include <iostream>
7
+#include "libnfc_cpptools/FreeFareAccessBits.h"
8
+#include "libnfc_cpptools/StringUtils.h"
9
+#include "libnfc_cpptools/ArrayUtils.h"
10
+
11
+namespace LibNfc
12
+{
13
+namespace FreeFare
14
+{
15
+
16
+const char FreeFareAccessBits::nonInvertedBitPosition[4][4] = {
17
+        {0,  0,  0,  0 },
18
+        {11, 10, 9,  8 },
19
+        {23, 22, 21, 20},
20
+        {19, 18, 17, 16}};
21
+
22
+const char FreeFareAccessBits::invertedBitPosition[4][4] = {
23
+        {0,  0,  0,  0 },
24
+        {7,  6,  5,  4 },
25
+        {3,  2,  1,  0},
26
+        {15, 14, 13, 12}};
27
+
28
+FreeFareAccessBits::FreeFareAccessBits()
29
+    : _bits("\xff\x0f\00\x00", 4)
30
+{
31
+}
32
+
33
+FreeFareAccessBits::FreeFareAccessBits(const std::string &bits)
34
+    : _bits(LibNfc::Utils::StringUtils::ensureSize(bits, 4))
35
+{
36
+}
37
+
38
+char FreeFareAccessBits::getUserData() const
39
+{
40
+    return _bits[_bits.length() - 1];
41
+}
42
+
43
+void FreeFareAccessBits::setUserData(const char &data)
44
+{
45
+    _bits[_bits.length() - 1] = data;
46
+}
47
+
48
+void FreeFareAccessBits::setBit(int i, int j, const bool& value)
49
+{
50
+    char buf[_bits.length()];
51
+    memcpy(buf, _bits.c_str(), _bits.length());
52
+
53
+    LibNfc::Utils::ArrayUtils::setArrayBit(buf, nonInvertedBitPosition[i][j], value);
54
+    LibNfc::Utils::ArrayUtils::setArrayBit(buf, invertedBitPosition[i][j], !value);
55
+
56
+    _bits = std::string(buf, _bits.length());
57
+}
58
+
59
+bool FreeFareAccessBits::getBit(int i, int j) const
60
+{
61
+    const char* buf = _bits.c_str();
62
+    return LibNfc::Utils::ArrayUtils::getArrayBit(buf, nonInvertedBitPosition[i][j]) && !LibNfc::Utils::ArrayUtils::getArrayBit(buf, invertedBitPosition[i][j]);
63
+}
64
+
65
+std::string FreeFareAccessBits::getBits() const
66
+{
67
+    return _bits;
68
+}
69
+
70
+bool FreeFareAccessBits::canKeyAReadBlock(int block) const
71
+{
72
+    bool c1 = getBit(1, block);
73
+    bool c2 = getBit(2, block);
74
+    bool c3 = getBit(3, block);
75
+    return !c3 || (!c1 && !c2 && c3);
76
+}
77
+
78
+bool FreeFareAccessBits::canKeyBReadBlock(int block) const
79
+{
80
+    bool c1 = getBit(1, block);
81
+    bool c2 = getBit(2, block);
82
+    bool c3 = getBit(3, block);
83
+    return !c1 || !c2 || !c3;
84
+}
85
+
86
+bool FreeFareAccessBits::canKeyAWriteBlock(int block) const
87
+{
88
+    bool c1 = getBit(1, block);
89
+    bool c2 = getBit(2, block);
90
+    bool c3 = getBit(3, block);
91
+    return !c1 && !c2 && !c3;
92
+}
93
+
94
+bool FreeFareAccessBits::canKeyBWriteBlock(int block) const
95
+{
96
+    bool c1 = getBit(1, block);
97
+    bool c2 = getBit(2, block);
98
+    bool c3 = getBit(3, block);
99
+    return (!c2 && !c3) || (c1 && !c3) || (!c1 && c2 && c3);
100
+}
101
+
102
+bool FreeFareAccessBits::canKeyAIncrementBlock(int block) const
103
+{
104
+    bool c1 = getBit(1, block);
105
+    bool c2 = getBit(2, block);
106
+    bool c3 = getBit(3, block);
107
+    return !c1 && !c2 && !c3;
108
+}
109
+
110
+bool FreeFareAccessBits::canKeyBIncrementBlock(int block) const
111
+{
112
+    bool c1 = getBit(1, block);
113
+    bool c2 = getBit(2, block);
114
+    bool c3 = getBit(3, block);
115
+    return (!c1 && !c2 && !c3) || (c1 && c2 && !c3);
116
+}
117
+
118
+bool FreeFareAccessBits::canKeyADecrementBlock(int block) const
119
+{
120
+    bool c1 = getBit(1, block);
121
+    bool c2 = getBit(2, block);
122
+    bool c3 = getBit(3, block);
123
+    return (!c1 && !c2) || (c1 && c2 && !c3);
124
+}
125
+
126
+bool FreeFareAccessBits::canKeyBDecrementBlock(int block) const
127
+{
128
+    bool c1 = getBit(1, block);
129
+    bool c2 = getBit(2, block);
130
+    bool c3 = getBit(3, block);
131
+    return (!c1 && !c2) || (c1 && c2 && !c3);
132
+}
133
+
134
+bool FreeFareAccessBits::canKeyAReadKeyATrailer() const
135
+{
136
+    return false;
137
+}
138
+
139
+bool FreeFareAccessBits::canKeyBReadKeyATrailer() const
140
+{
141
+    return false;
142
+}
143
+
144
+bool FreeFareAccessBits::canKeyAWriteKeyATrailer() const
145
+{
146
+    bool c1 = getBit(1, 3);
147
+    bool c2 = getBit(2, 3);
148
+    bool c3 = getBit(3, 3);
149
+    return !c1 && !c2;
150
+}
151
+
152
+bool FreeFareAccessBits::canKeyBWriteKeyATrailer() const
153
+{
154
+    bool c1 = getBit(1, 3);
155
+    bool c2 = getBit(2, 3);
156
+    bool c3 = getBit(3, 3);
157
+    return (!c1 && c2 && c3) || (c1 && !c2 && !c3);
158
+}
159
+
160
+bool FreeFareAccessBits::canKeyAReadAccessBitsTrailer() const
161
+{
162
+    return true;
163
+}
164
+
165
+bool FreeFareAccessBits::canKeyBReadAccessBitsTrailer() const
166
+{
167
+    bool c1 = getBit(1, 3);
168
+    bool c2 = getBit(2, 3);
169
+    bool c3 = getBit(3, 3);
170
+    return c1 || (c2 && c3);
171
+}
172
+
173
+bool FreeFareAccessBits::canKeyAWriteAccessBitsTrailer() const
174
+{
175
+    bool c1 = getBit(1, 3);
176
+    bool c2 = getBit(2, 3);
177
+    bool c3 = getBit(3, 3);
178
+    return !c1 && !c2 && c3;
179
+}
180
+
181
+bool FreeFareAccessBits::canKeyBWriteAccessBitsTrailer() const
182
+{
183
+    bool c1 = getBit(1, 3);
184
+    bool c2 = getBit(2, 3);
185
+    bool c3 = getBit(3, 3);
186
+    return (!c1 && c2 && c3) || (c1 && !c2 && c3);
187
+}
188
+
189
+bool FreeFareAccessBits::canKeyAReadKeyBTrailer() const
190
+{
191
+    bool c1 = getBit(1, 3);
192
+    bool c2 = getBit(2, 3);
193
+    bool c3 = getBit(3, 3);
194
+    return (!c1 && !c2) || (!c1 && !c3);
195
+}
196
+
197
+bool FreeFareAccessBits::canKeyBReadKeyBTrailer() const
198
+{
199
+    return false;
200
+}
201
+
202
+bool FreeFareAccessBits::canKeyAWriteKeyBTrailer() const
203
+{
204
+    bool c1 = getBit(1, 3);
205
+    bool c2 = getBit(2, 3);
206
+    bool c3 = getBit(3, 3);
207
+    return !c1 && !c2;
208
+}
209
+
210
+bool FreeFareAccessBits::canKeyBWriteKeyBTrailer() const
211
+{
212
+    bool c1 = getBit(1, 3);
213
+    bool c2 = getBit(2, 3);
214
+    bool c3 = getBit(3, 3);
215
+    return (!c1 && c2 && c3) || (c1 && !c2 && !c3);
216
+}
217
+
218
+}; // FreeFare
219
+}; // LibNfc

+ 37
- 0
libnfc_cpptools/src/freefare/FreeFareDevice.cpp View File

@@ -0,0 +1,37 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#include "libnfc_cpptools/FreeFareDevice.h"
6
+#include "FreeFareDeviceInternal.h"
7
+
8
+namespace LibNfc
9
+{
10
+namespace FreeFare
11
+{
12
+
13
+FreeFareDevice::FreeFareDevice(std::shared_ptr<LibNfc::Core::NfcDevice> device)
14
+    : _device(device),
15
+      _freeFareDevice(std::make_shared<FreeFareDeviceInternal>(_device->getDevice()))
16
+{
17
+}
18
+
19
+LibNfc::Utils::Result<std::vector<std::shared_ptr<FreeFareTag>>> FreeFareDevice::getTags() const
20
+{
21
+    if (!_device->isOpened()) {
22
+        return LibNfc::Utils::Result<std::vector<std::shared_ptr<FreeFareTag>>>::error("Device is not opened");
23
+    }
24
+    auto tagsResult = _freeFareDevice->getTags();
25
+    if (!tagsResult) {
26
+        return LibNfc::Utils::Result<std::vector<std::shared_ptr<FreeFareTag>>>::error(tagsResult);
27
+    }
28
+    auto tags = tagsResult.getData();
29
+    std::vector<std::shared_ptr<FreeFareTag>> tagsBusiness;
30
+    for (auto tag : tags) {
31
+        tagsBusiness.push_back(std::make_shared<FreeFareTag>(tag));
32
+    }
33
+    return LibNfc::Utils::Result<std::vector<std::shared_ptr<FreeFareTag>>>::ok(tagsBusiness);
34
+}
35
+
36
+}; // FreeFare
37
+}; // LibNfc

+ 31
- 0
libnfc_cpptools/src/freefare/FreeFareDeviceInternal.cpp View File

@@ -0,0 +1,31 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#include "FreeFareDeviceInternal.h"
6
+
7
+namespace LibNfc
8
+{
9
+namespace FreeFare
10
+{
11
+
12
+FreeFareDeviceInternal::FreeFareDeviceInternal(std::shared_ptr<LibNfc::Core::NfcDeviceInternal> device)
13
+    : _device(device)
14
+{
15
+}
16
+
17
+LibNfc::Utils::Result<std::vector<std::shared_ptr<FreeFareTagInternal>>> FreeFareDeviceInternal::getTags()
18
+{
19
+    FreefareTag* tags = freefare_get_tags(_device->getDevice());
20
+    if (!tags) {
21
+        return LibNfc::Utils::Result<std::vector<std::shared_ptr<FreeFareTagInternal>>>::error("Failed to get MIFARE tags");
22
+    }
23
+    std::vector<std::shared_ptr<FreeFareTagInternal>> tagList;
24
+    for (size_t i = 0; tags[i] != 0; ++i) {
25
+        tagList.push_back(std::make_shared<FreeFareTagInternal>(tags[i]));
26
+    }
27
+    return LibNfc::Utils::Result<std::vector<std::shared_ptr<FreeFareTagInternal>>>::ok(tagList);
28
+}
29
+
30
+}; // FreeFare
31
+}; // LibNfc

+ 32
- 0
libnfc_cpptools/src/freefare/FreeFareDeviceInternal.h View File

@@ -0,0 +1,32 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_FREEFAREDEVICE_H
6
+#define MIFARE_TOOLS_FREEFAREDEVICE_H
7
+
8
+
9
+#include <freefare.h>
10
+#include "NfcDeviceInternal.h"
11
+#include "FreeFareTagInternal.h"
12
+
13
+namespace LibNfc
14
+{
15
+namespace FreeFare
16
+{
17
+
18
+class FreeFareDeviceInternal
19
+{
20
+public:
21
+    FreeFareDeviceInternal(std::shared_ptr<LibNfc::Core::NfcDeviceInternal> device);
22
+
23
+    LibNfc::Utils::Result<std::vector<std::shared_ptr<FreeFareTagInternal>>> getTags();
24
+
25
+private:
26
+    std::shared_ptr<LibNfc::Core::NfcDeviceInternal> _device;
27
+};
28
+
29
+}; // FreeFare
30
+}; // LibNfc
31
+
32
+#endif //MIFARE_TOOLS_FREEFAREDEVICE_H

+ 117
- 0
libnfc_cpptools/src/freefare/FreeFareSector.cpp View File

@@ -0,0 +1,117 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#include "libnfc_cpptools/StringUtils.h"
6
+#include "libnfc_cpptools/FreeFareSector.h"
7
+
8
+namespace LibNfc
9
+{
10
+namespace FreeFare
11
+{
12
+
13
+FreeFareSector::FreeFareSector(const std::string &data)
14
+{
15
+    std::string d = LibNfc::Utils::StringUtils::ensureSize(data, 64);
16
+    for (int i = 0; i < 4; ++i) {
17
+        _blocks[i] = d.substr(16 * i, 16);
18
+        _haveBlocks[i] = true;
19
+    }
20
+}
21
+
22
+const std::string &FreeFareSector::getBlock(int block) const
23
+{
24
+    return _blocks[block];
25
+}
26
+
27
+std::string FreeFareSector::getKeyA() const
28
+{
29
+    return _blocks[3].substr(0, 6);
30
+}
31
+
32
+std::string FreeFareSector::getKeyB() const
33
+{
34
+    return _blocks[3].substr(10, 6);
35
+}
36
+
37
+std::string FreeFareSector::getAccessBits() const
38
+{
39
+    return _blocks[3].substr(6, 4);
40
+}
41
+
42
+FreeFareAccessBits FreeFareSector::getAccessBitsDbo() const
43
+{
44
+    return FreeFareAccessBits(getAccessBits());
45
+}
46
+
47
+void FreeFareSector::setBlock(int block, const std::string &data)
48
+{
49
+    std::string d = LibNfc::Utils::StringUtils::ensureSize(data, 16);
50
+    if (block == 3) {
51
+        setKeyA(d.substr(0, 6));
52
+        setKeyB(d.substr(10, 6));
53
+        setAccessBits(d.substr(6, 4));
54
+    }
55
+    else {
56
+        _haveBlocks[block] = !data.empty();
57
+        _blocks[block] = d;
58
+    }
59
+}
60
+
61
+void FreeFareSector::setKeyA(const std::string &key)
62
+{
63
+    std::string k = LibNfc::Utils::StringUtils::ensureSize(key, 6);
64
+    for (int i = 0; i < k.size(); ++i) {
65
+        _blocks[3][i] = k[i];
66
+    }
67
+    _hasKeyA = !key.empty();
68
+}
69
+
70
+void FreeFareSector::setKeyB(const std::string &key)
71
+{
72
+    std::string k = LibNfc::Utils::StringUtils::ensureSize(key, 6);
73
+    for (int i = 0; i < k.size(); ++i) {
74
+        _blocks[3][10 + i] = k[i];
75
+    }
76
+    _hasKeyB = !key.empty();
77
+}
78
+
79
+void FreeFareSector::setAccessBits(const std::string &accessBits)
80
+{
81
+    std::string a = LibNfc::Utils::StringUtils::ensureSize(accessBits, 4);
82
+    for (int i = 0; i < a.size(); ++i) {
83
+        _blocks[3][6 + i] = a[i];
84
+    }
85
+    _hasAccessBits = !accessBits.empty();
86
+}
87
+
88
+void FreeFareSector::setAccessBits(const FreeFareAccessBits &accessBits)
89
+{
90
+    setAccessBits(accessBits.getBits());
91
+}
92
+
93
+bool FreeFareSector::hasBlock(int block) const
94
+{
95
+    if (block == 3) {
96
+        return _hasKeyA && _hasKeyB && _hasAccessBits;
97
+    }
98
+    return _haveBlocks[block];
99
+}
100
+
101
+bool FreeFareSector::hasKeyA() const
102
+{
103
+    return _hasKeyA;
104
+}
105
+
106
+bool FreeFareSector::hasKeyB() const
107
+{
108
+    return _hasKeyB;
109
+}
110
+
111
+bool FreeFareSector::hasAccessBits() const
112
+{
113
+    return _hasAccessBits;
114
+}
115
+
116
+}; // FreeFare
117
+}; // LibNfc

+ 335
- 0
libnfc_cpptools/src/freefare/FreeFareTag.cpp View File

@@ -0,0 +1,335 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#include "libnfc_cpptools/FreeFareTag.h"
6
+#include "libnfc_cpptools/StringUtils.h"
7
+#include "FreeFareTagInternal.h"
8
+
9
+namespace LibNfc
10
+{
11
+namespace FreeFare
12
+{
13
+
14
+std::string FreeFareTag::getTagTypeString(FreeFareTag::FreeFareTagType type)
15
+{
16
+    if (type == FreeFareTagType::FELICA)
17
+    {
18
+        return "FELICA";
19
+    }
20
+    if (type == FreeFareTagType::MIFARE_MINI)
21
+    {
22
+        return "MIFARE_MINI";
23
+    }
24
+    if (type == FreeFareTagType::MIFARE_CLASSIC_1K)
25
+    {
26
+        return "MIFARE_CLASSIC_1K";
27
+    }
28
+    if (type == FreeFareTagType::MIFARE_CLASSIC_4K)
29
+    {
30
+        return "MIFARE_CLASSIC_4K";
31
+    }
32
+    if (type == FreeFareTagType::MIFARE_DESFIRE)
33
+    {
34
+        return "MIFARE_DESFIRE";
35
+    }
36
+    if (type == FreeFareTagType::MIFARE_ULTRALIGHT)
37
+    {
38
+        return "MIFARE_ULTRALIGHT";
39
+    }
40
+    if (type == FreeFareTagType::MIFARE_ULTRALIGHT_C)
41
+    {
42
+        return "MIFARE_ULTRALIGHT_C";
43
+    }
44
+    return "UNKNOWN";
45
+}
46
+
47
+FreeFareTag::FreeFareTag(std::shared_ptr<FreeFareTagInternal> tag)
48
+    : _tag(tag)
49
+{
50
+}
51
+
52
+LibNfc::Utils::ResultBool FreeFareTag::authenticate(int sector, std::string key, int keyType)
53
+{
54
+    return _tag->authenticate(sector, key, keyType);
55
+}
56
+
57
+LibNfc::Utils::Result<MappedKeys> FreeFareTag::mapKeys(std::vector<std::string> keys, std::function<void(int, int)> cb)
58
+{
59
+    MappedKeys mappedKeys;
60
+    int done = 0;
61
+    int total = 16 * keys.size();
62
+
63
+    for (int i = 0; i < 16; ++i) {
64
+        std::pair<std::string, std::string> blockKeys;
65
+        for (int k = 0; k < keys.size(); ++k) {
66
+            auto key = keys[k];
67
+            if (authenticate(i, key, MFC_KEY_A)) {
68
+                blockKeys.first = key;
69
+            }
70
+            if (authenticate(i, key, MFC_KEY_B)) {
71
+                blockKeys.second = key;
72
+            }
73
+            if (cb != 0) {
74
+                cb(++done, total);
75
+            }
76
+            if (!blockKeys.first.empty() && !blockKeys.second.empty()) {
77
+                break;
78
+            }
79
+        }
80
+        mappedKeys.push_back(blockKeys);
81
+    }
82
+    if (cb != 0 && done < total) {
83
+        cb(total, total);
84
+    }
85
+
86
+    return LibNfc::Utils::Result<MappedKeys>::ok(mappedKeys);
87
+}
88
+
89
+LibNfc::Utils::ResultString FreeFareTag::readBlock(int sector, int block, std::string key, int keyType)
90
+{
91
+    return _tag->readBlock(sector, block, key, keyType);
92
+}
93
+
94
+LibNfc::Utils::Result<FreeFareSector> FreeFareTag::readSector(int sector, std::string key, int keyType)
95
+{
96
+    std::string res;
97
+    int lastBlock = _tag->getSectorBlockCount(sector);
98
+    for (int i = 0; i < lastBlock; ++i) {
99
+        auto data = readBlock(sector, i, key, keyType);
100
+        if (data) {
101
+            res += data.getData();
102
+        }
103
+        else {
104
+            return LibNfc::Utils::Result<FreeFareSector>::error(data);
105
+        }
106
+    }
107
+    return LibNfc::Utils::Result<FreeFareSector>::ok(FreeFareSector(res));
108
+}
109
+
110
+LibNfc::Utils::Result<std::vector<FreeFareSector>> FreeFareTag::read(MappedKeys keys, std::function<void(int, int)> cb)
111
+{
112
+    if (keys.size() != 16) {
113
+        return LibNfc::Utils::Result<std::vector<FreeFareSector>>::error("Must have 16 sectors keys");
114
+    }
115
+    int done = 0;
116
+    int total = 4 * keys.size();
117
+    std::vector<FreeFareSector> sectors;
118
+    for (int s = 0; s < keys.size(); ++s) {
119
+        auto sectorKey = keys[s];
120
+        FreeFareSector sector;
121
+        bool keyA = false;
122
+        bool keyB = false;
123
+        for (int b = 0; b < 3; ++b) {
124
+            std::string data = "";
125
+            if (!sectorKey.first.empty()) {
126
+                auto blockResult = readBlock(s, b, sectorKey.first, MFC_KEY_A);
127
+                if (blockResult) {
128
+                    data = blockResult.getData();
129
+                    keyA = true;
130
+                }
131
+            }
132
+            if (!sectorKey.second.empty()) {
133
+                auto blockResult = readBlock(s, b, sectorKey.second, MFC_KEY_B);
134
+                if (blockResult) {
135
+                    if (data.empty()) {
136
+                        data = blockResult.getData();
137
+                    }
138
+                    keyB = true;
139
+                }
140
+            }
141
+            sector.setBlock(b, data);
142
+            if (cb != 0) {
143
+                cb(++done, total);
144
+            }
145
+        }
146
+        int b = 3;
147
+        std::string dataA = "";
148
+        std::string dataB = "";
149
+        if (!sectorKey.first.empty()) {
150
+            auto blockResult = readBlock(s, b, sectorKey.first, MFC_KEY_A);
151
+            if (blockResult) {
152
+                dataA = blockResult.getData();
153
+                keyA = true;
154
+            }
155
+        }
156
+        if (!sectorKey.second.empty()) {
157
+            auto blockResult = readBlock(s, b, sectorKey.second, MFC_KEY_B);
158
+            if (blockResult) {
159
+                dataB = blockResult.getData();
160
+                keyB = true;
161
+            }
162
+        }
163
+        if (cb != 0) {
164
+            cb(++done, total);
165
+        }
166
+
167
+        sector.setBlock(b, dataA);
168
+        FreeFareAccessBits accessBitsDboA = sector.getAccessBitsDbo();
169
+        sector.setBlock(b, dataB);
170
+        FreeFareAccessBits accessBitsDboB = sector.getAccessBitsDbo();
171
+        sector.setKeyA(keyA ? sectorKey.first : "");
172
+        sector.setKeyB(keyB ? sectorKey.second : "");
173
+
174
+        std::string accessBits;
175
+        if (keyA && accessBitsDboA.canKeyAReadAccessBitsTrailer()) {
176
+            accessBits = accessBitsDboA.getBits();
177
+        }
178
+        else if (keyB && accessBitsDboB.canKeyBReadAccessBitsTrailer()) {
179
+            accessBits = accessBitsDboB.getBits();
180
+        }
181
+        sector.setAccessBits(accessBits);
182
+
183
+        sectors.push_back(sector);
184
+    }
185
+    if (cb != 0 && done < total) {
186
+        cb(total, total);
187
+    }
188
+
189
+    return LibNfc::Utils::Result<std::vector<FreeFareSector>>::ok(sectors);
190
+}
191
+
192
+LibNfc::Utils::Result<std::vector<FreeFareSector>> FreeFareTag::read(std::vector<std::string> keys, std::function<void(int, int)> mapCb,
193
+                                                         std::function<void(int, int)> readCb)
194
+{
195
+    auto mappedKeysResult = mapKeys(keys, mapCb);
196
+    if (!mappedKeysResult) {
197
+        return LibNfc::Utils::Result<std::vector<FreeFareSector>>::error(mappedKeysResult);
198
+    }
199
+    return read(mappedKeysResult.getData(), readCb);
200
+}
201
+
202
+LibNfc::Utils::ResultBool FreeFareTag::writeBlock(int sector, int block, std::string key, int keyType, const std::string &data)
203
+{
204
+    return _tag->writeBlock(sector, block, key, keyType, LibNfc::Utils::StringUtils::ensureSize(data, 16));
205
+}
206
+
207
+LibNfc::Utils::ResultBool FreeFareTag::writeSector(int sector, std::string key, int keyType, const std::string &data)
208
+{
209
+    std::string d = LibNfc::Utils::StringUtils::ensureSize(data, 64);
210
+    std::string errors;
211
+    for (int b = 0; b < 4; ++b) {
212
+        auto result = writeBlock(sector, b, key, keyType, d.substr(b * 16, 16));
213
+        if (!result) {
214
+            errors += std::string(errors.empty() ? "" : "\n") + "Failed to write sector " + std::to_string(sector) +
215
+                      " block " + std::to_string(b) + " with key " + (keyType == MFC_KEY_A ? "A" : "B") + ": " + result.getError();
216
+        }
217
+    }
218
+    if (errors.empty()) {
219
+        return LibNfc::Utils::ResultBool::ok(true);
220
+    }
221
+    return LibNfc::Utils::ResultBool::error(errors);
222
+}
223
+
224
+LibNfc::Utils::ResultBool FreeFareTag::write(MappedKeys keys, const std::string &data, bool writeSector0, std::function<void(int, int)> cb)
225
+{
226
+    if (keys.size() != 16) {
227
+        return LibNfc::Utils::ResultBool::error("Must have 16 sectors keys");
228
+    }
229
+    std::string d = LibNfc::Utils::StringUtils::ensureSize(data, 1024);
230
+    std::string errors;
231
+    int done = 0;
232
+    int total = 4 * keys.size();
233
+    for (int s = 0; s < keys.size(); ++s) {
234
+        auto sectorKey = keys[s];
235
+        for (int b = 0; b < 4; ++b) {
236
+            if (s == 0 && b == 0 && !writeSector0) {
237
+                continue;
238
+            }
239
+            std::string blockData = d.substr((s * 64) + (b * 16), 16);
240
+            if (cb != 0 && done < total) {
241
+                bool keyA = false;
242
+                bool keyB = false;
243
+                std::string sectorErrors;
244
+                if (!sectorKey.first.empty()) {
245
+                    auto resultA = writeBlock(s, b, sectorKey.first, MFC_KEY_A, blockData);
246
+                    if (resultA) {
247
+                        keyA = true;
248
+                    }
249
+                    else {
250
+                        sectorErrors = "Failed to write sector " + std::to_string(s) +
251
+                                       " block " + std::to_string(b) + " with key A: " + resultA.getError();
252
+                    }
253
+                }
254
+                if (!keyA && !sectorKey.second.empty()) {
255
+                    auto resultB = writeBlock(s, b, sectorKey.first, MFC_KEY_A, blockData);
256
+                    if (resultB) {
257
+                        keyB = true;
258
+                    }
259
+                    else {
260
+                        sectorErrors = std::string(sectorErrors.empty() ? "" : "\n") + "Failed to write sector " + std::to_string(s) +
261
+                                       " block " + std::to_string(b) + " with key B: " + resultB.getError();
262
+                    }
263
+                }
264
+                if (!keyA && !keyB) {
265
+                    errors += std::string(errors.empty() ? "" : "\n") + sectorErrors;
266
+                }
267
+                cb(++done, total);
268
+            }
269
+        }
270
+    }
271
+    if (cb != 0 && done < total) {
272
+        cb(total, total);
273
+    }
274
+    if (errors.empty()) {
275
+        return LibNfc::Utils::ResultBool::ok(true);
276
+    }
277
+    return LibNfc::Utils::ResultBool::error(errors);
278
+}
279
+
280
+LibNfc::Utils::ResultBool FreeFareTag::write(std::vector<std::string> keys, const std::string &data, bool writeSector0,
281
+                                      std::function<void(int, int)> mapCb, std::function<void(int, int)> writeCb)
282
+{
283
+    auto mappedKeysResult = mapKeys(keys, mapCb);
284
+    if (!mappedKeysResult) {
285
+        return LibNfc::Utils::ResultBool::error(mappedKeysResult);
286
+    }
287
+    return write(mappedKeysResult.getData(), data, writeSector0, writeCb);
288
+}
289
+
290
+const std::string &FreeFareTag::getUid() const
291
+{
292
+    return _tag->getUid();
293
+}
294
+
295
+FreeFareTag::FreeFareTagType FreeFareTag::getType() const
296
+{
297
+    auto type = _tag->getType();
298
+    if (type == freefare_tag_type::FELICA)
299
+    {
300
+        return FreeFareTagType::FELICA;
301
+    }
302
+    if (type == freefare_tag_type::MIFARE_MINI)
303
+    {
304
+        return FreeFareTagType::MIFARE_MINI;
305
+    }
306
+    if (type == freefare_tag_type::MIFARE_CLASSIC_1K)
307
+    {
308
+        return FreeFareTagType::MIFARE_CLASSIC_1K;
309
+    }
310
+    if (type == freefare_tag_type::MIFARE_CLASSIC_4K)
311
+    {
312
+        return FreeFareTagType::MIFARE_CLASSIC_4K;
313
+    }
314
+    if (type == freefare_tag_type::MIFARE_DESFIRE)
315
+    {
316
+        return FreeFareTagType::MIFARE_DESFIRE;
317
+    }
318
+    if (type == freefare_tag_type::MIFARE_ULTRALIGHT)
319
+    {
320
+        return FreeFareTagType::MIFARE_ULTRALIGHT;
321
+    }
322
+    if (type == freefare_tag_type::MIFARE_ULTRALIGHT_C)
323
+    {
324
+        return FreeFareTagType::MIFARE_ULTRALIGHT_C;
325
+    }
326
+    return FreeFareTagType::UNKNOWN;
327
+}
328
+
329
+std::shared_ptr<FreeFareTagInternal> FreeFareTag::getTag() const
330
+{
331
+    return _tag;
332
+}
333
+
334
+}; // FreeFare
335
+}; // LibNfc

+ 109
- 0
libnfc_cpptools/src/freefare/FreeFareTagInternal.cpp View File

@@ -0,0 +1,109 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#include <sstream>
6
+#include <map>
7
+#include "FreeFareTagInternal.h"
8
+
9
+namespace LibNfc
10
+{
11
+namespace FreeFare
12
+{
13
+
14
+FreeFareTagInternal::FreeFareTagInternal(FreefareTag tag)
15
+    : _tag(tag)
16
+{
17
+    _type = freefare_get_tag_type(tag);
18
+    _uid = freefare_get_tag_uid(tag);
19
+}
20
+
21
+FreeFareTagInternal::~FreeFareTagInternal()
22
+{
23
+    freefare_free_tag(_tag);
24
+}
25
+
26
+LibNfc::Utils::ResultBool FreeFareTagInternal::authenticate(int sector, std::string key, int keyType)
27
+{
28
+
29
+    if (mifare_classic_connect(_tag) != 0) {
30
+        return LibNfc::Utils::ResultBool::error("Failed to connect to MIFARE tag");
31
+    }
32
+    int block = mifare_classic_sector_last_block((MifareClassicBlockNumber)sector);
33
+    if (mifare_classic_authenticate(_tag, (MifareClassicBlockNumber)block, (const unsigned char*)key.c_str(),
34
+                                    (MifareClassicKeyType)keyType) != 0) {
35
+        return LibNfc::Utils::ResultBool::error("Failed to authenticate to MIFARE tag");
36
+    }
37
+    mifare_classic_disconnect(_tag);
38
+    return LibNfc::Utils::ResultBool::ok(true);
39
+}
40
+
41
+LibNfc::Utils::ResultString FreeFareTagInternal::readBlock(int sector, int block, std::string key, int keyType)
42
+{
43
+    if (mifare_classic_connect(_tag) != 0) {
44
+        return LibNfc::Utils::ResultString::error("Failed to connect to MIFARE tag");
45
+    }
46
+    block = mifare_classic_sector_first_block((MifareClassicBlockNumber)sector) + block;
47
+    if (mifare_classic_authenticate(_tag, (MifareClassicBlockNumber)block, (const unsigned char*)key.c_str(),
48
+                                    (MifareClassicKeyType)keyType) != 0) {
49
+        return LibNfc::Utils::ResultString::error("Failed to authenticate to MIFARE tag");
50
+    }
51
+
52
+    MifareClassicBlock data;
53
+    if (mifare_classic_read(_tag, (MifareClassicBlockNumber)block, &data)) {
54
+        return LibNfc::Utils::ResultString::error("Failed to read MIFARE tag data");
55
+    }
56
+    mifare_classic_disconnect(_tag);
57
+    return LibNfc::Utils::ResultString::ok(std::string((const char*)data, sizeof(data)));
58
+}
59
+
60
+LibNfc::Utils::ResultBool FreeFareTagInternal::writeBlock(int sector, int block, std::string key, int keyType, const std::string &data)
61
+{
62
+    if (mifare_classic_connect(_tag) != 0) {
63
+        return LibNfc::Utils::ResultBool::error("Failed to connect to MIFARE tag");
64
+    }
65
+    block = mifare_classic_sector_first_block((MifareClassicBlockNumber)sector) + block;
66
+    if (mifare_classic_authenticate(_tag, (MifareClassicBlockNumber)block, (const unsigned char*)key.c_str(),
67
+                                    (MifareClassicKeyType)keyType) != 0) {
68
+        return LibNfc::Utils::ResultBool::error("Failed to authenticate to MIFARE tag");
69
+    }
70
+
71
+    if (mifare_classic_write(_tag, (MifareClassicBlockNumber)block, (const unsigned char*)data.c_str())) {
72
+        return LibNfc::Utils::ResultBool::error("Failed to write data to MIFARE tag");
73
+    }
74
+    mifare_classic_disconnect(_tag);
75
+    return LibNfc::Utils::ResultBool::ok(true);
76
+}
77
+
78
+const freefare_tag *FreeFareTagInternal::getTag() const
79
+{
80
+    return _tag;
81
+}
82
+
83
+int FreeFareTagInternal::getFirstBlock(int sector) const
84
+{
85
+    return mifare_classic_sector_first_block(sector);
86
+}
87
+
88
+int FreeFareTagInternal::getLastBlock(int sector) const
89
+{
90
+    return mifare_classic_sector_last_block(sector);
91
+}
92
+
93
+int FreeFareTagInternal::getSectorBlockCount(int sector)
94
+{
95
+    return mifare_classic_sector_block_count(sector);
96
+}
97
+
98
+freefare_tag_type FreeFareTagInternal::getType() const
99
+{
100
+    return _type;
101
+}
102
+
103
+const std::string &FreeFareTagInternal::getUid() const
104
+{
105
+    return _uid;
106
+}
107
+
108
+}; // FreeFare
109
+}; // LibNfc

+ 53
- 0
libnfc_cpptools/src/freefare/FreeFareTagInternal.h View File

@@ -0,0 +1,53 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_FREEFARETAG_H
6
+#define MIFARE_TOOLS_FREEFARETAG_H
7
+
8
+#include <freefare.h>
9
+#include <string>
10
+#include "libnfc_cpptools/Result.h"
11
+
12
+namespace LibNfc
13
+{
14
+namespace FreeFare
15
+{
16
+
17
+class FreeFareTagInternal
18
+{
19
+public:
20
+
21
+    FreeFareTagInternal(FreefareTag tag);
22
+    ~FreeFareTagInternal();
23
+
24
+    LibNfc::Utils::ResultBool authenticate(int sector, std::string key, int keyType);
25
+
26
+    LibNfc::Utils::ResultString readBlock(int sector, int block, std::string key, int keyType);
27
+
28
+    LibNfc::Utils::ResultBool writeBlock(int sector, int block, std::string key, int keyType, const std::string& data);
29
+
30
+    int getFirstBlock(int sector) const;
31
+
32
+    int getLastBlock(int sector) const;
33
+
34
+    int getSectorBlockCount(int sector);
35
+
36
+    const freefare_tag * getTag() const;
37
+
38
+    freefare_tag_type getType() const;
39
+
40
+    const std::string & getUid() const;
41
+
42
+private:
43
+    FreefareTag _tag;
44
+
45
+    freefare_tag_type _type;
46
+
47
+    std::string _uid;
48
+};
49
+
50
+}; // FreeFare
51
+}; // LibNfc
52
+
53
+#endif //MIFARE_TOOLS_FREEFARETAG_H

+ 83
- 0
libnfc_cpptools/src/libnfc/LibNfc.cpp View File

@@ -0,0 +1,83 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#include <algorithm>
6
+#include "libnfc_cpptools/LibNfc.h"
7
+#include "LibNfcInternal.h"
8
+
9
+#define Q(x) #x
10
+#define QUOTE(x) Q(x)
11
+
12
+#ifndef GIT_SHA1
13
+#define GIT_SHA1 "unknown"
14
+#endif
15
+
16
+#ifndef GIT_REF_NAME
17
+#define GIT_REF_NAME "unknown"
18
+#endif
19
+
20
+namespace LibNfc
21
+{
22
+namespace Core
23
+{
24
+
25
+LibNfcContext::LibNfcContext()
26
+{
27
+    _libNfc = std::make_shared<LibNfcInternal>();
28
+}
29
+
30
+LibNfcContext::~LibNfcContext()
31
+{
32
+    _libNfc->clean();
33
+}
34
+
35
+LibNfc::Utils::ResultBool LibNfcContext::init()
36
+{
37
+    if (isInitialized()) {
38
+        return LibNfc::Utils::ResultBool::error("LibNfc is already initialized");
39
+    }
40
+    return _libNfc->init();
41
+}
42
+
43
+std::string LibNfcContext::getLibNfcVersion()
44
+{
45
+    return LibNfcInternal::getVersion();
46
+}
47
+
48
+void LibNfcContext::clean()
49
+{
50
+    if (isInitialized()) {
51
+        _libNfc->clean();
52
+    }
53
+}
54
+
55
+bool LibNfcContext::isInitialized() const
56
+{
57
+    return _libNfc->getContext() != 0;
58
+}
59
+
60
+LibNfc::Utils::Result<std::vector<std::shared_ptr<NfcDevice>>> LibNfcContext::getDevices() const
61
+{
62
+    if (!isInitialized()) {
63
+        return LibNfc::Utils::Result<std::vector<std::shared_ptr<NfcDevice>>>::error("LibNfc is not initialized");
64
+    }
65
+    auto devicesResult = _libNfc->getDevices();
66
+    if (!devicesResult) {
67
+        return LibNfc::Utils::Result<std::vector<std::shared_ptr<NfcDevice>>>::error(devicesResult);
68
+    }
69
+    auto devices = devicesResult.getData();
70
+    std::vector<std::shared_ptr<NfcDevice>> devicesBusiness;
71
+    for (auto device : devices) {
72
+        devicesBusiness.push_back(std::make_shared<NfcDevice>(device));
73
+    }
74
+    return LibNfc::Utils::Result<std::vector<std::shared_ptr<NfcDevice>>>::ok(devicesBusiness);
75
+}
76
+
77
+std::string LibNfcContext::getMifareToolsVersion()
78
+{
79
+    return QUOTE(GIT_REF_NAME)  "-"  QUOTE(GIT_SHA1);
80
+}
81
+
82
+}; // Core
83
+}; // LibNfc

+ 64
- 0
libnfc_cpptools/src/libnfc/LibNfcInternal.cpp View File

@@ -0,0 +1,64 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#include <boost/shared_ptr.hpp>
6
+#include "LibNfcInternal.h"
7
+
8
+namespace LibNfc
9
+{
10
+namespace Core
11
+{
12
+
13
+LibNfcInternal::LibNfcInternal()
14
+    : _context(0)
15
+{
16
+}
17
+
18
+LibNfcInternal::~LibNfcInternal()
19
+{
20
+    clean();
21
+}
22
+
23
+LibNfc::Utils::ResultBool LibNfcInternal::init()
24
+{
25
+    nfc_init(&_context);
26
+    if (!_context) {
27
+        return LibNfc::Utils::ResultBool::error("LibNfc could not be initialized");
28
+    }
29
+    return LibNfc::Utils::ResultBool::ok(true);
30
+}
31
+
32
+std::string LibNfcInternal::getVersion()
33
+{
34
+    return nfc_version();
35
+}
36
+
37
+void LibNfcInternal::clean()
38
+{
39
+    nfc_exit(_context);
40
+    _context = 0;
41
+}
42
+
43
+LibNfc::Utils::Result<std::vector<std::shared_ptr<NfcDeviceInternal>>> LibNfcInternal::getDevices() const
44
+{
45
+    nfc_connstring devices[16];
46
+    ::memset((char*)devices, 0, sizeof(devices));
47
+    size_t count = nfc_list_devices(_context, devices, 16);
48
+    if (count < 0) {
49
+        return LibNfc::Utils::Result<std::vector<std::shared_ptr<NfcDeviceInternal>>>::error("Failed to list NFC devices: " + count);
50
+    }
51
+    std::vector<std::shared_ptr<NfcDeviceInternal>> devicesList;
52
+    for (size_t i = 0; i < count; ++i) {
53
+        devicesList.push_back(std::make_shared<NfcDeviceInternal>(this, devices[i]));
54
+    }
55
+    return LibNfc::Utils::Result<std::vector<std::shared_ptr<NfcDeviceInternal>>>::ok(devicesList);
56
+}
57
+
58
+nfc_context *LibNfcInternal::getContext() const
59
+{
60
+    return _context;
61
+}
62
+
63
+}; // Core
64
+}; // LibNfc

+ 43
- 0
libnfc_cpptools/src/libnfc/LibNfcInternal.h View File

@@ -0,0 +1,43 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_LIBNFC_H
6
+#define MIFARE_TOOLS_LIBNFC_H
7
+
8
+#include <memory>
9
+#include <nfc/nfc.h>
10
+#include "NfcDeviceInternal.h"
11
+#include "libnfc_cpptools/Result.h"
12
+
13
+namespace LibNfc
14
+{
15
+namespace Core
16
+{
17
+
18
+class NfcDeviceInternal;
19
+
20
+class LibNfcInternal
21
+{
22
+public:
23
+    LibNfcInternal();
24
+    virtual ~LibNfcInternal();
25
+
26
+    LibNfc::Utils::ResultBool init();
27
+
28
+    void clean();
29
+
30
+    LibNfc::Utils::Result<std::vector<std::shared_ptr<NfcDeviceInternal>>> getDevices() const;
31
+
32
+    static std::string getVersion();
33
+
34
+    nfc_context* getContext() const;
35
+
36
+protected:
37
+    nfc_context* _context;
38
+};
39
+
40
+}; // Core
41
+}; // LibNfc
42
+
43
+#endif //MIFARE_TOOLS_LIBNFC_H

+ 49
- 0
libnfc_cpptools/src/libnfc/NfcDevice.cpp View File

@@ -0,0 +1,49 @@
1
+//
2
+// Created by robin on 7/22/16.
3
+//
4
+
5
+#include "libnfc_cpptools/NfcDevice.h"
6
+#include "NfcDeviceInternal.h"
7
+
8
+namespace LibNfc
9
+{
10
+namespace Core
11
+{
12
+
13
+NfcDevice::NfcDevice(std::shared_ptr<NfcDeviceInternal> device)
14
+    : _device(device)
15
+{
16
+}
17
+
18
+LibNfc::Utils::ResultBool NfcDevice::open()
19
+{
20
+    if (isOpened()) {
21
+        return LibNfc::Utils::ResultBool::error("NFC device is already opened");
22
+    }
23
+    return _device->open();
24
+}
25
+
26
+void NfcDevice::close()
27
+{
28
+    if (isOpened()) {
29
+        _device->close();
30
+    }
31
+}
32
+
33
+bool NfcDevice::isOpened() const
34
+{
35
+    return _device->getDevice() != 0;
36
+}
37
+
38
+const std::string &NfcDevice::getConnStr() const
39
+{
40
+    return _device->getConnStr();
41
+}
42
+
43
+std::shared_ptr<NfcDeviceInternal> NfcDevice::getDevice() const
44
+{
45
+    return _device;
46
+}
47
+
48
+}; // Core
49
+}; // LibNfc

+ 50
- 0
libnfc_cpptools/src/libnfc/NfcDeviceInternal.cpp View File

@@ -0,0 +1,50 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#include "NfcDeviceInternal.h"
6
+
7
+namespace LibNfc
8
+{
9
+namespace Core
10
+{
11
+
12
+NfcDeviceInternal::NfcDeviceInternal(const LibNfcInternal* libNfc, const std::string& str)
13
+    : _connStr(str)
14
+    , _device(0)
15
+    , _libNfc(libNfc)
16
+{
17
+}
18
+
19
+NfcDeviceInternal::~NfcDeviceInternal()
20
+{
21
+    close();
22
+}
23
+
24
+LibNfc::Utils::ResultBool NfcDeviceInternal::open()
25
+{
26
+    _device = nfc_open(_libNfc->getContext(), _connStr.c_str());
27
+    if (!_device) {
28
+        return LibNfc::Utils::ResultBool::error("Failed to open NFC device");
29
+    }
30
+    return LibNfc::Utils::ResultBool::ok(true);
31
+}
32
+
33
+void NfcDeviceInternal::close()
34
+{
35
+    nfc_close(_device);
36
+    _device = 0;
37
+}
38
+
39
+nfc_device *NfcDeviceInternal::getDevice() const
40
+{
41
+    return _device;
42
+}
43
+
44
+const std::string &NfcDeviceInternal::getConnStr() const
45
+{
46
+    return _connStr;
47
+}
48
+
49
+}; // Core
50
+}; // LibNfc

+ 46
- 0
libnfc_cpptools/src/libnfc/NfcDeviceInternal.h View File

@@ -0,0 +1,46 @@
1
+//
2
+// Created by robin on 6/19/16.
3
+//
4
+
5
+#ifndef MIFARE_TOOLS_NFCDEVICEDBO_H
6
+#define MIFARE_TOOLS_NFCDEVICEDBO_H
7
+
8
+
9
+#include <string>
10
+#include <nfc/nfc-types.h>
11
+#include "libnfc_cpptools/Result.h"
12
+#include "LibNfcInternal.h"
13
+
14
+namespace LibNfc
15
+{
16
+namespace Core
17
+{
18
+
19
+class LibNfcInternal;
20
+
21
+class NfcDeviceInternal
22
+{
23
+public:
24
+    NfcDeviceInternal(const LibNfcInternal* libNfc, const std::string& connStr);
25
+    ~NfcDeviceInternal();
26
+
27
+    LibNfc::Utils::ResultBool open();
28
+
29
+    void close();
30
+
31
+    const std::string & getConnStr() const;
32
+
33
+    nfc_device * getDevice() const;
34
+
35
+private:
36
+    std::string _connStr;
37
+
38
+    nfc_device* _device;
39
+
40
+    const LibNfcInternal* _libNfc;
41
+};
42
+
43
+}; // Core
44
+}; // LibNfc
45
+
46
+#endif //MIFARE_TOOLS_NFCDEVICEDBO_H

+ 44
- 0
libnfc_cpptools/src/utils/ArrayUtils.cpp View File

@@ -0,0 +1,44 @@
1
+//
2
+// Created by robin on 7/23/16.
3
+//
4
+
5
+#include "libnfc_cpptools/ArrayUtils.h"
6
+
7
+namespace LibNfc
8
+{
9
+namespace Utils
10
+{
11
+
12
+void ArrayUtils::setArrayBit(char *buf, const char &bitPosition, const bool &value)
13
+{
14
+    char byteOffset = (char)(bitPosition / 8);
15
+    char bitOffset = (char)(7 - (bitPosition % 8));
16
+    if(value)
17
+    {
18
+        buf[byteOffset] |=  (1 << bitOffset);
19
+    }
20
+    else
21
+    {
22
+        buf[byteOffset] &= ~(1 << bitOffset);
23
+    }
24
+}
25
+
26
+void ArrayUtils::setArrayBit(unsigned char *buf, const char &bitPosition, const bool &value)
27
+{
28
+    setArrayBit((char*)buf, bitPosition, value);
29
+}
30
+
31
+bool ArrayUtils::getArrayBit(const char *buf, const char &bitPosition)
32
+{
33
+    char byteOffset = (char)(bitPosition / 8);
34
+    char bitOffset = (char)(7 - (bitPosition % 8));
35
+    return (buf[byteOffset] >> bitOffset) & 1 == 1;
36
+}
37
+
38
+bool ArrayUtils::getArrayBit(const unsigned char *buf, const char &bitPosition)
39
+{
40
+    return getArrayBit((const char *)buf, bitPosition);
41
+}
42
+
43
+}; // Utils
44
+}; // LibNfc

+ 168
- 0
libnfc_cpptools/src/utils/StringUtils.cpp View File

@@ -0,0 +1,168 @@
1
+//
2
+// Created by robin on 6/20/16.
3
+//
4
+
5
+#include <algorithm>
6
+#include "libnfc_cpptools/StringUtils.h"
7
+
8
+namespace LibNfc
9
+{
10
+namespace Utils
11
+{
12
+
13
+const std::string StringUtils::hex = "0123456789abcdef";
14
+
15
+std::string StringUtils::rawToHuman(uint8_t c)
16
+{
17
+    return std::string(1, hex[c >> 4]) + std::string(1, hex[c & 0x0f]);
18
+}
19
+
20
+std::string StringUtils::rawToHuman(int8_t c)
21
+{
22
+    return rawToHuman((uint8_t) c);
23
+}
24
+
25
+std::string StringUtils::rawToHuman(uint16_t c)
26
+{
27
+    return rawToHuman((uint8_t) (c >> 8)) + rawToHuman((uint8_t) c);
28
+}
29
+
30
+std::string StringUtils::rawToHuman(int16_t c)
31
+{
32
+    return rawToHuman((uint16_t) c);
33
+}
34
+
35
+std::string StringUtils::rawToHuman(uint32_t c)
36
+{
37
+    return rawToHuman((uint16_t) (c >> 16)) + rawToHuman((uint16_t) c);
38
+}
39
+
40
+std::string StringUtils::rawToHuman(int32_t c)
41
+{
42
+    return rawToHuman((uint32_t) c);
43
+}
44
+
45
+std::string StringUtils::rawToHuman(uint64_t c)
46
+{
47
+    return rawToHuman((uint32_t) (c >> 32)) + rawToHuman((uint32_t) c);
48
+}
49
+
50
+std::string StringUtils::rawToHuman(int64_t c)
51
+{
52
+    return rawToHuman((uint64_t) c);
53
+}
54
+
55
+std::string StringUtils::rawToHuman(const std::string &raw)
56
+{
57
+    std::string human;
58
+    for (size_t i = 0; i < raw.size(); ++i)
59
+    {
60
+        human += rawToHuman((int8_t) raw[i]);
61
+    }
62
+    return human;
63
+}
64
+
65
+ResultString StringUtils::humanToRaw(const std::string &human)
66
+{
67
+    if (human.size() % 2 != 0)
68
+    {
69
+        return ResultString::error("Malformed hex data: invalid length");
70
+    }
71
+    std::string raw;
72
+    for (size_t i = 0; i < human.size(); i += 2)
73
+    {
74
+        char c1 = toLower(human[i]);
75
+        char c2 = toLower(human[i + 1]);
76
+        size_t i1 = hex.find(c1);
77
+        size_t i2 = hex.find(c2);
78
+        if (i1 == std::string::npos || i2 == std::string::npos)
79
+        {
80
+            return ResultString::error("Malformed hex data at char " + std::to_string(i));
81
+        }
82
+        raw += std::string(1, (char) ((i1 << 4) + i2));
83
+    }
84
+    return ResultString::ok(raw);
85
+}
86
+
87
+std::string StringUtils::toLower(const std::string &str)
88
+{
89
+    std::string lower;
90
+    for (size_t i = 0; i < str.size(); ++i)
91
+    {
92
+        lower += tolower(str[i]);
93
+    }
94
+    return lower;
95
+}
96
+
97
+char StringUtils::toLower(char c)
98
+{
99
+    if (c >= 'A' && c <= 'Z')
100
+    {
101
+        return c + ('a' - 'A');
102
+    }
103
+    return c;
104
+}
105
+
106
+std::string StringUtils::toUpper(const std::string &str)
107
+{
108
+    std::string upper;
109
+    for (size_t i = 0; i < str.size(); ++i)
110
+    {
111
+        upper += toUpper(str[i]);
112
+    }
113
+    return upper;
114
+}
115
+
116
+char StringUtils::toUpper(char c)
117
+{
118
+    if (c >= 'a' && c <= 'z')
119
+    {
120
+        return c - ('a' - 'A');
121
+    }
122
+    return c;
123
+}
124
+
125
+std::string StringUtils::ensureSize(const std::string &data, int size)
126
+{
127
+    if (data.size() == size)
128
+    {
129
+        return data;
130
+    } else if (data.size() > size)
131
+    {
132
+        return data.substr(0, size);
133
+    } else
134
+    {
135
+        return data + std::string(size - data.size(), '\0');
136
+    }
137
+}
138
+
139
+std::string StringUtils::ltrim(const std::string &s)
140
+{
141
+    std::string data = s;
142
+    data.erase(data.begin(), std::find_if(data.begin(), data.end(),
143
+                                          std::not1(std::ptr_fun<int, int>(std::isspace))));
144
+    return data;
145
+}
146
+
147
+std::string StringUtils::rtrim(const std::string &s)
148
+{
149
+    std::string data = s;
150
+    data.erase(std::find_if(data.rbegin(), data.rend(),
151
+                            std::not1(std::ptr_fun<int, int>(std::isspace))).base(), data.end());
152
+    return data;
153
+}
154
+
155
+std::string StringUtils::trim(const std::string &s)
156
+{
157
+    return ltrim(rtrim(s));
158
+}
159
+
160
+std::string StringUtils::removeSpaces(const std::string &s)
161
+{
162
+    std::string data = s;
163
+    data.erase(std::remove_if(data.begin(), data.end(), std::ptr_fun<int, int>(std::isspace)), data.end());
164
+    return data;
165
+}
166
+
167
+}; // Utils
168
+}; // LibNfc

+ 14
- 0
tests/CMakeLists.txt View File

@@ -0,0 +1,14 @@
1
+enable_testing()
2
+include_directories(
3
+        ${LIBNFC_CPPTOOLS_INCLUDE_PATH}
4
+        )
5
+
6
+message(STATUS "include path: " ${LIBNFC_CPPTOOLS_INCLUDE_PATH})
7
+
8
+find_package (Threads)
9
+add_executable(${PROJECT_NAME}-test
10
+        test-main.cpp
11
+        )
12
+
13
+target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME} gtest pthread)
14
+add_test(${PROJECT_NAME}-test ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-test)

+ 542
- 0
tests/test-main.cpp View File

@@ -0,0 +1,542 @@
1
+#include <iostream>
2
+#include <string.h>
3
+#include <gtest/gtest.h>
4
+#include <libnfc_cpptools/LibNfc.h>
5
+#include <libnfc_cpptools/StringUtils.h>
6
+#include <libnfc_cpptools/ArrayUtils.h>
7
+#include <libnfc_cpptools/FreeFareAccessBits.h>
8
+
9
+TEST(StringUtils, rawToHumanChar)
10
+{
11
+    ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int8_t)255), "ff");
12
+    ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int8_t)127), "7f");
13
+    ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int8_t)10), "0a");
14
+    ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int8_t)0), "00");
15
+}
16
+
17
+TEST(StringUtils, rawToHumanShort)
18
+{
19
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int16_t)65535), "ffff");
20
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int16_t)65534), "fffe");
21
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int16_t)256), "0100");
22
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int16_t)255), "00ff");
23
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int16_t)127), "007f");
24
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int16_t)10), "000a");
25
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int16_t)0), "0000");
26
+}
27
+
28
+TEST(StringUtils, rawToHumanInt)
29
+{
30
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)4294967295), "ffffffff");
31
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)4294967294), "fffffffe");
32
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)65536), "00010000");
33
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)65535), "0000ffff");
34
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)65534), "0000fffe");
35
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)256), "00000100");
36
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)255), "000000ff");
37
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)127), "0000007f");
38
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)10), "0000000a");
39
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int32_t)0), "00000000");
40
+}
41
+
42
+TEST(StringUtils, rawToHumanLong)
43
+{
44
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)std::numeric_limits<unsigned long>::max()), "ffffffffffffffff");
45
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)std::numeric_limits<unsigned long>::max() - 1), "fffffffffffffffe");
46
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)4294967296), "0000000100000000");
47
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)4294967295), "00000000ffffffff");
48
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)4294967294), "00000000fffffffe");
49
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)65536), "0000000000010000");
50
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)65535), "000000000000ffff");
51
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)65534), "000000000000fffe");
52
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)256), "0000000000000100");
53
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)255), "00000000000000ff");
54
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)127), "000000000000007f");
55
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)10), "000000000000000a");
56
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman((int64_t)0), "0000000000000000");
57
+}
58
+
59
+TEST(StringUtils, rawToHumanString)
60
+{
61
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rawToHuman(std::string({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
62
+                                                0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f})),
63
+            "000102030405060708090a0b0c0d0e0f");
64
+}
65
+
66
+TEST(StringUtils, toLower)
67
+{
68
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toLower('a'), 'a');
69
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toLower('z'), 'z');
70
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toLower('A'), 'a');
71
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toLower('Z'), 'z');
72
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toLower('1'), '1');
73
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toLower('@'), '@');
74
+}
75
+
76
+TEST(StringUtils, toUpper)
77
+{
78
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toUpper('a'), 'A');
79
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toUpper('z'), 'Z');
80
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toUpper('A'), 'A');
81
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toUpper('Z'), 'Z');
82
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toUpper('1'), '1');
83
+  ASSERT_EQ(LibNfc::Utils::StringUtils::toUpper('@'), '@');
84
+}
85
+
86
+TEST(StringUtils, humanToRaw)
87
+{
88
+  ASSERT_EQ(LibNfc::Utils::StringUtils::humanToRaw("0f00").getData(), std::string({0x0f, 0x00}));
89
+  ASSERT_EQ(LibNfc::Utils::StringUtils::humanToRaw("000f").getData(), std::string({0x00, 0x0f}));
90
+  ASSERT_EQ(LibNfc::Utils::StringUtils::humanToRaw("0a0a").getData(), std::string({0x0a, 0x0a}));
91
+  ASSERT_EQ(LibNfc::Utils::StringUtils::humanToRaw("1a0f").getData(), std::string({0x1a, 0x0f}));
92
+  ASSERT_EQ(LibNfc::Utils::StringUtils::humanToRaw("1a00f").getError(), "Malformed hex data: invalid length");
93
+  ASSERT_EQ(LibNfc::Utils::StringUtils::humanToRaw("1a\n00f").getError(), "Malformed hex data at char 2");
94
+}
95
+
96
+TEST(StringUtils, ensureSize)
97
+{
98
+  ASSERT_EQ(LibNfc::Utils::StringUtils::ensureSize("test", 3), "tes");
99
+  ASSERT_EQ(LibNfc::Utils::StringUtils::ensureSize("test", 4), "test");
100
+  ASSERT_EQ(LibNfc::Utils::StringUtils::ensureSize("test", 5), std::string({'t', 'e', 's', 't', '\0'}));
101
+}
102
+
103
+TEST(StringUtils, ltrim)
104
+{
105
+  ASSERT_EQ(LibNfc::Utils::StringUtils::ltrim("  \n 42"), "42");
106
+  ASSERT_EQ(LibNfc::Utils::StringUtils::ltrim("  \n 42 \n"), "42 \n");
107
+  ASSERT_EQ(LibNfc::Utils::StringUtils::ltrim("42  \n "), "42  \n ");
108
+  ASSERT_EQ(LibNfc::Utils::StringUtils::ltrim(" 42 \n 42  \n "), "42 \n 42  \n ");
109
+}
110
+
111
+TEST(StringUtils, rtrim)
112
+{
113
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rtrim("  \n 42"), "  \n 42");
114
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rtrim("  \n 42 \n"), "  \n 42");
115
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rtrim("42  \n "), "42");
116
+  ASSERT_EQ(LibNfc::Utils::StringUtils::rtrim(" 42 \n 42  \n "), " 42 \n 42");
117
+}
118
+
119
+TEST(StringUtils, trim)
120
+{
121
+  ASSERT_EQ(LibNfc::Utils::StringUtils::trim("  \n 42"), "42");
122
+  ASSERT_EQ(LibNfc::Utils::StringUtils::trim("  \n 42 \n"), "42");
123
+  ASSERT_EQ(LibNfc::Utils::StringUtils::trim("42  \n "), "42");
124
+  ASSERT_EQ(LibNfc::Utils::StringUtils::trim(" 42 \n 42  \n "), "42 \n 42");
125
+}
126
+
127
+TEST(StringUtils, removeSpaces)
128
+{
129
+  ASSERT_EQ(LibNfc::Utils::StringUtils::removeSpaces("  \n 42"), "42");
130
+  ASSERT_EQ(LibNfc::Utils::StringUtils::removeSpaces("  \n 42 \n"), "42");
131
+  ASSERT_EQ(LibNfc::Utils::StringUtils::removeSpaces("42  \n "), "42");
132
+  ASSERT_EQ(LibNfc::Utils::StringUtils::removeSpaces(" 42 \n 42  \n "), "4242");
133
+}
134
+
135
+TEST(ArrayUtils, getArrayBitimple)
136
+{
137
+  const unsigned char buf[] = {0x04};
138
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 0));
139
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 1));
140
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 2));
141
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 3));
142
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 4));
143
+  ASSERT_TRUE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 5));
144
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 6));
145
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 7));
146
+}
147
+
148
+TEST(ArrayUtils, getArrayBitMultiple)
149
+{
150
+  const unsigned char buf[] = {0x80, 0x14, 0x01};
151
+  ASSERT_TRUE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 0));
152
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 1));
153
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 2));
154
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 3));
155
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 4));
156
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 5));
157
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 6));
158
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 7));
159
+
160
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 8));
161
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 9));
162
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 10));
163
+  ASSERT_TRUE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 11));
164
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 12));
165
+  ASSERT_TRUE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 13));
166
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 14));
167
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 15));
168
+
169
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 16));
170
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 17));
171
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 18));
172
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 19));
173
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 20));
174
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 21));
175
+  ASSERT_FALSE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 22));
176
+  ASSERT_TRUE(LibNfc::Utils::ArrayUtils::getArrayBit(buf, 23));
177
+}
178
+
179
+TEST(AccessBitsDbo, getBit)
180
+{
181
+  const unsigned char buf[4] = {0x05, 0xa3, 0xcf, 0x00};
182
+  LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
183
+
184
+  ASSERT_FALSE(dbo.getBit(1, 0));
185
+  ASSERT_TRUE(dbo.getBit(2, 0));
186
+  ASSERT_FALSE(dbo.getBit(3, 0));
187
+
188
+  ASSERT_TRUE(dbo.getBit(1, 1));
189
+  ASSERT_TRUE(dbo.getBit(2, 1));
190
+  ASSERT_FALSE(dbo.getBit(3, 1));
191
+
192
+  ASSERT_FALSE(dbo.getBit(1, 2));
193
+  ASSERT_TRUE(dbo.getBit(2, 2));
194
+  ASSERT_TRUE(dbo.getBit(3, 2));
195
+
196
+  ASSERT_TRUE(dbo.getBit(1, 3));
197
+  ASSERT_TRUE(dbo.getBit(2, 3));
198
+  ASSERT_TRUE(dbo.getBit(3, 3));
199
+}
200
+
201
+TEST(AccessBitsDbo, canKeyDoThisOnThisBlock1)
202
+{
203
+  const unsigned char buf[4] = {0xff, 0x0f, 0x00, 0x00};
204
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
205
+
206
+  ASSERT_TRUE(dbo.canKeyAReadBlock(0));
207
+  ASSERT_TRUE(dbo.canKeyBReadBlock(0));
208
+
209
+  ASSERT_TRUE(dbo.canKeyAWriteBlock(0));
210
+  ASSERT_TRUE(dbo.canKeyBWriteBlock(0));
211
+
212
+  ASSERT_TRUE(dbo.canKeyAIncrementBlock(0));
213
+  ASSERT_TRUE(dbo.canKeyBIncrementBlock(0));
214
+
215
+  ASSERT_TRUE(dbo.canKeyADecrementBlock(0));
216
+  ASSERT_TRUE(dbo.canKeyBDecrementBlock(0));
217
+}
218
+
219
+TEST(AccessBitsDbo, canKeyDoThisOnThisBlock2)
220
+{
221
+  const unsigned char buf[4] = {0xef, 0x0f, 0x01, 0x00};
222
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
223
+
224
+  ASSERT_TRUE(dbo.canKeyAReadBlock(0));
225
+  ASSERT_TRUE(dbo.canKeyBReadBlock(0));
226
+
227
+  ASSERT_FALSE(dbo.canKeyAWriteBlock(0));
228
+  ASSERT_FALSE(dbo.canKeyBWriteBlock(0));
229
+
230
+  ASSERT_FALSE(dbo.canKeyAIncrementBlock(0));
231
+  ASSERT_FALSE(dbo.canKeyBIncrementBlock(0));
232
+
233
+  ASSERT_FALSE(dbo.canKeyADecrementBlock(0));
234
+  ASSERT_FALSE(dbo.canKeyBDecrementBlock(0));
235
+}
236
+
237
+TEST(AccessBitsDbo, canKeyDoThisOnThisBlock3)
238
+{
239
+  const unsigned char buf[4] = {0xfe, 0x1f, 0x00, 0x00};
240
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
241
+
242
+  ASSERT_TRUE(dbo.canKeyAReadBlock(0));
243
+  ASSERT_TRUE(dbo.canKeyBReadBlock(0));
244
+
245
+  ASSERT_FALSE(dbo.canKeyAWriteBlock(0));
246
+  ASSERT_TRUE(dbo.canKeyBWriteBlock(0));
247
+
248
+  ASSERT_FALSE(dbo.canKeyAIncrementBlock(0));
249
+  ASSERT_FALSE(dbo.canKeyBIncrementBlock(0));
250
+
251
+  ASSERT_FALSE(dbo.canKeyADecrementBlock(0));
252
+  ASSERT_FALSE(dbo.canKeyBDecrementBlock(0));
253
+}
254
+
255
+TEST(AccessBitsDbo, canKeyDoThisOnThisBlock4)
256
+{
257
+  const unsigned char buf[4] = {0xee, 0x1f, 0x01, 0x00};
258
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
259
+
260
+  ASSERT_TRUE(dbo.canKeyAReadBlock(0));
261
+  ASSERT_TRUE(dbo.canKeyBReadBlock(0));
262
+
263
+  ASSERT_FALSE(dbo.canKeyAWriteBlock(0));
264
+  ASSERT_TRUE(dbo.canKeyBWriteBlock(0));
265
+
266
+  ASSERT_FALSE(dbo.canKeyAIncrementBlock(0));
267
+  ASSERT_TRUE(dbo.canKeyBIncrementBlock(0));
268
+
269
+  ASSERT_TRUE(dbo.canKeyADecrementBlock(0));
270
+  ASSERT_TRUE(dbo.canKeyBDecrementBlock(0));
271
+}
272
+
273
+TEST(AccessBitsDbo, canKeyDoThisOnThisBlock5)
274
+{
275
+  const unsigned char buf[4] = {0xff, 0x0e, 0x10, 0x00};
276
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
277
+
278
+  ASSERT_TRUE(dbo.canKeyAReadBlock(0));
279
+  ASSERT_TRUE(dbo.canKeyBReadBlock(0));
280
+
281
+  ASSERT_FALSE(dbo.canKeyAWriteBlock(0));
282
+  ASSERT_FALSE(dbo.canKeyBWriteBlock(0));
283
+
284
+  ASSERT_FALSE(dbo.canKeyAIncrementBlock(0));
285
+  ASSERT_FALSE(dbo.canKeyBIncrementBlock(0));
286
+
287
+  ASSERT_TRUE(dbo.canKeyADecrementBlock(0));
288
+  ASSERT_TRUE(dbo.canKeyBDecrementBlock(0));
289
+}
290
+
291
+TEST(AccessBitsDbo, canKeyDoThisOnThisBlock6)
292
+{
293
+  const unsigned char buf[4] = {0xef, 0x0e, 0x11, 0x00};
294
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
295
+
296
+  ASSERT_FALSE(dbo.canKeyAReadBlock(0));
297
+  ASSERT_TRUE(dbo.canKeyBReadBlock(0));
298
+
299
+  ASSERT_FALSE(dbo.canKeyAWriteBlock(0));
300
+  ASSERT_TRUE(dbo.canKeyBWriteBlock(0));
301
+
302
+  ASSERT_FALSE(dbo.canKeyAIncrementBlock(0));
303
+  ASSERT_FALSE(dbo.canKeyBIncrementBlock(0));
304
+
305
+  ASSERT_FALSE(dbo.canKeyADecrementBlock(0));
306
+  ASSERT_FALSE(dbo.canKeyBDecrementBlock(0));
307
+}
308
+
309
+TEST(AccessBitsDbo, canKeyDoThisOnThisBlock7)
310
+{
311
+  const unsigned char buf[4] = {0xfe, 0x1e, 0x10, 0x00};
312
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
313
+
314
+  ASSERT_FALSE(dbo.canKeyAReadBlock(0));
315
+  ASSERT_TRUE(dbo.canKeyBReadBlock(0));
316
+
317
+  ASSERT_FALSE(dbo.canKeyAWriteBlock(0));
318
+  ASSERT_FALSE(dbo.canKeyBWriteBlock(0));
319
+
320
+  ASSERT_FALSE(dbo.canKeyAIncrementBlock(0));
321
+  ASSERT_FALSE(dbo.canKeyBIncrementBlock(0));
322
+
323
+  ASSERT_FALSE(dbo.canKeyADecrementBlock(0));
324
+  ASSERT_FALSE(dbo.canKeyBDecrementBlock(0));
325
+}
326
+
327
+TEST(AccessBitsDbo, canKeyDoThisOnThisBlock8)
328
+{
329
+  const unsigned char buf[4] = {0xee, 0x1e, 0x11, 0x00};
330
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
331
+
332
+  ASSERT_FALSE(dbo.canKeyAReadBlock(0));
333
+  ASSERT_FALSE(dbo.canKeyBReadBlock(0));
334
+
335
+  ASSERT_FALSE(dbo.canKeyAWriteBlock(0));
336
+  ASSERT_FALSE(dbo.canKeyBWriteBlock(0));
337
+
338
+  ASSERT_FALSE(dbo.canKeyAIncrementBlock(0));
339
+  ASSERT_FALSE(dbo.canKeyBIncrementBlock(0));
340
+
341
+  ASSERT_FALSE(dbo.canKeyADecrementBlock(0));
342
+  ASSERT_FALSE(dbo.canKeyBDecrementBlock(0));
343
+}
344
+
345
+TEST(AccessBitsDbo, canKeyDoThisOnThisTrailer1)
346
+{
347
+  const unsigned char buf[4] = {0xff, 0x0f, 0x00, 0x00};
348
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
349
+
350
+  ASSERT_FALSE(dbo.canKeyAReadKeyATrailer());
351
+  ASSERT_FALSE(dbo.canKeyBReadKeyATrailer());
352
+
353
+  ASSERT_TRUE(dbo.canKeyAWriteKeyATrailer());
354
+  ASSERT_FALSE(dbo.canKeyBWriteKeyATrailer());
355
+
356
+  ASSERT_TRUE(dbo.canKeyAReadAccessBitsTrailer());
357
+  ASSERT_FALSE(dbo.canKeyBReadAccessBitsTrailer());
358
+
359
+  ASSERT_FALSE(dbo.canKeyAWriteAccessBitsTrailer());
360
+  ASSERT_FALSE(dbo.canKeyBWriteAccessBitsTrailer());
361
+
362
+  ASSERT_TRUE(dbo.canKeyAReadKeyBTrailer());
363
+  ASSERT_FALSE(dbo.canKeyBReadKeyBTrailer());
364
+
365
+  ASSERT_TRUE(dbo.canKeyAWriteKeyBTrailer());
366
+  ASSERT_FALSE(dbo.canKeyBWriteKeyBTrailer());
367
+}
368
+
369
+TEST(AccessBitsDbo, canKeyDoThisOnThisTrailer2)
370
+{
371
+  const unsigned char buf[4] = {0x7f, 0x0f, 0x08, 0x00};
372
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
373
+
374
+  ASSERT_FALSE(dbo.canKeyAReadKeyATrailer());
375
+  ASSERT_FALSE(dbo.canKeyBReadKeyATrailer());
376
+
377
+  ASSERT_FALSE(dbo.canKeyAWriteKeyATrailer());
378
+  ASSERT_FALSE(dbo.canKeyBWriteKeyATrailer());
379
+
380
+  ASSERT_TRUE(dbo.canKeyAReadAccessBitsTrailer());
381
+  ASSERT_FALSE(dbo.canKeyBReadAccessBitsTrailer());
382
+
383
+  ASSERT_FALSE(dbo.canKeyAWriteAccessBitsTrailer());
384
+  ASSERT_FALSE(dbo.canKeyBWriteAccessBitsTrailer());
385
+
386
+  ASSERT_TRUE(dbo.canKeyAReadKeyBTrailer());
387
+  ASSERT_FALSE(dbo.canKeyBReadKeyBTrailer());
388
+
389
+  ASSERT_FALSE(dbo.canKeyAWriteKeyBTrailer());
390
+  ASSERT_FALSE(dbo.canKeyBWriteKeyBTrailer());
391
+}
392
+
393
+TEST(AccessBitsDbo, canKeyDoThisOnThisTrailer3)
394
+{
395
+  const unsigned char buf[4] = {0xf7, 0x8f, 0x00, 0x00};
396
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
397
+
398
+  ASSERT_FALSE(dbo.canKeyAReadKeyATrailer());
399
+  ASSERT_FALSE(dbo.canKeyBReadKeyATrailer());
400
+
401
+  ASSERT_FALSE(dbo.canKeyAWriteKeyATrailer());
402
+  ASSERT_TRUE(dbo.canKeyBWriteKeyATrailer());
403
+
404
+  ASSERT_TRUE(dbo.canKeyAReadAccessBitsTrailer());
405
+  ASSERT_TRUE(dbo.canKeyBReadAccessBitsTrailer());
406
+
407
+  ASSERT_FALSE(dbo.canKeyAWriteAccessBitsTrailer());
408
+  ASSERT_FALSE(dbo.canKeyBWriteAccessBitsTrailer());
409
+
410
+  ASSERT_FALSE(dbo.canKeyAReadKeyBTrailer());
411
+  ASSERT_FALSE(dbo.canKeyBReadKeyBTrailer());
412
+
413
+  ASSERT_FALSE(dbo.canKeyAWriteKeyBTrailer());
414
+  ASSERT_TRUE(dbo.canKeyBWriteKeyBTrailer());
415
+}
416
+
417
+TEST(AccessBitsDbo, canKeyDoThisOnThisTrailer4)
418
+{
419
+  const unsigned char buf[4] = {0x77, 0x8f, 0x08, 0x00};
420
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
421
+
422
+  ASSERT_FALSE(dbo.canKeyAReadKeyATrailer());
423
+  ASSERT_FALSE(dbo.canKeyBReadKeyATrailer());
424
+
425
+  ASSERT_FALSE(dbo.canKeyAWriteKeyATrailer());
426
+  ASSERT_FALSE(dbo.canKeyBWriteKeyATrailer());
427
+
428
+  ASSERT_TRUE(dbo.canKeyAReadAccessBitsTrailer());
429
+  ASSERT_TRUE(dbo.canKeyBReadAccessBitsTrailer());
430
+
431
+  ASSERT_FALSE(dbo.canKeyAWriteAccessBitsTrailer());
432
+  ASSERT_FALSE(dbo.canKeyBWriteAccessBitsTrailer());
433
+
434
+  ASSERT_FALSE(dbo.canKeyAReadKeyBTrailer());
435
+  ASSERT_FALSE(dbo.canKeyBReadKeyBTrailer());
436
+
437
+  ASSERT_FALSE(dbo.canKeyAWriteKeyBTrailer());
438
+  ASSERT_FALSE(dbo.canKeyBWriteKeyBTrailer());
439
+}
440
+
441
+TEST(AccessBitsDbo, canKeyDoThisOnThisTrailer5)
442
+{
443
+  const unsigned char buf[4] = {0xff, 0x07, 0x80, 0x00};
444
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
445
+
446
+  ASSERT_FALSE(dbo.canKeyAReadKeyATrailer());
447
+  ASSERT_FALSE(dbo.canKeyBReadKeyATrailer());
448
+
449
+  ASSERT_TRUE(dbo.canKeyAWriteKeyATrailer());
450
+  ASSERT_FALSE(dbo.canKeyBWriteKeyATrailer());
451
+
452
+  ASSERT_TRUE(dbo.canKeyAReadAccessBitsTrailer());
453
+  ASSERT_FALSE(dbo.canKeyBReadAccessBitsTrailer());
454
+
455
+  ASSERT_TRUE(dbo.canKeyAWriteAccessBitsTrailer());
456
+  ASSERT_FALSE(dbo.canKeyBWriteAccessBitsTrailer());
457
+
458
+  ASSERT_TRUE(dbo.canKeyAReadKeyBTrailer());
459
+  ASSERT_FALSE(dbo.canKeyBReadKeyBTrailer());
460
+
461
+  ASSERT_TRUE(dbo.canKeyAWriteKeyBTrailer());
462
+  ASSERT_FALSE(dbo.canKeyBWriteKeyBTrailer());
463
+}
464
+
465
+TEST(AccessBitsDbo, canKeyDoThisOnThisTrailer6)
466
+{
467
+  const unsigned char buf[4] = {0x7f, 0x07, 0x88, 0x00};
468
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
469
+
470
+  ASSERT_FALSE(dbo.canKeyAReadKeyATrailer());
471
+  ASSERT_FALSE(dbo.canKeyBReadKeyATrailer());
472
+
473
+  ASSERT_FALSE(dbo.canKeyAWriteKeyATrailer());
474
+  ASSERT_TRUE(dbo.canKeyBWriteKeyATrailer());
475
+
476
+  ASSERT_TRUE(dbo.canKeyAReadAccessBitsTrailer());
477
+  ASSERT_TRUE(dbo.canKeyBReadAccessBitsTrailer());
478
+
479
+  ASSERT_FALSE(dbo.canKeyAWriteAccessBitsTrailer());
480
+  ASSERT_TRUE(dbo.canKeyBWriteAccessBitsTrailer());
481
+
482
+  ASSERT_FALSE(dbo.canKeyAReadKeyBTrailer());
483
+  ASSERT_FALSE(dbo.canKeyBReadKeyBTrailer());
484
+
485
+  ASSERT_FALSE(dbo.canKeyAWriteKeyBTrailer());
486
+  ASSERT_TRUE(dbo.canKeyBWriteKeyBTrailer());
487
+}
488
+
489
+TEST(AccessBitsDbo, canKeyDoThisOnThisTrailer7)
490
+{
491
+  const unsigned char buf[4] = {0xf7, 0x87, 0x80, 0x00};
492
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
493
+
494
+  ASSERT_FALSE(dbo.canKeyAReadKeyATrailer());
495
+  ASSERT_FALSE(dbo.canKeyBReadKeyATrailer());
496
+
497
+  ASSERT_FALSE(dbo.canKeyAWriteKeyATrailer());
498
+  ASSERT_FALSE(dbo.canKeyBWriteKeyATrailer());
499
+
500
+  ASSERT_TRUE(dbo.canKeyAReadAccessBitsTrailer());
501
+  ASSERT_TRUE(dbo.canKeyBReadAccessBitsTrailer());
502
+
503
+  ASSERT_FALSE(dbo.canKeyAWriteAccessBitsTrailer());
504
+  ASSERT_TRUE(dbo.canKeyBWriteAccessBitsTrailer());
505
+
506
+  ASSERT_FALSE(dbo.canKeyAReadKeyBTrailer());
507
+  ASSERT_FALSE(dbo.canKeyBReadKeyBTrailer());
508
+
509
+  ASSERT_FALSE(dbo.canKeyAWriteKeyBTrailer());
510
+  ASSERT_FALSE(dbo.canKeyBWriteKeyBTrailer());
511
+}
512
+
513
+TEST(AccessBitsDbo, canKeyDoThisOnThisTrailer8)
514
+{
515
+  const unsigned char buf[4] = {0x77, 0x87, 0x88, 0x00};
516
+    LibNfc::FreeFare::FreeFareAccessBits dbo((const char*)buf);
517
+
518
+  ASSERT_FALSE(dbo.canKeyAReadKeyATrailer());
519
+  ASSERT_FALSE(dbo.canKeyBReadKeyATrailer());
520
+
521
+  ASSERT_FALSE(dbo.canKeyAWriteKeyATrailer());
522
+  ASSERT_FALSE(dbo.canKeyBWriteKeyATrailer());
523
+
524
+  ASSERT_TRUE(dbo.canKeyAReadAccessBitsTrailer());
525
+  ASSERT_TRUE(dbo.canKeyBReadAccessBitsTrailer());
526
+
527
+  ASSERT_FALSE(dbo.canKeyAWriteAccessBitsTrailer());
528
+  ASSERT_FALSE(dbo.canKeyBWriteAccessBitsTrailer());
529
+
530
+  ASSERT_FALSE(dbo.canKeyAReadKeyBTrailer());
531
+  ASSERT_FALSE(dbo.canKeyBReadKeyBTrailer());
532
+
533
+  ASSERT_FALSE(dbo.canKeyAWriteKeyBTrailer());
534
+  ASSERT_FALSE(dbo.canKeyBWriteKeyBTrailer());
535
+}
536
+
537
+int main(int argc, char* argv[])
538
+{
539
+    std::cout << "LibNfc version: " << LibNfc::Core::LibNfcContext::getLibNfcVersion() << std::endl;
540
+    ::testing::InitGoogleTest(&argc, argv);
541
+    return RUN_ALL_TESTS();
542
+}

Loading…
Cancel
Save