41#define NUM_PINS ARRAY_LEN(pin_table)
42#define DECIMAL_BASE 10U
56 uint32_t mask_word = prefix == 0 ? 0 :
UINT32_ALL_ONES << (32 - prefix);
57 netmask[0] = (mask_word >> 24) & 0xFF;
58 netmask[1] = (mask_word >> 16) & 0xFF;
59 netmask[2] = (mask_word >> 8) & 0xFF;
60 netmask[3] = (mask_word >> 0) & 0xFF;
66 if (input_str == NULL || output_value == NULL || *input_str ==
'\0')
73 unsigned long parsed_value = strtoul(input_str, &end_ptr,
DECIMAL_BASE);
74 if (errno == ERANGE || end_ptr == input_str || *end_ptr !=
'\0' || parsed_value > UINT32_MAX)
79 *output_value = (uint32_t)parsed_value;
85 if (input_str == NULL || output_value == NULL || *input_str ==
'\0')
92 long parsed_value = strtol(input_str, &end_ptr,
DECIMAL_BASE);
93 if (errno == ERANGE || end_ptr == input_str || *end_ptr !=
'\0' || parsed_value < INT32_MIN ||
94 parsed_value > INT32_MAX)
99 *output_value = (int32_t)parsed_value;
105 if (input_str == NULL || ip_addr == NULL)
110 const char* cursor = input_str;
111 for (
size_t octet_index = 0; octet_index < 4; octet_index++)
119 char* end_ptr = NULL;
120 unsigned long octet_value = strtoul(cursor, &end_ptr,
DECIMAL_BASE);
121 if (errno == ERANGE || end_ptr == cursor || octet_value > UINT8_MAX)
132 cursor = end_ptr + 1;
134 else if (*end_ptr !=
'\0')
139 ip_addr[octet_index] = (uint8_t)octet_value;
148 const char* input_str = args;
151 size_t prefix_len = strlen(prefix);
152 if (strncmp(args, prefix, prefix_len) == 0 && args[prefix_len] ==
' ')
154 input_str = args + prefix_len + 1;
168 const char* input_str = args;
171 size_t prefix_len = strlen(prefix);
172 if (strncmp(args, prefix, prefix_len) == 0 && args[prefix_len] ==
' ')
174 input_str = args + prefix_len + 1;
178 uint32_t parsed_value = 0;
179 if (!
parse_u32_strict(input_str, &parsed_value) || parsed_value > UINT16_MAX)
183 *value = (uint16_t)parsed_value;
189 if (args == NULL || ip_addr == NULL || netmask == NULL)
194 const char* input_str = args;
195 if (strncmp(input_str,
"ip ", 3) == 0)
200 char address_buf[32];
201 size_t input_len = strnlen(input_str,
sizeof(address_buf));
202 if (input_len ==
sizeof(address_buf))
206 memcpy(address_buf, input_str, input_len + 1);
208 char* slash_pos = strchr(address_buf,
'/');
209 if (slash_pos == NULL)
234 if (args == NULL || pin_name == NULL || value == NULL || pin == NULL)
240 size_t len = strnlen(args,
sizeof(buf));
241 if (len ==
sizeof(buf))
245 memcpy(buf, args, len + 1);
247 char* saveptr = NULL;
248 char* tok_pin = strtok_r(buf,
" ", &saveptr);
249 const char* tok_val = strtok_r(NULL,
" ", &saveptr);
250 const char* tok_extra = strtok_r(NULL,
" ", &saveptr);
251 if (tok_pin == NULL || tok_val == NULL || tok_extra != NULL)
256 size_t pin_len = strnlen(tok_pin, 16);
261 memcpy(pin_name, tok_pin, pin_len + 1);
263 int32_t parsed_value = 0;
264 if (!
parse_i32_strict(tok_val, &parsed_value) || (parsed_value != 0 && parsed_value != 1))
268 *value = (int)parsed_value;
276 if (!(*pin)->is_output)
285 if (strncmp(args,
"net ", 4) != 0)
314 if (polarities == NULL)
319 memset(polarities, 0,
sizeof(*polarities));
335 const char* token_list = args;
336 if (strncmp(token_list,
"invert ", (CHAR_BIT - 1U)) == 0)
338 token_list += (CHAR_BIT - 1U);
342 size_t token_len = strnlen(token_list,
sizeof(token_buf));
343 if (token_len ==
sizeof(token_buf))
347 memcpy(token_buf, token_list, token_len + 1);
349 char* token_ptr = strtok(token_buf,
",");
350 while (token_ptr != NULL)
352 while (*token_ptr ==
' ')
356 char* token_end = token_ptr + strlen(token_ptr);
357 while (token_end > token_ptr && token_end[-1] ==
' ')
363 if (*token_ptr ==
'\0')
369 if (pin_info == NULL)
374 if (strcmp(token_ptr,
"txd") == 0)
378 else if (strcmp(token_ptr,
"rts") == 0)
382 else if (strcmp(token_ptr,
"cts") == 0)
386 else if (strcmp(token_ptr,
"dtr") == 0)
390 else if (strcmp(token_ptr,
"rxd") == 0)
394 else if (strcmp(token_ptr,
"dcd") == 0)
398 else if (strcmp(token_ptr,
"tck") == 0)
402 else if (strcmp(token_ptr,
"rck") == 0)
411 token_ptr = strtok(NULL,
",");
419 if (baudrate == NULL)
424 const char* input_str = args;
425 if (input_str == NULL)
429 while (*input_str ==
' ')
433 if (*input_str ==
'\0')
438 uint32_t baud_value = 0;
464 if (clockmode == NULL)
469 const char* input_str = args;
470 if (input_str == NULL)
474 while (*input_str ==
' ')
478 if (*input_str ==
'\0')
483 uint32_t clock_mode_value = 0U;
488 if (clock_mode_value > 1U)
493 *clockmode = (clock_mode_value == 1U);
505 for (
size_t pin_index = 0; pin_index <
NUM_PINS; pin_index++)
507 if (strcmp(name,
pin_table[pin_index].name) == 0)
518 if (sscanf(args,
"%15s", pin_name) != 1)
534 if (!line || !cmd || !args || cmd_cap == 0 || args_cap == 0)
559 const char* cmd_end = line;
560 while (*cmd_end && *cmd_end !=
' ')
565 size_t cmd_len = (size_t)(cmd_end - line);
566 if (cmd_len + 1 > cmd_cap)
571 memcpy(cmd, line, cmd_len);
575 const char* arg_start = cmd_end;
576 while (*arg_start ==
' ')
581 int written = snprintf(args, args_cap,
"%s", arg_start);
586 if ((
size_t)written >= args_cap)
e2s_error_t parse_set_v24_baudrate(const char *args, V24_BAUDRATE_T *baudrate)
Parse V.24 baudrate argument.
e2s_error_t cli_parse(const char *line, char *cmd, size_t cmd_cap, char *args, size_t args_cap)
Split one CLI line into command and argument string.
e2s_error_t parse_set_ip_args(const char *args, uint8_t ip_addr[4], uint8_t netmask[4])
Parse ip_addr and optional netmask values.
static bool parse_ipv4_strict(const char *input_str, uint8_t ip_addr[4])
static bool parse_i32_strict(const char *input_str, int32_t *output_value)
e2s_error_t parse_set_gateway_args(const char *args, uint8_t ip_addr[4])
Parse gateway ip_addr argument.
e2s_error_t parse_get_args(const char *args, char *pin_name, const pin_info_t **pin)
Parse get command arguments and resolve pin metadata.
static e2s_error_t parse_u16_with_optional_prefix(const char *args, const char *prefix, uint16_t *value)
e2s_error_t parse_set_v24_clockmode(const char *args, bool *clockmode)
Parse V.24 tx clock mode argument.
const pin_info_t * find_pin(const char *name)
Lookup pin metadata by name.
static bool prefix_to_mask(uint8_t prefix, uint8_t netmask[4])
static bool parse_u32_strict(const char *input_str, uint32_t *output_value)
static const pin_info_t pin_table[]
static e2s_error_t parse_ipv4_with_optional_prefix(const char *args, const char *prefix, uint8_t ip_addr[4])
e2s_error_t parse_set_udp_port_remote_args(const char *args, uint16_t *port)
Parse remote UDP port argument.
e2s_error_t parse_set_gpio_args(const char *args, char *pin_name, int *value, const pin_info_t **pin)
Parse GPIO set command arguments.
const pin_info_t * get_pin_table(void)
Return pointer to static pin metadata table.
e2s_error_t parse_set_net_ip_args(const char *args, uint8_t ip_addr[4], uint8_t netmask[4])
Parse network local ip_addr/subnet arguments.
e2s_error_t parse_set_udp_port_local_args(const char *args, uint16_t *port)
Parse local UDP port argument.
size_t get_num_pins(void)
Return number of entries in the CLI pin table.
e2s_error_t parse_set_ip_remote_args(const char *args, uint8_t ip_addr[4])
Parse remote ip_addr argument.
e2s_error_t parse_set_v24_polarities(const char *args, V24_POLARITIES_T *polarities)
Parse V.24 polarities argument list.
e2s_error_t
Common error codes returned by ether2ser modules.
@ E2S_ERR_CLI_UNKNOWN_PIN
@ E2S_ERR_CLI_LINE_FORMAT
@ E2S_ERR_CLI_LINE_TRUNCATED
@ E2S_ERR_CLI_PIN_INPUT_ONLY
Combined TX and RX polarity configuration.
V24_RX_POLARITIES_T rx_polarities
V24_TX_POLARITIES_T tx_polarities
Pin metadata entry used by CLI lookup and validation.
V24_BAUDRATE_T
Supported synchronous V.24 baudrates.