#include <fstream>
#include <iomanip>
#include <iostream>
#include "../ilr_cpp_helpers.h"
#define ILR_LOG
#define ILR_LOG_FILE
using namespace ilr;
const int64_t kPassword = -1;
#ifdef ILR_LOG
const char kLogLevelChars[] = {'-', 'E', 'W', 'I', 'D'};
const char kLogFileName[] = "ilreaders.log";
void 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
void DoReadTemic(CReader& oReader) {
size_t nRead = 0;
std::ios_base::fmtflags ff(std::cout.flags());
try {
const uint kBitRates[8] = {8, 16, 32, 40, 50, 64, 100, 128};
const char* kPskCf[4] = {"RF/2", "RF/4", "RF/8", "Reserved"};
const char* kFlagStrs[2] = {"False", "True"};
std::cout << "Чтение данных карты..." << std::endl;
uint aBlocks[10];
auto tStartTime = now();
oReader.LoadTemicPassword(kPassword);
oReader.ReadTemic(0, aBlocks, std::size(aBlocks), -1, &nRead);
std::cout << "Прочитано за " << since(tStartTime).count() << " мс" << std::endl;
uint nConfig = 0;
uint nDataRate = 0;
uint nModulation = 0;
uint nMaxBlock = 0;
uint nBlockData;
uint8_t* pBytes;
for (size_t i = 0; i < std::size(aBlocks); ++i) {
nBlockData = aBlocks[i];
pBytes = (uint8_t*)&nBlockData;
std::cout << std::noshowbase << std::dec << std::setw(2) << i << ". " << std::hex
<< std::setw(2) << (uint)pBytes[0] << ' ' << std::setw(2) << (uint)pBytes[1]
<< ' ' << std::setw(2) << (uint)pBytes[2] << ' ' << std::setw(2)
<< (uint)pBytes[3] << ' ';
switch (i) {
case 0:
{
std::cout << "Конфигурация" << std::endl;
nConfig = nBlockData;
bool fXMode = GET_BIT(nConfig, 9);
if (fXMode)
std::cout << "\tРежим: X-Mode" << std::endl;
else
std::cout << "\tРежим: e5550 Compatibility Mode" << std::endl;
std::cout << "\tMaster Key: " << std::dec << ((nConfig >> 4) & 0xf)
<< std::endl;
if (fXMode)
nDataRate = ((nConfig >> 10) & 0x3F) * 2 + 2;
else
nDataRate = kBitRates[(nConfig >> 10) & 7];
std::cout << "\tData Bit Rate: RF/" << std::dec << nDataRate << std::endl;
nModulation = ((nConfig >> 20) & 0xF) | (((nConfig >> 8) & 1) << 4);
std::cout << "\tModulation: ";
switch (nModulation) {
case 0:
std::cout << "Direct";
break;
case 1:
std::cout << "PSK1";
break;
case 2:
std::cout << "PSK2";
break;
case 3:
std::cout << "PSK3";
break;
case 4:
std::cout << "FSK1";
break;
case 5:
std::cout << "FSK2";
break;
case 6:
std::cout << "FSK1a";
break;
case 7:
std::cout << "FSK2a";
break;
case 8:
std::cout << "Manchester";
break;
case 0x10:
std::cout << "Biphase('50)";
break;
case 0x18:
std::cout << "Biphase('57)";
break;
}
std::cout << std::endl;
std::cout << "\tPSK-CF: " << kPskCf[(nConfig >> 18) & 3] << std::endl;
std::cout << "\tAOR: " << kFlagStrs[GET_BIT(nConfig, 17)] << std::endl;
if (fXMode)
std::cout << "\tOTP: " << kFlagStrs[GET_BIT(nConfig, 16)] << std::endl;
nMaxBlock = (nConfig >> 29) & 7;
std::cout << "\tMAX-BLOCK: " << std::dec << nMaxBlock << std::endl;
std::cout << "\tPassword: " << kFlagStrs[GET_BIT(nConfig, 28)] << std::endl;
if (fXMode) {
std::cout << "\tSST-Sequence Start Marker: "
<< kFlagStrs[GET_BIT(nConfig, 27)] << std::endl;
std::cout << "\tFastwrite: " << kFlagStrs[GET_BIT(nConfig, 26)]
<< std::endl;
std::cout << "\tInverse Data: " << kFlagStrs[GET_BIT(nConfig, 25)]
<< std::endl;
}
else
std::cout << "\tST-Sequence Terminator: " << kFlagStrs[GET_BIT(nConfig, 27)]
<< std::endl;
std::cout << "\tPOR delay: " << kFlagStrs[GET_BIT(nConfig, 24)] << std::endl;
break;
}
case 7:
if (GET_BIT(nConfig, 28))
std::cout << "Пароль" << std::endl;
else
std::cout << "Данные пользователя" << std::endl;
break;
case 8:
std::cout << "Данные производителя" << std::endl;
std::cout << "\tACL: " << std::showbase << std::hex << std::setw(2)
<< (nBlockData & 0xff) << std::endl;
std::cout << "\tMFC: " << std::setw(2) << ((nBlockData >> 8) & 0xff) << std::endl;
std::cout << "\tICR: " << std::setw(2) << ((nBlockData >> 16) & 0xff) << std::endl;
std::cout << "\tMSN LotID: " << std::dec << (nBlockData >> 24) << std::endl;
break;
case 9:
std::cout << "Данные производителя" << std::endl;
std::cout << "\tLotID: " << std::dec << (nBlockData & 0xFFF) << std::endl;
std::cout << "\twafer #: " << std::showbase << std::hex << std::setw(2)
<< ((nBlockData >> 12) & 0x3F) << std::endl;
std::cout << "\tdie on wafer #: " << std::setw(2) << ((nBlockData >> 18) & 0x3FFF)
<< std::endl;
break;
default:
std::cout << "Данные пользователя" << std::endl;
break;
}
}
CCardUID rUID;
int nWiegand;
if ((64 == nDataRate) && (8 == nModulation) && (2 == nMaxBlock)) {
oReader.DecodeTemicEmMarine(aBlocks, 3, rUID);
if (!rUID.IsEmpty())
std::cout << "Эмулирует Em-Marine " << CardUIDToStr(nType, rUID) << std::endl;
}
else if ((50 == nDataRate) && (5 == nModulation) && (3 == nMaxBlock)) {
oReader.DecodeTemicHid(aBlocks, 4, rUID, nWiegand);
if (!rUID.IsEmpty())
std::cout << "Эмулирует HID (W" << std::dec << nWiegand << ") "
<< CardUIDToStr(nType, rUID) << std::endl;
}
std::cout << "-----" << std::endl;
std::cout.flags(ff);
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
std::cout.flags(ff);
std::cout << "Прочитано " << nRead << " блока из 10" << std::endl;
}
}
void DoWriteTemic(CReader& oReader) {
size_t nWritten = 0;
try {
std::cout << "Введите номер блока и байты 0 1 2 3 (16-ричное):" << std::endl;
uint nBlockN, a[4];
std::cin >> std::hex >> nBlockN >> a[0] >> a[1] >> a[2] >> a[3];
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (std::cin.fail()) {
std::cout << "Неправильный ввод" << std::endl;
return;
}
uint8_t aBytes[4];
for (size_t i = 0; i < std::size(aBytes); ++i)
aBytes[i] = (uint8_t)a[i];
std::cout << "Запись..." << std::endl;
auto tStartTime = now();
oReader.LoadTemicPassword(kPassword);
oReader.WriteTemic(nBlockN, (uint*)aBytes, 1, false, -1, &nWritten);
std::cout << "Записано за " << since(tStartTime).count() << " мс" << std::endl;
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
std::cout << "Записано " << nWritten << " блока из 1" << std::endl;
}
}
void DoWriteEmMarine(CReader& oReader) {
size_t nWritten = 0;
try {
std::cout
<< "Введите номер Em-Marine: код производителя (16-ричное), серия (10-тичное), номер "
"(10-тичное):"
<< std::endl;
uint nFacility, nSeries, nNumber;
std::cin >> std::hex >> nFacility >> std::dec >> nSeries >> nNumber;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (std::cin.fail()) {
std::cout << "Неправильный ввод" << std::endl;
return;
}
ilr_card_uid rUID;
rUID.em_marine.nSeries = static_cast<uint8_t>(nSeries);
rUID.em_marine.nNumber = static_cast<uint16_t>(nNumber);
rUID.em_marine.nFacility = static_cast<uint16_t>(nFacility);
rUID.nLength = 5;
uint aBlocks[3];
oReader.EncodeTemicEmMarine(rUID, aBlocks, std::size(aBlocks));
std::cout << "Запись..." << std::endl;
auto tStartTime = now();
oReader.LoadTemicPassword(kPassword);
oReader.WriteTemic(0, aBlocks, std::size(aBlocks), false, -1, &nWritten);
std::cout << "Записано за " << since(tStartTime).count() << " мс" << std::endl;
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
std::cout << "Записано " << nWritten << " блока из 3" << std::endl;
}
}
void DoWriteHID(CReader& oReader) {
size_t nWritten = 0;
try {
std::cout << "Введите номер HID: виганд (10-тичное), код производителя (16-ричное), номер "
"(10-тичное):"
<< std::endl;
int nWiegand, nNumber;
uint nFacility;
std::cin >> std::dec >> nWiegand >> std::hex >> nFacility >> std::dec >> nNumber;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
if (std::cin.fail() || (nWiegand < 10) || (nWiegand > 37)) {
std::cout << "Неправильный ввод" << std::endl;
return;
}
ilr_card_uid rUID;
auto nFSize = static_cast<size_t>(nWiegand - 2 - 16);
auto nFCount = (nFSize / 8);
if ((nFSize % 8) != 0)
++nFCount;
*(uint16_t*)&rUID.aBytes[0] = static_cast<uint16_t>(nNumber);
if (nFCount > 0)
memcpy(&rUID.aBytes[2], &nFacility, nFCount);
rUID.nLength = static_cast<uint8_t>(nFCount + 2);
uint aBlocks[4];
oReader.EncodeTemicHid(rUID, aBlocks, std::size(aBlocks), nWiegand);
std::cout << "Запись..." << std::endl;
auto tStartTime = now();
oReader.LoadTemicPassword(kPassword);
oReader.WriteTemic(0, aBlocks, std::size(aBlocks), false, -1, &nWritten);
std::cout << "Записано за " << since(tStartTime).count() << " мс" << std::endl;
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
std::cout << "Записано " << nWritten << " блока из 4" << std::endl;
}
}
void DoInitTemic(CReader& oReader) {
try {
uint nConfigData = 0x40801400;
std::cout << "Запись..." << std::endl;
auto tStartTime = now();
oReader.LoadTemicPassword(kPassword);
oReader.WriteTemic(0, &nConfigData, 1, false, 0x0002);
std::cout << "Записано за " << since(tStartTime).count() << " мс\n" << std::endl;
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
}
bool DoConnectTo(CILR& oILR, CReader& oReader) {
CReaderSearch oSearch(oILR.GetSearch());
{
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);
continue;
fFound = true;
break;
}
}
if (!fFound) {
std::cout << "Считыватель не поддерживает чтение/запись карт Temic" << std::endl;
return false;
}
std::cout <<
"Подключение к считывателю [" << kPortTypeNames[rInfo.
nPortType] <<
": "
oReader.SetAutoScan(false);
oReader.GetOptions(rOptions);
oReader.SetOptions(rOptions);
}
oReader.Connect();
oReader.GetReaderInfo(rInfo);
std::stringstream ss;
ss << kReaderModelNames[rInfo.
nModel];
ss <<
" с/н:" << rInfo.
nSn;
ss <<
" прошивка:" << ReaderVersionToStr(rInfo.
nFwVersion);
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);
#endif
CILR oILR;
CReader oReader;
if (!DoConnectTo(oILR, oReader))
return 0;
oReader.SetScanTemic();
while (true) {
std::cout << "Поиск карты Temic..." << std::endl;
oReader.Scan();
oReader.GetCardInfo(rCI);
if (fCardFound)
std::cout << kCardTypeNames[rCI.
nType] <<
' ' << CardUIDToStr(rCI.
nType, rCI.
rUID)
<< std::endl;
else
std::cout << "Карта Temic не найдена" << std::endl;
std::cout << "-----" << std::endl;
std::cout << "Введите номер команды:" << std::endl;
std::cout << "1 - Искать карту снова" << std::endl;
std::cout << "2 - Записать стандартную конфигурацию Temic" << std::endl;
if (fCardFound) {
std::cout << "3 - Прочитать данные из карты" << std::endl;
std::cout << "4 - Записать данные на карту..." << std::endl;
std::cout << "5 - Записать Em-Marine..." << std::endl;
std::cout << "6 - Записать HID..." << 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 0:
return 0;
case 1:
break;
case 2:
if (!fCardFound)
DoInitTemic(oReader);
break;
case 3:
if (fCardFound)
DoReadTemic(oReader);
break;
case 4:
if (fCardFound)
DoWriteTemic(oReader);
break;
case 5:
if (fCardFound)
DoWriteEmMarine(oReader);
break;
case 6:
if (fCardFound)
DoWriteHID(oReader);
break;
default:
std::cout << "Неправильный ввод" << std::endl;
break;
}
}
}
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
@ ILR_RWCT_F_TEMIC
Temic.
Definition: ilreaders.h:628
@ ILR_READER_CCID
Definition: ilreaders.h:454
Заголовочный файл API SDK Readers.
ilr_log_level
Уровень лога.
Definition: ilreaders.h:306
@ ILR_LOG_LEVEL_DEBUG
Отладочные сообщения.
Definition: ilreaders.h:336
@ ILR_CARD_EM_MARINE
Em-Marine.
Definition: ilreaders.h:250
@ ILR_CARD_UNKNOWN
Не известно.
Definition: ilreaders.h:249
@ ILR_CARD_HID
HID.
Definition: ilreaders.h:251
@ ILR_CARD_TEMIC
Temic (T5557).
Definition: ilreaders.h:257
@ ILR_READER_MODEL_UNKNOWN
Definition: ilreaders.h:200
Информация о карте.
Definition: ilreaders.h:583
ilr_card_type nType
Тип карты.
Definition: ilreaders.h:584
ilr_card_uid rUID
Номер карты.
Definition: ilreaders.h:585
Информация о считывателе.
Definition: ilreaders.h:282
ilr_reader_model nModel
Definition: ilreaders.h:291
uint32_t nFwVersion
Definition: ilreaders.h:297
const char * pszConnect
Definition: ilreaders.h:289
const char * pszPortName
Definition: ilreaders.h:286
int64_t nFwBuildDate
Definition: ilreaders.h:300
ilr_port_type nPortType
Definition: ilreaders.h:284
int nSn
Definition: ilreaders.h:293
Настройки считывателя.
Definition: ilreaders.h:656
ilr_reader_model nConnectModel
Definition: ilreaders.h:658
Настройки поиска считывателей.
Definition: ilreaders.h:461
uint32_t nReaderTypes
Definition: ilreaders.h:466