|
@@ -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
|
}
|