From d246347483a74d7964890fba640fdf3a47fc1d20 Mon Sep 17 00:00:00 2001 From: Ellis Sarza-Nguyen Date: Sat, 29 Aug 2026 15:24:58 -0700 Subject: [PATCH] [protocol] Convert console to use the new compact error format Signed-off-by: Ellis Sarza-Nguyen --- examples/htool.c | 10 ++++- examples/htool_console.c | 72 ++++++++++++++++-------------- examples/htool_console.h | 8 ++-- protocol/BUILD | 2 + protocol/console.c | 94 ++++++++++++++++++++++------------------ protocol/console.h | 30 +++++++------ 6 files changed, 122 insertions(+), 94 deletions(-) diff --git a/examples/htool.c b/examples/htool.c index ade53de..84fa267 100644 --- a/examples/htool.c +++ b/examples/htool.c @@ -571,11 +571,17 @@ static int command_console(const struct htool_invocation* inv) { return -1; } + libhoth_error err = HOTH_SUCCESS; if (opts.snapshot) { - return htool_console_snapshot(dev, &opts); + err = htool_console_snapshot(dev, &opts); } else { - return htool_console_run(dev, &opts); + err = htool_console_run(dev, &opts); } + if (err != HOTH_SUCCESS) { + htool_report_error("console", err); + return -1; + } + return 0; } static int command_flash_spi_info(const struct htool_invocation* inv) { diff --git a/examples/htool_console.c b/examples/htool_console.c index 3287395..25d1fe9 100644 --- a/examples/htool_console.c +++ b/examples/htool_console.c @@ -61,27 +61,27 @@ void restore_terminal(int fd, const struct termios* old_termios) { tcsetattr(fd, TCSANOW, old_termios); } -int htool_console_run(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts) { +libhoth_error htool_console_run(struct libhoth_device* dev, + const struct libhoth_htool_console_opts* opts) { printf("%sStarting Interactive Console\n", kAnsiRed); struct hoth_channel_uart_config uart_config = {}; - int status = libhoth_get_uart_config(dev, opts, &uart_config); - if (status == LIBHOTH_OK) { + libhoth_error status = libhoth_get_uart_config(dev, opts, &uart_config); + if (status == HOTH_SUCCESS) { if (opts->baud_rate != 0) { uart_config.baud_rate = opts->baud_rate; status = libhoth_set_uart_config(dev, opts, &uart_config); - if (status != LIBHOTH_OK) { - fprintf( - stderr, - "libhoth_set_uart_config() failed: %d; unable to set baud-rate\n", - status); + if (status != HOTH_SUCCESS) { + fprintf(stderr, + "libhoth_set_uart_config() failed: 0x%016llx; unable to set " + "baud-rate\n", + (unsigned long long)status); return status; } status = libhoth_get_uart_config(dev, opts, &uart_config); } } - if (status == LIBHOTH_OK) { + if (status == HOTH_SUCCESS) { printf("Using baud-rate %d\n", uart_config.baud_rate); } printf("[ Use Ctrl+T-Q to quit ]%s\n", kAnsiReset); @@ -90,8 +90,9 @@ int htool_console_run(struct libhoth_device* dev, // will be stored at this offset) uint32_t offset; status = libhoth_get_channel_status(dev, opts, &offset); - if (status != LIBHOTH_OK) { - fprintf(stderr, "libhoth_get_channel_status() failed: %d\n", status); + if (status != HOTH_SUCCESS) { + fprintf(stderr, "libhoth_get_channel_status() failed: 0x%016llx\n", + (unsigned long long)status); return status; } @@ -106,7 +107,7 @@ int htool_console_run(struct libhoth_device* dev, while (!quit) { // Any previous failure should reset all of the USB state before retrying - while (status != LIBHOTH_OK) { + while (status != HOTH_SUCCESS) { // 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. @@ -114,7 +115,7 @@ int htool_console_run(struct libhoth_device* dev, // Make sure we don't end up in a tight retry loop usleep(100 * 1000); } else { - status = LIBHOTH_OK; + status = HOTH_SUCCESS; } } // Give an opportunity for other clients to use the interface. @@ -123,20 +124,21 @@ int htool_console_run(struct libhoth_device* dev, if (libhoth_claim_device(dev, 1000 * 1000 * opts->claim_timeout_secs) != HOTH_SUCCESS) { // If USB is down we might fail claim, just go back and retry - status = LIBHOTH_ERR_FAIL; + status = LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH, + LIBHOTH_ERR_FAIL); continue; } status = libhoth_read_console(dev, STDOUT_FILENO, false, opts->channel_id, &offset); - if (status != LIBHOTH_OK) { + if (status != HOTH_SUCCESS) { // 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) { + if (status != HOTH_SUCCESS) { // Device resets cause failures, just loop and allow reconnection continue; } @@ -147,12 +149,14 @@ int htool_console_run(struct libhoth_device* dev, return status; } -int htool_console_snapshot_legacy(struct libhoth_device* dev) { +libhoth_error htool_console_snapshot_legacy(struct libhoth_device* dev) { size_t response_bytes_written; - int status = libhoth_hostcmd_exec(dev, HOTH_CMD_CONSOLE_REQUEST, 0, NULL, 0, - NULL, 0, &response_bytes_written); - if (status != LIBHOTH_OK) { - fprintf(stderr, "HOTH_CMD_CONSOLE_REQUEST status: %d\n", status); + libhoth_error status = + libhoth_hostcmd_exec_v2(dev, HOTH_CMD_CONSOLE_REQUEST, 0, NULL, 0, NULL, + 0, &response_bytes_written); + if (status != HOTH_SUCCESS) { + fprintf(stderr, "HOTH_CMD_CONSOLE_REQUEST status: 0x%016llx\n", + (unsigned long long)status); return status; } @@ -162,11 +166,12 @@ int htool_console_snapshot_legacy(struct libhoth_device* dev) { MAILBOX_SIZE - sizeof(struct hoth_host_response); while (true) { char buf[MAILBOX_SIZE]; - status = libhoth_hostcmd_exec(dev, HOTH_CMD_CONSOLE_READ, 0, &read_request, - sizeof(read_request), buf, max_bytes_per_read, - &response_bytes_written); - if (status != LIBHOTH_OK) { - fprintf(stderr, "HOTH_CMD_CONSOLE_READ status: %d\n", status); + status = libhoth_hostcmd_exec_v2( + dev, HOTH_CMD_CONSOLE_READ, 0, &read_request, sizeof(read_request), buf, + max_bytes_per_read, &response_bytes_written); + if (status != HOTH_SUCCESS) { + fprintf(stderr, "HOTH_CMD_CONSOLE_READ status: 0x%016llx\n", + (unsigned long long)status); return status; } fwrite(buf, strnlen(buf, sizeof(buf)), 1, stdout); @@ -176,8 +181,8 @@ int htool_console_snapshot_legacy(struct libhoth_device* dev) { return status; } -int htool_console_snapshot(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts) { +libhoth_error htool_console_snapshot( + struct libhoth_device* dev, const struct libhoth_htool_console_opts* opts) { // Legacy host commands for console snapshot. if (!opts->channel_id) { return htool_console_snapshot_legacy(dev); @@ -186,9 +191,10 @@ int htool_console_snapshot(struct libhoth_device* dev, // Starting from current_offset - 0x80000000 so it's guaranteed to be outside // of the Hoth buffer. Repeat read until reaching current offset. uint32_t current_offset; - int status = libhoth_get_channel_status(dev, opts, ¤t_offset); - if (status != LIBHOTH_OK) { - fprintf(stderr, "libhoth_get_channel_status) failed: %d\n", status); + libhoth_error status = libhoth_get_channel_status(dev, opts, ¤t_offset); + if (status != HOTH_SUCCESS) { + fprintf(stderr, "libhoth_get_channel_status failed: 0x%016llx\n", + (unsigned long long)status); return status; } uint32_t offset = current_offset - 0x80000000; @@ -196,7 +202,7 @@ int htool_console_snapshot(struct libhoth_device* dev, while (true) { status = libhoth_read_console(dev, STDOUT_FILENO, false, opts->channel_id, &offset); - if (status != LIBHOTH_OK) { + if (status != HOTH_SUCCESS) { break; } // Extra check in case UINT32_MAX wrap-around. diff --git a/examples/htool_console.h b/examples/htool_console.h index 47a1948..fa9ac78 100644 --- a/examples/htool_console.h +++ b/examples/htool_console.h @@ -27,11 +27,11 @@ extern "C" { struct libhoth_device; -int htool_console_run(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts); +libhoth_error htool_console_run(struct libhoth_device* dev, + const struct libhoth_htool_console_opts* opts); -int htool_console_snapshot(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts); +libhoth_error htool_console_snapshot( + struct libhoth_device* dev, const struct libhoth_htool_console_opts* opts); #ifdef __cplusplus } diff --git a/protocol/BUILD b/protocol/BUILD index eeaafd3..8387a71 100644 --- a/protocol/BUILD +++ b/protocol/BUILD @@ -544,11 +544,13 @@ cc_library( hdrs = ["console.h"], deps = [ ":host_cmd", + ":libhoth_status", ":util", "//transports:libhoth_device", ], ) + cc_library( name = "dfu_hostcmd", srcs = ["dfu_hostcmd.c"], diff --git a/protocol/console.c b/protocol/console.c index 9c6420f..15634d3 100644 --- a/protocol/console.c +++ b/protocol/console.c @@ -14,10 +14,12 @@ #include "protocol/console.h" +#include #include #include #include "host_cmd.h" +#include "protocol/status.h" #include "protocol/util.h" void libhoth_print_erot_console(struct libhoth_device* const dev) { @@ -27,9 +29,11 @@ void libhoth_print_erot_console(struct libhoth_device* const dev) { struct libhoth_htool_console_opts opts = {0}; opts.channel_id = EROT_CHANNEL_ID; - int status = libhoth_get_channel_status(dev, &opts, ¤t_offset); - if (status != LIBHOTH_OK) { - fprintf(stderr, "libhoth_get_channel_status() failed: %d\n", status); + libhoth_error status = + libhoth_get_channel_status(dev, &opts, ¤t_offset); + if (status != HOTH_SUCCESS) { + fprintf(stderr, "libhoth_get_channel_status() failed: 0x%016llx\n", + (unsigned long long)status); return; } @@ -40,7 +44,7 @@ void libhoth_print_erot_console(struct libhoth_device* const dev) { while (true) { status = libhoth_read_console(dev, STDOUT_FILENO, true, opts.channel_id, &offset); - if (status != LIBHOTH_OK) { + if (status != HOTH_SUCCESS) { break; } // Extra check in case UINT32_MAX wrap-around. @@ -50,37 +54,40 @@ void libhoth_print_erot_console(struct libhoth_device* const dev) { } } -int libhoth_get_channel_status(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts, - uint32_t* offset) { +libhoth_error libhoth_get_channel_status( + struct libhoth_device* dev, const struct libhoth_htool_console_opts* opts, + uint32_t* offset) { struct hoth_channel_status_request req = { .channel_id = opts->channel_id, }; struct hoth_channel_status_response resp; - int status = libhoth_hostcmd_exec( + libhoth_error status = libhoth_hostcmd_exec_v2( dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CHANNEL_STATUS, /*version=*/0, &req, sizeof(req), &resp, sizeof(resp), NULL); - if (status) { - if (status == HTOOL_ERROR_HOST_COMMAND_START + HOTH_RES_INVALID_COMMAND) { - fprintf(stderr, - "This is likely because the running RoT firmware doesn't have " - "support for channels enabled\n"); - } - if (status == HTOOL_ERROR_HOST_COMMAND_START + HOTH_RES_INVALID_PARAM) { - fprintf(stderr, - "This is likely because the requested channel doesn't exist.\n"); + if (status != HOTH_SUCCESS) { + if (LIBHOTH_ERR_GET_SPACE(status) == HOTH_HOST_SPACE_EC) { + uint32_t code = LIBHOTH_ERR_GET_CODE(status); + if (code == HOTH_RES_INVALID_COMMAND) { + fprintf(stderr, + "This is likely because the running RoT firmware doesn't have " + "support for channels enabled\n"); + } else if (code == HOTH_RES_INVALID_PARAM) { + fprintf( + stderr, + "This is likely because the requested channel doesn't exist.\n"); + } } return status; } *offset = resp.write_offset; - return 0; + return HOTH_SUCCESS; } -int libhoth_read_console(struct libhoth_device* dev, int fd, - bool prototext_format_enabled, uint32_t channel_id, - uint32_t* offset) { +libhoth_error libhoth_read_console(struct libhoth_device* dev, int fd, + bool prototext_format_enabled, + uint32_t channel_id, uint32_t* offset) { struct hoth_channel_read_request req = { .channel_id = channel_id, .offset = *offset, @@ -100,10 +107,10 @@ int libhoth_read_console(struct libhoth_device* dev, int fd, "unexpected layout"); size_t response_size = 0; - int status = libhoth_hostcmd_exec( + libhoth_error status = libhoth_hostcmd_exec_v2( dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CHANNEL_READ, /*version=*/0, &req, sizeof(req), &resp, sizeof(resp), &response_size); - if (status != 0) { + if (status != HOTH_SUCCESS) { return status; } if (req.offset != resp.resp.offset) { @@ -131,13 +138,14 @@ int libhoth_read_console(struct libhoth_device* dev, int fd, else { if (libhoth_force_write(fd, resp.buffer, len) != 0) { perror("Unable to write console output"); - return -1; + return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_POSIX, + errno); } } } *offset = resp.resp.offset + len; - return 0; + return HOTH_SUCCESS; } static int unescape(char* buf, int in, struct unescape_flags* flags) { @@ -176,8 +184,9 @@ static int unescape(char* buf, int in, struct unescape_flags* flags) { return out; } -int libhoth_write_console(struct libhoth_device* dev, uint32_t channel_id, - bool force_drive_tx, bool* quit) { +libhoth_error libhoth_write_console(struct libhoth_device* dev, + uint32_t channel_id, bool force_drive_tx, + bool* quit) { struct { struct hoth_channel_write_request_v1 req; char buffer[64]; @@ -188,12 +197,13 @@ int libhoth_write_console(struct libhoth_device* dev, uint32_t channel_id, // clear non-blocking, as it can affect STDOUT. fcntl(STDIN_FILENO, F_SETFL, fcntl(0, F_GETFL) & ~O_NONBLOCK); if (numRead <= 0) { - return 0; + return HOTH_SUCCESS; } struct unescape_flags flags = {}; int numWrite = unescape(req.buffer, numRead, &flags); - if ((*quit = flags.quit) || (numWrite == 0 && !flags.uart_break)) return 0; + if ((*quit = flags.quit) || (numWrite == 0 && !flags.uart_break)) + return HOTH_SUCCESS; req.req.channel_id = channel_id; req.req.flags = @@ -201,12 +211,13 @@ int libhoth_write_console(struct libhoth_device* dev, uint32_t channel_id, req.req.flags |= flags.uart_break ? HOTH_CHANNEL_WRITE_REQUEST_FLAG_SEND_BREAK : 0; - int status = libhoth_hostcmd_exec( + libhoth_error status = libhoth_hostcmd_exec_v2( dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CHANNEL_WRITE, /*version=*/1, &req, sizeof(req.req) + numWrite, NULL, 0, NULL); - if (status != 0) { - if (status == HTOOL_ERROR_HOST_COMMAND_START + HOTH_RES_UNAVAILABLE) { + if (status != HOTH_SUCCESS) { + if (LIBHOTH_ERR_GET_SPACE(status) == HOTH_HOST_SPACE_EC && + LIBHOTH_ERR_GET_CODE(status) == HOTH_RES_UNAVAILABLE) { fprintf(stderr, "This is likely because the RoT was unable to confirm that no " "other device is driving the UART TX net. If you are certain " @@ -215,28 +226,29 @@ int libhoth_write_console(struct libhoth_device* dev, uint32_t channel_id, return status; } - return 0; + return HOTH_SUCCESS; } -int libhoth_get_uart_config(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts, - struct hoth_channel_uart_config* resp) { +libhoth_error libhoth_get_uart_config( + struct libhoth_device* dev, const struct libhoth_htool_console_opts* opts, + struct hoth_channel_uart_config* resp) { struct hoth_channel_uart_config_get_req req = { .channel_id = opts->channel_id, }; - return libhoth_hostcmd_exec( + return libhoth_hostcmd_exec_v2( dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CHANNEL_UART_CONFIG_GET, /*version=*/0, &req, sizeof(req), resp, sizeof(*resp), NULL); } -int libhoth_set_uart_config(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts, - struct hoth_channel_uart_config* config) { + +libhoth_error libhoth_set_uart_config( + struct libhoth_device* dev, const struct libhoth_htool_console_opts* opts, + struct hoth_channel_uart_config* config) { struct hoth_channel_uart_config_set_req req = { .channel_id = opts->channel_id, .config = *config, }; - return libhoth_hostcmd_exec( + return libhoth_hostcmd_exec_v2( dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CHANNEL_UART_CONFIG_SET, /*version=*/0, &req, sizeof(req), NULL, 0, NULL); diff --git a/protocol/console.h b/protocol/console.h index 0192211..7f419c2 100644 --- a/protocol/console.h +++ b/protocol/console.h @@ -23,6 +23,7 @@ extern "C" { #include #include +#include "protocol/status.h" #include "transports/libhoth_device.h" #define EROT_CHANNEL_ID 0x45524F54 // 'EROT' @@ -129,24 +130,25 @@ struct libhoth_htool_console_opts { void libhoth_print_erot_console(struct libhoth_device* const dev); -int libhoth_get_channel_status(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts, - uint32_t* offset); +libhoth_error libhoth_get_channel_status( + struct libhoth_device* dev, const struct libhoth_htool_console_opts* opts, + uint32_t* offset); -int libhoth_read_console(struct libhoth_device* dev, int fd, - bool prototext_format_enabled, uint32_t channel_id, - uint32_t* offset); +libhoth_error libhoth_read_console(struct libhoth_device* dev, int fd, + bool prototext_format_enabled, + uint32_t channel_id, uint32_t* offset); -int libhoth_write_console(struct libhoth_device* dev, uint32_t channel_id, - bool force_drive_tx, bool* quit); +libhoth_error libhoth_write_console(struct libhoth_device* dev, + uint32_t channel_id, bool force_drive_tx, + bool* quit); -int libhoth_get_uart_config(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts, - struct hoth_channel_uart_config* resp); +libhoth_error libhoth_get_uart_config( + struct libhoth_device* dev, const struct libhoth_htool_console_opts* opts, + struct hoth_channel_uart_config* resp); -int libhoth_set_uart_config(struct libhoth_device* dev, - const struct libhoth_htool_console_opts* opts, - struct hoth_channel_uart_config* config); +libhoth_error libhoth_set_uart_config( + struct libhoth_device* dev, const struct libhoth_htool_console_opts* opts, + struct hoth_channel_uart_config* config); #ifdef __cplusplus }