grabowski 8b95d0d5d7
Release / release (push) Successful in 6m46s
Read feature, release workflow (v0.3.0)
- Read button (desktop and web): reads the tag now, bypassing the status
  cache, and puts its first link or text record into the input field so it
  can be copied to another tag. POST /api/read in the web version.
- Raw memory: every 4-byte page from page 0 (UID, lock bytes, CC, data) in
  hex and ASCII, collapsed by default.
- Content now shows the records and the note together (a locked tag showed
  only "read-only" before); read failures are flagged with read_failed
  instead of matching message text.
- .gitea/workflows/release.yml: on a v* tag, tests and clippy, then Linux
  (ubuntu-22.04, glibc 2.35) and Windows (MinGW cross-build) packages
  attached to the tag's release with its CHANGELOG.md section.
- README: reading, why the reader program runs on the reader's machine,
  releases.
2026-10-29 09:38:43 +07:00

NFC tag writer

Programs and reads NFC tags through a USB PC/SC reader such as the ACS ACR1252U-M1. Type a URL or some text, put a tag on the reader, press Program. Press Read to load a tag's link or text into the field, for example to copy it to another tag.

Downloads for Windows and Linux: https://git.b4l.co.th/B4L/NFC/releases

There are two ways to run it, with the same reader logic behind both:

Program What it is
nfc-writer Desktop window. No browser or network needed.
nfc-writer-web Local web page at http://127.0.0.1:7252 (port: NFC_PORT), reachable from this machine only.

What it writes

  • Input that starts with http://, https://, www., tel:, mailto:, sms: or geo:, or any scheme://, becomes an NDEF link record. www. gets https:// in front.
  • Anything else becomes an NDEF text record (language en).
  • Supported tags: NTAG213, NTAG215, NTAG216 and MIFARE Ultralight / EV1 / C (NFC Forum Type 2). MIFARE Classic, DESFire and bank cards are recognised and refused with a message.
  • A write first empties the tag's NDEF message and writes its header last. If the tag is pulled away halfway, it ends up empty rather than holding broken data. After writing, the tag is read back and compared.

What it reads

As soon as a tag is on the reader, the window shows its UID, chip type, memory use and content. Read reads the tag again and puts its first link or text into the input field. "Raw memory" lists every 4-byte page of the tag in hex and ASCII. Any card shows its UID; only Type 2 tags show content.

Which reader it uses

The program asks the operating system's smart-card service (PC/SC) for readers. Any PC/SC contactless reader should work, not only the ACR1252U.

  • It skips SAM slots (the ACR1252U shows up as two readers, … PICC and … SAM).
  • It prefers a reader whose name says contactless (PICC, Contactless, NFC, CL), then a reader that has a card on it.
  • To force a reader, set NFC_READER to part of its name, e.g. NFC_READER="ACR1252".
  • Plugging the reader in or out while the program runs is fine; it is picked up within a second.

Build and run

You need Rust (https://rustup.rs). Then, in this folder:

cargo run --release                      # desktop window
cargo run --release --bin nfc-writer-web # web page

The binaries end up in target/release/. Build on the operating system you want to run it on.

Windows

Nothing else to install: the smart-card service and a driver for the ACR1252U come with Windows.

macOS

Install the Xcode command line tools (xcode-select --install). macOS has the smart-card service built in. If the reader is not listed, install the ACR1252U driver from the ACS website.

Linux (Debian, Ubuntu)

sudo apt install pkg-config libpcsclite-dev pcscd libccid
sudo systemctl enable --now pcscd.socket

Fedora: sudo dnf install pkgconf pcsc-lite-devel pcsc-lite pcsc-lite-ccid. Arch: sudo pacman -S pkgconf pcsclite ccid.

Why it runs on the machine with the reader

Browsers cannot reach a USB smart-card reader: WebUSB blocks the smart-card device class, and Web NFC exists only in Chrome on Android. So the program that talks to the reader has to run on the computer the reader is plugged into. The web version is a convenience for that same computer; hosting it on a server would only reach the server's own USB ports.

Releases

Push a tag v* (with a matching section in CHANGELOG.md): .gitea/workflows/release.yml tests, builds Linux and Windows x86_64 packages and attaches them to the tag's release.

Tested

Windows 11 macOS Linux
Builds, unit tests, clippy yes type-checked only type-checked only
Finds the ACR1252U yes not yet not yet
Reads and writes a tag not yet not yet not yet

Code

  • src/ndef.rs: NDEF records and Type 2 TLVs (unit-tested).
  • src/reader.rs: reader choice, card type from the ATR, reading and writing tag memory.
  • src/main.rs: desktop window (egui).
  • src/bin/nfc-writer-web.rs and static/index.html: web version (axum).
S
Description
No description provided
Readme
143 KiB
0 Stars 8 Watchers 0 Forks
2026-10-29 09:45:26 +07:00
Languages
Rust 78.2%
HTML 15.7%
Python 6.1%