瀏覽代碼

fixes; cli dump and map

develop
Robin Thoni 7 年之前
父節點
當前提交
58a7c27461

+ 63
- 28
cli/Interface/MainClass.cpp 查看文件

43
     for (size_t i = 0; i < devices.size(); ++i) {
43
     for (size_t i = 0; i < devices.size(); ++i) {
44
         std::cout << devices[i]->getConnStr() << std::endl;
44
         std::cout << devices[i]->getConnStr() << std::endl;
45
     }
45
     }
46
+    std::cout << "Using first device" << std::endl;
46
 
47
 
47
     auto device = devices[0];
48
     auto device = devices[0];
48
     auto open = device->open();
49
     auto open = device->open();
52
     }
53
     }
53
 
54
 
54
     FreeFareDeviceBusiness freeFareDevice(device);
55
     FreeFareDeviceBusiness freeFareDevice(device);
55
-    auto tags = freeFareDevice.getTags();
56
-    if (!tags) {
57
-        tags.print();
56
+    auto tagsResult = freeFareDevice.getTags();
57
+    if (!tagsResult) {
58
+        tagsResult.print();
58
         return 5;
59
         return 5;
59
     }
60
     }
60
 
61
 
61
-    std::cout << "Found " << tags.getData().size() << " tags:" << std::endl;
62
-    for (size_t i = 0; i < tags.getData().size(); ++i) {
63
-        auto tag = tags.getData()[i];
62
+    auto tags = tagsResult.getData();
63
+    if (tags.size() == 0) {
64
+        std::cerr << "No tag found" << std::endl;
65
+        return 6;
66
+    }
67
+
68
+    std::cout << "Found " << tagsResult.getData().size() << " tags:" << std::endl;
69
+    for (size_t i = 0; i < tagsResult.getData().size(); ++i) {
70
+        auto tag = tagsResult.getData()[i];
64
         std::cout << "UID: " << tag->getUid() << std::endl;
71
         std::cout << "UID: " << tag->getUid() << std::endl;
65
         std::cout << "Type: " << tag->getType() << std::endl;
72
         std::cout << "Type: " << tag->getType() << std::endl;
66
-        mapKeys(tag);
67
     }
73
     }
74
+    std::cout << "Using first tag" << std::endl;
75
+
76
+    auto tag = tags[0];
77
+
78
+    std::vector<std::string> keys;
79
+//    keys.push_back(StringUtils::humanToRaw("8829da9daf76").getData());
80
+//    keys.push_back(StringUtils::humanToRaw("ffffffffffff").getData());
81
+    keys.push_back(StringUtils::humanToRaw("484558414354").getData());
82
+
83
+    int res = dump(tag, keys); //mapKeys(tag);
68
 
84
 
69
     device->close();
85
     device->close();
70
     libNfc.clean();
86
     libNfc.clean();
71
 
87
 
72
-    return 0;
88
+    return res;
73
 }
89
 }
74
 
90
 
75
-int MainClass::mapKeys(std::shared_ptr<FreeFareTagBusiness> tag)
91
+int MainClass::mapKeys(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::string> keys)
76
 {
92
 {
77
-    std::vector<std::string> keys;
78
-    keys.push_back(StringUtils::humanToRaw("8829da9daf76").getData());
79
     auto mappedKeysResult = tag->mapKeys(keys);
93
     auto mappedKeysResult = tag->mapKeys(keys);
80
     if (!mappedKeysResult) {
94
     if (!mappedKeysResult) {
81
         mappedKeysResult.print();
95
         mappedKeysResult.print();
96
     return 0;
110
     return 0;
97
 }
111
 }
98
 
112
 
99
-int MainClass::dump(std::shared_ptr<FreeFareTagBusiness> tag)
113
+int MainClass::dump(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::string> keys)
100
 {
114
 {
101
-    for(int s = 0; s < 16; ++s)
102
-    {
115
+    auto dumpResult = tag->dump(keys);
116
+    if (!dumpResult) {
117
+        dumpResult.print();
118
+        return 7;
119
+    }
120
+    auto dump = dumpResult.getData();
121
+    for(int s = 0; s < 16; ++s) {
103
         std::cout << "+Sector: " << s << std::endl;
122
         std::cout << "+Sector: " << s << std::endl;
104
-        auto sectorResult = tag->readSector(s, StringUtils::humanToRaw("8829da9daf76").getData(), MFC_KEY_A);
105
-        if (!sectorResult)
106
-        {
107
-            sectorResult.print();
123
+        auto sector = dump[s];
124
+        for (int b = 0; b < 3; ++b) {
125
+            std::cout << (sector.hasBlock(b) ? StringUtils::rawToHuman(sector.getBlock(b)) : std::string(32, '-')) << std::endl;
108
         }
126
         }
109
-        else
110
-        {
111
-            auto sector = sectorResult.getData();
112
-            for (int b = 0; b < 3; ++b)
113
-            {
114
-                std::cout << StringUtils::rawToHuman(sector.getBlock(b)) << std::endl;
115
-            }
116
-            std::cout << StringUtils::rawToHuman(sector.getKeyA()) << " "
117
-            << StringUtils::rawToHuman(sector.getAccessBits()) << " "
118
-            << StringUtils::rawToHuman(sector.getKeyB()) << std::endl;
127
+        std::cout << (sector.hasKeyA() ? StringUtils::rawToHuman(sector.getKeyA()) : std::string(12, '-')) << " "
128
+            << (sector.hasAccessBits() ? StringUtils::rawToHuman(sector.getAccessBits()) : std::string(8, '-'))  << " "
129
+            << (sector.hasKeyB() ? StringUtils::rawToHuman(sector.getKeyB()) : std::string(12, '-')) << std::endl;
130
+        AccessBitsDbo accessBitsDbo = sector.getAccessBitsDbo();
131
+        for (int b = 0; b < 3; ++b) {
132
+            std::cout << "+Block: " << b << " ";
133
+            printBlockAccessBits(accessBitsDbo, b);
119
         }
134
         }
135
+        std::cout << "+Block: 4 ";
136
+        printTrailerAccessBits(accessBitsDbo);
120
     }
137
     }
121
     return 0;
138
     return 0;
122
 }
139
 }
123
 
140
 
141
+void MainClass::printBlockAccessBits(const AccessBitsDbo &accessBits, int block)
142
+{
143
+    std::cout << "read: " << (accessBits.canKeyAReadBlock(block) ? "A" : "") << (accessBits.canKeyBReadBlock(block) ? "B" : "");
144
+    std::cout << " write: " << (accessBits.canKeyAWriteBlock(block) ? "A" : "") << (accessBits.canKeyBWriteBlock(block) ? "B" : "");
145
+    std::cout << " increment: " << (accessBits.canKeyAIncrementBlock(block) ? "A" : "") << (accessBits.canKeyBIncrementBlock(block) ? "B" : "");
146
+    std::cout << " decrement: " << (accessBits.canKeyADecrementBlock(block) ? "A" : "") << (accessBits.canKeyBDecrementBlock(block) ? "B" : "") << std::endl;
147
+}
148
+
149
+void MainClass::printTrailerAccessBits(const AccessBitsDbo &accessBits)
150
+{
151
+    std::cout << "key A read: " << (accessBits.canKeyAReadKeyATrailer() ? "A" : "") << (accessBits.canKeyBReadKeyATrailer() ? "B" : "");
152
+    std::cout << " key A write: " << (accessBits.canKeyAWriteKeyATrailer() ? "A" : "") << (accessBits.canKeyBWriteKeyATrailer() ? "B" : "");
153
+
154
+    std::cout << " AC bits read: " << (accessBits.canKeyAReadAccessBitsTrailer() ? "A" : "") << (accessBits.canKeyBReadAccessBitsTrailer() ? "B" : "");
155
+    std::cout << " AC bits write: " << (accessBits.canKeyAWriteAccessBitsTrailer() ? "A" : "") << (accessBits.canKeyBWriteAccessBitsTrailer() ? "B" : "");
124
 
156
 
157
+    std::cout << " key B read: " << (accessBits.canKeyAReadKeyBTrailer() ? "A" : "") << (accessBits.canKeyBReadKeyBTrailer() ? "B" : "");
158
+    std::cout << " key B write: " << (accessBits.canKeyAWriteKeyBTrailer() ? "A" : "") << (accessBits.canKeyBWriteKeyBTrailer() ? "B" : "") << std::endl;;
159
+}

+ 6
- 2
cli/Interface/MainClass.h 查看文件

14
 
14
 
15
     int main();
15
     int main();
16
 
16
 
17
-    int mapKeys(std::shared_ptr<FreeFareTagBusiness> tag);
17
+    int mapKeys(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::string> keys);
18
 
18
 
19
-    int dump(std::shared_ptr<FreeFareTagBusiness> tag);
19
+    int dump(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::string> keys);
20
+
21
+    void printBlockAccessBits(const AccessBitsDbo& accessBits, int block);
22
+
23
+    void printTrailerAccessBits(const AccessBitsDbo& accessBits);
20
 
24
 
21
 private:
25
 private:
22
     int _argc;
26
     int _argc;

+ 90
- 7
src/Business/FreeFareTagBusiness.cpp 查看文件

32
             return Result<SectorDbo>::error(data);
32
             return Result<SectorDbo>::error(data);
33
         }
33
         }
34
     }
34
     }
35
-    return SectorDbo::parse(res);
35
+    return Result<SectorDbo>::ok(SectorDbo(res));
36
 }
36
 }
37
 
37
 
38
 const std::string &FreeFareTagBusiness::getUid() const
38
 const std::string &FreeFareTagBusiness::getUid() const
50
     return _tag;
50
     return _tag;
51
 }
51
 }
52
 
52
 
53
-Result<std::vector<std::vector<std::pair<std::string, std::string>>>> FreeFareTagBusiness::mapKeys(std::vector<std::string> keys)
53
+Result<MappedKeys> FreeFareTagBusiness::mapKeys(std::vector<std::string> keys)
54
 {
54
 {
55
     std::vector<std::vector<std::pair<std::string, std::string>>> mappedKeys;
55
     std::vector<std::vector<std::pair<std::string, std::string>>> mappedKeys;
56
 
56
 
59
         for (int j = 0; j < 4; ++j) {
59
         for (int j = 0; j < 4; ++j) {
60
             std::pair<std::string, std::string> blockKeys;
60
             std::pair<std::string, std::string> blockKeys;
61
             for (auto key : keys) {
61
             for (auto key : keys) {
62
-                auto res = authenticate(i, j, key, MFC_KEY_A);
63
-                if (res) {
62
+                if (authenticate(i, j, key, MFC_KEY_A)) {
64
                     blockKeys.first = key;
63
                     blockKeys.first = key;
65
                 }
64
                 }
66
-                res = authenticate(i, j, key, MFC_KEY_B);
67
-                if (res) {
65
+                if (authenticate(i, j, key, MFC_KEY_B)) {
68
                     blockKeys.second = key;
66
                     blockKeys.second = key;
69
                 }
67
                 }
68
+                if (!blockKeys.first.empty() && !blockKeys.second.empty()) {
69
+                    break;
70
+                }
70
             }
71
             }
71
             sectorKeys.push_back(blockKeys);
72
             sectorKeys.push_back(blockKeys);
72
         }
73
         }
74
     }
75
     }
75
 
76
 
76
     return Result<std::vector<std::vector<std::pair<std::string, std::string>>>>::ok(mappedKeys);
77
     return Result<std::vector<std::vector<std::pair<std::string, std::string>>>>::ok(mappedKeys);
77
-}
78
+}
79
+
80
+Result<std::vector<SectorDbo>> FreeFareTagBusiness::dump(MappedKeys keys)
81
+{
82
+    if (keys.size() != 16) {
83
+        return Result<std::vector<SectorDbo>>::error("Must have 16 sectors");
84
+    }
85
+    for (int i = 0; i < keys.size(); ++i) {
86
+        auto key = keys[i];
87
+        if (key.size() != 4) {
88
+            return Result<std::vector<SectorDbo>>::error("Must have 4 keys in sector " + i);
89
+        }
90
+    }
91
+    std::vector<SectorDbo> sectors;
92
+    for (int s = 0; s < keys.size(); ++s) {
93
+        auto sectorKeys = keys[s];
94
+        SectorDbo sector;
95
+        bool keyA = false;
96
+        bool keyB = false;
97
+        for (int b = 0; b < sectorKeys.size() - 1; ++b) {
98
+            auto blockKey = sectorKeys[b];
99
+            std::string data = "";
100
+            if (!blockKey.first.empty()) {
101
+                auto blockResult = readBlock(s, b, blockKey.first, MFC_KEY_A);
102
+                if (blockResult) {
103
+                    data = blockResult.getData();
104
+                    keyA = true;
105
+                }
106
+            }
107
+            if (!blockKey.second.empty()) {
108
+                auto blockResult = readBlock(s, b, blockKey.second, MFC_KEY_B);
109
+                if (blockResult) {
110
+                    data = blockResult.getData();
111
+                    keyB = true;
112
+                }
113
+            }
114
+            sector.setBlock(b, data);
115
+        }
116
+        int b = sectorKeys.size() - 1;
117
+        auto blockKey = sectorKeys[b];
118
+        std::string data = "";
119
+        if (!blockKey.first.empty()) {
120
+            auto blockResult = readBlock(s, b, blockKey.first, MFC_KEY_A);
121
+            if (blockResult) {
122
+                data = blockResult.getData();
123
+                keyA = true;
124
+            }
125
+        }
126
+        if (!blockKey.second.empty()) {
127
+            auto blockResult = readBlock(s, b, blockKey.second, MFC_KEY_B);
128
+            if (blockResult) {
129
+                data = blockResult.getData();
130
+                keyB = true;
131
+            }
132
+        }
133
+        sector.setBlock(b, data);
134
+        AccessBitsDbo accessBitsDbo = sector.getAccessBitsDbo();
135
+
136
+        sector.setKeyA(keyA ? blockKey.first : "");
137
+        sector.setKeyB(keyB ? blockKey.second : "");
138
+        std::string accessBits;
139
+        if (!data.empty())
140
+        {
141
+            if ((keyA && accessBitsDbo.canKeyAReadAccessBitsTrailer()) || (keyB && accessBitsDbo.canKeyBReadAccessBitsTrailer())) {
142
+                accessBits = accessBitsDbo.getBits();
143
+            }
144
+        }
145
+        sector.setAccessBits(accessBits);
146
+
147
+        sectors.push_back(sector);
148
+    }
149
+
150
+    return Result<std::vector<SectorDbo>>::ok(sectors);
151
+}
152
+
153
+Result<std::vector<SectorDbo>> FreeFareTagBusiness::dump(std::vector<std::string> keys)
154
+{
155
+    auto mappedKeysResult = mapKeys(keys);
156
+    if (!mappedKeysResult) {
157
+        return Result<std::vector<SectorDbo>>::error(mappedKeysResult);
158
+    }
159
+    return dump(mappedKeysResult.getData());
160
+}

+ 7
- 1
src/Business/FreeFareTagBusiness.h 查看文件

10
 #include <DataAccess/FreeFareTag.h>
10
 #include <DataAccess/FreeFareTag.h>
11
 #include <DataAccess/SectorDbo.h>
11
 #include <DataAccess/SectorDbo.h>
12
 
12
 
13
+typedef std::vector<std::vector<std::pair<std::string, std::string>>> MappedKeys;
14
+
13
 class FreeFareTagBusiness
15
 class FreeFareTagBusiness
14
 {
16
 {
15
 public:
17
 public:
21
 
23
 
22
     Result<SectorDbo> readSector(int sector, std::string key, int keyType);
24
     Result<SectorDbo> readSector(int sector, std::string key, int keyType);
23
 
25
 
24
-    Result<std::vector<std::vector<std::pair<std::string, std::string>>>> mapKeys(std::vector<std::string> keys);
26
+    Result<MappedKeys> mapKeys(std::vector<std::string> keys);
27
+
28
+    Result<std::vector<SectorDbo>> dump(MappedKeys keys);
29
+
30
+    Result<std::vector<SectorDbo>> dump(std::vector<std::string> keys);
25
 
31
 
26
     const std::string& getUid() const;
32
     const std::string& getUid() const;
27
 
33
 

+ 1
- 1
src/CMakeLists.txt 查看文件

11
         DataAccess/FreeFareDevice.h
11
         DataAccess/FreeFareDevice.h
12
         DataAccess/FreeFareTag.cpp
12
         DataAccess/FreeFareTag.cpp
13
         DataAccess/FreeFareTag.h
13
         DataAccess/FreeFareTag.h
14
-        DBO/StringUtils.cpp DBO/StringUtils.h DBO/AccessBitsDbo.cpp DBO/AccessBitsDbo.h Business/LibNfcBusiness.cpp Business/LibNfcBusiness.h Business/NfcDeviceBusiness.cpp Business/NfcDeviceBusiness.h Business/FreeFareDeviceBusiness.cpp Business/FreeFareDeviceBusiness.h Business/FreeFareTagBusiness.cpp Business/FreeFareTagBusiness.h DataAccess/SectorDbo.cpp DataAccess/SectorDbo.h)
14
+        DBO/StringUtils.cpp DBO/StringUtils.h DBO/AccessBitsDbo.cpp DBO/AccessBitsDbo.h Business/LibNfcBusiness.cpp Business/LibNfcBusiness.h Business/NfcDeviceBusiness.cpp Business/NfcDeviceBusiness.h Business/FreeFareDeviceBusiness.cpp Business/FreeFareDeviceBusiness.h Business/FreeFareTagBusiness.cpp Business/FreeFareTagBusiness.h DataAccess/SectorDbo.cpp DataAccess/SectorDbo.h DBO/ArrayUtils.cpp DBO/ArrayUtils.h)
15
 
15
 
16
 add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
16
 add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
17
 target_link_libraries(${PROJECT_NAME} ${LIBS})
17
 target_link_libraries(${PROJECT_NAME} ${LIBS})

+ 18
- 42
src/DBO/AccessBitsDbo.cpp 查看文件

5
 #include <cstring>
5
 #include <cstring>
6
 #include <iostream>
6
 #include <iostream>
7
 #include "AccessBitsDbo.h"
7
 #include "AccessBitsDbo.h"
8
+#include "StringUtils.h"
9
+#include "ArrayUtils.h"
8
 
10
 
9
 const char AccessBitsDbo::nonInvertedBitPosition[4][4] = {
11
 const char AccessBitsDbo::nonInvertedBitPosition[4][4] = {
10
         {0,  0,  0,  0 },
12
         {0,  0,  0,  0 },
24
 }
26
 }
25
 
27
 
26
 AccessBitsDbo::AccessBitsDbo(const std::string &bits)
28
 AccessBitsDbo::AccessBitsDbo(const std::string &bits)
27
-    : _bits(bits.substr(0, 4))
29
+    : _bits(StringUtils::ensureSize(bits, 4))
28
 {
30
 {
29
 }
31
 }
30
 
32
 
38
     _bits[_bits.length() - 1] = data;
40
     _bits[_bits.length() - 1] = data;
39
 }
41
 }
40
 
42
 
41
-void AccessBitsDbo::setBit(const char& i, const char& j, const bool& value)
43
+void AccessBitsDbo::setBit(int i, int j, const bool& value)
42
 {
44
 {
43
     char buf[_bits.length()];
45
     char buf[_bits.length()];
44
     memcpy(buf, _bits.c_str(), _bits.length());
46
     memcpy(buf, _bits.c_str(), _bits.length());
45
 
47
 
46
-    setArrayBit(buf, nonInvertedBitPosition[i][j], value);
47
-    setArrayBit(buf, invertedBitPosition[i][j], !value);
48
+    ArrayUtils::setArrayBit(buf, nonInvertedBitPosition[i][j], value);
49
+    ArrayUtils::setArrayBit(buf, invertedBitPosition[i][j], !value);
48
 
50
 
49
     _bits = std::string(buf, _bits.length());
51
     _bits = std::string(buf, _bits.length());
50
 }
52
 }
51
 
53
 
52
-void AccessBitsDbo::setArrayBit(char *buf, const char &bitPosition, const bool &value)
53
-{
54
-    char byteOffset = (char)(bitPosition / 8);
55
-    char bitOffset = (char)(7 - (bitPosition % 8));
56
-    if(value)
57
-    {
58
-        buf[byteOffset] |=  (1 << bitOffset);
59
-    }
60
-    else
61
-    {
62
-        buf[byteOffset] &= ~(1 << bitOffset);
63
-    }
64
-}
65
-
66
-void AccessBitsDbo::setArrayBit(unsigned char *buf, const char &bitPosition, const bool &value)
67
-{
68
-    setArrayBit((char*)buf, bitPosition, value);
69
-}
70
-
71
-bool AccessBitsDbo::getBit(const char &i, const char &j) const
54
+bool AccessBitsDbo::getBit(int i, int j) const
72
 {
55
 {
73
     const char* buf = _bits.c_str();
56
     const char* buf = _bits.c_str();
74
-    return getArrayBit(buf, nonInvertedBitPosition[i][j]) && !getArrayBit(buf, invertedBitPosition[i][j]);
75
-}
76
-
77
-bool AccessBitsDbo::getArrayBit(const char *buf, const char &bitPosition)
78
-{
79
-    char byteOffset = (char)(bitPosition / 8);
80
-    char bitOffset = (char)(7 - (bitPosition % 8));
81
-    return (buf[byteOffset] >> bitOffset) & 1 == 1;
57
+    return ArrayUtils::getArrayBit(buf, nonInvertedBitPosition[i][j]) && !ArrayUtils::getArrayBit(buf, invertedBitPosition[i][j]);
82
 }
58
 }
83
 
59
 
84
-bool AccessBitsDbo::getArrayBit(const unsigned char *buf, const char &bitPosition)
60
+std::string AccessBitsDbo::getBits() const
85
 {
61
 {
86
-    return getArrayBit((const char *)buf, bitPosition);
62
+    return _bits;
87
 }
63
 }
88
 
64
 
89
-bool AccessBitsDbo::canKeyAReadBlock(const char &block) const
65
+bool AccessBitsDbo::canKeyAReadBlock(int block) const
90
 {
66
 {
91
     bool c1 = getBit(1, block);
67
     bool c1 = getBit(1, block);
92
     bool c2 = getBit(2, block);
68
     bool c2 = getBit(2, block);
94
     return !c3 || (!c1 && !c2 && c3);
70
     return !c3 || (!c1 && !c2 && c3);
95
 }
71
 }
96
 
72
 
97
-bool AccessBitsDbo::canKeyBReadBlock(const char &block) const
73
+bool AccessBitsDbo::canKeyBReadBlock(int block) const
98
 {
74
 {
99
     bool c1 = getBit(1, block);
75
     bool c1 = getBit(1, block);
100
     bool c2 = getBit(2, block);
76
     bool c2 = getBit(2, block);
102
     return !c1 || !c2 || !c3;
78
     return !c1 || !c2 || !c3;
103
 }
79
 }
104
 
80
 
105
-bool AccessBitsDbo::canKeyAWriteBlock(const char &block) const
81
+bool AccessBitsDbo::canKeyAWriteBlock(int block) const
106
 {
82
 {
107
     bool c1 = getBit(1, block);
83
     bool c1 = getBit(1, block);
108
     bool c2 = getBit(2, block);
84
     bool c2 = getBit(2, block);
110
     return !c1 && !c2 && !c3;
86
     return !c1 && !c2 && !c3;
111
 }
87
 }
112
 
88
 
113
-bool AccessBitsDbo::canKeyBWriteBlock(const char &block) const
89
+bool AccessBitsDbo::canKeyBWriteBlock(int block) const
114
 {
90
 {
115
     bool c1 = getBit(1, block);
91
     bool c1 = getBit(1, block);
116
     bool c2 = getBit(2, block);
92
     bool c2 = getBit(2, block);
118
     return (!c2 && !c3) || (c1 && !c3) || (!c1 && c2 && c3);
94
     return (!c2 && !c3) || (c1 && !c3) || (!c1 && c2 && c3);
119
 }
95
 }
120
 
96
 
121
-bool AccessBitsDbo::canKeyAIncrementBlock(const char &block) const
97
+bool AccessBitsDbo::canKeyAIncrementBlock(int block) const
122
 {
98
 {
123
     bool c1 = getBit(1, block);
99
     bool c1 = getBit(1, block);
124
     bool c2 = getBit(2, block);
100
     bool c2 = getBit(2, block);
126
     return !c1 && !c2 && !c3;
102
     return !c1 && !c2 && !c3;
127
 }
103
 }
128
 
104
 
129
-bool AccessBitsDbo::canKeyBIncrementBlock(const char &block) const
105
+bool AccessBitsDbo::canKeyBIncrementBlock(int block) const
130
 {
106
 {
131
     bool c1 = getBit(1, block);
107
     bool c1 = getBit(1, block);
132
     bool c2 = getBit(2, block);
108
     bool c2 = getBit(2, block);
134
     return (!c1 && !c2 && !c3) || (c1 && c2 && !c3);
110
     return (!c1 && !c2 && !c3) || (c1 && c2 && !c3);
135
 }
111
 }
136
 
112
 
137
-bool AccessBitsDbo::canKeyADecrementBlock(const char &block) const
113
+bool AccessBitsDbo::canKeyADecrementBlock(int block) const
138
 {
114
 {
139
     bool c1 = getBit(1, block);
115
     bool c1 = getBit(1, block);
140
     bool c2 = getBit(2, block);
116
     bool c2 = getBit(2, block);
142
     return (!c1 && !c2) || (c1 && c2 && !c3);
118
     return (!c1 && !c2) || (c1 && c2 && !c3);
143
 }
119
 }
144
 
120
 
145
-bool AccessBitsDbo::canKeyBDecrementBlock(const char &block) const
121
+bool AccessBitsDbo::canKeyBDecrementBlock(int block) const
146
 {
122
 {
147
     bool c1 = getBit(1, block);
123
     bool c1 = getBit(1, block);
148
     bool c2 = getBit(2, block);
124
     bool c2 = getBit(2, block);

+ 11
- 15
src/DBO/AccessBitsDbo.h 查看文件

25
     char getUserData() const;
25
     char getUserData() const;
26
     void setUserData(const char& data);
26
     void setUserData(const char& data);
27
 
27
 
28
-    void setBit(const char& i, const char& j, const bool& value);
29
-    bool getBit(const char& i, const char& j) const;
28
+    void setBit(int i, int j, const bool& value);
29
+    bool getBit(int i, int j) const;
30
+    std::string getBits() const;
30
 
31
 
31
-    bool canKeyAReadBlock(const char& block) const;
32
-    bool canKeyBReadBlock(const char& block) const;
32
+    bool canKeyAReadBlock(int block) const;
33
+    bool canKeyBReadBlock(int block) const;
33
 
34
 
34
-    bool canKeyAWriteBlock(const char& block) const;
35
-    bool canKeyBWriteBlock(const char& block) const;
35
+    bool canKeyAWriteBlock(int block) const;
36
+    bool canKeyBWriteBlock(int block) const;
36
 
37
 
37
-    bool canKeyAIncrementBlock(const char& block) const;
38
-    bool canKeyBIncrementBlock(const char& block) const;
38
+    bool canKeyAIncrementBlock(int block) const;
39
+    bool canKeyBIncrementBlock(int block) const;
39
 
40
 
40
-    bool canKeyADecrementBlock(const char& block) const;
41
-    bool canKeyBDecrementBlock(const char& block) const;
41
+    bool canKeyADecrementBlock(int block) const;
42
+    bool canKeyBDecrementBlock(int block) const;
42
 
43
 
43
     bool canKeyAReadKeyATrailer() const;
44
     bool canKeyAReadKeyATrailer() const;
44
     bool canKeyBReadKeyATrailer() const;
45
     bool canKeyBReadKeyATrailer() const;
58
     bool canKeyAWriteKeyBTrailer() const;
59
     bool canKeyAWriteKeyBTrailer() const;
59
     bool canKeyBWriteKeyBTrailer() const;
60
     bool canKeyBWriteKeyBTrailer() const;
60
 
61
 
61
-    static void setArrayBit(char *buf, const char &bitPosition, const bool &value);
62
-    static void setArrayBit(unsigned char *buf, const char &bitPosition, const bool &value);
63
-    static bool getArrayBit(const char *buf, const char &bitPosition);
64
-    static bool getArrayBit(const unsigned char *buf, const char &bitPosition);
65
-
66
 private:
62
 private:
67
     std::string _bits;
63
     std::string _bits;
68
 };
64
 };

+ 37
- 0
src/DBO/ArrayUtils.cpp 查看文件

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

+ 20
- 0
src/DBO/ArrayUtils.h 查看文件

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
+class ArrayUtils
10
+{
11
+public:
12
+    static void setArrayBit(char *buf, const char &bitPosition, const bool &value);
13
+    static void setArrayBit(unsigned char *buf, const char &bitPosition, const bool &value);
14
+    static bool getArrayBit(const char *buf, const char &bitPosition);
15
+    static bool getArrayBit(const unsigned char *buf, const char &bitPosition);
16
+
17
+};
18
+
19
+
20
+#endif //MIFARE_TOOLS_ARRAYUTILS_H

+ 20
- 4
src/DBO/StringUtils.cpp 查看文件

46
     return rawToHuman((unsigned long)c);
46
     return rawToHuman((unsigned long)c);
47
 }
47
 }
48
 
48
 
49
-std::string StringUtils::rawToHuman(std::string raw)
49
+std::string StringUtils::rawToHuman(const std::string& raw)
50
 {
50
 {
51
     std::string human;
51
     std::string human;
52
     for (size_t i = 0; i < raw.size(); ++i) {
52
     for (size_t i = 0; i < raw.size(); ++i) {
55
     return human;
55
     return human;
56
 }
56
 }
57
 
57
 
58
-ResultString StringUtils::humanToRaw(std::string human)
58
+ResultString StringUtils::humanToRaw(const std::string& human)
59
 {
59
 {
60
     if (human.size() % 2 != 0) {
60
     if (human.size() % 2 != 0) {
61
         return ResultString::error("Malformed hex data: invalid length");
61
         return ResultString::error("Malformed hex data: invalid length");
74
     return ResultString::ok(raw);
74
     return ResultString::ok(raw);
75
 }
75
 }
76
 
76
 
77
-std::string StringUtils::toLower(std::string str)
77
+std::string StringUtils::toLower(const std::string& str)
78
 {
78
 {
79
     std::string lower;
79
     std::string lower;
80
     for (size_t i = 0; i < str.size(); ++i) {
80
     for (size_t i = 0; i < str.size(); ++i) {
91
     return c;
91
     return c;
92
 }
92
 }
93
 
93
 
94
-std::string StringUtils::toUpper(std::string str)
94
+std::string StringUtils::toUpper(const std::string& str)
95
 {
95
 {
96
     std::string upper;
96
     std::string upper;
97
     for (size_t i = 0; i < str.size(); ++i) {
97
     for (size_t i = 0; i < str.size(); ++i) {
107
     }
107
     }
108
     return c;
108
     return c;
109
 }
109
 }
110
+
111
+std::string StringUtils::ensureSize(const std::string &data, int size)
112
+{
113
+    if (data.size() >= size) {
114
+        return data.substr(0, size);
115
+    }
116
+    else {
117
+        std::string d = data;
118
+        while (d.size() < size) {
119
+            d += '\0';
120
+        }
121
+        return d;
122
+    }
123
+}
124
+
125
+

+ 6
- 4
src/DBO/StringUtils.h 查看文件

22
     static std::string rawToHuman(int c);
22
     static std::string rawToHuman(int c);
23
     static std::string rawToHuman(unsigned long c);
23
     static std::string rawToHuman(unsigned long c);
24
     static std::string rawToHuman(long c);
24
     static std::string rawToHuman(long c);
25
-    static std::string rawToHuman(std::string raw);
25
+    static std::string rawToHuman(const std::string& raw);
26
 
26
 
27
-    static ResultString humanToRaw(std::string human);
27
+    static ResultString humanToRaw(const std::string& human);
28
 
28
 
29
-    static std::string toLower(std::string str);
29
+    static std::string toLower(const std::string& str);
30
     static char toLower(char c);
30
     static char toLower(char c);
31
 
31
 
32
-    static std::string toUpper(std::string str);
32
+    static std::string toUpper(const std::string& str);
33
     static char toUpper(char c);
33
     static char toUpper(char c);
34
+
35
+    static std::string ensureSize(const std::string& data, int size);
34
 };
36
 };
35
 
37
 
36
 
38
 

+ 79
- 7
src/DataAccess/SectorDbo.cpp 查看文件

2
 // Created by robin on 7/22/16.
2
 // Created by robin on 7/22/16.
3
 //
3
 //
4
 
4
 
5
+#include <DBO/StringUtils.h>
5
 #include "SectorDbo.h"
6
 #include "SectorDbo.h"
6
 
7
 
7
-Result<SectorDbo> SectorDbo::parse(std::string data)
8
+SectorDbo::SectorDbo(const std::string &data)
8
 {
9
 {
9
-    if (data.length() != 64) {
10
-        return Result<SectorDbo>::error("Data length must be 64");
11
-    }
12
-    SectorDbo dbo;
10
+    std::string d = StringUtils::ensureSize(data, 64);
13
     for (int i = 0; i < 4; ++i) {
11
     for (int i = 0; i < 4; ++i) {
14
-        dbo._blocks[i] = data.substr(16 * i, 16);
12
+        _blocks[i] = d.substr(16 * i, 16);
13
+        _haveBlocks[i] = true;
15
     }
14
     }
16
-    return Result<SectorDbo>::ok(dbo);
17
 }
15
 }
18
 
16
 
19
 const std::string &SectorDbo::getBlock(int block) const
17
 const std::string &SectorDbo::getBlock(int block) const
35
 {
33
 {
36
     return _blocks[3].substr(6, 4);
34
     return _blocks[3].substr(6, 4);
37
 }
35
 }
36
+
37
+AccessBitsDbo SectorDbo::getAccessBitsDbo() const
38
+{
39
+    return AccessBitsDbo(getAccessBits());
40
+}
41
+
42
+void SectorDbo::setBlock(int block, const std::string &data)
43
+{
44
+    std::string d = StringUtils::ensureSize(data, 16);
45
+    if (block == 3) {
46
+        setKeyA(d.substr(0, 6));
47
+        setKeyB(d.substr(10, 6));
48
+        setAccessBits(d.substr(6, 4));
49
+    }
50
+    else {
51
+        _haveBlocks[block] = !data.empty();
52
+        _blocks[block] = d;
53
+    }
54
+}
55
+
56
+void SectorDbo::setKeyA(const std::string &key)
57
+{
58
+    std::string k = StringUtils::ensureSize(key, 6);
59
+    for (int i = 0; i < k.size(); ++i) {
60
+        _blocks[3][i] = k[i];
61
+    }
62
+    _hasKeyA = !key.empty();
63
+}
64
+
65
+void SectorDbo::setKeyB(const std::string &key)
66
+{
67
+    std::string k = StringUtils::ensureSize(key, 6);
68
+    for (int i = 0; i < k.size(); ++i) {
69
+        _blocks[3][10 + i] = k[i];
70
+    }
71
+    _hasKeyB = !key.empty();
72
+}
73
+
74
+void SectorDbo::setAccessBits(const std::string &accessBits)
75
+{
76
+    std::string a = StringUtils::ensureSize(accessBits, 4);
77
+    for (int i = 0; i < a.size(); ++i) {
78
+        _blocks[3][6 + i] = a[i];
79
+    }
80
+    _hasAccessBits = !accessBits.empty();
81
+}
82
+
83
+void SectorDbo::setAccessBits(const AccessBitsDbo &accessBits)
84
+{
85
+    setAccessBits(accessBits.getBits());
86
+}
87
+
88
+bool SectorDbo::hasBlock(int block) const
89
+{
90
+    if (block == 3) {
91
+        return _hasKeyA && _hasKeyB && _hasAccessBits;
92
+    }
93
+    return _haveBlocks[block];
94
+}
95
+
96
+bool SectorDbo::hasKeyA() const
97
+{
98
+    return _hasKeyA;
99
+}
100
+
101
+bool SectorDbo::hasKeyB() const
102
+{
103
+    return _hasKeyB;
104
+}
105
+
106
+bool SectorDbo::hasAccessBits() const
107
+{
108
+    return _hasAccessBits;
109
+}

+ 29
- 1
src/DataAccess/SectorDbo.h 查看文件

8
 
8
 
9
 #include <string>
9
 #include <string>
10
 #include <DBO/Result.h>
10
 #include <DBO/Result.h>
11
+#include <DBO/AccessBitsDbo.h>
11
 
12
 
12
 class SectorDbo
13
 class SectorDbo
13
 {
14
 {
14
 public:
15
 public:
16
+    SectorDbo(const std::string& data = "");
15
 
17
 
16
     const std::string& getBlock(int block) const;
18
     const std::string& getBlock(int block) const;
17
 
19
 
21
 
23
 
22
     std::string getAccessBits() const;
24
     std::string getAccessBits() const;
23
 
25
 
24
-    static Result<SectorDbo> parse(std::string data);
26
+    AccessBitsDbo getAccessBitsDbo() const;
27
+
28
+    void setBlock(int block, const std::string& data);
29
+
30
+    void setKeyA(const std::string& key);
31
+
32
+    void setKeyB(const std::string& key);
33
+
34
+    void setAccessBits(const std::string& accessBits);
35
+
36
+    void setAccessBits(const AccessBitsDbo& accessBits);
37
+
38
+    bool hasBlock(int block) const;
39
+
40
+    bool hasKeyA() const;
41
+
42
+    bool hasKeyB() const;
43
+
44
+    bool hasAccessBits() const;
25
 
45
 
26
 protected:
46
 protected:
27
     std::string _blocks[4];
47
     std::string _blocks[4];
48
+
49
+    bool _haveBlocks[3];
50
+
51
+    bool _hasKeyA;
52
+
53
+    bool _hasKeyB;
54
+
55
+    bool _hasAccessBits;
28
 };
56
 };
29
 
57
 
30
 
58
 

+ 44
- 36
tests/test-main.cpp 查看文件

3
 #include <gtest/gtest.h>
3
 #include <gtest/gtest.h>
4
 #include <DataAccess/LibNfc.h>
4
 #include <DataAccess/LibNfc.h>
5
 #include <DBO/StringUtils.h>
5
 #include <DBO/StringUtils.h>
6
+#include <DBO/ArrayUtils.h>
6
 #include <DBO/AccessBitsDbo.h>
7
 #include <DBO/AccessBitsDbo.h>
7
 
8
 
8
 TEST(StringUtils, rawToHumanChar)
9
 TEST(StringUtils, rawToHumanChar)
92
   ASSERT_EQ(StringUtils::humanToRaw("1a\n00f").getError(), "Malformed hex data at char 2");
93
   ASSERT_EQ(StringUtils::humanToRaw("1a\n00f").getError(), "Malformed hex data at char 2");
93
 }
94
 }
94
 
95
 
95
-TEST(AccessBitsDbo, getArrayBitimple)
96
+TEST(StringUtils, ensureSize)
97
+{
98
+  ASSERT_EQ(StringUtils::ensureSize("test", 3), "tes");
99
+  ASSERT_EQ(StringUtils::ensureSize("test", 4), "test");
100
+  ASSERT_EQ(StringUtils::ensureSize("test", 5), std::string({'t', 'e', 's', 't', '\0'}));
101
+}
102
+
103
+TEST(ArrayUtils, getArrayBitimple)
96
 {
104
 {
97
   const unsigned char buf[] = {0x04};
105
   const unsigned char buf[] = {0x04};
98
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 0));
99
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 1));
100
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 2));
101
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 3));
102
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 4));
103
-  ASSERT_TRUE(AccessBitsDbo::getArrayBit(buf, 5));
104
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 6));
105
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 7));
106
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 0));
107
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 1));
108
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 2));
109
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 3));
110
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 4));
111
+  ASSERT_TRUE(ArrayUtils::getArrayBit(buf, 5));
112
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 6));
113
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 7));
106
 }
114
 }
107
 
115
 
108
-TEST(AccessBitsDbo, getArrayBitMultiple)
116
+TEST(ArrayUtils, getArrayBitMultiple)
109
 {
117
 {
110
   const unsigned char buf[] = {0x80, 0x14, 0x01};
118
   const unsigned char buf[] = {0x80, 0x14, 0x01};
111
-  ASSERT_TRUE(AccessBitsDbo::getArrayBit(buf, 0));
112
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 1));
113
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 2));
114
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 3));
115
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 4));
116
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 5));
117
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 6));
118
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 7));
119
-
120
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 8));
121
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 9));
122
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 10));
123
-  ASSERT_TRUE(AccessBitsDbo::getArrayBit(buf, 11));
124
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 12));
125
-  ASSERT_TRUE(AccessBitsDbo::getArrayBit(buf, 13));
126
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 14));
127
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 15));
128
-
129
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 16));
130
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 17));
131
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 18));
132
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 19));
133
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 20));
134
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 21));
135
-  ASSERT_FALSE(AccessBitsDbo::getArrayBit(buf, 22));
136
-  ASSERT_TRUE(AccessBitsDbo::getArrayBit(buf, 23));
119
+  ASSERT_TRUE(ArrayUtils::getArrayBit(buf, 0));
120
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 1));
121
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 2));
122
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 3));
123
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 4));
124
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 5));
125
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 6));
126
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 7));
127
+
128
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 8));
129
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 9));
130
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 10));
131
+  ASSERT_TRUE(ArrayUtils::getArrayBit(buf, 11));
132
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 12));
133
+  ASSERT_TRUE(ArrayUtils::getArrayBit(buf, 13));
134
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 14));
135
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 15));
136
+
137
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 16));
138
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 17));
139
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 18));
140
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 19));
141
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 20));
142
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 21));
143
+  ASSERT_FALSE(ArrayUtils::getArrayBit(buf, 22));
144
+  ASSERT_TRUE(ArrayUtils::getArrayBit(buf, 23));
137
 }
145
 }
138
 
146
 
139
 TEST(AccessBitsDbo, getBit)
147
 TEST(AccessBitsDbo, getBit)

Loading…
取消
儲存