diff --git a/examples/htool.c b/examples/htool.c index ade53de..ff7dc12 100644 --- a/examples/htool.c +++ b/examples/htool.c @@ -753,31 +753,36 @@ int htool_controlled_storage_write(const struct htool_invocation* inv) { return -1; } - int ret; + int result = -1; struct stat statbuf; - if ((ret = fstat(fd, &statbuf)) != 0) { + if (fstat(fd, &statbuf) != 0) { fprintf(stderr, "fstat error: %s\n", strerror(errno)); goto cleanup; } if (statbuf.st_size > SIZE_MAX) { fprintf(stderr, "file too large\n"); - ret = -1; goto cleanup; } size_t file_size = statbuf.st_size; uint8_t* file_data = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0); if (file_data == NULL) { - ret = -1; goto cleanup; } - ret = libhoth_controlled_storage_write(dev, slot, file_data, file_size); + libhoth_error err = + libhoth_controlled_storage_write(dev, slot, file_data, file_size); munmap(file_data, file_size); + if (err != HOTH_SUCCESS) { + htool_report_error("controlled_storage write", err); + goto cleanup; + } + + result = 0; cleanup: close(fd); - return ret; + return result; } int htool_controlled_storage_read(const struct htool_invocation* inv) { @@ -799,8 +804,10 @@ int htool_controlled_storage_read(const struct htool_invocation* inv) { struct hoth_payload_controlled_storage payload; size_t payload_len; - if (libhoth_controlled_storage_read(dev, slot, &payload, &payload_len) != 0) { - fprintf(stderr, "Unable to read from controlled storage.\n"); + libhoth_error err = + libhoth_controlled_storage_read(dev, slot, &payload, &payload_len); + if (err != HOTH_SUCCESS) { + htool_report_error("controlled_storage read", err); return -1; } @@ -841,7 +848,12 @@ int htool_controlled_storage_delete(const struct htool_invocation* inv) { return -1; } - return libhoth_controlled_storage_delete(dev, slot); + libhoth_error err = libhoth_controlled_storage_delete(dev, slot); + if (err != HOTH_SUCCESS) { + htool_report_error("controlled_storage delete", err); + return -1; + } + return 0; } static int command_set_gpio_drive_strength(const struct htool_invocation* inv) { diff --git a/protocol/BUILD b/protocol/BUILD index 5094ad2..c49f498 100644 --- a/protocol/BUILD +++ b/protocol/BUILD @@ -354,6 +354,7 @@ cc_library( hdrs = ["controlled_storage.h"], deps = [ ":host_cmd", + ":libhoth_status", ":progress", "//transports:libhoth_device", ], @@ -364,6 +365,7 @@ cc_test( srcs = ["controlled_storage_test.cc"], deps = [ ":controlled_storage", + ":libhoth_status", "//protocol/test:libhoth_device_mock", "//transports:libhoth_device", "@googletest//:gtest", diff --git a/protocol/controlled_storage.c b/protocol/controlled_storage.c index ed6a41e..4134985 100644 --- a/protocol/controlled_storage.c +++ b/protocol/controlled_storage.c @@ -16,44 +16,58 @@ #include -#include "controlled_storage.h" +#include "host_cmd.h" +#include "protocol/status.h" -int libhoth_controlled_storage_read( +libhoth_error libhoth_controlled_storage_read( struct libhoth_device* dev, uint32_t slot, struct hoth_payload_controlled_storage* payload, size_t* payload_len) { + if (dev == NULL || payload == NULL) { + return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH, + LIBHOTH_ERR_INVALID_PARAMETER); + } struct hoth_request_controlled_storage req = {}; req.operation = CONTROLLED_STORAGE_READ; req.slot = slot; - return libhoth_hostcmd_exec( + return libhoth_hostcmd_exec_v2( dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CONTROLLED_STORAGE, /*version=*/0, &req, sizeof(req), payload, sizeof(*payload), payload_len); } -int libhoth_controlled_storage_write(struct libhoth_device* dev, uint32_t slot, - const uint8_t* data, size_t len) { - struct hoth_request_controlled_storage req = {}; - if (len > sizeof(req.payload.data)) { - return -1; +libhoth_error libhoth_controlled_storage_write(struct libhoth_device* dev, + uint32_t slot, + const uint8_t* data, + size_t len) { + if (dev == NULL || data == NULL || + len > + sizeof(((struct hoth_request_controlled_storage*)0)->payload.data)) { + return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH, + LIBHOTH_ERR_INVALID_PARAMETER); } + struct hoth_request_controlled_storage req = {}; req.operation = CONTROLLED_STORAGE_WRITE; req.slot = slot; memcpy(req.payload.data, data, len); - return libhoth_hostcmd_exec( + return libhoth_hostcmd_exec_v2( dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CONTROLLED_STORAGE, /*version=*/0, &req, sizeof(req) - sizeof(struct hoth_payload_controlled_storage) + len, NULL, 0, NULL); } -int libhoth_controlled_storage_delete(struct libhoth_device* dev, - uint32_t slot) { +libhoth_error libhoth_controlled_storage_delete(struct libhoth_device* dev, + uint32_t slot) { + if (dev == NULL) { + return LIBHOTH_ERR_CONSTRUCT(HOTH_CTX_CMD_EXEC, HOTH_HOST_SPACE_LIBHOTH, + LIBHOTH_ERR_INVALID_PARAMETER); + } struct hoth_request_controlled_storage req = {}; req.operation = CONTROLLED_STORAGE_DELETE; req.slot = slot; - return libhoth_hostcmd_exec( + return libhoth_hostcmd_exec_v2( dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CONTROLLED_STORAGE, /*version=*/0, &req, sizeof(req) - sizeof(struct hoth_payload_controlled_storage), NULL, 0, diff --git a/protocol/controlled_storage.h b/protocol/controlled_storage.h index e842cf6..6bed991 100644 --- a/protocol/controlled_storage.h +++ b/protocol/controlled_storage.h @@ -15,15 +15,17 @@ #ifndef _LIBHOTH_PROTOCOL_CONTROLLED_STORAGE_H_ #define _LIBHOTH_PROTOCOL_CONTROLLED_STORAGE_H_ +#include +#include + #include "host_cmd.h" +#include "protocol/status.h" #include "transports/libhoth_device.h" #ifdef __cplusplus extern "C" { #endif -#include - #define HOTH_PRV_CMD_HOTH_CONTROLLED_STORAGE 0x0015 #define CONTROLLED_STORAGE_SIZE_MAX 128 #define CONTROLLED_STORAGE_SIZE 64 @@ -48,13 +50,14 @@ struct hoth_request_controlled_storage { struct hoth_payload_controlled_storage payload; } __attribute__((packed)); -int libhoth_controlled_storage_read( +libhoth_error libhoth_controlled_storage_read( struct libhoth_device* dev, uint32_t slot, struct hoth_payload_controlled_storage* payload, size_t* payload_len); -int libhoth_controlled_storage_write(struct libhoth_device* dev, uint32_t slot, - const uint8_t* data, size_t len); -int libhoth_controlled_storage_delete(struct libhoth_device* dev, - uint32_t slot); +libhoth_error libhoth_controlled_storage_write(struct libhoth_device* dev, + uint32_t slot, + const uint8_t* data, size_t len); +libhoth_error libhoth_controlled_storage_delete(struct libhoth_device* dev, + uint32_t slot); #ifdef __cplusplus } diff --git a/protocol/controlled_storage_test.cc b/protocol/controlled_storage_test.cc index 7651584..b0ecec1 100644 --- a/protocol/controlled_storage_test.cc +++ b/protocol/controlled_storage_test.cc @@ -12,13 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "controlled_storage.h" +#include "protocol/controlled_storage.h" #include #include #include +#include +#include "protocol/status.h" #include "test/libhoth_device_mock.h" using ::testing::_; @@ -47,20 +49,35 @@ TEST_F(LibHothTest, controlled_storage_read_test) { size_t payload_len = 0; EXPECT_EQ(libhoth_controlled_storage_read(&hoth_dev_, 0, &resp, &payload_len), - LIBHOTH_OK); + HOTH_SUCCESS); EXPECT_EQ(payload_len, ex_payload_len); EXPECT_THAT(std::vector(ex_resp.data, ex_resp.data + ex_payload_len), ElementsAreArray(resp.data, payload_len)); } +TEST_F(LibHothTest, controlled_storage_read_null_params) { + struct hoth_payload_controlled_storage resp = {}; + size_t payload_len = 0; + + libhoth_error err = + libhoth_controlled_storage_read(nullptr, 0, &resp, &payload_len); + EXPECT_EQ(LIBHOTH_ERR_GET_CTX(err), HOTH_CTX_CMD_EXEC); + EXPECT_EQ(LIBHOTH_ERR_GET_SPACE(err), HOTH_HOST_SPACE_LIBHOTH); + EXPECT_EQ(LIBHOTH_ERR_GET_CODE(err), LIBHOTH_ERR_INVALID_PARAMETER); + + err = libhoth_controlled_storage_read(&hoth_dev_, 0, nullptr, &payload_len); + EXPECT_EQ(LIBHOTH_ERR_GET_CTX(err), HOTH_CTX_CMD_EXEC); + EXPECT_EQ(LIBHOTH_ERR_GET_SPACE(err), HOTH_HOST_SPACE_LIBHOTH); + EXPECT_EQ(LIBHOTH_ERR_GET_CODE(err), LIBHOTH_ERR_INVALID_PARAMETER); +} + TEST_F(LibHothTest, controlled_storage_write_test) { EXPECT_CALL(mock_, send(_, UsesCommand(HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CONTROLLED_STORAGE), _)) - .WillOnce(Return(LIBHOTH_OK)) - .WillOnce(Return(-1)); + .WillOnce(Return(LIBHOTH_OK)); uint32_t dummy = 0; EXPECT_CALL(mock_, receive) @@ -70,10 +87,28 @@ TEST_F(LibHothTest, controlled_storage_write_test) { EXPECT_EQ( libhoth_controlled_storage_write(&hoth_dev_, 0, payload, sizeof(payload)), - LIBHOTH_OK); - EXPECT_EQ( - libhoth_controlled_storage_write(&hoth_dev_, 0, payload, sizeof(payload)), - -1); + HOTH_SUCCESS); +} + +TEST_F(LibHothTest, controlled_storage_write_null_params) { + uint8_t payload[] = {0xAB, 0xCD, 0xEF}; + + libhoth_error err = + libhoth_controlled_storage_write(nullptr, 0, payload, sizeof(payload)); + EXPECT_EQ(LIBHOTH_ERR_GET_CTX(err), HOTH_CTX_CMD_EXEC); + EXPECT_EQ(LIBHOTH_ERR_GET_SPACE(err), HOTH_HOST_SPACE_LIBHOTH); + EXPECT_EQ(LIBHOTH_ERR_GET_CODE(err), LIBHOTH_ERR_INVALID_PARAMETER); + + err = + libhoth_controlled_storage_write(&hoth_dev_, 0, nullptr, sizeof(payload)); + EXPECT_EQ(LIBHOTH_ERR_GET_CTX(err), HOTH_CTX_CMD_EXEC); + EXPECT_EQ(LIBHOTH_ERR_GET_SPACE(err), HOTH_HOST_SPACE_LIBHOTH); + EXPECT_EQ(LIBHOTH_ERR_GET_CODE(err), LIBHOTH_ERR_INVALID_PARAMETER); + + err = libhoth_controlled_storage_write(&hoth_dev_, 0, payload, 1000); + EXPECT_EQ(LIBHOTH_ERR_GET_CTX(err), HOTH_CTX_CMD_EXEC); + EXPECT_EQ(LIBHOTH_ERR_GET_SPACE(err), HOTH_HOST_SPACE_LIBHOTH); + EXPECT_EQ(LIBHOTH_ERR_GET_CODE(err), LIBHOTH_ERR_INVALID_PARAMETER); } TEST_F(LibHothTest, controlled_storage_delete_test) { @@ -81,13 +116,18 @@ TEST_F(LibHothTest, controlled_storage_delete_test) { UsesCommand(HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_HOTH_CONTROLLED_STORAGE), _)) - .WillOnce(Return(LIBHOTH_OK)) - .WillOnce(Return(-1)); + .WillOnce(Return(LIBHOTH_OK)); uint32_t dummy = 0; EXPECT_CALL(mock_, receive) .WillOnce(DoAll(CopyResp(&dummy, 0), Return(LIBHOTH_OK))); - EXPECT_EQ(libhoth_controlled_storage_delete(&hoth_dev_, 0), LIBHOTH_OK); - EXPECT_EQ(libhoth_controlled_storage_delete(&hoth_dev_, 0), -1); + EXPECT_EQ(libhoth_controlled_storage_delete(&hoth_dev_, 0), HOTH_SUCCESS); +} + +TEST_F(LibHothTest, controlled_storage_delete_null_params) { + libhoth_error err = libhoth_controlled_storage_delete(nullptr, 0); + EXPECT_EQ(LIBHOTH_ERR_GET_CTX(err), HOTH_CTX_CMD_EXEC); + EXPECT_EQ(LIBHOTH_ERR_GET_SPACE(err), HOTH_HOST_SPACE_LIBHOTH); + EXPECT_EQ(LIBHOTH_ERR_GET_CODE(err), LIBHOTH_ERR_INVALID_PARAMETER); }