Explorar o código

[net][at] update AT component V1.3.0, change as follows:

- AT Socket feature supports multi-client connections;
- Fix `send data error, current socket (0) state (0) is error` issue when the socket is closed;
- Improve dirty data processing when AT device hard reset;
- Improve `at_obj_set_urc_table()` fucntion, Support for setting multiple URC tables;
- Improve RAW data print format;
chenyong %!s(int64=6) %!d(string=hai) anos
pai
achega
b5ad12573f

+ 1 - 1
components/net/at/Kconfig

@@ -83,7 +83,7 @@ if RT_USING_AT
 
     config AT_SW_VERSION_NUM
         hex
-        default 0x10200
+        default 0x10300
         help
             sfotware module version number
 

+ 259 - 153
components/net/at/at_socket/at_socket.c

@@ -15,11 +15,15 @@
 #include <sys/time.h>
 
 #include <at_socket.h>
+#include <at_device.h>
 
 #ifdef SAL_USING_POSIX
 #include <dfs_poll.h>
 #endif
 
+#include <arpa/inet.h>
+#include <netdev.h>
+
 #define LOG_TAG              "at.skt"
 #include <at_log.h>
 
@@ -32,10 +36,6 @@
         ((unsigned char *)&addr)[2], \
         ((unsigned char *)&addr)[3]
 
-#if !defined(AT_DEVICE_SOCKETS_NUM) || defined(AT_DEVICE_NOT_SELECTED)
-#error The AT socket device is not selected, please select it through the env menuconfig.
-#endif
-
 /* The maximum number of sockets structure */
 #ifndef AT_SOCKETS_NUM
 #define AT_SOCKETS_NUM       AT_DEVICE_SOCKETS_NUM
@@ -47,31 +47,41 @@ typedef enum {
     AT_EVENT_ERROR,
 } at_event_t;
 
-/* the global array of available sockets */
-static struct at_socket sockets[AT_SOCKETS_NUM] = { 0 };
-/* AT device socket options */
-static struct at_device_ops *at_dev_ops = RT_NULL;
+
+/* the global of sockets list */
+static rt_slist_t _socket_list = RT_SLIST_OBJECT_INIT(_socket_list);
 
 struct at_socket *at_get_socket(int socket)
 {
-    if (socket < 0 || socket >= AT_SOCKETS_NUM)
-    {
-        return RT_NULL;
-    }
+    rt_base_t level;
+    size_t list_num = 0;
+    rt_slist_t *node = RT_NULL;
+    struct at_socket *at_sock = RT_NULL;
+
+    level = rt_hw_interrupt_disable();
 
-    /* check socket structure valid or not */
-    if (sockets[socket].magic != AT_SOCKET_MAGIC)
+    rt_slist_for_each(node, &_socket_list)
     {
-        return RT_NULL;
-    }
+        if (socket == (list_num++))
+        {
+            at_sock = rt_slist_entry(node, struct at_socket, list);
+            if (at_sock && at_sock->magic == AT_SOCKET_MAGIC)
+            {
+                rt_hw_interrupt_enable(level);
+                return at_sock;
+            }
+        }
+    } 
+    
+    rt_hw_interrupt_enable(level);
 
-    return &sockets[socket];
+    return RT_NULL;
 }
 
 /* get a block to the AT socket receive list*/
 static size_t at_recvpkt_put(rt_slist_t *rlist, const char *ptr, size_t length)
 {
-    at_recv_pkt_t pkt;
+    at_recv_pkt_t pkt = RT_NULL;
 
     pkt = (at_recv_pkt_t) rt_calloc(1, sizeof(struct at_recv_pkt));
     if (pkt == RT_NULL)
@@ -92,11 +102,13 @@ static size_t at_recvpkt_put(rt_slist_t *rlist, const char *ptr, size_t length)
 /* delete and free all receive buffer list */
 static int at_recvpkt_all_delete(rt_slist_t *rlist)
 {
-    at_recv_pkt_t pkt;
-    rt_slist_t *node;
+    at_recv_pkt_t pkt = RT_NULL;
+    rt_slist_t *node = RT_NULL;
 
-    if(rt_slist_isempty(rlist))
+    if (rt_slist_isempty(rlist))
+    {
         return 0;
+    }
 
     for(node = rt_slist_first(rlist); node; node = rt_slist_next(node))
     {
@@ -105,7 +117,7 @@ static int at_recvpkt_all_delete(rt_slist_t *rlist)
         {
             rt_free(pkt->buff);
         }
-        if(pkt)
+        if (pkt)
         {
             rt_free(pkt);
             pkt = RT_NULL;
@@ -118,14 +130,16 @@ static int at_recvpkt_all_delete(rt_slist_t *rlist)
 /* delete and free specified list block */
 static int at_recvpkt_node_delete(rt_slist_t *rlist, rt_slist_t *node)
 {
-    at_recv_pkt_t pkt;
+    at_recv_pkt_t pkt = RT_NULL;
 
-    if(rt_slist_isempty(rlist))
+    if (rt_slist_isempty(rlist))
+    {
         return 0;
+    }
 
     rt_slist_remove(rlist, node);
 
-    pkt= rt_slist_entry(node, struct at_recv_pkt, list);
+    pkt = rt_slist_entry(node, struct at_recv_pkt, list);
     if (pkt->buff)
     {
         rt_free(pkt->buff);
@@ -139,15 +153,17 @@ static int at_recvpkt_node_delete(rt_slist_t *rlist, rt_slist_t *node)
     return 0;
 }
 
-/* get a block from AT socket receive list */
+/* get a block from AT socket receive buffer list */
 static size_t at_recvpkt_get(rt_slist_t *rlist, char *mem, size_t len)
 {
-    rt_slist_t *node;
-    at_recv_pkt_t pkt;
+    rt_slist_t *node = RT_NULL;
+    at_recv_pkt_t pkt = RT_NULL;
     size_t content_pos = 0, page_pos = 0;
 
-    if(rt_slist_isempty(rlist))
+    if (rt_slist_isempty(rlist))
+    {
         return 0;
+    }
 
     for (node = rt_slist_first(rlist); node; node = rt_slist_next(node))
     {
@@ -191,7 +207,6 @@ static void at_do_event_changes(struct at_socket *sock, at_event_t event, rt_boo
 #ifdef SAL_USING_POSIX
             rt_wqueue_wakeup(&sock->wait_head, (void*) POLLOUT);
 #endif
-
         }
         else if (sock->sendevent)
         {
@@ -208,7 +223,6 @@ static void at_do_event_changes(struct at_socket *sock, at_event_t event, rt_boo
 #ifdef SAL_USING_POSIX
             rt_wqueue_wakeup(&sock->wait_head, (void*) POLLIN);
 #endif
-
         }
         else if (sock->rcvevent)
         {
@@ -225,7 +239,6 @@ static void at_do_event_changes(struct at_socket *sock, at_event_t event, rt_boo
 #ifdef SAL_USING_POSIX
             rt_wqueue_wakeup(&sock->wait_head, (void*) POLLERR);
 #endif
-
         }
         else if (sock->errevent)
         {
@@ -262,20 +275,20 @@ static void at_do_event_clean(struct at_socket *sock, at_event_t event)
     }
 }
 
-static struct at_socket *alloc_socket(void)
+static struct at_socket *alloc_socket_by_device(struct at_device *device)
 {
     static rt_mutex_t at_slock = RT_NULL;
-    char name[RT_NAME_MAX];
-    struct at_socket *sock;
-    int idx;
+    struct at_socket *sock = RT_NULL;
+    char name[RT_NAME_MAX] = {0};
+    int idx = 0;
 
-    if(at_slock == RT_NULL)
+    if (at_slock == RT_NULL)
     {
         /* create AT socket lock */
-        at_slock = rt_mutex_create("at_s", RT_IPC_FLAG_FIFO);
+        at_slock = rt_mutex_create("at_slock", RT_IPC_FLAG_FIFO);
         if (at_slock == RT_NULL)
         {
-            LOG_E("No memory for AT socket lock!");
+            LOG_E("No memory for socket allocation lock!");
             return RT_NULL;
         }
     }
@@ -283,34 +296,58 @@ static struct at_socket *alloc_socket(void)
     rt_mutex_take(at_slock, RT_WAITING_FOREVER);
 
     /* find an empty at socket entry */
-    for (idx = 0; idx < AT_SOCKETS_NUM && sockets[idx].magic; idx++);
+    for (idx = 0; idx < device->class->socket_num && device->sockets[idx].magic; idx++);
 
     /* can't find an empty protocol family entry */
-    if (idx == AT_SOCKETS_NUM)
+    if (idx == device->class->socket_num)
     {
         goto __err;
     }
 
-    sock = &(sockets[idx]);
+    /* add device socket to global socket list */
+    {
+        rt_base_t level;
+
+        level = rt_hw_interrupt_disable();
+
+        rt_slist_init(&(device->sockets[idx].list));
+        rt_slist_append(&_socket_list, &(device->sockets[idx].list));
+
+        rt_hw_interrupt_enable(level);
+    }
+
+    sock = &(device->sockets[idx]);
+    /* the socket descriptor is the number of sockte lists */
+    sock->socket = rt_slist_len(&_socket_list) - 1;
+    /* the socket operations is the specify operations of the device */
+    sock->ops = device->class->socket_ops;
+    /* the user-data is the at device socket descriptor */
+    sock->user_data = (void *) idx;
+    sock->device = (void *) device;
     sock->magic = AT_SOCKET_MAGIC;
-    sock->socket = idx;
     sock->state = AT_SOCKET_NONE;
     sock->rcvevent = RT_NULL;
     sock->sendevent = RT_NULL;
     sock->errevent = RT_NULL;
     rt_slist_init(&sock->recvpkt_list);
+#ifdef SAL_USING_POSIX
+    rt_wqueue_init(&sock->wait_head);
+#endif
 
-    rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_sr", idx);
+    rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_skt", idx);
     /* create AT socket receive mailbox */
     if ((sock->recv_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO)) == RT_NULL)
     {
+        LOG_E("No memory socket receive notic semaphore create.");
         goto __err;
     }
 
-    rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_sr", idx);
+    rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_skt", idx);
     /* create AT socket receive ring buffer lock */
     if((sock->recv_lock = rt_mutex_create(name, RT_IPC_FLAG_FIFO)) == RT_NULL)
     {
+        LOG_E("No memory for socket receive mutex create.");
+        rt_sem_delete(sock->recv_notice);
         goto __err;
     }
 
@@ -322,13 +359,42 @@ __err:
     return RT_NULL;
 }
 
+static struct at_socket *alloc_socket(int domain)
+{
+    extern struct netdev *netdev_default;
+    struct netdev *netdev = RT_NULL;
+    struct at_device *device = RT_NULL;
+
+    if (netdev_default && netdev_is_up(netdev_default))
+    {
+        netdev = netdev_default;
+    }
+    else
+    {
+        /* get network interface device by protocol family */
+        netdev = netdev_get_by_family(domain);
+        if (netdev == RT_NULL)
+        {
+            return RT_NULL;
+        }
+    }
+
+    device = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, netdev->name);
+    if (device == RT_NULL)
+    {
+        return RT_NULL;
+    }
+
+    return alloc_socket_by_device(device);
+}
+
 int at_socket(int domain, int type, int protocol)
 {
-    struct at_socket *sock;
+    struct at_socket *sock = RT_NULL;
     enum at_socket_type socket_type;
 
     /* check socket family protocol */
-    RT_ASSERT(domain == AF_AT||domain == AF_INET);
+    RT_ASSERT(domain == AF_AT || domain == AF_INET);
 
     //TODO check protocol
 
@@ -348,17 +414,13 @@ int at_socket(int domain, int type, int protocol)
     }
 
     /* allocate and initialize a new AT socket */
-    sock = alloc_socket();
-    if(sock == RT_NULL)
+    sock = alloc_socket(domain);
+    if (sock == RT_NULL)
     {
-        LOG_E("Allocate a new AT socket failed!");
-        return RT_NULL;
+        return -1;
     }
     sock->type = socket_type;
-
-#ifdef SAL_USING_POSIX
-    rt_wqueue_init(&sock->wait_head);
-#endif
+    sock->state = AT_SOCKET_OPEN;
 
     return sock->socket;
 }
@@ -380,21 +442,41 @@ static int free_socket(struct at_socket *sock)
         at_recvpkt_all_delete(&sock->recvpkt_list);
     }
 
-    memset(sock, 0x00, sizeof(struct at_socket));
+    /* delect socket from socket list */
+    {
+        rt_base_t level;
+        int list_num = 0;
+        rt_slist_t *node = RT_NULL;
+        struct at_socket *at_sock = RT_NULL;
+
+        level = rt_hw_interrupt_disable();
+
+        rt_slist_for_each(node, &_socket_list)
+        {
+            if (sock->socket == (list_num++))
+            {
+                at_sock = rt_slist_entry(node, struct at_socket, list);
+                if (at_sock)
+                {
+                    rt_slist_remove(&_socket_list, &at_sock->list);
+                    break;
+                }
+            }
+        }
+
+        rt_hw_interrupt_enable(level);
+    }
+
+    rt_memset(sock, 0x00, sizeof(struct at_socket));
 
     return 0;
 }
 
 int at_closesocket(int socket)
 {
-    struct at_socket *sock;
+    struct at_socket *sock = RT_NULL;
     enum at_socket_state last_state;
 
-    if (at_dev_ops == RT_NULL)
-    {
-        return -1;
-    }
-
     /* deal with TCP server actively disconnect */
     rt_thread_delay(rt_tick_from_millisecond(100));
     
@@ -409,9 +491,9 @@ int at_closesocket(int socket)
     /* the rt_at_socket_close is need some time, so change state in advance */
     sock->state = AT_SOCKET_CLOSED;
 
-    if (last_state == AT_SOCKET_CONNECT)
+    if (last_state != AT_SOCKET_CLOSED)
     {
-        if (at_dev_ops->at_closesocket(socket) != 0)
+        if (sock->ops->at_closesocket(sock) != 0)
         {
             free_socket(sock);
             return -1;
@@ -424,12 +506,8 @@ int at_closesocket(int socket)
 
 int at_shutdown(int socket, int how)
 {
-    struct at_socket *sock;
-
-    if (at_dev_ops == RT_NULL)
-    {
-        return -1;
-    }
+    struct at_socket *sock = RT_NULL;
+    enum at_socket_state last_state;
 
     sock = at_get_socket(socket);
     if (sock == RT_NULL)
@@ -437,9 +515,14 @@ int at_shutdown(int socket, int how)
         return -1;
     }
 
-    if (sock->state == AT_SOCKET_CONNECT)
+    last_state = sock->state;
+
+    /* the rt_at_socket_close is need some time, so change state in advance */
+    sock->state = AT_SOCKET_CLOSED;
+
+    if (last_state != AT_SOCKET_CLOSED)
     {
-        if (at_dev_ops->at_closesocket(socket) != 0)
+        if (sock->ops->at_closesocket(sock) != 0)
         {
             free_socket(sock);
             return -1;
@@ -450,17 +533,6 @@ int at_shutdown(int socket, int how)
     return 0;
 }
 
-int at_bind(int socket, const struct sockaddr *name, socklen_t namelen)
-{
-
-    if (at_get_socket(socket) == RT_NULL)
-    {
-        return -1;
-    }
-
-    return 0;
-}
-
 /* get IP address and port by socketaddr structure information */
 static int socketaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *addr, uint16_t *port)
 {
@@ -479,6 +551,59 @@ static int socketaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t
     return 0;
 }
 
+int at_bind(int socket, const struct sockaddr *name, socklen_t namelen)
+{
+    struct at_socket *sock = RT_NULL;
+    struct at_device *device = RT_NULL;
+    ip_addr_t input_ipaddr, local_ipaddr;
+    uint16_t port = 0;
+
+    sock = at_get_socket(socket);
+    if (sock == RT_NULL)
+    {
+        return -1;
+    }
+
+    /* get current device ip address */
+    device = (struct at_device *) sock->device;
+    ip_addr_copy(local_ipaddr, device->netdev->ip_addr);
+
+    /* prase ip address and port from sockaddr structure */
+    socketaddr_to_ipaddr_port(name, &input_ipaddr, &port);
+
+    /* input ip address is different from device ip address */
+    if (ip_addr_cmp(&input_ipaddr, &local_ipaddr) == 0)
+    {   
+        struct at_socket *new_sock = RT_NULL;
+        struct at_device *new_device = RT_NULL;
+        enum at_socket_type type = sock->type;
+
+        /* close old socket */
+        if (at_closesocket(socket) < 0)
+        {
+            return -1;
+        }
+        
+        extern struct at_device *at_device_get_by_ipaddr(ip_addr_t *ip_addr);
+        new_device = at_device_get_by_ipaddr(&input_ipaddr);
+        if (new_device == RT_NULL)
+        {
+            return -1;
+        }
+
+        /* allocate new socket */
+        new_sock = alloc_socket_by_device(new_device);
+        if (new_sock == RT_NULL)
+        {
+            return -1;
+        }
+        new_sock->type = type;
+        new_sock->state = AT_SOCKET_OPEN;
+    }
+
+    return 0;
+}
+
 /* ipaddr structure change to IP address */
 static int ipaddr_to_ipstr(const struct sockaddr *sockaddr, char *ipstr)
 {
@@ -490,17 +615,16 @@ static int ipaddr_to_ipstr(const struct sockaddr *sockaddr, char *ipstr)
     return 0;
 }
 
-static void at_recv_notice_cb(int socket, at_socket_evt_t event, const char *buff, size_t bfsz)
+static void at_recv_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz)
 {
-    struct at_socket *sock;
-
     RT_ASSERT(buff);
-    RT_ASSERT(bfsz);
     RT_ASSERT(event == AT_SOCKET_EVT_RECV);
-
-    sock = at_get_socket(socket);
-    if (sock == RT_NULL)
-        return ;
+    
+    /* check the socket object status */
+    if (sock->magic != AT_SOCKET_MAGIC)
+    {
+        return;
+    }
 
     /* put receive buffer to receiver packet list */
     rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER);
@@ -512,15 +636,16 @@ static void at_recv_notice_cb(int socket, at_socket_evt_t event, const char *buf
     at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE);
 }
 
-static void at_closed_notice_cb(int socket, at_socket_evt_t event, const char *buff, size_t bfsz)
+static void at_closed_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz)
 {
-    struct at_socket *sock;
-
     RT_ASSERT(event == AT_SOCKET_EVT_CLOSED);
 
-    if ((sock = at_get_socket(socket)) == RT_NULL)
-        return ;
-
+    /* check the socket object status */
+    if (sock->magic != AT_SOCKET_MAGIC)
+    {
+        return;
+    }
+    
     at_do_event_changes(sock, AT_EVENT_RECV, RT_TRUE);
     at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE);
 
@@ -530,17 +655,12 @@ static void at_closed_notice_cb(int socket, at_socket_evt_t event, const char *b
 
 int at_connect(int socket, const struct sockaddr *name, socklen_t namelen)
 {
-    struct at_socket *sock;
+    struct at_socket *sock = RT_NULL;
     ip_addr_t remote_addr;
-    uint16_t remote_port;
+    uint16_t remote_port = 0;
     char ipstr[16] = { 0 };
     int result = 0;
 
-    if (at_dev_ops == RT_NULL)
-    {
-        return -1;
-    }
-
     sock = at_get_socket(socket);
     if (sock == RT_NULL)
     {
@@ -548,7 +668,7 @@ int at_connect(int socket, const struct sockaddr *name, socklen_t namelen)
         goto __exit;
     }
 
-    if (sock->state != AT_SOCKET_NONE)
+    if (sock->state != AT_SOCKET_OPEN)
     {
         LOG_E("Socket(%d) connect state is %d.", sock->socket, sock->state);
         result = -1;
@@ -559,7 +679,7 @@ int at_connect(int socket, const struct sockaddr *name, socklen_t namelen)
     socketaddr_to_ipaddr_port(name, &remote_addr, &remote_port);
     ipaddr_to_ipstr(name, ipstr);
 
-    if (at_dev_ops->at_connect(socket, ipstr, remote_port, sock->type, RT_TRUE) < 0)
+    if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0)
     {
         result = -1;
         goto __exit;
@@ -568,8 +688,8 @@ int at_connect(int socket, const struct sockaddr *name, socklen_t namelen)
     sock->state = AT_SOCKET_CONNECT;
 
     /* set AT socket receive data callback function */
-    at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
-    at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
+    sock->ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
+    sock->ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
 
 __exit:
 
@@ -591,9 +711,8 @@ __exit:
 
 int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
 {
-    struct at_socket *sock;
-    int timeout;
-    int result = 0;
+    struct at_socket *sock = RT_NULL;
+    int timeout, result = 0;
     size_t recv_len = 0;
 
     if (mem == RT_NULL || len == 0)
@@ -602,11 +721,6 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f
         return -1;
     }
 
-    if (at_dev_ops == RT_NULL)
-    {
-        return -1;
-    }
-
     sock = at_get_socket(socket);
     if (sock == RT_NULL)
     {
@@ -615,24 +729,24 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f
     }
 
     /* if the socket type is UDP, nead to connect socket first */
-    if (from && sock->type == AT_SOCKET_UDP && sock->state == AT_SOCKET_NONE)
+    if (from && sock->type == AT_SOCKET_UDP && sock->state == AT_SOCKET_OPEN)
     {
         ip_addr_t remote_addr;
-        uint16_t remote_port;
+        uint16_t remote_port = 0;
         char ipstr[16] = { 0 };
 
         socketaddr_to_ipaddr_port(from, &remote_addr, &remote_port);
         ipaddr_to_ipstr(from, ipstr);
 
-        if (at_dev_ops->at_connect(socket, ipstr, remote_port, sock->type, RT_TRUE) < 0)
+        if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0)
         {
             result = -1;
             goto __exit;
         }
         sock->state = AT_SOCKET_CONNECT;
         /* set AT socket receive data callback function */
-        at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
-        at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
+        sock->ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
+        sock->ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
     }
 
     /* receive packet list last transmission of remaining data */
@@ -650,7 +764,7 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f
         result = 0;
         goto __exit;
     }
-    else if (sock->state != AT_SOCKET_CONNECT)
+    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;
@@ -664,7 +778,7 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f
     }
 
     /* set AT socket receive timeout */
-    if((timeout = sock->recv_timeout) == 0)
+    if ((timeout = sock->recv_timeout) == 0)
     {
         timeout = RT_WAITING_FOREVER;
     }
@@ -739,15 +853,9 @@ int at_recv(int s, void *mem, size_t len, int flags)
 
 int at_sendto(int socket, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
 {
-    struct at_socket *sock;
+    struct at_socket *sock = RT_NULL;
     int len, result = 0;
 
-    if (at_dev_ops == RT_NULL)
-    {
-        result = -1;
-        goto __exit;
-    }
-
     if (data == RT_NULL || size == 0)
     {
         LOG_E("AT sendto input data or size error!");
@@ -765,14 +873,19 @@ int at_sendto(int socket, const void *data, size_t size, int flags, const struct
     switch (sock->type)
     {
     case AT_SOCKET_TCP:
-        if (sock->state != AT_SOCKET_CONNECT)
+        if (sock->state == AT_SOCKET_CLOSED)
+        {
+            result = 0;
+            goto __exit;
+        }
+        else if (sock->state != AT_SOCKET_CONNECT && sock->state != AT_SOCKET_OPEN)
         {
             LOG_E("send data error, current socket (%d) state (%d) is error.", socket, sock->state);
             result = -1;
             goto __exit;
         }
 
-        if ((len = at_dev_ops->at_send(sock->socket, (const char *) data, size, sock->type)) < 0)
+        if ((len = sock->ops->at_send(sock, (const char *) data, size, sock->type)) < 0)
         {
             result = -1;
             goto __exit;
@@ -780,27 +893,27 @@ int at_sendto(int socket, const void *data, size_t size, int flags, const struct
         break;
 
     case AT_SOCKET_UDP:
-        if (to && sock->state == AT_SOCKET_NONE)
+        if (to && sock->state == AT_SOCKET_OPEN)
         {
             ip_addr_t remote_addr;
-            uint16_t remote_port;
+            uint16_t remote_port = 0;
             char ipstr[16] = { 0 };
 
             socketaddr_to_ipaddr_port(to, &remote_addr, &remote_port);
             ipaddr_to_ipstr(to, ipstr);
 
-            if (at_dev_ops->at_connect(socket, ipstr, remote_port, sock->type, RT_TRUE) < 0)
+            if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0)
             {
                 result = -1;
                 goto __exit;
             }
             sock->state = AT_SOCKET_CONNECT;
             /* set AT socket receive data callback function */
-            at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
-            at_dev_ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
+            sock->ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb);
+            sock->ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb);
         }
 
-        if ((len = at_dev_ops->at_send(sock->socket, (char *) data, size, sock->type)) < 0)
+        if ((len = sock->ops->at_send(sock, (char *) data, size, sock->type)) < 0)
         {
             result = -1;
             goto __exit;
@@ -973,6 +1086,7 @@ static uint32_t ipstr_to_u32(char *ipstr)
 
 struct hostent *at_gethostbyname(const char *name)
 {
+    struct at_device *device = RT_NULL;
     ip_addr_t addr;
     char ipstr[16] = { 0 };
     /* buffer variables for at_gethostbyname() */
@@ -989,7 +1103,8 @@ struct hostent *at_gethostbyname(const char *name)
         return RT_NULL;
     }
 
-    if (at_dev_ops == RT_NULL)
+    device = at_device_get_first_initialized();
+    if (device == RT_NULL)
     {
         return RT_NULL;
     }
@@ -998,7 +1113,7 @@ struct hostent *at_gethostbyname(const char *name)
 
     if (idx < strlen(name))
     {
-        if (at_dev_ops->at_domain_resolve(name, ipstr) < 0)
+        if (device->class->socket_ops->at_domain_resolve(name, ipstr) < 0)
         {
             return RT_NULL;
         }
@@ -1042,6 +1157,7 @@ int at_getaddrinfo(const char *nodename, const char *servname,
     size_t total_size = 0;
     size_t namelen = 0;
     int ai_family = 0;
+    struct at_device *device = RT_NULL;
 
     if (res == RT_NULL)
     {
@@ -1049,7 +1165,8 @@ int at_getaddrinfo(const char *nodename, const char *servname,
     }
     *res = RT_NULL;
 
-    if (at_dev_ops == RT_NULL)
+    device = at_device_get_first_initialized();
+    if (device == RT_NULL)
     {
         return EAI_FAIL;
     }
@@ -1103,7 +1220,7 @@ int at_getaddrinfo(const char *nodename, const char *servname,
 
             if(idx < strlen(nodename))
             {
-                if (at_dev_ops->at_domain_resolve((char *) nodename, ip_str) != 0)
+                if (device->class->socket_ops->at_domain_resolve((char *) nodename, ip_str) != 0)
                 {
                     return EAI_FAIL;
                 }
@@ -1201,15 +1318,4 @@ void at_freeaddrinfo(struct addrinfo *ai)
     }
 }
 
-void at_socket_device_register(const struct at_device_ops *ops)
-{
-    RT_ASSERT(ops);
-    RT_ASSERT(ops->at_connect);
-    RT_ASSERT(ops->at_closesocket);
-    RT_ASSERT(ops->at_send);
-    RT_ASSERT(ops->at_domain_resolve);
-    RT_ASSERT(ops->at_set_event_cb);
-    at_dev_ops = (struct at_device_ops *) ops;
-}
-
 #endif /* AT_USING_SOCKET */

+ 17 - 8
components/net/at/at_socket/at_socket.h

@@ -36,6 +36,7 @@ extern "C" {
 enum at_socket_state
 {
     AT_SOCKET_NONE,
+    AT_SOCKET_OPEN,
     AT_SOCKET_LISTEN,
     AT_SOCKET_CONNECT,
     AT_SOCKET_CLOSED
@@ -54,18 +55,19 @@ typedef enum
     AT_SOCKET_EVT_CLOSED,
 } at_socket_evt_t;
 
-typedef void (*at_evt_cb_t)(int socket, at_socket_evt_t event, const char *buff, size_t bfsz);
-
 struct at_socket;
+
+typedef void (*at_evt_cb_t)(struct at_socket *socket, at_socket_evt_t event, const char *buff, size_t bfsz);
+
 /* A callback prototype to inform about events for AT socket */
 typedef void (* at_socket_callback)(struct at_socket *conn, int event, uint16_t len);
 
-/* AT device socket options function */
-struct at_device_ops
+/* AT socket operations function */
+struct at_socket_ops
 {
-    int (*at_connect)(int socket, char *ip, int32_t port, enum at_socket_type type, rt_bool_t is_client);
-    int (*at_closesocket)(int socket);
-    int (*at_send)(int socket, const char *buff, size_t bfsz, enum at_socket_type type);
+    int (*at_connect)(struct at_socket *socket, char *ip, int32_t port, enum at_socket_type type, rt_bool_t is_client);
+    int (*at_closesocket)(struct at_socket *socket);
+    int (*at_send)(struct at_socket *socket, const char *buff, size_t bfsz, enum at_socket_type type);
     int (*at_domain_resolve)(const char *name, char ip[16]);
     void (*at_set_event_cb)(at_socket_evt_t event, at_evt_cb_t cb);
 };
@@ -86,10 +88,14 @@ struct at_socket
     uint32_t magic;
 
     int socket;
+    /* device releated information for the socket */
+    void *device;
     /* type of the AT socket (TCP, UDP or RAW) */
     enum at_socket_type type;
     /* current state of the AT socket */
     enum at_socket_state state;
+    /* sockets operations */
+    const struct at_socket_ops *ops;
     /* receive semaphore, received data release semaphore */
     rt_sem_t recv_notice;
     rt_mutex_t recv_lock;
@@ -111,6 +117,10 @@ struct at_socket
 #ifdef SAL_USING_POSIX
     rt_wqueue_t wait_head;
 #endif
+    rt_slist_t list;
+
+    /* user-specific data */
+    void *user_data;
 };
 
 int at_socket(int domain, int type, int protocol);
@@ -129,7 +139,6 @@ int at_getaddrinfo(const char *nodename, const char *servname, const struct addr
 void at_freeaddrinfo(struct addrinfo *ai);
 
 struct at_socket *at_get_socket(int socket);
-void at_socket_device_register(const struct at_device_ops *ops);
 
 #ifndef RT_USING_SAL
 

+ 22 - 8
components/net/at/include/at.h

@@ -18,7 +18,7 @@
 extern "C" {
 #endif
 
-#define AT_SW_VERSION                  "1.2.0"
+#define AT_SW_VERSION                  "1.3.0"
 
 #define AT_CMD_NAME_LEN                16
 #define AT_END_MARK_LEN                4
@@ -124,9 +124,11 @@ struct at_response
 {
     /* response buffer */
     char *buf;
-    /* the maximum response buffer size */
+    /* the maximum response buffer size, it set by `at_create_resp()` function */
     rt_size_t buf_size;
-    /* the number of setting response lines
+    /* the length of current response buffer */
+    rt_size_t buf_len;
+    /* the number of setting response lines, it set by `at_create_resp()` function
      * == 0: the response data will auto return when received 'OK' or 'ERROR'
      * != 0: the response data will return when received setting lines number data */
     rt_size_t line_num;
@@ -138,15 +140,24 @@ struct at_response
 
 typedef struct at_response *at_response_t;
 
+struct at_client;
+
 /* URC(Unsolicited Result Code) object, such as: 'RING', 'READY' request by AT server */
 struct at_urc
 {
     const char *cmd_prefix;
     const char *cmd_suffix;
-    void (*func)(const char *data, rt_size_t size);
+    void (*func)(struct at_client *client, const char *data, rt_size_t size);
 };
 typedef struct at_urc *at_urc_t;
 
+struct at_urc_table
+{
+    size_t urc_size;
+    const struct at_urc *urc;
+};
+typedef struct at_urc *at_urc_table_t;
+
 struct at_client
 {
     rt_device_t device;
@@ -154,9 +165,12 @@ struct at_client
     at_status_t status;
     char end_sign;
 
-    char *recv_buffer;
+    /* the current received one line data buffer */
+    char *recv_line_buf;
+    /* The length of the currently received one line data */
+    rt_size_t recv_line_len;
+    /* The maximum supported receive data length */
     rt_size_t recv_bufsz;
-    rt_size_t cur_recv_len;
     rt_sem_t rx_notice;
     rt_mutex_t lock;
 
@@ -164,7 +178,7 @@ struct at_client
     rt_sem_t resp_notice;
     at_resp_status_t resp_status;
 
-    const struct at_urc *urc_table;
+    struct at_urc_table *urc_table;
     rt_size_t urc_table_size;
 
     rt_thread_t parser;
@@ -207,7 +221,7 @@ rt_size_t at_client_obj_recv(at_client_t client, char *buf, rt_size_t size, rt_i
 void at_obj_set_end_sign(at_client_t client, char ch);
 
 /* Set URC(Unsolicited Result Code) table */
-void at_obj_set_urc_table(at_client_t client, const struct at_urc * table, rt_size_t size);
+int at_obj_set_urc_table(at_client_t client, const struct at_urc * table, rt_size_t size);
 
 /* AT client send commands to AT server and waiter response */
 int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr, ...);

+ 105 - 52
components/net/at/src/at_client.c

@@ -301,13 +301,18 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr
     client->resp_status = AT_RESP_OK;
     client->resp = resp;
 
+    if (resp != RT_NULL)
+    {
+        resp->buf_len = 0;
+        resp->line_counts = 0;
+    }
+
     va_start(args, cmd_expr);
     at_vprintfln(client->device, cmd_expr, args);
     va_end(args);
 
     if (resp != RT_NULL)
     {
-        resp->line_counts = 0;
         if (rt_sem_take(client->resp_notice, resp->timeout) != RT_EOK)
         {
             cmd = at_get_last_cmd(&cmd_size);
@@ -348,17 +353,18 @@ int at_client_obj_wait_connect(at_client_t client, rt_uint32_t timeout)
     rt_err_t result = RT_EOK;
     at_response_t resp = RT_NULL;
     rt_tick_t start_time = 0;
+    char *client_name = client->device->parent.name;
 
     if (client == RT_NULL)
     {
-        LOG_E("input AT Client object is NULL, please create or get AT Client object!");
+        LOG_E("input AT client object is NULL, please create or get AT Client object!");
         return -RT_ERROR;
     }
 
-    resp = at_create_resp(16, 0, rt_tick_from_millisecond(500));
+    resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
     if (resp == RT_NULL)
     {
-        LOG_E("No memory for response object!");
+        LOG_E("no memory for AT client(%s) response object.", client_name);
         return -RT_ENOMEM;
     }
 
@@ -372,12 +378,13 @@ int at_client_obj_wait_connect(at_client_t client, rt_uint32_t timeout)
         /* Check whether it is timeout */
         if (rt_tick_get() - start_time > rt_tick_from_millisecond(timeout))
         {
-            LOG_E("wait connect timeout (%d millisecond)!", timeout);
+            LOG_E("wait AT client(%s) connect timeout(%d tick).", client_name, timeout);
             result = -RT_ETIMEOUT;
             break;
         }
 
         /* Check whether it is already connected */
+        resp->buf_len = 0;
         resp->line_counts = 0;
         rt_device_write(client->device, 0, "AT\r\n", 4);
 
@@ -417,7 +424,7 @@ rt_size_t at_client_obj_send(at_client_t client, const char *buf, rt_size_t size
     }
 
 #ifdef AT_PRINT_RAW_CMD
-    at_print_raw_cmd("send", buf, size);
+    at_print_raw_cmd("sendline", buf, size);
 #endif
 
     return rt_device_write(client->device, 0, buf, size);
@@ -518,14 +525,14 @@ void at_obj_set_end_sign(at_client_t client, char ch)
  * @param table URC table
  * @param size table size
  */
-void at_obj_set_urc_table(at_client_t client, const struct at_urc *urc_table, rt_size_t table_sz)
+int at_obj_set_urc_table(at_client_t client, const struct at_urc *urc_table, rt_size_t table_sz)
 {
     rt_size_t idx;
 
     if (client == RT_NULL)
     {
         LOG_E("input AT Client object is NULL, please create or get AT Client object!");
-        return;
+        return -RT_ERROR;
     }
 
     for (idx = 0; idx < table_sz; idx++)
@@ -534,8 +541,47 @@ void at_obj_set_urc_table(at_client_t client, const struct at_urc *urc_table, rt
         RT_ASSERT(urc_table[idx].cmd_suffix);
     }
 
-    client->urc_table = urc_table;
-    client->urc_table_size = table_sz;
+    if (client->urc_table_size == 0)
+    {
+        client->urc_table = (struct at_urc_table *) rt_calloc(1, sizeof(struct at_urc_table));
+        if (client->urc_table == RT_NULL)
+        {
+            return -RT_ENOMEM;
+        }
+
+        client->urc_table[0].urc = urc_table;
+        client->urc_table[0].urc_size = table_sz;
+        client->urc_table_size++;
+    }
+    else
+    {
+        struct at_urc_table *old_urc_table = RT_NULL;
+        size_t old_table_size = client->urc_table_size * sizeof(struct at_urc_table);
+
+        old_urc_table = (struct at_urc_table *) rt_malloc(old_table_size);
+        if (old_urc_table == RT_NULL)
+        {
+            return -RT_ENOMEM;
+        }
+        rt_memcpy(old_urc_table, client->urc_table, old_table_size);
+
+        /* realloc urc table space */
+        client->urc_table = (struct at_urc_table *) rt_realloc(client->urc_table,
+                old_table_size + sizeof(struct at_urc_table));
+        if (client->urc_table == RT_NULL)
+        {
+            rt_free(old_urc_table);
+            return -RT_ENOMEM;
+        }
+        rt_memcpy(client->urc_table, old_urc_table, old_table_size);
+        client->urc_table[client->urc_table_size].urc = urc_table;
+        client->urc_table[client->urc_table_size].urc_size = table_sz;
+        client->urc_table_size++;
+        
+        rt_free(old_urc_table);
+    }
+
+    return RT_EOK;
 }
 
 /**
@@ -579,30 +625,38 @@ at_client_t at_client_get_first(void)
 
 static const struct at_urc *get_urc_obj(at_client_t client)
 {
-    rt_size_t i, prefix_len, suffix_len;
-    rt_size_t buf_sz;
+    rt_size_t i, j, prefix_len, suffix_len;
+    rt_size_t bufsz;
     char *buffer = RT_NULL;
+    const struct at_urc *urc = RT_NULL;
+    struct at_urc_table *urc_table = RT_NULL;
 
     if (client->urc_table == RT_NULL)
     {
         return RT_NULL;
     }
 
-    buffer = client->recv_buffer;
-    buf_sz = client->cur_recv_len;
+    buffer = client->recv_line_buf;
+    bufsz = client->recv_line_len;
 
     for (i = 0; i < client->urc_table_size; i++)
     {
-        prefix_len = strlen(client->urc_table[i].cmd_prefix);
-        suffix_len = strlen(client->urc_table[i].cmd_suffix);
-        if (buf_sz < prefix_len + suffix_len)
+        for (j = 0; j < client->urc_table[i].urc_size; j++)
         {
-            continue;
-        }
-        if ((prefix_len ? !strncmp(buffer, client->urc_table[i].cmd_prefix, prefix_len) : 1)
-                && (suffix_len ? !strncmp(buffer + buf_sz - suffix_len, client->urc_table[i].cmd_suffix, suffix_len) : 1))
-        {
-            return &client->urc_table[i];
+            urc_table = client->urc_table + i;
+            urc = urc_table->urc + j;
+
+            prefix_len = rt_strlen(urc->cmd_prefix);
+            suffix_len = rt_strlen(urc->cmd_suffix);
+            if (bufsz < prefix_len + suffix_len)
+            {
+                continue;
+            }
+            if ((prefix_len ? !rt_strncmp(buffer, urc->cmd_prefix, prefix_len) : 1)
+                    && (suffix_len ? !rt_strncmp(buffer + bufsz - suffix_len, urc->cmd_suffix, suffix_len) : 1))
+            {
+                return urc;
+            }
         }
     }
 
@@ -615,8 +669,8 @@ static int at_recv_readline(at_client_t client)
     char ch = 0, last_ch = 0;
     rt_bool_t is_full = RT_FALSE;
 
-    memset(client->recv_buffer, 0x00, client->recv_bufsz);
-    client->cur_recv_len = 0;
+    rt_memset(client->recv_line_buf, 0x00, client->recv_bufsz);
+    client->recv_line_len = 0;
 
     while (1)
     {
@@ -624,8 +678,8 @@ static int at_recv_readline(at_client_t client)
 
         if (read_len < client->recv_bufsz)
         {
-            client->recv_buffer[read_len++] = ch;
-            client->cur_recv_len = read_len;
+            client->recv_line_buf[read_len++] = ch;
+            client->recv_line_len = read_len;
         }
         else
         {
@@ -639,8 +693,8 @@ static int at_recv_readline(at_client_t client)
             if (is_full)
             {
                 LOG_E("read line failed. The line data length is out of buffer size(%d)!", client->recv_bufsz);
-                memset(client->recv_buffer, 0x00, client->recv_bufsz);
-                client->cur_recv_len = 0;
+                rt_memset(client->recv_line_buf, 0x00, client->recv_bufsz);
+                client->recv_line_len = 0;
                 return -RT_EFULL;
             }
             break;
@@ -649,7 +703,7 @@ static int at_recv_readline(at_client_t client)
     }
 
 #ifdef AT_PRINT_RAW_CMD
-    at_print_raw_cmd("recvline", client->recv_buffer, read_len);
+    at_print_raw_cmd("recvline", client->recv_line_buf, read_len);
 #endif
 
     return read_len;
@@ -657,9 +711,7 @@ static int at_recv_readline(at_client_t client)
 
 static void client_parser(at_client_t client)
 {
-    int resp_buf_len = 0;
     const struct at_urc *urc;
-    rt_size_t line_counts = 0;
 
     while(1)
     {
@@ -670,39 +722,42 @@ static void client_parser(at_client_t client)
                 /* current receive is request, try to execute related operations */
                 if (urc->func != RT_NULL)
                 {
-                    urc->func(client->recv_buffer, client->cur_recv_len);
+                    urc->func(client, client->recv_line_buf, client->recv_line_len);
                 }
             }
             else if (client->resp != RT_NULL)
             {
+                at_response_t resp = client->resp;
+
                 /* current receive is response */
-                client->recv_buffer[client->cur_recv_len - 1] = '\0';
-                if (resp_buf_len + client->cur_recv_len < client->resp->buf_size)
+                client->recv_line_buf[client->recv_line_len - 1] = '\0';
+                if (resp->buf_len + client->recv_line_len < resp->buf_size)
                 {
                     /* copy response lines, separated by '\0' */
-                    memcpy(client->resp->buf + resp_buf_len, client->recv_buffer, client->cur_recv_len);
-                    resp_buf_len += client->cur_recv_len;
+                    rt_memcpy(resp->buf + resp->buf_len, client->recv_line_buf, client->recv_line_len);
 
-                    line_counts++;
+                    /* update the current response information */
+                    resp->buf_len += client->recv_line_len;
+                    resp->line_counts++;
                 }
                 else
                 {
                     client->resp_status = AT_RESP_BUFF_FULL;
-                    LOG_E("Read response buffer failed. The Response buffer size is out of buffer size(%d)!", client->resp->buf_size);
+                    LOG_E("Read response buffer failed. The Response buffer size is out of buffer size(%d)!", resp->buf_size);
                 }
                 /* check response result */
-                if (memcmp(client->recv_buffer, AT_RESP_END_OK, strlen(AT_RESP_END_OK)) == 0
-                        && client->resp->line_num == 0)
+                if (rt_memcmp(client->recv_line_buf, AT_RESP_END_OK, rt_strlen(AT_RESP_END_OK)) == 0
+                        && resp->line_num == 0)
                 {
                     /* get the end data by response result, return response state END_OK. */
                     client->resp_status = AT_RESP_OK;
                 }
-                else if (strstr(client->recv_buffer, AT_RESP_END_ERROR)
-                        || (memcmp(client->recv_buffer, AT_RESP_END_FAIL, strlen(AT_RESP_END_FAIL)) == 0))
+                else if (rt_strstr(client->recv_line_buf, AT_RESP_END_ERROR)
+                        || (rt_memcmp(client->recv_line_buf, AT_RESP_END_FAIL, rt_strlen(AT_RESP_END_FAIL)) == 0))
                 {
                     client->resp_status = AT_RESP_ERROR;
                 }
-                else if (line_counts == client->resp->line_num && client->resp->line_num)
+                else if (resp->line_counts == resp->line_num && resp->line_num)
                 {
                     /* get the end data by response line, return response state END_OK.*/
                     client->resp_status = AT_RESP_OK;
@@ -711,15 +766,13 @@ static void client_parser(at_client_t client)
                 {
                     continue;
                 }
-                client->resp->line_counts = line_counts;
 
                 client->resp = RT_NULL;
                 rt_sem_release(client->resp_notice);
-                resp_buf_len = 0, line_counts = 0;
             }
             else
             {
-//                log_d("unrecognized line: %.*s", client->cur_recv_len, client->recv_buffer);
+//                log_d("unrecognized line: %.*s", client->recv_line_len, client->recv_line_buf);
             }
         }
     }
@@ -754,9 +807,9 @@ static int at_client_para_init(at_client_t client)
 
     client->status = AT_STATUS_UNINITIALIZED;
 
-    client->cur_recv_len = 0;
-    client->recv_buffer = (char *) rt_calloc(1, client->recv_bufsz);
-    if (client->recv_buffer == RT_NULL)
+    client->recv_line_len = 0;
+    client->recv_line_buf = (char *) rt_calloc(1, client->recv_bufsz);
+    if (client->recv_line_buf == RT_NULL)
     {
         LOG_E("AT client initialize failed! No memory for receive buffer.");
         result = -RT_ENOMEM;
@@ -829,9 +882,9 @@ __exit:
             rt_device_close(client->device);
         }
 
-        if (client->recv_buffer)
+        if (client->recv_line_buf)
         {
-            rt_free(client->recv_buffer);
+            rt_free(client->recv_line_buf);
         }
 
         rt_memset(client, 0x00, sizeof(struct at_client));

+ 1 - 1
components/net/at/src/at_utils.c

@@ -70,7 +70,7 @@ rt_size_t at_vprintf(rt_device_t device, const char *format, va_list args)
     last_cmd_len = vsnprintf(send_buf, sizeof(send_buf), format, args);
 
 #ifdef AT_PRINT_RAW_CMD
-    at_print_raw_cmd("send", send_buf, last_cmd_len);
+    at_print_raw_cmd("sendline", send_buf, last_cmd_len);
 #endif
 
     return rt_device_write(device, 0, send_buf, last_cmd_len);