From 3c4a2de8ad65e5b409e6f714818dd5b8a3c433b1 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 21 Oct 2026 18:18:55 +0000 Subject: [PATCH] cyberpunkunicorn-os 0.1.6: a write on a card that isn't an NTAG says so Daniel's 0.1.5 log: the reader works now and saw his card at once, but the card was an ISO 14443-4 card (UID 01020304), not an NTAG. The write selected it again, lost it, and answered 'No card'. A website write now answers 'Not an NTAG213/215/216 tag' when the tapped card isn't one (the console already turns that into 'use an NTAG card or sticker'), and logs what was tapped. A card lost between the tap and the write is reported as a failed write, not as no card. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_015Aw32AU4vVqCSEoNA5aP3U --- cyberpunkunicorn-os/apps/frequency/card.cpp | 3 ++- cyberpunkunicorn-os/apps/remote/app_handlers.cpp | 8 ++++++-- cyberpunkunicorn-os/build.sh | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cyberpunkunicorn-os/apps/frequency/card.cpp b/cyberpunkunicorn-os/apps/frequency/card.cpp index dde72b9..a26882c 100644 --- a/cyberpunkunicorn-os/apps/frequency/card.cpp +++ b/cyberpunkunicorn-os/apps/frequency/card.cpp @@ -344,7 +344,8 @@ CardStatus waitCard( CardStatus writeCard(const String &uri, CardInfo &out) { if (!held || !rfid) return CARD_NO_READER; CardInfo before; - if (!selectCard(200) || readFull() != RFIDInterface::SUCCESS) return CARD_NONE; + // The card was just seen: losing it here is a slipped card, not an empty reader. + if (!selectCard(200) || readFull() != RFIDInterface::SUCCESS) return CARD_WRITE_FAILED; fill(before); if (!before.ntag) return CARD_NOT_NTAG; if (before.locked) return CARD_LOCKED; diff --git a/cyberpunkunicorn-os/apps/remote/app_handlers.cpp b/cyberpunkunicorn-os/apps/remote/app_handlers.cpp index df8d873..b3a5f6f 100644 --- a/cyberpunkunicorn-os/apps/remote/app_handlers.cpp +++ b/cyberpunkunicorn-os/apps/remote/app_handlers.cpp @@ -134,9 +134,13 @@ void cmdWriteTag(remote::Request &r) { if (!u.ok) return r.fail("bad_url", u.problem.length() ? u.problem : String("not a Frequency URL")); freq::CardInfo card; if (!tap(r, card)) return; - freq::CardStatus s = freq::writeCard(u.fixed, card); + // A phone or bank card answers the tap but can't hold a link: say so, not "No card". + freq::CardStatus s = card.ntag ? freq::writeCard(u.fixed, card) : freq::CARD_NOT_NTAG; freq::readerClose(); - if (s != freq::CARD_OK) return r.fail("write_failed", freq::cardStatusText(s)); + if (s != freq::CARD_OK) { + Serial.printf("[freq] write: %s (tapped %s, %s)\n", freq::cardStatusText(s), card.type.c_str(), card.uid.c_str()); + return r.fail("write_failed", freq::cardStatusText(s)); + } freq::logWrite(label, u, card.uid, false); putCard(r.data, card); r.data["written"] = u.host + u.path; // no query: the signature stays out of logs diff --git a/cyberpunkunicorn-os/build.sh b/cyberpunkunicorn-os/build.sh index c3fbf61..b5a565c 100755 --- a/cyberpunkunicorn-os/build.sh +++ b/cyberpunkunicorn-os/build.sh @@ -9,7 +9,7 @@ PIO_ENV=CYD-2432S028 PLATFORMIO_VERSION=6.2.0 ESPTOOL_VERSION=5.4.0 OS_NAME="CyberUnicorn 5000" -OS_VERSION=0.1.5 +OS_VERSION=0.1.6 source ./boot.conf for var in BOOT_TITLE BOOT_TAGLINE; do