- nfc-writer is now a native egui window (Windows, macOS, Linux); the web version moves to the nfc-writer-web binary. Both share src/reader.rs and src/ndef.rs through the library crate. - Reader choice no longer depends on the ACR1252U's Windows naming: skip SAM slots, prefer contactless names (PICC/Contactless/NFC/CL), then a reader with a card present; NFC_READER forces one by name substring. - ATR via SCardStatus instead of SCardGetAttrib, which macOS lacks. - Platform-specific "no reader" hints (pcscd/libccid on Linux, ACS driver on macOS); Thai fallback font for the GUI from the system fonts. - Clippy clean for x86_64-pc-windows-msvc, x86_64-unknown-linux-gnu and aarch64-apple-darwin; README with per-OS setup and a test matrix.
70 lines
3.0 KiB
Markdown
70 lines
3.0 KiB
Markdown
# NFC tag writer
|
|
|
|
Programs 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**.
|
|
|
|
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.
|
|
|
|
## 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`.
|
|
|
|
## 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).
|