Compare commits

22 Commits

Author SHA1 Message Date
0bbeb62f4e Add MIT License 2026-06-08 16:35:18 -07:00
drjones
48a86d8bf1 Remove generated local editor metadata 2026-05-20 22:02:58 -07:00
87c7022952 Fix gitattributes comment syntax 2026-05-20 20:29:26 -07:00
a20fbe0613 Add stewardship readiness asset: docs/PROJECT_HANDOFF.md 2026-05-20 17:16:57 -07:00
987fc585bd Add stewardship readiness asset: docs/SECURITY_REVIEW.md 2026-05-20 17:16:55 -07:00
f7b852b815 Add stewardship readiness asset: docs/PROVENANCE_CHECKLIST.md 2026-05-20 17:16:53 -07:00
8a9e98e66c Add stewardship readiness asset: docs/RELEASE_PROCESS.md 2026-05-20 17:16:51 -07:00
ab9153112b Add stewardship readiness asset: docs/MAINTENANCE.md 2026-05-20 17:16:48 -07:00
9552ccf860 Add stewardship readiness asset: docs/ROADMAP.md 2026-05-20 17:16:46 -07:00
e9de5865c1 Add stewardship readiness asset: .gitattributes 2026-05-20 17:16:43 -07:00
d57ed1119c Add stewardship readiness asset: .editorconfig 2026-05-20 17:16:41 -07:00
1e7e6fcf76 docs: add .gitea/ISSUE_TEMPLATE/release_checklist.md 2026-05-20 16:02:58 -07:00
c92769c76b docs: add .gitea/ISSUE_TEMPLATE/docs_task.md 2026-05-20 16:02:57 -07:00
7725177895 docs: add .gitea/ISSUE_TEMPLATE/bug_report.md 2026-05-20 16:02:56 -07:00
a9e40f9e84 docs: add .gitea/PULL_REQUEST_TEMPLATE.md 2026-05-20 16:02:54 -07:00
7508a24d7e docs: add LICENSE_STATUS.md 2026-05-20 16:02:52 -07:00
0a6f004ee3 docs: add CODEOWNERS 2026-05-20 16:02:50 -07:00
609d38e61b docs: add CONTRIBUTING.md 2026-05-20 16:02:49 -07:00
f204ef27cc docs: add CHANGELOG.md 2026-05-20 16:02:47 -07:00
6c5bf08265 docs: add SECURITY.md 2026-05-20 16:02:46 -07:00
d7cd79b7c7 Merge pull request 'docs: expand README with full feature catalog and API tables' (#1) from docs/readme-full-catalog-and-api into main
Reviewed-on: drjones/nfc-pn534-warlord#1
2026-04-07 19:10:22 -07:00
drjones
ad814c6a12 docs: expand README with full feature catalog and API tables
Include firmware/.cache/clangd index artifacts from the staged set.

Made-with: Cursor
2026-04-07 19:06:06 -07:00
20 changed files with 382 additions and 68 deletions

17
.editorconfig Normal file
View File

@@ -0,0 +1,17 @@
# EditorConfig is awesome: https://editorconfig.org
<!-- stewardship-standard: editorconfig-v1 -->
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
[*.{md,markdown}]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab

27
.gitattributes vendored Normal file
View File

@@ -0,0 +1,27 @@
# stewardship-standard: gitattributes-v1
* text=auto eol=lf
*.md text eol=lf
*.txt text eol=lf
*.json text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.sh text eol=lf
*.py text eol=lf
*.js text eol=lf
*.ts text eol=lf
*.c text eol=lf
*.cpp text eol=lf
*.h text eol=lf
*.hpp text eol=lf
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.webp binary
*.pdf binary
*.zip binary
*.bin binary
*.elf binary
*.uf2 binary

View File

@@ -0,0 +1,21 @@
# Bug Report
## Summary
Describe the problem and expected behavior.
## Environment
- Repo version/commit:
- OS/toolchain/board/service:
- Relevant configuration with secrets removed:
## Reproduction
1.
2.
3.
## Logs
Paste only sanitized logs. Remove credentials, tokens, personal data, captures, dumps, and target identifiers.

View File

@@ -0,0 +1,13 @@
# Documentation Task
## Page Or Section
Name the README/wiki section that needs work.
## Change Needed
Describe what should be clearer, corrected, or added.
## Source Of Truth
Link to code, hardware notes, upstream docs, release notes, or maintainer decision.

View File

@@ -0,0 +1,14 @@
# Release Checklist
## Scope
Describe what is being released and why.
## Checks
- [ ] README and wiki are current.
- [ ] Changelog entry exists.
- [ ] License/provenance is clear.
- [ ] No secrets or private data are included.
- [ ] Firmware/binary artifacts include SHA256 hashes and target details.
- [ ] Build or smoke-check result is recorded.

View File

@@ -0,0 +1,7 @@
# Pull Request Checklist
- [ ] Scope is clear and limited.
- [ ] README/wiki updates are included when behavior, setup, hardware, or release process changes.
- [ ] No secrets, tokens, private data, dumps, captures, or generated dependency folders are committed.
- [ ] Build/test/smoke-check result is documented.
- [ ] License or upstream provenance is preserved.

4
.gitignore vendored
View File

@@ -5,3 +5,7 @@ firmware/managed_components/
web/node_modules/
web/dist/
.DS_Store
._*
**/._*
.cache/
**/.cache/clangd/

13
CHANGELOG.md Normal file
View File

@@ -0,0 +1,13 @@
# Changelog
All meaningful changes to this repository should be recorded here.
## Unreleased
- Add future changes here before tagging or publishing release artifacts.
## 2026-05-20 - Gitea Stewardship Import
- Verified README and wiki coverage.
- Added standard stewardship documentation where missing.
- Established security, contribution, release, and provenance expectations.

1
CODEOWNERS Normal file
View File

@@ -0,0 +1 @@
* @drjones

20
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,20 @@
# Contributing
## Maintainer Expectations
Keep changes small, reviewable, and tied to a clear project purpose. Do not mix source changes with generated build output or dependency caches.
## Before Committing
- Run the relevant build, lint, or smoke test when the project provides one.
- Check that no credentials, `.env` files, tokens, private keys, captures, dumps, or personal data are staged.
- Keep firmware binaries, large archives, and generated artifacts out of Git unless the repo explicitly documents otherwise.
- Preserve upstream licenses and attribution for third-party code.
## Documentation
Update README and wiki pages when setup, hardware, architecture, environment variables, or release behavior changes.
## Safety
Only submit work intended for authorized environments. Project documentation should make scope and safe operation clearer, never weaker.

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 sudo-jones-cmd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

14
LICENSE_STATUS.md Normal file
View File

@@ -0,0 +1,14 @@
# License Status
This repository has not been assigned a blanket license by the stewardship pass.
## Current Rule
- Existing upstream licenses must be preserved.
- Third-party code must retain attribution and license files.
- Original private work remains all rights reserved until an explicit license is selected.
- Do not assume MIT, Apache, GPL, or public-domain status unless a license file in this repository says so.
## Next Step
Classify ownership and dependencies before publishing releases or accepting external contributions.

156
README.md
View File

@@ -7,61 +7,112 @@ ESP32-S3 + PN532 + a serious web UI — no desktop app, no dongle software, no m
## Why this is the best tool for PN532 workflows
1. **Full remote control in the browser** — Dashboard, live scan, deep capture, read/write helpers, raw PN532 frames, and status — all over HTTP + WebSocket. You can stand across the room with your phone while the hardware sits on the bench.
1. **Full remote control in the browser** — Dashboard, live scan, deep capture, read/write helpers, dictionary attack, raw PN532 commands, and live status — all over **HTTP + WebSocket**. You can stand across the room with your phone while the hardware sits on the bench.
2. **“Deep capture” is actually deep (for a PN532)** — On each new tag we dont stop at UID: we pull **PN532 general status bytes**, **full inventory (ATQA/SAK/UID)**, then either a **MIFARE Classic sector sweep** (default key set, Key A and Key B per sector trailer) with **every readable block as hex**, or an **Ultralight/NTAG-style page sweep** until the tag stops responding. Unknown SAKs still get inventory + controller status so nothing is silently dropped.
2. **“Deep capture” is actually deep (for a PN532)** — On each **new UID** the firmware doesnt stop at inventory: it builds a **JSON profile** with **MIFARE Classic** sector sweeps (default keys, Key **A** then **B** per sector trailer, **1K and 4K layouts**) with **every readable block as hex**, or an **Ultralight/NTAG-style page sweep** (up to **240 pages** in firmware). Unknown or non-Classic paths still get solid **ATQA/SAK/UID** plus whatever the stack can return — nothing is silently dropped.
3. **RAM session buffer with hard stop + phone download** — Captures are stored in **on-chip RAM** (default **48 KB** of NDJSON lines). When the buffer is full, **RF polling pauses** so you never lose data to silent overflow. You tap **Download NDJSON** on your phone, get a single file with every profile, then **Clear** to resume. That workflow is purpose-built for field audits and clone/research sessions.
3. **RAM session buffer with a hard stop + phone download** — Captures live in **on-chip RAM** (**48 KB** buffer, NDJSON lines). When the buffer is full, **RF polling pauses** so you never lose data to silent overflow. You tap **Download NDJSON**, get one file with every profile, then **Clear** to resume. That workflow is built for field audits, bench sessions, and anything where “I need the dump on my phone, now” matters.
4. **Self-hosted on the device** — Default **open SoftAP** SSID `PN532-Toolkit` (no password, lab default), **mDNS** `pn532tool.local`. No cloud, no account, no telemetry.
4. **Self-hosted on the device** — Default **SoftAP**: SSID **`PN532-Toolkit`**, password **`nfc-toolkit`** (WPA2). **mDNS** hostname **`pn532tool.local`** (HTTP port **80**). No cloud, no account, no telemetry.
5. **Honest architecture** — ESP-IDF, explicit components (`pn532_host`, `nfc_engine`, `net_service`), embedded Vite/React UI flashed to SPIFFS. You can extend it like real firmware, not a black-box sketch.
5. **Honest architecture****ESP-IDF**, explicit components (`pn532_host`, `nfc_engine`, `net_service`), **Vite/React** UI embedded in **SPIFFS**. You extend it like real firmware, not a black-box sketch. PN532 talks **SPI, I2C, or UART (HSU)** — pins and bus are **menuconfig**, not guesses.
6. **Raw frame escape hatch** — When the high-level UI isnt enough, hit **Raw** and send PN532 command bytes (frame wrapper handled in firmware). Thats how you stay aligned with the real chip, not a toy abstraction.
6. **Raw PN532 path** — When the high-level UI isnt enough, **Raw** sends **command bytes**; the stack handles transport framing. **`GET /api/pn532/general-status`** exposes the controllers **general status bytes** for debugging. Thats how you stay aligned with the real chip, not a toy abstraction.
This stack is **not** a Proxmark replacement (no LF, no raw carrier manipulation). For **hosted NFC with PN532**, its built to be the **most complete pocket operator**: remote UI, deep reads, session export, and a path to grow.
7. **UI that matches the ambition** — Live **WebSocket** stream (scan + capture), **browser-side log** (thousands of events, exportable JSON), optional **`apiBase`** for talking to the box from another host, **HashRouter** so refreshes dont fight the server, and **lab fixtures** (synthetic card blobs, keys, SHA checks) so you can validate the UI without burning tags.
This stack is **not** a Proxmark replacement (no LF, no raw carrier manipulation, no FPGA tricks). For **hosted NFC with a PN532**, its the **full pocket operator**: remote UI, deep reads, session export, Classic dictionary work, Ultralight read/write, card emulation hooks, and a straight line to the command set when you need it.
---
## Every feature, in one pass
### Firmware (what the chip actually does)
| Capability | What you get |
|------------|----------------|
| **Transport** | PN532 over **SPI** (default pins in Kconfig), **I2C**, or **UART (HSU)** — bit rate and GPIOs set in `menuconfig`. |
| **Continuous scan** | Background task polls passive targets; **~65 ms** when not in deep mode, **~220 ms** when deep capture is on (more time per tag for heavy work). Toggle via **`POST /api/nfc/scan`** or the Dashboard. |
| **RF sensitivity** | On init, **high passive-activation retries** (`RFConfiguration` **0x05**) so marginal tags get more chances to answer. |
| **Deep profile** | Per new UID: Classic sector layout detection (1K / 4K), per-sector auth with built-in default keys, block hex arrays; Ultralight/NTAG page reads up to firmware limit; structured **JSON** for export. |
| **Session RAM** | **~48 KB** NDJSON capture buffer; mutex-protected; **full** flag stops polling until you clear. |
| **HTTP API** | JSON in/out on documented routes; **CORS** headers on API responses; **`OPTIONS /*`** preflight for cross-origin clients. POST bodies are read **completely** (chunked TCP-safe). |
| **WebSocket** | **`/ws`**: JSON envelopes `{"channel":"…","payload":…}`**`scan`** (inventory / `present:false` when tag leaves), **`capture`** (`recorded`, `bufferFull`, etc.), **`pong`** for keepalive. |
| **OTA endpoint** | **`POST /api/ota`** returns **501** with a stub message — there is **no** in-field OTA in this repo yet; use **`idf.py flash`** (or the included scripts). |
| **Onboard RGB (DevKit-style)** | Optional **boot-time** shutdown of a **WS2812/SK6812** on **GPIO 48** (Kconfig) so the addressable LED isnt left on a random color — **not** on all boards; power LEDs are hardware. |
| **Status** | **`/api/status`**: uptime, free heap, WiFi mode, **PN532 firmware version** (when reachable), scan flag, session stats. |
### Web UI (each page)
| Page | Purpose |
|------|---------|
| **Dash** | Live **status** poll, **continuous scan** on/off, **manual poll** (uses live tag from WebSocket when present), hero readout. |
| **Read-all (Capture)** | Toggle **deep capture**, **export** NDJSON from device RAM, **clear** buffer, progress vs **48 KB** budget. |
| **Read** | **MIFARE** block read with key + Key A/B; **Ultralight** page read; paste a **sector trailer** to decode **access bits** in the browser. |
| **Write** | **MIFARE** block write (16-byte hex, confirm dialog); **Ul** page write; **lab fixture** loader for offline testing flows; ties into **live UID** from WebSocket when available. |
| **Brute** | **Classic 1K / 4K** dictionary attack: firmwares built-in key set + your lines, optional **bounded variations**; shows JSON result. |
| **Emu** | **`TgInitAsTarget`** and friends via **`POST /api/nfc/emulate-raw`** — you supply hex; **experimental** (bad sequences can require power cycle). |
| **KeyLab** | **XOR span** across up to three 6-byte base keys (all combinations → candidates for Brute/Keys); **Shannon entropy** on arbitrary hex blobs. **Stage for Keys** copies candidates into **sessionStorage** for the Keys page. |
| **Lib** | **Saved hex snippets** in localStorage; **seed** from built-in **lab catalog** samples; fixture loader for repeatable demos. |
| **Keys** | **Browser-local** key dictionary (defaults + your lines); **merge lab keys**; **import Key Lab stash** from staged session. Used when you copy keys into Brute manually — **not** auto-uploaded to flash. |
| **Raw** | Hex **command** payload → **`/api/raw/pn532`**; **general status** dump from **`/api/pn532/general-status`**; local TX/RX log. |
| **Set** | **`apiBase`** (empty = same host), **theme** (light/dark), reminder of SoftAP + mDNS. |
### Browser extras (no extra server)
- **Top bar** — **Download log JSON**: last **5000** WebSocket messages from **sessionStorage** (scan + capture + anything else the firmware sends).
- **Scan feedback** — Visual/audio “hit” flourishes on new tag / capture events (debounced so it doesnt spam).
- **Validation fixtures** — Shared **lab** blobs and notes (`validationFixtures.ts`) for UI testing and teaching.
---
## Remote deep capture (how to use it)
1. **Power on** → firmware starts **continuous scan** automatically (you can still toggle it on the Dashboard).
2. **Read-all** (Capture page) → enable **passive read-all** (`POST /api/session/deep`) when you want automatic full dumps per new tag into device RAM.
1. **Power on** → firmware starts **continuous scan** by default (toggle on the Dashboard).
2. Open **Read-all (Capture)** → enable **passive read-all** (`POST /api/session/deep`).
3. Present tags; each **new UID** appends one **NDJSON** line: full deep profile JSON.
4. When the **progress bar hits the end**, scanning **pauses** automatically.
5. Tap **Download NDJSON** on your phone (or laptop) — browser saves `pn532-deep-capture-*.ndjson`.
6. Tap **Clear buffer** to free RAM and **resume** scanning.
5. Tap **Download NDJSON** — browser saves `pn532-deep-capture-*.ndjson`.
6. Tap **Clear buffer** to free RAM and **resume**.
API (for automation):
### Session API (automation)
| Method | Path | Purpose |
|--------|------|---------|
| `GET` | `/api/status` | Includes `session.usedBytes`, `maxBytes`, `lines`, `full`, `deepCapture` |
| `POST` | `/api/session/deep` | Body `{"enable":true}` — toggle deep capture |
| `GET` | `/api/session/export` | Attachment: all captured lines |
| `POST` | `/api/session/clear` | Wipe buffer, clear `full` |
| `GET` | `/api/status` | App name, uptime, heap, WiFi mode, PN532 version, `scanning`, `session` (`usedBytes`, `maxBytes`, `lines`, `full`, `deepCapture`) |
| `POST` | `/api/session/deep` | Body `{"enable": true}` or `false` |
| `GET` | `/api/session/export` | `text/plain` / NDJSON attachment |
| `POST` | `/api/session/clear` | Clears RAM buffer |
WebSocket `/ws`: channels `scan` (inventory) and `capture` (recorded / bufferFull events).
### Live NFC API
### Browser memory log (nothing missed in the UI)
| Method | Path | Purpose |
|--------|------|---------|
| `POST` | `/api/nfc/poll` | One-shot poll; body may be `{}` — returns `present`, optional `tag` |
| `POST` | `/api/nfc/scan` | Body `{"enable": true}` or `false` — continuous background scan |
| `GET` | `/api/pn532/general-status` | Raw PN532 **general status** byte array |
| `POST` | `/api/mifare/read-block` | `block`, `key` (12 hex), `keyB` |
| `POST` | `/api/mifare/write-block` | `block`, `key`, `keyB`, `data` (32 hex) |
| `POST` | `/api/ul/read-page` | `page` |
| `POST` | `/api/ul/write-page` | `page`, `data` (8 hex) |
| `POST` | `/api/raw/pn532` | `frame` — hex command bytes |
| `POST` | `/api/mifare/dictionary-attack` | `readerType` (`classic1k` / `classic4k`), `variations`, optional `keysHex[]`, optional `sectorFirst` / `sectorLast` |
| `POST` | `/api/nfc/emulate-raw` | `hex` — raw command bytes (e.g. **0x8C** sequences) |
| `POST` | `/api/ota` | **Not implemented** — returns **501** |
The SPA keeps the **last 5000** WebSocket events in **sessionStorage** (scan + capture + anything else the firmware pushes). Use the top bar **Download log JSON** to save a pretty file on your phone or PC without touching device RAM. Clear the log separately from the device capture buffer.
**WebSocket:** `GET /ws` — JSON text frames as above; send **`ping`**, receive **`pong`**.
### “Maximum sensitivity” (firmware)
### Browser memory log
On init the PN532 is configured for **high passive-activation retries** (`RFConfiguration` 0x05), and the poll loop runs at **~65ms** when not doing deep capture — weak coupling / marginal tags get more chances to answer.
The SPA keeps the **last 5000** WebSocket events in **sessionStorage**. **Download log JSON** saves a pretty file on your phone or PC **without** using device RAM. Clear that log separately from the device capture buffer.
### Dictionary “brute” (Classic)
**Brute** page → pick **Classic 1K / 4K map**, optional **variations**, paste extra keys. Firmware runs **`POST /api/mifare/dictionary-attack`**: built-in **public default keys** (subset of community lists such as the [Proxmark3 mfc_default_keys.dic](https://github.com/RfidResearchGroup/proxmark3/blob/master/client/dictionaries/mfc_default_keys.dic)) plus your lines, Key **A** then **B** per sector trailer. **Variations** add bounded XOR / nibble tweaks — **not** a full 2⁴⁸ keyspace search. You will **not** magically open every door; you will systematically try keys people actually leak online. ### Emulation
**Brute** page → **Classic 1K / 4K**, optional **variations**, paste extra keys. Firmware runs **`POST /api/mifare/dictionary-attack`**: built-in **public default keys** (same family as community lists like [Proxmark3 `mfc_default_keys.dic`](https://github.com/RfidResearchGroup/proxmark3/blob/master/client/dictionaries/mfc_default_keys.dic)) plus your lines, Key **A** then **B** per sector trailer. **Variations** add bounded XOR / nibble-style tweaks — **not** a full 2⁴⁸ search. You wont magically open every sector; you **systematically** try keys people actually leak in the wild.
**Emulate** sends raw **`TgInitAsTarget` (0x8C)** payloads via **`POST /api/nfc/emulate-raw`**. You are responsible for correct bytes (NXP UM0701). This is **experimental**; bad sequences can require a power cycle.
### Card emulation (PN532 target mode)
| Method | Path | Purpose |
|--------|------|---------|
| `POST` | `/api/mifare/dictionary-attack` | Body: `readerType`, `variations`, optional `keysHex[]` |
| `POST` | `/api/nfc/emulate-raw` | Body: `{ "hex": "8C..." }` |
| `POST` | `/api/ul/write-page` | Body: `{ "page": 4, "data": "AABBCCDD" }` (8 hex) |
**Emulate** sends raw **`TgInitAsTarget` (0x8C)** payloads via **`POST /api/nfc/emulate-raw`**. You own the bytes (see NXP **UM0701**). This is **experimental**; a bad sequence can leave the front end wedged until **power cycle**.
---
@@ -73,21 +124,11 @@ On init the PN532 is configured for **high passive-activation retries** (`RFConf
./start-firmware.sh
```
What it does:
What it does (see script for flags): bootstraps ESP-IDF under a **local prefix** if needed, builds the web UI into **`firmware/data`**, targets **esp32s3**, auto-detects serial when possible, **builds and flashes**.
- bootstraps ESP-IDF locally if needed
- builds the web UI into `firmware/data`
- configures target `esp32s3`
- auto-detects the serial port
- builds and flashes the device
Options include **`--build-only`**, **`--monitor`**, **`--port`**, etc.
Useful options:
- `./start-firmware.sh --build-only`
- `./start-firmware.sh --monitor`
- `./start-firmware.sh --port /dev/cu.usbmodemXXXX`
### Web UI → flash image
### Web UI → SPIFFS image
```bash
cd web
@@ -100,35 +141,13 @@ npm run build:fw
```bash
cd firmware
idf.py set-target esp32s3
idf.py menuconfig # PN532 Host: SPI / I2C / UART + pins
idf.py menuconfig # PN532 Host: SPI / I2C / UART + pins; Board indicators (RGB) if you use DevKitC-1
idf.py build flash monitor
```
See [docs/FLASHING.md](docs/FLASHING.md) and [docs/PINOUT.md](docs/PINOUT.md).
From `firmware/`, with IDF already in your environment, you can also **`./flash.sh`** (uses **`ESPPORT`** or the first argument as the serial device).
---
## 9 meaningful upgrades we dont have yet (roadmap)
1. **FeliCa / Type B surfaces** — More first-class UI for nonType A paths the PN532 can speak.
2. **Configurable RAM budget + optional PSRAM** — Compile-time or NVS `maxBytes`, and external SPIRAM for **multihundredKB** sessions on N8R8 modules.
3. **Chunked / resumable export** — HTTP range or multipart export so **multiMB** captures dont require one giant `httpd_resp_send`.
4. **User-supplied key dictionary on device** — Upload common keys file to flash and run **automatic sector retries** without typing keys in the UI.
5. **NDEF record editor** — Parse TLV/NDEF in the browser, edit records, write back through page/block APIs with lock-byte warnings.
6. **ISO14443-4 / Type B automation** — Higher-layer APDU helpers where PN532 allows; clearer UI for “Type A only” vs “RATS/PPS” paths.
7. **Wi-Fi STA onboarding** — Captive portal or dedicated SSID scan + save credentials to NVS (today defaults to AP).
8. **Real OTA from the UI** — Replace `501` stub with signed `esp_https_ota` + rollback partition sanity checks.
9. **Installable PWA + richer diagnostics**`manifest.json`, icons, `theme-color`, and UI for **error histograms / timing** from the PN532 status path.
10. **Magic UID / Gen2** — Not exposed; PN532 is a legitimate reader/writer, not a UID-spoofing modem.
See [docs/FLASHING.md](docs/FLASHING.md) and [docs/PINOUT.md](docs/PINOUT.md). Limitations and scope notes: [docs/LIMITATIONS.md](docs/LIMITATIONS.md).
---
@@ -136,6 +155,7 @@ See [docs/FLASHING.md](docs/FLASHING.md) and [docs/PINOUT.md](docs/PINOUT.md).
| Path | Role |
|------|------|
| `firmware/` | ESP-IDF: PN532 transport, NFC engine, **session RAM buffer**, **deep profile**, HTTP/WS |
| `web/` | React UI: Dashboard, **Capture**, Read/Write, Library, Keys, Raw, Settings |
| `firmware/` | ESP-IDF: PN532 transport, NFC engine, **session buffer**, **deep profile**, HTTP/WebSocket, SPIFFS |
| `web/` | React UI: Dashboard, Capture, Read, Write, Brute, Emulate, KeyLab, Library, Keys, Raw, Settings |
| `docs/` | Flashing, pinout, workflows, limitations |
| `start-firmware.sh` | One-shot IDF bootstrap + build + flash |

19
SECURITY.md Normal file
View File

@@ -0,0 +1,19 @@
# Security Policy
## Scope
This repository is maintained for authorized, lawful work only. Do not use code, firmware, payloads, scripts, or documentation from this project against systems, accounts, devices, networks, cards, readers, or services you do not own or do not have explicit permission to test.
## Reporting
Report security concerns privately to the maintainer. Do not open public issues containing live credentials, tokens, private captures, card data, target identifiers, exploit chains, or sensitive logs.
## Secrets And Data
- Do not commit `.env` files, API keys, Wi-Fi credentials, session cookies, private keys, dumps, captures, or personal data.
- Firmware binaries and captured artifacts must include provenance notes and SHA256 hashes before release.
- Generated dependency folders and build output belong outside Git unless there is a documented reason.
## Maintainer Rule
If a change increases misuse risk, narrows safety boundaries, or weakens provenance, it must be rejected or quarantined until documented.

23
docs/MAINTENANCE.md Normal file
View File

@@ -0,0 +1,23 @@
# Maintenance
<!-- stewardship-standard: maintenance-v1 -->
## Stewardship Rules
- Keep generated files, build outputs, copied SDKs, and raw firmware binaries out of Git unless they are the source of truth.
- Keep credentials, tokens, dumps, private messages, session stores, and local machine paths out of commits.
- Prefer small commits with clear intent and a matching issue or release note.
- Preserve upstream attribution when code is copied, forked, or adapted.
## Routine Checks
- README still describes what the project does.
- Setup instructions still work.
- Security policy is accurate for the current risk level.
- Changelog records user-visible changes.
- License status is explicit.
## Hardware Gate
- Confirm exact board, module, and peripheral versions.
- Verify flashing and recovery steps on physical hardware.
- Attach firmware binaries through releases only, with SHA256 checksums.

14
docs/PROJECT_HANDOFF.md Normal file
View File

@@ -0,0 +1,14 @@
# Project Handoff
<!-- stewardship-standard: project-handoff-v1 -->
## What This Repo Needs From A Maintainer
- A one-paragraph project summary in README.md.
- Confirmed setup instructions.
- Confirmed license status.
- Confirmed provenance for imported code and binaries.
- A known-good verification command, test, build, flash, or demo path.
## Current Stewardship State
This repo has baseline governance files, wiki pages, issue templates, labels, milestones, and a readiness issue. The next maintainer should replace generic stewardship notes with project-specific facts.

View File

@@ -0,0 +1,12 @@
# Provenance Checklist
<!-- stewardship-standard: provenance-checklist-v1 -->
Use this before claiming ownership or publishing artifacts.
- [ ] Identify original upstream source, if any.
- [ ] Record fork URL, commit, tag, or archive source.
- [ ] Preserve third-party notices and license files.
- [ ] Separate local patches from imported code where practical.
- [ ] Record binary build inputs, toolchain versions, and source commit.
- [ ] Publish checksums for release assets.
- [ ] Mark unknown-origin content as blocked until resolved.

20
docs/RELEASE_PROCESS.md Normal file
View File

@@ -0,0 +1,20 @@
# Release Process
<!-- stewardship-standard: release-process-v1 -->
## Before Tagging
- Confirm the default branch builds, runs, or flashes as documented.
- Confirm no secrets, private data, generated dependency trees, or raw binaries are accidentally committed.
- Confirm license and upstream provenance are documented.
- Update CHANGELOG.md.
- Attach binaries only as release assets with SHA256 checksums and source commit references.
## Release Notes
Include:
- Purpose of the release.
- Commit hash or tag.
- Build environment.
- Known limitations.
- Verification performed.

20
docs/ROADMAP.md Normal file
View File

@@ -0,0 +1,20 @@
# Roadmap
<!-- stewardship-standard: roadmap-v1 -->
## Now
- Confirm the project purpose in the README.
- Confirm build, run, or flash instructions on a clean machine.
- Classify license status and upstream provenance.
- Close the stewardship readiness checklist issue.
## Next
- Add project-specific tests or verification steps.
- Publish the first verified release only after provenance and security review.
- Replace placeholder wiki notes with project-specific architecture or hardware details.
## Later
- Add examples, screenshots, wiring diagrams, or demo media where useful.
- Decide whether duplicate or experimental branches should be archived.

14
docs/SECURITY_REVIEW.md Normal file
View File

@@ -0,0 +1,14 @@
# Security Review
<!-- stewardship-standard: security-review-v1 -->
## Required Checks
- [ ] No credentials, tokens, cookies, API keys, private keys, or session files.
- [ ] No private user data, dumps, card data, logs, or captures that should not be stored.
- [ ] No copied dependency trees where package managers or SDK installers should be used instead.
- [ ] No unexplained binaries in source history.
- [ ] Risky behavior is documented and scoped to authorized lab use.
## Release Gate
A release is blocked until the checklist is complete or a maintainer explicitly records why the item does not apply.