Skip to content

Commit addd5fa

Browse files
committed
Fixed LE decimals to hex checker on rfid
1 parent d3f493b commit addd5fa

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

client/lib/views/kiosk/kiosk_scan_handler.dart

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,13 @@ Future<void> handleKioskScan({
113113
/// - 89:02:9e:40 (colon-separated, lowercase)
114114
/// - 89 02 9e 40 (space-separated)
115115
/// - 89029e40 (no separator)
116-
/// - decimal BE string (e.g. "2299477568")
117-
/// - decimal LE string (e.g. "1075381897")
116+
/// - decimal BE string (e.g. "2298650176")
117+
/// - decimal LE string (e.g. "1084097161")
118118
///
119-
/// If a user stored a decimal value in their alias, we also parse it
120-
/// to hex and generate the hex variants from that.
119+
/// From a decimal input like "1084097161" (keyboard RFID reader) we produce:
120+
/// - BE hex: 40:9e:02:89 (direct byte conversion)
121+
/// - LE hex: 89:02:9e:40 (reversed — matches PCSC format)
122+
/// - plus space-separated and no-separator variants of both
121123
Set<String> _buildUidVariants(String input) {
122124
final variants = <String>{};
123125
final normalized = input.trim().toLowerCase();
@@ -150,17 +152,28 @@ Set<String> _buildUidVariants(String input) {
150152
}
151153

152154
// If input looks like a plain decimal number, parse it to hex bytes
153-
// and add those variants too (in case user stored hex but card gave decimal)
155+
// and add those variants too (in case user stored hex but card gave decimal).
156+
// We generate both BE and LE byte orders because keyboard RFID readers
157+
// typically output the LE decimal of the UID bytes.
154158
final asInt = BigInt.tryParse(normalized);
155159
if (asInt != null && asInt > BigInt.zero) {
156160
final bytes = _bigIntToBytes(asInt);
157161
if (bytes.isNotEmpty) {
158-
final hexParts = bytes
162+
// Big-endian interpretation
163+
final hexBe = bytes
159164
.map((b) => b.toRadixString(16).padLeft(2, '0'))
160165
.toList();
161-
variants.add(hexParts.join(':'));
162-
variants.add(hexParts.join(' '));
163-
variants.add(hexParts.join());
166+
variants.add(hexBe.join(':'));
167+
variants.add(hexBe.join(' '));
168+
variants.add(hexBe.join());
169+
170+
// Little-endian (reversed) interpretation
171+
final hexLe = bytes.reversed
172+
.map((b) => b.toRadixString(16).padLeft(2, '0'))
173+
.toList();
174+
variants.add(hexLe.join(':'));
175+
variants.add(hexLe.join(' '));
176+
variants.add(hexLe.join());
164177
}
165178
}
166179

client/lib/widgets/rfid_scan_button.dart

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,24 @@ class RfidScanButton extends HookWidget {
1616
Widget build(BuildContext context) {
1717
final listening = useState(false);
1818
final timerRef = useRef<Timer?>(null);
19+
final mounted = useRef(true);
20+
21+
// Cancel the timer on dispose to prevent writing to a disposed notifier
22+
useEffect(() {
23+
mounted.value = true;
24+
return () {
25+
mounted.value = false;
26+
timerRef.value?.cancel();
27+
timerRef.value = null;
28+
};
29+
}, const []);
1930

2031
void stopListening() {
2132
timerRef.value?.cancel();
2233
timerRef.value = null;
23-
listening.value = false;
34+
if (mounted.value) {
35+
listening.value = false;
36+
}
2437
}
2538

2639
useRfidScanner(
@@ -47,10 +60,7 @@ class RfidScanButton extends HookWidget {
4760
return OutlinedButton.icon(
4861
onPressed: () {
4962
listening.value = true;
50-
timerRef.value = Timer(_timeoutDuration, () {
51-
listening.value = false;
52-
timerRef.value = null;
53-
});
63+
timerRef.value = Timer(_timeoutDuration, stopListening);
5464
},
5565
icon: const Icon(Icons.contactless),
5666
label: const Text('Scan RFID Card'),

0 commit comments

Comments
 (0)