Quellcode durchsuchen

write methods

develop
Robin Thoni vor 7 Jahren
Ursprung
Commit
be19fc4a3d

+ 4
- 4
cli/Interface/MainClass.cpp Datei anzeigen

@@ -34,8 +34,8 @@ int MainClass::main()
34 34
     CommandLineOption optionHelp(&parser, "help", 'h', "Show this help");
35 35
 
36 36
     CommandLineOption optionMap(&parser, "map", 'm', "Map keys for the tag");
37
-    CommandLineOption optionDump(&parser, "dump", 'd', "Dump the tag");
38
-    CommandLineOption optionDevices(&parser, "devices", 'l', "List NFC devices");
37
+    CommandLineOption optionDump(&parser, "read", 'r', "Read the tag");
38
+    CommandLineOption optionDevices(&parser, "devices", 'd', "List NFC devices");
39 39
     CommandLineOption optionTags(&parser, "tags", 't', "List NFC tags");
40 40
 
41 41
     CommandLineOption optionDevice(&parser, "device", 'e', "Use the device DEVICE", "DEVICE");
@@ -178,7 +178,7 @@ int MainClass::main()
178 178
                                     res = mapKeys(tag, keys);
179 179
                                 }
180 180
                                 else {
181
-                                    std::cerr << "Must select an action (map|dump|devices|tags)" << std::endl;
181
+                                    std::cerr << "Must select an action (map|read|devices|tags)" << std::endl;
182 182
                                     res = EX_USAGE;
183 183
                                 }
184 184
                             }
@@ -218,7 +218,7 @@ int MainClass::mapKeys(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std
218 218
 
219 219
 int MainClass::dump(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::string> keys)
220 220
 {
221
-    auto dumpResult = tag->dump(keys, printPercentMapKeys, printPercentDump);
221
+    auto dumpResult = tag->read(keys, printPercentMapKeys, printPercentDump);
222 222
     if (!dumpResult) {
223 223
         dumpResult.print();
224 224
         return EX_DUMP_ERROR;

+ 127
- 40
src/Business/FreeFareTagBusiness.cpp Datei anzeigen

@@ -2,6 +2,7 @@
2 2
 // Created by robin on 7/22/16.
3 3
 //
4 4
 
5
+#include <DBO/StringUtils.h>
5 6
 #include "FreeFareTagBusiness.h"
6 7
 
7 8
 FreeFareTagBusiness::FreeFareTagBusiness(std::shared_ptr<FreeFareTag> tag)
@@ -14,42 +15,6 @@ ResultBool FreeFareTagBusiness::authenticate(int sector, std::string key, int ke
14 15
     return _tag->authenticate(sector, key, keyType);
15 16
 }
16 17
 
17
-ResultString FreeFareTagBusiness::readBlock(int sector, int block, std::string key, int keyType)
18
-{
19
-    return _tag->readBlock(sector, block, key, keyType);
20
-}
21
-
22
-Result<SectorDbo> FreeFareTagBusiness::readSector(int sector, std::string key, int keyType)
23
-{
24
-    std::string res;
25
-    int lastBlock = _tag->getSectorBlockCount(sector);
26
-    for (int i = 0; i < lastBlock; ++i) {
27
-        auto data = readBlock(sector, i, key, keyType);
28
-        if (data) {
29
-            res += data.getData();
30
-        }
31
-        else {
32
-            return Result<SectorDbo>::error(data);
33
-        }
34
-    }
35
-    return Result<SectorDbo>::ok(SectorDbo(res));
36
-}
37
-
38
-const std::string &FreeFareTagBusiness::getUid() const
39
-{
40
-    return _tag->getUid();
41
-}
42
-
43
-freefare_tag_type FreeFareTagBusiness::getType() const
44
-{
45
-    return _tag->getType();
46
-}
47
-
48
-std::shared_ptr<FreeFareTag> FreeFareTagBusiness::getTag() const
49
-{
50
-    return _tag;
51
-}
52
-
53 18
 Result<MappedKeys> FreeFareTagBusiness::mapKeys(std::vector<std::string> keys, std::function<void(int, int)> cb)
54 19
 {
55 20
     MappedKeys mappedKeys;
@@ -82,10 +47,31 @@ Result<MappedKeys> FreeFareTagBusiness::mapKeys(std::vector<std::string> keys, s
82 47
     return Result<MappedKeys>::ok(mappedKeys);
83 48
 }
84 49
 
85
-Result<std::vector<SectorDbo>> FreeFareTagBusiness::dump(MappedKeys keys, std::function<void(int, int)> cb)
50
+ResultString FreeFareTagBusiness::readBlock(int sector, int block, std::string key, int keyType)
51
+{
52
+    return _tag->readBlock(sector, block, key, keyType);
53
+}
54
+
55
+Result<SectorDbo> FreeFareTagBusiness::readSector(int sector, std::string key, int keyType)
56
+{
57
+    std::string res;
58
+    int lastBlock = _tag->getSectorBlockCount(sector);
59
+    for (int i = 0; i < lastBlock; ++i) {
60
+        auto data = readBlock(sector, i, key, keyType);
61
+        if (data) {
62
+            res += data.getData();
63
+        }
64
+        else {
65
+            return Result<SectorDbo>::error(data);
66
+        }
67
+    }
68
+    return Result<SectorDbo>::ok(SectorDbo(res));
69
+}
70
+
71
+Result<std::vector<SectorDbo>> FreeFareTagBusiness::read(MappedKeys keys, std::function<void(int, int)> cb)
86 72
 {
87 73
     if (keys.size() != 16) {
88
-        return Result<std::vector<SectorDbo>>::error("Must have 16 sectors");
74
+        return Result<std::vector<SectorDbo>>::error("Must have 16 sectors keys");
89 75
     }
90 76
     int done = 0;
91 77
     int total = 4 * keys.size();
@@ -164,11 +150,112 @@ Result<std::vector<SectorDbo>> FreeFareTagBusiness::dump(MappedKeys keys, std::f
164 150
     return Result<std::vector<SectorDbo>>::ok(sectors);
165 151
 }
166 152
 
167
-Result<std::vector<SectorDbo>> FreeFareTagBusiness::dump(std::vector<std::string> keys, std::function<void(int, int)> mapCb, std::function<void(int, int)> dumpCb)
153
+Result<std::vector<SectorDbo>> FreeFareTagBusiness::read(std::vector<std::string> keys, std::function<void(int, int)> mapCb,
154
+                                                         std::function<void(int, int)> dumpCb)
168 155
 {
169 156
     auto mappedKeysResult = mapKeys(keys, mapCb);
170 157
     if (!mappedKeysResult) {
171 158
         return Result<std::vector<SectorDbo>>::error(mappedKeysResult);
172 159
     }
173
-    return dump(mappedKeysResult.getData(), dumpCb);
160
+    return read(mappedKeysResult.getData(), dumpCb);
161
+}
162
+
163
+ResultBool FreeFareTagBusiness::writeBlock(int sector, int block, std::string key, int keyType, const std::string &data)
164
+{
165
+    return _tag->writeBlock(sector, block, key, keyType, StringUtils::ensureSize(data, 16));
166
+}
167
+
168
+ResultBool FreeFareTagBusiness::writeSector(int sector, std::string key, int keyType, const std::string &data)
169
+{
170
+    std::string d = StringUtils::ensureSize(data, 64);
171
+    std::string errors;
172
+    for (int b = 0; b < 4; ++b) {
173
+        auto result = writeBlock(sector, b, key, keyType, d.substr(b * 16, 16));
174
+        if (!result) {
175
+            errors += std::string(errors.empty() ? "" : "\n") + "Failed to write sector " + std::to_string(sector) +
176
+                      " block " + std::to_string(b) + " with key " + (keyType == MFC_KEY_A ? "A" : "B") + ": " + result.getError();
177
+        }
178
+    }
179
+    if (errors.empty()) {
180
+        return ResultBool::ok(true);
181
+    }
182
+    return ResultBool::error(errors);
183
+}
184
+
185
+ResultBool FreeFareTagBusiness::write(MappedKeys keys, const std::string &data, bool writeSector0, std::function<void(int, int)> cb)
186
+{
187
+    if (keys.size() != 16) {
188
+        return ResultBool::error("Must have 16 sectors keys");
189
+    }
190
+    std::string d = StringUtils::ensureSize(data, 1024);
191
+    std::string errors;
192
+    int done = 0;
193
+    int total = 4 * (keys.size() - (writeSector0 ? 0 : 1));
194
+    for (int s = writeSector0 ? 0 : 1; s < keys.size(); ++s) {
195
+        auto sectorKey = keys[s];
196
+        for (int b = 0; b < 4; ++b) {
197
+            std::string blockData = d.substr((s * 64) + (b * 16), 16);
198
+            if (cb != 0 && done < total) {
199
+                bool keyA = false;
200
+                bool keyB = false;
201
+                std::string sectorErrors;
202
+                if (!sectorKey.first.empty()) {
203
+                    auto resultA = writeBlock(s, b, sectorKey.first, MFC_KEY_A, blockData);
204
+                    if (resultA) {
205
+                        keyA = true;
206
+                    }
207
+                    else {
208
+                        sectorErrors = "Failed to write sector " + std::to_string(s) +
209
+                                       " block " + std::to_string(b) + " with key A: " + resultA.getError();
210
+                    }
211
+                }
212
+                if (!keyA && !sectorKey.second.empty()) {
213
+                    auto resultB = writeBlock(s, b, sectorKey.first, MFC_KEY_A, blockData);
214
+                    if (resultB) {
215
+                        keyB = true;
216
+                    }
217
+                    else {
218
+                        sectorErrors = std::string(sectorErrors.empty() ? "" : "\n") + "Failed to write sector " + std::to_string(s) +
219
+                                       " block " + std::to_string(b) + " with key B: " + resultB.getError();
220
+                    }
221
+                }
222
+                if (!keyA && !keyB) {
223
+                    errors += std::string(errors.empty() ? "" : "\n") + sectorErrors;
224
+                }
225
+                cb(++done, total);
226
+            }
227
+        }
228
+    }
229
+    if (cb != 0 && done < total) {
230
+        cb(total, total);
231
+    }
232
+    if (errors.empty()) {
233
+        return ResultBool::ok(true);
234
+    }
235
+    return ResultBool::error(errors);
236
+}
237
+
238
+ResultBool FreeFareTagBusiness::write(std::vector<std::string> keys, const std::string &data, bool writeSector0,
239
+                                      std::function<void(int, int)> mapCb, std::function<void(int, int)> dumpCb)
240
+{
241
+    auto mappedKeysResult = mapKeys(keys, mapCb);
242
+    if (!mappedKeysResult) {
243
+        return ResultBool::error(mappedKeysResult);
244
+    }
245
+    return write(mappedKeysResult.getData(), data, writeSector0, dumpCb);
246
+}
247
+
248
+const std::string &FreeFareTagBusiness::getUid() const
249
+{
250
+    return _tag->getUid();
251
+}
252
+
253
+freefare_tag_type FreeFareTagBusiness::getType() const
254
+{
255
+    return _tag->getType();
256
+}
257
+
258
+std::shared_ptr<FreeFareTag> FreeFareTagBusiness::getTag() const
259
+{
260
+    return _tag;
174 261
 }

+ 13
- 3
src/Business/FreeFareTagBusiness.h Datei anzeigen

@@ -19,15 +19,25 @@ public:
19 19
 
20 20
     ResultBool authenticate(int sector, std::string key, int keyType);
21 21
 
22
+    Result<MappedKeys> mapKeys(std::vector<std::string> keys, std::function<void(int, int)> cb = 0);
23
+
22 24
     ResultString readBlock(int sector, int block, std::string key, int keyType);
23 25
 
24 26
     Result<SectorDbo> readSector(int sector, std::string key, int keyType);
25 27
 
26
-    Result<MappedKeys> mapKeys(std::vector<std::string> keys, std::function<void(int, int)> cb = 0);
28
+    Result<std::vector<SectorDbo>> read(MappedKeys keys, std::function<void(int, int)> cb = 0);
29
+
30
+    Result<std::vector<SectorDbo>> read(std::vector<std::string> keys, std::function<void(int, int)> mapCb = 0,
31
+                                        std::function<void(int, int)> dumpCb = 0);
32
+
33
+    ResultBool writeBlock(int sector, int block, std::string key, int keyType, const std::string& data);
34
+
35
+    ResultBool writeSector(int sector, std::string key, int keyType, const std::string& data);
27 36
 
28
-    Result<std::vector<SectorDbo>> dump(MappedKeys keys, std::function<void(int, int)> cb  = 0);
37
+    ResultBool write(MappedKeys keys, const std::string& data, bool writeSector0, std::function<void(int, int)> cb = 0);
29 38
 
30
-    Result<std::vector<SectorDbo>> dump(std::vector<std::string> keys, std::function<void(int, int)> mapCb = 0, std::function<void(int, int)> dumpCb = 0);
39
+    ResultBool write(std::vector<std::string> keys, const std::string& data, bool writeSector0,
40
+                     std::function<void(int, int)> mapCb = 0, std::function<void(int, int)> dumpCb = 0);
31 41
 
32 42
     const std::string& getUid() const;
33 43
 

+ 5
- 6
src/DBO/StringUtils.cpp Datei anzeigen

@@ -111,15 +111,14 @@ char StringUtils::toUpper(char c)
111 111
 
112 112
 std::string StringUtils::ensureSize(const std::string &data, int size)
113 113
 {
114
-    if (data.size() >= size) {
114
+    if (data.size() == size) {
115
+        return data;
116
+    }
117
+    else if (data.size() > size) {
115 118
         return data.substr(0, size);
116 119
     }
117 120
     else {
118
-        std::string d = data;
119
-        while (d.size() < size) {
120
-            d += '\0';
121
-        }
122
-        return d;
121
+        return data + std::string(size - data.size(), '\0');
123 122
     }
124 123
 }
125 124
 

+ 18
- 1
src/DataAccess/FreeFareTag.cpp Datei anzeigen

@@ -35,7 +35,6 @@ ResultBool FreeFareTag::authenticate(int sector, std::string key, int keyType)
35 35
 
36 36
 ResultString FreeFareTag::readBlock(int sector, int block, std::string key, int keyType)
37 37
 {
38
-
39 38
     if (mifare_classic_connect(_tag) != 0) {
40 39
         return ResultString::error("Failed to connect to MIFARE tag");
41 40
     }
@@ -53,6 +52,24 @@ ResultString FreeFareTag::readBlock(int sector, int block, std::string key, int
53 52
     return ResultString::ok(std::string((const char*)data, sizeof(data)));
54 53
 }
55 54
 
55
+ResultBool FreeFareTag::writeBlock(int sector, int block, std::string key, int keyType, const std::string &data)
56
+{
57
+    if (mifare_classic_connect(_tag) != 0) {
58
+        return ResultBool::error("Failed to connect to MIFARE tag");
59
+    }
60
+    block = mifare_classic_sector_first_block((MifareClassicBlockNumber)sector) + block;
61
+    if (mifare_classic_authenticate(_tag, (MifareClassicBlockNumber)block, (const unsigned char*)key.c_str(),
62
+                                    (MifareClassicKeyType)keyType) != 0) {
63
+        return ResultBool::error("Failed to authenticate to MIFARE tag");
64
+    }
65
+
66
+    if (mifare_classic_write(_tag, (MifareClassicBlockNumber)block, (const unsigned char*)data.c_str())) {
67
+        return ResultBool::error("Failed to write data to MIFARE tag");
68
+    }
69
+    mifare_classic_disconnect(_tag);
70
+    return ResultBool::ok(true);
71
+}
72
+
56 73
 const freefare_tag *FreeFareTag::getTag() const
57 74
 {
58 75
     return _tag;

+ 2
- 0
src/DataAccess/FreeFareTag.h Datei anzeigen

@@ -20,6 +20,8 @@ public:
20 20
 
21 21
     ResultString readBlock(int sector, int block, std::string key, int keyType);
22 22
 
23
+    ResultBool writeBlock(int sector, int block, std::string key, int keyType, const std::string& data);
24
+
23 25
     int getFirstBlock(int sector) const;
24 26
 
25 27
     int getLastBlock(int sector) const;

Laden…
Abbrechen
Speichern