Работа напрямую с NTAG/MIFARE Ultralight через (A?)PDU
разрабатываю нативную компоненту для 1С. необходимо подключить считыватель CRT-310NR01, на который есть подробная но кривоватая документация. Проблема в том, что считыватель достаточно древний видимо, и в наборе команд есть команды для чтения и записи MIFARE Ultralight, но с NTAG216 они срабатывают только до 15го сектора. и далее считыватель возвращает ошибку. В наборе его команд есть возможность посылать напрямую команду в метку без обработки считывателем ('C','Z','4'), но не могу нигде найти примера как это делать пробовал записывать 0x30[номер страницы][crc] как описано в даташите на NTAG216, но метка команду отбивает, подскажите (кто сталкивался, если есть подобный опыт) где можно найти легковесную библиотеку которая подобные команды уже реализует или пример на любом си-подобном языке. Или может у меня ошибка в функции расчета CRC?
iso14443a_crc(uint8_t *pbtData, size_t szLen)
{
uint32_t wCrc = 0x6363;
do {
uint8_t bt;
bt = *pbtData++;
bt = (bt ^ (uint8_t)(wCrc & 0x00FF));
bt = (bt ^ (bt << 4));
wCrc = (wCrc >> 8) ^ ((uint32_t)bt << 8) ^ ((uint32_t)bt << 3) ^ ((uint32_t)bt >> 4);
} while (--szLen);
return (uint8_t)(wCrc & 0xFF) | (uint8_t)((wCrc >> 8) & 0xFF);
}
bool readPageAdv(HANDLE hPort, uint16_t pageNumber)
{
BYTE response = 0;
BYTE st1 = 0;
BYTE st0 = 0;
char atr_buffer[200];
memset(atr_buffer, 0, sizeof(atr_buffer));
int len = 0;
uint32_t cmd_buffer = 0;
cmd_buffer = '0' | pageNumber << 8;
cmd_buffer |= (iso14443a_crc((BYTE*)&cmd_buffer, 2)<< 16);
RS232_ExeCommand(hPort, 'Z', '4', sizeof(cmd_buffer), (BYTE*)&cmd_buffer, &response, &st1, &st0, &len, (BYTE*)atr_buffer);
if (response != 'P')
{
std::cout << "readPage fault!" << std::endl;
std::cout << "st0 = " << st0 << std::endl;
std::cout << "st1 = " << st1 << std::endl;
std::cout << "ATR: ";
std::ios::fmtflags f(std::cout.flags());
for (int i = 0; i < len; i++)
{
std::cout << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex;
std::cout << (int)(0xff & atr_buffer[i]) << ' ';
}
std::cout.flags(f);
std::cout << " END ATR " << std::endl;
}
else
{
std::cout << "readPage OK!" << std::endl;
std::cout << "st0 = " << st0 << std::endl;
std::cout << "st1 = " << st1 << std::endl;
std::cout << "status_description(): " << status_description(st1, st0) << std::endl;
std::cout << "ATR: ";
std::ios::fmtflags f(std::cout.flags());
for (int i = 0; i < len; i++)
{
std::cout << "0x" << std::setfill('0') << std::setw(2) << std::right << std::hex;
std::cout << (int)(0xff & atr_buffer[i]) << ' ';
}
std::cout.flags(f);
std::cout << " END ATR " << std::endl;
}
error_description(st1, st0);
return response == 'P';
}