SDK Readers 1.0.1
SDK для связи со считывателями Iron logic
mf_classic/main.cpp

Демонстрирует работу с картами Mifare Classic и Mifare Plus SL1: поиск, чтение и запись данных карты, запись ключей аутентификации в память считывателя.

#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h> // readlink
#include <filesystem>
#include <fstream>
#include <iomanip> // для std::put_time
#include <iostream> // для std::cout и std::cin
#include "ilreaders.h"
#define ILR_LOG // Раскомментируйте, чтобы включить отладочные сообщения
#define ILR_LOG_FILE // Писать лог в файл
using namespace ilr;
// True, авторизовать по ключу B, иначе - A
bool g_fAuthKeyB = false;
// Ключ аутентификации Mifare Classic
// Биты ключей аутентификации считывателя
uint g_nRdKeys = 0;
// Сохранённые ключи считывателя
CMifareClassicKey g_aSavedRdKeys[2][16];
// Серийный номер считывателя (устанавливается автоматически)
int g_nReaderSn = -1;
#ifdef ILR_LOG
const char kLogLevelChars[] = {'-', 'E', 'W', 'I', 'D'};
const char kLogFileName[] = "ilreaders.log"; // Путь к лог файлу
void ILR_CALL LogCallback(ilr_log_level level, const char* pContext, const char* pMessage, void*) {
#ifdef ILR_LOG_FILE // Запись в файл
std::ofstream file(kLogFileName, std::ios_base::out | std::ios_base::app);
auto& out = file;
#else // иначе в консоль
auto& out = std::cout;
#endif
auto t = std::time(nullptr);
auto tmb = std::localtime(&t);
out << std::put_time(tmb, "%d-%m-%Y %H:%M:%S") << " [" << kLogLevelChars[level] << ' '
<< pContext << "] " << pMessage << std::endl;
}
#endif
// Возвращает путь к файлу настроек
std::filesystem::path GetSettingFilePath() {
char szCfgPath[PATH_MAX];
auto count = readlink("/proc/self/exe", szCfgPath, std::size(szCfgPath) - 1);
szCfgPath[count] = 0;
std::stringstream ss;
ss << szCfgPath << '_' << g_nReaderSn << ".txt";
return ss.str();
}
// Загружает настройки
void LoadSettings() {
auto sPath(GetSettingFilePath());
if (std::filesystem::exists(sPath)) {
std::ifstream inFile;
inFile.open(sPath);
inFile >> std::boolalpha >> g_fAuthKeyB;
inFile >> std::hex >> (uint64_t&)g_AuthKey >> g_nRdKeys;
for (size_t i = 0; i < std::size(g_aSavedRdKeys); i++)
for (size_t j = 0; j < std::size(g_aSavedRdKeys[i]); j++)
inFile >> (uint64_t&)g_aSavedRdKeys[i][j];
}
}
// Сохраняет настройки
void SaveSettings() {
std::filesystem::path sPath(GetSettingFilePath());
std::ofstream outFile;
outFile.open(sPath);
outFile << std::boolalpha << g_fAuthKeyB << " ";
outFile << std::hex << std::showbase << g_AuthKey << " " << g_nRdKeys;
for (size_t i = 0; i < std::size(g_aSavedRdKeys); i++) {
outFile << "\n";
for (size_t j = 0; j < std::size(g_aSavedRdKeys[i]); j++)
outFile << (uint64_t&)g_aSavedRdKeys[i][j] << " ";
}
}
void PrintTrailerAccess(bool fValid, uint32_t nAreaAccess) {
// Выводим параметры доступа прицепа
std::cout << "3. Прицеп. Доступ (";
if (fValid) {
std::cout << (nAreaAccess & 1) << ' ' << ((nAreaAccess >> 1) & 1) << ' '
<< ((nAreaAccess >> 2) & 1) << "): ";
switch (nAreaAccess) {
case 0: // 0 0 0
assert(!g_fAuthKeyB);
std::cout << "Ключ A [-w]; Биты доступа [r-]; Ключ B [rw]";
break;
case 2: // 0 1 0
assert(!g_fAuthKeyB);
std::cout << "Ключ A [--]; Биты доступа [r-]; Ключ B [r-]";
break;
case 1: // 1 0 0
if (g_fAuthKeyB)
std::cout << "Ключ A [-w]; Биты доступа [r-]; Ключ B [-w]";
else
std::cout << "Ключ A [--]; Биты доступа [r-]; Ключ B [--]";
break;
case 3: // 1 1 0
std::cout << "Ключ A [--]; Биты доступа [r-]; Ключ B [--]";
break;
case 4: // 0 0 1
assert(!g_fAuthKeyB);
std::cout << "Ключ A [-w]; Биты доступа [rw]; Ключ B [rw]; транспортная";
break;
case 6: // 0 1 1
if (g_fAuthKeyB)
std::cout << "Ключ A [-w]; Биты доступа [rw]; Ключ B [-w]";
else
std::cout << "Ключ A [--]; Биты доступа [r-]; Ключ B [--]";
break;
case 5: // 1 0 1
if (g_fAuthKeyB)
std::cout << "Ключ A [--]; Биты доступа [rw]; Ключ B [-w]";
else
std::cout << "Ключ A [--]; Биты доступа [r-]; Ключ B [--]";
break;
case 7: // 1 1 1
std::cout << "Ключ A [--]; Биты доступа [r-]; Ключ B [--]";
break;
}
std::cout << std::endl;
}
else
std::cout << "некорректные биты доступа)" << std::endl;
}
void PrintDataAccess(size_t nAreaN, bool fValid, uint32_t nAreaAccess) {
// Выводим параметры доступа блока данных
std::cout << std::dec << nAreaN << ". Данные. Доступ (";
if (fValid) {
std::cout << (nAreaAccess & 1) << ' ' << ((nAreaAccess >> 1) & 1) << ' '
<< ((nAreaAccess >> 2) & 1) << "): ";
switch (nAreaAccess) {
case 0: // 0 0 0
std::cout << "rwidtr; транспортная";
break;
case 2: // 0 1 0
std::cout << "r-----";
break;
case 1: // 1 0 0
if (g_fAuthKeyB)
std::cout << "rw----";
else
std::cout << "r-----";
break;
case 3: // 1 1 0
if (g_fAuthKeyB)
std::cout << "rwidtr; блок-значение";
else
std::cout << "r--dtr; блок-значение";
break;
case 4: // 0 0 1
std::cout << "r--dtr; блок-значение";
break;
case 6: // 0 1 1
if (g_fAuthKeyB)
std::cout << "rw----";
else
std::cout << "------";
break;
case 5: // 1 0 1
if (g_fAuthKeyB)
std::cout << "r-----";
else
std::cout << "------";
break;
case 7: // 1 1 1
std::cout << "------";
break;
}
std::cout << std::endl;
}
else
std::cout << "некорректные биты доступа)" << std::endl;
}
void DoReadAllFromCard(CReader& oReader) {
size_t nRead = 0;
size_t nBlockMax = 0;
try {
oReader.GetCardInfo(rCI);
nBlockMax = GetNumberOfMfBlocks(rCI.nMemSize);
std::vector<ilr_mf_block_data> oBlocks(nBlockMax);
std::cout << "Чтение данных карты..." << std::endl;
auto tStartTime = now();
if (g_nRdKeys != 0) {
if (oReader.AuthMfCard2(0, g_fAuthKeyB, g_nRdKeys) == -1) {
std::cout << "Нет подходящего ключа аутентификации в памяти считывателя"
<< std::endl;
return;
}
}
else {
oReader.LoadMfCKey(g_AuthKey);
if (!oReader.AuthMfCard(0, g_fAuthKeyB)) {
std::cout << "Ключ аутентификации [" << std::showbase << std::hex << std::setw(12)
<< g_AuthKey << "] не подошёл" << std::endl;
return;
}
}
oReader.ReadMfClassic(0, oBlocks.data(), oBlocks.size(), &nRead);
std::cout << "Прочитано за " << since(tStartTime).count() << " мс" << std::endl;
size_t nSectorIdx = 0;
size_t nSBlockIdx = 0;
size_t nSTrailer, nAreaN;
uint32_t nAccessBits, nAreaAccess;
bool fAreaValid;
for (size_t i = 0; i < nRead; ++i) {
nSTrailer = (i < 128) ? 3 : 15;
if (0 == nSBlockIdx)
nAccessBits = GetMfAccessBits(oBlocks[i + nSTrailer]);
pBData = &oBlocks[i];
// Выводим байты блока
auto ff(std::cout.flags());
std::cout << std::dec << std::setfill(' ') << std::setw(3) << i << " (" << std::setw(2)
<< nSectorIdx << "). " << std::noshowbase << std::hex << std::setfill('0')
<< std::setw(2) << (uint)pBData->a[0] << ' ' << std::setw(2)
<< (uint)pBData->a[1] << ' ' << std::setw(2) << (uint)pBData->a[2] << ' '
<< std::setw(2) << (uint)pBData->a[3] << ' ' << std::setw(2)
<< (uint)pBData->a[4] << ' ' << std::setw(2) << (uint)pBData->a[5] << ' '
<< std::setw(2) << (uint)pBData->a[6] << ' ' << std::setw(2)
<< (uint)pBData->a[7] << ' ' << std::setw(2) << (uint)pBData->a[8] << ' '
<< std::setw(2) << (uint)pBData->a[9] << ' ' << std::setw(2)
<< (uint)pBData->a[10] << ' ' << std::setw(2) << (uint)pBData->a[11] << ' '
<< std::setw(2) << (uint)pBData->a[12] << ' ' << std::setw(2)
<< (uint)pBData->a[13] << ' ' << std::setw(2) << (uint)pBData->a[14] << ' '
<< std::setw(2) << (uint)pBData->a[15] << std::endl;
std::cout.flags(ff);
nAreaN = (nSBlockIdx * 3) / nSTrailer;
fAreaValid = TryGetMfAreaAccess(nAccessBits, nAreaN, nAreaAccess);
// Если это блок-прицеп,
if (nSBlockIdx == nSTrailer) {
PrintTrailerAccess(fAreaValid, nAreaAccess);
++nSectorIdx;
nSBlockIdx = 0;
}
else {
PrintDataAccess(nAreaN, fAreaValid, nAreaAccess);
++nSBlockIdx;
}
}
std::cout << "-----" << std::endl;
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
std::cout << "Прочитано " << std::dec << nRead << " из " << nBlockMax << " блоков"
<< std::endl;
}
}
void DoReadBlockFromCard(CReader& oReader) {
try {
// Запрашиваем номер сектора и номер блока Mifare
std::cout << "Введите номер сектора и номер блока:" << std::endl;
size_t nSectorIdx, nSBlockIdx;
std::cin >> std::dec >> nSectorIdx >> nSBlockIdx;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (std::cin.fail()) {
std::cin.clear();
std::cout << "Неправильный ввод" << std::endl;
return;
}
size_t nBlockIdx, nSTrailer;
bool fTrailer;
if (nSectorIdx < 32) {
nBlockIdx = (nSectorIdx * 4) + nSBlockIdx;
nSTrailer = 3;
}
else {
nBlockIdx = 128 + ((nSectorIdx - 32) * 16) + nSBlockIdx;
nSTrailer = 15;
}
fTrailer = (nSTrailer == nSBlockIdx);
ilr_mf_block_data rBlockData;
std::cout << "Чтение..." << std::endl;
auto tStartTime = now();
if (g_nRdKeys != 0) {
if (oReader.AuthMfCard2(nBlockIdx, g_fAuthKeyB, g_nRdKeys) == -1) {
std::cout << "Нет подходящего ключа аутентификации в памяти считывателя"
<< std::endl;
return;
}
}
else {
oReader.LoadMfCKey(g_AuthKey);
if (!oReader.AuthMfCard(nBlockIdx, g_fAuthKeyB)) {
std::cout << "Ключ аутентификации [" << std::showbase << std::hex << std::setw(12)
<< g_AuthKey << "] не подошёл" << std::endl;
return;
}
}
oReader.ReadMfClassic(nBlockIdx, &rBlockData, 1);
std::cout << "Прочитано за " << std::dec << since(tStartTime).count() << " мс" << std::endl;
// Выводим байты блока
auto ff(std::cout.flags());
std::cout << std::noshowbase << std::hex << std::setfill('0') << std::setw(2)
<< (uint)rBlockData.a[0] << ' ' << std::setw(2) << (uint)rBlockData.a[1] << ' '
<< std::setw(2) << (uint)rBlockData.a[2] << ' ' << std::setw(2)
<< (uint)rBlockData.a[3] << ' ' << std::setw(2) << (uint)rBlockData.a[4] << ' '
<< std::setw(2) << (uint)rBlockData.a[5] << ' ' << std::setw(2)
<< (uint)rBlockData.a[6] << ' ' << std::setw(2) << (uint)rBlockData.a[7] << ' '
<< std::setw(2) << (uint)rBlockData.a[8] << ' ' << std::setw(2)
<< (uint)rBlockData.a[9] << ' ' << std::setw(2) << (uint)rBlockData.a[10] << ' '
<< std::setw(2) << (uint)rBlockData.a[11] << ' ' << std::setw(2)
<< (uint)rBlockData.a[12] << ' ' << std::setw(2) << (uint)rBlockData.a[13] << ' '
<< std::setw(2) << (uint)rBlockData.a[14] << ' ' << std::setw(2)
<< (uint)rBlockData.a[15] << std::endl;
std::cout.flags(ff);
if (fTrailer) {
auto nAccessBits = GetMfAccessBits(rBlockData);
uint32_t nAreaAccess;
bool fAreaValid;
for (size_t i = 0; i < 4; i++) {
fAreaValid = TryGetMfAreaAccess(nAccessBits, i, nAreaAccess);
if (3 == i)
PrintTrailerAccess(fAreaValid, nAreaAccess);
else
PrintDataAccess(i, fAreaValid, nAreaAccess);
}
}
std::cout << "-----" << std::endl;
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
}
void DoWriteBlockToCard(CReader& oReader) {
try {
// Запрашиваем номер сектора и номер блока Mifare
std::cout << "Введите номер сектора и номер блока:" << std::endl;
size_t nSectorIdx, nSBlockIdx;
std::cin >> std::dec >> nSectorIdx >> nSBlockIdx;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (std::cin.fail()) {
std::cin.clear();
std::cout << "Неправильный ввод" << std::endl;
return;
}
// Запрашиваем значения байтов блока Mifare
std::cout << "Введите байты 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 (16-ричное):"
<< std::endl;
uint aN[16];
std::cin >> std::hex >> aN[0] >> aN[1] >> aN[2] >> aN[3] >> aN[4] >> aN[5] >> aN[6] >>
aN[7] >> aN[8] >> aN[9] >> aN[10] >> aN[11] >> aN[12] >> aN[13] >> aN[14] >> aN[15];
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (std::cin.fail()) {
std::cin.clear();
std::cout << "Неправильный ввод" << std::endl;
return;
}
ilr_mf_block_data rBlockData;
for (size_t i = 0; i < std::size(rBlockData.a); i++)
rBlockData.a[i] = static_cast<uint8_t>(aN[i]);
size_t nBlockIdx;
bool fTrailer;
if (nSectorIdx < 32) {
nBlockIdx = (nSectorIdx * 4) + nSBlockIdx;
fTrailer = (3 == nSBlockIdx);
}
else {
nBlockIdx = 128 + ((nSectorIdx - 32) * 16) + nSBlockIdx;
fTrailer = (15 == nSBlockIdx);
}
// Если это блок-прицеп,
if (fTrailer) {
// Проверяем корректность битов доступа
uint32_t nAccessBits = GetMfAccessBits(rBlockData);
if (((nAccessBits & 0xFFF) ^ (nAccessBits >> 12)) != 0xFFF) {
std::cout << "Некорректное значение битов доступа. Запись отменена" << std::endl;
return;
}
// Выводим ключ A
auto nKeyA = GetMfClassicKey(rBlockData, false);
std::cout << "Ключ A: " << std::showbase << std::hex << std::setw(12) << nKeyA
<< std::endl;
// Выводим ключ B
auto nKeyB = GetMfClassicKey(rBlockData, true);
std::cout << "Ключ B: " << std::hex << std::setw(12) << nKeyB << std::endl;
}
std::cout << "Запись..." << std::endl;
auto tStartTime = now();
if (g_nRdKeys != 0) {
if (oReader.AuthMfCard2(nBlockIdx, g_fAuthKeyB, g_nRdKeys) == -1) {
std::cout << "Нет подходящего ключа аутентификации" << std::endl;
return;
}
}
else {
oReader.LoadMfCKey(g_AuthKey);
if (!oReader.AuthMfCard(nBlockIdx, g_fAuthKeyB)) {
std::cout << "Ключ аутентификации не подошёл" << std::endl;
return;
}
}
size_t nWritten = 0;
oReader.WriteMfClassic(nBlockIdx, &rBlockData, 1, &nWritten);
std::cout << "Записано за " << since(tStartTime).count() << " мс" << std::endl;
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
}
void WriteAuthKeyToReader(CReader& oReader) {
try {
// Запрашиваем номер ключа и значение ключа аутентификации Mifare
std::cout << "Введите номер ключа (10-тичное) и значение ключа (16-тичное):" << std::endl;
size_t nIdx;
std::cin >> std::dec >> nIdx >> std::hex >> nNewKey;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (std::cin.fail() || (nNewKey > 0xffffffffffff)) {
std::cin.clear();
std::cout << "Неправильный ввод" << std::endl;
return;
}
if (nNewKey < 0)
nNewKey = CMifareClassicKey::kDefault;
std::cout << "Запись..." << std::endl;
auto tStartTime = now();
oReader.WriteMfCKey(nIdx, g_fAuthKeyB, &nNewKey, 1);
std::cout << "Записано за " << std::dec << since(tStartTime).count() << " мс" << std::endl;
g_aSavedRdKeys[g_fAuthKeyB][nIdx] = nNewKey;
// Сохраняем ключ в файл настроек
SaveSettings();
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
}
void DoSwitchAuthKeyType() {
std::cout << "Введите тип ключа: A или B:" << std::endl;
char ch;
std::cin >> ch;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (std::cin.fail()) {
std::cin.clear();
std::cout << "Неправильный ввод" << std::endl;
return;
}
ch = static_cast<char>(toupper(static_cast<int>(ch)));
if (ch == 'A')
g_fAuthKeyB = false;
else if (ch == 'B')
g_fAuthKeyB = true;
else {
std::cout << "Неправильный ввод" << std::endl;
return;
}
// Сохраняем тип ключа в файл настроек
SaveSettings();
}
void DoEnterAuthKey() {
std::cout << "Введите ключ аутентификации (16-ричное):" << std::endl;
std::cin >> std::hex >> nNewKey;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (std::cin.fail() || (nNewKey > 0xffffffffffff)) {
std::cin.clear();
std::cout << "Неправильный ввод" << std::endl;
return;
}
if (nNewKey < 0)
nNewKey = CMifareClassicKey::kDefault;
g_AuthKey = nNewKey;
// Сохраняем ключ в файл настроек
SaveSettings();
}
void DoSelectRdAuthKeys() {
std::cout << "Введите номер ключа (0..15) или '=' + битовую маске (16-ричное):" << std::endl;
std::string sInput;
std::getline(std::cin, sInput);
if (sInput.empty()) {
std::cout << "Неправильный ввод" << std::endl;
return;
}
char* p;
if (sInput.front() == '=')
g_nRdKeys = static_cast<uint>(strtoul(&sInput[1], &p, 16));
else {
const char* pszDelimiters = " ,;";
p = nullptr;
char* pToken;
int nKeyIdx;
g_nRdKeys = 0;
pToken = strtok_r(sInput.data(), pszDelimiters, &p);
while (pToken != nullptr) {
nKeyIdx = atoi(pToken);
if ((nKeyIdx >= 0) && (nKeyIdx < 16))
g_nRdKeys |= (1u << nKeyIdx);
pToken = strtok_r(nullptr, pszDelimiters, &p);
}
}
// Сохраняем биты ключей в файл настроек
SaveSettings();
}
void ShowSavedReaderKeys() {
for (size_t i = 0; i < std::size(g_aSavedRdKeys); ++i) {
std::cout << "Сохранённые ключи " << (i ? 'B' : 'A') << ':' << std::endl;
for (size_t j = 0; j < std::size(g_aSavedRdKeys[i]); ++j) {
if (g_aSavedRdKeys[i][j] != (ilr_mf_classic_key)-1)
std::cout << std::dec << std::setw(2) << j << ": " << std::hex << std::setw(12)
<< g_aSavedRdKeys[i][j] << std::endl;
else
std::cout << std::dec << std::setw(2) << j << ": -" << std::endl;
}
std::cout << std::endl;
}
}
bool DoConnectTo(CILR& oILR, CReader& oReader) {
CReaderSearch oSearch(oILR.GetSearch());
{
// Включаем поиск считывателя Z-2 MF CCID (по умолчанию выключен)
oSearch.GetOptions(rOptions);
oSearch.SetOptions(rOptions);
}
// Ищем считыватели
std::cout << "Поиск считывателей..." << std::endl;
oSearch.Scan();
auto nCount = oSearch.GetReaderCount();
if (0 == nCount) {
std::cout << "Считыватель не найден" << std::endl;
return false;
}
std::cout << "Найдено " << nCount << ':' << std::endl;
bool fFound = false;
for (size_t i = 0; i < nCount; i++) {
oSearch.GetReaderInfo(i, rInfo);
// Если порт занят, пропускаем его
if (*rInfo.pszConnect != '\0')
continue;
if (CReader::GetSupportedRewrittenCardTypes(rInfo.nModel, rInfo.nFwVersion) &
fFound = true;
break;
}
}
if (!fFound) {
std::cout << "Считыватель не поддерживает чтение/запись карт Mifare Classic" << std::endl;
return false;
}
// Подключаемся к считывателю
std::cout << "Подключение к считывателю [" << kPortTypeNames[rInfo.nPortType] << ": "
<< rInfo.pszPortName << "]..." << std::endl;
oReader = oILR.GetReader(rInfo.nPortType, rInfo.pszPortName);
// Отключаем авто поиск карт
oReader.SetAutoScan(false);
oReader.GetOptions(rOptions);
rOptions.nConnectModel = rInfo.nModel;
oReader.SetOptions(rOptions);
}
oReader.Connect();
oReader.GetReaderInfo(rInfo);
g_nReaderSn = rInfo.nSn;
std::stringstream ss;
ss << kReaderModelNames[rInfo.nModel];
if (rInfo.nSn != -1)
ss << " с/н:" << rInfo.nSn;
if (rInfo.nFwVersion != 0)
ss << " прошивка:" << ReaderVersionToStr(rInfo.nFwVersion);
if (rInfo.nFwBuildDate != 0)
ss << " сборка " << TimeToStr(rInfo.nFwBuildDate);
std::cout << "Считыватель успешно подключён [" << ss.str() << ']' << std::endl;
return true;
}
int main() {
try {
#ifdef ILR_LOG
#ifdef ILR_LOG_FILE
// Очищаем лог файл
std::ofstream file(kLogFileName, std::ios_base::out | std::ios_base::trunc);
file.close();
#endif
CILR::SetLogCallback(LogCallback);
CILR::SetLogLevel(ILR_LOG_LEVEL_DEBUG);
#endif
// Ищем считыватель и подключаемся к нему
CILR oILR;
CReader oReader;
if (!DoConnectTo(oILR, oReader))
return 0;
// Загружаем настройки из файла
LoadSettings();
// Основной цикл программы
while (true) {
std::cout << "Поиск карты Mifare Classic..." << std::endl;
oReader.Scan();
oReader.GetCardInfo(rCI);
bool fCardFound = IsMfClassicMode(rCI.nType, rCI.nSL);
// Если карта Mifare Classic найдена,
if (fCardFound)
std::cout << kCardTypeNames[rCI.nType] << ' ' << CardUIDToStr(rCI.nType, rCI.rUID)
<< std::endl;
else // Mifare Classic не найдена
std::cout << "Карта не найдена" << std::endl;
std::cout << "-----" << std::endl;
std::cout << "Введите номер команды:" << std::endl;
std::cout << "1 - Искать снова" << std::endl;
if (fCardFound) {
std::cout << "2 - Прочитать данные из карты" << std::endl;
std::cout << "3 - Прочитать блок данных из карты..." << std::endl;
std::cout << "4 - Записать блок данных на карту..." << std::endl;
}
std::cout << "5 - Записать ключ аутентификации в считыватель..." << std::endl;
std::cout << "6 - Показать сохранённые ключи считывателя" << std::endl;
std::cout << "7 - Переключить тип ключа A или B [" << (g_fAuthKeyB ? 'B' : 'A')
<< "]..." << std::endl;
std::cout << "8 - Выбрать ключи аутентификации считывателя [" << std::hex << g_nRdKeys
<< "]..." << std::endl;
std::cout << "9 - Ввести ключ аутентификации [" << std::showbase << std::hex
<< std::setw(12) << g_AuthKey << "]..." << std::endl;
std::cout << "0 - Выйти из программы" << std::endl;
int nCommand;
std::cin >> nCommand;
if (std::cin.fail()) {
std::cin.clear();
nCommand = -1;
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
switch (nCommand) {
case 1:
break;
case 2:
if (fCardFound)
DoReadAllFromCard(oReader);
break;
case 3:
if (fCardFound)
DoReadBlockFromCard(oReader);
break;
case 4:
if (fCardFound)
DoWriteBlockToCard(oReader);
break;
case 5:
WriteAuthKeyToReader(oReader);
break;
case 6:
ShowSavedReaderKeys();
break;
case 7:
DoSwitchAuthKeyType();
break;
case 8:
DoSelectRdAuthKeys();
break;
case 9:
DoEnterAuthKey();
break;
case 0:
return 0;
default:
std::cout << "Неправильный ввод" << std::endl;
break;
}
}
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
Класс для инициализации/финализации библиотеки SDK.
Definition: ilr_cpp_helpers.h:2607
CReaderSearch GetSearch()
Создаёт дескриптор поиска считывателей.
Definition: ilr_cpp_helpers.h:2761
CReader GetReader(ilr_port_type nPortType, const char *pszPortName)
Создаёт дескриптор считывателя.
Definition: ilr_cpp_helpers.h:2767
Класс ключа аутентификации Mifare Classic.
Definition: ilr_cpp_helpers.h:231
Класс поиска считывателей.
Definition: ilr_cpp_helpers.h:583
Класс считывателя.
Definition: ilr_cpp_helpers.h:996
void ReadMfClassic(size_t nBlockIdx, ilr_mf_block_data *pBuf, size_t nBlockCount, size_t *pRead=nullptr)
Читает данные карты Mifare Classic или Mifare Plus SL1.
Definition: ilr_cpp_helpers.h:2332
void SetAutoScan(bool fEnable=true, bool fWait=true)
Включает/выключает автоматическое сканирование карт.
Definition: ilr_cpp_helpers.h:2242
void Connect(bool fReconnect=false)
Подключается к считывателю.
Definition: ilr_cpp_helpers.h:2197
int AuthMfCard2(size_t nAddress, bool fKeyB, uint32_t nKeys=0xFFFF)
Авторизует сектор карты Mifare Classic / Plus, используя ключи считывателя.
Definition: ilr_cpp_helpers.h:2316
bool AuthMfCard(size_t nAddress, bool fKeyB)
Авторизует сектор карты Mifare Classic/Plus.
Definition: ilr_cpp_helpers.h:2298
void SetOptions(const ilr_reader_options &rOptions)
Устанавливает параметры считывателя.
Definition: ilr_cpp_helpers.h:2189
void Scan(bool fReset=false, bool fPowerOff=true)
Ищет карты.
Definition: ilr_cpp_helpers.h:2227
void WriteMfClassic(size_t nBlockIdx, const ilr_mf_block_data *pData, size_t nBlockCount, size_t *pWritten=nullptr)
Пишет данные карты Mifare Classic или Mifare Plus SL1.
Definition: ilr_cpp_helpers.h:2348
void WriteMfCKey(size_t nIdx, bool fKeyB, const ilr_mf_classic_key *pKeys, size_t nCount, size_t *pWritten=nullptr)
Записывает ключи аутентификации Mifare Classic в память считывателя.
Definition: ilr_cpp_helpers.h:2472
void LoadMfCKey(const ilr_mf_classic_key &nKey)
Загружает ключ для авторизации сектора Mifare Classic / Plus SL1.
Definition: ilr_cpp_helpers.h:2290
void GetReaderInfo(ilr_reader_info &rInfo) const
Возвращает информацию о считывателе.
Definition: ilr_cpp_helpers.h:2223
void GetOptions(ilr_reader_options &rOptions) const
Возвращает параметры считывателя.
Definition: ilr_cpp_helpers.h:2193
bool GetCardInfo(ilr_card_info &rInfo) const
Возвращает информацию о карте в поле считывателя.
Definition: ilr_cpp_helpers.h:2237
int64_t ilr_mf_classic_key
Ключ аутентификации Mifare Classic.
Definition: ilreaders.h:610
@ ILR_RWCT_F_MF_CLASSIC
Mifare Classic или Plus SL1.
Definition: ilreaders.h:643
@ ILR_READER_CCID
Definition: ilreaders.h:467
Заголовочный файл SDK Readers с классами-помощниками C++.
size_t GetNumberOfMfBlocks(uint32_t nMemSize)
Вычисляет количество блоков карты Mifare Classic/Plus по размеру её памяти.
Definition: ilr_cpp_helpers.h:2881
auto since(std::chrono::time_point< clock_t, duration_t > const &start)
Возвращает интервал времени в миллисекундах от времени start до текущего времени.
Definition: ilr_cpp_helpers.h:2802
std::chrono::steady_clock::time_point now()
Definition: ilr_cpp_helpers.h:2791
CMifareClassicKey GetMfClassicKey(const ilr_mf_block_data &rTrailerData, bool fKeyB)
Извлекает ключ аутентификации из блока-прицепа Mifare Classic.
Definition: ilr_cpp_helpers.h:2989
Заголовочный файл API SDK Readers.
#define ILR_CALL
Макрос, определяющий соглашение о вызове функций.
Definition: ilreaders.h:56
ilr_log_level
Уровень лога.
Definition: ilreaders.h:319
@ ILR_LOG_LEVEL_DEBUG
Отладочные сообщения.
Definition: ilreaders.h:349
@ ILR_READER_MODEL_UNKNOWN
Definition: ilreaders.h:213
Информация о карте.
Definition: ilreaders.h:596
ilr_card_type nType
Тип карты.
Definition: ilreaders.h:597
uint32_t nMemSize
Размер памяти карты (в байтах).
Definition: ilreaders.h:599
ilr_mf_plus_sl nSL
Уровень безопасности Mifare Plus.
Definition: ilreaders.h:600
ilr_card_uid rUID
Номер карты.
Definition: ilreaders.h:598
Данные блока Mifare Classic/Plus.
Definition: ilreaders.h:631
uint8_t a[16]
Байты блока.
Definition: ilreaders.h:632
Информация о считывателе.
Definition: ilreaders.h:295
ilr_reader_model nModel
Definition: ilreaders.h:304
uint32_t nFwVersion
Definition: ilreaders.h:310
const char * pszConnect
Definition: ilreaders.h:302
const char * pszPortName
Definition: ilreaders.h:299
int64_t nFwBuildDate
Definition: ilreaders.h:313
ilr_port_type nPortType
Definition: ilreaders.h:297
int nSn
Definition: ilreaders.h:306
Настройки считывателя.
Definition: ilreaders.h:663
ilr_reader_model nConnectModel
Definition: ilreaders.h:665
Настройки поиска считывателей.
Definition: ilreaders.h:474
uint32_t nReaderTypes
Definition: ilreaders.h:479