Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NFCPy support #2190

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
s-martin marked this conversation as resolved.
Show resolved Hide resolved
s-martin marked this conversation as resolved.
Show resolved Hide resolved

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:
s-martin marked this conversation as resolved.
Show resolved Hide resolved
`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
s-martin marked this conversation as resolved.
Show resolved Hide resolved
- `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>`
s-martin marked this conversation as resolved.
Show resolved Hide resolved

[!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"""
s-martin marked this conversation as resolved.
Show resolved Hide resolved
# 40 chars: '========================================'
DESCRIPTION = 'Generic NFCPY NFC Reader Module'
s-martin marked this conversation as resolved.
Show resolved Hide resolved
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')
s-martin marked this conversation as resolved.
Show resolved Hide resolved
# 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
s-martin marked this conversation as resolved.
Show resolved Hide resolved
"""
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})')
s-martin marked this conversation as resolved.
Show resolved Hide resolved
# 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
s-martin marked this conversation as resolved.
Show resolved Hide resolved
# 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
Loading