at.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-03-30 chenyong first version
  9. * 2018-08-17 chenyong multiple client support
  10. */
  11. #ifndef __AT_H__
  12. #define __AT_H__
  13. #include <stddef.h>
  14. #include <rtthread.h>
  15. #ifdef __cplusplus
  16. extern "C" {
  17. #endif
  18. #define AT_SW_VERSION "1.3.1"
  19. #define AT_CMD_NAME_LEN 16
  20. #ifndef AT_SERVER_RECV_BUFF_LEN
  21. #define AT_SERVER_RECV_BUFF_LEN 256
  22. #endif
  23. #ifndef AT_SERVER_DEVICE
  24. #define AT_SERVER_DEVICE "uart2"
  25. #endif
  26. /* the maximum number of supported AT clients */
  27. #ifndef AT_CLIENT_NUM_MAX
  28. #define AT_CLIENT_NUM_MAX 1
  29. #endif
  30. #define AT_CMD_EXPORT(_name_, _args_expr_, _test_, _query_, _setup_, _exec_) \
  31. rt_used static const struct at_cmd __at_cmd_##_test_##_query_##_setup_##_exec_ rt_section("RtAtCmdTab") = \
  32. { \
  33. _name_, \
  34. _args_expr_, \
  35. _test_, \
  36. _query_, \
  37. _setup_, \
  38. _exec_, \
  39. };
  40. enum at_status
  41. {
  42. AT_STATUS_UNINITIALIZED = 0,
  43. AT_STATUS_INITIALIZED,
  44. AT_STATUS_CLI,
  45. };
  46. typedef enum at_status at_status_t;
  47. #ifdef AT_USING_SERVER
  48. enum at_result
  49. {
  50. AT_RESULT_OK = 0, /* AT result is no error */
  51. AT_RESULT_FAILE = -1, /* AT result have a generic error */
  52. AT_RESULT_NULL = -2, /* AT result not need return */
  53. AT_RESULT_CMD_ERR = -3, /* AT command format error or No way to execute */
  54. AT_RESULT_CHECK_FAILE = -4, /* AT command expression format is error */
  55. AT_RESULT_PARSE_FAILE = -5, /* AT command arguments parse is error */
  56. };
  57. typedef enum at_result at_result_t;
  58. struct at_cmd
  59. {
  60. char name[AT_CMD_NAME_LEN];
  61. char *args_expr;
  62. at_result_t (*test)(void);
  63. at_result_t (*query)(void);
  64. at_result_t (*setup)(const char *args);
  65. at_result_t (*exec)(void);
  66. };
  67. typedef struct at_cmd *at_cmd_t;
  68. struct at_server
  69. {
  70. rt_device_t device;
  71. at_status_t status;
  72. rt_err_t (*get_char)(struct at_server *server, char *ch, rt_int32_t timeout);
  73. rt_bool_t echo_mode;
  74. char send_buffer[AT_SERVER_SEND_BUFF_LEN];
  75. char recv_buffer[AT_SERVER_RECV_BUFF_LEN];
  76. rt_size_t cur_recv_len;
  77. rt_sem_t rx_notice;
  78. rt_thread_t parser;
  79. void (*parser_entry)(struct at_server *server);
  80. };
  81. typedef struct at_server *at_server_t;
  82. #endif /* AT_USING_SERVER */
  83. #ifdef AT_USING_CLIENT
  84. enum at_resp_status
  85. {
  86. AT_RESP_OK = 0, /* AT response end is OK */
  87. AT_RESP_ERROR = -1, /* AT response end is ERROR */
  88. AT_RESP_TIMEOUT = -2, /* AT response is timeout */
  89. AT_RESP_BUFF_FULL= -3, /* AT response buffer is full */
  90. };
  91. typedef enum at_resp_status at_resp_status_t;
  92. struct at_response
  93. {
  94. /* response buffer */
  95. char *buf;
  96. /* the maximum response buffer size, it set by `at_create_resp()` function */
  97. rt_size_t buf_size;
  98. /* the length of current response buffer */
  99. rt_size_t buf_len;
  100. /* the number of setting response lines, it set by `at_create_resp()` function
  101. * == 0: the response data will auto return when received 'OK' or 'ERROR'
  102. * != 0: the response data will return when received setting lines number data */
  103. rt_size_t line_num;
  104. /* the count of received response lines */
  105. rt_size_t line_counts;
  106. /* the maximum response time */
  107. rt_int32_t timeout;
  108. };
  109. typedef struct at_response *at_response_t;
  110. struct at_client;
  111. /* URC(Unsolicited Result Code) object, such as: 'RING', 'READY' request by AT server */
  112. struct at_urc
  113. {
  114. const char *cmd_prefix;
  115. const char *cmd_suffix;
  116. void (*func)(struct at_client *client, const char *data, rt_size_t size);
  117. };
  118. typedef struct at_urc *at_urc_t;
  119. struct at_urc_table
  120. {
  121. size_t urc_size;
  122. const struct at_urc *urc;
  123. };
  124. typedef struct at_urc *at_urc_table_t;
  125. struct at_client
  126. {
  127. rt_device_t device;
  128. at_status_t status;
  129. char end_sign;
  130. char *send_buf;
  131. /* The maximum supported send cmd length */
  132. rt_size_t send_bufsz;
  133. /* The length of last cmd */
  134. rt_size_t last_cmd_len;
  135. /* the current received one line data buffer */
  136. char *recv_line_buf;
  137. /* The length of the currently received one line data */
  138. rt_size_t recv_line_len;
  139. /* The maximum supported receive data length */
  140. rt_size_t recv_bufsz;
  141. rt_sem_t rx_notice;
  142. rt_mutex_t lock;
  143. at_response_t resp;
  144. rt_sem_t resp_notice;
  145. at_resp_status_t resp_status;
  146. struct at_urc_table *urc_table;
  147. rt_size_t urc_table_size;
  148. const struct at_urc *urc;
  149. rt_thread_t parser;
  150. };
  151. typedef struct at_client *at_client_t;
  152. #endif /* AT_USING_CLIENT */
  153. #ifdef AT_USING_SERVER
  154. /* AT server initialize and start */
  155. int at_server_init(void);
  156. /* AT server send command execute result to AT device */
  157. void at_server_printf(const char *format, ...);
  158. void at_server_printfln(const char *format, ...);
  159. void at_server_print_result(at_result_t result);
  160. rt_size_t at_server_send(at_server_t server, const char *buf, rt_size_t size);
  161. rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32_t timeout);
  162. /* AT server request arguments parse */
  163. int at_req_parse_args(const char *req_args, const char *req_expr, ...);
  164. #endif /* AT_USING_SERVER */
  165. #ifdef AT_USING_CLIENT
  166. /* AT client initialize and start*/
  167. int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bufsz);
  168. /* ========================== multiple AT client function ============================ */
  169. /* get AT client object */
  170. at_client_t at_client_get(const char *dev_name);
  171. at_client_t at_client_get_first(void);
  172. /* AT client wait for connection to external devices. */
  173. int at_client_obj_wait_connect(at_client_t client, rt_uint32_t timeout);
  174. /* AT client send or receive data */
  175. rt_size_t at_client_obj_send(at_client_t client, const char *buf, rt_size_t size);
  176. rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_int32_t timeout);
  177. /* set AT client a line end sign */
  178. void at_obj_set_end_sign(at_client_t client, char ch);
  179. /* Set URC(Unsolicited Result Code) table */
  180. int at_obj_set_urc_table(at_client_t client, const struct at_urc * table, rt_size_t size);
  181. /* AT client send commands to AT server and waiter response */
  182. int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr, ...);
  183. /* AT response object create and delete */
  184. at_response_t at_create_resp(rt_size_t buf_size, rt_size_t line_num, rt_int32_t timeout);
  185. void at_delete_resp(at_response_t resp);
  186. at_response_t at_resp_set_info(at_response_t resp, rt_size_t buf_size, rt_size_t line_num, rt_int32_t timeout);
  187. /* AT response line buffer get and parse response buffer arguments */
  188. const char *at_resp_get_line(at_response_t resp, rt_size_t resp_line);
  189. const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword);
  190. int at_resp_parse_line_args(at_response_t resp, rt_size_t resp_line, const char *resp_expr, ...);
  191. int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const char *resp_expr, ...);
  192. /* ========================== single AT client function ============================ */
  193. /**
  194. * NOTE: These functions can be used directly when there is only one AT client.
  195. * If there are multiple AT Client in the program, these functions can operate on the first initialized AT client.
  196. */
  197. #define at_exec_cmd(resp, ...) at_obj_exec_cmd(at_client_get_first(), resp, __VA_ARGS__)
  198. #define at_client_wait_connect(timeout) at_client_obj_wait_connect(at_client_get_first(), timeout)
  199. #define at_client_send(buf, size) at_client_obj_send(at_client_get_first(), buf, size)
  200. #define at_client_recv(buf, size, timeout) at_client_obj_recv(at_client_get_first(), buf, size, timeout)
  201. #define at_set_end_sign(ch) at_obj_set_end_sign(at_client_get_first(), ch)
  202. #define at_set_urc_table(urc_table, table_sz) at_obj_set_urc_table(at_client_get_first(), urc_table, table_sz)
  203. #endif /* AT_USING_CLIENT */
  204. /* ========================== User port function ============================ */
  205. #ifdef AT_USING_SERVER
  206. /* AT server device reset */
  207. void at_port_reset(void);
  208. /* AT server device factory reset */
  209. void at_port_factory_reset(void);
  210. #endif
  211. #ifdef __cplusplus
  212. }
  213. #endif
  214. #endif /* __AT_H__ */