Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions examples/htool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions protocol/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ cc_library(
hdrs = ["controlled_storage.h"],
deps = [
":host_cmd",
":libhoth_status",
":progress",
"//transports:libhoth_device",
],
Expand All @@ -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",
Expand Down
38 changes: 26 additions & 12 deletions protocol/controlled_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,58 @@

#include <string.h>

#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,
Expand Down
17 changes: 10 additions & 7 deletions protocol/controlled_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@
#ifndef _LIBHOTH_PROTOCOL_CONTROLLED_STORAGE_H_
#define _LIBHOTH_PROTOCOL_CONTROLLED_STORAGE_H_

#include <stddef.h>
#include <stdint.h>

#include "host_cmd.h"
#include "protocol/status.h"
#include "transports/libhoth_device.h"

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

#define HOTH_PRV_CMD_HOTH_CONTROLLED_STORAGE 0x0015
#define CONTROLLED_STORAGE_SIZE_MAX 128
#define CONTROLLED_STORAGE_SIZE 64
Expand All @@ -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
}
Expand Down
64 changes: 52 additions & 12 deletions protocol/controlled_storage_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 <gmock/gmock.h>
#include <gtest/gtest.h>

#include <cstdint>
#include <vector>

#include "protocol/status.h"
#include "test/libhoth_device_mock.h"

using ::testing::_;
Expand Down Expand Up @@ -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<uint8_t>(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)
Expand All @@ -70,24 +87,47 @@ 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) {
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)
.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);
}
Loading