NDEF Creation and Modification Tool

The ndeftool is a command line utility for creating, modifying and printing NFC Data Exchange Format (NDEF) Records. It is licensed under the ISCL, hosted on GitHub and installable from PyPI.

$ pip install ndeftool
$ ndeftool --help

NDEFTOOL

Create, modify or print NFC Data Exchange Format Records.

Synopsis

ndeftool [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...

Description

The ndeftool provides a number of commands to create, modify or print NDEF records. Commands can be chained together to successively extend or modify the list of records that are generated. Except for save and print, all records forwarded by the last command are send to standard output as binary NDEF message data. The save and print commands implicitly consume all records unless the --keep option is set. They also, unlike all other commands, do not start an empty record list but read from standard input when given as the first command (the same behavior can be achieved for the load command by setting the file path to -).

By default, NDEF records read from disk or standard input must be correctly formatted NDEF message data (for example, the first and the last record must have the message begin and end flag set). The --relax makes the decoder accept correctable data errors and the --ignore option will additionally skip records with uncorrectable errors.

Options

--version

Show the version and exit.

--relax

Ignore some errors when decoding.

--ignore

Ignore all errors when decoding.

--silent

Suppress all progress information.

--debug

Output debug progress information.

--help

Show this message and exit.

Commands

load

Load records or payloads from disk.

Synopsis
ndeftool load [OPTIONS] PATH
ndeftool l [OPTIONS] PATH
Description

The load command reads records or payloads from disk files or standard input. The files for reading are determined by the pattern specified by PATH, which in the simplest form is an existing file name. Other forms may include *, ? and character ranges expressed by []. A single - may be used to read from standard input. Note that patterns containg wildcards may need to be escaped to avoid shell expansion.

The default mode of operation is to load files containing NDEF records. In --pack mode the files are loaded into the payload of NDEF records with record type (NDEF Record TNF and TYPE) set to the mimetype discovered from the payload and record name (NDEF Record ID) set to the filename.

Options
-p, --pack

Pack files as payload into mimetype records.

--help

Show this message and exit.

Examples

Pack text from standard input and pack as record.

$ echo -n "Hello World" | ndeftool load --pack - print
/bin/sh: 1: ndeftool: not found

Read text from file and pack as record.

$ echo -n "Hello World" > /tmp/hello && ndeftool load --pack /tmp/hello print
/bin/sh: 1: ndeftool: not found

Read with path containing wildcard characters.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/load.rst, line 64)

Command u”ndeftool load –pack ‘i?d*.rst’ print” failed: [Errno 2] No such file or directory

Read and pack multiple files.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/load.rst, line 68)

Command u”ndeftool load –pack ‘../se?up.*’ print” failed: [Errno 2] No such file or directory

save

Save records or payloads to disk.

Synopsis
ndeftool save [OPTIONS] PATH
ndeftool s [OPTIONS] PATH
Description

The save command writes the current records to disk. The records to write can be restricted to the subset selected with --skip, --count, --head and --tail applied in that order. The default mode is to save all selected records as one NDEF message into a single file given by PATH. In --burst mode each record is written as one NDEF message into a separate file under the directory given by PATH. The file names are three digit numbers created from the record index. In --unpack mode the payload of each record is written to a separate file under directory PATH with the file name set to the record name (NDEF Record ID). Records without name are not written unless --unpack and --burst are both set.

The save command does not replace existing files or directories unless this is requested with --force.

The save command consumes records from the internal message pipe. This can be prevented with --keep, all records are then forwarded to the next command or written to standard output. When save is the first command it creates the pipe by reading from standard input.

Options
--skip N

Skip the first N records.

--count N

Skip the first N records.

--head N

Save the first N records.

--tail N

Save the last N records.

-b, --burst

Save single record files in directory.

-u, --unpack

Unpack records to files in directory.

-f, --force

Replace existing file or directory.

-k, --keep

Forward records to next command.

--help

Show this message and exit.

Examples

Create an NFC Forum Text Record and save it to to a file in the /tmp directory, overwriting the file if it exists.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/save.rst, line 88)

Command u’ndeftool text “Hello World” save –force /tmp/hello.ndef’ failed: [Errno 2] No such file or directory

Same as above but the with three NDEF Text Records.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/save.rst, line 92)

Command u’ndeftool text One text Two text Three save –force /tmp/text.ndef’ failed: [Errno 2] No such file or directory

Out of three records the second is saved using the --skip and --count options and the others are forwarded to print.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/save.rst, line 97)

Command u’ndeftool txt aa txt bb txt cc save -f –skip 1 –count 1 /tmp/text.ndef print’ failed: [Errno 2] No such file or directory

Out of three records the second is saved using the --head and --tail options and the others are forwarded to print.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/save.rst, line 102)

Command u’ndeftool txt aa txt bb txt cc save -f –head 2 –tail 1 /tmp/text.ndef print’ failed: [Errno 2] No such file or directory

Save each record to a separate file with auto-numbered file name plus ndef extension.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/save.rst, line 107)

Command u’ndeftool txt aa txt bb txt cc save -f –burst /tmp/text/’ failed: [Errno 2] No such file or directory

Unpack record payloads to separate files using the record identifier as the file name.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/save.rst, line 112)

Command u’ndeftool txt aa id 1.txt txt bb id 2.txt txt cc id 3.txt save -f –unpack /tmp/text/’ failed: [Errno 2] No such file or directory

print

Print records as human readable.

Synopsis
ndeftool print [OPTIONS]
ndeftool p [OPTIONS]
Description

The print command outputs a formatted representation of all current NDEF Records. By default this is the one line str() representation for each record. The --long format produces multiple indented lines per record in an attempt to provide a more readable output. Printing consumes all records so that no more data is send to stdout or given to the next command. This can be changed with the --keep flag.

When given as the first command print attempts to decode an NDEF message from standard input and process the generated list of records.

Options
-l, --long

Output in a long print format.

-k, --keep

Keep records for next command.

--help

Show this message and exit.

Examples

Print records in short format.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/print.rst, line 54)

Command u’ndeftool text “Hello World” print’ failed: [Errno 2] No such file or directory

Print records in long format.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/print.rst, line 58)

Command u’ndeftool text “Hello World” print –long’ failed: [Errno 2] No such file or directory

Print records in both short and long format.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/print.rst, line 62)

Command u’ndeftool text “Hello World” print –keep print –long’ failed: [Errno 2] No such file or directory

identifier

Change the identifier of the last record.

Synopsis
ndeftool identifier [OPTIONS] NAME
ndeftool id [OPTIONS] NAME
Description

The identifier command either changes the current last record’s name (NDEF Record ID) or, if the current message does not have any records, creates a record with unknown record type and the given record name.

Options
--help

Show this message and exit.

Examples

Create a record with unknown type and set the identifier.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/identifier.rst, line 40)

Command u”ndeftool identifier ‘record identifier’ print” failed: [Errno 2] No such file or directory

Create two text records with specific identifiers.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/identifier.rst, line 44)

Command u”ndeftool text ‘first’ id ‘r1’ text ‘second’ id ‘r2’ print” failed: [Errno 2] No such file or directory

typename

Change the type name of the last record.

Synopsis
ndeftool typename [OPTIONS] TYPE
ndeftool tn [OPTIONS] TYPE
Description

The typename command either changes the current last record’s type (NDEF Record TNF and TYPE) or, if the current message does not have any records, creates a record with the given record type. The changed record is verified to successfully encode and decode unless disabled with -x.

Options
-x, --no-check

Do not check decoding after type name change.

--help

Show this message and exit.

Examples

Create a record with text/plain mime type and no payload.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/typename.rst, line 45)

Command u”ndeftool typename ‘text/plain’ print” failed: [Errno 2] No such file or directory

Create a plain text record and add some payload.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/typename.rst, line 49)

Command u”ndeftool typename ‘text/plain’ payload ‘Hello World’ print” failed: [Errno 2] No such file or directory

Create a record with a payload that does not match the record type.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/typename.rst, line 53)

Command u”ndeftool payload ‘Hello World’ typename -x ‘urn:nfc:wkt:T’ print -l” failed: [Errno 2] No such file or directory

payload

Change the payload of the last record.

Synopsis
ndeftool payload [OPTIONS] DATA
ndeftool pl [OPTIONS] DATA
Description

The payload command either changes the current last record’s data (NDEF Record PAYLOAD) or, if the current message does not have any records, creates a record with the given record data. The changed record is verified to successfully encode and decode unless disabled with -x.

The data string may contain hexadecimal bytes using xNN notation where each N is a nibble from [0-F].

Options
-x, --no-check

Do not check decoding after type name change.

--help

Show this message and exit.

Examples

Create a plain text payload record.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/payload.rst, line 48)

Command u”ndeftool payload ‘Hello World’ typename ‘text/plain’ print” failed: [Errno 2] No such file or directory

Create an NFC Forum Text record with language code and content.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/payload.rst, line 52)

Command u”ndeftool payload ‘\\x02enHello World’ typename ‘urn:nfc:wkt:T’ print -l” failed: [Errno 2] No such file or directory

Create a record with a payload that does not match the record type. The first command creates an NFC Forum Text Record with language code identifier and text content. The second command then replaces the payload with just the text and would make decoding fail.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/payload.rst, line 59)

Command u”ndeftool text ‘Hello World’ payload -x ‘Hello World’ print -l” failed: [Errno 2] No such file or directory

text

Create an NFC Forum Text Record.

Synopsis
ndeftool text [OPTIONS] TEXT
ndeftool txt [OPTIONS] TEXT
Description

The text command creates an NFC Forum Text Record with the given input text. The text language defaults to English (language code en) and can be set with --language followed by the IANA language code. The text content is encoded as UTF-8 or UTF-16 depending on --encoding. The default encoding is UTF-8.

Options
-l, --language TEXT

Set the IANA language code.

--encoding [UTF-8|UTF-16]

Set the encoding (default UTF-8).

--help

Show this message and exit.

Examples

Create an NFC Forum Text Record with the default language en and encoding UTF-8.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/text.rst, line 50)

Command u”ndeftool text ‘created with the nfcpy ndeftool’ print” failed: [Errno 2] No such file or directory

Create one text record with English text and one record with German text.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/text.rst, line 54)

Command u”ndeftool text –language en ‘English’ text –language de ‘Deutsch’ print” failed: [Errno 2] No such file or directory

Create a text record with UTF-16 encoding.

$ ndeftool text --encoding UTF-16 'text encoded in UTF-16' | hd
/bin/sh: 1: ndeftool: not found
/bin/sh: 1: hd: not found

uri

Create an NFC Forum URI Record.

Synopsis
ndeftool uri [OPTIONS] RESOURCE
Description

The uri command creates an NFC Forum URI Record wit the given resource identifier. Note that this is actually an Internationalized Resource Identifier (IRI).

Options
--help

Show this message and exit.

Examples

Create a URI record that links to http://nfcpy.org.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/uri.rst, line 39)

Command u”ndeftool uri ‘http://nfcpy.org’ print” failed: [Errno 2] No such file or directory

smartposter

Create an NFC Forum Smart Poster Record.

Synopsis
ndeftool smartposter [OPTIONS] RESOURCE
ndeftool smp [OPTIONS] RESOURCE
Description

The smartposter command creates an NFC Forum Smart Poster Record for the resource identifier. A smart poster record combines the uniform resource identifier with additional data such as titles and icons for representation and processing instructions for the reader application.

A smart poster record should have title text for the desired languages, added with repetitive -t options. An English title text may also be added with -T. The recommended action set with -a tells the reader application to either run the default action for the URI, save it for later or open for editing.

A smart poster may also provide a collection of icons for graphical representation. An icon file is added with the -i option that may be given more than once. The icon type is determined from the file content and must be an image or video mime type.

Options
-T TEXT

Smartposter title for language code ‘en’.

-t LANG TEXT

Smartposter title for a given language code.

-a [exec|save|edit]

Recommended action for handling the resource.

-i FILENAME

Icon file for a graphical representation.

--help

Show this message and exit.

Examples

An NFC Forum Smart Poster Record with just a link, nothing more useful than a URI Record.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/smartposter.rst, line 68)

Command u’ndeftool smartposter http://nfcpy.org print’ failed: [Errno 2] No such file or directory

Same as above but with an English title.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/smartposter.rst, line 72)

Command u”ndeftool smartposter -T ‘nfcpy project’ http://nfcpy.org print” failed: [Errno 2] No such file or directory

Titles for other languages must be given with a language code.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/smartposter.rst, line 76)

Command u”ndeftool smartposter -t de ‘Google Deutschland’ https://www.google.de print” failed: [Errno 2] No such file or directory

An emergency call number should be called immediately.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/smartposter.rst, line 80)

Command u”ndeftool smartposter -T ‘EMERGENCY CALL 911’ -a exec ‘tel:911’ print -l” failed: [Errno 2] No such file or directory

Add an icon file to a smart poster.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/commands/smartposter.rst, line 84)

Command u’ndeftool smp -i images/ndeftool.png https://github.com/nfcpy/ndeftool print -l’ failed: [Errno 2] No such file or directory

Examples

Any NDEF Record can be constructed with the payload, typename and identifier commands.

System Message: ERROR/3 (/home/docs/checkouts/readthedocs.org/user_builds/ndeftool/checkouts/v0.1.0/docs/ndeftool.rst, line 92)

Command u”ndeftool payload ‘\\02ensample text’ typename ‘urn:nfc:wkt:T’ id ‘r1’ print” failed: [Errno 2] No such file or directory

The same record can be created with the text command. Here the output goes to stdout and is then printed with a separate ndeftool process call.

$ ndeftool text 'sample text' id 'r1' | ndeftool print
/bin/sh: 1: ndeftool: not found
/bin/sh: 1: ndeftool: not found

The save command writes the records to disk or <stdout> for path name -. The following example creates an NDEF message with three NFC Forum Text Records, the first and last record with the message begin and message end flags set.

$ ndeftool text ONE text TWO text THREE save - | hd
/bin/sh: 1: ndeftool: not found
/bin/sh: 1: hd: not found

The save command can be used to write intermediate results, here immediately after a text record has been created. Note that by writing to <stdout> the result is a sequence of three individual NDEF messages of one record each. This would not be a proper NDEF message file.

$ ndeftool text ONE save - text TWO save - text THREE save - | hd
/bin/sh: 1: ndeftool: not found
/bin/sh: 1: hd: not found

The load command reads records from disk or <stdin> for path name -.

$ ndeftool text ONE text TWO text THREE | ndeftool load - print
/bin/sh: 1: ndeftool: not found
/bin/sh: 1: ndeftool: not found

An empty NDEF Record can be created with an empty type name string. The first octet 11010000b sets the Message Begin (MB) and Message End (ME) flags in the two most signifant bits. The Type Name Format (TNF) value 0 in the least significant three bits indicates that there is no type or payload associated with this record and thus the TYPE LENGTH and PAYLOAD LENGTH fields must be zero.

$ ndeftool typename '' | hd
/bin/sh: 1: ndeftool: not found
/bin/sh: 1: hd: not found

The default decoding of an NDEF message requires correct data format. Data with minor format errors can be decoded with the --relax option. The following example creates two empty records with invalid MB and ME flags that do only decode with --relax.

$ python3 -c "import sys; sys.stdout.buffer.write(b'\x10\0\0\x10\0\0')" | ndeftool --relax print
/bin/sh: 1: ndeftool: not found
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

NDEF message data with uncorrectable errors can be skipped with the --ignore option. The payload length 1 in the second record is an invalid value for an empty record.

$ python3 -c "import sys; sys.stdout.buffer.write(b'\x10\0\0\x10\1\0')" | ndeftool --ignore print
/bin/sh: 1: ndeftool: not found
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

Contributing

Thank you for considering contributing to ndeftool. There are many ways to help and any help is welcome.

Reporting issues

  • Under which versions of Python does this happen? This is especially important if your issue is encoding related.
  • Under which versions of ndeftool does this happen? Check if this issue is fixed in the repository.

Submitting patches

  • Include tests if your patch is supposed to solve a bug, and explain clearly under which circumstances the bug happens. Make sure the test fails without your patch.
  • Include or update tests and documentation if your patch is supposed to add a new feature. Note that documentation is in two places, the code itself for rendering help pages and in the docs folder for the online documentation.
  • Follow PEP 8 and PEP 257.

Development tips

  • Fork the repository and clone it locally:

    git clone git@github.com:your-username/ndeftool.git
    cd ndeftool
    
  • Create virtual environments for Python 2 an Python 3, setup the ndeftool package in develop mode, and install required development packages:

    virtualenv python-2
    python3 -m venv python-3
    source python-2/bin/activate
    python setup.py develop
    pip install -r requirements-dev.txt
    source python-3/bin/activate
    python setup.py develop
    pip install -r requirements-dev.txt
    
  • Verify that all tests pass and the documentation is build:

    tox
    
  • Preferably develop in the Python 3 virtual environment. Running tox ensures tests are run with both the Python 2 and Python 3 interpreter but it takes some time to complete. Alternatively switch back and forth between versions and just run the tests:

    source python-2/bin/activate
    py.test
    source python-3/bin/activate
    py.test
    
  • Test coverage should be close to 100 percent. A great help is the HTML output produced by coverage.py:

    py.test --cov ndeftool --cov-report html
    firefox htmlcov/index.html
    
  • The documentation can be created and viewed loacally:

    (cd docs && make html)
    firefox docs/_build/html/index.html
    

License

The ndeftool is licensed under the Internet Systems Consortium ISC license. This is a permissive free software license functionally equivalent to the simplified BSD and the MIT license.

License text

ISC License

Copyright (c) 2017 by Stephen Tiedemann.

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.