diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2017-01-18 21:55:04 +0200 |
---|---|---|
committer | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2017-01-27 15:06:06 +0200 |
commit | 7ad52b94cf40cb2dc6f8179ee63f93210939b429 (patch) | |
tree | 88f96e8445b0d9d601b86a48e419dee8e2dd5643 | |
parent | 028896063f98ac1fb0d5c52fa4c5751dfb53d11f (diff) |
net: echo-client: Add TCP support
This commit enables echo-client application to start to
send data over TCP connection.
Change-Id: I9acdaae7f1e8411952c30caeedc9c1fb07cdd448
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
-rw-r--r-- | samples/net/echo_client/src/echo-client.c | 516 |
1 files changed, 382 insertions, 134 deletions
diff --git a/samples/net/echo_client/src/echo-client.c b/samples/net/echo_client/src/echo-client.c index 86c6128db..f5aba7325 100644 --- a/samples/net/echo_client/src/echo-client.c +++ b/samples/net/echo_client/src/echo-client.c @@ -68,6 +68,32 @@ static char *lorem_ipsum = static int ipsum_len; +#define MY_PORT 8484 +#define PEER_PORT 4242 + +struct data { + uint32_t expecting_udp; + uint32_t expecting_tcp; + uint32_t received_tcp; +}; + +static struct { +#if defined(CONFIG_NET_UDP) + /* semaphore for controlling udp data sending */ + struct k_sem recv_ipv6; + struct k_sem recv_ipv4; +#endif /* CONFIG_NET_UDP */ + + struct data ipv4; + struct data ipv6; +} conf; + +#if defined(CONFIG_NET_TCP) +static bool send_tcp_data(struct net_context *ctx, + char *proto, + struct data *data); +#endif /* CONFIG_NET_TCP */ + #if defined(CONFIG_NET_IPV6) /* admin-local, dynamically allocated multicast address */ #define MCAST_IP6ADDR { { { 0xff, 0x84, 0, 0, 0, 0, 0, 0, \ @@ -85,8 +111,22 @@ static int ipsum_len; static struct in6_addr in6addr_my = MY_IP6ADDR; static struct in6_addr in6addr_peer = PEER_IP6ADDR; static struct in6_addr in6addr_mcast = MCAST_IP6ADDR; -static struct k_sem recv_ipv6; -static int expecting_ipv6; + +static struct sockaddr_in6 my_addr6 = { + .sin6_family = AF_INET6, + .sin6_port = htons(MY_PORT), +}; + +static struct sockaddr_in6 peer_addr6 = { + .sin6_family = AF_INET6, + .sin6_port = htons(PEER_PORT), +}; + +static struct sockaddr_in6 mcast_addr6 = { + .sin6_family = AF_INET6, + .sin6_port = htons(PEER_PORT), +}; + static char __noinit __stack ipv6_stack[STACKSIZE]; #endif /* CONFIG_NET_IPV6 */ @@ -100,15 +140,21 @@ static char __noinit __stack ipv6_stack[STACKSIZE]; static struct in_addr in4addr_my = MY_IP4ADDR; static struct in_addr in4addr_peer = PEER_IP4ADDR; -static struct k_sem recv_ipv4; -static int expecting_ipv4; + +static struct sockaddr_in my_addr4 = { + .sin_family = AF_INET, + .sin_port = htons(MY_PORT), +}; + +static struct sockaddr_in peer_addr4 = { + .sin_family = AF_INET, + .sin_port = htons(PEER_PORT), +}; + static char __noinit __stack ipv4_stack[STACKSIZE]; #endif /* CONFIG_NET_IPV4 */ -#define MY_PORT 8484 -#define PEER_PORT 4242 - #define WAIT_TIME (2 * MSEC_PER_SEC) #if defined(CONFIG_NET_MGMT_EVENT) @@ -120,21 +166,25 @@ static inline void init_app(void) NET_INFO("Run echo client"); #if defined(CONFIG_NET_IPV6) -#if defined(CONFIG_NET_SAMPLES_MY_IPV6_ADDR) +#if defined(CONFIG_NET_SAMPLES_IP_ADDRESSES) if (net_addr_pton(AF_INET6, CONFIG_NET_SAMPLES_MY_IPV6_ADDR, - (struct sockaddr *)&in6addr_my) < 0) { + (struct sockaddr *)&my_addr6.sin6_addr) < 0) { NET_ERR("Invalid IPv6 address %s", CONFIG_NET_SAMPLES_MY_IPV6_ADDR); + + net_ipaddr_copy(&my_addr6.sin6_addr, &in6addr_my); } #endif -#if defined(CONFIG_NET_SAMPLES_PEER_IPV6_ADDR) +#if defined(CONFIG_NET_SAMPLES_IP_ADDRESSES) if (net_addr_pton(AF_INET6, CONFIG_NET_SAMPLES_PEER_IPV6_ADDR, - (struct sockaddr *)&in6addr_peer) < 0) { + (struct sockaddr *)&peer_addr6.sin6_addr) < 0) { NET_ERR("Invalid peer IPv6 address %s", CONFIG_NET_SAMPLES_PEER_IPV6_ADDR); + + net_ipaddr_copy(&peer_addr6.sin6_addr, &in6addr_peer); } #endif @@ -142,74 +192,62 @@ static inline void init_app(void) struct net_if_addr *ifaddr; ifaddr = net_if_ipv6_addr_add(net_if_get_default(), - &in6addr_my, NET_ADDR_MANUAL, 0); + &my_addr6.sin6_addr, + NET_ADDR_MANUAL, 0); } while (0); + net_ipaddr_copy(&mcast_addr6.sin6_addr, &in6addr_mcast); net_if_ipv6_maddr_add(net_if_get_default(), &in6addr_mcast); - k_sem_init(&recv_ipv6, 0, UINT_MAX); +#if defined(CONFIG_NET_UDP) + k_sem_init(&conf.recv_ipv6, 0, UINT_MAX); +#endif #endif #if defined(CONFIG_NET_IPV4) #if defined(CONFIG_NET_DHCPV4) net_dhcpv4_start(net_if_get_default()); #else -#if defined(CONFIG_NET_SAMPLES_MY_IPV4_ADDR) +#if defined(CONFIG_NET_SAMPLES_IP_ADDRESSES) if (net_addr_pton(AF_INET, CONFIG_NET_SAMPLES_MY_IPV4_ADDR, - (struct sockaddr *)&in4addr_my) < 0) { + (struct sockaddr *)&my_addr4.sin_addr) < 0) { NET_ERR("Invalid IPv4 address %s", CONFIG_NET_SAMPLES_MY_IPV4_ADDR); + + net_ipaddr_copy(&my_addr4.sin_addr, &in4addr_my); } #endif -#if defined(CONFIG_NET_SAMPLES_PEER_IPV4_ADDR) +#if defined(CONFIG_NET_SAMPLES_IP_ADDRESSES) if (net_addr_pton(AF_INET, CONFIG_NET_SAMPLES_PEER_IPV4_ADDR, - (struct sockaddr *)&in4addr_peer) < 0) { + (struct sockaddr *)&peer_addr4.sin_addr) < 0) { NET_ERR("Invalid peer IPv4 address %s", CONFIG_NET_SAMPLES_PEER_IPV4_ADDR); + + net_ipaddr_copy(&peer_addr4.sin_addr, &in4addr_peer); } #endif - net_if_ipv4_addr_add(net_if_get_default(), &in4addr_my, + net_if_ipv4_addr_add(net_if_get_default(), &my_addr4.sin_addr, NET_ADDR_MANUAL, 0); #endif /* CONFIG_NET_DHCPV4 */ - k_sem_init(&recv_ipv4, 0, UINT_MAX); +#if defined(CONFIG_NET_UDP) + k_sem_init(&conf.recv_ipv4, 0, UINT_MAX); +#endif #endif } static inline bool get_context(struct net_context **udp_recv4, struct net_context **udp_recv6, + struct net_context **tcp_recv4, + struct net_context **tcp_recv6, struct net_context **mcast_recv6) { int ret; -#if defined(CONFIG_NET_IPV6) - struct sockaddr_in6 mcast_addr6 = { 0 }; - struct sockaddr_in6 my_addr6 = { 0 }; -#endif - -#if defined(CONFIG_NET_IPV4) - struct sockaddr_in my_addr4 = { 0 }; -#endif - -#if defined(CONFIG_NET_IPV6) - net_ipaddr_copy(&mcast_addr6.sin6_addr, &in6addr_mcast); - mcast_addr6.sin6_family = AF_INET6; - - net_ipaddr_copy(&my_addr6.sin6_addr, &in6addr_my); - my_addr6.sin6_family = AF_INET6; - my_addr6.sin6_port = htons(MY_PORT); -#endif - -#if defined(CONFIG_NET_IPV4) - net_ipaddr_copy(&my_addr4.sin_addr, &in4addr_my); - my_addr4.sin_family = AF_INET; - my_addr4.sin_port = htons(MY_PORT); -#endif - #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_UDP) ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, udp_recv6); if (ret < 0) { @@ -258,6 +296,47 @@ static inline bool get_context(struct net_context **udp_recv4, } #endif +#if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_TCP) + if (tcp_recv6) { + ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP, + tcp_recv6); + if (ret < 0) { + NET_ERR("Cannot get network context " + "for IPv6 TCP (%d)", ret); + return false; + } + + ret = net_context_bind(*tcp_recv6, + (struct sockaddr *)&my_addr6, + sizeof(struct sockaddr_in6)); + if (ret < 0) { + NET_ERR("Cannot bind IPv6 TCP port %d (%d)", + ntohs(my_addr6.sin6_port), ret); + return false; + } + } +#endif + +#if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_TCP) + if (tcp_recv4) { + ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP, + tcp_recv4); + if (ret < 0) { + NET_ERR("Cannot get network context for IPv4 TCP"); + return false; + } + + ret = net_context_bind(*tcp_recv4, + (struct sockaddr *)&my_addr4, + sizeof(struct sockaddr_in)); + if (ret < 0) { + NET_ERR("Cannot bind IPv4 TCP port %d", + ntohs(my_addr4.sin_port)); + return false; + } + } +#endif + return true; } @@ -320,7 +399,7 @@ static inline void set_dst_addr(sa_family_t family, #if defined(CONFIG_NET_IPV6) if (family == AF_INET6) { net_ipaddr_copy(&net_sin6(dst_addr)->sin6_addr, - &in6addr_peer); + &peer_addr6.sin6_addr); net_sin6(dst_addr)->sin6_family = AF_INET6; net_sin6(dst_addr)->sin6_port = htons(PEER_PORT); @@ -331,7 +410,7 @@ static inline void set_dst_addr(sa_family_t family, #if defined(CONFIG_NET_IPV4) if (family == AF_INET) { net_ipaddr_copy(&net_sin(dst_addr)->sin_addr, - &in4addr_peer); + &peer_addr4.sin_addr); net_sin(dst_addr)->sin_family = AF_INET; net_sin(dst_addr)->sin_port = htons(PEER_PORT); @@ -340,7 +419,8 @@ static inline void set_dst_addr(sa_family_t family, #endif /* CONFIG_NET_IPV4 */ } -static bool compare_data(struct net_buf *buf, int expecting_len) +#if defined(CONFIG_NET_UDP) +static bool compare_udp_data(struct net_buf *buf, int expecting_len) { uint8_t *ptr = net_nbuf_appdata(buf); int pos = 0; @@ -351,9 +431,9 @@ static bool compare_data(struct net_buf *buf, int expecting_len) */ buf = buf->frags; - /* Do not include the protocol headers in len for the - * first fragment. The remaining fragments contain only - * data so the user data length is directly the fragment len. + /* Do not include the protocol headers in the first fragment. + * The remaining fragments contain only data so the user data + * length is directly the fragment len. */ len = buf->len - (ptr - buf->data); @@ -390,37 +470,45 @@ static void setup_udp_recv(struct net_context *udp, void *user_data, } } -#if defined(CONFIG_NET_IPV4) -static bool send_ipv4_data(struct net_context *udp) +static bool send_udp_data(struct net_context *udp, + sa_family_t family, + char *proto, + struct data *data) { + bool status = false; struct net_buf *send_buf; struct sockaddr dst_addr; - bool status = false; + socklen_t addrlen; size_t len; int ret; - expecting_ipv4 = sys_rand32_get() % ipsum_len; + data->expecting_udp = sys_rand32_get() % ipsum_len; - send_buf = prepare_send_buf("IPv4", udp, expecting_ipv4); + send_buf = prepare_send_buf(proto, udp, data->expecting_udp); if (!send_buf) { goto out; } len = net_buf_frags_len(send_buf); - NET_ASSERT_INFO(expecting_ipv4 == len, + NET_ASSERT_INFO(data->expecting_udp == len, "Data to send %d bytes, real len %zu", - expecting_ipv4, len); + data->expecting_udp, len); - set_dst_addr(AF_INET, send_buf, &dst_addr); + set_dst_addr(family, send_buf, &dst_addr); + + if (family == AF_INET6) { + addrlen = sizeof(struct sockaddr_in6); + } else { + addrlen = sizeof(struct sockaddr_in); + } ret = net_context_sendto(send_buf, &dst_addr, - sizeof(struct sockaddr_in), - udp_sent, 0, + addrlen, udp_sent, 0, UINT_TO_POINTER(len), - "IPv4"); + proto); if (ret < 0) { - NET_ERR("Cannot send IPv4 data to peer (%d)", ret); + NET_ERR("Cannot send %s data to peer (%d)", proto, ret); net_nbuf_unref(send_buf); } else { status = true; @@ -430,145 +518,301 @@ out: return status; } -static void udp_ipv4_received(struct net_context *context, +static void udp_received(struct net_context *context, struct net_buf *buf, int status, void *user_data) { sa_family_t family = net_nbuf_family(buf); - struct k_sem *recv = user_data; + struct data *data = user_data; + struct k_sem *recv; ARG_UNUSED(context); ARG_UNUSED(status); if (family == AF_INET) { - if (expecting_ipv4 != net_nbuf_appdatalen(buf)) { - NET_ERR("Sent %d bytes, received %u bytes", - expecting_ipv4, net_nbuf_appdatalen(buf)); - } - - if (!compare_data(buf, expecting_ipv4)) { - NET_DBG("Data mismatch"); - } + recv = &conf.recv_ipv4; + } else { + recv = &conf.recv_ipv6; + } - net_nbuf_unref(buf); + if (data->expecting_udp != net_nbuf_appdatalen(buf)) { + NET_ERR("Sent %d bytes, received %u bytes", + data->expecting_udp, net_nbuf_appdatalen(buf)); + } - k_sem_give(recv); + if (!compare_udp_data(buf, data->expecting_udp)) { + NET_DBG("Data mismatch"); } + + net_nbuf_unref(buf); + + k_sem_give(recv); } -static void send_ipv4(struct net_context *udp) +static void send_udp(struct net_context *udp, + sa_family_t family, + char *proto, + struct k_sem *sem, + struct data *data) { - setup_udp_recv(udp, &recv_ipv4, udp_ipv4_received); + setup_udp_recv(udp, data, udp_received); - NET_INFO("Starting to send IPv4 data"); + NET_INFO("Starting to send %s data", proto); do { /* We first send a packet, then wait for a packet to arrive. * If the reply does not come in time, we send another packet. */ - send_ipv4_data(udp); + send_udp_data(udp, family, proto, data); - NET_DBG("Waiting IPv4 packet"); + NET_DBG("Waiting %s packet", proto); - if (!wait_reply("IPv4", &recv_ipv4)) { + if (!wait_reply(proto, sem)) { NET_DBG("Waited %d bytes but did not receive them.", - expecting_ipv4); + data->expecting_udp); } k_yield(); } while (1); } -#endif -#if defined(CONFIG_NET_IPV6) -static bool send_ipv6_data(struct net_context *udp) +#endif /* CONFIG_NET_UDP */ + +#if defined(CONFIG_NET_TCP) +static bool compare_tcp_data(struct net_buf *buf, int expecting_len, + int received_len) +{ + uint8_t *ptr = net_nbuf_appdata(buf), *start; + int pos = 0; + struct net_buf *frag; + int len; + + /* frag will point to first fragment with IP header in it. + */ + frag = buf->frags; + + /* Do not include the protocol headers for the first fragment. + * The remaining fragments contain only data so the user data + * length is directly the fragment len. + */ + len = frag->len - (ptr - frag->data); + + start = lorem_ipsum + received_len; + + while (frag) { + if (memcmp(ptr, start + pos, len)) { + NET_DBG("Invalid data received"); + return false; + } + + pos += len; + + frag = frag->frags; + if (!frag) { + break; + } + + ptr = frag->data; + len = frag->len; + } + + NET_DBG("Compared %d bytes, all ok", net_nbuf_appdatalen(buf)); + + return true; +} + +static void tcp_received(struct net_context *context, + struct net_buf *buf, + int status, + void *user_data) +{ + struct data *data = user_data; + char *proto; + + ARG_UNUSED(status); + + if (!buf || net_nbuf_appdatalen(buf) == 0) { + /* No need to unref the buf in this case, the IP stack + * will do it. + */ + return; + } + + if (net_nbuf_family(buf) == AF_INET6) { + proto = "IPv6"; + } else { + proto = "IPv4"; + } + + NET_DBG("Sent %d bytes, received %u bytes", + data->expecting_tcp, net_nbuf_appdatalen(buf)); + + if (!compare_tcp_data(buf, data->expecting_tcp, data->received_tcp)) { + NET_DBG("Data mismatch"); + } else { + data->received_tcp += net_nbuf_appdatalen(buf); + } + + if (data->expecting_tcp <= data->received_tcp) { + /* Send more data */ + send_tcp_data(context, proto, data); + } + + net_nbuf_unref(buf); +} + +static void setup_tcp_recv(struct net_context *tcp, + net_context_recv_cb_t cb, + void *user_data) +{ + int ret; + + ret = net_context_recv(tcp, cb, 0, user_data); + if (ret < 0) { + NET_ERR("Cannot receive TCP packets (%d)", ret); + } +} + +static void tcp_sent(struct net_context *context, + int status, + void *token, + void *user_data) +{ + uint32_t len = POINTER_TO_UINT(token); + + if (len) { + if (status) { + NET_DBG("%s: len %u status %d", (char *)user_data, + len, status); + } else { + NET_DBG("%s: len %u", (char *)user_data, len); + } + } +} + +static bool send_tcp_data(struct net_context *ctx, + char *proto, + struct data *data) { struct net_buf *send_buf; - struct sockaddr dst_addr; bool status = false; size_t len; int ret; - expecting_ipv6 = sys_rand32_get() % ipsum_len; + data->expecting_tcp = sys_rand32_get() % ipsum_len; + data->received_tcp = 0; - send_buf = prepare_send_buf("IPv6", udp, expecting_ipv6); + send_buf = prepare_send_buf(proto, ctx, data->expecting_tcp); if (!send_buf) { goto out; } len = net_buf_frags_len(send_buf); - NET_ASSERT_INFO(expecting_ipv6 == len, - "Data to send %d bytes, real len %zu", - expecting_ipv6, len); - - set_dst_addr(AF_INET6, send_buf, &dst_addr); + NET_ASSERT_INFO(data->expecting_tcp == len, + "%s data to send %d bytes, real len %zu", + proto, data->expecting_tcp, len); - ret = net_context_sendto(send_buf, &dst_addr, - sizeof(struct sockaddr_in6), - udp_sent, 0, - UINT_TO_POINTER(len), - "IPv6"); + ret = net_context_send(send_buf, tcp_sent, 0, + UINT_TO_POINTER(len), proto); if (ret < 0) { - NET_ERR("Cannot send IPv6 data to peer (%d)", ret); + NET_ERR("Cannot send %s data to peer (%d)", proto, ret); net_nbuf_unref(send_buf); } else { status = true; } -out: +out: return status; } -static void udp_ipv6_received(struct net_context *context, - struct net_buf *buf, - int status, - void *user_data) +static void tcp_connected(struct net_context *context, + int status, + void *user_data) { - sa_family_t family = net_nbuf_family(buf); - struct k_sem *recv = user_data; + /* Start to send data */ + sa_family_t family = POINTER_TO_UINT(user_data); - ARG_UNUSED(context); - ARG_UNUSED(status); + NET_DBG("%s connected.", family == AF_INET ? "IPv4" : "IPv6"); - if (family == AF_INET6) { - if (expecting_ipv6 != net_nbuf_appdatalen(buf)) { - NET_ERR("Sent %d bytes, received %d bytes", - expecting_ipv6, net_nbuf_appdatalen(buf)); - } + if (family == AF_INET) { +#if defined(CONFIG_NET_IPV4) + setup_tcp_recv(context, tcp_received, &conf.ipv4); - if (!compare_data(buf, expecting_ipv6)) { - NET_DBG("Data mismatch"); - } + send_tcp_data(context, "IPv4", &conf.ipv4); +#else + NET_DBG("IPv4 data skipped."); +#endif + } else if (family == AF_INET6) { +#if defined(CONFIG_NET_IPV6) + setup_tcp_recv(context, tcp_received, &conf.ipv6); + + send_tcp_data(context, "IPv6", &conf.ipv6); +#else + NET_DBG("IPv6 data skipped."); +#endif + } +} - net_nbuf_unref(buf); +#if defined(CONFIG_NET_IPV4) +static void tcp_connect4(struct net_context *tcp_send) +{ + int ret; - k_sem_give(recv); + ret = net_context_connect(tcp_send, + (struct sockaddr *)&peer_addr4, + sizeof(peer_addr4), + tcp_connected, + K_FOREVER, + UINT_TO_POINTER(AF_INET)); + if (ret < 0) { + NET_DBG("Cannot connect to IPv4 peer (%d)", ret); } } +#endif -static void send_ipv6(struct net_context *udp) +#if defined(CONFIG_NET_IPV6) +static void tcp_connect6(struct net_context *tcp_send) { - setup_udp_recv(udp, &recv_ipv6, udp_ipv6_received); + int ret; - NET_INFO("Starting to send IPv6 data"); + ret = net_context_connect(tcp_send, + (struct sockaddr *)&peer_addr6, + sizeof(peer_addr6), + tcp_connected, + K_FOREVER, + UINT_TO_POINTER(AF_INET6)); + if (ret < 0) { + NET_DBG("Cannot connect to IPv6 peer (%d)", ret); + } +} +#endif /* CONFIG_NET_IPV6 */ +#endif /* CONFIG_NET_TCP */ - do { - /* We first send a packet, then wait for a packet to arrive. - * If the reply does not come in time, we send another packet. - */ - send_ipv6_data(udp); +#if defined(CONFIG_NET_IPV4) +static void send_ipv4(struct net_context *udp, struct net_context *tcp) +{ +#if defined(CONFIG_NET_TCP) + tcp_connect4(tcp); +#endif - NET_DBG("Waiting IPv6 packet"); +#if defined(CONFIG_NET_UDP) + send_udp(udp, AF_INET, "IPv4", &conf.recv_ipv4, &conf.ipv4); +#endif +} +#endif - if (!wait_reply("IPv6", &recv_ipv6)) { - NET_DBG("Waited %d bytes but did not receive them.", - expecting_ipv6); - } +#if defined(CONFIG_NET_IPV6) +static void send_ipv6(struct net_context *udp, struct net_context *tcp) +{ +#if defined(CONFIG_NET_TCP) + tcp_connect6(tcp); +#endif - k_yield(); - } while (1); +#if defined(CONFIG_NET_UDP) + send_udp(udp, AF_INET6, "IPv6", &conf.recv_ipv6, &conf.ipv6); +#endif } #endif @@ -577,11 +821,15 @@ static void event_iface_up(struct net_mgmt_event_callback *cb, { struct net_context *udp_send4 = { 0 }; struct net_context *udp_send6 = { 0 }; + struct net_context *tcp_send4 = { 0 }; + struct net_context *tcp_send6 = { 0 }; struct net_context *mcast_send6 = { 0 }; ipsum_len = strlen(lorem_ipsum); - if (!get_context(&udp_send4, &udp_send6, &mcast_send6)) { + if (!get_context(&udp_send4, &udp_send6, + &tcp_send4, &tcp_send6, + &mcast_send6)) { NET_ERR("Cannot get network contexts"); return; } @@ -589,13 +837,13 @@ static void event_iface_up(struct net_mgmt_event_callback *cb, #if defined(CONFIG_NET_IPV4) k_thread_spawn(ipv4_stack, STACKSIZE, (k_thread_entry_t)send_ipv4, - udp_send4, NULL, NULL, K_PRIO_COOP(7), 0, 0); + udp_send4, tcp_send4, NULL, K_PRIO_COOP(7), 0, 0); #endif #if defined(CONFIG_NET_IPV6) k_thread_spawn(ipv6_stack, STACKSIZE, (k_thread_entry_t)send_ipv6, - udp_send6, NULL, NULL, K_PRIO_COOP(7), 0, 0); + udp_send6, tcp_send6, NULL, K_PRIO_COOP(7), 0, 0); #endif } |