tagtool.py

The tagtool.py example program can be used to read or write NFC Forum Tags. For some tags, currently Type 3 Tags only, tagtool can also be used to format for NDEF use.

$ tagtool.py [-h|--help] [options] command

Options

--loop, -l

Repeat the command endlessly, use Control-C to abort.

--wait

After reading or writing a tag, wait until it is removed before returning. This option is implicit when the option --loop is set.

--technology {A,B,F}

Poll only for tags of a specific technology. The technologies NFC-A, NFC-B, and NFC-F are defined in the NFC Forum Digital Specification. The technology indicator is case insensitive. The default is to poll for all technologies.

-q

Do not print log messages except for errors and warnings.

-d MODULE

Output debug messages for MODULE to the log facility. Logs are written to <stderr> unless a log file is set with -f. MODULE is a string that corresponds to an nfcpy module or individual file, with dots between path components. For example, -d nfc enables all nfcpy debug logs, -d nfc.tag enables debug logs for all tag types, and -d nfc.tag.tt3 enables debug logs only for type 3 tags. This option may be given multiple times to enable debug logs for several modules.

-f LOGFILE

Write debug log messages to <LOGFILE> instead of <stderr>. Info, warning and error logs will still be printed to <stderr> unless -q is set to supress info messages on <stderr>.

--nolog-symm

When operating in peer mode this option prevents logging of LLCP Symmetry PDUs from the nfc.llcp.llc module. Symmetry PDUs are exchanged regularly and quite frequently over an LLCP Link and are logged by default if debug output is enabled for the llcp module.

--device PATH

Use a specific reader or search only for a subset of readers. The syntax for PATH is:

  • 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.
-p PASSWORD

Use PASSWORD to authentication with a tag that supports password protection. This would be the same password as used in tagtool.py protect -p to set a password.

Commands

Available commands are listed below. The default if no command is specified is to invoke tagtool.py show.

show

The show command prints information about a tag, including NDEF data if present.:

$ tagtool.py [options] show [-h] [-v]
-v

Print verbose information about the tag found. The amount of additional information depends on the tag type.

dump

The dump command dumps tag data to the console or into a file. Data written to the console is a hexadecimal string. Data written to a file is raw bytes.

$ tagtool.py [options] dump [-h] [-o FILE]
-o FILE

Write data to FILE. Data format is plain bytes.

load

The load command writes data to a tag. Data may be plain bytes or a hex string, as generated by the dump command or with the ndeftool.

$ tagtool.py [options] load [-h] FILE
FILE

Load NDEF data to write from FILE which must exist and be readable. The file may contain NDEF data in either raw bytes or a hexadecimal string which gets converted to bytes. If FILE is specified as a single dash - data is read from stdin.

format

The format command writes NDEF capability information for an empty NDEF memory area on NFC Forum compliant tags. A tag type may be specified to give further options.

$ tagtool.py [options] format [-h] [options] {tt1,tt2,tt3,tt4} ...
--version x.y

The format of the management information that describes the NDEF data area on the tag, as defined in the NFC Forum tag specifications. Only defined version numbers are acceptable. The version must be expressed as a version string of the form <major>.<minor>, where each component is an integer between 0 and 15, inclusively. For example, --version 1.3 denotes major version 1 and minor version 3. If --version is not provided, the highest possible version number is used.

--wipe BYTE

When formatting a tag the NDEF message data itself is usually not touched and could be easily recovered. The --wipe options instructs the formatter to overwrite the complete data area with the given 8-bit integer value. Depending on the tag type and size this may take a couple of seconds.

format tt1

The format tt1 command formats the NDEF partition on a Type 1 Tag.

$ tagtool.py [options] format tt1 [-h]
--magic BYTE

The value to use as the NDEF magic byte. This option can be used to set an invalid magic byte.

--ver x.y

Type 1 Tag NDEF mapping version number, specified as a version string in the same way as for to the --version argument. The difference is that this version number will be written regardless of whether it constitutes a valid version number.

--tms BYTE

Value to write into the tag memory size byte.

--rwa BYTE

Value to write into the read/write access byte.

format tt2

The format tt2 command formats the NDEF partition on a Type 2 Tag.

$ tagtool.py [options] format tt2 [-h]

format tt3

The format tt3 command formats the NDEF partition on a Type 3 Tag. With no additional options it does format for the maximum capacity. With further options it is possible to create any kind of weird tag formats for testing reader implementations. Note that none of these options is verified, except for the possible value range to fit the destination field. None of the options is necessary to create a correct format.

$ tagtool.py [options] format tt3 [-h] [--ver STR] [--nbr INT] [--nbw INT]
                                  [--max INT] [--rfu INT] [--wf INT]
                                  [--rw INT] [--len INT] [--crc INT]
--ver x.y

Type 3 Tag NDEF mapping version number, specified as a version string in the same way as for to the --version argument. The difference is that this version number will be written regardless of whether it constitutes a valid version number.

--nbr N

Type 3 Tag attribute block Nbr field value, the number of blocks that can be read at once. Must be an 8-bit integer in decimal or hexadecimal notation.

--nbw N

Type 3 Tag attribute block Nbw field value, the number of blocks that can be written at once. Must be an 8-bit integer in decimal or hexadecimal notation.

--max N

Type 3 Tag attribute block Nmaxb field value, which is the maximum number of blocks available for NDEF data. Must be a 16-bit integer in decimal or hexadecimal notation.

--rfu N

Type 3 Tag attribute block reserved field value. Must be an 8-bit integer in decimal or hexadecimal notation.

--wf N

Type 3 Tag attribute block WriteF field value. Must be an 8-bit integer in decimal or hexadecimal notation.

--rw N

Type 3 Tag attribute block RW Flag field value. Must be an 8-bit integer in decimal or hexadecimal notation.

--len N

Type 3 Tag attribute block Ln field value that specifies the actual size of the NDEF data stored. Must be a 24-bit integer in decimal or hexadecimal notation.

--crc N

Type 3 Tag attribute block Checksum field value. Must be a 16-bit integer in decimal or hexadecimal notation. If not specified, the checksum is computed to be correct.

format tt4

The format tt4 command formats the NDEF partition on a Type 4 Tag.

$ tagtool.py [options] format tt4 [-h]

protect

The protect command attempts to protect the tag against write modifications, optionally also against unauthorized read access. Support for protection depends on the tag type and product. Without options the the default attempt is protect with lock bits, be warned that this can not be undone. Lock bits are only available for type 1 and type 2 tags. With option -p the protection will be based on a password and further modifications are possible for anyone in posession of the password. Password protection works on NXP NTAG 21x type 2 tags and Sony FeliCa Lite-S type 3 tags.

$ tagtool.py protect [-h] [-p PASSWORD] [--from BLOCK] [--unreadable]
-p PASSWORD

Protect the tag with the given PASSWORD. This works only for the NXP NTAG 21x type 2 tags and Sony FeliCa Lite-S type 3 tags. The password string is used as a key to compute an HMAC-SHA256 with the tag identifier (UID or IDm) as the message. The final password is the leftmost number of octets as needed for the tag product, 6 octets for an NTAG 21x and 16 octets for a FeliCa Lite-S. A password protected tag can then be unlocked with tagtool.py -p.

$ tagtool.py protect -p "my secret password"
$ tagtool.py -p "my secret password" protect -p "new secret"
--from BLOCK

Start protecting data from a given block number. This option does only make sense on tags that organize memory in blocks or pages (Type 1, 2 and 3 Tags). A block corresponds to 4 byte of memory (a page) on Type 1 and 2 Tags, and 16 byte of memory on Type 3 Tags. If the tag has fewer blocks than specified, the value is silently adjusted to the largest possible.

--unreadable

This option can only be used with password based protection. The result is that the tag will become unreadable without a password, i.e. the content is completely hidden. Further reads must then use the password option before the command.

$ tagtool.py -p "secret password" show

emulate

The emulate command emulates an NDEF tag if the hardware and driver support that functionality. The tag type must be specified following the optional parameters. The only currently supported tag type it tt3.

$ tagtool.py emulate [-h] [-l] [-k] [-s SIZE] [-p FILE] [FILE] {tt3} ...
FILE

Initialize the tag with NDEF data read from FILE. If not specified the tag will be just empty.

-l, --loop

Automatically restart after the tag has been released by the Initiator.

-k, --keep

If the --loop option is set, keep the same memory content after tag relase for the next tag activation. Without the -k option the tag memory is initialized from the command options for every activation.

-s SIZE

The minimum size for NDEF data. Depending on the tag type this may be rounded up to the nearest multiple of the tag storage granularity. If NDEF data is provided the size may be adjusted to fit the length of the data.

-p FILE

Preserve memory content in FILE after the tag is relased by the Initiator. The file is created if it does not exist and otherwise overwritten.

emulate tt3

The emulate tt3 command emulates an NFC Forum Type 3 Tag.

$ tagtool.py [options] emulate [options] tt3 [-h] [--idm HEX] [--pmm HEX]
                                             [--sys HEX] [--bitrate {212,424}]
--idm HEX

The Manufacture Identifier to use in the polling response. Specified as a hexadecimal string. Defaults to 03FEFFE011223344.

--pmm HEX

The Manufacture Parameter to use in the polling response. Specified as a hexadecimal string. Defaults to 01E0000000FFFF00.

--sys HEX, --sc HEX

The system code use in the polling response if requested. Specified as a hexadecimal string. Defaults to 12FC.

--bitrate {212,424}

The bitrate to listen for and respond with. Must be either 212 or 424. Defaults to 212 kbps.

Examples

Copy NDEF from one tag to another:

$ tagtool.py dump -o /tmp/tag.ndef && tagtool load /tmp/tag.ndef

Copy NDEF from one tag to many others:

$ tagtool.py dump -o /tmp/tag.ndef && tagtool --loop load /tmp/tag.ndef