nfc

nfc.ContactlessFrontend

class nfc.ContactlessFrontend(path=None)

The contactless frontend is the main interface class for working with contactless reader devices. A reader device may be opened when an instance is created by providing the path argument, see nfc.ContactlessFrontend.open() for how it must be constructed.

The initializer method raises IOError(errno.ENODEV) if a path is specified but no no reader are found.

open(path)

Open a contactless reader device identified by path.

Parameters:path – search path for contactless reader
Returns True:if reader was found and activated

Path specification:

usb[:vendor[:product]]
with optional vendor and product as four digit hexadecimal numbers, like usb:054c:06c3 would open the first Sony RC-S380 reader and usb:054c the first Sony reader.
usb[:bus[:device]]
with optional bus and device number as three-digit decimal numbers, like usb:001:023 would specifically mean the usb device with bus number 1 and device id 23 whereas usb:001 would mean to use the first available reader on bus number 1.
tty:port:driver
with mandatory port and driver name should be used on Posix systems to open the serial port at device node /dev/tty<port> and load the driver from module nfc/dev/<driver>.py. A typical example would be tty:USB0:arygon for the Arygon APPx/ADRx at /dev/ttyUSB0.
com:port:driver
with mandatory port and driver name should be used on Windows systems to open the serial port COM<port> and load the nfc/dev/<driver>.py driver module.
udp[:host][:port] with optional host name or address
and port number will use a fake communication channel over UDP/IP. Either value may be omitted in which case host defaults to ‘localhost’ and port defaults to 54321.
close()

Close the contacless reader device.

connect(**options)

Connect with a contactless target or become connected as a contactless target. The calling thread is blocked until a single activation and deactivation has completed or a callback function supplied as the keyword argument terminate returned True. The result of the terminate function also applies to the loop run after activation, so the example below will make connect() return after 10 seconds from either waiting for a peer device or when connected.

>>> import nfc, time
>>> clf = nfc.ContactlessFrontend('usb')
>>> after5s = lambda: time.time() - started > 5
>>> started = time.time(); clf.connect(llcp={}, terminate=after5s)

Connect options are given as keyword arguments with dictionary values. Possible options are:

  • rdwr={key: value, ...} - options for reader/writer operation
  • llcp={key: value, ...} - options for peer to peer mode operation
  • card={key: value, ...} - options for card emulation operation

Reader/Writer Options

‘targets’: sequence
A list of target specifications with each target of either type TTA, TTB, or TTF. A default set is choosen if ‘targets’ is not provided.
‘on-startup’: function
A function that will be called with the list of targets (from ‘targets’) to search for. Must return a list of targets or None. Only the targets returned are finally considered.
‘on-connect’: function
A function object that will be called with an activated Tag object.
>>> import nfc
>>> def connected(tag):
...     print tag
...     return True
...
>>> clf = nfc.ContactlessFrontend()
>>> clf.connect(rdwr={'on-connect': connected})
Type3Tag IDm=01010501b00ac30b PMm=03014b024f4993ff SYS=12fc
True

Peer To Peer Options

‘on-startup’: function
A function that is called before an attempt is made to establish peer to peer communication. The function receives the initialized LogicalLinkController instance as parameter, which may then be used to allocate and bind communication sockets for service applications. The return value must be either the LogicalLinkController instance or None to effectively remove llcp from the options considered.
‘on-connect’: function
A function that is be called when peer to peer communication was established. The function receives the connected LogicalLinkController instance as parameter, which may then be used to allocate communication sockets with socket() and spawn working threads to perform communication. The callback must return more or less immediately with True unless the logical link controller run loop is handled within the callback.
‘role’: string
Defines which role the local LLC shall take for the data exchange protocol activation. Possible values are ‘initiator’ and ‘target’. The default is to alternate between both roles until communication is established.
‘miu’: integer
Defines the maximum information unit size that will be supported and announced to the remote LLC. The default value is 128.
‘lto’: integer
Defines the link timeout value (in milliseconds) that will be announced to the remote LLC. The default value is 100 milliseconds.
‘agf’: boolean
Defines if the local LLC performs PDU aggregation and may thus send Aggregated Frame (AGF) PDUs to the remote LLC. The dafault is to use aggregation.
>>> import nfc
>>> import threading
>>> def worker(socket):
...     socket.sendto("Hi there!", address=16)
...     socket.close()
...
>>> def connected(llc):
...     socket = llc.socket(nfc.llcp.LOGICAL_DATA_LINK)
...     threading.Thread(target=worker, args=(socket,)).start()
...     return True
...
>>> clf = nfc.ContactlessFrontend()
>>> clf.connect(llcp={'on-connect': connected})

Card Emulation Options

‘targets’: sequence
A list of target specifications with each target of either type TTA, TTB, or TTF. The list of targets is processed sequentially. Defaults to an empty list.
‘on-startup’: function
A function that will be called with the list of targets (from ‘targets’) to emulate. Must return a list of one target choosen or None.
‘on-connect’: function
A function that will be called with an activated TagEmulation instance as first parameter and the first command received as the second parameter.
‘on-release’: function A function that will be called when the
activated tag has been released by it’s Initiator, basically that is when the tag has been removed from the Initiator’s RF field.
‘timeout’: integer
The timeout in seconds to wait for for each target to become initialized. The default value is 1 second.
>>> import nfc
>>>
>>> def connected(tag, command):
...     print tag
...     print str(command).encode("hex")
...
>>> clf = nfc.ContactlessFrontend()
>>> idm = bytearray.fromhex("01010501b00ac30b")
>>> pmm = bytearray.fromhex("03014b024f4993ff")
>>> sys = bytearray.fromhex("12fc")
>>> target = nfc.clf.TTF(212, idm, pmm, sys)
>>> clf.connect(card={'targets': [target], 'on-connect': connected})
Type3TagEmulation IDm=01010501b00ac30b PMm=03014b024f4993ff SYS=12fc
100601010501b00ac30b010b00018000
True

Connect returns None if no options were to execute, False if interrupted by a KeyboardInterrupt, or True if terminated normally and the ‘on-connect’ callback function had returned True. If the ‘on-connect’ callback had returned False the return value of connect() is the same parameters as were provided to the callback function.

Connect raises IOError(errno.ENODEV) if called before a contactless reader was opened.

sense(targets, **kwargs)

Send discovery and activation requests to find a target. Targets is a list of target specifications (TTA, TTB, TTF). Not all readers may support all possible target types. The return value is an activated target with a possibly updated specification (bitrate) or None.

Additional keyword arguments are driver specific.

Note

This is a direct interface to the driver and not needed if connect() is used.

listen(target, timeout)

Listen for timeout seconds to become initialized as a target. The target must be one of nfc.clf.TTA, nfc.clf.TTB, nfc.clf.TTF, or nfc.clf.DEP (note that target type support depends on the hardware capabilities). The return value is None if timeout elapsed without activation or a tuple (target, command) where target is the activated target (which may differ from the requested target, see below) and command is the first command received from the initiator.

If an activated target is returned, the target type and attributes may differ from the target requested. This is especically true if activation as a nfc.clf.DEP target is requested but the contactless frontend does not have a hardware implementation of the data exchange protocol and returns a nfc.clf.TTA or nfc.clf.TTF target instead.

Note

This is a direct interface to the driver and not needed if connect() is used.

exchange(send_data, timeout)

Exchange data with an activated target (data is a command frame) or as an activated target (data is a response frame). Returns a target response frame (if data is send to an activated target) or a next command frame (if data is send from an activated target). Returns None if the communication link broke during exchange (if data is sent as a target). The timeout is the number of seconds to wait for data to return, if the timeout expires an nfc.clf.TimeoutException is raised. Other nfc.clf.DigitalProtocolExceptions may be raised if an error is detected during communication.

Note

This is a direct interface to the driver and not needed if connect() is used.

set_communication_mode(brm, **kwargs)

Set the hardware communication mode. The effect of calling this method depends on the hardware support, some drivers may purposely ignore this function. If supported, the parameter brm specifies the communication mode to choose as a string composed of the bitrate and modulation type, for example ‘212F’ shall switch to 212 kbps Type F communication. Other communication parameters may be changed with optional keyword arguments. Currently implemented by the RC-S380 driver are the parameters ‘add-crc’ and ‘check-crc’ when running as initator. It is possible to set brm to an empty string if bitrate and modulation shall not be changed but only optional parameters executed.

Note

This is a direct interface to the driver and not needed if connect() is used.

class nfc.clf.TTA(br=None, cfg=None, uid=None, ats=None)

Represents a Type A target. The integer br is the bitrate. The bytearray cf is the two byte SENS_RES data plus the one byte SEL_RES data for a tag type 1/4 tag. The bytearray uid is the target UID. The bytearray ats is the answer to select data of a type 4 tag if the chipset does activation as part of discovery.

class nfc.clf.TTB(br=None)

Represents a Type B target. The integer br is the bitrate. Type B targets are not yet supported in nfcpy, for the simple reason that no cards for testing are available.

class nfc.clf.TTF(br=None, idm=None, pmm=None, sys=None)

Represents a Type F target. The integer br is the bitrate. The bytearray idm is the 8 byte manufacture id. The bytearray pmm is the 8 byte manufacture parameter. The bytearray sys is the 2 byte system code.

class nfc.clf.DEP(br=None, gb=None)

Represents a DEP target. The integer br is the bitrate. The bytearray gb is the ATR general bytes.