More nfc
changes #370
|
@ -15,7 +15,6 @@ Backends
|
||||||
platypush/backend/music.spotify.rst
|
platypush/backend/music.spotify.rst
|
||||||
platypush/backend/nodered.rst
|
platypush/backend/nodered.rst
|
||||||
platypush/backend/redis.rst
|
platypush/backend/redis.rst
|
||||||
platypush/backend/scard.rst
|
|
||||||
platypush/backend/sensor.ir.zeroborg.rst
|
platypush/backend/sensor.ir.zeroborg.rst
|
||||||
platypush/backend/sensor.leap.rst
|
platypush/backend/sensor.leap.rst
|
||||||
platypush/backend/stt.deepspeech.rst
|
platypush/backend/stt.deepspeech.rst
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
``scard``
|
|
||||||
===========================
|
|
||||||
|
|
||||||
.. automodule:: platypush.backend.scard
|
|
||||||
:members:
|
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
from platypush.backend import Backend
|
|
||||||
from platypush.message.event.scard import SmartCardDetectedEvent, SmartCardRemovedEvent
|
|
||||||
|
|
||||||
|
|
||||||
class ScardBackend(Backend):
|
|
||||||
"""
|
|
||||||
Generic backend to read smart cards and NFC tags and trigger an event
|
|
||||||
whenever a device is detected.
|
|
||||||
|
|
||||||
Extend this backend to implement more advanced communication with custom
|
|
||||||
smart cards.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, atr=None, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
:param atr: If set, the backend will trigger events only for card(s)
|
|
||||||
with the specified ATR(s). It can be either an ATR string
|
|
||||||
(space-separated hex octects) or a list of ATR strings. Default:
|
|
||||||
none (any card will be detected).
|
|
||||||
"""
|
|
||||||
|
|
||||||
from smartcard.CardType import AnyCardType, ATRCardType
|
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.ATRs = []
|
|
||||||
|
|
||||||
if atr:
|
|
||||||
if isinstance(atr, str):
|
|
||||||
self.ATRs = [atr]
|
|
||||||
elif isinstance(atr, list):
|
|
||||||
self.ATRs = atr
|
|
||||||
else:
|
|
||||||
raise RuntimeError(
|
|
||||||
f"Unsupported ATR: \"{atr}\" - type: {type(atr)}, "
|
|
||||||
+ "supported types: string, list"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.cardtype = ATRCardType(*[self._to_bytes(atr) for atr in self.ATRs])
|
|
||||||
else:
|
|
||||||
self.cardtype = AnyCardType()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _to_bytes(data) -> bytes:
|
|
||||||
if isinstance(data, str):
|
|
||||||
data = data.encode()
|
|
||||||
return data
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
from smartcard.CardRequest import CardRequest
|
|
||||||
from smartcard.Exceptions import NoCardException, CardConnectionException
|
|
||||||
from smartcard.util import toHexString
|
|
||||||
|
|
||||||
super().run()
|
|
||||||
|
|
||||||
self.logger.info(
|
|
||||||
'Initialized smart card reader backend - ATR filter: {}'.format(self.ATRs)
|
|
||||||
)
|
|
||||||
|
|
||||||
prev_atr = None
|
|
||||||
reader = None
|
|
||||||
|
|
||||||
while not self.should_stop():
|
|
||||||
try:
|
|
||||||
cardrequest = CardRequest(timeout=None, cardType=self.cardtype)
|
|
||||||
cardservice = cardrequest.waitforcard()
|
|
||||||
cardservice.connection.connect()
|
|
||||||
|
|
||||||
reader = cardservice.connection.getReader()
|
|
||||||
atr = toHexString(cardservice.connection.getATR())
|
|
||||||
|
|
||||||
if atr != prev_atr:
|
|
||||||
self.logger.info(
|
|
||||||
'Smart card detected on reader {}, ATR: {}'.format(reader, atr)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.bus.post(SmartCardDetectedEvent(atr=atr, reader=reader))
|
|
||||||
prev_atr = atr
|
|
||||||
except Exception as e:
|
|
||||||
if isinstance(e, (NoCardException, CardConnectionException)):
|
|
||||||
self.bus.post(SmartCardRemovedEvent(atr=prev_atr, reader=reader))
|
|
||||||
else:
|
|
||||||
self.logger.exception(e)
|
|
||||||
|
|
||||||
prev_atr = None
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
|
|
@ -1,17 +0,0 @@
|
||||||
manifest:
|
|
||||||
events:
|
|
||||||
platypush.message.event.scard.SmartCardDetectedEvent: when a smart card is detected
|
|
||||||
platypush.message.event.scard.SmartCardRemovedEvent: when a smart card is removed
|
|
||||||
install:
|
|
||||||
apk:
|
|
||||||
- py3-pyscard
|
|
||||||
apt:
|
|
||||||
- python3-pyscard
|
|
||||||
dnf:
|
|
||||||
- python-pyscard
|
|
||||||
pacman:
|
|
||||||
- python-pyscard
|
|
||||||
pip:
|
|
||||||
- pyscard
|
|
||||||
package: platypush.backend.scard
|
|
||||||
type: backend
|
|
|
@ -7,7 +7,7 @@ from platypush.message.event.nfc import (
|
||||||
NFCDeviceConnectedEvent,
|
NFCDeviceConnectedEvent,
|
||||||
NFCDeviceDisconnectedEvent,
|
NFCDeviceDisconnectedEvent,
|
||||||
)
|
)
|
||||||
from platypush.plugins import RunnablePlugin
|
from platypush.plugins import RunnablePlugin, action
|
||||||
|
|
||||||
|
|
||||||
class NfcPlugin(RunnablePlugin):
|
class NfcPlugin(RunnablePlugin):
|
||||||
|
@ -21,7 +21,7 @@ class NfcPlugin(RunnablePlugin):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, device='usb', *args, **kwargs):
|
def __init__(self, device='usb', **kwargs):
|
||||||
"""
|
"""
|
||||||
:param device: Address or ID of the device to be opened. Examples:
|
:param device: Address or ID of the device to be opened. Examples:
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class NfcPlugin(RunnablePlugin):
|
||||||
* ``usb:003`` opens the first available device on bus 3
|
* ``usb:003`` opens the first available device on bus 3
|
||||||
* ``usb`` opens the first available USB device (default)
|
* ``usb`` opens the first available USB device (default)
|
||||||
"""
|
"""
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(**kwargs)
|
||||||
self.device_id = device
|
self.device_id = device
|
||||||
self._clf = None
|
self._clf = None
|
||||||
|
|
||||||
|
@ -229,6 +229,31 @@ class NfcPlugin(RunnablePlugin):
|
||||||
|
|
||||||
return callback
|
return callback
|
||||||
|
|
||||||
|
@action
|
||||||
|
def status(self):
|
||||||
|
"""
|
||||||
|
Get information about the NFC reader status.
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"display_name": "ACS ACR122U PN532v1.6 at usb:001:017",
|
||||||
|
"path": "usb:001:017",
|
||||||
|
"product_name": "ACR122U",
|
||||||
|
"vendor_name": "ACS"
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
assert self._clf and self._clf.device, 'NFC reader not initialized'
|
||||||
|
return {
|
||||||
|
'display_name': str(self._clf.device),
|
||||||
|
'path': self._clf.device.path,
|
||||||
|
'product_name': self._clf.device.product_name,
|
||||||
|
'vendor_name': self._clf.device.vendor_name,
|
||||||
|
}
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
fail_wait = 5
|
fail_wait = 5
|
||||||
max_fail_wait = 60
|
max_fail_wait = 60
|
||||||
|
|
Loading…
Reference in New Issue