You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
7.1 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "atcmd.h"
  2. #include "zport.h"
  3. #include <lwip/sockets.h>
  4. #include "config.h"
  5. #define at_address_cmd_template(_config_get) \
  6. { \
  7. ip4_addr_t int_addr; \
  8. char ip_address[16]; \
  9. if (*p == '?') \
  10. { \
  11. printf("config ip address:%s\r\n", inet_ntoa(_config_get)); \
  12. } \
  13. else \
  14. { \
  15. if (len >= sizeof(ip_address)) \
  16. { /* 长度判断 */ \
  17. printf("AT+ERR\r\n"); \
  18. return AT_ERR; \
  19. } /* 拷贝len有效字符长度的字符串到ip_address中 */ \
  20. strncpy(ip_address, (const char *)p, len); \
  21. ip_address[len] = 0; /* 这个必须要加,否则转换会出错 */ \
  22. inet_aton(ip_address, &int_addr); \
  23. _config_get = int_addr.addr; \
  24. config_dump_config(); \
  25. printf("AT+OK\r\n"); \
  26. } \
  27. return AT_SUCCESS; \
  28. }
  29. #define at_processer_rx_buf_size 128
  30. #define at_processer_tx_buf_size 128
  31. // 接收到了多少数据
  32. volatile uint16_t s_at_cmd_uart_rx_off = 0;
  33. // 当前是否正在处理接收到的数据
  34. volatile bool s_at_cmd_uart_rx_buf_is_processing = false;
  35. static uint8_t at_rx_buf[at_processer_rx_buf_size];
  36. // static uint8_t at_tx_buf[at_processer_tx_buf_size];
  37. /* AT指令表 */
  38. const AT_cmd_func at_cmd_func[] = {
  39. {AT_CMD_TEST, "AT", at_cmd_test},
  40. {AT_CMD_IP, "AT+IP=", at_cmd_ip},
  41. {AT_CMD_GW, "AT+GW=", at_cmd_gw},
  42. {AT_CMD_NETMASK, "AT+NETMASK=", at_cmd_netmask},
  43. {AT_CMD_OBTAINING_IP_MODE, "AT+OBTAINING_IP_MODE=", at_cmd_obtaining_ip_mode},
  44. {AT_END, NULL, NULL}};
  45. unsigned int mstrlen(const char *s)
  46. {
  47. const char *ss = s;
  48. while (*ss)
  49. ss++;
  50. return ss - s;
  51. }
  52. int mstrncmp(const char *s1, const char *s2, int n)
  53. {
  54. const unsigned char *c1 = (const unsigned char *)s1;
  55. const unsigned char *c2 = (const unsigned char *)s2;
  56. unsigned char ch;
  57. int d = 0;
  58. while (n--)
  59. {
  60. d = (int)(ch = *c1++) - (int)*c2++;
  61. if (d || !ch)
  62. break;
  63. }
  64. return d;
  65. }
  66. /* 指令执行函数 */
  67. AT_STATUS at_cmd_test(unsigned char *p, unsigned char len)
  68. {
  69. printf("AT+OK\r\n");
  70. return AT_SUCCESS;
  71. }
  72. AT_STATUS at_cmd_ip(unsigned char *p, unsigned char len)
  73. {
  74. at_address_cmd_template(config_get()->ip);
  75. }
  76. AT_STATUS at_cmd_gw(unsigned char *p, unsigned char len)
  77. {
  78. at_address_cmd_template(config_get()->gw);
  79. }
  80. AT_STATUS at_cmd_netmask(unsigned char *p, unsigned char len)
  81. {
  82. at_address_cmd_template(config_get()->netmask);
  83. }
  84. AT_STATUS at_cmd_obtaining_ip_mode(unsigned char *p, unsigned char len)
  85. {
  86. if (*p == '?')
  87. {
  88. printf("config obtaining_ip_mode:%d\r\n", config_get()->obtaining_ip_mode);
  89. }
  90. else
  91. {
  92. if (((*p != '0') && (*p != '1')) || (len > 1))
  93. {
  94. printf("AT+ERR\r\n");
  95. return AT_ERR;
  96. }
  97. config_get()->obtaining_ip_mode = *p - 48; /* ascii码字符0十进制为48 */
  98. config_dump_config();
  99. printf("AT+OK\r\n");
  100. }
  101. return AT_SUCCESS;
  102. }
  103. /* 查找指令表中对应的指令 */
  104. unsigned char AT_cmd_search(unsigned char *p, unsigned char len)
  105. {
  106. unsigned char ret = 0;
  107. // unsigned char *pstr;
  108. unsigned char i, n;
  109. for (i = 1; at_cmd_func[i].cmd != AT_END; i++)
  110. {
  111. n = mstrlen((const char *)at_cmd_func[i].str);
  112. if (!mstrncmp((const char *)p, (const char *)at_cmd_func[i].str, n))
  113. {
  114. ret = i;
  115. break;
  116. }
  117. }
  118. return ret;
  119. }
  120. /* AT指令解析 */
  121. AT_STATUS at_cmd_parse(unsigned char *p, unsigned char len)
  122. {
  123. AT_STATUS ret = AT_SUCCESS;
  124. unsigned char index = 0;
  125. if (len < 4)
  126. return AT_ERR; /* 不符合指令最小长度 */
  127. if ((p[0] == 'A') && (p[1] == 'T') && (p[len - 2] == 0x0D) && (p[len - 1] == 0x0A))
  128. {
  129. if (len == 4)
  130. { /* 测试指令 */
  131. if (at_cmd_func[AT_CMD_TEST].cb != NULL)
  132. at_cmd_func[AT_CMD_TEST].cb(NULL, 0); /* 执行测试指令 */
  133. }
  134. else if (p[2] == '+')
  135. { /* 执行指令解析 */
  136. index = AT_cmd_search(p, len); /* 查找匹配的执行指令,0-已匹配,!0-未匹配 */
  137. if (index)
  138. {
  139. if (at_cmd_func[index].cb != NULL)
  140. { /* 判断指令对应执行函数是否存在 */
  141. unsigned char n;
  142. n = mstrlen((const char *)at_cmd_func[index].str);
  143. ret = at_cmd_func[index].cb(p + n, len - n - 2); /* 执行对应的指令函数, p+n:将指令参数传输执行函数,len-n-2:指令参数有效长度 */
  144. }
  145. else
  146. ret = AT_ERR_FUN_UNUSED; /* 没有可执行函数 */
  147. }
  148. else
  149. {
  150. ret = AT_ERR_UNINVAIL; /* 未找到匹配的指令 */
  151. }
  152. }
  153. }
  154. else
  155. { /* 格式不匹配 */
  156. return AT_ERR;
  157. }
  158. return ret;
  159. }
  160. void at_cmd_processer_push_data(uint8_t rxdata)
  161. {
  162. if (!s_at_cmd_uart_rx_buf_is_processing)
  163. {
  164. if (s_at_cmd_uart_rx_off < at_processer_rx_buf_size)
  165. {
  166. at_rx_buf[s_at_cmd_uart_rx_off] = rxdata;
  167. s_at_cmd_uart_rx_off++;
  168. }
  169. }
  170. }
  171. void at_cmd_processer_try_process_data(void)
  172. {
  173. /**
  174. * @brief
  175. * modbus协议3.5
  176. */
  177. if (s_at_cmd_uart_rx_off != 0)
  178. {
  179. uint16_t modbus_uart_rx_off_before = s_at_cmd_uart_rx_off;
  180. HAL_Delay(1);
  181. sys_critical_enter();
  182. if (s_at_cmd_uart_rx_off == modbus_uart_rx_off_before)
  183. {
  184. s_at_cmd_uart_rx_buf_is_processing = true;
  185. }
  186. sys_critical_exit();
  187. if (s_at_cmd_uart_rx_buf_is_processing)
  188. {
  189. if (at_cmd_parse(at_rx_buf, s_at_cmd_uart_rx_off) != AT_SUCCESS)
  190. {
  191. printf("at cmd parse error\r\n");
  192. }
  193. sys_critical_enter();
  194. s_at_cmd_uart_rx_off = 0;
  195. s_at_cmd_uart_rx_buf_is_processing = false;
  196. sys_critical_exit();
  197. }
  198. }
  199. }