mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2026-10-08 20:27:16 +00:00
* iButton: choose which blank types a write may try, and show the current one A Dallas key carries no hint of which blank is in front of the reader, so a write attempt walks the blank types in turn and keeps the one whose read-back matches. Until now that chain was hidden inside dallas_ds1990_write_id(): the app could not say which type it was attempting, and the user could not stop it attempting one. Mirrors the LFRFID write-target design. iButtonWriteTarget names the four writers (RW1990.1, RW1990.2, TM2004, TM01x) and a protocol declares which of them apply to it, so DS1420 no longer has to repeat DS1990's chain by hand. The group walks that mask, announcing each target before it is tried - from outside the critical section, because the announcement reaches the UI thread. Settings > Write Blanks toggles them, stored via saved_struct and honoured by the app and the CLI. Honouring it is opt-in: a worker starts at ibutton_write_targets_default(), which is all four, matching the behaviour before this existed. ibutton_protocols_write_id() keeps its signature and delegates with no context, so the API change is additive (88.12) and existing FAPs still link. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * iButton: address review of the write-target work Every Dallas protocol now goes through write_targets. ds_generic, ds1971, ds1992 and ds1996 each had a write_id that called tm2004_write() directly, so they took a fallback branch that consulted neither mask and wrote a TM2004 with TM2004 switched off - the setting covered two protocols out of six. With all six converted the fallback branch, the write_id slot in the Dallas descriptor and the "zero means it writes itself" sentinel all go away, and the ROM comes from get_editable_data() rather than a cast onto the front of the protocol's data. A mask that resolves to nothing no longer looks like an empty reader: the worker reports iButtonWorkerWriteNoEnabledTarget, and the write screen distinguishes "no blanks enabled" from "no enabled blank can write this key" - reachable without disabling everything, since DS1420 cannot use TM01x. The CLI says so too instead of spinning. Settings are saved on Back while the plugin is still mapped, and a failure raises a storage error dialog instead of only a log line, which is what the plugin ABI comment always claimed happened. Also: iButtonWriteTargetContext moves beside the types it is built from, so ibutton_protocols.h stops pulling protocol_group_base.h and protocol_common_i.h into the SDK tree; write_chip_name is cleared per write session; the settings loader masks on read and no longer logs "unreadable (OK)" for a corrupt file; static asserts pin the enum bit positions the saved mask depends on; and the success screen names the blank that accepted the key. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * iButton: simplify the write-target code The blank name on the write screen was always one target behind. Worker, app and GUI threads all run at Normal priority, so posting the progress event does not yield, and the next line masks the scheduler for most of a second - the label queued before a target was painted only once that target had finished. A 1 ms delay after the announcement is what actually lets the screen repaint. Nothing-enabled is terminal, not something a retry can fix while the screen is up, so it now reports once and drops the worker to idle instead of rebuilding the screen and re-blinking every second forever. The write context is normalised once at the API boundary, so the group stops testing it for NULL twice; write_chip_name's 16-byte buffer and its snprintf become the target itself, with the name derived on read; and the four places a write reports collapse into one helper. ibutton_protocols_get_write_targets, _write_id_targets, ibutton_write_target_write and ibutton_write_targets_default have no caller outside lib/ibutton, so they drop to '-' and stop costing FAP export thunks - the same treatment lfrfid_write_target_type already gets. Also: write_id's doc block had been orphaned by an insertion above it; the four bit-position asserts collapse into one; .write_targets sits with the data fields in all six descriptors rather than where write_id used to be; read() and write_copy() stop the bus outside their critical sections, matching write_id; and a dead scene-state enum, an overstated settings comment and three verbose blocks go. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * iButton: let the write screen keep up with the blank being tried The label showed only TM01x - the last blank of the pass. Announcing a target and then masking the scheduler microseconds later just queues the events up, so the app got to paint once, at the end, with the final name. 1 ms was nowhere near a widget rebuild plus a GUI frame; 50 ms lets each one land, costing 200 ms on a pass where all four are tried and fail. With nothing enabled the scene also flashed up a writing screen that the first tick immediately replaced with an error. It already knows the mask before the worker starts, so it now says so directly. The narrower case - something enabled, but nothing that fits this key - still needs the worker to answer, since the app cannot ask which blanks a protocol supports. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * iButton: changelog for the write-target selection Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * iButton: address review of the write-target selection Honour the documented NULL write_ctx instead of dereferencing it, and let ibutton_protocols_write_id() be the NULL case it describes. The blank-type setting governs Write ID only, so an empty list no longer blocks Full Writing, which rewrites the same chip and never consults it. Do not crash on a write result this build has not heard of: the app is a separate .fap, so a newer firmware must not take an older one down with it. The switch keeps no default, so -Wswitch still catches in-tree additions. Drop an unreadable settings file rather than fail every later read, which left the settings page presenting defaults as a saved choice and skipping the save that would have replaced it. Make the setter read-modify-write so a setting added beside this one is not zeroed. Clear the blank-type label when a pass gives up, reset the app-wide Popup before the plugin error uses it, name the remedy instead of printing a PluginManagerError ordinal, return before touching the bus when no target is enabled, and check the ROM size the blank writers assume. Export ibutton_write_targets_default(), which an exported header already told apps a worker starts from. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * iButton: simplify the write-target selection Derive the WriteId feature from write_targets instead of storing the same fact twice in all six Dallas tables, which also deletes the runtime checks that existed to catch the two disagreeing. Charge the announce delay to the callback that repaints, not to the 1-Wire path: the CLI registers a write callback but drops the progress result, so it paid 50 ms per target for a name it never prints. Drop the read-modify-write in the settings setter - it read a value it overwrote on the next line, costing a stat and a full load on every save. A static assert on the struct size forces the question when a second setting is actually added. Stop deleting an unreadable settings file from inside the getter: it is a filesystem write on a read path, and "unreadable" includes a version a newer firmware wrote. The page now saves on the way out even when nothing changed, which replaces a bad file without destroying a good one. Remove the "none enabled at all" branch and the scene state behind it. The early return in on_enter means that event can only arrive with targets enabled, so the distinction was unreachable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>