Add Transport-Neutral Serial Session Broker

This commit is contained in:
2026-08-23 00:01:50 +02:00
parent 535c27350d
commit 2524f43fac
11 changed files with 1407 additions and 102 deletions
+9 -83
View File
@@ -20,8 +20,6 @@ static void print_usage(void)
printf(" serial set <baud|data-bits|parity|stop-bits|flow|dtr|rts-threshold> <value>\n");
printf(" serial save|load|defaults|reset\n");
printf(" serial counters|clear-counters\n");
printf(" serial send-hex <hex-bytes>\n");
printf(" serial read [maximum-bytes]\n");
}
static void print_config(const serial_config_t *config)
@@ -39,6 +37,15 @@ static void print_config(const serial_config_t *config)
static bool parse_unsigned(const char *text, uint32_t minimum, uint32_t maximum, uint32_t *value)
{
if (text == NULL || *text == '\0') {
return false;
}
for (const char *character = text; *character != '\0'; ++character) {
if (*character < '0' || *character > '9') {
return false;
}
}
char *end = NULL;
errno = 0;
unsigned long parsed = strtoul(text, &end, 10);
@@ -184,72 +191,6 @@ static int set_parameter(const char *parameter, const char *value)
return 0;
}
static int hexadecimal_value(char character)
{
if (character >= '0' && character <= '9') {
return character - '0';
}
if (character >= 'a' && character <= 'f') {
return character - 'a' + 10;
}
if (character >= 'A' && character <= 'F') {
return character - 'A' + 10;
}
return -1;
}
static int send_hexadecimal(const char *text)
{
/* The 160-character REPL line comfortably carries at most 64 hex bytes. */
uint8_t data[64];
size_t text_length = strlen(text);
if (text_length == 0 || (text_length % 2) != 0 || text_length > sizeof(data) * 2) {
printf("Provide 1..64 bytes as an even number of hexadecimal digits without separators.\n");
return 1;
}
size_t data_length = text_length / 2;
for (size_t index = 0; index < data_length; ++index) {
int high = hexadecimal_value(text[index * 2]);
int low = hexadecimal_value(text[index * 2 + 1]);
if (high < 0 || low < 0) {
size_t invalid_index = index * 2 + (high < 0 ? 0 : 1);
printf("Invalid hexadecimal digit at character %u.\n", (unsigned int)invalid_index);
return 1;
}
data[index] = (uint8_t)((high << 4) | low);
}
size_t accepted = serial_service_write(data, data_length);
printf("Queued %u of %u bytes.\n", (unsigned int)accepted, (unsigned int)data_length);
return accepted == data_length ? 0 : 1;
}
static int read_hexadecimal(int argc, char **argv)
{
uint32_t maximum = 512;
if (argc == 3 && !parse_unsigned(argv[2], 1, 512, &maximum)) {
printf("Read size must be 1..512 bytes.\n");
return 1;
}
if (argc > 3) {
print_usage();
return 1;
}
uint8_t data[512];
size_t received = serial_service_read(data, maximum);
printf("Read %u byte%s", (unsigned int)received, received == 1 ? "" : "s");
if (received > 0) {
printf(": ");
for (size_t index = 0; index < received; ++index) {
printf("%02x", data[index]);
}
}
printf("\n");
return 0;
}
static int command_serial(int argc, char **argv)
{
if (argc == 1 || (argc == 2 && strcmp(argv[1], "status") == 0)) {
@@ -345,21 +286,6 @@ static int command_serial(int argc, char **argv)
printf("Serial counters cleared.\n");
return 0;
}
if (argc == 3 && strcmp(argv[1], "send-hex") == 0) {
if (!serial_service_is_running()) {
printf("UART service is stopped; run 'serial start' first.\n");
return 1;
}
return send_hexadecimal(argv[2]);
}
if ((argc == 2 || argc == 3) && strcmp(argv[1], "read") == 0) {
if (!serial_service_is_running()) {
printf("UART service is stopped; run 'serial start' first.\n");
return 1;
}
return read_hexadecimal(argc, argv);
}
print_usage();
return 1;
}