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