From d760d4a8bb2797ae1e5fc891a4934a6e1133f47a Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 2 Mar 2026 15:19:21 -0800 Subject: [PATCH 1/2] htool_console: Reconnect USB on failure We usually don't want to kill the console logger with an error when a USB failure occurs. Instead, we want to try reconnecting in a loop until the device comes back. This allows us to retain the console pointer around platform resets that cause USB disconnections and prevents our services streaming these logs from sending duplicate messages. --- examples/htool_console.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/examples/htool_console.c b/examples/htool_console.c index be687f5..cc2ac60 100644 --- a/examples/htool_console.c +++ b/examples/htool_console.c @@ -105,26 +105,35 @@ int htool_console_run(struct libhoth_device* dev, bool quit = false; while (!quit) { + // Any previous failure should reset all of the USB state before retrying + while (status != LIBHOTH_OK) { + // TODO: Read STDIN during this time and buffer it so we can capture + // quit events even when the console is disconnected. We will also want + // to tune the reconnect time to match. + status = libhoth_device_reconnect(dev); + // If USB is down we might fail reconnect, just retry + } + // Give an opportunity for other clients to use the interface. + libhoth_release_device(dev); + usleep(1000 * opts->yield_ms); + status = libhoth_claim_device(dev, 1000 * 1000 * opts->claim_timeout_secs); + if (status != LIBHOTH_OK) { + // If USB is down we might fail claim, just go back and retry + continue; + } + status = libhoth_read_console(dev, STDOUT_FILENO, false, opts->channel_id, &offset); if (status != LIBHOTH_OK) { - break; + // Device resets cause failures, just loop and allow reconnection + continue; } status = libhoth_write_console(dev, opts->channel_id, opts->force_drive_tx, &quit); if (status != LIBHOTH_OK) { - break; - } - - libhoth_release_device(dev); - - // Give an opportunity for other clients to use the interface. - usleep(1000 * opts->yield_ms); - - status = libhoth_claim_device(dev, 1000 * 1000 * opts->claim_timeout_secs); - if (status != LIBHOTH_OK) { - break; + // Device resets cause failures, just loop and allow reconnection + continue; } } From b5707a198a4d92b714c9a14f7de4a3bae80736bc Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 2 Mar 2026 15:46:03 -0800 Subject: [PATCH 2/2] protocol/console: Log buffer jumps It's possible that if the console is disconnected long enough we can experience jumps in the console data because the buffer on the RoT side was not big enough for our time lapse. Log any time this happens so we can understand how much context we lost if any. --- protocol/console.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/protocol/console.c b/protocol/console.c index 141d9ce..16a7f04 100644 --- a/protocol/console.c +++ b/protocol/console.c @@ -106,6 +106,10 @@ int libhoth_read_console(struct libhoth_device* dev, int fd, if (status != 0) { return status; } + if (req.offset != resp.resp.offset) { + fprintf(stderr, "Console jumped forward %u bytes\n", + resp.resp.offset - req.offset); + } int len = response_size - sizeof(resp.resp); if (len > 0) {