From 413f9ec070243670ac0d0cf95cebca9a04613008 Mon Sep 17 00:00:00 2001 From: Claude Tuxedo Date: Sun, 6 Sep 2026 22:29:00 +0200 Subject: [PATCH] Wait for the erase to finish before reporting success MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The device does not answer once. It streams progress reports, 02 4A 41 , stepping to 100 — byte [3] is a percentage, not a status constant. The README's 'status code of 100' is the device saying 100 % complete. Reading a single reply therefore prints 'Done. Recordings deleted. (status: 0)' while the erase has not started. Observed on hardware: the message appeared 2.3 s before the device had finished. krode now reads until 100 %, showing progress on a terminal and staying quiet when redirected so logs do not fill with percents. Losing the device after progress has been reported is treated as a normal ending rather than a failure: the transmitter drops off the bus as soon as it is done. Losing it before any reply is still an error. Co-Authored-By: Claude Opus 5 (1M context) --- krode.c | 76 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/krode.c b/krode.c index 7ab7f46..f2b8c43 100644 --- a/krode.c +++ b/krode.c @@ -14,6 +14,7 @@ #include #include +#include #include #define RODE_VID 0x19F7 @@ -25,11 +26,17 @@ #define REPORT_SIZE 17 #define CMD_DELETE 0x4A #define DELETE_ALL 0x01 +#define ACK_OK 0x41 +#define DONE_PERCENT 100 + +/* First reply, then however long the device needs to work through storage. */ +#define REPLY_MS 3000 +#define PROGRESS_MS 120000 static int delete_recordings(hid_device *dev, unsigned short pid) { unsigned char buf[REPORT_SIZE]; - int ret; + int ret, percent = -1; memset(buf, 0, sizeof(buf)); buf[0] = 0x01; /* Report ID */ @@ -44,21 +51,58 @@ static int delete_recordings(hid_device *dev, unsigned short pid) return -1; } - /* Read response - device ACKs with 0x4A 0x41 0x64 */ - memset(buf, 0, sizeof(buf)); - ret = hid_read_timeout(dev, buf, sizeof(buf), 3000); - if (ret < 0) { - fprintf(stderr, "hid_read failed: %ls\n", hid_error(dev)); - return -1; - } - if (ret == 0) { - fprintf(stderr, "Timeout waiting for device response.\n"); - return -1; - } - - if (buf[1] == CMD_DELETE && buf[2] == 0x41) { - printf("Done. Recordings deleted (status: %d).\n", buf[3]); - return 0; + /* + * The device does not answer once. It streams progress reports, + * 02 4A 41 , stepping to 100 - byte [3] is a percentage, + * not a status constant. Reading a single reply announces success + * while the erase is still running. + */ + for (;;) { + memset(buf, 0, sizeof(buf)); + ret = hid_read_timeout(dev, buf, sizeof(buf), + percent < 0 ? REPLY_MS : PROGRESS_MS); + if (ret <= 0) { + /* + * The transmitter drops off the bus as soon as it is + * done, so losing it after progress has been reported + * is the normal ending, not a failure. Losing it + * before any reply is not. + */ + if (percent < 0) { + if (ret < 0) + fprintf(stderr, "hid_read failed: %ls\n", + hid_error(dev)); + else + fprintf(stderr, "Timeout waiting for " + "device response.\n"); + return -1; + } + if (isatty(STDOUT_FILENO)) + printf("\r"); + printf("Device disconnected at %d%% - it re-enumerates " + "when the erase finishes.\n", percent); + return 0; + } + + if (buf[1] != CMD_DELETE || buf[2] != ACK_OK) + break; /* unexpected: dump it below */ + + if (buf[3] != percent) { + percent = buf[3]; + /* Overwrite in place on a terminal, stay quiet when + * redirected so logs do not fill with percents. */ + if (isatty(STDOUT_FILENO)) { + printf("\r %3d%%", percent); + fflush(stdout); + } + } + + if (percent >= DONE_PERCENT) { + if (isatty(STDOUT_FILENO)) + printf("\r"); + printf("Done. Recordings deleted.\n"); + return 0; + } } /* Print raw response for debugging */