/************************************************************************** * File Name : tls_netconn.c * Author : * Version : * Date : * Description : * * Copyright (c) 2014 Winner Microelectronics Co., Ltd. * All rights reserved. * ***************************************************************************/ #include "wm_config.h" #if TLS_CONFIG_SOCKET_RAW #include "tls_netconn.h" #include "wm_debug.h" #include "wm_regs.h" #include "lwip/sys.h" #include "lwip/tcp.h" #include "lwip/udp.h" #include "lwip/tcpip.h" #include #include "wm_sockets.h" struct tls_netconn *p_net_conn[TLS_MAX_NETCONN_NUM]; #if CONN_SEM_NOT_FREE sys_sem_t conn_op_completed[TLS_MAX_NETCONN_NUM] = {NULL}; #endif //static err_t net_tcp_sent_cb(void *arg, struct tcp_pcb *pcb, u16_t len); static void net_tcp_err_cb(void *arg, err_t err); static err_t net_tcp_poll_cb(void *arg, struct tcp_pcb *pcb); static void net_free_socket(int socketno); //static err_t net_do_writemore(struct tls_netconn *conn); #define BUF_CIRC_CNT_TO_END(head,tail,size) \ ({int end = (size) - (tail); \ int n = ((head) + end) & ((size)-1); \ n < end ? n : end;}) u32 current_src_ip = 0; void tls_net_set_sourceip(u32 ipvalue) { current_src_ip = ipvalue; } u32 tls_net_get_sourceip(void) { return current_src_ip; } struct tls_netconn *get_server_conn(struct tls_netconn *conn) { struct tls_netconn *server_conn = NULL; do{ server_conn = dl_list_first(&conn->list, struct tls_netconn, list); conn = server_conn; }while((server_conn != NULL) && server_conn->client); return server_conn; } static struct tls_netconn *net_alloc_socket(struct tls_netconn *conn) { int sock=-1, i=0, j=0; u32 cpu_sr; struct tls_netconn * conn_t = NULL; for (i = 0; i < TLS_MAX_NETCONN_NUM; i++) { if(p_net_conn[i] == NULL) { sock = i; break; } } if (i == TLS_MAX_NETCONN_NUM){ TLS_DBGPRT_ERR("\nnet_alloc_socket error\n"); return NULL; } if(conn != NULL) { j = dl_list_len(&conn->list); if(j>=4) { TLS_DBGPRT_ERR("list len > 4\n"); sock = -1; } } if(sock < 0) { TLS_DBGPRT_ERR("sock < 0\n"); return NULL; } cpu_sr = tls_os_set_critical(); conn_t = tls_mem_alloc(sizeof(struct tls_netconn)); tls_os_release_critical(cpu_sr); if (NULL != conn_t) { p_net_conn[sock] = conn_t; memset(conn_t, 0, sizeof(struct tls_netconn)); conn_t->used = true; conn_t->state = NETCONN_STATE_NONE; conn_t->skt_num = sock + 1;//TLS_MAX_NETCONN_NUM + dl_list_init(&conn_t->list); #if CONN_SEM_NOT_FREE TLS_DBGPRT_INFO("conn_op_completed[%d]=%x\n",sock, conn_op_completed[sock]); if(NULL == conn_op_completed[sock]) { if(sys_sem_new(&conn_op_completed[sock], 0) != ERR_OK) { net_free_socket(conn_t->skt_num); } } #else if (sys_sem_new(&conn_t->op_completed, 0) != ERR_OK) { net_free_socket(conn_t->skt_num); } #endif } TLS_DBGPRT_INFO("net_alloc_socket conn ptr = 0x%x\n", conn_t); return conn_t; // return NULL; } static void net_free_socket(int socketno) { int index; u32 cpu_sr; struct tls_netconn *conn = NULL; conn = tls_net_get_socket(socketno); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("\nconn=%x,used=%d\n",conn, conn->used); return; } TLS_DBGPRT_INFO("conn ptr = 0x%x\n", conn); #if !CONN_SEM_NOT_FREE if (NULL != conn->op_completed) { sys_sem_free(&conn->op_completed); } #endif conn->used = false; if(conn->client && conn->list.prev != NULL && conn->list.prev != &conn->list) { TLS_DBGPRT_INFO("del from list.\n"); cpu_sr = tls_os_set_critical(); dl_list_del(&conn->list); tls_os_release_critical(cpu_sr); } index = conn->skt_num - 1;//TLS_MAX_NETCONN_NUM - if (conn->pcb.tcp) { tcp_close(conn->pcb.tcp); conn->pcb.tcp = NULL; } tls_mem_free(conn); cpu_sr = tls_os_set_critical(); conn = NULL; p_net_conn[index] = NULL; tls_os_release_critical(cpu_sr); } static void net_send_event_to_hostif(struct tls_netconn *conn, int event) { struct tls_socket_desc *skt_desc = conn->skd; TLS_DBGPRT_INFO("skt_desc->state_changed: 0x%x, event=%d\n", skt_desc->state_changed, event); if(skt_desc->state_changed) { skt_desc->state_changed(conn->skt_num, event, conn->state); } } static void net_tcp_close_connect(int socketno) { err_t err; struct tls_netconn *conn = NULL; conn = tls_net_get_socket(socketno); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("\nconn=%x,used=%d\n",conn, conn->used); return; } if (NULL == conn->pcb.tcp){ TLS_DBGPRT_ERR("\ntcp=null\n"); return; } /* Set back some callback pointers */ tcp_arg(conn->pcb.tcp, NULL); if (conn->pcb.tcp->state == LISTEN) { tcp_accept(conn->pcb.tcp, NULL); } else { /* some callbacks have to be reset if tcp_close is not successful */ tcp_recv(conn->pcb.tcp, NULL); tcp_accept(conn->pcb.tcp, NULL); tcp_sent(conn->pcb.tcp, NULL); tcp_poll(conn->pcb.tcp, NULL, 4); tcp_err(conn->pcb.tcp, NULL); } err = tcp_close(conn->pcb.tcp); if (err) err = tcp_shutdown(conn->pcb.tcp, 1, 1); if (err == ERR_OK) { /* Closing succeeded */ TLS_DBGPRT_INFO("tcp %d closed\n", conn->skt_num); conn->state = NETCONN_STATE_NONE; /* Set back some callback pointers as conn is going away */ conn->pcb.tcp = NULL; net_free_socket(socketno); /* Trigger select() in socket layer. Make sure everybody notices activity on the connection, error first! */ } else { /* Closing failed, restore some of the callbacks */ /* Closing of listen pcb will never fail! */ LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); //tcp_sent(conn->pcb.tcp, net_tcp_sent_cb); tcp_poll(conn->pcb.tcp, net_tcp_poll_cb, 4); tcp_err(conn->pcb.tcp, net_tcp_err_cb); tcp_arg(conn->pcb.tcp, (void *)socketno); /* don't restore recv callback: we don't want to receive any more data */ } } static err_t net_tcp_poll_cb(void *arg, struct tcp_pcb *pcb) { err_t err_ret = ERR_OK; struct tls_netconn *conn = NULL; struct tls_netconn *server_conn = NULL; int socketno = (int)arg; conn = tls_net_get_socket(socketno); if(conn == NULL || TRUE != conn->used || NULL == pcb) { TLS_DBGPRT_ERR("\nconn=%x,used=%d,pcb=%x\n",conn, conn->used, pcb); return ERR_ARG; } //TLS_DBGPRT_INFO("net_tcp_poll_cb start\n"); /* if (conn == NULL || pcb == NULL) { TLS_DBGPRT_ERR("\npcb=null\n"); return ERR_CLSD; } */ if (conn->write_state && (conn->state == NETCONN_STATE_CONNECTED)) { //net_do_writemore(conn); } else if (conn->state == NETCONN_STATE_CLOSED) { net_tcp_close_connect(socketno); } else { if ((pcb->state == CLOSE_WAIT) || (pcb->state == CLOSED)) { if (conn->pcb.tcp != NULL) { tcp_arg(conn->pcb.tcp, NULL); tcp_accept(conn->pcb.tcp, NULL); tcp_recv(conn->pcb.tcp, NULL); tcp_sent(conn->pcb.tcp, NULL); tcp_poll(conn->pcb.tcp, NULL, 4); tcp_err(conn->pcb.tcp, NULL); tcp_close(conn->pcb.tcp); conn->state = NETCONN_STATE_NONE; net_send_event_to_hostif(conn, NET_EVENT_TCP_DISCONNECT); conn->pcb.tcp = NULL; net_free_socket(socketno); } } } if (conn){ if(conn->client && conn->idle_time > 0) { TLS_DBGPRT_INFO("conn->skt_num=%d, conn->client=%d\n", conn->skt_num, conn->client); // server_conn = dl_list_first(&conn->list, struct tls_netconn, list); server_conn = get_server_conn(conn); if(server_conn) { --conn->idle_time; if(conn->idle_time == 0) { tcp_abort(pcb); //tls_socket_close(conn->skt_num); TLS_DBGPRT_INFO("update conn->idle_time %d\n", conn->idle_time); return ERR_ABRT; } } } if((conn->skd) != NULL && (conn->skd->pollf) != NULL) { err_ret = conn->skd->pollf(conn->skt_num); if(err_ret == ERR_ABRT) tcp_abort(pcb); return err_ret; } } return ERR_OK; } static void net_tcp_err_cb(void *arg, err_t err) { struct tls_netconn *conn = NULL; struct tcp_pcb *pcb = NULL; int socketno = (int)arg; u8 event = NET_EVENT_TCP_CONNECT_FAILED; conn = tls_net_get_socket(socketno); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("\nconn=%x,used=%d\n",conn, conn->used); return; } pcb = conn->pcb.tcp; TLS_DBGPRT_INFO("tcp err = %d, pcb==%x, conn==%x, skt==%x\n", err, (char *)pcb, (char *)conn, conn->skd); if (pcb) { tcp_arg(pcb, NULL); tcp_sent(pcb, NULL); tcp_recv(pcb, NULL); tcp_err(pcb, NULL); if (!conn->client) { tcp_accept(pcb, NULL); } if(err == ERR_OK) { tcp_close(pcb); } if(conn->state != NETCONN_STATE_NONE) { conn->state = NETCONN_STATE_NONE; event = NET_EVENT_TCP_DISCONNECT; } net_send_event_to_hostif(conn, event); if(conn->skd->errf != NULL) { conn->skd->errf(conn->skt_num, err); } conn->pcb.tcp = NULL; net_free_socket(socketno); //printf("\nfree socket\n"); } } #if (RAW_SOCKET_USE_CUSTOM_PBUF) static struct raw_sk_pbuf_custom* raw_sk_alloc_pbuf_custom(void) { return (struct raw_sk_pbuf_custom*)mem_malloc(sizeof(struct raw_sk_pbuf_custom)); } static void raw_sk_free_pbuf_custom(struct raw_sk_pbuf_custom* p) { if(p != NULL) { mem_free(p); p = NULL; } } static void raw_sk_free_pbuf_custom_fn(struct pbuf *p) { struct raw_sk_pbuf_custom *pcr = (struct raw_sk_pbuf_custom*)p; if(p != NULL) { //printf("\nraw_sk_free_pbuf_custom_fn,len=%d, custom pcb=%x, conn=%x, conn pcb=%x\n\n",p->tot_len, pcr->pcb, pcr->conn, ((struct tls_netconn *)pcr->conn)->pcb.tcp); if(TRUE == ((struct tls_netconn *)pcr->conn)->used && pcr->pcb == ((struct tls_netconn *)pcr->conn)->pcb.tcp) { tcp_recved((struct tcp_pcb *)pcr->pcb, p->tot_len); } if (pcr->original != NULL) { // printf("\ngo to pbuf_free,original pbuf=%x\n",pcr->original); pbuf_free(pcr->original); } raw_sk_free_pbuf_custom(pcr); } } #endif /** * Receive callback function for TCP connect. */ static err_t net_tcp_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { struct tls_netconn *conn; struct tls_netconn *server_conn = NULL; err_t err_ret = ERR_OK; u16 datalen = 0; #if (RAW_SOCKET_USE_CUSTOM_PBUF) struct raw_sk_pbuf_custom *pcr = NULL; struct pbuf *newpbuf = NULL; #endif struct pbuf *p_tmp,*p_next; int socketno = -1; // TLS_DBGPRT_INFO("net_tcp_recv_cb err=%d\n", err); LWIP_UNUSED_ARG(pcb); LWIP_ASSERT("must have a pcb argument", pcb != NULL); LWIP_ASSERT("must have an argument", arg < 0); socketno = (int)arg; conn = tls_net_get_socket(socketno); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("\nconn=%x,used=%d\n",conn, conn->used); return ERR_ARG; } LWIP_ASSERT("tcp recv for wrong pcb!", conn->pcb.tcp == pcb); if (err) { /* tcp is disconnect */ TLS_DBGPRT_INFO("err code = %d\n", err); err_ret = err; #if 0 if (conn->pcb.tcp != NULL) { tcp_arg(conn->pcb.tcp, NULL); tcp_accept(conn->pcb.tcp, NULL); tcp_recv(conn->pcb.tcp, NULL); tcp_sent(conn->pcb.tcp, NULL); tcp_poll(conn->pcb.tcp, NULL, 4); tcp_err(conn->pcb.tcp, NULL); tcp_close(conn->pcb.tcp); conn->state = NETCONN_STATE_NONE; net_send_event_to_hostif(conn, NET_EVENT_TCP_DISCONNECT); conn->pcb.tcp = NULL; net_free_socket(conn); } #endif if(conn->skd != NULL && conn->skd->recvf != NULL) { TLS_DBGPRT_INFO("conn->skd->recvf to call."); err_ret = conn->skd->recvf(conn->skt_num, p, err); if(err_ret == ERR_ABRT) tcp_abort(pcb); p = NULL; } if (p){ pbuf_free(p); p = NULL; } return err_ret; } if (pcb == NULL ||conn == NULL) {//p == NULL || TLS_DBGPRT_INFO("pcb = 0x%x, p = 0x%x\n", pcb ,p); return ERR_VAL; } if(p == NULL) { TLS_DBGPRT_ERR("received 0\n"); net_tcp_err_cb((void *)socketno, ERR_OK); return ERR_OK; } #if 0//(RAW_SOCKET_USE_CUSTOM_PBUF) pcr = raw_sk_alloc_pbuf_custom(); if(pcr == NULL) { return ERR_MEM; } //newpbuf = pbuf_alloced_custom(PBUF_RAW, p->tot_len, PBUF_REF, &pcr->pc, p->payload, p->tot_len); newpbuf = &(pcr->pc); newpbuf->len = 0; newpbuf->payload = NULL; newpbuf->tot_len = p->tot_len; newpbuf->next = p; newpbuf->flags = PBUF_FLAG_IS_CUSTOM; newpbuf->type = PBUF_REF; newpbuf->ref =1; if (newpbuf == NULL) { raw_sk_free_pbuf_custom(pcr); return ERR_MEM; } pcr->original = p; pcr->param = pcb; pcr->pc.custom_free_function = raw_sk_free_pbuf_custom_fn; #endif #if !RAW_SOCKET_USE_CUSTOM_PBUF tcp_recved(pcb, p->tot_len); #endif if(conn->client && conn->idle_time > 0) { TLS_DBGPRT_INFO("conn->skt_num=%d, conn->client=%d\n", conn->skt_num, conn->client); // server_conn = dl_list_first(&conn->list, struct tls_netconn, list); server_conn = get_server_conn(conn); TLS_DBGPRT_INFO("server_conn=%p\n", server_conn); if(server_conn) { conn->idle_time = server_conn->idle_time; TLS_DBGPRT_INFO("update conn->idle_time %d\n", conn->idle_time); } } if(conn->skd->recvf != NULL) { tls_net_set_sourceip(ip_addr_get_ip4_u32(&pcb->remote_ip)); datalen = p->tot_len; if (conn->skd->recvwithipf != NULL){ //conn->skd->recvwithipf(conn->skt_num, datalen, (u8 *)(&(pcb->remote_ip.addr)), pcb->remote_port, ERR_OK); err_ret = conn->skd->recvwithipf(conn->skt_num, datalen, (u8 *)(&(ip_2_ip4(&pcb->remote_ip)->addr)), pcb->remote_port, ERR_OK); if(err_ret == ERR_ABRT) tcp_abort(pcb); } p_next = p; for(p_tmp = p; p_tmp != NULL; ) { p_next = p_tmp->next; p_tmp->next = NULL; if(err_ret == ERR_ABRT) { pbuf_free(p_tmp); } else if(err_ret == ERR_OK) { if(p_next != NULL) printf("\npbufcat p next=%x\n",(u32)p_next); #if (RAW_SOCKET_USE_CUSTOM_PBUF) pcr = raw_sk_alloc_pbuf_custom(); if(pcr == NULL) { return ERR_MEM; } newpbuf = pbuf_alloced_custom(PBUF_RAW, p_tmp->len, PBUF_REF, &pcr->pc, p_tmp->payload, p_tmp->len); if (newpbuf == NULL) { raw_sk_free_pbuf_custom(pcr); return ERR_MEM; } pcr->original = p_tmp; pcr->conn = conn; pcr->pcb = pcb; pcr->pc.custom_free_function = raw_sk_free_pbuf_custom_fn; err_ret = conn->skd->recvf(conn->skt_num, newpbuf, ERR_OK); #else err_ret = conn->skd->recvf(conn->skt_num, p_tmp, ERR_OK); #endif if(err_ret == ERR_ABRT) tcp_abort(pcb); } p_tmp = p_next; } } else { #if 0//(RAW_SOCKET_USE_CUSTOM_PBUF) raw_sk_free_pbuf_custom(pcr); #endif if (p) pbuf_free(p); } return err_ret; } #if 0 static err_t net_tcp_sent_cb(void *arg, struct tcp_pcb *pcb, u16_t len) { struct tls_netconn *conn = (struct tls_netconn *)arg; //TLS_DBGPRT_INFO("s\n"); if (conn->write_state && (conn->state == NETCONN_STATE_CONNECTED)) { net_do_writemore(conn); } else if (conn->state == NETCONN_STATE_CLOSED) { net_tcp_close_connect(conn); } return ERR_OK; } #endif /** * tcp connnect callback */ static err_t net_tcp_connect_cb(void *arg, struct tcp_pcb *pcb, err_t err) { struct tls_netconn *conn; err_t err_ret = ERR_OK; int socketno = -1; socketno = (int)arg; conn = tls_net_get_socket(socketno); if(conn == NULL || conn->used != TRUE){ TLS_DBGPRT_ERR("\nconn=%x,used=%d\n",conn, conn->used); tcp_abort(pcb); return ERR_ABRT; } //pcb = conn->pcb.tcp; if ((conn->proto == TLS_NETCONN_TCP) && (err == ERR_OK)) { TLS_DBGPRT_INFO("net_tcp_connect_cb =====> state : %d\n", pcb->state); conn->state = NETCONN_STATE_CONNECTED; net_send_event_to_hostif(conn, NET_EVENT_TCP_CONNECTED); } else { TLS_DBGPRT_INFO("the err is =%d\n", err); } if(conn->skd != NULL && conn->skd->connf != NULL) { err_ret = conn->skd->connf(conn->skt_num, err); if(err_ret == ERR_ABRT) tcp_abort(pcb); return err_ret; } return err; } /** * Accept callback function for TCP netconns. */ static err_t net_tcp_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t err_ret = ERR_OK; struct tls_netconn *conn = NULL; struct tls_netconn *newconn; struct tcp_pcb *pcb; u32 cpu_sr; int socketno = -1; //TLS_DBGPRT_INFO("=====>\n"); #if 0 if (conn->tcp_connect_cnt >= TLS_MAX_SOCKET_NUM) { return ERR_ABRT; } #endif socketno = (int)arg; conn = tls_net_get_socket(socketno); if(conn == NULL || conn->used != TRUE){ TLS_DBGPRT_ERR("\nconn=%x,used=%d\n",conn, conn->used); tcp_abort(newpcb); return ERR_ABRT; } if (conn){ tcp_accepted(conn->pcb.tcp); } newconn = net_alloc_socket(conn); //printf("\nnew conn==%x, new pcb==%x\n",newconn,newpcb); if (!newconn) { /* connection aborted */ /* not happen */ tcp_abort(newpcb); //printf("\r\nnet_tcp_accept_cb err\r\n"); return ERR_ABRT; } //conn->tcp_connect_cnt++; newconn->used = true; newconn->pcb.tcp = newpcb; newconn->client = true; newconn->idle_time = conn->idle_time; newconn->proto = TLS_NETCONN_TCP; newconn->state = NETCONN_STATE_CONNECTED; pcb = newconn->pcb.tcp; ip_set_option(newconn->pcb.tcp, SOF_KEEPALIVE); newconn->skd = conn->skd; tcp_arg(pcb, (void *)(newconn->skt_num)); tcp_recv(pcb, net_tcp_recv_cb); //tcp_sent(pcb, net_tcp_sent_cb); tcp_poll(pcb, net_tcp_poll_cb, 2); tcp_err(pcb, net_tcp_err_cb); cpu_sr = tls_os_set_critical(); dl_list_add_tail(&conn->list, &newconn->list); tls_os_release_critical(cpu_sr); newconn->port = host_to_le16(pcb->remote_port); newconn->localport = conn->localport; // ip_addr_set(&newconn->addr, &pcb->remote_ip); ip_addr_copy(newconn->addr, pcb->remote_ip); net_send_event_to_hostif(newconn, NET_EVENT_TCP_JOINED); if(conn->skd->acceptf != NULL) { err_ret =conn->skd->acceptf(newconn->skt_num, err); if(err_ret == ERR_ABRT) { tcp_abort(pcb); } } //conn->state = NETCONN_STATE_CONNECTED; return err_ret; } /** * Receive callback function for UDP netconns. */ static void net_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *srcaddr, u16_t port) { struct tls_netconn *conn; u32 datalen = 0; int socketno = -1; //TLS_DBGPRT_INFO("=====>\n"); LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); LWIP_ASSERT("recv_udp must have an argument", arg < 0); socketno = (int)arg; conn = tls_net_get_socket(socketno); if(conn == NULL || conn->used != TRUE || NULL == pcb){ TLS_DBGPRT_ERR("\nconn=%x,used=%d\n",conn, conn->used); if (p != NULL) pbuf_free(p); return; } LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); /* if (conn == NULL || pcb == NULL) { TLS_DBGPRT_INFO("if (conn == NULL || pcb == NULL) \n"); if (p != NULL) pbuf_free(p); return; } */ if(conn->skd->recvf != NULL) { datalen = p->tot_len; /*if Address is broadcast, update source IP according to source address and source port according to sender*/ // if ((conn->addr.addr == IPADDR_BROADCAST)||((conn->addr.addr & 0xFF) == 0xFF)) if((ip_addr_get_ip4_u32(&conn->addr) == IPADDR_BROADCAST) || ((ip_addr_get_ip4_u32(&conn->addr) & 0xFF) == 0xFF)) { tls_net_set_sourceip(ip_addr_get_ip4_u32(srcaddr)); conn->port = port; }else{ tls_net_set_sourceip(ip_addr_get_ip4_u32(&conn->addr)); } if (conn->skd->recvwithipf != NULL){ conn->skd->recvwithipf(conn->skt_num, datalen, (u8 *)(&(ip_2_ip4(srcaddr)->addr)), port, ERR_OK); } conn->skd->recvf(conn->skt_num, p, ERR_OK); } else { if (p){ pbuf_free(p); p = NULL; } } return; } /** * Start create TCP connection */ static err_t net_tcp_start(struct tls_netconn *conn) { struct tcp_pcb *pcb; err_t err; u16 localportnum = conn->localport; //TLS_DBGPRT_INFO("=====>\n"); conn->pcb.tcp = tcp_new(); pcb = conn->pcb.tcp; if (pcb == NULL) { TLS_DBGPRT_INFO("could not allocate tcp pcb\n"); return ERR_VAL; } tcp_arg(pcb, (void *)(conn->skt_num)); if (conn->client) { TLS_DBGPRT_INFO("pcb = 0x%x, conn->addr = 0x%x, port = %d, localport=%d\n", pcb, ip_addr_get_ip4_u32(&conn->addr), conn->port, conn->localport); tcp_err(pcb, net_tcp_err_cb); tcp_recv(pcb, net_tcp_recv_cb); //tcp_nagle_disable(pcb); if (pcb->recv != NULL) { TLS_DBGPRT_INFO("pcb->recv != NULL\n"); } //tcp_sent(pcb, net_tcp_sent_cb); tcp_poll(pcb, net_tcp_poll_cb, 4); ip_set_option(pcb, SOF_KEEPALIVE); if(localportnum > 0 && localportnum <= 0xFFFF) { err = tcp_bind(pcb, IP_ADDR_ANY, localportnum); if (err != ERR_OK) { TLS_DBGPRT_INFO("tcp bind failed %d\n", err); return err; } } err = tcp_connect(pcb, &conn->addr, conn->port, net_tcp_connect_cb); if (err != ERR_OK) { TLS_DBGPRT_INFO("tcp connect failed %d\n", err); return err; } if (conn->localport == 0){ conn->localport = pcb->local_port; } } else { TLS_DBGPRT_INFO("pcb ptr = 0x%x, conn->port = %d\n", pcb, conn->port); ip_set_option(pcb, SOF_REUSEADDR); err = tcp_bind(pcb, IP_ADDR_ANY, conn->port); if (err != ERR_OK) { TLS_DBGPRT_INFO("tcp bind failed %d\n", err); return err; } conn->pcb.tcp = tcp_listen(pcb); //ip_set_option(conn->pcb.tcp, SOF_KEEPALIVE); if (conn->pcb.tcp == NULL) { tcp_close(pcb); /* create tcp sever failed */ TLS_DBGPRT_INFO("tcp listen failed\n"); return ERR_VAL; } tcp_arg(conn->pcb.tcp, (void *)(conn->skt_num)); tcp_accept(conn->pcb.tcp, net_tcp_accept_cb); } return ERR_OK; } /** * Start create UDP connection */ static err_t net_udp_start(struct tls_netconn *conn) { struct udp_pcb *udppcb; u16 localportnum = conn->localport; udppcb = udp_new(); if(udppcb == NULL) { return ERR_MEM; } conn->pcb.udp = udppcb; if (udp_bind(udppcb, IP_ADDR_ANY, localportnum)!= ERR_OK){ TLS_DBGPRT_INFO("udp connect failed\n"); return ERR_CONN; } if (conn->localport == 0){ conn->localport = udppcb->local_port; } /* Set a receive callback for the upcb */ udp_recv(udppcb, net_udp_recv_cb, (void *)(conn->skt_num)); return ERR_OK; } #if 0 static err_t net_do_writemore(struct tls_netconn *conn) { err_t err = ERR_OK; void *dataptr; u16 len, available; u8 write_finished = 0; u32 diff; u8 apiflags = TCP_WRITE_FLAG_COPY; u8 dontblock = 0; dataptr = (u8_t*)conn->current_msg->dataptr + conn->current_msg->write_offset; diff = conn->current_msg->len - conn->current_msg->write_offset; if (diff > 0xffffUL) { /* max_u16_t */ len = 0xffff; apiflags |= TCP_WRITE_FLAG_MORE; } else { len = (u16_t)diff; } available = tcp_sndbuf(conn->pcb.tcp); if (available < len) { /* don't try to write more than sendbuf */ len = available; if (dontblock){ if (!len) { err = ERR_WOULDBLOCK; goto err_mem; } } else { apiflags |= TCP_WRITE_FLAG_MORE; } } err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); err_mem: if (err == ERR_OK) { conn->current_msg->write_offset += len; if ((conn->current_msg->write_offset == conn->current_msg->len) || dontblock) { /* everything was written */ write_finished = 1; conn->current_msg->write_offset = 0; } tcp_output(conn->pcb.tcp); } else if ((err == ERR_MEM) && !dontblock) { /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called we do NOT return to the application thread, since ERR_MEM is only a temporary error! */ /* tcp_write returned ERR_MEM, try tcp_output anyway */ tcp_output(conn->pcb.tcp); } else { /* On errors != ERR_MEM, we don't try writing any more but return the error to the application thread. */ write_finished = 1; conn->current_msg->len = 0; } if (write_finished) { /* everything was written: set back connection state and back to application task */ conn->current_msg->err = err; conn->write_state = false; tls_mem_free(conn->current_msg); conn->current_msg = NULL; } return ERR_OK; } #endif static err_t net_skt_tcp_send(struct tls_net_msg *net_msg) { struct tcp_pcb *pcb = NULL; struct tls_netconn *conn; err_t err; //TLS_DBGPRT_INFO("=====>\n"); conn = tls_net_get_socket(net_msg->skt_no); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("conn =%x,used=%d\n", conn, conn->used); return ERR_ARG; } pcb = conn->pcb.tcp; /* When tcp error occured, lwip will delete the pcb and sometimes GSKT. This function maybe registered by GSKT_TimerSend, so we must check if GSKT has been delted!!! */ err = tcp_write(pcb, net_msg->dataptr, net_msg->len, TCP_WRITE_FLAG_COPY); if (err == ERR_OK){ //sys_sem_signal(&net_msg->conn->op_completed); tcp_output(pcb); } else { // TLS_DBGPRT_INFO("err:%d\n", err); } return err; } /** * Send data on a UDP pcb */ static void net_do_send(void *ctx) { struct tls_net_msg *msg = (struct tls_net_msg *)ctx; struct tls_netconn *conn = NULL; struct pbuf *p; int socketno = msg->skt_no; //TLS_DBGPRT_INFO("=====>\n"); p = msg->p; conn = tls_net_get_socket(socketno); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("conn =%x,used=%d\n", conn, conn->used); if(p) pbuf_free(p); #if CONN_SEM_NOT_FREE sys_sem_signal(&conn_op_completed[socketno - 1]); #endif return; } #if LWIP_CHECKSUM_ON_COPY if (ip_addr_isany(&msg->addr)) { msg->err = udp_send_chksum(conn->pcb.udp, p, 0, 0); } else { msg->err = udp_sendto_chksum(conn->pcb.udp, p, &msg->addr, msg->port, 0, 0); } #else /* LWIP_CHECKSUM_ON_COPY */ if (ip_addr_isany(&msg->addr)) { msg->err = udp_send(conn->pcb.udp, p); } else { msg->err = udp_sendto(conn->pcb.udp, p, &msg->addr, msg->port); } #endif /* LWIP_CHECKSUM_ON_COPY */ pbuf_free(p); #if CONN_SEM_NOT_FREE sys_sem_signal(&conn_op_completed[socketno - 1]); #else conn = tls_net_get_socket(socketno); if(conn && TRUE == conn->used) { sys_sem_signal(&conn->op_completed); } #endif } /** * Send data on a TCP pcb */ static void net_do_write(void *ctx) { struct tls_net_msg *net_msg = (struct tls_net_msg *)ctx; struct tls_netconn *conn = NULL; struct tls_netconn *server_conn = NULL; int socketno = -1; //TLS_DBGPRT_INFO("=====>\n"); socketno = net_msg->skt_no; conn = tls_net_get_socket(socketno); if(conn == NULL ||TRUE != conn->used) { TLS_DBGPRT_ERR("\n conn=%x,used=%d\n",conn, conn->used); #if CONN_SEM_NOT_FREE sys_sem_signal(&conn_op_completed[socketno - 1]); #endif return; } //TLS_DBGPRT_INFO("s=%d,p=0x%x\n", conn->state, conn->pcb.tcp); #if 0 if (ERR_IS_FATAL(conn->last_err)) { net_msg->err = conn->last_err; } #endif if (conn->proto == TLS_NETCONN_TCP) { #if LWIP_TCP if (conn->state != NETCONN_STATE_CONNECTED) { /* netconn is connecting, closing or in blocking write */ net_msg->err = ERR_INPROGRESS; } else if (conn->pcb.tcp != NULL) { conn->write_state = true; //conn->write_offset = 0; net_msg->err = net_skt_tcp_send(net_msg); /* for both cases: if do_writemore was called, don't ACK the APIMSG since do_writemore ACKs it! */ } else { net_msg->err = ERR_CONN; TLS_DBGPRT_INFO("==>err=%d\n", net_msg->err); } if(conn->client && conn->idle_time > 0) { TLS_DBGPRT_INFO("conn->skt_num=%d, conn->client=%d\n", conn->skt_num, conn->client); // server_conn = dl_list_first(&conn->list, struct tls_netconn, list); server_conn = get_server_conn(conn); TLS_DBGPRT_INFO("server_conn=%p\n", server_conn); if(server_conn) { conn->idle_time = server_conn->idle_time; TLS_DBGPRT_INFO("update conn->idle_time %d\n", conn->idle_time); } } #else /* LWIP_TCP */ net_msg->err = ERR_VAL; #endif /* LWIP_TCP */ #if (LWIP_UDP || LWIP_RAW) } else { net_msg->err = ERR_VAL; #endif /* (LWIP_UDP || LWIP_RAW) */ } //tls_mem_free(net_msg->dataptr); //if(net_msg->err != ERR_OK) { //TLS_DBGPRT_INFO("conn->proto=%d, err=%d\n", conn->proto, net_msg->err); //TLS_DBGPRT_INFO("free net_msg->dataptr=%p\n", net_msg->dataptr); #if CONN_SEM_NOT_FREE sys_sem_signal(&conn_op_completed[socketno - 1]); #else conn = tls_net_get_socket(socketno); if(conn && TRUE == conn->used) { sys_sem_signal(&conn->op_completed); } #endif } #if 0 tls_mem_free(net_msg); #endif } static void do_create_connect(void *ctx) { struct tls_net_msg *net_msg = (struct tls_net_msg *)ctx; struct tls_netconn *conn; err_t err; int socketno = -1; //TLS_DBGPRT_INFO("=====>\n"); socketno = net_msg->skt_no; conn = tls_net_get_socket(socketno); if(conn == NULL || TRUE != conn->used) { tls_mem_free(net_msg); TLS_DBGPRT_ERR("\nconn=%x,usde=%d\n",conn, conn->used); return; } TLS_DBGPRT_INFO("conn ptr = 0x%x, conn->skt_num=%d, conn->client=%d\n", conn, conn->skt_num, conn->client); switch (conn->proto) { case TLS_NETCONN_UDP: err = net_udp_start(conn); if (err != ERR_OK){ conn->state = NETCONN_STATE_NONE; net_send_event_to_hostif(conn, NET_EVENT_UDP_START_FAILED); net_free_socket(socketno); }else{ conn->state = NETCONN_STATE_CONNECTED; net_send_event_to_hostif(conn, NET_EVENT_UDP_START); } break; case TLS_NETCONN_TCP: err = net_tcp_start(conn); if (err != ERR_OK){ conn->state = NETCONN_STATE_NONE; net_send_event_to_hostif(conn, NET_EVENT_TCP_CONNECT_FAILED); net_free_socket(socketno); }else{ if (!conn->client){ net_send_event_to_hostif(conn, NET_EVENT_TCP_CONNECTED); } //conn->state = NETCONN_STATE_CONNECTED; } break; default: /* Unsupported netconn type, e.g. protocol disabled */ break; } tls_mem_free(net_msg); return; } static void do_close_connect(void *ctx) { struct tls_net_msg *net_msg = (struct tls_net_msg *)ctx; struct tls_netconn *conn = NULL; struct tls_netconn *client_conn; int socketno = net_msg->skt_no; int i; int sktNums[TLS_MAX_SOCKET_NUM] = {-1};// 2*TLS_MAX_NETCONN_NUM conn = tls_net_get_socket(socketno); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("conn==%x,used=%d\n",conn, conn->used); tls_mem_free(net_msg); return; } switch (conn->proto) { case TLS_NETCONN_UDP: if (conn->pcb.udp != NULL) { conn->pcb.udp->recv_arg = NULL; udp_remove(conn->pcb.udp); conn->pcb.udp = NULL; } conn->state = NETCONN_STATE_CLOSED; break; case TLS_NETCONN_TCP: if (!conn->client) { /* it's a server, close connected client */ i=0; dl_list_for_each(client_conn, &conn->list, struct tls_netconn, list){ if (client_conn->used) { client_conn->state = NETCONN_STATE_CLOSED; sktNums[i++] = client_conn->skt_num; } } while(i-->0) { //client_conn = tls_net_get_socket(sktNums[i]); net_tcp_close_connect(sktNums[i]); } } conn->state = NETCONN_STATE_CLOSED; net_tcp_close_connect(socketno); break; default: break; } net_free_socket(socketno); tls_mem_free(net_msg); } int tls_socket_create(struct tls_socket_desc * skd) { struct tls_netconn *conn = NULL; struct tls_net_msg *net_msg; err_t err = ERR_OK; //TLS_DBGPRT_INFO("=====>socket_type=%d, skd->protocol=%d\n", socket_type, skd->protocol); if ((skd->protocol == SOCKET_PROTO_TCP) || (skd->protocol == SOCKET_PROTO_UDP)) { conn = net_alloc_socket(NULL); if (conn) { conn->client = (skd->cs_mode == SOCKET_CS_MODE_CLIENT); conn->proto = skd->protocol; if (conn->client){ IP_SET_TYPE(&skd->ip_addr, IPADDR_TYPE_V4); ip_addr_copy(conn->addr, skd->ip_addr); conn->state = NETCONN_STATE_NONE; } else { if(conn->proto == 1) ip_addr_set(&conn->addr, IP_ADDR_BROADCAST); else ip_addr_set(&conn->addr, IP_ADDR_ANY); conn->state = NETCONN_STATE_WAITING; } conn->port = skd->port; conn->localport = skd->localport; conn->idle_time = skd->timeout; conn->skd = skd; //conn->cmd_mode = cmd_mode; net_msg = tls_mem_alloc(sizeof(*net_msg)); if (net_msg == NULL) { net_free_socket(conn->skt_num); return -1; } memset(net_msg, 0, sizeof(*net_msg)); net_msg->skt_no = conn->skt_num; err = tcpip_callback_with_block(do_create_connect, net_msg, 0); if (err) { conn->state = NETCONN_STATE_NONE; net_free_socket(conn->skt_num); tls_mem_free(net_msg); } } else { return 0; } } else { err = ERR_VAL; } if (conn) return conn->skt_num; else return -1; } int tls_socket_get_status(u8 socket, u8 *buf, u32 bufsize) { struct tls_skt_status_t *skt_status; struct tls_skt_status_ext_t *skts_ext; struct tls_netconn *conn; struct tls_netconn *client_conn; struct tls_netconn *server_conn; int remain_len; skt_status = (struct tls_skt_status_t *)buf; if (bufsize < sizeof(struct tls_skt_status_t)) { TLS_DBGPRT_ERR("\nbufsize=%d\n",bufsize); return ERR_VAL; } if (socket < 1 || socket > 20) { TLS_DBGPRT_ERR("\nskt num=%d\n",socket); return ERR_VAL; } memset(buf, 0, bufsize); conn = tls_net_get_socket(socket); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("conn==%x,used=%d\n",conn, conn->used); return ERR_VAL; } remain_len = bufsize - sizeof(u32); skts_ext = (struct tls_skt_status_ext_t *)(buf + sizeof(u32)); if(conn == NULL){ skt_status->socket_cnt = 1; skts_ext->protocol = SOCKET_PROTO_TCP; skts_ext->status = 0; skts_ext->socket = socket; skts_ext->host_ipaddr[0] = 0; skts_ext->host_ipaddr[1] = 0; skts_ext->host_ipaddr[2] = 0; skts_ext->host_ipaddr[3] = 0; return 0; } skts_ext->protocol = (enum tls_socket_protocol)conn->proto; //TLS_DBGPRT_INFO("conn->client=%d, conn->state=%d, conn->used=%d\n", conn->client, conn->state,conn->used); if (conn->client) { skt_status->socket_cnt = 1; if (conn->used) { MEMCPY(skts_ext->host_ipaddr, (u8 *)ip_2_ip4(&conn->addr), 4); // server_conn = dl_list_first(&conn->list, struct tls_netconn, list); server_conn = get_server_conn(conn); if(server_conn != NULL){ // TLS_DBGPRT_INFO("server_conn->skt_num = %d\n", server_conn->skt_num); skts_ext->local_port = server_conn->localport; } else skts_ext->local_port = conn->localport; skts_ext->remote_port = conn->port; skts_ext->status = conn->state; /* connected */ skts_ext->socket = conn->skt_num; } else { skts_ext->status = conn->state; /* disconnect */ skts_ext->socket = conn->skt_num; } //TLS_DBGPRT_INFO("skts_ext->socket=%d, skts_ext->status=%d, conn->state=%d\n", skts_ext->socket, skts_ext->status, conn->state); } else { struct tls_ethif * ethif; ethif = tls_netif_get_ethif(); skt_status->socket_cnt = 1; if (conn->used) { skts_ext->status = conn->state; /* listen */ //MEMCPY(skts_ext->host_ipaddr, &conn->addr.addr, 4); //MEMCPY(skts_ext->host_ipaddr, (char *)&sys->ethif->nif->ip_addr.addr, 4); //MEMCPY(&conn->addr.addr, (char *)&sys->ethif->nif->ip_addr.addr, 4); //MEMCPY(skts_ext->host_ipaddr, (char *)ðif->ip_addr.addr, 4); MEMCPY(skts_ext->host_ipaddr, (char *)(ip_2_ip4(ðif->ip_addr)), 4); if(conn->proto == 1){ skts_ext->remote_port = conn->port; skts_ext->local_port = conn->localport; if(skts_ext->local_port==0) skts_ext->local_port = skts_ext->remote_port; MEMCPY(skts_ext->host_ipaddr, IP_ADDR_BROADCAST, 4); }else{ skts_ext->local_port = conn->port; skts_ext->remote_port = 0; } skts_ext->socket = conn->skt_num; remain_len -= sizeof(struct tls_skt_status_ext_t); dl_list_for_each(client_conn, &conn->list, struct tls_netconn, list){ if (remain_len < sizeof(struct tls_skt_status_ext_t)) break; if (client_conn->used) { skts_ext++; skts_ext->status = client_conn->state; /* connect */ skt_status->socket_cnt++; MEMCPY(skts_ext->host_ipaddr, (char *)ip_2_ip4(&client_conn->addr), 4); skts_ext->local_port = conn->port; skts_ext->remote_port = client_conn->port; skts_ext->socket = client_conn->skt_num; skts_ext->protocol = (enum tls_socket_protocol)client_conn->proto; remain_len -= sizeof(struct tls_skt_status_ext_t); } } } else { skts_ext->status = conn->state; skts_ext->socket = conn->skt_num; } } return 0; } struct tls_netconn * tls_net_get_socket(u8 socket) { struct tls_netconn *conn = NULL; if (socket < 1 || socket > TLS_MAX_NETCONN_NUM )//* 2 { TLS_DBGPRT_ERR("skt num=%d\n", socket); return NULL; } conn = p_net_conn[socket - 1]; //TLS_DBGPRT_INFO("conn->skt_num = %d\n", conn->skt_num); return conn; } int tls_socket_close(u8 socket) { struct tls_net_msg *net_msg; struct tls_netconn *conn; err_t err; //TLS_DBGPRT_INFO("socket=%d.\n", socket); if (socket < 1 || socket > TLS_MAX_NETCONN_NUM)//*2 { TLS_DBGPRT_ERR("skt num=%d\n", socket); return -1; } conn = tls_net_get_socket(socket); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("conn==%x,used=%d\n",conn, conn->used); return -1; } net_msg = tls_mem_alloc(sizeof(*net_msg)); if (net_msg == NULL) { TLS_DBGPRT_ERR("\nmem err\n"); return -1; } memset(net_msg, 0, sizeof(*net_msg)); net_msg->skt_no = socket; err = tcpip_callback_with_block(do_close_connect, net_msg, 0); if (err) { tls_mem_free(net_msg); } return err; } static err_t netconn_msg(tcpip_callback_fn function, struct tls_net_msg *net_msg, u8_t block) { err_t err = ERR_OK; struct tls_netconn *conn = NULL; conn = tls_net_get_socket(net_msg->skt_no); if(conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("netconn_msg conn=%x,used=%d\n",conn, conn->used); return ERR_ARG; } #if 1 err = tcpip_callback_with_block(function, net_msg, block); if(err) { //TLS_DBGPRT_INFO("free net_msg->dataptr=%p\n", net_msg->dataptr); //tls_mem_free(net_msg->dataptr); TLS_DBGPRT_INFO("callback end, err=%d\n", err); // tls_mem_free(net_msg); return err; } #if CONN_SEM_NOT_FREE sys_arch_sem_wait(&conn_op_completed[net_msg->skt_no - 1], 0); #else conn = tls_net_get_socket(net_msg->skt_no); if(conn != NULL && conn->op_completed != NULL) { sys_arch_sem_wait(&conn->op_completed, 0); conn = tls_net_get_socket(net_msg->skt_no); if(conn == NULL || TRUE != conn->used) { printf("wait error, conn is freeed\n"); } } #endif err = net_msg->err; return err; #else struct tls_net_msg *net_msg_item; if(conn->current_msg == NULL) { conn->current_msg = net_msg; } else { dl_list_add_tail(&conn->current_msg->list, &net_msg->list); } //TLS_DBGPRT_INFO("callback\n"); err = tcpip_callback_with_block(function, conn->current_msg, block); if(err) { TLS_DBGPRT_INFO("callback end, err=%d\n", err); return err; } sys_arch_sem_wait(&conn->op_completed, 0); //TLS_DBGPRT_INFO("callback end\n"); if(conn->current_msg->err) return conn->current_msg->err; dl_list_for_each(net_msg_item, &conn->current_msg->list, struct tls_net_msg, list){ err = tcpip_callback_with_block(function, net_msg_item, block); if(err) break; sys_arch_sem_wait(&conn->op_completed, 0); if(net_msg_item->err) break; dl_list_del(&net_msg_item->list); tls_mem_free(net_msg_item); } if(dl_list_empty(&conn->current_msg->list)) { tls_mem_free(conn->current_msg); conn->current_msg = NULL; } else { tls_mem_free(conn->current_msg); conn->current_msg = net_msg_item; } return ERR_OK; #endif } int tls_socket_udp_sendto(u16 localport, u8 *ip_addr, u16 port, void *pdata, u16 len) { struct tls_netconn *conn; struct tls_net_msg *net_msg = NULL; struct pbuf *p; int i; int err = 0; bool found = false; /* find match socket */ for (i = 0; iused && (localport== conn->port) && (conn->proto == TLS_NETCONN_UDP)) { found = true; break; } } if (!found) { TLS_DBGPRT_ERR("\nfound=0\n"); err = -1; goto out; } net_msg = tls_mem_alloc(sizeof(struct tls_net_msg)); if(!net_msg) return ERR_MEM; net_msg->len = len; net_msg->dataptr = pdata; /* udp */ while (1) { p = pbuf_alloc(PBUF_TRANSPORT, net_msg->len, PBUF_REF); if (p != NULL) { break; } else { /* delay 1 ticks */ tls_os_time_delay(1); } } p->payload = (void*)net_msg->dataptr; p->len = p->tot_len = net_msg->len; net_msg->err = ERR_VAL;/* for debug : catch not set err */ net_msg->p = p; net_msg->port = port; net_msg->skt_no = conn->skt_num; MEMCPY((char *)&(ip_2_ip4(&net_msg->addr)->addr), ip_addr, 4); IP_SET_TYPE(&net_msg->addr, IPADDR_TYPE_V4); err = netconn_msg(net_do_send, net_msg, 0); out: if( net_msg) /*Who allocates free it*/ tls_mem_free(net_msg); return err; } int tls_socket_send(u8 skt_num, void *pdata, u16 len) { struct tls_net_msg net_msg[1] = {0}; struct tls_netconn *conn; struct tls_netconn *client_conn; struct pbuf *p; err_t err = ERR_OK; u32 socket; u32 errornum = 0; socket = skt_num; dl_list_init(&net_msg->list); net_msg->len = len; net_msg->dataptr = pdata; if (socket < 1 || socket > TLS_MAX_NETCONN_NUM)//*2 { TLS_DBGPRT_ERR("\nskt num=%d\n",socket); return ERR_VAL; } conn = tls_net_get_socket(socket); if (conn == NULL || TRUE != conn->used) { TLS_DBGPRT_ERR("\nconn=%x,used=%d\n",conn, conn->used); return ERR_VAL; } if (conn->proto == TLS_NETCONN_UDP) { net_msg->skt_no = skt_num; net_msg->err = ERR_VAL;/* for debug : catch not set err */ do{ p = pbuf_alloc(PBUF_TRANSPORT, net_msg->len, PBUF_REF); if (p != NULL) { break; } else { TLS_DBGPRT_INFO("pbuf_alloc err.\n"); return ERR_VAL; } }while (0); p->payload = (void*)net_msg->dataptr; p->len = p->tot_len = net_msg->len; net_msg->p = p; net_msg->port = conn->port; // ip_addr_set(&net_msg->addr, &conn->addr); ip_addr_copy(net_msg->addr, conn->addr); err = netconn_msg(net_do_send, net_msg, 0); } else if (conn->proto == TLS_NETCONN_TCP) { if (conn->client) { net_msg->skt_no = skt_num; net_msg->err = ERR_VAL;/* for debug : catch not set err */ err = netconn_msg(net_do_write, net_msg, 0); } else { dl_list_for_each(client_conn, &conn->list, struct tls_netconn, list) { //printf("\nclient conn=%x,used==%d, sock num=%d, net conn=%x\n",client_conn, client_conn->used, client_conn->skt_num, p_net_conn[client_conn->skt_num - 1]); if (client_conn && TRUE == client_conn->used && client_conn == p_net_conn[client_conn->skt_num - 1]) { net_msg->skt_no = client_conn->skt_num; net_msg->err = ERR_VAL;/* for debug : catch not set err */ err = netconn_msg(net_do_write, net_msg, 0); if(err) { // TLS_DBGPRT_ERR("\nerr:%d\n",err); } } else { struct tls_netconn *conn_tmp; conn_tmp = tls_net_get_socket(socket); errornum ++; if(NULL == conn_tmp || errornum >= 4) { TLS_DBGPRT_ERR("\nconn=%x, errnum=%d\n", conn_tmp, errornum); err = ERR_VAL; break; } } } } } else { err = -1; } return err; } int tls_net_init() { //int i; memset(p_net_conn, 0, sizeof(struct tls_netconn *) * TLS_MAX_NETCONN_NUM); return 0; } #endif //TLS_CONFIG_SOCKET_RAW