diff --git a/BUILD b/BUILD index d0048cb..1ce7d8d 100644 --- a/BUILD +++ b/BUILD @@ -7,6 +7,14 @@ cc_library( hdrs = [":gen_version_header"], ) +cc_library( + name = "libhoth_status", + hdrs = ["include/libhoth/status.h"], + strip_include_prefix = "include", + visibility = ["//visibility:public"], +) + + genrule( name = "gen_version_header", outs = ["git_version.h"], diff --git a/examples/htool.c b/examples/htool.c index 59a9881..9c10e74 100644 --- a/examples/htool.c +++ b/examples/htool.c @@ -769,9 +769,11 @@ static int command_hello(const struct htool_invocation* inv) { } uint32_t output = 0; - const int rv = libhoth_hello(dev, input, &output); - if (rv) { - return rv; + const libhoth_error rv = libhoth_hello(dev, input, &output); + if (rv != HOTH_SUCCESS) { + fprintf(stderr, "libhoth_hello failed with error: 0x%016lx\n", + (unsigned long)rv); + return -1; } printf("output: 0x%08x\n", output); diff --git a/include/libhoth/status.h b/include/libhoth/status.h new file mode 100644 index 0000000..941e917 --- /dev/null +++ b/include/libhoth/status.h @@ -0,0 +1,85 @@ + +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBHOTH_INCLUDE_LIBHOTH_STATUS_H_ +#define LIBHOTH_INCLUDE_LIBHOTH_STATUS_H_ + +#include + +// Represents success +#define HOTH_SUCCESS 0x0ULL + +// Typedef for the error code +typedef uint64_t libhoth_error; + +#define LIBHOTH_ERR_CONSTRUCT(ctx, space, code) \ + (((uint64_t)(ctx) << 32) | ((uint64_t)(space) << 16) | (uint64_t)(code)) + +// HothContextId: High 32 bits of the error code. +// Uniquely identifies the libhoth operation or subsystem. +enum HothContextId { + HOTH_CTX_NONE = 0, + + // Initialization / General + HOTH_CTX_INIT = 1, + + // Transport layers + HOTH_CTX_USB = 10, + HOTH_CTX_SPI = 20, + + // Command Execution + HOTH_CTX_CMD_EXEC = 30, +}; + +// HothHostSpace: Top 16 bits of the low 32-bit Base Error Code. +// Indicates the domain of host-side errors. +enum HothHostSpace { + HOTH_HOST_SPACE_FW = 0x0000, // Firmware errors directly + HOTH_HOST_SPACE_POSIX = 0x0001, // errno values + HOTH_HOST_SPACE_LIBUSB = 0x0002, // libusb_error values + HOTH_HOST_SPACE_LIBHOTH = 0x0005, // libhoth internal errors +}; + +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + +// Firmware Error +enum hoth_fw_error_status { + HOTH_RES_SUCCESS = 0, + HOTH_RES_INVALID_COMMAND = 1, + HOTH_RES_ERROR = 2, + HOTH_RES_INVALID_PARAM = 3, + HOTH_RES_ACCESS_DENIED = 4, + HOTH_RES_INVALID_RESPONSE = 5, + HOTH_RES_INVALID_VERSION = 6, + HOTH_RES_INVALID_CHECKSUM = 7, + HOTH_RES_IN_PROGRESS = 8, + HOTH_RES_UNAVAILABLE = 9, + HOTH_RES_TIMEOUT = 10, + HOTH_RES_OVERFLOW = 11, + HOTH_RES_INVALID_HEADER = 12, + HOTH_RES_REQUEST_TRUNCATED = 13, + HOTH_RES_RESPONSE_TOO_BIG = 14, + HOTH_RES_BUS_ERROR = 15, + HOTH_RES_BUSY = 16, + HOTH_RES_INVALID_HEADER_VERSION = 17, + HOTH_RES_INVALID_HEADER_CRC = 18, + HOTH_RES_INVALID_DATA_CRC = 19, + HOTH_RES_DUP_UNAVAILABLE = 20, + HOTH_RES_MAX = UINT16_MAX +} __packed; + +#endif // LIBHOTH_INCLUDE_LIBHOTH_STATUS_H_ diff --git a/meson.build b/meson.build index 0cd1e43..c7cfc23 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,7 @@ project('libhoth', 'c', 'cpp', license: 'Apache-2.0', version: '0.0.0') +install_headers('include/libhoth/status.h', subdir: 'libhoth') + header_subdirs = ['libhoth'] libhoth_objs = [] libhoth_deps = [] diff --git a/protocol/BUILD b/protocol/BUILD index ee80cff..daeec98 100644 --- a/protocol/BUILD +++ b/protocol/BUILD @@ -8,6 +8,7 @@ cc_library( srcs = ["host_cmd.c"], hdrs = ["host_cmd.h"], deps = [ + "//:libhoth_status", "//transports:libhoth_device", ], ) @@ -390,6 +391,7 @@ cc_library( hdrs = ["hello.h"], deps = [ ":host_cmd", + "//:libhoth_status", "//transports:libhoth_device", ], ) @@ -399,6 +401,7 @@ cc_test( srcs = ["hello_test.cc"], deps = [ ":hello", + "//:libhoth_status", "//protocol/test:libhoth_device_mock", "//transports:libhoth_device", "@googletest//:gtest", diff --git a/protocol/hello.c b/protocol/hello.c index 9a05779..6784281 100644 --- a/protocol/hello.c +++ b/protocol/hello.c @@ -16,8 +16,8 @@ #include -int libhoth_hello(struct libhoth_device* const dev, const uint32_t input, - uint32_t* const output) { +libhoth_error libhoth_hello(struct libhoth_device* const dev, const uint32_t input, + uint32_t* const output) { const struct hoth_request_hello request = { .input = input, }; @@ -25,6 +25,11 @@ int libhoth_hello(struct libhoth_device* const dev, const uint32_t input, const int rv = libhoth_hostcmd_exec(dev, HOTH_CMD_HELLO, /*version=*/0, &request, sizeof(request), &response, sizeof(response), NULL); + + if (rv != LIBHOTH_OK) { + return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH, rv); + } + *output = response.output; - return rv; + return HOTH_SUCCESS; } diff --git a/protocol/hello.h b/protocol/hello.h index 88804d2..1a73c0c 100644 --- a/protocol/hello.h +++ b/protocol/hello.h @@ -17,6 +17,7 @@ #include +#include "libhoth/status.h" #include "protocol/host_cmd.h" #ifdef __cplusplus @@ -35,7 +36,8 @@ struct hoth_response_hello { uint32_t output; } __hoth_align4; -int libhoth_hello(struct libhoth_device* dev, uint32_t input, uint32_t* output); +libhoth_error libhoth_hello(struct libhoth_device* dev, uint32_t input, + uint32_t* output); #ifdef __cplusplus } diff --git a/protocol/hello_test.cc b/protocol/hello_test.cc index ea77bb6..232ae2d 100644 --- a/protocol/hello_test.cc +++ b/protocol/hello_test.cc @@ -39,6 +39,6 @@ TEST_F(LibHothTest, hello_test) { const uint32_t input = 0xa0b0c0d0; uint32_t output = 0; - EXPECT_EQ(libhoth_hello(&hoth_dev_, input, &output), LIBHOTH_OK); + EXPECT_EQ(libhoth_hello(&hoth_dev_, input, &output), HOTH_SUCCESS); EXPECT_EQ(output, response.output); } diff --git a/protocol/host_cmd.h b/protocol/host_cmd.h index 17e8100..eca28d7 100644 --- a/protocol/host_cmd.h +++ b/protocol/host_cmd.h @@ -18,6 +18,7 @@ #include #include +#include "libhoth/status.h" #include "transports/libhoth_device.h" #ifdef __cplusplus @@ -42,6 +43,7 @@ extern "C" { #define HOTH_CMD_BOARD_SPECIFIC_BASE 0x3E00 #define HOTH_CMD_BOARD_SPECIFIC_LAST 0x3FFF +/* enum hoth_status { HOTH_RES_SUCCESS = 0, HOTH_RES_INVALID_COMMAND = 1, @@ -66,6 +68,8 @@ enum hoth_status { HOTH_RES_DUP_UNAVAILABLE = 20, HOTH_RES_MAX = UINT16_MAX } __packed; +*/ +typedef enum hoth_fw_error_status hoth_status; #define HOTH_HOST_REQUEST_VERSION 3