diff --git a/components/net/at/include/at.h b/components/net/at/include/at.h index dc2abef353..a7a6aeca7a 100644 --- a/components/net/at/include/at.h +++ b/components/net/at/include/at.h @@ -96,7 +96,7 @@ struct at_server rt_device_t device; at_status_t status; - char (*get_char)(void); + rt_err_t (*get_char)(struct at_server *server, char *ch, rt_int32_t timeout); rt_bool_t echo_mode; char recv_buffer[AT_SERVER_RECV_BUFF_LEN]; @@ -194,6 +194,8 @@ int at_server_init(void); void at_server_printf(const char *format, ...); void at_server_printfln(const char *format, ...); void at_server_print_result(at_result_t result); +rt_size_t at_server_send(at_server_t server, const char *buf, rt_size_t size); +rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32_t timeout); /* AT server request arguments parse */ int at_req_parse_args(const char *req_args, const char *req_expr, ...); diff --git a/components/net/at/src/at_cli.c b/components/net/at/src/at_cli.c index 80af613fa6..e39a913357 100644 --- a/components/net/at/src/at_cli.c +++ b/components/net/at/src/at_cli.c @@ -100,6 +100,12 @@ void at_cli_deinit(void) } #ifdef AT_USING_SERVER +static rt_err_t at_server_console_getchar(struct at_server *server, char *ch, rt_int32_t timeout) +{ + *ch = console_getchar(); + return RT_EOK; +} + static void server_cli_parser(void) { extern at_server_t at_get_server(void); @@ -107,7 +113,7 @@ static void server_cli_parser(void) at_server_t server = at_get_server(); rt_base_t int_lvl; static rt_device_t device_bak; - static char (*getchar_bak)(void); + static rt_err_t (*getchar_bak)(struct at_server *server, char *ch, rt_int32_t timeout); static char endmark_back[AT_END_MARK_LEN]; /* backup server device and getchar function */ @@ -122,7 +128,7 @@ static void server_cli_parser(void) /* setup server device as console device */ server->device = rt_console_get_device(); - server->get_char = console_getchar; + server->get_char = at_server_console_getchar; memset(server->end_mark, 0x00, AT_END_MARK_LEN); server->end_mark[0] = '\r'; diff --git a/components/net/at/src/at_server.c b/components/net/at/src/at_server.c index 31f1bec96f..81d00951f5 100644 --- a/components/net/at/src/at_server.c +++ b/components/net/at/src/at_server.c @@ -167,6 +167,79 @@ void rt_at_server_print_all_cmd(void) } } +/** + * Send data to AT Client by uart device. + * + * @param server current AT server object + * @param buf send data buffer + * @param size send fixed data size + * + * @return >0: send data size + * =0: send failed + */ +rt_size_t at_server_send(at_server_t server, const char *buf, rt_size_t size) +{ + RT_ASSERT(buf); + + if (server == RT_NULL) + { + LOG_E("input AT Server object is NULL, please create or get AT Server object!"); + return 0; + } + + return rt_device_write(server->device, 0, buf, size); +} + +/** + * AT Server receive fixed-length data. + * + * @param client current AT Server object + * @param buf receive data buffer + * @param size receive fixed data size + * @param timeout receive data timeout (ms) + * + * @note this function can only be used in execution function of AT commands + * + * @return >0: receive data size + * =0: receive failed + */ +rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32_t timeout) +{ + rt_size_t read_idx = 0; + rt_err_t result = RT_EOK; + char ch = 0; + + RT_ASSERT(buf); + + if (server == RT_NULL) + { + LOG_E("input AT Server object is NULL, please create or get AT Server object!"); + return 0; + } + + while (1) + { + if (read_idx < size) + { + /* check get data value */ + result = server->get_char(server, &ch, timeout); + if (result != RT_EOK) + { + LOG_E("AT Server receive failed, uart device get data error."); + return 0; + } + + buf[read_idx++] = ch; + } + else + { + break; + } + } + + return read_idx; +} + at_server_t at_get_server(void) { RT_ASSERT(at_server_local); @@ -339,17 +412,21 @@ static rt_err_t at_cmd_get_name(const char *cmd_buffer, char *cmd_name) return -RT_ERROR; } -static char at_server_gerchar(void) +static rt_err_t at_server_gerchar(at_server_t server, char *ch, rt_int32_t timeout) { - char ch; + rt_err_t result = RT_EOK; - while (rt_device_read(at_server_local->device, 0, &ch, 1) == 0) + while (rt_device_read(at_server_local->device, 0, ch, 1) == 0) { rt_sem_control(at_server_local->rx_notice, RT_IPC_CMD_RESET, RT_NULL); - rt_sem_take(at_server_local->rx_notice, RT_WAITING_FOREVER); + result = rt_sem_take(at_server_local->rx_notice, rt_tick_from_millisecond(timeout)); + if (result != RT_EOK) + { + return result; + } } - return ch; + return result; } static void server_parser(at_server_t server) @@ -365,14 +442,24 @@ static void server_parser(at_server_t server) RT_ASSERT(server); RT_ASSERT(server->status != AT_STATUS_UNINITIALIZED); - while (ESC_KEY != (ch = server->get_char())) + while (1) { + server->get_char(server, &ch, RT_WAITING_FOREVER); + if (ESC_KEY == ch) + { + break; + } + if (server->echo_mode) { if (ch == AT_CMD_CR || (ch == AT_CMD_LF && last_ch != AT_CMD_CR)) { at_server_printf("%c%c", AT_CMD_CR, AT_CMD_LF); } + else if (ch == AT_CMD_LF) + { + // skip the end sign check + } else if (ch == BACKSPACE_KEY || ch == DELECT_KEY) { if (server->cur_recv_len)