Add Transport-Neutral Serial Session Broker
This commit is contained in:
+9
-83
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user