summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2017-01-18 21:55:04 +0200
committerJukka Rissanen <jukka.rissanen@linux.intel.com>2017-01-27 15:06:06 +0200
commit7ad52b94cf40cb2dc6f8179ee63f93210939b429 (patch)
tree88f96e8445b0d9d601b86a48e419dee8e2dd5643
parent028896063f98ac1fb0d5c52fa4c5751dfb53d11f (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.c516
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
}