From 7bfd6b6189ed23b655c606547bb1fd60e7295e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AD=90=E6=AD=AA?= Date: Sat, 5 Sep 2026 05:18:51 +0800 Subject: [PATCH] docs: content clean up --- doc/mfu_ndef_format_notes.md | 60 ++++++++++-------------------------- 1 file changed, 16 insertions(+), 44 deletions(-) diff --git a/doc/mfu_ndef_format_notes.md b/doc/mfu_ndef_format_notes.md index d4a79a86e..8f18917e1 100644 --- a/doc/mfu_ndef_format_notes.md +++ b/doc/mfu_ndef_format_notes.md @@ -1,8 +1,8 @@ -# Notes on `hf mfu format` +# Notes on `hf mfu ndefformat` # Table of Contents -- [Notes on hf mfu format](#notes-on-hf-mfu-format) +- [Notes on hf mfu ndefformat](#notes-on-hf-mfu-ndefformat) - [Table of Contents](#table-of-contents) - [Why the command exists](#why-the-command-exists) - [Capability Container basics](#capability-container-basics) @@ -14,40 +14,27 @@ ## Why the command exists ^[Top](#top) -`hf mfu ndefwrite` refuses a tag with no Capability Container (CC). Before this command the only -way to add one was a hand computed `hf mfu wrbl -b 3 -d ` — block 3 is One Time Programmable -(OTP), so a wrong value is permanent. +`hf mfu ndefwrite` refuses a tag with no Capability Container (CC). Before this command the only way to add one was a hand computed `hf mfu wrbl -b 3 -d ` — block 3 is One Time Programmable (OTP), so a wrong value is permanent. -`hf mfu format` writes the NXP factory delivery content (CC + an empty NDEF message) for the -detected tag type, restoring what the tag looked like before anything was written to it. +`hf mfu ndefformat` writes the NXP factory delivery content (CC + an empty NDEF message) for the detected tag type, restoring what the tag looked like before anything was written to it. ## Capability Container basics ^[Top](#top) -Page 3 (`E1 10 00`) is OTP on every type below: a WRITE is bit-wise OR'ed with the current -content, so a bit already set to 1 can never be cleared again. `MLEN * 8` is the size of the NDEF -data area in bytes. +Page 3 (`E1 10 00`) is OTP on every type below: a WRITE is bit-wise OR'ed with the current content, so a bit already set to 1 can never be cleared again. `MLEN * 8` is the size of the NDEF data area in bytes. -Consequences for the implementation, in `mfu_get_ndef_format()` / `CmdHF14AMfUFormat()` in -`client/src/cmdhfmfu.c`: +Consequences for the implementation, in `mfu_get_ndef_format()` / `CmdHF14AMfUFormat()` in `client/src/cmdhfmfu.c`: - an unknown tag type is refused rather than guessed at -- a target CC that the current OTP content cannot reach (checked with the same bit-wise OR) is - refused before anything is written -- `-d` on a *known* type is capped at that type's own MLEN unless `--force` is given, so a typo - cannot silently announce more memory than the tag holds -- `--erase`'s end block is derived from the table's MLEN, never from `-d`, so it cannot run past - the user memory into the lock bytes or configuration pages -- after writing, the command re-selects and reads blocks 3-5 back to confirm the OTP write - actually took — a tag can ACK a WRITE and still not commit the page (weak field, tearing, a lock - bit already set) +- a target CC that the current OTP content cannot reach (checked with the same bit-wise OR) is refused before anything is written +- `-d` on a *known* type is capped at that type's own MLEN unless `--force` is given, so a typo cannot silently announce more memory than the tag holds +- `--erase`'s end block is derived from the table's MLEN, never from `-d`, so it cannot run past the user memory into the lock bytes or configuration pages +- after writing, the command re-selects and reads blocks 3-5 back to confirm the OTP write actually took — a tag can ACK a WRITE and still not commit the page (weak field, tearing, a lock bit already set) ## Per-type delivery content ^[Top](#top) -Only the NTAG21x family ships with a CC at all. UL / UL-C / UL EV1 and NTAG203 leave page 3 blank -at delivery, so their CC is derived from the user memory range instead of copied from a data -sheet. +Only the NTAG21x family ships with a CC at all. UL / UL-C / UL EV1 and NTAG203 leave page 3 blank at delivery, so their CC is derived from the user memory range instead of copied from a data sheet. | Type | Part | MLEN | User memory | Data sheet | |---|---|---|---|---| @@ -70,33 +57,18 @@ sheet. ## Lock Control TLV ^[Top](#top) -Standards ref: NFC Forum Type 2 Tag Operation, and the Capability Container layout in the data -sheets cited above. +Standards ref: NFC Forum Type 2 Tag Operation, and the Capability Container layout in the data sheets cited above. -NTAG212, NTAG213, NTAG213F and NTAG213TT are delivered with a 5 byte Lock Control TLV ahead of the -NDEF TLV (`01 03 ...`). The other types in the table -are not. This TLV tells an NFC device where the *dynamic* lock bytes live so it can lock the tag -read-only — on these parts the dynamic lock bytes sit just past the user memory (e.g. NTAG213 at -page 40h, right after the page 04h-27h data area), so the TLV exists purely for that use case, not -because a writer needs to avoid overwriting anything. +NTAG212, NTAG213, NTAG213F and NTAG213TT are delivered with a 5 byte Lock Control TLV ahead of the NDEF TLV (`01 03 ...`). The other types in the table are not. This TLV tells an NFC device where the *dynamic* lock bytes live so it can lock the tag read-only — on these parts the dynamic lock bytes sit just past the user memory (e.g. NTAG213 at page 40h, right after the page 04h-27h data area), so the TLV exists purely for that use case, not because a writer needs to avoid overwriting anything. -`hf mfu format` copies this TLV verbatim from the factory content; it does not construct one. -`hf mfu ndefwrite` preserves any control TLV (type `01` or `02`) it finds ahead of the NDEF TLV -before overwriting the data area — see the code for the exact scan. +`hf mfu ndefformat` copies this TLV verbatim from the factory content; it does not construct one. `hf mfu ndefwrite` preserves any control TLV (type `01` or `02`) it finds ahead of the NDEF TLV before overwriting the data area — see the code for the exact scan. ## NTAG215 / NTAG216 under-reporting ^[Top](#top) -The factory MLEN announces less than the physical user memory: NTAG215 announces 496 bytes of a -504 byte area, NTAG216 announces 872 of 888. The data sheet does not explain the 8/16 byte gap. -The NXP value is used as-is rather than corrected upward, since under-reporting can never let a -write run past the user memory while a larger value could. +The factory MLEN announces less than the physical user memory: NTAG215 announces 496 bytes of a 504 byte area, NTAG216 announces 872 of 888. The data sheet does not explain the 8/16 byte gap. The NXP value is used as-is rather than corrected upward, since under-reporting can never let a write run past the user memory while a larger value could. ## NTAG213C ^[Top](#top) -NXP publishes no data sheet for this part number (NT2H1311C1DTL) and none could be found anywhere -else. It was added to the client in commit `ad19f8384` (2020-09-26, "add accurate detection for -NT2H1311C1DTL") from an observed tag's `GET_VERSION` response, which differs from a plain NTAG213 -only in the minor product version byte (`01h` vs `00h`); the storage size byte — the one that -encodes the 144 byte user memory — is identical. The NTAG213 content is used on that basis. +NXP publishes no data sheet for this part number (NT2H1311C1DTL) and none could be found anywhere else. It was added to the client in commit `ad19f8384` (2020-09-26, "add accurate detection for NT2H1311C1DTL") from an observed tag's `GET_VERSION` response, which differs from a plain NTAG213 only in the minor product version byte (`01h` vs `00h`); the storage size byte — the one that encodes the 144 byte user memory — is identical. The NTAG213 content is used on that basis.