977 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			977 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/****************************************************************************
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
							 | 
						||
| 
								 | 
							
								be copied by any method or incorporated into another program without
							 | 
						||
| 
								 | 
							
								the express written consent of Aerospace C.Power. This Information or any portion
							 | 
						||
| 
								 | 
							
								thereof remains the property of Aerospace C.Power. The Information contained herein
							 | 
						||
| 
								 | 
							
								is believed to be accurate and Aerospace C.Power assumes no responsibility or
							 | 
						||
| 
								 | 
							
								liability for its use in any way and conveys no license or title under
							 | 
						||
| 
								 | 
							
								any patent or copyright and makes no representation or warranty that this
							 | 
						||
| 
								 | 
							
								Information is free from patent or copyright infringement.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								****************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* os_shim header files */
							 | 
						||
| 
								 | 
							
								#include "os_types_api.h"
							 | 
						||
| 
								 | 
							
								#include "os_event_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* lwip header files */
							 | 
						||
| 
								 | 
							
								#include "posix/sys/socket.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* iot header files */
							 | 
						||
| 
								 | 
							
								#include "iot_config.h"
							 | 
						||
| 
								 | 
							
								#include "iot_task_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_utils_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_errno_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_socket_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_mem_pool_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_LWIP_SUPPORT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define IOT_SOCKET_MSG_POOL_SIZE        16
							 | 
						||
| 
								 | 
							
								#define IOT_SOCKET_RECV_BUF_LEN         1024
							 | 
						||
| 
								 | 
							
								#define IOT_SOCKET_SYNC_IP              "127.0.0.1"
							 | 
						||
| 
								 | 
							
								#define IOT_SOCKET_SYNC_UDP_PORT        44444
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define IOT_SOCKET_MAX_CNT              12
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* event for socket task to handle */
							 | 
						||
| 
								 | 
							
								#define IOT_SOCKET_MSG_TYPE_CREATE_SOCK 1
							 | 
						||
| 
								 | 
							
								#define IOT_SOCKET_MSG_TYPE_DELETE_SOCK 2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* data send to sync_socket. */
							 | 
						||
| 
								 | 
							
								const static uint8_t sync_data[] = {0xFA, 0xFB, 0xFC, 0xFD};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct _iot_socket_op_arg {
							 | 
						||
| 
								 | 
							
								    /* address to be bind with the new created socket.
							 | 
						||
| 
								 | 
							
								     * as address for ipv4 and ipv6 share the same buffer,
							 | 
						||
| 
								 | 
							
								     * we can always use ipv4 address to refer to this buffer.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    union {
							 | 
						||
| 
								 | 
							
								        struct sockaddr_in ipv4_addr;
							 | 
						||
| 
								 | 
							
								#if LWIP_IPV6
							 | 
						||
| 
								 | 
							
								        struct sockaddr_in6 ipv6_addr;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    } addr;
							 | 
						||
| 
								 | 
							
								    /* type of the socket to be create, see IOT_SOCKET_TYPE_XXX */
							 | 
						||
| 
								 | 
							
								    uint8_t                 sock_type;
							 | 
						||
| 
								 | 
							
								    /* callback function for the socket. */
							 | 
						||
| 
								 | 
							
								    iot_socket_cb_func_t    func;
							 | 
						||
| 
								 | 
							
								    /* required headroom for received data of iot_socket_cb_func_t. */
							 | 
						||
| 
								 | 
							
								    uint8_t                 headroom;
							 | 
						||
| 
								 | 
							
								    /* socket to operate on. */
							 | 
						||
| 
								 | 
							
								    int32_t                 socket;
							 | 
						||
| 
								 | 
							
								    /* result of the operation. see ERR_XXX */
							 | 
						||
| 
								 | 
							
								    uint32_t                result;
							 | 
						||
| 
								 | 
							
								} iot_socket_op_arg_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* socket task message */
							 | 
						||
| 
								 | 
							
								typedef struct _iot_socket_msg {
							 | 
						||
| 
								 | 
							
								    /* iot task message */
							 | 
						||
| 
								 | 
							
								    iot_task_msg_t      task_msg;
							 | 
						||
| 
								 | 
							
								    void                *arg_ptr;
							 | 
						||
| 
								 | 
							
								} iot_socket_msg_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct _iot_socket_entry {
							 | 
						||
| 
								 | 
							
								    /* socket handle. */
							 | 
						||
| 
								 | 
							
								    int32_t                 socket;
							 | 
						||
| 
								 | 
							
								    /* callback function for the socket, shall not be NULL for valid entry. */
							 | 
						||
| 
								 | 
							
								    iot_socket_cb_func_t    func;
							 | 
						||
| 
								 | 
							
								    /* socket of the socket, see IOT_SOCKET_TYPE_XXX for detail. */
							 | 
						||
| 
								 | 
							
								    uint8_t                 sock_type;
							 | 
						||
| 
								 | 
							
								    /* domain of the socket, AF_NET for ipv4, AF_NET6 for ipv6. */
							 | 
						||
| 
								 | 
							
								    uint8_t                 domain;
							 | 
						||
| 
								 | 
							
								    /* required headroom for received data of iot_socket_cb_func_t. */
							 | 
						||
| 
								 | 
							
								    uint8_t                 headroom;
							 | 
						||
| 
								 | 
							
								} iot_socket_entry_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct _iot_socket_global {
							 | 
						||
| 
								 | 
							
								    /* address for sync socket. */
							 | 
						||
| 
								 | 
							
								    struct sockaddr_in          sync_addr;
							 | 
						||
| 
								 | 
							
								    /* pointer to socket task message queues */
							 | 
						||
| 
								 | 
							
								    iot_msg_queue_t             msg_q;
							 | 
						||
| 
								 | 
							
								    /* socket task messages pool */
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_t              *msg_p;
							 | 
						||
| 
								 | 
							
								    /* socket and its callback method */
							 | 
						||
| 
								 | 
							
								    iot_socket_entry_t          sock_entry[IOT_SOCKET_MAX_CNT];
							 | 
						||
| 
								 | 
							
								    /* socket used for sync */
							 | 
						||
| 
								 | 
							
								    int32_t                     sync_socket;
							 | 
						||
| 
								 | 
							
								    /* event for sync. only one task can create/delete socket at any time. */
							 | 
						||
| 
								 | 
							
								    os_event_h                  sock_evt;
							 | 
						||
| 
								 | 
							
								    /* event for sync. make async operation looks like sync operation. */
							 | 
						||
| 
								 | 
							
								    os_event_h                  sock_op_done;
							 | 
						||
| 
								 | 
							
								    /* socket task handle. */
							 | 
						||
| 
								 | 
							
								    iot_task_h                  task_h;
							 | 
						||
| 
								 | 
							
								} iot_socket_global_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_socket_global_t *p_socket_glb = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline uint32_t iot_socket_is_ipv6_enabled()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ipv6_enabled = 0;
							 | 
						||
| 
								 | 
							
								#if LWIP_IPV6
							 | 
						||
| 
								 | 
							
								    ipv6_enabled = 1;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    return ipv6_enabled;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline uint32_t iot_socket_is_valid_domain(int32_t domain)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (domain == AF_INET) {
							 | 
						||
| 
								 | 
							
								        return 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (domain == AF_INET6 && iot_socket_is_ipv6_enabled()) {
							 | 
						||
| 
								 | 
							
								        return 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline uint32_t iot_socket_set_addr(struct sockaddr_in *addr,
							 | 
						||
| 
								 | 
							
								    uint8_t domain, const char* ip, uint16_t port)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    struct sockaddr_in6 *addr_v6;
							 | 
						||
| 
								 | 
							
								    if (domain == AF_INET) {
							 | 
						||
| 
								 | 
							
								        if (ip == NULL) {
							 | 
						||
| 
								 | 
							
								            ip4_addr_set_any((ip4_addr_t*)&addr->sin_addr.s_addr);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            addr->sin_addr.s_addr = inet_addr(ip);
							 | 
						||
| 
								 | 
							
								            if (IPADDR_NONE == addr->sin_addr.s_addr) {
							 | 
						||
| 
								 | 
							
								                /* invalid ip address. */
							 | 
						||
| 
								 | 
							
								                return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        addr->sin_family = AF_INET;
							 | 
						||
| 
								 | 
							
								        addr->sin_port = htons(port);
							 | 
						||
| 
								 | 
							
								        addr->sin_len = sizeof(struct sockaddr_in);
							 | 
						||
| 
								 | 
							
								        return ERR_OK;
							 | 
						||
| 
								 | 
							
								    } else if (domain == AF_INET6) {
							 | 
						||
| 
								 | 
							
								#if LWIP_IPV6
							 | 
						||
| 
								 | 
							
								        addr_v6 = (struct sockaddr_in6 *)addr;
							 | 
						||
| 
								 | 
							
								        if (ip == NULL) {
							 | 
						||
| 
								 | 
							
								            ip6_addr_set_any((ip6_addr_t*)&addr_v6->sin6_addr);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            if (!ip6addr_aton(ip, (ip6_addr_t*)&addr_v6->sin6_addr)) {
							 | 
						||
| 
								 | 
							
								                /* invalid ip address. */
							 | 
						||
| 
								 | 
							
								                return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        addr_v6->sin6_family = AF_INET6;
							 | 
						||
| 
								 | 
							
								        addr_v6->sin6_port = htons(port);
							 | 
						||
| 
								 | 
							
								        addr_v6->sin6_len = sizeof(struct sockaddr_in6);
							 | 
						||
| 
								 | 
							
								        return ERR_OK;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        (void)addr_v6;
							 | 
						||
| 
								 | 
							
								        (void)addr;
							 | 
						||
| 
								 | 
							
								        (void)domain;
							 | 
						||
| 
								 | 
							
								        (void)ip;
							 | 
						||
| 
								 | 
							
								        (void)port;
							 | 
						||
| 
								 | 
							
								        return ERR_NOSUPP;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: add a socket to local socket list
							 | 
						||
| 
								 | 
							
								 * @param socket: the socket to be added.
							 | 
						||
| 
								 | 
							
								 * @param sock_type: type of the socket. see IOT_SOCKET_TYPE_XXX.
							 | 
						||
| 
								 | 
							
								 * @param domain: domain of the socket, AF_NET or AF_INET6.
							 | 
						||
| 
								 | 
							
								 * @param func: callback function to be called when data/event
							 | 
						||
| 
								 | 
							
								 *              arrival on this socket.
							 | 
						||
| 
								 | 
							
								 * @param pkt_headroom: required headroom for received data of
							 | 
						||
| 
								 | 
							
								 *                      iot_socket_cb_func_t.
							 | 
						||
| 
								 | 
							
								 * @return: ERR_OK for succeed case, other ERR_XXX for failed case.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint32_t iot_socket_add_sock_entry(int32_t socket, uint8_t sock_type,
							 | 
						||
| 
								 | 
							
								    uint8_t domain, iot_socket_cb_func_t func, uint8_t pkt_headroom)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i;
							 | 
						||
| 
								 | 
							
								    iot_socket_entry_t *free_entry = NULL;
							 | 
						||
| 
								 | 
							
								    if (func == NULL) {
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!iot_socket_is_valid_domain(domain)) {
							 | 
						||
| 
								 | 
							
								        return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < IOT_SOCKET_MAX_CNT; ++i) {
							 | 
						||
| 
								 | 
							
								        if (free_entry == NULL && p_socket_glb->sock_entry[i].func == NULL) {
							 | 
						||
| 
								 | 
							
								            /* find a free entry. */
							 | 
						||
| 
								 | 
							
								            free_entry = &p_socket_glb->sock_entry[i];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* if find the socket entry, update it's callback function. */
							 | 
						||
| 
								 | 
							
								        if (p_socket_glb->sock_entry[i].func &&
							 | 
						||
| 
								 | 
							
								            p_socket_glb->sock_entry[i].socket == socket) {
							 | 
						||
| 
								 | 
							
								            p_socket_glb->sock_entry[i].func = func;
							 | 
						||
| 
								 | 
							
								            p_socket_glb->sock_entry[i].sock_type = sock_type;
							 | 
						||
| 
								 | 
							
								            p_socket_glb->sock_entry[i].domain = domain;
							 | 
						||
| 
								 | 
							
								            p_socket_glb->sock_entry[i].headroom = pkt_headroom;
							 | 
						||
| 
								 | 
							
								            return ERR_OK;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (free_entry) {
							 | 
						||
| 
								 | 
							
								        free_entry->func = func;
							 | 
						||
| 
								 | 
							
								        free_entry->socket = socket;
							 | 
						||
| 
								 | 
							
								        free_entry->sock_type = sock_type;
							 | 
						||
| 
								 | 
							
								        free_entry->domain = domain;
							 | 
						||
| 
								 | 
							
								        free_entry->headroom = pkt_headroom;
							 | 
						||
| 
								 | 
							
								        return ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* failed, no free entry. */
							 | 
						||
| 
								 | 
							
								    return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static iot_socket_entry_t* iot_socket_get_sock_entry(int32_t socket)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i;
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < IOT_SOCKET_MAX_CNT; ++i) {
							 | 
						||
| 
								 | 
							
								        /* if find the socket entry, update it's callback function */
							 | 
						||
| 
								 | 
							
								        if (p_socket_glb->sock_entry[i].func &&
							 | 
						||
| 
								 | 
							
								            p_socket_glb->sock_entry[i].socket == socket) {
							 | 
						||
| 
								 | 
							
								            return &p_socket_glb->sock_entry[i];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_socket_rm_all_sock_entry()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i;
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < IOT_SOCKET_MAX_CNT; ++i) {
							 | 
						||
| 
								 | 
							
								        /* if find the socket entry, update it's callback function */
							 | 
						||
| 
								 | 
							
								        if (p_socket_glb->sock_entry[i].func) {
							 | 
						||
| 
								 | 
							
								            p_socket_glb->sock_entry[i].func = NULL;
							 | 
						||
| 
								 | 
							
								            p_socket_glb->sock_entry[i].socket = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_socket_rm_sock_entry(int32_t socket)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_socket_entry_t* sock_entry;
							 | 
						||
| 
								 | 
							
								    sock_entry = iot_socket_get_sock_entry(socket);
							 | 
						||
| 
								 | 
							
								    if (sock_entry) {
							 | 
						||
| 
								 | 
							
								        /* if find the socket entry, update it's callback function */
							 | 
						||
| 
								 | 
							
								        sock_entry->func = NULL;
							 | 
						||
| 
								 | 
							
								        sock_entry->socket = 0;
							 | 
						||
| 
								 | 
							
								        sock_entry->sock_type = 0;
							 | 
						||
| 
								 | 
							
								        sock_entry->domain = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static iot_socket_cb_func_t iot_socket_get_cb(int32_t socket)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_socket_entry_t *sock_entry = iot_socket_get_sock_entry(socket);
							 | 
						||
| 
								 | 
							
								    if (sock_entry) {
							 | 
						||
| 
								 | 
							
								        return sock_entry->func;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint8_t iot_socket_get_msg_hdr_len(int32_t socket)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_socket_entry_t *sock_entry = iot_socket_get_sock_entry(socket);
							 | 
						||
| 
								 | 
							
								    if (sock_entry) {
							 | 
						||
| 
								 | 
							
								        return sock_entry->headroom;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_socket_invoke_cb(int32_t socket, uint32_t cb_type,
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_socket_cb_func_t cb = iot_socket_get_cb(socket);
							 | 
						||
| 
								 | 
							
								    if (cb) {
							 | 
						||
| 
								 | 
							
								        cb(cb_type, socket, pkt);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: alloc a message from socket task's msg pool
							 | 
						||
| 
								 | 
							
								 * @return: socket message. NULL if failed to allocate a message.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								iot_socket_msg_t *iot_socket_task_alloc_msg()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_task_msg_t *msg;
							 | 
						||
| 
								 | 
							
								    msg = iot_mem_pool_alloc_with_reserve(p_socket_glb->msg_p, 0);
							 | 
						||
| 
								 | 
							
								    if (msg) {
							 | 
						||
| 
								 | 
							
								        iot_msg_entry_init(&msg->link);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return (iot_socket_msg_t*)msg;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: free a msg to socket task's msg pool
							 | 
						||
| 
								 | 
							
								 * @param socket_msg: socket message to be freed.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void iot_socket_task_free_msg(iot_socket_msg_t *socket_msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_task_msg_t *msg = (iot_task_msg_t *)&socket_msg->task_msg;
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_free(p_socket_glb->msg_p, msg);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: send data to sync socket to notify socket task
							 | 
						||
| 
								 | 
							
								 *         that there is msg in queue and shall be processed.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_socket_task_notify()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* send a udp packet to signal socket. */
							 | 
						||
| 
								 | 
							
								    sendto(p_socket_glb->sync_socket, sync_data, sizeof(sync_data), 0,
							 | 
						||
| 
								 | 
							
								        (const struct sockaddr *)&p_socket_glb->sync_addr,
							 | 
						||
| 
								 | 
							
								        sizeof(p_socket_glb->sync_addr));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: put a msg into msg queue and notify socket task.
							 | 
						||
| 
								 | 
							
								 *         it returns when socket task finish operation.
							 | 
						||
| 
								 | 
							
								 * @param sock_msg: msg to be put into queue of socket task.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_socket_task_put_msg_sync(iot_socket_msg_t *sock_msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_task_msg_t *msg = &sock_msg->task_msg;
							 | 
						||
| 
								 | 
							
								    os_wait_event(p_socket_glb->sock_evt, MAX_TIME);
							 | 
						||
| 
								 | 
							
								    iot_msg_queue_put(&p_socket_glb->msg_q, &msg->link);
							 | 
						||
| 
								 | 
							
								    iot_socket_task_notify();
							 | 
						||
| 
								 | 
							
								    /* wait until the operation finished.
							 | 
						||
| 
								 | 
							
								     * make async operation looks like sync operation.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    os_wait_event(p_socket_glb->sock_op_done, MAX_TIME);
							 | 
						||
| 
								 | 
							
								    os_set_event(p_socket_glb->sock_evt);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: get a msg from msg pool of socket task.
							 | 
						||
| 
								 | 
							
								 * @return: msg from msg queue of socket task, NULL if failed..
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static iot_socket_msg_t* iot_socket_task_get_msg()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_task_msg_t *msg = NULL;
							 | 
						||
| 
								 | 
							
								    iot_msg_entry_t *entry = iot_msg_queue_get(&p_socket_glb->msg_q);
							 | 
						||
| 
								 | 
							
								    if (entry) {
							 | 
						||
| 
								 | 
							
								        msg = container_of(entry, iot_task_msg_t, link);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return (iot_socket_msg_t*)msg;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_socket_create_internal(iot_socket_msg_t *msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int32_t ret;
							 | 
						||
| 
								 | 
							
								    int32_t sock;
							 | 
						||
| 
								 | 
							
								    uint8_t domain;
							 | 
						||
| 
								 | 
							
								    uint32_t proto_type;
							 | 
						||
| 
								 | 
							
								    uint8_t socket_type;
							 | 
						||
| 
								 | 
							
								    iot_socket_op_arg_t *p_arg = (iot_socket_op_arg_t *)msg->arg_ptr;
							 | 
						||
| 
								 | 
							
								    if (p_arg == NULL) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    socket_type = p_arg->sock_type;
							 | 
						||
| 
								 | 
							
								    if (socket_type == IOT_SOCKET_TYPE_UDP) {
							 | 
						||
| 
								 | 
							
								        proto_type = SOCK_DGRAM;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        /* unsupported socket type. */
							 | 
						||
| 
								 | 
							
								        p_arg->socket = -1;
							 | 
						||
| 
								 | 
							
								        p_arg->result = ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    domain = p_arg->addr.ipv4_addr.sin_family;
							 | 
						||
| 
								 | 
							
								    sock = socket(domain, proto_type, 0);
							 | 
						||
| 
								 | 
							
								    ret = bind(sock, (struct sockaddr*)&p_arg->addr.ipv4_addr,
							 | 
						||
| 
								 | 
							
								        p_arg->addr.ipv4_addr.sin_len);
							 | 
						||
| 
								 | 
							
								    if (ret) {
							 | 
						||
| 
								 | 
							
								        /* failed to bind the socket */
							 | 
						||
| 
								 | 
							
								        closesocket(sock);
							 | 
						||
| 
								 | 
							
								        p_arg->socket = -1;
							 | 
						||
| 
								 | 
							
								        p_arg->result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (proto_type) {
							 | 
						||
| 
								 | 
							
								    case SOCK_DGRAM:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        p_arg->socket = sock;
							 | 
						||
| 
								 | 
							
								        p_arg->result = ERR_OK;
							 | 
						||
| 
								 | 
							
								        iot_socket_add_sock_entry(sock, socket_type, domain, p_arg->func,
							 | 
						||
| 
								 | 
							
								            p_arg->headroom);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case SOCK_STREAM:
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        p_arg->socket = -1;
							 | 
						||
| 
								 | 
							
								        p_arg->result = ERR_NOSUPP;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void iot_socket_delete_internal(iot_socket_msg_t *msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int32_t sock;
							 | 
						||
| 
								 | 
							
								    iot_socket_entry_t *sock_entry;
							 | 
						||
| 
								 | 
							
								    iot_socket_op_arg_t *p_arg = (iot_socket_op_arg_t *)msg->arg_ptr;
							 | 
						||
| 
								 | 
							
								    if (p_arg == NULL) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    sock = p_arg->socket;
							 | 
						||
| 
								 | 
							
								    if (sock <= 0) {
							 | 
						||
| 
								 | 
							
								        /* socket 0 is for internal use. it cannot be deleted.
							 | 
						||
| 
								 | 
							
								         * socket less than 0 is invalid.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    sock_entry = iot_socket_get_sock_entry(sock);
							 | 
						||
| 
								 | 
							
								    if (sock_entry == NULL) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (sock_entry->sock_type) {
							 | 
						||
| 
								 | 
							
								    case IOT_SOCKET_TYPE_UDP:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        closesocket(sock);
							 | 
						||
| 
								 | 
							
								        iot_socket_rm_sock_entry(sock);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        /* api shall reject unsupported operation.
							 | 
						||
| 
								 | 
							
								         * codes shall not reach here.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: message handler method. It always frees the msg.
							 | 
						||
| 
								 | 
							
								 * @param msg: message to be handled.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_socket_msg_handler(iot_socket_msg_t *msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (msg == NULL) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (msg->task_msg.type) {
							 | 
						||
| 
								 | 
							
								    case IOT_SOCKET_MSG_TYPE_CREATE_SOCK:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_socket_create_internal(msg);
							 | 
						||
| 
								 | 
							
								        os_set_event(p_socket_glb->sock_op_done);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    case IOT_SOCKET_MSG_TYPE_DELETE_SOCK:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        iot_socket_delete_internal(msg);
							 | 
						||
| 
								 | 
							
								        os_set_event(p_socket_glb->sock_op_done);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_socket_task_free_msg(msg);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: get fd object from current socket list.
							 | 
						||
| 
								 | 
							
								 * @param set: output parameter for fd_set object
							 | 
						||
| 
								 | 
							
								 * @return: max socket handle in fd_set, -1 for failed case.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static int32_t iot_socket_get_fd(fd_set *set)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i;
							 | 
						||
| 
								 | 
							
								    int32_t max_fd = -1;
							 | 
						||
| 
								 | 
							
								    /* clear the fd_set object. */
							 | 
						||
| 
								 | 
							
								    os_mem_set(set, 0, sizeof(*set));
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < IOT_SOCKET_MAX_CNT; ++i) {
							 | 
						||
| 
								 | 
							
								        if (p_socket_glb->sock_entry[i].func) {
							 | 
						||
| 
								 | 
							
								            if (p_socket_glb->sock_entry[i].socket > max_fd) {
							 | 
						||
| 
								 | 
							
								                max_fd = p_socket_glb->sock_entry[i].socket;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            FD_SET(p_socket_glb->sock_entry[i].socket, set);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return max_fd;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: task function for socket task.
							 | 
						||
| 
								 | 
							
								 *         it use a socket as a event for synchronization.
							 | 
						||
| 
								 | 
							
								 *         when recv data from sync socket, it takes a msg from task
							 | 
						||
| 
								 | 
							
								 *         msg queue and handle it. when recv data from other socket,
							 | 
						||
| 
								 | 
							
								 *         it call corresponding callback function.
							 | 
						||
| 
								 | 
							
								 * @arg: argument for the task func
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_socket_task_func(void* arg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int32_t i;
							 | 
						||
| 
								 | 
							
								    int32_t result;
							 | 
						||
| 
								 | 
							
								    int32_t max_fd;
							 | 
						||
| 
								 | 
							
								    int32_t pending_data_len = 0;
							 | 
						||
| 
								 | 
							
								    uint8_t pkt_headroom = 0;
							 | 
						||
| 
								 | 
							
								    fd_set fd;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_printf("%s - %p\n", __FUNCTION__, arg);
							 | 
						||
| 
								 | 
							
								    while (1) {
							 | 
						||
| 
								 | 
							
								        max_fd = iot_socket_get_fd(&fd);
							 | 
						||
| 
								 | 
							
								        result = select(max_fd + 1, &fd, NULL, NULL, NULL);
							 | 
						||
| 
								 | 
							
								        if (result < 0) {
							 | 
						||
| 
								 | 
							
								            /* error happened */
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (i = 0; i <= max_fd; i++) {
							 | 
						||
| 
								 | 
							
								            if (!FD_ISSET(i, &fd)) {
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (ioctlsocket(i, FIONREAD, &pending_data_len)) {
							 | 
						||
| 
								 | 
							
								                /* for ioctlsocket to work on lwip, LWIP_FIONREAD_LINUXMODE
							 | 
						||
| 
								 | 
							
								                 * shall be set to 1 to enable Linux style ioctl/FIONREAD.
							 | 
						||
| 
								 | 
							
								                 * Linux style ioctl/FIONREAD return length next pending data.
							 | 
						||
| 
								 | 
							
								                 * Windows style ioctl/FIONREAD return length of all pending
							 | 
						||
| 
								 | 
							
								                 * data, which shall NOT be used here.
							 | 
						||
| 
								 | 
							
								                 */
							 | 
						||
| 
								 | 
							
								                IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (pending_data_len == 0) {
							 | 
						||
| 
								 | 
							
								                pending_data_len = 1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            pkt_headroom = iot_socket_get_msg_hdr_len(i);
							 | 
						||
| 
								 | 
							
								            pkt = iot_pkt_alloc(pending_data_len + pkt_headroom,
							 | 
						||
| 
								 | 
							
								                IOT_SOCKET_MID);
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(pkt);
							 | 
						||
| 
								 | 
							
								            iot_pkt_reserve(pkt, pkt_headroom);
							 | 
						||
| 
								 | 
							
								            result = recv(i, iot_pkt_data(pkt),
							 | 
						||
| 
								 | 
							
								                iot_pkt_tail_len(pkt) - pkt_headroom, 0);
							 | 
						||
| 
								 | 
							
								            iot_pkt_put(pkt, result);
							 | 
						||
| 
								 | 
							
								            iot_socket_invoke_cb(i, IOT_SOCKET_CB_DATA_RECV, pkt);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief: callback method for sync socket
							 | 
						||
| 
								 | 
							
								 * @param cb_type: type of event that trigger the callback
							 | 
						||
| 
								 | 
							
								 * @param socket: the socket on which event occur
							 | 
						||
| 
								 | 
							
								 * @param data_pkt: pkt contains data for the callback.
							 | 
						||
| 
								 | 
							
								 *                  this method shall free data_pkt.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_sg_sync_socket_cb(uint32_t cb_type, int32_t socket,
							 | 
						||
| 
								 | 
							
								    iot_pkt_t* data_pkt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t *ptr;
							 | 
						||
| 
								 | 
							
								    iot_socket_msg_t *msg;
							 | 
						||
| 
								 | 
							
								    if (cb_type != IOT_SOCKET_CB_DATA_RECV) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (socket != p_socket_glb->sync_socket) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (data_pkt == NULL) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ptr = iot_pkt_data(data_pkt);
							 | 
						||
| 
								 | 
							
								    if (iot_pkt_data_len(data_pkt) == sizeof(sync_data) &&
							 | 
						||
| 
								 | 
							
								        os_mem_cmp(ptr, sync_data, sizeof(sync_data)) == 0) {
							 | 
						||
| 
								 | 
							
								        /* receives data from sync socket and pattern matches. */
							 | 
						||
| 
								 | 
							
								        msg = iot_socket_task_get_msg();
							 | 
						||
| 
								 | 
							
								        iot_socket_msg_handler(msg);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(data_pkt);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_socket_task_init()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int32_t ret;
							 | 
						||
| 
								 | 
							
								    uint8_t socket_created = 0;
							 | 
						||
| 
								 | 
							
								    uint8_t msg_q_created = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb == NULL) {
							 | 
						||
| 
								 | 
							
								        p_socket_glb = os_mem_malloc(IOT_SOCKET_MID, sizeof(*p_socket_glb));
							 | 
						||
| 
								 | 
							
								        if (p_socket_glb == NULL) {
							 | 
						||
| 
								 | 
							
								            goto err_label;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->task_h) {
							 | 
						||
| 
								 | 
							
								        /* don't create again. */
							 | 
						||
| 
								 | 
							
								        return ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* event for synchronization, it's set by default. */
							 | 
						||
| 
								 | 
							
								    p_socket_glb->sock_evt = os_create_event(IOT_SMART_GRID_MID, 1);
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->sock_evt == 0) {
							 | 
						||
| 
								 | 
							
								        goto err_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_socket_glb->sock_op_done = os_create_event(IOT_SMART_GRID_MID, 0);
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->sock_op_done == 0) {
							 | 
						||
| 
								 | 
							
								        goto err_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_socket_glb->sync_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->sync_socket >= 0) {
							 | 
						||
| 
								 | 
							
								        socket_created = 1;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        /* create socket failed. close the socket. */
							 | 
						||
| 
								 | 
							
								        goto err_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* init local address for sync. */
							 | 
						||
| 
								 | 
							
								    iot_socket_set_addr(&p_socket_glb->sync_addr, AF_INET,
							 | 
						||
| 
								 | 
							
								        IOT_SOCKET_SYNC_IP, IOT_SOCKET_SYNC_UDP_PORT);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* bind socket with local ipv4 address. */
							 | 
						||
| 
								 | 
							
								    ret = bind(p_socket_glb->sync_socket,
							 | 
						||
| 
								 | 
							
								        (const struct sockaddr*)&p_socket_glb->sync_addr,
							 | 
						||
| 
								 | 
							
								        sizeof(p_socket_glb->sync_addr));
							 | 
						||
| 
								 | 
							
								    iot_printf("bind socket, ret = %d\n", ret);
							 | 
						||
| 
								 | 
							
								    if (ret) {
							 | 
						||
| 
								 | 
							
								        /* bind failed. close the socket. */
							 | 
						||
| 
								 | 
							
								        goto err_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ret = iot_mem_pool_new(IOT_SOCKET_MID, IOT_SOCKET_MSG_POOL_SIZE,
							 | 
						||
| 
								 | 
							
								        sizeof(iot_socket_msg_t), &p_socket_glb->msg_p, 1);
							 | 
						||
| 
								 | 
							
								    if (ret != ERR_OK) {
							 | 
						||
| 
								 | 
							
								        goto err_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    msg_q_created = 1;
							 | 
						||
| 
								 | 
							
								    ret = iot_msg_queue_init(&p_socket_glb->msg_q);
							 | 
						||
| 
								 | 
							
								    if (ret != ERR_OK) {
							 | 
						||
| 
								 | 
							
								        goto err_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_socket_add_sock_entry(p_socket_glb->sync_socket,
							 | 
						||
| 
								 | 
							
								        IOT_SOCKET_TYPE_UDP, AF_INET, iot_sg_sync_socket_cb, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_socket_glb->task_h = os_create_task(iot_socket_task_func,
							 | 
						||
| 
								 | 
							
								        p_socket_glb, IOT_SOCKET_TASK_PRIO);
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->task_h == 0) {
							 | 
						||
| 
								 | 
							
								        goto err_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_printf("%s: socket_task = 0x%08X\n",
							 | 
						||
| 
								 | 
							
								        __FUNCTION__, p_socket_glb->task_h);
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								err_label:
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->sock_evt) {
							 | 
						||
| 
								 | 
							
								        os_delete_event(p_socket_glb->sock_evt);
							 | 
						||
| 
								 | 
							
								        p_socket_glb->sock_evt = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->sock_op_done) {
							 | 
						||
| 
								 | 
							
								        os_delete_event(p_socket_glb->sock_op_done);
							 | 
						||
| 
								 | 
							
								        p_socket_glb->sock_op_done = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->task_h) {
							 | 
						||
| 
								 | 
							
								        os_delete_task(p_socket_glb->task_h);
							 | 
						||
| 
								 | 
							
								        p_socket_glb->task_h = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (socket_created) {
							 | 
						||
| 
								 | 
							
								        closesocket(p_socket_glb->sync_socket);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->msg_p) {
							 | 
						||
| 
								 | 
							
								        iot_mem_pool_destroy(p_socket_glb->msg_p);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (msg_q_created) {
							 | 
						||
| 
								 | 
							
								        iot_msg_queue_deinit(&p_socket_glb->msg_q);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_socket_rm_all_sock_entry();
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb) {
							 | 
						||
| 
								 | 
							
								        os_mem_free(p_socket_glb);
							 | 
						||
| 
								 | 
							
								        p_socket_glb = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* failed to create socket task. */
							 | 
						||
| 
								 | 
							
								    return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_socket_task_deinit()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb == NULL) {
							 | 
						||
| 
								 | 
							
								        /* task was not initialized yet. */
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->task_h) {
							 | 
						||
| 
								 | 
							
								        os_delete_task(p_socket_glb->task_h);
							 | 
						||
| 
								 | 
							
								        p_socket_glb->task_h = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->sock_evt) {
							 | 
						||
| 
								 | 
							
								        os_delete_event(p_socket_glb->sock_evt);
							 | 
						||
| 
								 | 
							
								        p_socket_glb->sock_evt = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->sock_op_done) {
							 | 
						||
| 
								 | 
							
								        os_delete_event(p_socket_glb->sock_op_done);
							 | 
						||
| 
								 | 
							
								        p_socket_glb->sock_op_done = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    closesocket(p_socket_glb->sync_socket);
							 | 
						||
| 
								 | 
							
								    p_socket_glb->sync_socket = 0;
							 | 
						||
| 
								 | 
							
								    iot_msg_queue_deinit(&p_socket_glb->msg_q);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb->msg_p) {
							 | 
						||
| 
								 | 
							
								        iot_mem_pool_destroy(p_socket_glb->msg_p);
							 | 
						||
| 
								 | 
							
								        p_socket_glb->msg_p = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_socket_rm_all_sock_entry();
							 | 
						||
| 
								 | 
							
								    os_mem_free(p_socket_glb);
							 | 
						||
| 
								 | 
							
								    p_socket_glb = NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline uint32_t iot_socket_create_arg_validate(uint32_t socket_type,
							 | 
						||
| 
								 | 
							
								    uint32_t is_ipv6, iot_socket_cb_func_t recv_cb, int32_t *ret_sock)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								    uint32_t valid_sock_type;
							 | 
						||
| 
								 | 
							
								    if (recv_cb == NULL || ret_sock == NULL) {
							 | 
						||
| 
								 | 
							
								        /* invalid arguments. */
							 | 
						||
| 
								 | 
							
								        result = ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (iot_socket_is_ipv6_enabled() == 0 && is_ipv6) {
							 | 
						||
| 
								 | 
							
								        /* ipv6 is not supported */
							 | 
						||
| 
								 | 
							
								        result = ERR_NOSUPP;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (socket_type) {
							 | 
						||
| 
								 | 
							
								    case IOT_SOCKET_TYPE_UDP:
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        valid_sock_type = 1;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        valid_sock_type = 0;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (valid_sock_type == 0) {
							 | 
						||
| 
								 | 
							
								        result = ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exit_label:
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_socket_create(uint8_t socket_type, uint8_t is_ipv6,
							 | 
						||
| 
								 | 
							
								    const char *ip, uint16_t port, iot_socket_cb_func_t recv_cb,
							 | 
						||
| 
								 | 
							
								    uint8_t pkt_headroom, int32_t *ret_sock)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_socket_msg_t *msg;
							 | 
						||
| 
								 | 
							
								    int32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								    uint8_t domain = AF_INET;
							 | 
						||
| 
								 | 
							
								    iot_socket_op_arg_t create_arg = {0};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb == NULL) {
							 | 
						||
| 
								 | 
							
								        iot_printf("%s - error. socket not start yet.\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        result = ERR_NOT_READY;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (iot_socket_create_arg_validate(socket_type, is_ipv6,
							 | 
						||
| 
								 | 
							
								        recv_cb, ret_sock)) {
							 | 
						||
| 
								 | 
							
								        /* invalid arguments. */
							 | 
						||
| 
								 | 
							
								        result = ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    msg = iot_socket_task_alloc_msg();
							 | 
						||
| 
								 | 
							
								    if (msg == NULL) {
							 | 
						||
| 
								 | 
							
								        result = ERR_NOMEM;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (is_ipv6) {
							 | 
						||
| 
								 | 
							
								        domain = AF_INET6;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    msg->task_msg.type = IOT_SOCKET_MSG_TYPE_CREATE_SOCK;
							 | 
						||
| 
								 | 
							
								    msg->task_msg.id = 0;
							 | 
						||
| 
								 | 
							
								    msg->arg_ptr = (void*)&create_arg;
							 | 
						||
| 
								 | 
							
								    create_arg.func = recv_cb;
							 | 
						||
| 
								 | 
							
								    create_arg.sock_type = socket_type;
							 | 
						||
| 
								 | 
							
								    create_arg.headroom = pkt_headroom;
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != iot_socket_set_addr(&create_arg.addr.ipv4_addr,
							 | 
						||
| 
								 | 
							
								        domain, ip, port)) {
							 | 
						||
| 
								 | 
							
								        iot_socket_task_free_msg(msg);
							 | 
						||
| 
								 | 
							
								        result = ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_socket_task_put_msg_sync(msg);
							 | 
						||
| 
								 | 
							
								    *ret_sock = create_arg.socket;
							 | 
						||
| 
								 | 
							
								    result = create_arg.result;
							 | 
						||
| 
								 | 
							
								    if (*ret_sock < 0) {
							 | 
						||
| 
								 | 
							
								        result = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exit_label:
							 | 
						||
| 
								 | 
							
								    iot_printf("%s - %d, reason = %lu\n", __FUNCTION__, *ret_sock, result);
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_socket_delete(int32_t socket)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								    iot_socket_op_arg_t delete_arg = {0};
							 | 
						||
| 
								 | 
							
								    iot_socket_msg_t *msg;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb == NULL) {
							 | 
						||
| 
								 | 
							
								        iot_printf("%s - error. socket not start yet.\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        result = ERR_NOT_READY;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (socket <= 0) {
							 | 
						||
| 
								 | 
							
								        /* socket 0 is for internal use. it shall not be deleted.
							 | 
						||
| 
								 | 
							
								         * socket less than 0 is invalid.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        result = ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    msg = iot_socket_task_alloc_msg();
							 | 
						||
| 
								 | 
							
								    if (msg == NULL) {
							 | 
						||
| 
								 | 
							
								        result = ERR_NOMEM;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    msg->task_msg.type = IOT_SOCKET_MSG_TYPE_DELETE_SOCK;
							 | 
						||
| 
								 | 
							
								    msg->task_msg.id = 0;
							 | 
						||
| 
								 | 
							
								    msg->arg_ptr = (void*)&delete_arg;
							 | 
						||
| 
								 | 
							
								    delete_arg.socket = socket;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_socket_task_put_msg_sync(msg);
							 | 
						||
| 
								 | 
							
								exit_label:
							 | 
						||
| 
								 | 
							
								    iot_printf("%s - result = %lu.\n", __FUNCTION__, result);
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_socket_udp_send(int32_t socket, uint8_t *data,
							 | 
						||
| 
								 | 
							
								    uint32_t data_len, uint32_t is_ipv6, const char *ip, uint16_t port)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t result = ERR_OK;
							 | 
						||
| 
								 | 
							
								    struct sockaddr_storage sock_addr_obj = {0};
							 | 
						||
| 
								 | 
							
								    struct sockaddr_in *sock_addr = (struct sockaddr_in*)&sock_addr_obj;
							 | 
						||
| 
								 | 
							
								    int32_t send_ret;
							 | 
						||
| 
								 | 
							
								    uint8_t domain;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_socket_glb == NULL) {
							 | 
						||
| 
								 | 
							
								        iot_printf("%s - error. socket not start yet.\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        result = ERR_NOT_READY;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (data == NULL || data_len == 0) {
							 | 
						||
| 
								 | 
							
								        result = ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    domain = AF_INET;
							 | 
						||
| 
								 | 
							
								    if (is_ipv6) {
							 | 
						||
| 
								 | 
							
								        domain = AF_INET6;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (iot_socket_set_addr(sock_addr, domain, ip, port)) {
							 | 
						||
| 
								 | 
							
								        result = ERR_INVAL;
							 | 
						||
| 
								 | 
							
								        goto exit_label;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    send_ret = sendto(socket, data, data_len, 0,
							 | 
						||
| 
								 | 
							
								        (const struct sockaddr*)sock_addr, sock_addr->sin_len);
							 | 
						||
| 
								 | 
							
								    iot_printf("%s: len = %d, send ret = %d\n",
							 | 
						||
| 
								 | 
							
								        __FUNCTION__, data_len, send_ret);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exit_label:
							 | 
						||
| 
								 | 
							
								    return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else   /* IOT_LWIP_SUPPORT */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_socket_task_init()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return ERR_NOSUPP;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_socket_task_deinit()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_socket_create(uint8_t socket_type, uint8_t is_ipv6,
							 | 
						||
| 
								 | 
							
								    const char *ip, uint16_t port, iot_socket_cb_func_t recv_cb,
							 | 
						||
| 
								 | 
							
								    uint8_t pkt_headroom, int32_t *ret_sock)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)socket_type;
							 | 
						||
| 
								 | 
							
								    (void)is_ipv6;
							 | 
						||
| 
								 | 
							
								    (void)ip;
							 | 
						||
| 
								 | 
							
								    (void)port;
							 | 
						||
| 
								 | 
							
								    (void)recv_cb;
							 | 
						||
| 
								 | 
							
								    (void)pkt_headroom;
							 | 
						||
| 
								 | 
							
								    (void)ret_sock;
							 | 
						||
| 
								 | 
							
								    return ERR_NOSUPP;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_socket_delete(int32_t socket)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)socket;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t iot_socket_udp_send(int32_t socket, uint8_t *data, uint32_t len,
							 | 
						||
| 
								 | 
							
								    uint32_t is_ipv6, const char *ip, uint16_t port)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)socket;
							 | 
						||
| 
								 | 
							
								    (void)data;
							 | 
						||
| 
								 | 
							
								    (void)len;
							 | 
						||
| 
								 | 
							
								    (void)is_ipv6;
							 | 
						||
| 
								 | 
							
								    (void)ip;
							 | 
						||
| 
								 | 
							
								    (void)port;
							 | 
						||
| 
								 | 
							
								    return ERR_NOSUPP;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif  /* IOT_LWIP_SUPPORT */
							 |