// // Created by robin on 7/22/16. // #include "FreeFareTagBusiness.h" FreeFareTagBusiness::FreeFareTagBusiness(std::shared_ptr tag) : _tag(tag) { } ResultBool FreeFareTagBusiness::authenticate(int sector, int block, std::string key, int keyType) { return _tag->authenticate(sector, block, key, keyType); } ResultString FreeFareTagBusiness::readBlock(int sector, int block, std::string key, int keyType) { return _tag->readBlock(sector, block, key, keyType); } Result FreeFareTagBusiness::readSector(int sector, std::string key, int keyType) { std::string res; int lastBlock = _tag->getSectorBlockCount(sector); for (int i = 0; i < lastBlock; ++i) { auto data = readBlock(sector, i, key, keyType); if (data) { res += data.getData(); } else { return Result::error(data); } } return Result::ok(SectorDbo(res)); } const std::string &FreeFareTagBusiness::getUid() const { return _tag->getUid(); } freefare_tag_type FreeFareTagBusiness::getType() const { return _tag->getType(); } std::shared_ptr FreeFareTagBusiness::getTag() const { return _tag; } Result FreeFareTagBusiness::mapKeys(std::vector keys, std::function cb) { std::vector>> mappedKeys; for (int i = 0; i < 16; ++i) { std::vector> sectorKeys; for (int j = 0; j < 4; ++j) { std::pair blockKeys; for (int k = 0; k < keys.size(); ++k) { auto key = keys[k]; if (authenticate(i, j, key, MFC_KEY_A)) { blockKeys.first = key; } if (authenticate(i, j, key, MFC_KEY_B)) { blockKeys.second = key; } if (cb != 0) { cb((i * 4 * keys.size()) + (j * keys.size()) + k + 1, 16 * 4 * keys.size()); } if (!blockKeys.first.empty() && !blockKeys.second.empty()) { break; } } sectorKeys.push_back(blockKeys); } mappedKeys.push_back(sectorKeys); } return Result>>>::ok(mappedKeys); } Result> FreeFareTagBusiness::dump(MappedKeys keys, std::function cb) { if (keys.size() != 16) { return Result>::error("Must have 16 sectors"); } for (int i = 0; i < keys.size(); ++i) { auto key = keys[i]; if (key.size() != 4) { return Result>::error("Must have 4 keys in sector " + i); } } std::vector sectors; for (int s = 0; s < keys.size(); ++s) { auto sectorKeys = keys[s]; SectorDbo sector; bool keyA = false; bool keyB = false; for (int b = 0; b < sectorKeys.size() - 1; ++b) { auto blockKey = sectorKeys[b]; std::string data = ""; if (!blockKey.first.empty()) { auto blockResult = readBlock(s, b, blockKey.first, MFC_KEY_A); if (blockResult) { data = blockResult.getData(); keyA = true; } } if (!blockKey.second.empty()) { auto blockResult = readBlock(s, b, blockKey.second, MFC_KEY_B); if (blockResult) { data = blockResult.getData(); keyB = true; } } sector.setBlock(b, data); if (cb != 0) { cb((s * sectorKeys.size()) + b + 1, keys.size() * sectorKeys.size()); } } int b = sectorKeys.size() - 1; auto blockKey = sectorKeys[b]; std::string data = ""; if (!blockKey.first.empty()) { auto blockResult = readBlock(s, b, blockKey.first, MFC_KEY_A); if (blockResult) { data = blockResult.getData(); keyA = true; } } if (!blockKey.second.empty()) { auto blockResult = readBlock(s, b, blockKey.second, MFC_KEY_B); if (blockResult) { data = blockResult.getData(); keyB = true; } } sector.setBlock(b, data); AccessBitsDbo accessBitsDbo = sector.getAccessBitsDbo(); if (cb != 0) { cb((s * sectorKeys.size()) + b + 1, keys.size() * sectorKeys.size()); } sector.setKeyA(keyA ? blockKey.first : ""); sector.setKeyB(keyB ? blockKey.second : ""); std::string accessBits; if (!data.empty()) { if ((keyA && accessBitsDbo.canKeyAReadAccessBitsTrailer()) || (keyB && accessBitsDbo.canKeyBReadAccessBitsTrailer())) { accessBits = accessBitsDbo.getBits(); } } sector.setAccessBits(accessBits); sectors.push_back(sector); } return Result>::ok(sectors); } Result> FreeFareTagBusiness::dump(std::vector keys, std::function mapCb, std::function dumpCb) { auto mappedKeysResult = mapKeys(keys, mapCb); if (!mappedKeysResult) { return Result>::error(mappedKeysResult); } return dump(mappedKeysResult.getData(), dumpCb); }