1
0
Эх сурвалжийг харах

Merge pull request #1807 from Lawlieta/at

fix at receive data issue
Bernard Xiong 6 жил өмнө
parent
commit
3a5d9e73f1

+ 18 - 9
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,18 +679,20 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f
 
 __exit:
 
-    if (result < 0)
-    {
-        at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
-    }
-    else
+    if (recv_len > 0)
     {
         result = recv_len;
-        if (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_FALSE);
+            at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE);
         }
     }
+    else
+    {
+        at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
+    }
 
     return result;
 }

+ 4 - 4
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)
 

+ 20 - 8
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)
         {