summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryangpengya <[email protected]>2024-02-19 00:07:05 +0800
committerGitHub <[email protected]>2024-02-18 11:07:05 -0500
commita8d5a645f2e26af67c8fe94e2c7f1726ae05cca7 (patch)
tree8d164ecdf22a47bfe126710b577fff774ba1fe7b
parent02eaf76d7b9c6ee0f968465cd8837fe5dfa58a83 (diff)
[components][at] 优化AT组件,并解决内存泄露
1.优化at server endmark判断,支持自动识别'\r''\n'"\r\n"。 2.优化at_recvfrom,修复大数据量时sem多次释放造成的接收错误。 3.修复at组件中可能存在的内存泄露。 4.优化部分代码逻辑,减少冗余代码。
-rw-r--r--components/net/at/Kconfig19
-rw-r--r--components/net/at/at_socket/at_socket.c228
-rw-r--r--components/net/at/include/at.h15
-rw-r--r--components/net/at/src/at_cli.c16
-rw-r--r--components/net/at/src/at_client.c57
-rw-r--r--components/net/at/src/at_server.c158
-rw-r--r--components/net/sal/impl/af_inet_at.c3
7 files changed, 165 insertions, 331 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,106 +999,68 @@ 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)
{
- LOG_D("AT socket (%d) receive timeout (%d)!", socket, timeout);
- errno = EAGAIN;
- result = -1;
- goto __exit;
+ /* socket passively closed, receive function return 0 */
+ result = 0;
+ break;
}
- 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
+ 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))
{
- /* we have no data to receive but are woken up,
- which means the socket have been closed. */
- errno = EIO;
- result = -1;
- goto __exit;
+ at_do_event_clean(sock, AT_EVENT_RECV);
}
+ errno = 0;
+ result = recv_len;
+ break;
}
- }
-__exit:
+ if (flags & MSG_DONTWAIT)
+ {
+ errno = EAGAIN;
+ result = -1;
+ break;
+ }
- if (sock != RT_NULL)
- {
- if (recv_len > 0)
+ /* set AT socket receive timeout */
+ if (sock->recv_timeout == 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);
- }
+ timeout = RT_WAITING_FOREVER;
}
else
{
- at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
+ 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;
+ break;
}
}
+ if (result <= 0)
+ {
+ 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)
+ }
+ else
+ {
+ if (rt_sem_take(client->rx_notice, rt_tick_from_millisecond(timeout)) != RT_EOK)
break;
-
- continue;
}
-
- 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,14 +887,14 @@ __exit:
rt_sem_delete(client->resp_notice);
}
- if (client->device)
+ if (client->recv_line_buf)
{
- rt_device_close(client->device);
+ rt_free(client->recv_line_buf);
}
- if (client->recv_line_buf)
+ if (client->send_buf)
{
- rt_free(client->recv_line_buf);
+ rt_free(client->send_buf);
}
rt_memset(client, 0x00, sizeof(struct at_client));
@@ -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))
- {
- 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->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)
{
- 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 */