|
@@ -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 */
|