From a8d5a645f2e26af67c8fe94e2c7f1726ae05cca7 Mon Sep 17 00:00:00 2001 From: yangpengya <53293497+yangpengya@users.noreply.github.com> Date: Mon, 19 Feb 2024 00:07:05 +0800 Subject: [PATCH] =?UTF-8?q?[components][at]=20=E4=BC=98=E5=8C=96AT?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E5=B9=B6=E8=A7=A3=E5=86=B3=E5=86=85?= =?UTF-8?q?=E5=AD=98=E6=B3=84=E9=9C=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.优化at server endmark判断,支持自动识别'\r''\n'"\r\n"。 2.优化at_recvfrom,修复大数据量时sem多次释放造成的接收错误。 3.修复at组件中可能存在的内存泄露。 4.优化部分代码逻辑,减少冗余代码。 --- components/net/at/Kconfig | 19 -- components/net/at/at_socket/at_socket.c | 238 ++++++++---------------- components/net/at/include/at.h | 15 -- components/net/at/src/at_cli.c | 16 +- components/net/at/src/at_client.c | 61 +++--- components/net/at/src/at_server.c | 158 +++++++--------- components/net/sal/impl/af_inet_at.c | 3 + 7 files changed, 172 insertions(+), 338 deletions(-) diff --git a/components/net/at/Kconfig b/components/net/at/Kconfig index 4b0dd6735c..de5e11f1f6 100644 --- a/components/net/at/Kconfig +++ b/components/net/at/Kconfig @@ -26,25 +26,6 @@ if RT_USING_AT int "The maximum length of server commands buffer" default 256 - choice - prompt "The commands new line sign" - help - This end mark can used for AT server determine the end of commands , - it can choose "\r", "\n" or "\r\n" - - default AT_CMD_END_MARK_CRLF - - config AT_CMD_END_MARK_CRLF - bool "\\r\\n" - - config AT_CMD_END_MARK_CR - bool "\\r" - - config AT_CMD_END_MARK_LF - bool "\\n" - - endchoice - endif config AT_USING_CLIENT diff --git a/components/net/at/at_socket/at_socket.c b/components/net/at/at_socket/at_socket.c index 67f51459b9..2beed442bb 100644 --- a/components/net/at/at_socket/at_socket.c +++ b/components/net/at/at_socket/at_socket.c @@ -717,16 +717,13 @@ static int ipaddr_to_ipstr(const struct sockaddr *sockaddr, char *ipstr) } #ifdef AT_USING_SOCKET_SERVER -static int (*store_at_socket_temporary)(struct at_device *device, enum at_socket_type type); static void at_connect_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz) { RT_ASSERT(buff); RT_ASSERT(sock == RT_NULL); RT_ASSERT(event == AT_SOCKET_EVT_CONNECTED); - extern struct netdev *netdev_default; - struct netdev *netdev = RT_NULL; - struct at_device *device = RT_NULL; + int new_socket; struct at_socket *new_sock = RT_NULL; rt_base_t level; rt_slist_t *node = RT_NULL; @@ -734,51 +731,17 @@ static void at_connect_notice_cb(struct at_socket *sock, at_socket_evt_t event, char *socket_info = RT_NULL; int base_socket = 0; - if (netdev_default && netdev_is_up(netdev_default) && - netdev_family_get(netdev_default) == AF_AT) - { - netdev = netdev_default; - } - else - { - /* get network interface device by protocol family AF_AT */ - netdev = netdev_get_by_family(AF_AT); - if (netdev == RT_NULL) - { - return; - } - } - - device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name); - if (device == RT_NULL) - { - return; - } - /* avoid use bottom driver to alloc "socket" */ - store_at_socket_temporary = device->class->socket_ops->at_socket; - device->class->socket_ops->at_socket = RT_NULL; - new_sock = alloc_socket_by_device(device, AT_SOCKET_TCP); - if (new_sock == RT_NULL) + new_socket = at_socket(AF_AT, SOCK_STREAM, 0); + if (new_socket == -1) { return; } - new_sock->type = AT_SOCKET_TCP; + new_sock = at_get_socket(new_socket); new_sock->state = AT_SOCKET_CONNECT; - - /* set AT socket receive data callback function */ - new_sock->ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb); - new_sock->ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb); - new_sock->ops->at_set_event_cb(AT_SOCKET_EVT_CONNECTED, at_connect_notice_cb); - device->class->socket_ops->at_socket = store_at_socket_temporary; - - /* put incoming "socket" to the listen socket receiver packet list */ sscanf(buff, "SOCKET:%d", &base_socket); LOG_D("ACCEPT BASE SOCKET: %d", base_socket); new_sock->user_data = (void *)base_socket; - socket_info = rt_malloc(AT_SOCKET_INFO_LEN); - rt_memset(socket_info, 0, AT_SOCKET_INFO_LEN); - rt_sprintf(socket_info, "SOCKET:%d", new_sock->socket); /* find out the listen socket */ level = rt_hw_interrupt_disable(); @@ -793,16 +756,23 @@ static void at_connect_notice_cb(struct at_socket *sock, at_socket_evt_t event, } rt_hw_interrupt_enable(level); - if(at_sock == RT_NULL) + if (at_sock == RT_NULL) { + at_closesocket(new_socket); return; } + /* put incoming "socket" to the listen socket receiver packet list */ + socket_info = rt_malloc(AT_SOCKET_INFO_LEN); + rt_memset(socket_info, 0, AT_SOCKET_INFO_LEN); + rt_sprintf(socket_info, "SOCKET:%d", new_sock->socket); + /* wakeup the "accept" function */ rt_mutex_take(at_sock->recv_lock, RT_WAITING_FOREVER); if (at_recvpkt_put(&(at_sock->recvpkt_list), socket_info, AT_SOCKET_INFO_LEN) != RT_EOK) { - rt_free((void *)buff); + at_closesocket(new_socket); + rt_free(socket_info); rt_mutex_release(at_sock->recv_lock); return; } @@ -866,8 +836,7 @@ int at_listen(int socket, int backlog) sock = at_get_socket(socket); if (sock == RT_NULL) { - result = -1; - goto __exit; + return -1; } if (sock->state != AT_SOCKET_OPEN) @@ -890,10 +859,7 @@ __exit: if (result < 0) { - if (sock != RT_NULL) - { - at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); - } + at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); } return result; @@ -911,8 +877,7 @@ int at_connect(int socket, const struct sockaddr *name, socklen_t namelen) sock = at_get_socket(socket); if (sock == RT_NULL) { - result = -1; - goto __exit; + return -1; } if (sock->state != AT_SOCKET_OPEN) @@ -938,13 +903,9 @@ __exit: if (result < 0) { - if (sock != RT_NULL) - { - at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); - } + at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); } - - if (sock) + else { at_do_event_changes(sock, AT_EVENT_SEND, RT_TRUE); } @@ -966,8 +927,7 @@ int at_accept(int socket, struct sockaddr *name, socklen_t *namelen) sock = at_get_socket(socket); if (sock == RT_NULL) { - result = -1; - goto __exit; + return -1; } if (sock->state != AT_SOCKET_LISTEN) @@ -990,16 +950,11 @@ int at_accept(int socket, struct sockaddr *name, socklen_t *namelen) rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER); at_recvpkt_get(&(sock->recvpkt_list), (char *) &receive_buff, AT_SOCKET_INFO_LEN); rt_mutex_release(sock->recv_lock); + at_do_event_changes(sock, AT_EVENT_RECV, RT_FALSE); } sscanf(&receive_buff[0], "SOCKET:%d", &new_socket); new_sock = at_get_socket(new_socket); - if (sock == RT_NULL) - { - result = -1; - goto __exit; - } - new_sock->state = AT_SOCKET_CONNECT; ip4_addr_set_any(&remote_addr); ipaddr_port_to_socketaddr(name, &remote_addr, &remote_port); LOG_D("Accept: [socket :%d, base_socket:%d]", new_socket, (int)new_sock->user_data); @@ -1007,10 +962,7 @@ int at_accept(int socket, struct sockaddr *name, socklen_t *namelen) __exit: if (result < 0) { - if (sock != RT_NULL) - { - at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); - } + at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); } return new_sock->socket; @@ -1025,15 +977,14 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f if (mem == RT_NULL || len == 0) { - LOG_E("AT recvfrom input data or length error!"); - return -1; + /* if the requested number of bytes to receive from a stream socket was 0. */ + return 0; } sock = at_get_socket(socket); if (sock == RT_NULL) { - result = -1; - goto __exit; + return -1; } /* if the socket type is UDP, need to connect socket first */ @@ -1048,104 +999,66 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0) { - result = -1; - goto __exit; + at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); + /* socket shutdown */ + return 0; } sock->state = AT_SOCKET_CONNECT; } - /* receive packet list last transmission of remaining data */ - rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER); - if((recv_len = at_recvpkt_get(&(sock->recvpkt_list), (char *)mem, len)) > 0) - { - rt_mutex_release(sock->recv_lock); - goto __exit; - } - rt_mutex_release(sock->recv_lock); - - /* socket passively closed, receive function return 0 */ - if (sock->state == AT_SOCKET_CLOSED) - { - result = 0; - goto __exit; - } - else if (sock->state != AT_SOCKET_CONNECT && sock->state != AT_SOCKET_OPEN) - { - LOG_E("received data error, current socket (%d) state (%d) is error.", socket, sock->state); - result = -1; - goto __exit; - } - - /* non-blocking sockets receive data */ - if (flags & MSG_DONTWAIT) - { - goto __exit; - } - - /* set AT socket receive timeout */ - if ((timeout = sock->recv_timeout) == 0) - { - timeout = RT_WAITING_FOREVER; - } - else - { - timeout = rt_tick_from_millisecond(timeout); - } - while (1) { - /* wait the receive semaphore */ - if (rt_sem_take(sock->recv_notice, timeout) < 0) + if (sock->state == AT_SOCKET_CLOSED) + { + /* socket passively closed, receive function return 0 */ + result = 0; + break; + } + + rt_sem_control(sock->recv_notice, RT_IPC_CMD_RESET, RT_NULL); + /* receive packet list last transmission of remaining data */ + rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER); + recv_len = at_recvpkt_get(&(sock->recvpkt_list), (char *)mem, len); + rt_mutex_release(sock->recv_lock); + if (recv_len > 0) + { + if (rt_slist_isempty(&sock->recvpkt_list)) + { + at_do_event_clean(sock, AT_EVENT_RECV); + } + errno = 0; + result = recv_len; + break; + } + + if (flags & MSG_DONTWAIT) + { + errno = EAGAIN; + result = -1; + break; + } + + /* set AT socket receive timeout */ + if (sock->recv_timeout == 0) + { + timeout = RT_WAITING_FOREVER; + } + else + { + timeout = rt_tick_from_millisecond(sock->recv_timeout); + } + if (rt_sem_take(sock->recv_notice, timeout) != RT_EOK) { LOG_D("AT socket (%d) receive timeout (%d)!", socket, timeout); errno = EAGAIN; result = -1; - goto __exit; - } - else - { - - /* get receive buffer to receiver ring buffer */ - rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER); - recv_len = at_recvpkt_get(&(sock->recvpkt_list), (char *) mem, len); - rt_mutex_release(sock->recv_lock); - if (recv_len > 0) - { - break; - } - else - { - /* we have no data to receive but are woken up, - which means the socket have been closed. */ - errno = EIO; - result = -1; - goto __exit; - } + break; } } -__exit: - - if (sock != RT_NULL) + if (result <= 0) { - if (recv_len > 0) - { - result = recv_len; - at_do_event_changes(sock, AT_EVENT_RECV, RT_FALSE); - errno = 0; - if (!rt_slist_isempty(&sock->recvpkt_list)) - { - at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE); - } - else - { - at_do_event_clean(sock, AT_EVENT_RECV); - } - } - else - { - at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); - } + at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); } return result; @@ -1164,15 +1077,13 @@ int at_sendto(int socket, const void *data, size_t size, int flags, const struct if (data == RT_NULL || size == 0) { LOG_E("AT sendto input data or size error!"); - result = -1; - goto __exit; + return -1; } sock = at_get_socket(socket); if (sock == RT_NULL) { - result = -1; - goto __exit; + return -1; } switch (sock->type) @@ -1232,10 +1143,7 @@ __exit: if (result < 0) { - if (sock != RT_NULL) - { - at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); - } + at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); } else { diff --git a/components/net/at/include/at.h b/components/net/at/include/at.h index fa6ccca503..2d9e7e51db 100644 --- a/components/net/at/include/at.h +++ b/components/net/at/include/at.h @@ -22,20 +22,6 @@ extern "C" { #define AT_SW_VERSION "1.3.1" #define AT_CMD_NAME_LEN 16 -#define AT_END_MARK_LEN 4 - -#ifndef AT_CMD_MAX_LEN -#define AT_CMD_MAX_LEN 128 -#endif - -/* the server AT commands new line sign */ -#if defined(AT_CMD_END_MARK_CRLF) -#define AT_CMD_END_MARK "\r\n" -#elif defined(AT_CMD_END_MARK_CR) -#define AT_CMD_END_MARK "\r" -#elif defined(AT_CMD_END_MARK_LF) -#define AT_CMD_END_MARK "\n" -#endif #ifndef AT_SERVER_RECV_BUFF_LEN #define AT_SERVER_RECV_BUFF_LEN 256 @@ -104,7 +90,6 @@ struct at_server char recv_buffer[AT_SERVER_RECV_BUFF_LEN]; rt_size_t cur_recv_len; rt_sem_t rx_notice; - char end_mark[AT_END_MARK_LEN]; rt_thread_t parser; void (*parser_entry)(struct at_server *server); diff --git a/components/net/at/src/at_cli.c b/components/net/at/src/at_cli.c index fb26d0bf14..dea1dbb894 100644 --- a/components/net/at/src/at_cli.c +++ b/components/net/at/src/at_cli.c @@ -114,7 +114,6 @@ static void server_cli_parser(void) rt_base_t level; static rt_device_t device_bak; 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 */ { @@ -123,16 +122,10 @@ static void server_cli_parser(void) device_bak = server->device; getchar_bak = server->get_char; - rt_memset(endmark_back, 0x00, AT_END_MARK_LEN); - rt_memcpy(endmark_back, server->end_mark, strlen(server->end_mark)); - /* setup server device as console device */ server->device = rt_console_get_device(); server->get_char = at_server_console_getchar; - rt_memset(server->end_mark, 0x00, AT_END_MARK_LEN); - server->end_mark[0] = '\r'; - rt_hw_interrupt_enable(level); } @@ -154,9 +147,6 @@ static void server_cli_parser(void) server->device = device_bak; server->get_char = getchar_bak; - rt_memset(server->end_mark, 0x00, AT_END_MARK_LEN); - rt_memcpy(server->end_mark, endmark_back, strlen(endmark_back)); - rt_hw_interrupt_enable(level); } } @@ -223,6 +213,9 @@ static void client_cli_parser(at_client_t client) client->status = AT_STATUS_CLI; } + rt_sem_init(&client_rx_notice, "cli_r", 0, RT_IPC_FLAG_FIFO); + client_rx_fifo = rt_ringbuffer_create(AT_CLI_FIFO_SIZE); + /* backup client device RX indicate */ { level = rt_hw_interrupt_disable(); @@ -231,9 +224,6 @@ static void client_cli_parser(at_client_t client) rt_hw_interrupt_enable(level); } - rt_sem_init(&client_rx_notice, "cli_r", 0, RT_IPC_FLAG_FIFO); - client_rx_fifo = rt_ringbuffer_create(AT_CLI_FIFO_SIZE); - at_client = rt_thread_create("at_cli", at_client_entry, RT_NULL, 512, 8, 8); if (client_rx_fifo && at_client) { diff --git a/components/net/at/src/at_client.c b/components/net/at/src/at_client.c index 06e23c7a38..5d665fee66 100644 --- a/components/net/at/src/at_client.c +++ b/components/net/at/src/at_client.c @@ -146,7 +146,6 @@ at_response_t at_resp_set_info(at_response_t resp, rt_size_t buf_size, rt_size_t const char *at_resp_get_line(at_response_t resp, rt_size_t resp_line) { char *resp_buf = resp->buf; - char *resp_line_buf = RT_NULL; rt_size_t line_num = 1; RT_ASSERT(resp); @@ -161,9 +160,7 @@ const char *at_resp_get_line(at_response_t resp, rt_size_t resp_line) { if (resp_line == line_num) { - resp_line_buf = resp_buf; - - return resp_line_buf; + return resp_buf; } resp_buf += strlen(resp_buf) + 1; @@ -184,7 +181,6 @@ const char *at_resp_get_line(at_response_t resp, rt_size_t resp_line) const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword) { char *resp_buf = resp->buf; - char *resp_line_buf = RT_NULL; rt_size_t line_num = 1; RT_ASSERT(resp); @@ -194,9 +190,7 @@ const char *at_resp_get_line_by_kw(at_response_t resp, const char *keyword) { if (strstr(resp_buf, keyword)) { - resp_line_buf = resp_buf; - - return resp_line_buf; + return resp_buf; } resp_buf += strlen(resp_buf) + 1; @@ -332,17 +326,14 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr LOG_W("execute command (%.*s) timeout (%d ticks)!", client->last_cmd_len, client->send_buf, resp->timeout); client->resp_status = AT_RESP_TIMEOUT; result = -RT_ETIMEOUT; - goto __exit; } - if (client->resp_status != AT_RESP_OK) + else if (client->resp_status != AT_RESP_OK) { LOG_E("execute command (%.*s) failed!", client->last_cmd_len, client->send_buf); result = -RT_ERROR; - goto __exit; } } -__exit: client->resp = RT_NULL; rt_mutex_release(client->lock); @@ -401,9 +392,7 @@ int at_client_obj_wait_connect(at_client_t client, rt_uint32_t timeout) resp->line_counts = 0; at_utils_send(client->device, 0, "AT\r\n", 4); - if (rt_sem_take(client->resp_notice, resp->timeout) != RT_EOK) - continue; - else + if (rt_sem_take(client->resp_notice, resp->timeout) == RT_EOK) break; } @@ -494,25 +483,23 @@ rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_i return 0; } - while (1) + while (size) { rt_size_t read_len; rt_sem_control(client->rx_notice, RT_IPC_CMD_RESET, RT_NULL); read_len = rt_device_read(client->device, 0, buf + len, size); - if(read_len > 0) + if (read_len > 0) { len += read_len; size -= read_len; - if(size == 0) - break; - - continue; } - - if(rt_sem_take(client->rx_notice, rt_tick_from_millisecond(timeout)) != RT_EOK) - break; + else + { + if (rt_sem_take(client->rx_notice, rt_tick_from_millisecond(timeout)) != RT_EOK) + break; + } } #ifdef AT_PRINT_RAW_CMD @@ -676,7 +663,6 @@ static const struct at_urc *get_urc_obj(at_client_t client) static int at_recv_readline(at_client_t client) { - rt_size_t read_len = 0; char ch = 0, last_ch = 0; rt_bool_t is_full = RT_FALSE; @@ -687,10 +673,9 @@ static int at_recv_readline(at_client_t client) { at_client_getchar(client, &ch, RT_WAITING_FOREVER); - if (read_len < client->recv_bufsz) + if (client->recv_line_len < client->recv_bufsz) { - client->recv_line_buf[read_len++] = ch; - client->recv_line_len = read_len; + client->recv_line_buf[client->recv_line_len++] = ch; } else { @@ -714,10 +699,10 @@ static int at_recv_readline(at_client_t client) } #ifdef AT_PRINT_RAW_CMD - at_print_raw_cmd("recvline", client->recv_line_buf, read_len); + at_print_raw_cmd("recvline", client->recv_line_buf, client->recv_line_len); #endif - return read_len; + return client->recv_line_len; } static void client_parser(at_client_t client) @@ -882,7 +867,6 @@ static int at_client_para_init(at_client_t client) if (client->parser == RT_NULL) { result = -RT_ENOMEM; - goto __exit; } __exit: @@ -903,16 +887,16 @@ __exit: rt_sem_delete(client->resp_notice); } - if (client->device) - { - rt_device_close(client->device); - } - if (client->recv_line_buf) { rt_free(client->recv_line_buf); } + if (client->send_buf) + { + rt_free(client->send_buf); + } + rt_memset(client, 0x00, sizeof(struct at_client)); } else @@ -928,6 +912,7 @@ __exit: * * @param dev_name AT client device name * @param recv_bufsz the maximum number of receive buffer length + * @param send_bufsz the maximum number of send command length * * @return 0 : initialize success * -1 : initialize failed @@ -974,6 +959,7 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu { RT_ASSERT(client->device->type == RT_Device_Class_Char); + rt_device_set_rx_indicate(client->device, at_client_rx_ind); /* using DMA mode first */ open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX); /* using interrupt mode when DMA mode not supported */ @@ -982,14 +968,11 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); } RT_ASSERT(open_result == RT_EOK); - - rt_device_set_rx_indicate(client->device, at_client_rx_ind); } else { LOG_E("AT client initialize failed! Not find the device(%s).", dev_name); result = -RT_ERROR; - goto __exit; } __exit: diff --git a/components/net/at/src/at_server.c b/components/net/at/src/at_server.c index 563fe39235..de67001e17 100644 --- a/components/net/at/src/at_server.c +++ b/components/net/at/src/at_server.c @@ -311,70 +311,59 @@ static rt_err_t at_check_args(const char *args, const char *args_format) return RT_EOK; } -static rt_err_t at_cmd_process(at_cmd_t cmd, const char *cmd_args) +static at_result_t at_cmd_process(at_cmd_t cmd, const char *cmd_args) { - at_result_t result = AT_RESULT_OK; - RT_ASSERT(cmd); RT_ASSERT(cmd_args); - if (cmd_args[0] == AT_CMD_EQUAL_MARK && cmd_args[1] == AT_CMD_QUESTION_MARK && cmd_args[2] == AT_CMD_CR) + /* AT+TEST=? */ + if (cmd_args[0] == AT_CMD_EQUAL_MARK && cmd_args[1] == AT_CMD_QUESTION_MARK) { if (cmd->test == RT_NULL) { - at_server_print_result(AT_RESULT_CMD_ERR); - return -RT_ERROR; + return AT_RESULT_CMD_ERR; } - result = cmd->test(); - at_server_print_result(result); + return cmd->test(); } - else if (cmd_args[0] == AT_CMD_QUESTION_MARK && cmd_args[1] == AT_CMD_CR) + /* AT+TEST? */ + else if (cmd_args[0] == AT_CMD_QUESTION_MARK) { if (cmd->query == RT_NULL) { - at_server_print_result(AT_RESULT_CMD_ERR); - return -RT_ERROR; + return AT_RESULT_CMD_ERR; } - result = cmd->query(); - at_server_print_result(result); + return cmd->query(); } + /* AT+TEST=1 or ATE1 */ else if (cmd_args[0] == AT_CMD_EQUAL_MARK - || (cmd_args[0] >= AT_CMD_CHAR_0 && cmd_args[0] <= AT_CMD_CHAR_9 && cmd_args[1] == AT_CMD_CR)) + || (cmd_args[0] >= AT_CMD_CHAR_0 && cmd_args[0] <= AT_CMD_CHAR_9 && (cmd_args[1] == AT_CMD_CR || cmd_args[1] == AT_CMD_LF))) { if (cmd->setup == RT_NULL) { - at_server_print_result(AT_RESULT_CMD_ERR); - return -RT_ERROR; + return AT_RESULT_CMD_ERR; } if(at_check_args(cmd_args, cmd->args_expr) < 0) { - at_server_print_result(AT_RESULT_CHECK_FAILE); - return -RT_ERROR; + return AT_RESULT_CHECK_FAILE; } - result = cmd->setup(cmd_args); - at_server_print_result(result); + return cmd->setup(cmd_args); } - else if (cmd_args[0] == AT_CMD_CR) + /* AT+TEST */ + else if (cmd_args[0] == AT_CMD_CR || cmd_args[0] == AT_CMD_LF) { if (cmd->exec == RT_NULL) { - at_server_print_result(AT_RESULT_CMD_ERR); - return -RT_ERROR; + return AT_RESULT_CMD_ERR; } - result = cmd->exec(); - at_server_print_result(result); - } - else - { - return -RT_ERROR; + return cmd->exec(); } - return RT_EOK; + return AT_RESULT_FAILE; } static at_cmd_t at_find_cmd(const char *cmd) @@ -400,10 +389,10 @@ static rt_err_t at_cmd_get_name(const char *cmd_buffer, char *cmd_name) RT_ASSERT(cmd_name); RT_ASSERT(cmd_buffer); - for (i = 0; i < strlen(cmd_buffer); i++) + for (i = 0; i < strlen(cmd_buffer) && i < AT_CMD_NAME_LEN; i++) { if (*(cmd_buffer + i) == AT_CMD_QUESTION_MARK || *(cmd_buffer + i) == AT_CMD_EQUAL_MARK - || *(cmd_buffer + i) == AT_CMD_CR + || *(cmd_buffer + i) == AT_CMD_CR || *(cmd_buffer + i) == AT_CMD_LF || (*(cmd_buffer + i) >= AT_CMD_CHAR_0 && *(cmd_buffer + i) <= AT_CMD_CHAR_9)) { cmd_name_len = i; @@ -443,6 +432,7 @@ static void server_parser(at_server_t server) char cur_cmd_name[AT_CMD_NAME_LEN] = { 0 }; at_cmd_t cur_cmd = RT_NULL; char *cur_cmd_args = RT_NULL, ch, last_ch; + at_result_t result; RT_ASSERT(server); RT_ASSERT(server->status != AT_STATUS_UNINITIALIZED); @@ -455,66 +445,54 @@ static void server_parser(at_server_t server) break; } - if (server->echo_mode) + if (ch == BACKSPACE_KEY || ch == DELECT_KEY) { - if (ch == AT_CMD_CR || (ch == AT_CMD_LF && last_ch != AT_CMD_CR)) + if (server->cur_recv_len) + server->cur_recv_len--; + if (server->echo_mode) + at_server_printf("\b \b"); + } + else if (ch == AT_CMD_LF && last_ch == AT_CMD_CR) + { + /* skip '\n' if we get "\r\n" */ + } + else + { + if (server->cur_recv_len < sizeof(server->recv_buffer) - 1) { - 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) + server->recv_buffer[server->cur_recv_len++] = ch; + if (ch == AT_CMD_CR || ch == AT_CMD_LF) { - server->recv_buffer[--server->cur_recv_len] = 0; - at_server_printf("\b \b"); - } + if (server->echo_mode) + at_server_printf("%c%c", AT_CMD_CR, AT_CMD_LF); + server->recv_buffer[server->cur_recv_len] = '\0'; + result = AT_RESULT_FAILE; + if (at_cmd_get_name(server->recv_buffer, cur_cmd_name) == RT_EOK) + { + cur_cmd = at_find_cmd(cur_cmd_name); + if (cur_cmd) + { + cur_cmd_args = server->recv_buffer + strlen(cur_cmd_name); + result = at_cmd_process(cur_cmd, cur_cmd_args); + } + } - continue; - } - else if (ch == AT_CMD_NULL) - { - continue; + at_server_print_result(result); + server->cur_recv_len = 0; + } + else + { + if (server->echo_mode) + at_server_printf("%c", ch); + } + last_ch = ch; } else { - at_server_printf("%c", ch); + /* server receive buffer overflow!!! */ + server->cur_recv_len = 0; } } - - server->recv_buffer[server->cur_recv_len++] = ch; - last_ch = ch; - - if(!strstr(server->recv_buffer, server->end_mark)) - { - continue; - } - - if (at_cmd_get_name(server->recv_buffer, cur_cmd_name) < 0) - { - at_server_print_result(AT_RESULT_CMD_ERR); - goto __retry; - } - - cur_cmd = at_find_cmd(cur_cmd_name); - if (!cur_cmd) - { - at_server_print_result(AT_RESULT_CMD_ERR); - goto __retry; - } - - cur_cmd_args = server->recv_buffer + strlen(cur_cmd_name); - if (at_cmd_process(cur_cmd, cur_cmd_args) < 0) - { - goto __retry; - } - -__retry: - rt_memset(server->recv_buffer, 0x00, AT_SERVER_RECV_BUFF_LEN); - server->cur_recv_len = 0; } } @@ -586,6 +564,7 @@ int at_server_init(void) { RT_ASSERT(at_server_local->device->type == RT_Device_Class_Char); + rt_device_set_rx_indicate(at_server_local->device, at_rx_ind); /* using DMA mode first */ open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX); /* using interrupt mode when DMA mode not supported */ @@ -594,8 +573,6 @@ int at_server_init(void) open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); } RT_ASSERT(open_result == RT_EOK); - - rt_device_set_rx_indicate(at_server_local->device, at_rx_ind); } else { @@ -605,7 +582,6 @@ int at_server_init(void) } at_server_local->get_char = at_server_getchar; - rt_memcpy(at_server_local->end_mark, AT_CMD_END_MARK, sizeof(AT_CMD_END_MARK)); at_server_local->parser_entry = server_parser; at_server_local->parser = rt_thread_create("at_svr", @@ -617,7 +593,6 @@ int at_server_init(void) if (at_server_local->parser == RT_NULL) { result = -RT_ENOMEM; - goto __exit; } __exit: @@ -633,7 +608,16 @@ __exit: { if (at_server_local) { + if (at_server_local->rx_notice) + { + rt_sem_delete(at_server_local->rx_notice); + } + if (at_server_local->device) + { + rt_device_close(at_server_local->device); + } rt_free(at_server_local); + at_server_local = RT_NULL; } LOG_E("RT-Thread AT server (V%s) initialize failed(%d).", AT_SW_VERSION, result); diff --git a/components/net/sal/impl/af_inet_at.c b/components/net/sal/impl/af_inet_at.c index 4e94d1e96c..0d1ea310fa 100644 --- a/components/net/sal/impl/af_inet_at.c +++ b/components/net/sal/impl/af_inet_at.c @@ -81,6 +81,8 @@ static const struct sal_socket_ops at_socket_ops = NULL, #endif at_sendto, + NULL, + NULL, at_recvfrom, at_getsockopt, at_setsockopt, @@ -88,6 +90,7 @@ static const struct sal_socket_ops at_socket_ops = NULL, NULL, NULL, + NULL, #ifdef SAL_USING_POSIX at_poll, #endif /* SAL_USING_POSIX */