diff --git a/ClipboardReaderService.py b/NfcReaderService.py similarity index 68% rename from ClipboardReaderService.py rename to NfcReaderService.py index d4fea2d..721e4fb 100644 --- a/ClipboardReaderService.py +++ b/NfcReaderService.py @@ -1,29 +1,34 @@ import time -import pyperclip +from datetime import datetime, timedelta from smartcard.CardRequest import CardRequest -from smartcard.Exceptions import CardConnectionException +from smartcard.Exceptions import CardConnectionException, NoCardException from smartcard.CardConnection import CardConnection from smartcard.util import toHexString +from pynput.keyboard import Controller + from card_reader import read_card -CLIPBOARD_MESSAGE_PREFIX = "ezgglan-clipboard-message:" - -class ClipboardReaderService: +class NfcReaderService: def __init__(self) -> None: self._is_running = True self._last_uid = None + self._keyboard = Controller() + self._last_write = datetime(1900, 1, 1) def run(self) -> None: print("Reader ready.") while self._is_running: try: + 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) @@ -39,18 +44,19 @@ class ClipboardReaderService: 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: - pyperclip.copy(CLIPBOARD_MESSAGE_PREFIX + str(user_id)) - else: - pyperclip.copy(CLIPBOARD_MESSAGE_PREFIX + "Fehler: Erneut scannen") + now = datetime.now() + if now - self._last_write > timedelta(seconds=2): + self._keyboard.type(str(user_id)) + self._last_write = now - except CardConnectionException: + except (CardConnectionException, NoCardException): pass finally: @@ -68,5 +74,5 @@ class ClipboardReaderService: self._is_running = False if __name__ == "__main__": - service = ClipboardReaderService() + service = NfcReaderService() service.run() diff --git a/README.md b/README.md index 8294f42..a21c41e 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,12 @@ Currently supported NFC Device: ACR 1252U - Library: API for extracting user ID from card - card_writer - Standalone: Takes user ID as console input, writes it securely to card -- ClipboardReaderService - - Standalone: Continuously reads cards and writes decrypted user ID or error message to clipboard +- NfcReaderService + - Standalone: Continuously reads cards and writes decrypted user ID as keyboard output ## 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. \ No newline at end of file diff --git a/main.py b/main.py index 83f05cd..2bbcc7a 100644 --- a/main.py +++ b/main.py @@ -2,6 +2,9 @@ from smartcard.CardRequest import CardRequest from smartcard.util import toHexString from smartcard.CardConnection import CardConnection +from card_writer import write_ndef_text + + def read_page(connection, page): apdu = [0xFF, 0xB0, 0x00, page, 0x04] data, sw1, sw2 = connection.transmit(apdu) diff --git a/nfc-reader.service b/nfc-reader.service new file mode 100644 index 0000000..3c0afd9 --- /dev/null +++ b/nfc-reader.service @@ -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 diff --git a/requirements.txt b/requirements.txt index d1fabf5..7c2fc60 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ libusb1==3.3.1 ndeflib==0.3.3 pyDes==2.0.1 -pyperclip==1.11.0 pyscard==2.3.1 pyserial==3.5