blob: c9225071a5fbc7fa7734c690ea19956d96d3fe29 [file] [log] [blame]
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/net/buf.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
#include <zephyr/mgmt/mcumgr/transport/smp_dummy.h>
#include <zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt.h>
#include <zcbor_common.h>
#include <zcbor_decode.h>
#include <mgmt/mcumgr/transport/smp_internal.h>
#define SMP_RESPONSE_WAIT_TIME 3
/* Test fs_mgmt supported hash/checksum query command */
static const uint8_t command[] = {
0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x01, 0x03,
0xbf, 0xff,
};
struct hash_checksum_type {
uint8_t name[32];
uint32_t format;
uint32_t size;
bool found;
bool entries_matched;
};
ZTEST(fs_mgmt_hash_supported, test_supported)
{
struct net_buf *nb;
struct hash_checksum_type expected_types[] = {
#ifdef CONFIG_FS_MGMT_HASH_SHA256
{
.name = "sha256",
.format = 1,
.size = 32,
.found = false,
.entries_matched = false,
},
#endif
#ifdef CONFIG_FS_MGMT_CHECKSUM_IEEE_CRC32
{
.name = "crc32",
.format = 0,
.size = 4,
.found = false,
.entries_matched = false,
},
#endif
};
/* Register os_mgmt mcumgr group */
fs_mgmt_register_group();
/* Enable dummy SMP backend and ready for usage */
smp_dummy_enable();
smp_dummy_clear_state();
/* Send test echo command to dummy SMP backend */
(void)smp_dummy_tx_pkt(command, sizeof(command));
smp_dummy_add_data();
/* For a short duration to see if response has been received */
bool received = smp_dummy_wait_for_data(SMP_RESPONSE_WAIT_TIME);
zassert_true(received, "Expected to receive data but timed out\n");
/* Retrieve response buffer and ensure validity */
nb = smp_dummy_get_outgoing();
smp_dummy_disable();
/* Check that the headers seem valid */
struct smp_hdr *response_hdr = (struct smp_hdr *)nb->data;
uint16_t len = ntohs(response_hdr->nh_len);
uint16_t group = ntohs(response_hdr->nh_group);
zassert_equal(response_hdr->nh_op, MGMT_OP_READ_RSP,
"Expected response to have rease response type");
zassert_true((len > 20), "Expected response to be at least 20 bytes in length");
zassert_equal(group, MGMT_GROUP_ID_FS, "Expected response to be FS group");
zassert_equal(response_hdr->nh_id, FS_MGMT_ID_SUPPORTED_HASH_CHECKSUM,
"Expected response to be supported hash/checksum ID");
/* Process the payload with zcbor and check expected types are present */
zcbor_state_t state[10];
struct zcbor_string key;
uint32_t format_value;
bool format_found;
uint32_t size_value;
bool size_found;
int8_t entry = 0;
bool ok = true;
/* Search expected type array for this type and update details */
zcbor_new_decode_state(state, 10, &nb->data[sizeof(struct smp_hdr)],
(nb->len - sizeof(struct smp_hdr)), 1);
ok = zcbor_map_start_decode(state);
ok = zcbor_tstr_decode(state, &key);
zassert_equal(key.len, strlen("types"),
"Expected CBOR response 'types' value length to match");
zassert_mem_equal(key.value, "types", strlen("types"),
"Expected CBOR response 'types' value to match");
ok = zcbor_map_start_decode(state);
while (ok == true) {
ok = zcbor_tstr_decode(state, &key);
if (!ok) {
break;
}
entry = 0;
while (entry < ARRAY_SIZE(expected_types)) {
if (memcmp(key.value, expected_types[entry].name, MIN(key.len,
strlen(expected_types[entry].name))) == 0) {
zassert_equal(expected_types[entry].found, false,
"Found entry multiple times");
expected_types[entry].found = true;
break;
}
++entry;
}
zassert_equal(entry < ARRAY_SIZE(expected_types), true,
"Did not find entry for type");
ok = zcbor_map_start_decode(state);
format_found = false;
size_found = false;
while (ok == true) {
ok = zcbor_tstr_decode(state, &key);
if (!ok) {
break;
}
if (memcmp(key.value, "format", strlen("format")) == 0) {
zassert_false(format_found,
"Expected format to only be found once");
ok &= zcbor_uint32_decode(state, &format_value);
format_found = true;
} else if (memcmp(key.value, "size", strlen("size")) == 0) {
zassert_false(size_found, "Expected size to be only found once");
ok &= zcbor_uint32_decode(state, &size_value);
size_found = true;
} else {
zassert_true(false, "Unexpected field in CBOR response");
}
if (format_found == true && size_found == true) {
zassert_equal(expected_types[entry].format, format_value,
"Format value mismatch with expected value");
zassert_equal(expected_types[entry].size, size_value,
"Size value mismatch with expected value");
expected_types[entry].entries_matched = true;
}
}
ok = zcbor_map_end_decode(state);
}
ok = zcbor_map_end_decode(state);
}
ZTEST_SUITE(fs_mgmt_hash_supported, NULL, NULL, NULL, NULL, NULL);