#include "atcmd.h" #include "zport.h" #include #include "config.h" extern ETH_HandleTypeDef heth; #define at_address_cmd_template(_config_get) \ { \ ip4_addr_t int_addr; \ char ip_address[16]; \ if (*p == '?') \ { \ printf("config ip address:%s\r\n", inet_ntoa(_config_get)); \ } \ else \ { \ if (len >= sizeof(ip_address)) \ { /* 长度判断 */ \ printf("AT+ERR\r\n"); \ return AT_ERR; \ } /* 拷贝len有效字符长度的字符串到ip_address中 */ \ strncpy(ip_address, (const char *)p, len); \ ip_address[len] = 0; /* 这个必须要加,否则转换会出错 */ \ inet_aton(ip_address, &int_addr); \ _config_get = int_addr.addr; \ config_dump_config(); \ printf("AT+OK\r\n"); \ } \ return AT_SUCCESS; \ } #define at_processer_rx_buf_size 128 #define at_processer_tx_buf_size 128 // 接收到了多少数据 volatile uint16_t s_at_cmd_uart_rx_off = 0; // 当前是否正在处理接收到的数据 volatile bool s_at_cmd_uart_rx_buf_is_processing = false; static uint8_t at_rx_buf[at_processer_rx_buf_size]; // static uint8_t at_tx_buf[at_processer_tx_buf_size]; /* AT指令表 */ const AT_cmd_func at_cmd_func[] = { {AT_CMD_TEST, "AT", at_cmd_test}, {AT_CMD_IP, "AT+IP=", at_cmd_ip}, {AT_CMD_GW, "AT+GW=", at_cmd_gw}, {AT_CMD_NETMASK, "AT+NETMASK=", at_cmd_netmask}, {AT_CMD_OBTAINING_IP_MODE, "AT+OBTAINING_IP_MODE=", at_cmd_obtaining_ip_mode}, {AT_CMD_MAC, "AT+MAC=", at_cmd_mac}, {AT_END, NULL, NULL}}; unsigned int mstrlen(const char *s) { const char *ss = s; while (*ss) ss++; return ss - s; } int mstrncmp(const char *s1, const char *s2, int n) { const unsigned char *c1 = (const unsigned char *)s1; const unsigned char *c2 = (const unsigned char *)s2; unsigned char ch; int d = 0; while (n--) { d = (int)(ch = *c1++) - (int)*c2++; if (d || !ch) break; } return d; } /* 指令执行函数 */ AT_STATUS at_cmd_test(unsigned char *p, unsigned char len) { printf("AT+OK\r\n"); return AT_SUCCESS; } AT_STATUS at_cmd_ip(unsigned char *p, unsigned char len) { at_address_cmd_template(config_get()->ip); } AT_STATUS at_cmd_gw(unsigned char *p, unsigned char len) { at_address_cmd_template(config_get()->gw); } AT_STATUS at_cmd_netmask(unsigned char *p, unsigned char len) { at_address_cmd_template(config_get()->netmask); } AT_STATUS at_cmd_obtaining_ip_mode(unsigned char *p, unsigned char len) { if (*p == '?') { printf("config obtaining_ip_mode:%d\r\n", config_get()->obtaining_ip_mode); } else { if (((*p != '0') && (*p != '1')) || (len > 1)) { printf("AT+ERR\r\n"); return AT_ERR; } config_get()->obtaining_ip_mode = *p - 48; /* ascii码字符0十进制为48 */ config_dump_config(); printf("AT+OK\r\n"); } return AT_SUCCESS; } AT_STATUS at_cmd_mac(unsigned char *p, unsigned char len) { if (*p == '?') { printf("mac:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\r\n", // heth.Init.MACAddr[0], heth.Init.MACAddr[1], heth.Init.MACAddr[2], // heth.Init.MACAddr[3], heth.Init.MACAddr[4], heth.Init.MACAddr[5]); // } else { printf("AT+OK\r\n"); } return AT_SUCCESS; } /* 查找指令表中对应的指令 */ unsigned char AT_cmd_search(unsigned char *p, unsigned char len) { unsigned char ret = 0; // unsigned char *pstr; unsigned char i, n; for (i = 1; at_cmd_func[i].cmd != AT_END; i++) { n = mstrlen((const char *)at_cmd_func[i].str); if (!mstrncmp((const char *)p, (const char *)at_cmd_func[i].str, n)) { ret = i; break; } } return ret; } /* AT指令解析 */ AT_STATUS at_cmd_parse(unsigned char *p, unsigned char len) { AT_STATUS ret = AT_SUCCESS; unsigned char index = 0; if (len < 4) return AT_ERR; /* 不符合指令最小长度 */ if ((p[0] == 'A') && (p[1] == 'T') && (p[len - 2] == 0x0D) && (p[len - 1] == 0x0A)) { if (len == 4) { /* 测试指令 */ if (at_cmd_func[AT_CMD_TEST].cb != NULL) at_cmd_func[AT_CMD_TEST].cb(NULL, 0); /* 执行测试指令 */ } else if (p[2] == '+') { /* 执行指令解析 */ index = AT_cmd_search(p, len); /* 查找匹配的执行指令,0-已匹配,!0-未匹配 */ if (index) { if (at_cmd_func[index].cb != NULL) { /* 判断指令对应执行函数是否存在 */ unsigned char n; n = mstrlen((const char *)at_cmd_func[index].str); ret = at_cmd_func[index].cb(p + n, len - n - 2); /* 执行对应的指令函数, p+n:将指令参数传输执行函数,len-n-2:指令参数有效长度 */ } else ret = AT_ERR_FUN_UNUSED; /* 没有可执行函数 */ } else { ret = AT_ERR_UNINVAIL; /* 未找到匹配的指令 */ } } } else { /* 格式不匹配 */ return AT_ERR; } return ret; } void at_cmd_processer_push_data(uint8_t rxdata) { if (!s_at_cmd_uart_rx_buf_is_processing) { if (s_at_cmd_uart_rx_off < at_processer_rx_buf_size) { at_rx_buf[s_at_cmd_uart_rx_off] = rxdata; s_at_cmd_uart_rx_off++; } } } void at_cmd_processer_try_process_data(void) { /** * @brief * 根据modbus协议,当超过3.5个字符时间后依然没有收到数据 */ if (s_at_cmd_uart_rx_off != 0) { uint16_t modbus_uart_rx_off_before = s_at_cmd_uart_rx_off; HAL_Delay(1); sys_critical_enter(); if (s_at_cmd_uart_rx_off == modbus_uart_rx_off_before) { s_at_cmd_uart_rx_buf_is_processing = true; } sys_critical_exit(); if (s_at_cmd_uart_rx_buf_is_processing) { if (at_cmd_parse(at_rx_buf, s_at_cmd_uart_rx_off) != AT_SUCCESS) { printf("at cmd parse error\r\n"); } sys_critical_enter(); s_at_cmd_uart_rx_off = 0; s_at_cmd_uart_rx_buf_is_processing = false; sys_critical_exit(); } } }