Compare commits

2 Commits

Author SHA1 Message Date
Typhus c416eb8cef Update README.md 2026-04-02 09:00:59 +00:00
Typhus 99bba1b59a Update nfc-reader.service 2026-04-02 08:57:04 +00:00
3 changed files with 65 additions and 78 deletions
+45 -74
View File
@@ -10,98 +10,69 @@ from pynput.keyboard import Controller
from card_reader import read_card
GET_UID = [0xFF, 0xCA, 0x00, 0x00, 0x00]
class NfcReaderService:
def __init__(self) -> None:
self._is_running = True
self._last_uid = None
self._keyboard = Controller()
self._last_write = datetime.min
self._last_write = datetime(1900, 1, 1)
def run(self) -> None:
print("Reader ready.")
while self._is_running:
try:
self._poll_card()
time.sleep(0.1)
card_request = CardRequest(timeout=None)
print("Waiting for card...")
card_service = card_request.waitforcard()
connection = card_service.connection
print("Connected to card!")
try:
connection.connect(CardConnection.T1_protocol)
GET_UID = [0xFF, 0xCA, 0x00, 0x00, 0x00]
uid, sw1, sw2 = connection.transmit(GET_UID)
if sw1 != 0x90:
raise CardConnectionException("UID read failed")
uid_hex = toHexString(uid)
if uid_hex == self._last_uid:
connection.disconnect()
time.sleep(0.5)
self._last_uid = None
continue
self._last_uid = uid_hex
user_id = read_card(connection)
if user_id is not None:
now = datetime.now()
if now - self._last_write > timedelta(seconds=2):
self._keyboard.type(str(user_id))
self._last_write = now
except (CardConnectionException, NoCardException):
pass
finally:
try:
connection.disconnect()
except:
pass
time.sleep(0.5)
except (KeyboardInterrupt, SystemExit):
self.stop()
except Exception as e:
print(f"[ERROR] Unexpected failure: {e}")
time.sleep(1)
def _poll_card(self) -> None:
card_request = CardRequest(timeout=1)
try:
card_service = card_request.waitforcard()
except NoCardException:
self._last_uid = None
return
connection = card_service.connection
try:
connection.connect(CardConnection.T1_protocol)
uid_hex = self._read_uid(connection)
if uid_hex is None:
return
# Card still present and unchanged -> ignore
if uid_hex == self._last_uid:
return
self._last_uid = uid_hex
self._handle_card(connection)
except (CardConnectionException, NoCardException) as e:
print(f"[CARD ERROR] {e}")
finally:
try:
connection.disconnect()
except Exception:
pass
def _read_uid(self, connection) -> Optional[str]:
uid, sw1, sw2 = connection.transmit(GET_UID)
if sw1 != 0x90:
raise CardConnectionException("UID read failed")
return toHexString(uid)
def _handle_card(self, connection) -> None:
user_id = read_card(connection)
if user_id is None:
return
now = datetime.now()
# debounce keyboard output
if now - self._last_write < timedelta(seconds=2):
return
self._send_to_keyboard(user_id)
self._last_write = now
def _send_to_keyboard(self, user_id: str) -> None:
try:
self._keyboard.type(f"{user_id}\n")
except Exception as e:
print(f"[KEYBOARD ERROR] {e}")
def stop(self) -> None:
print("Stopping NFC service.")
self._is_running = False
if __name__ == "__main__":
service = NfcReaderService()
service.run()
service.run()
+9 -1
View File
@@ -4,6 +4,14 @@ This repository contains the tooling around NFC readers/writers.
Currently supported NFC Device: ACR 1252U
## Installation
Make sure you have the apt packages `python3-dev` and `libpcsclite-dev` installed before installing the dependencies from `requirements.txt`.
## Configuration
The root path of the installation (next to `NfcReaderService.py`) needs to contain the `hmac_key.txt`. The correct key can be retrieved from sys admin.
## Tools:
- card_reader
@@ -17,6 +25,6 @@ Currently supported NFC Device: ACR 1252U
## Intended usage
Start `NfcReaderService` on terminals where LAN team needs to verify guest identity, EZGG LAN manager then reads user ID from clipboard.
`NfcReaderService` may be used as part of a systemd unit, to automate the startup process.
`NfcReaderService` may be used as part of a systemd unit, to automate the startup process. See service file for additional info.
Run `card_writer` when preparing tickets.
+11 -3
View File
@@ -1,10 +1,15 @@
# THIS IS A USER-LEVEL SERVICE
# ~/.config/systemd/user
# systemctl --user daemon-reload
# systemctl --user enable nfc-reader.service
# systemctl --user start nfc-reader.service
[Unit]
Description=NFC Reader Service
After=network.target
After=graphical-session.target
[Service]
Type=simple
User=ezgg
WorkingDirectory=/opt/nfc
ExecStart=/opt/nfc/venv/bin/python /opt/nfc/NfcReaderService.py
@@ -14,5 +19,8 @@ RestartSec=2
Environment=PYTHONUNBUFFERED=1
Environment=DISPLAY=:0
Environment=XAUTHORITY=%h/.Xauthority
[Install]
WantedBy=multi-user.target
WantedBy=default.target