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