1 /*
2 * Copyright (c) 2023 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
9
10 #include <stdio.h>
11 #include <zephyr/ztest_assert.h>
12
13 #include <zephyr/net/socket_service.h>
14
15 #include "../../socket_helpers.h"
16
17 #define BUF_AND_SIZE(buf) buf, sizeof(buf) - 1
18 #define STRLEN(buf) (sizeof(buf) - 1)
19
20 #define TEST_STR_SMALL "test"
21
22 #define MY_IPV6_ADDR "::1"
23
24 #define ANY_PORT 0
25 #define SERVER_PORT 4242
26 #define CLIENT_PORT 9898
27
28 #define TCP_TEARDOWN_TIMEOUT K_SECONDS(3)
29
30 K_SEM_DEFINE(wait_data, 0, UINT_MAX);
31 K_SEM_DEFINE(wait_data_tcp, 0, UINT_MAX);
32 #define WAIT_TIME 500
33
server_handler(struct net_socket_service_event * pev)34 static void server_handler(struct net_socket_service_event *pev)
35 {
36 ARG_UNUSED(pev);
37
38 k_sem_give(&wait_data);
39 }
40
tcp_server_handler(struct net_socket_service_event * pev)41 static void tcp_server_handler(struct net_socket_service_event *pev)
42 {
43 ARG_UNUSED(pev);
44
45 k_sem_give(&wait_data_tcp);
46
47 k_yield();
48
49 Z_SPIN_DELAY(100);
50 }
51
52 NET_SOCKET_SERVICE_SYNC_DEFINE(udp_service_sync, server_handler, 2);
53 NET_SOCKET_SERVICE_SYNC_DEFINE(tcp_service_small_sync, tcp_server_handler, 1);
54 NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(tcp_service_sync, tcp_server_handler, 2);
55
56
run_test_service(const struct net_socket_service_desc * udp_service,const struct net_socket_service_desc * tcp_service_small,const struct net_socket_service_desc * tcp_service)57 void run_test_service(const struct net_socket_service_desc *udp_service,
58 const struct net_socket_service_desc *tcp_service_small,
59 const struct net_socket_service_desc *tcp_service)
60 {
61 int ret;
62 int c_sock_udp;
63 int s_sock_udp;
64 int c_sock_tcp;
65 int s_sock_tcp;
66 int new_sock;
67 struct sockaddr_in6 c_addr;
68 struct sockaddr_in6 s_addr;
69 ssize_t len;
70 char buf[10];
71 struct zsock_pollfd sock[2] = {
72 [0] = { .fd = -1 },
73 [1] = { .fd = -1 },
74 };
75
76 prepare_sock_udp_v6(MY_IPV6_ADDR, CLIENT_PORT, &c_sock_udp, &c_addr);
77 prepare_sock_udp_v6(MY_IPV6_ADDR, SERVER_PORT, &s_sock_udp, &s_addr);
78 prepare_sock_tcp_v6(MY_IPV6_ADDR, CLIENT_PORT, &c_sock_tcp, &c_addr);
79 prepare_sock_tcp_v6(MY_IPV6_ADDR, SERVER_PORT, &s_sock_tcp, &s_addr);
80
81 sock[0].fd = s_sock_udp;
82 sock[0].events = ZSOCK_POLLIN;
83
84 ret = net_socket_service_register(udp_service, sock, ARRAY_SIZE(sock), NULL);
85 zassert_equal(ret, 0, "Cannot register udp service (%d)", ret);
86
87 sock[0].fd = s_sock_tcp;
88 sock[0].events = ZSOCK_POLLIN;
89
90 ret = net_socket_service_register(tcp_service_small, sock, ARRAY_SIZE(sock) + 1, NULL);
91 zassert_equal(ret, -ENOMEM, "Could register tcp service (%d)", ret);
92
93 ret = net_socket_service_register(tcp_service, sock, ARRAY_SIZE(sock), NULL);
94 zassert_equal(ret, 0, "Cannot register tcp service (%d)", ret);
95
96 ret = bind(s_sock_udp, (struct sockaddr *)&s_addr, sizeof(s_addr));
97 zassert_equal(ret, 0, "bind failed");
98
99 ret = connect(c_sock_udp, (struct sockaddr *)&s_addr, sizeof(s_addr));
100 zassert_equal(ret, 0, "connect failed");
101
102 /* Send pkt for s_sock_udp and poll with timeout of 10 */
103 len = send(c_sock_udp, BUF_AND_SIZE(TEST_STR_SMALL), 0);
104 zassert_equal(len, STRLEN(TEST_STR_SMALL), "invalid send len");
105
106 if (k_sem_take(&wait_data, K_MSEC(WAIT_TIME))) {
107 zassert_true(0, "Timeout while waiting callback");
108 }
109
110 /* Recv pkt from s_sock_udp and ensure no poll events happen */
111 len = recv(s_sock_udp, BUF_AND_SIZE(buf), 0);
112 zassert_equal(len, STRLEN(TEST_STR_SMALL), "invalid recv len");
113
114 ret = bind(s_sock_tcp, (struct sockaddr *)&s_addr, sizeof(s_addr));
115 zassert_equal(ret, 0, "bind failed (%d)", -errno);
116 ret = listen(s_sock_tcp, 0);
117 zassert_equal(ret, 0, "");
118
119 ret = connect(c_sock_tcp, (const struct sockaddr *)&s_addr,
120 sizeof(s_addr));
121 zassert_equal(ret, 0, "");
122
123 /* Let the network stack run */
124 k_msleep(10);
125
126 len = send(c_sock_tcp, BUF_AND_SIZE(TEST_STR_SMALL), 0);
127 zassert_equal(len, STRLEN(TEST_STR_SMALL), "invalid send len");
128
129 if (k_sem_take(&wait_data_tcp, K_MSEC(WAIT_TIME))) {
130 zassert_true(0, "Timeout while waiting callback");
131 }
132
133 new_sock = accept(s_sock_tcp, NULL, NULL);
134 zassert_true(new_sock >= 0, "");
135
136 sock[1].fd = new_sock;
137 sock[1].events = ZSOCK_POLLIN;
138
139 ret = net_socket_service_register(tcp_service, sock, ARRAY_SIZE(sock), NULL);
140 zassert_equal(ret, 0, "Cannot register tcp service (%d)", ret);
141
142 if (k_sem_take(&wait_data_tcp, K_MSEC(WAIT_TIME))) {
143 zassert_true(0, "Timeout while waiting callback");
144 }
145
146 len = recv(new_sock, BUF_AND_SIZE(buf), 0);
147 zassert_equal(len, STRLEN(TEST_STR_SMALL), "invalid recv len");
148
149 ret = net_socket_service_unregister(tcp_service);
150 zassert_equal(ret, 0, "Cannot unregister tcp service (%d)", ret);
151
152 ret = net_socket_service_unregister(udp_service);
153 zassert_equal(ret, 0, "Cannot unregister tcp service (%d)", ret);
154
155 ret = net_socket_service_unregister(tcp_service_small);
156 zassert_equal(ret, 0, "Cannot unregister tcp service (%d)", ret);
157
158 ret = close(new_sock);
159 zassert_equal(ret, 0, "close failed");
160
161 ret = close(c_sock_tcp);
162 zassert_equal(ret, 0, "close failed");
163
164 ret = close(s_sock_tcp);
165 zassert_equal(ret, 0, "close failed");
166
167 ret = close(c_sock_udp);
168 zassert_equal(ret, 0, "close failed");
169
170 ret = close(s_sock_udp);
171 zassert_equal(ret, 0, "close failed");
172
173 /* Let the stack close the TCP sockets properly */
174 k_msleep(100);
175 }
176
ZTEST(net_socket_service,test_service_sync)177 ZTEST(net_socket_service, test_service_sync)
178 {
179 run_test_service(&udp_service_sync, &tcp_service_small_sync,
180 &tcp_service_sync);
181 }
182
183 ZTEST_SUITE(net_socket_service, NULL, NULL, NULL, NULL, NULL);
184