diff --git a/AT固件使用手册.md b/AT固件使用手册.md index 9bd6659..5b277da 100644 --- a/AT固件使用手册.md +++ b/AT固件使用手册.md @@ -30,7 +30,7 @@ 1. `MUX`:全局数据承载模式开关 2. `NET`:全局静态网络配置记录 -3. `LINK[idx]`:按索引组织的链路配置记录 +3. `LINK[ROLE]`:按角色名组织的链路配置记录(`S1/S2/C1/C2`) 约束如下: @@ -127,18 +127,16 @@ NET = 192.168.1.100,255.255.255.0,192.168.1.1,02:00:00:00:00:01 ### 7.3 LINK 默认值 ```text -LINK0 = 1,8080,0.0.0.0,0,U0 -LINK1 = 0,8081,0.0.0.0,0,U1 -LINK2 = 1,9001,192.168.1.200,9000,U1 -LINK3 = 0,9002,192.168.1.201,9001,U0 +LINK:S1 = 1,8080,0.0.0.0,0,U0 +LINK:S2 = 0,8081,0.0.0.0,0,U1 +LINK:C1 = 1,9001,192.168.1.200,9000,U1 +LINK:C2 = 0,9002,192.168.1.201,9001,U0 ``` -固定索引映射: +说明: -- `0 = S1` -- `1 = S2` -- `2 = C1` -- `3 = C2` +- `S1/S2/C1/C2` 为对外可见角色名 +- 内部索引映射由固件管理,不对外暴露 UART 记号约定: @@ -174,10 +172,10 @@ AT+QUERY\r\n ```text +NET:IP=192.168.1.100,MASK=255.255.255.0,GW=192.168.1.1,MAC=02:00:00:00:00:01 -+LINK:0,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0 -+LINK:1,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1 -+LINK:2,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1 -+LINK:3,EN=0,LPORT=9002,RIP=192.168.1.201,RPORT=9001,UART=U0 ++LINK:S1,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0 ++LINK:S2,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1 ++LINK:C1,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1 ++LINK:C2,EN=0,LPORT=9002,RIP=192.168.1.201,RPORT=9001,UART=U0 +MUX:0 +MAP:UART2=0x04,UART3=0x08,C1=0x01,C2=0x02,S1=0x10,S2=0x20 +BAUD:U0=115200,U1=115200 @@ -242,19 +240,19 @@ OK #### 设置单条 LINK 记录 ```text -AT+LINK=0,1,8080,0.0.0.0,0,U0\r\n -AT+LINK=2,1,9001,192.168.1.200,9000,U1\r\n +AT+LINK=S1,1,8080,0.0.0.0,0,U0\r\n +AT+LINK=C1,1,9001,192.168.1.200,9000,U1\r\n ``` 字段顺序: ```text -IDX,EN,LPORT,RIP,RPORT,UART +ROLE,EN,LPORT,RIP,RPORT,UART ``` 字段说明: -- `IDX`:实例索引,固定为 `0..3` +- `ROLE`:链路角色名,固定为 `S1/S2/C1/C2` - `EN`:`0/1` - `LPORT`:本地端口 - `RIP`:对端 IP @@ -270,13 +268,13 @@ IDX,EN,LPORT,RIP,RPORT,UART #### 查询单条 LINK ```text -AT+LINK=0\r\n +AT+LINK=S1\r\n ``` 返回示例: ```text -+LINK:0,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0 ++LINK:S1,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0 OK ``` @@ -289,10 +287,10 @@ AT+LINK?\r\n 返回示例: ```text -+LINK:0,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0 -+LINK:1,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1 -+LINK:2,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1 -+LINK:3,EN=0,LPORT=9002,RIP=192.168.1.201,RPORT=9001,UART=U0 ++LINK:S1,EN=1,LPORT=8080,RIP=0.0.0.0,RPORT=0,UART=U0 ++LINK:S2,EN=0,LPORT=8081,RIP=0.0.0.0,RPORT=0,UART=U1 ++LINK:C1,EN=1,LPORT=9001,RIP=192.168.1.200,RPORT=9000,UART=U1 ++LINK:C2,EN=0,LPORT=9002,RIP=192.168.1.201,RPORT=9001,UART=U0 OK ``` @@ -353,9 +351,9 @@ OK: Defaults restored ```text AT+NET=192.168.1.123,255.255.255.0,192.168.1.1,02:00:00:00:00:01\r\n -AT+LINK=0,1,10001,0.0.0.0,0,U1\r\n -AT+LINK=1,1,10003,0.0.0.0,0,U1\r\n -AT+LINK=2,1,20001,192.168.1.201,10002,U0\r\n +AT+LINK=S1,1,10001,0.0.0.0,0,U1\r\n +AT+LINK=S2,1,10003,0.0.0.0,0,U1\r\n +AT+LINK=C1,1,20001,192.168.1.201,10002,U0\r\n AT+MUX=1\r\n AT+SAVE\r\n AT+RESET\r\n diff --git a/App/config.c b/App/config.c index cc195f7..df7b473 100644 --- a/App/config.c +++ b/App/config.c @@ -158,6 +158,48 @@ static const char *link_uart_to_str(uint8_t uart) return (uart == LINK_UART_U1) ? "U1" : "U0"; } +static const char *link_index_to_name(uint32_t index) +{ + switch (index) { + case CONFIG_LINK_S1: + return "S1"; + case CONFIG_LINK_S2: + return "S2"; + case CONFIG_LINK_C1: + return "C1"; + case CONFIG_LINK_C2: + return "C2"; + default: + return "?"; + } +} + +static int parse_link_name(const char *value, uint32_t *index) +{ + if (value == NULL || index == NULL) { + return -1; + } + + if (equals_ignore_case(value, "S1")) { + *index = CONFIG_LINK_S1; + return 0; + } + if (equals_ignore_case(value, "S2")) { + *index = CONFIG_LINK_S2; + return 0; + } + if (equals_ignore_case(value, "C1")) { + *index = CONFIG_LINK_C1; + return 0; + } + if (equals_ignore_case(value, "C2")) { + *index = CONFIG_LINK_C2; + return 0; + } + + return -1; +} + static bool parse_command_with_value(const char *cmd, const char *name, const char **value) { size_t name_len; @@ -309,10 +351,10 @@ static at_result_t handle_summary_query(char *response, uint16_t max_len) snprintf(response, max_len, "+NET:IP=%s,MASK=%s,GW=%s,MAC=%s\r\n" - "+LINK:0,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" - "+LINK:1,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" - "+LINK:2,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" - "+LINK:3,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" + "+LINK:S1,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" + "+LINK:S2,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" + "+LINK:C1,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" + "+LINK:C2,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" "+MUX:%u\r\n" "+MAP:UART2=0x04,UART3=0x08,C1=0x01,C2=0x02,S1=0x10,S2=0x20\r\n" "+BAUD:U0=%lu,U1=%lu\r\n" @@ -356,8 +398,8 @@ static at_result_t handle_link_query(uint32_t index, char *response, uint16_t ma config_ip_to_str(g_config.links[index].remote_ip, rip_str); snprintf(response, max_len, - "+LINK:%lu,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\nOK\r\n", - index, + "+LINK:%s,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\nOK\r\n", + link_index_to_name(index), g_config.links[index].enabled, g_config.links[index].local_port, rip_str, @@ -376,10 +418,10 @@ static at_result_t handle_all_link_query(char *response, uint16_t max_len) snprintf(response, max_len, - "+LINK:0,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" - "+LINK:1,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" - "+LINK:2,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" - "+LINK:3,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" + "+LINK:S1,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" + "+LINK:S2,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" + "+LINK:C1,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" + "+LINK:C2,EN=%u,LPORT=%u,RIP=%s,RPORT=%u,UART=%s\r\n" "OK\r\n", g_config.links[0].enabled, g_config.links[0].local_port, rip_str[0], g_config.links[0].remote_port, link_uart_to_str(g_config.links[0].uart), g_config.links[1].enabled, g_config.links[1].local_port, rip_str[1], g_config.links[1].remote_port, link_uart_to_str(g_config.links[1].uart), @@ -581,7 +623,7 @@ at_result_t config_process_at_cmd(const char *cmd, char *response, uint16_t max_ cursor = value_copy; token = config_next_token(&cursor); - if (token == NULL || parse_u32_value(token, 0u, CONFIG_LINK_COUNT - 1u, &index) != 0) { + if (token == NULL || parse_link_name(token, &index) != 0) { snprintf(response, max_len, "ERROR: Invalid route field\r\n"); return AT_INVALID_PARAM; } @@ -623,7 +665,10 @@ at_result_t config_process_at_cmd(const char *cmd, char *response, uint16_t max_ memcpy(g_config.links[index].remote_ip, rip, sizeof(rip)); g_config.links[index].remote_port = (uint16_t)remote_port; g_config.links[index].uart = uart; - snprintf(response, max_len, "OK\r\n"); + if (handle_link_query(index, response, max_len) != AT_OK) { + snprintf(response, max_len, "ERROR: Invalid route field\r\n"); + return AT_INVALID_PARAM; + } return AT_NEED_REBOOT; }