From 2ffad45cbed2f3bf79a3d0143af28813aaa9010d Mon Sep 17 00:00:00 2001 From: Yannick Heinrich Date: Fri, 9 Jan 2026 11:01:48 +0100 Subject: [PATCH 1/2] Fix RFID 125 khz reading It seems that for some reason, the previous code could not compute properly the checksum provided by the UART module properly. I did not find the reason but I guess some compiler optimisations or/and some conversion between long and int that introduced some errors. This code is a small different approach that does not use `strtol` method and convert nibbles to integer manually. The checksum is computed in one shot and compared with the one provided in the UI. I tested it on my cardputer and seems to work now. --- src/modules/rfid/rfid125.cpp | 39 ++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/modules/rfid/rfid125.cpp b/src/modules/rfid/rfid125.cpp index 706d1a0eaa..136bc857e3 100644 --- a/src/modules/rfid/rfid125.cpp +++ b/src/modules/rfid/rfid125.cpp @@ -12,6 +12,20 @@ #include "core/sd_functions.h" #include +static uint8_t hex2digit(char ch) { + if (ch >= '0' && ch <= '9') return ch - '0'; + if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10; + if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10; + return -1; +} + +static uint8_t hex2int(char *ch) { + uint8_t lnib = hex2digit(ch[0]); + uint8_t rnib = hex2digit(ch[1]); + uint8_t res = ((lnib << 4) | 0x0F) & (rnib | 0xF0); + return res; +} + RFID125::RFID125() { _initial_state = READ_MODE; setup(); @@ -171,8 +185,7 @@ void RFID125::read_card() { bool RFID125::read_card_data() { char buff[RFID125_PACKET_SIZE]; - uint8_t checksum; - uint32_t tag_id; + uint8_t checksum, check; if (!_stream) return false; @@ -189,21 +202,17 @@ bool RFID125::read_card_data() { for (int i = 0; i < RFID125_PACKET_SIZE; i++) _tag_data[i] = buff[i]; - /* add null and parse checksum */ - buff[13] = 0; - checksum = strtol(buff + 11, NULL, 16); - /* add null and parse tag_id */ - buff[11] = 0; - tag_id = strtol(buff + 3, NULL, 16); - /* add null and parse version (needs to be xored with checksum) */ - buff[3] = 0; - checksum ^= strtol(buff + 1, NULL, 16); + /* We read the provided checksum integer read from UART*/ + checksum = hex2int(buff + 11); - /* xore the tag_id and validate checksum */ - for (uint8_t i = 0; i < 32; i += 8) checksum ^= ((tag_id >> i) & 0xFF); - if (checksum) return false; + /* We compute xor check on payload data */ + check = hex2int(&buff[1]); + for (int i = 3; i < 11; i += 2) { + uint8_t value = hex2int(buff + i); + check ^= value; + } - return true; + return check == checksum; } void RFID125::clear_stream() { From 36f3d3f411de71bd79d636728294d5612c2f6ebd Mon Sep 17 00:00:00 2001 From: Yannick Heinrich Date: Tue, 13 Jan 2026 10:45:42 +0100 Subject: [PATCH 2/2] Better error handling --- src/modules/rfid/rfid125.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/modules/rfid/rfid125.cpp b/src/modules/rfid/rfid125.cpp index 136bc857e3..4f9529dd54 100644 --- a/src/modules/rfid/rfid125.cpp +++ b/src/modules/rfid/rfid125.cpp @@ -12,17 +12,24 @@ #include "core/sd_functions.h" #include +#define _HEX_DIGIT_ERROR 0xFF + static uint8_t hex2digit(char ch) { if (ch >= '0' && ch <= '9') return ch - '0'; if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10; if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10; - return -1; + return _HEX_DIGIT_ERROR; } static uint8_t hex2int(char *ch) { - uint8_t lnib = hex2digit(ch[0]); - uint8_t rnib = hex2digit(ch[1]); - uint8_t res = ((lnib << 4) | 0x0F) & (rnib | 0xF0); + uint8_t lnib, rnib, res; + lnib = hex2digit(ch[0]); + if (lnib == _HEX_DIGIT_ERROR) return _HEX_DIGIT_ERROR; + + rnib = hex2digit(ch[1]); + if (rnib == _HEX_DIGIT_ERROR) return _HEX_DIGIT_ERROR; + + res = ((lnib << 4) | 0x0F) & (rnib | 0xF0); return res; } @@ -204,14 +211,16 @@ bool RFID125::read_card_data() { /* We read the provided checksum integer read from UART*/ checksum = hex2int(buff + 11); + if (checksum == _HEX_DIGIT_ERROR) return false; /* We compute xor check on payload data */ check = hex2int(&buff[1]); + if (check == _HEX_DIGIT_ERROR) return false; + for (int i = 3; i < 11; i += 2) { uint8_t value = hex2int(buff + i); check ^= value; } - return check == checksum; }