uart: add host-tested immutable tx frame copy

This commit is contained in:
CinderSocket
2026-06-17 16:19:52 -07:00
parent 338af29408
commit 9cb9df5778
5 changed files with 153 additions and 0 deletions
+2
View File
@@ -24,6 +24,7 @@ test-host:
lib/host_tests/test_sam_startup_ui.c \
lib/host_tests/test_sam_key_label.c \
lib/host_tests/test_ccid_logic.c \
lib/host_tests/test_uart_tx_logic.c \
lib/host_tests/test_t1_existing.c \
lib/host_tests/test_t1_protocol.c \
lib/host_tests/test_snmp.c \
@@ -40,6 +41,7 @@ test-host:
board_power_lifecycle.c \
sam_startup_ui.c \
ccid_logic.c \
uart_tx_logic.c \
allocation_policy.c \
worker_loop_policy.c \
credential_sio_label.c \
+2
View File
@@ -6,6 +6,7 @@ extern MunitSuite test_board_power_lifecycle_suite;
extern MunitSuite test_hf_read_lifecycle_suite;
extern MunitSuite test_sam_startup_ui_suite;
extern MunitSuite test_ccid_logic_suite;
extern MunitSuite test_uart_tx_logic_suite;
extern MunitSuite test_sam_key_label_suite;
extern MunitSuite test_t1_existing_suite;
extern MunitSuite test_t1_protocol_suite;
@@ -40,6 +41,7 @@ int main(int argc, char* argv[]) {
{"/t1", test_t1_existing_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
{"/t1", test_t1_protocol_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
{"/ccid", test_ccid_logic_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
{"/uart-tx", test_uart_tx_logic_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
{"/snmp", test_snmp_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
{"/uhf-status-label", test_uhf_status_label_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
{"/credential-sio-label", test_credential_sio_label_suite.tests, NULL, 1, MUNIT_SUITE_OPTION_NONE},
+114
View File
@@ -0,0 +1,114 @@
#include <string.h>
#include "munit.h"
#include "uart_tx_logic.h"
static MunitResult test_tx_frame_copy_rejects_invalid_inputs(
const MunitParameter params[],
void* fixture) {
(void)params;
(void)fixture;
SeaderUartTxFrame frame = {0};
const uint8_t data[] = {0x01U};
munit_assert_false(seader_uart_tx_frame_copy(NULL, data, sizeof(data), sizeof(data)));
munit_assert_false(seader_uart_tx_frame_copy(&frame, NULL, sizeof(data), sizeof(data)));
munit_assert_false(seader_uart_tx_frame_copy(&frame, data, 0U, sizeof(data)));
munit_assert_false(seader_uart_tx_frame_copy(&frame, data, sizeof(data), 0U));
return MUNIT_OK;
}
static MunitResult test_tx_frame_copy_preserves_frame_bytes(
const MunitParameter params[],
void* fixture) {
(void)params;
(void)fixture;
SeaderUartTxFrame frame = {0};
const uint8_t data[] = {0x01U, 0x02U, 0x03U};
munit_assert_true(seader_uart_tx_frame_copy(&frame, data, sizeof(data), sizeof(frame.data)));
munit_assert_size(frame.len, ==, sizeof(data));
munit_assert_memory_equal(sizeof(data), frame.data, data);
return MUNIT_OK;
}
static MunitResult test_tx_frame_copy_is_immutable_after_source_reuse(
const MunitParameter params[],
void* fixture) {
(void)params;
(void)fixture;
SeaderUartTxFrame frame = {0};
uint8_t scratch[] = {0xAAU, 0xBBU, 0xCCU};
const uint8_t expected[] = {0xAAU, 0xBBU, 0xCCU};
munit_assert_true(
seader_uart_tx_frame_copy(&frame, scratch, sizeof(scratch), sizeof(frame.data)));
memset(scratch, 0x11, sizeof(scratch));
munit_assert_size(frame.len, ==, sizeof(expected));
munit_assert_memory_equal(sizeof(expected), frame.data, expected);
return MUNIT_OK;
}
static MunitResult test_back_to_back_copies_preserve_distinct_frames(
const MunitParameter params[],
void* fixture) {
(void)params;
(void)fixture;
SeaderUartTxFrame first = {0};
SeaderUartTxFrame second = {0};
uint8_t scratch[] = {0x10U, 0x20U};
const uint8_t first_expected[] = {0x10U, 0x20U};
const uint8_t second_expected[] = {0x30U, 0x40U};
munit_assert_true(
seader_uart_tx_frame_copy(&first, scratch, sizeof(scratch), sizeof(first.data)));
scratch[0] = 0x30U;
scratch[1] = 0x40U;
munit_assert_true(
seader_uart_tx_frame_copy(&second, scratch, sizeof(scratch), sizeof(second.data)));
munit_assert_memory_equal(sizeof(first_expected), first.data, first_expected);
munit_assert_memory_equal(sizeof(second_expected), second.data, second_expected);
return MUNIT_OK;
}
static MunitTest test_uart_tx_logic_cases[] = {
{(char*)"/copy/rejects-invalid",
test_tx_frame_copy_rejects_invalid_inputs,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{(char*)"/copy/preserves-bytes",
test_tx_frame_copy_preserves_frame_bytes,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{(char*)"/copy/immutable-after-source-reuse",
test_tx_frame_copy_is_immutable_after_source_reuse,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{(char*)"/copy/back-to-back-distinct",
test_back_to_back_copies_preserve_distinct_frames,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL},
{NULL, NULL, NULL, NULL, 0, NULL},
};
MunitSuite test_uart_tx_logic_suite = {
"",
test_uart_tx_logic_cases,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
+17
View File
@@ -0,0 +1,17 @@
#include "uart_tx_logic.h"
#include <string.h>
bool seader_uart_tx_frame_copy(
SeaderUartTxFrame* out,
const uint8_t* data,
size_t len,
size_t max_len) {
if(!out || !data || len == 0U || len > max_len || len > sizeof(out->data)) {
return false;
}
out->len = len;
memcpy(out->data, data, len);
return true;
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define SEADER_UART_TX_FRAME_MAX_SIZE (272U)
typedef struct {
size_t len;
uint8_t data[SEADER_UART_TX_FRAME_MAX_SIZE];
} SeaderUartTxFrame;
bool seader_uart_tx_frame_copy(
SeaderUartTxFrame* out,
const uint8_t* data,
size_t len,
size_t max_len);