#include <fstream>
#include <iomanip>
#include <iostream>
#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";
#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];
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;
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:
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;
}
}
int nWiegand;
if ((64 == nDataRate) && (8 == nModulation) && (2 == nMaxBlock)) {
std::cout << "Эмулирует Em-Marine " << CardUIDToStr(nType, rUID) << std::endl;
}
else if ((50 == nDataRate) && (5 == nModulation) && (3 == nMaxBlock)) {
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;
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];
std::cout << "Запись..." << std::endl;
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];
std::cout << "Запись..." << std::endl;
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;
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;
}
}
{
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] <<
": "
}
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
if (!DoConnectTo(oILR, oReader))
return 0;
while (true) {
std::cout << "Поиск карты Temic..." << std::endl;
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;
}
Класс ID карты.
Definition: ilr_cpp_helpers.h:51
bool IsEmpty() const
Проверяет пустой ли ID карты.
Definition: ilr_cpp_helpers.h:93
Класс для инициализации/финализации библиотеки 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
Класс поиска считывателей.
Definition: ilr_cpp_helpers.h:583
Класс считывателя.
Definition: ilr_cpp_helpers.h:996
void WriteTemic(size_t nBlockIdx, const uint32_t *pData, size_t nBlockCount, bool fLock=false, int nScanParam=-1, size_t *pWritten=nullptr)
Пишет данные карты Temic.
Definition: ilr_cpp_helpers.h:2544
void SetAutoScan(bool fEnable=true, bool fWait=true)
Включает/выключает автоматическое сканирование карт.
Definition: ilr_cpp_helpers.h:2242
void SetScanTemic(bool fEnable=true)
Вкл/выкл сканирование карт Temic (для Z-2 Rd-All и Z-2 EHR).
Definition: ilr_cpp_helpers.h:2518
void Connect(bool fReconnect=false)
Подключается к считывателю.
Definition: ilr_cpp_helpers.h:2197
void SetOptions(const ilr_reader_options &rOptions)
Устанавливает параметры считывателя.
Definition: ilr_cpp_helpers.h:2189
static void DecodeTemicEmMarine(const uint32_t *pData3, size_t nBlockCount, ilr_card_uid &rUID, bool *pConfigOk=nullptr)
Декодирует номер Em-Marine из данных блоков 0..2 карты Temic.
Definition: ilr_cpp_helpers.h:2577
static void EncodeTemicHid(const ilr_card_uid &rUID, uint32_t *pBuf4, size_t nBlockCount, int nWiegand)
Кодирует данные для эмуляции HID, для записи в блоки 0..3.
Definition: ilr_cpp_helpers.h:2585
void Scan(bool fReset=false, bool fPowerOff=true)
Ищет карты.
Definition: ilr_cpp_helpers.h:2227
void LoadTemicPassword(const int64_t nPassword)
Загружает пароль Temic в память объекта считывателя.
Definition: ilr_cpp_helpers.h:2504
static void EncodeTemicEmMarine(const ilr_card_uid &rUID, uint32_t *pBuf3, size_t nBlockCount)
Кодирует данные для эмуляции Em-Marine, для записи в блоки 0..2.
Definition: ilr_cpp_helpers.h:2572
static void DecodeTemicHid(const uint32_t *pData4, size_t nBlockCount, ilr_card_uid &rUID, int &nWiegand, bool *pConfigOk=nullptr)
Декодирует номер HID из данных блоков 0..3 карты Temic.
Definition: ilr_cpp_helpers.h:2590
void ReadTemic(size_t nBlockIdx, uint32_t *pBuf, size_t nBlockCount, int nScanParam=-1, size_t *pRead=nullptr)
Читает данные карты Temic.
Definition: ilr_cpp_helpers.h:2528
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
@ ILR_RWCT_F_TEMIC
Temic.
Definition: ilreaders.h:641
@ ILR_READER_CCID
Definition: ilreaders.h:467
Заголовочный файл SDK Readers с классами-помощниками C++.
#define GET_BIT(val, bitN)
Возвращает true если бит bitN установлен в числе val.
Definition: ilr_cpp_helpers.h:2779
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
Заголовочный файл 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_CARD_EM_MARINE
Em-Marine.
Definition: ilreaders.h:263
@ ILR_CARD_UNKNOWN
Не известно.
Definition: ilreaders.h:262
@ ILR_CARD_HID
HID.
Definition: ilreaders.h:264
@ ILR_CARD_TEMIC
Temic (T5557).
Definition: ilreaders.h:270
@ ILR_READER_MODEL_UNKNOWN
Definition: ilreaders.h:213
Информация о карте.
Definition: ilreaders.h:596
ilr_card_type nType
Тип карты.
Definition: ilreaders.h:597
ilr_card_uid rUID
Номер карты.
Definition: ilreaders.h:598
Информация о считывателе.
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