Skip to content

Commit

Permalink
Add NFCPy support
Browse files Browse the repository at this point in the history
  • Loading branch information
powertomato committed Jan 1, 2024
1 parent 3a904b5 commit c122387
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 0 deletions.
24 changes: 24 additions & 0 deletions documentation/developers/rfid/generic_nfcpy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generic NFCPy Reader

This module is based on the user space NFC reader library [nfcpy](https://nfcpy.readthedocs.io/en/latest/overview.html) ([on github](https://github.com/nfcpy/nfcpy)).
The link above also contains a list of supported devices.

The goal of this module is to handle USB NFC devices, that don't have a HID-keyboard
driver, and thus cannot be used with the [genericusb](genericusb.md) module.

## Installation

Since nfcpy is a user-space library, it is required to supress the kernel from loading its driver:
`echo 'install <DRIVER> /bin/true' > /etc/modprobe.d/disable_<DRIVER>.conf`

Where <DRIVER> is one of the following:
- `pn533_usb` for PN531 PN532 and PN533 based devices connected via USB
- `pn532_uart`\* for PN532 based devices connected via UART (or a UART-to-USB chip)
- `port100`\* for Port100 based devices
- `pn533_usb`\* for RC-S956 based devices

After the driver has been blacklisted. Unplug the device. Then either do `rmmod <DRIVER>`

[!NOTE]
\* Needs to be verified.

2 changes: 2 additions & 0 deletions src/jukebox/components/rfid/hardware/generic_nfcpy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

For documentation see [documentation/developers/rfid/generic_nfcpy.md](../../../../../../documentation/developers/rfid/generic_nfcpy.md).
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
""" List of supprted devices https://nfcpy.readthedocs.io/en/latest/overview.html"""
# 40 chars: '========================================'
DESCRIPTION = 'Generic NFCPY NFC Reader Module'
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Standard imports from python packages
import logging

import nfc
from nfc.clf import RemoteTarget

# Import the ReaderBaseClass for common API. Leave as this line as it is!
from components.rfid import ReaderBaseClass
import jukebox.cfghandler

# Also import the description string into this module, to make everything available in a single module w/o code duplication
# Leave this line as is!
from .description import DESCRIPTION

# Create logger.
# Logging is fully setup. Just replace '.new' with something meaningful and short
logger = logging.getLogger('jb.rfid.new')
# Get the global handler to the RFID config
cfg = jukebox.cfghandler.get_handler('rfid')




def query_customization() -> dict:
"""
Query the user for reader parameter customization
"""
return {}


class ReaderClass(ReaderBaseClass):
"""
The reader class for nfcpy supported NFC card readers.
"""
def __init__(self, reader_cfg_key):
# Create a per-instance logger, just in case the reader will run multiple times in various threads
# Replace '.new' with something meaningful and short
self._logger = logging.getLogger(f'jb.rfid.new({reader_cfg_key})')
# Initialize the super-class. Don't change anything here
super().__init__(reader_cfg_key=reader_cfg_key, description=DESCRIPTION, logger=self._logger)

# Get the configuration from the rfid.yaml:
# Lock config around the access
#with cfg:
# # Get a reference to the actual reader-specific config
# config = cfg.getn('rfid', 'readers', reader_cfg_key, 'config', default=None)
# # No config

self.clf = nfc.ContactlessFrontend('usb')

self._keep_running = True

def cleanup(self):
"""
The cleanup function: free and release all resources used by this card reader (if any).
"""
self.clf.close()

def stop(self):
"""
This function is called to tell the reader to exit its reading function.
"""
self._keep_running = False

def read_card(self) -> str:
"""
Blocking or non-blocking function that waits for a new card to appear and return the card's UID as string
"""
self._logger.debug("Wait for card")
while self._keep_running:
target = self.clf.sense(RemoteTarget('106A'),
RemoteTarget('106B'),
RemoteTarget('212F'),
interval=0.1,
iterations=1)
if not target:
continue

tag = nfc.tag.activate(self.clf, target)
if not tag:
continue

id = ''
for char in tag.identifier:
id += '%02X' % char

self._logger.debug(f'Found card with ID: "{id}"')
return id
self._logger.debug("NFC read stopped")
return ''
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# NFCPy related requirements
# You need to install these with `python -m pip install --upgrade --force-reinstall -q -r requirements.txt`

nfcpy

0 comments on commit c122387

Please sign in to comment.