finalize reader service

This commit is contained in:
David Rodenkirchen 2026-04-02 08:55:41 +02:00
parent 7c1cc2f538
commit 63d7c890d5
5 changed files with 42 additions and 15 deletions

View File

@ -1,29 +1,34 @@
import time import time
import pyperclip from datetime import datetime, timedelta
from smartcard.CardRequest import CardRequest from smartcard.CardRequest import CardRequest
from smartcard.Exceptions import CardConnectionException from smartcard.Exceptions import CardConnectionException, NoCardException
from smartcard.CardConnection import CardConnection from smartcard.CardConnection import CardConnection
from smartcard.util import toHexString from smartcard.util import toHexString
from pynput.keyboard import Controller
from card_reader import read_card from card_reader import read_card
CLIPBOARD_MESSAGE_PREFIX = "ezgglan-clipboard-message:"
class NfcReaderService:
class ClipboardReaderService:
def __init__(self) -> None: def __init__(self) -> None:
self._is_running = True self._is_running = True
self._last_uid = None self._last_uid = None
self._keyboard = Controller()
self._last_write = datetime(1900, 1, 1)
def run(self) -> None: def run(self) -> None:
print("Reader ready.") print("Reader ready.")
while self._is_running: while self._is_running:
try: try:
time.sleep(0.1)
card_request = CardRequest(timeout=None) card_request = CardRequest(timeout=None)
print("Waiting for card...")
card_service = card_request.waitforcard() card_service = card_request.waitforcard()
connection = card_service.connection connection = card_service.connection
print("Connected to card!")
try: try:
connection.connect(CardConnection.T1_protocol) connection.connect(CardConnection.T1_protocol)
@ -39,18 +44,19 @@ class ClipboardReaderService:
if uid_hex == self._last_uid: if uid_hex == self._last_uid:
connection.disconnect() connection.disconnect()
time.sleep(0.5) time.sleep(0.5)
self._last_uid = None
continue continue
self._last_uid = uid_hex self._last_uid = uid_hex
user_id = read_card(connection) user_id = read_card(connection)
if user_id is not None: if user_id is not None:
pyperclip.copy(CLIPBOARD_MESSAGE_PREFIX + str(user_id)) now = datetime.now()
else: if now - self._last_write > timedelta(seconds=2):
pyperclip.copy(CLIPBOARD_MESSAGE_PREFIX + "Fehler: Erneut scannen") self._keyboard.type(str(user_id))
self._last_write = now
except CardConnectionException: except (CardConnectionException, NoCardException):
pass pass
finally: finally:
@ -68,5 +74,5 @@ class ClipboardReaderService:
self._is_running = False self._is_running = False
if __name__ == "__main__": if __name__ == "__main__":
service = ClipboardReaderService() service = NfcReaderService()
service.run() service.run()

View File

@ -11,11 +11,12 @@ Currently supported NFC Device: ACR 1252U
- Library: API for extracting user ID from card - Library: API for extracting user ID from card
- card_writer - card_writer
- Standalone: Takes user ID as console input, writes it securely to card - Standalone: Takes user ID as console input, writes it securely to card
- ClipboardReaderService - NfcReaderService
- Standalone: Continuously reads cards and writes decrypted user ID or error message to clipboard - Standalone: Continuously reads cards and writes decrypted user ID as keyboard output
## Intended usage ## Intended usage
Start `ClipboardReaderService` on terminals where LAN team needs to verify guest identity, EZGG LAN manager then reads user ID from clipboard. 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.
Run `card_writer` when preparing tickets. Run `card_writer` when preparing tickets.

View File

@ -2,6 +2,9 @@ from smartcard.CardRequest import CardRequest
from smartcard.util import toHexString from smartcard.util import toHexString
from smartcard.CardConnection import CardConnection from smartcard.CardConnection import CardConnection
from card_writer import write_ndef_text
def read_page(connection, page): def read_page(connection, page):
apdu = [0xFF, 0xB0, 0x00, page, 0x04] apdu = [0xFF, 0xB0, 0x00, page, 0x04]
data, sw1, sw2 = connection.transmit(apdu) data, sw1, sw2 = connection.transmit(apdu)

18
nfc-reader.service Normal file
View File

@ -0,0 +1,18 @@
[Unit]
Description=NFC Reader Service
After=network.target
[Service]
Type=simple
User=ezgg
WorkingDirectory=/opt/nfc
ExecStart=/opt/nfc/venv/bin/python /opt/nfc/NfcReaderService.py
Restart=always
RestartSec=2
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target

View File

@ -1,6 +1,5 @@
libusb1==3.3.1 libusb1==3.3.1
ndeflib==0.3.3 ndeflib==0.3.3
pyDes==2.0.1 pyDes==2.0.1
pyperclip==1.11.0
pyscard==2.3.1 pyscard==2.3.1
pyserial==3.5 pyserial==3.5