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