diff --git a/components/net/at/at_socket/at_socket.c b/components/net/at/at_socket/at_socket.c index 9575868116..43913498f8 100644 --- a/components/net/at/at_socket/at_socket.c +++ b/components/net/at/at_socket/at_socket.c @@ -513,6 +513,7 @@ static void at_closed_notice_cb(int socket, at_socket_evt_t event, const char *b sock->state = AT_SOCKET_CLOSED; rt_sem_release(sock->recv_notice); } + int at_connect(int socket, const struct sockaddr *name, socklen_t namelen) { struct at_socket *sock; @@ -611,7 +612,13 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f sock->state = AT_SOCKET_CONNECT; } - if (sock->state != AT_SOCKET_CONNECT) + /* socket passively closed, receive function return 0 */ + if (sock->state == AT_SOCKET_CLOSED) + { + result = 0; + goto __exit; + } + else if (sock->state != AT_SOCKET_CONNECT) { LOG_E("received data error, current socket (%d) state (%d) is error.", socket, sock->state); result = -1; @@ -664,7 +671,7 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f else { LOG_D("received data exit, current socket (%d) is closed by remote.", socket); - result = -1; + result = 0; goto __exit; } } @@ -672,17 +679,19 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f __exit: - if (result < 0) + if (recv_len > 0) { - at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); + result = recv_len; + at_do_event_changes(sock, AT_EVENT_RECV, RT_FALSE); + + if (!rt_slist_isempty(&sock->recvpkt_list)) + { + at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE); + } } else { - result = recv_len; - if (recv_len) - { - at_do_event_changes(sock, AT_EVENT_RECV, RT_FALSE); - } + at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); } return result; diff --git a/components/net/at/include/at.h b/components/net/at/include/at.h index 2601562019..4bb378583a 100644 --- a/components/net/at/include/at.h +++ b/components/net/at/include/at.h @@ -32,8 +32,8 @@ extern "C" { #endif -#define AT_SW_VERSION "1.0.1" -#define AT_SW_VERSION_NUM 0x10000 +#define AT_SW_VERSION "1.1.0" +#define AT_SW_VERSION_NUM 0x10100 #define DBG_ENABLE #define DBG_SECTION_NAME "AT" @@ -231,7 +231,7 @@ int at_client_obj_wait_connect(at_client_t client, rt_uint32_t timeout); /* AT client send or receive data */ rt_size_t at_client_obj_send(at_client_t client, const char *buf, rt_size_t size); -rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size); +rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_int32_t timeout); /* set AT client a line end sign */ void at_obj_set_end_sign(at_client_t client, char ch); @@ -263,7 +263,7 @@ int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const #define at_exec_cmd(resp, ...) at_obj_exec_cmd(at_client_get_first(), resp, __VA_ARGS__) #define at_client_wait_connect(timeout) at_client_obj_wait_connect(at_client_get_first(), timeout) #define at_client_send(buf, size) at_client_obj_send(at_client_get_first(), buf, size) -#define at_client_recv(buf, size) at_client_obj_recv(at_client_get_first(), buf, size) +#define at_client_recv(buf, size, timeout) at_client_obj_recv(at_client_get_first(), buf, size, timeout) #define at_set_end_sign(ch) at_obj_set_end_sign(at_client_get_first(), ch) #define at_set_urc_table(urc_table, table_sz) at_obj_set_urc_table(at_client_get_first(), urc_table, table_sz) diff --git a/components/net/at/src/at_client.c b/components/net/at/src/at_client.c index 6e9e3541fc..847a8b2eb7 100644 --- a/components/net/at/src/at_client.c +++ b/components/net/at/src/at_client.c @@ -425,17 +425,22 @@ rt_size_t at_client_obj_send(at_client_t client, const char *buf, rt_size_t size return rt_device_write(client->device, 0, buf, size); } -static char at_client_getchar(at_client_t client) +static rt_err_t at_client_getchar(at_client_t client, char *ch, rt_int32_t timeout) { - char ch; + rt_err_t result = RT_EOK; - while (rt_device_read(client->device, 0, &ch, 1) == 0) + while (rt_device_read(client->device, 0, ch, 1) == 0) { rt_sem_control(client->rx_notice, RT_IPC_CMD_RESET, RT_NULL); - rt_sem_take(client->rx_notice, RT_WAITING_FOREVER); + + result = rt_sem_take(client->rx_notice, rt_tick_from_millisecond(timeout)); + if (result != RT_EOK) + { + return result; + } } - return ch; + return RT_EOK; } /** @@ -444,15 +449,17 @@ static char at_client_getchar(at_client_t client) * @param client current AT client 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 URC data * * @return >0: receive data size * =0: receive failed */ -rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size) +rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_int32_t timeout) { rt_size_t read_idx = 0; + rt_err_t result = RT_EOK; char ch; RT_ASSERT(buf); @@ -467,7 +474,12 @@ rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size) { if (read_idx < size) { - ch = at_client_getchar(client); + result = at_client_getchar(client, &ch, timeout); + if (result != RT_EOK) + { + LOG_E("AT Client receive failed, uart device get data error(%d)", result); + return 0; + } buf[read_idx++] = ch; } @@ -610,7 +622,7 @@ static int at_recv_readline(at_client_t client) while (1) { - ch = at_client_getchar(client); + at_client_getchar(client, &ch, RT_WAITING_FOREVER); if (read_len < client->recv_bufsz) {