8c4045e2a4
Fire-and-forget parameter write. Builds CRSF PARAM_WRITE frame and sends it over the serial port.
219 lines
7.6 KiB
C
219 lines
7.6 KiB
C
#include "unity.h"
|
|
#include "celrs/crsf_param.h"
|
|
#include "Mockserial_internal.h"
|
|
#include <string.h>
|
|
|
|
void setUp(void) {
|
|
Mockserial_internal_Init();
|
|
}
|
|
|
|
void tearDown(void) {
|
|
Mockserial_internal_Verify();
|
|
Mockserial_internal_Destroy();
|
|
}
|
|
|
|
/* cel_crsf_param_parse tests */
|
|
|
|
void test_param_parse_null_args(void) {
|
|
uint8_t payload[16] = {0};
|
|
TEST_ASSERT_EQUAL_INT(-1, cel_crsf_param_parse(NULL, payload, sizeof(payload)));
|
|
TEST_ASSERT_EQUAL_INT(-1, cel_crsf_param_parse(NULL, NULL, 0));
|
|
}
|
|
|
|
void test_param_parse_too_short(void) {
|
|
cel_crsf_param param;
|
|
uint8_t payload[5] = {0};
|
|
TEST_ASSERT_EQUAL_INT(-1, cel_crsf_param_parse(¶m, payload, sizeof(payload)));
|
|
}
|
|
|
|
void test_param_parse_text_select(void) {
|
|
cel_crsf_param param;
|
|
/* dest=0x10, src=0xEE, index=5, chunks=0, parent=0, type=TEXT_SELECT */
|
|
/* name="TX Power", options="10 mW;25 mW;100 mW;500 mW;1000 mW", value=2, min=0, max=4, default=0 */
|
|
uint8_t payload[] = {
|
|
0x10, /* dest */
|
|
0xEE, /* src */
|
|
0x05, /* index */
|
|
0x00, /* chunks_remaining */
|
|
0x00, /* parent */
|
|
0x09, /* type = CEL_PARAM_TEXT_SELECT */
|
|
'T', 'X', ' ', 'P', 'o', 'w', 'e', 'r', '\0', /* name */
|
|
'1', '0', ' ', 'm', 'W', ';', /* options */
|
|
'2', '5', ' ', 'm', 'W', ';',
|
|
'1', '0', '0', ' ', 'm', 'W', ';',
|
|
'5', '0', '0', ' ', 'm', 'W', ';',
|
|
'1', '0', '0', '0', ' ', 'm', 'W', '\0', /* end of options */
|
|
0x02, /* value */
|
|
0x00, /* min */
|
|
0x04, /* max */
|
|
0x00, /* default */
|
|
};
|
|
TEST_ASSERT_EQUAL_INT(0, cel_crsf_param_parse(¶m, payload, sizeof(payload)));
|
|
TEST_ASSERT_EQUAL_UINT8(5, param.index);
|
|
TEST_ASSERT_EQUAL_UINT8(CEL_PARAM_TEXT_SELECT, param.type);
|
|
TEST_ASSERT_EQUAL_UINT8(0, param.hidden);
|
|
TEST_ASSERT_EQUAL_STRING("TX Power", param.name);
|
|
TEST_ASSERT_EQUAL_STRING("10 mW;25 mW;100 mW;500 mW;1000 mW", param.options);
|
|
TEST_ASSERT_EQUAL_UINT8(2, param.value);
|
|
TEST_ASSERT_EQUAL_UINT8(0, param.min_val);
|
|
TEST_ASSERT_EQUAL_UINT8(4, param.max_val);
|
|
TEST_ASSERT_EQUAL_UINT8(0, param.default_val);
|
|
}
|
|
|
|
void test_param_parse_hidden_flag(void) {
|
|
cel_crsf_param param;
|
|
uint8_t payload[] = {
|
|
0x10, 0xEE, 0x00, 0x00, 0x00,
|
|
0x88, /* type with hidden bit set (0x80 | 0x08) */
|
|
'H', 'i', 'd', 'd', 'e', 'n', '\0',
|
|
'A', ';', 'B', '\0',
|
|
0x00, 0x00, 0x01, 0x00,
|
|
};
|
|
TEST_ASSERT_EQUAL_INT(0, cel_crsf_param_parse(¶m, payload, sizeof(payload)));
|
|
TEST_ASSERT_EQUAL_UINT8(CEL_PARAM_FLOAT, param.type);
|
|
TEST_ASSERT_EQUAL_UINT8(1, param.hidden);
|
|
}
|
|
|
|
void test_param_parse_uint8_type(void) {
|
|
cel_crsf_param param;
|
|
uint8_t payload[] = {
|
|
0x10, 0xEE, 0x10, 0x00, 0x00,
|
|
0x00, /* type = CEL_PARAM_UINT8 */
|
|
'V', 'a', 'l', '\0', /* name */
|
|
0x00, /* min */
|
|
0xFF, /* max */
|
|
0x80, /* default */
|
|
0x42, /* value */
|
|
};
|
|
TEST_ASSERT_EQUAL_INT(0, cel_crsf_param_parse(¶m, payload, sizeof(payload)));
|
|
TEST_ASSERT_EQUAL_UINT8(0x10, param.index);
|
|
TEST_ASSERT_EQUAL_UINT8(CEL_PARAM_UINT8, param.type);
|
|
TEST_ASSERT_EQUAL_STRING("Val", param.name);
|
|
TEST_ASSERT_EQUAL_UINT8(0x42, param.value);
|
|
TEST_ASSERT_EQUAL_UINT8(0x00, param.min_val);
|
|
TEST_ASSERT_EQUAL_UINT8(0xFF, param.max_val);
|
|
TEST_ASSERT_EQUAL_UINT8(0x80, param.default_val);
|
|
}
|
|
|
|
void test_param_parse_int8_type(void) {
|
|
cel_crsf_param param;
|
|
uint8_t payload[] = {
|
|
0x10, 0xEE, 0x01, 0x00, 0x00,
|
|
0x01, /* type = CEL_PARAM_INT8 */
|
|
'S', '\0',
|
|
0x80, /* min (-128) */
|
|
0x7F, /* max (127) */
|
|
0x00, /* default */
|
|
0x10, /* value */
|
|
};
|
|
TEST_ASSERT_EQUAL_INT(0, cel_crsf_param_parse(¶m, payload, sizeof(payload)));
|
|
TEST_ASSERT_EQUAL_UINT8(CEL_PARAM_INT8, param.type);
|
|
TEST_ASSERT_EQUAL_UINT8(0x10, param.value);
|
|
}
|
|
|
|
void test_param_parse_folder(void) {
|
|
cel_crsf_param param;
|
|
uint8_t payload[] = {
|
|
0x10, 0xEE, 0xFF, 0x00, 0x00,
|
|
0x0B, /* type = CEL_PARAM_FOLDER */
|
|
'F', 'o', 'l', 'd', 'e', 'r', '\0',
|
|
};
|
|
TEST_ASSERT_EQUAL_INT(0, cel_crsf_param_parse(¶m, payload, sizeof(payload)));
|
|
TEST_ASSERT_EQUAL_UINT8(CEL_PARAM_FOLDER, param.type);
|
|
TEST_ASSERT_EQUAL_STRING("Folder", param.name);
|
|
}
|
|
|
|
void test_param_parse_name_truncation(void) {
|
|
cel_crsf_param param;
|
|
/* Name longer than 63 chars (should be truncated) */
|
|
uint8_t payload[128] = {0};
|
|
payload[0] = 0x10; /* dest */
|
|
payload[1] = 0xEE; /* src */
|
|
payload[2] = 0x00; /* index */
|
|
payload[3] = 0x00; /* chunks */
|
|
payload[4] = 0x00; /* parent */
|
|
payload[5] = 0x0B; /* type = FOLDER */
|
|
/* Fill name with 70 'A' chars */
|
|
for (int i = 0; i < 70; i++) payload[6 + i] = 'A';
|
|
payload[6 + 70] = '\0';
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, cel_crsf_param_parse(¶m, payload, sizeof(payload)));
|
|
TEST_ASSERT_EQUAL_UINT8(63, strlen(param.name)); /* truncated to 63 */
|
|
}
|
|
|
|
void test_param_parse_options_truncation(void) {
|
|
cel_crsf_param param;
|
|
/* Options longer than 255 chars (should be truncated) */
|
|
uint8_t payload[400] = {0};
|
|
payload[0] = 0x10; /* dest */
|
|
payload[1] = 0xEE; /* src */
|
|
payload[2] = 0x00; /* index */
|
|
payload[3] = 0x00; /* chunks */
|
|
payload[4] = 0x00; /* parent */
|
|
payload[5] = 0x09; /* type = TEXT_SELECT */
|
|
strcpy((char*)(payload + 6), "Name");
|
|
payload[6 + 4] = '\0';
|
|
/* Fill options with 300 'O' chars */
|
|
size_t opts_start = 6 + 5; /* after name */
|
|
for (int i = 0; i < 299; i++) payload[opts_start + i] = 'O';
|
|
payload[opts_start + 299] = '\0';
|
|
/* Add type-specific data after options */
|
|
size_t after_opts = opts_start + 300;
|
|
payload[after_opts] = 0x00; /* value */
|
|
payload[after_opts + 1] = 0x00; /* min */
|
|
payload[after_opts + 2] = 0x00; /* max */
|
|
payload[after_opts + 3] = 0x00; /* default */
|
|
|
|
TEST_ASSERT_EQUAL_INT(0, cel_crsf_param_parse(¶m, payload, sizeof(payload)));
|
|
TEST_ASSERT_EQUAL_UINT8(255, strlen(param.options)); /* truncated to 255 */
|
|
}
|
|
|
|
/* cel_crsf_param_write tests */
|
|
|
|
void test_param_write_null_port(void) {
|
|
TEST_ASSERT_EQUAL_INT(-1, cel_crsf_param_write(NULL, 0, 0));
|
|
}
|
|
|
|
void test_param_write_success(void) {
|
|
cel_serial_platform_open_ExpectAndReturn("COM3", 400000,
|
|
(cel_serial_platform_handle)42);
|
|
cel_serial_port* port = cel_serial_open("COM3", 400000);
|
|
TEST_ASSERT_NOT_NULL(port);
|
|
|
|
cel_serial_platform_write_ExpectAnyArgsAndReturn(8);
|
|
TEST_ASSERT_EQUAL_INT(0, cel_crsf_param_write(port, 5, 3));
|
|
|
|
cel_serial_platform_close_Expect((cel_serial_platform_handle)42);
|
|
cel_serial_close(port);
|
|
}
|
|
|
|
void test_param_write_partial_write(void) {
|
|
cel_serial_platform_open_ExpectAndReturn("COM3", 400000,
|
|
(cel_serial_platform_handle)42);
|
|
cel_serial_port* port = cel_serial_open("COM3", 400000);
|
|
TEST_ASSERT_NOT_NULL(port);
|
|
|
|
cel_serial_platform_write_ExpectAnyArgsAndReturn(4);
|
|
TEST_ASSERT_EQUAL_INT(-1, cel_crsf_param_write(port, 5, 3));
|
|
|
|
cel_serial_platform_close_Expect((cel_serial_platform_handle)42);
|
|
cel_serial_close(port);
|
|
}
|
|
|
|
int main(void) {
|
|
UNITY_BEGIN();
|
|
RUN_TEST(test_param_parse_null_args);
|
|
RUN_TEST(test_param_parse_too_short);
|
|
RUN_TEST(test_param_parse_text_select);
|
|
RUN_TEST(test_param_parse_hidden_flag);
|
|
RUN_TEST(test_param_parse_uint8_type);
|
|
RUN_TEST(test_param_parse_int8_type);
|
|
RUN_TEST(test_param_parse_folder);
|
|
RUN_TEST(test_param_parse_name_truncation);
|
|
RUN_TEST(test_param_parse_options_truncation);
|
|
RUN_TEST(test_param_write_null_port);
|
|
RUN_TEST(test_param_write_success);
|
|
RUN_TEST(test_param_write_partial_write);
|
|
return UNITY_END();
|
|
}
|