Browse Source

write methods

develop
Robin Thoni 8 years ago
parent
commit
be19fc4a3d

+ 4
- 4
cli/Interface/MainClass.cpp View File

34
     CommandLineOption optionHelp(&parser, "help", 'h', "Show this help");
34
     CommandLineOption optionHelp(&parser, "help", 'h', "Show this help");
35
 
35
 
36
     CommandLineOption optionMap(&parser, "map", 'm', "Map keys for the tag");
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
     CommandLineOption optionTags(&parser, "tags", 't', "List NFC tags");
39
     CommandLineOption optionTags(&parser, "tags", 't', "List NFC tags");
40
 
40
 
41
     CommandLineOption optionDevice(&parser, "device", 'e', "Use the device DEVICE", "DEVICE");
41
     CommandLineOption optionDevice(&parser, "device", 'e', "Use the device DEVICE", "DEVICE");
178
                                     res = mapKeys(tag, keys);
178
                                     res = mapKeys(tag, keys);
179
                                 }
179
                                 }
180
                                 else {
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
                                     res = EX_USAGE;
182
                                     res = EX_USAGE;
183
                                 }
183
                                 }
184
                             }
184
                             }
218
 
218
 
219
 int MainClass::dump(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::string> keys)
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
     if (!dumpResult) {
222
     if (!dumpResult) {
223
         dumpResult.print();
223
         dumpResult.print();
224
         return EX_DUMP_ERROR;
224
         return EX_DUMP_ERROR;

+ 127
- 40
src/Business/FreeFareTagBusiness.cpp View File

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 "FreeFareTagBusiness.h"
6
 #include "FreeFareTagBusiness.h"
6
 
7
 
7
 FreeFareTagBusiness::FreeFareTagBusiness(std::shared_ptr<FreeFareTag> tag)
8
 FreeFareTagBusiness::FreeFareTagBusiness(std::shared_ptr<FreeFareTag> tag)
14
     return _tag->authenticate(sector, key, keyType);
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
 Result<MappedKeys> FreeFareTagBusiness::mapKeys(std::vector<std::string> keys, std::function<void(int, int)> cb)
18
 Result<MappedKeys> FreeFareTagBusiness::mapKeys(std::vector<std::string> keys, std::function<void(int, int)> cb)
54
 {
19
 {
55
     MappedKeys mappedKeys;
20
     MappedKeys mappedKeys;
82
     return Result<MappedKeys>::ok(mappedKeys);
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
     if (keys.size() != 16) {
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
     int done = 0;
76
     int done = 0;
91
     int total = 4 * keys.size();
77
     int total = 4 * keys.size();
164
     return Result<std::vector<SectorDbo>>::ok(sectors);
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
     auto mappedKeysResult = mapKeys(keys, mapCb);
156
     auto mappedKeysResult = mapKeys(keys, mapCb);
170
     if (!mappedKeysResult) {
157
     if (!mappedKeysResult) {
171
         return Result<std::vector<SectorDbo>>::error(mappedKeysResult);
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 View File

19
 
19
 
20
     ResultBool authenticate(int sector, std::string key, int keyType);
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
     ResultString readBlock(int sector, int block, std::string key, int keyType);
24
     ResultString readBlock(int sector, int block, std::string key, int keyType);
23
 
25
 
24
     Result<SectorDbo> readSector(int sector, std::string key, int keyType);
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
     const std::string& getUid() const;
42
     const std::string& getUid() const;
33
 
43
 

+ 5
- 6
src/DBO/StringUtils.cpp View File

111
 
111
 
112
 std::string StringUtils::ensureSize(const std::string &data, int size)
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
         return data.substr(0, size);
118
         return data.substr(0, size);
116
     }
119
     }
117
     else {
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 View File

35
 
35
 
36
 ResultString FreeFareTag::readBlock(int sector, int block, std::string key, int keyType)
36
 ResultString FreeFareTag::readBlock(int sector, int block, std::string key, int keyType)
37
 {
37
 {
38
-
39
     if (mifare_classic_connect(_tag) != 0) {
38
     if (mifare_classic_connect(_tag) != 0) {
40
         return ResultString::error("Failed to connect to MIFARE tag");
39
         return ResultString::error("Failed to connect to MIFARE tag");
41
     }
40
     }
53
     return ResultString::ok(std::string((const char*)data, sizeof(data)));
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
 const freefare_tag *FreeFareTag::getTag() const
73
 const freefare_tag *FreeFareTag::getTag() const
57
 {
74
 {
58
     return _tag;
75
     return _tag;

+ 2
- 0
src/DataAccess/FreeFareTag.h View File

20
 
20
 
21
     ResultString readBlock(int sector, int block, std::string key, int keyType);
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
     int getFirstBlock(int sector) const;
25
     int getFirstBlock(int sector) const;
24
 
26
 
25
     int getLastBlock(int sector) const;
27
     int getLastBlock(int sector) const;

Loading…
Cancel
Save