The POSIX_MAX_FDS option does not correspond to any standard POSIX option. It was used to define the size of the file descriptor table, which is by no means exclusively used by POSIX (also net, fs, ...). POSIX_MAX_FDS is being deprecated in order to ensure that Zephyr's POSIX Kconfig variables correspond to those defined in the specification, as of IEEE 1003.1-2017. Namely, POSIX_OPEN_MAX. CONFIG_POSIX_MAX_OPEN_FILES is being deprecated for the same reason. To mitigate any possible layering violations, that option is not user selectable. It tracks the newly added CONFIG_ZVFS_OPEN_MAX option, which is native to Zephyr. With this deprecation, we introduce the following Kconfig options that map directly to standard POSIX Option Groups by simply removing "CONFIG_": * CONFIG_POSIX_DEVICE_IO Similarly, with this deprecation, we introduce the following Kconfig options that map directly to standard POSIX Options by simply removing "CONFIG": * CONFIG_POSIX_OPEN_MAX In order to maintain parity with the current feature set, we introduce the following Kconfig options. * CONFIG_POSIX_DEVICE_IO_ALIAS_CLOSE * CONFIG_POSIX_DEVICE_IO_ALIAS_OPEN * CONFIG_POSIX_DEVICE_IO_ALIAS_READ * CONFIG_POSIX_DEVICE_IO_ALIAS_WRITE Gate open(), close(), read(), and write() via the CONFIG_POSIX_DEVICE_IO Kconfig option and move implementations into device_io.c, to be conformant with the spec. Lastly, stage function names for upcoming ZVFS work, to be completed as part of the LTSv3 Roadmap (e.g. zvfs_open(), ..). Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
184 lines
5.1 KiB
C
184 lines
5.1 KiB
C
/*
|
|
* Copyright (c) 2019 Linaro Limited
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
|
|
|
|
#include <stdio.h>
|
|
#include <zephyr/ztest_assert.h>
|
|
|
|
#include <zephyr/net/socket.h>
|
|
|
|
#include "../../socket_helpers.h"
|
|
|
|
#define BUF_AND_SIZE(buf) buf, sizeof(buf) - 1
|
|
#define STRLEN(buf) (sizeof(buf) - 1)
|
|
|
|
#define TEST_STR_SMALL "test"
|
|
|
|
#define MY_IPV6_ADDR "::1"
|
|
|
|
#define ANY_PORT 0
|
|
#define SERVER_PORT 4242
|
|
#define CLIENT_PORT 9898
|
|
|
|
/* Fudge factor added to expected timeouts, in milliseconds. */
|
|
#define FUZZ 60
|
|
|
|
#define TIMEOUT_MS 60
|
|
|
|
ZTEST_USER(net_socket_select, test_fd_set)
|
|
{
|
|
zsock_fd_set set;
|
|
|
|
/* Relies on specific value of CONFIG_ZVFS_OPEN_MAX in prj.conf */
|
|
zassert_equal(sizeof(set.bitset), sizeof(uint32_t) * 2, "");
|
|
|
|
ZSOCK_FD_ZERO(&set);
|
|
zassert_equal(set.bitset[0], 0, "");
|
|
zassert_equal(set.bitset[1], 0, "");
|
|
zassert_false(ZSOCK_FD_ISSET(0, &set), "");
|
|
|
|
ZSOCK_FD_SET(0, &set);
|
|
zassert_true(ZSOCK_FD_ISSET(0, &set), "");
|
|
|
|
ZSOCK_FD_CLR(0, &set);
|
|
zassert_false(ZSOCK_FD_ISSET(0, &set), "");
|
|
|
|
ZSOCK_FD_SET(0, &set);
|
|
zassert_equal(set.bitset[0], 0x00000001, "");
|
|
zassert_equal(set.bitset[1], 0, "");
|
|
|
|
ZSOCK_FD_SET(31, &set);
|
|
zassert_equal(set.bitset[0], 0x80000001, "");
|
|
zassert_equal(set.bitset[1], 0, "");
|
|
|
|
ZSOCK_FD_SET(33, &set);
|
|
zassert_equal(set.bitset[0], 0x80000001, "");
|
|
zassert_equal(set.bitset[1], 0x00000002, "");
|
|
|
|
ZSOCK_FD_ZERO(&set);
|
|
zassert_equal(set.bitset[0], 0, "");
|
|
zassert_equal(set.bitset[1], 0, "");
|
|
}
|
|
|
|
ZTEST_USER(net_socket_select, test_select)
|
|
{
|
|
int res;
|
|
int c_sock;
|
|
int s_sock;
|
|
struct sockaddr_in6 c_addr;
|
|
struct sockaddr_in6 s_addr;
|
|
zsock_fd_set readfds;
|
|
uint32_t tstamp;
|
|
ssize_t len;
|
|
char buf[10];
|
|
struct timeval tval;
|
|
|
|
prepare_sock_udp_v6(MY_IPV6_ADDR, CLIENT_PORT, &c_sock, &c_addr);
|
|
prepare_sock_udp_v6(MY_IPV6_ADDR, SERVER_PORT, &s_sock, &s_addr);
|
|
|
|
res = zsock_bind(s_sock, (struct sockaddr *)&s_addr, sizeof(s_addr));
|
|
zassert_equal(res, 0, "bind failed");
|
|
|
|
res = zsock_connect(c_sock, (struct sockaddr *)&s_addr, sizeof(s_addr));
|
|
zassert_equal(res, 0, "connect failed");
|
|
|
|
ZSOCK_FD_ZERO(&readfds);
|
|
ZSOCK_FD_SET(c_sock, &readfds);
|
|
ZSOCK_FD_SET(s_sock, &readfds);
|
|
|
|
/* Poll non-ready fd's with timeout of 0 */
|
|
tval.tv_sec = tval.tv_usec = 0;
|
|
tstamp = k_uptime_get_32();
|
|
res = zsock_select(s_sock + 1, &readfds, NULL, NULL, &tval);
|
|
tstamp = k_uptime_get_32() - tstamp;
|
|
/* Even though we expect select to be non-blocking, scheduler may
|
|
* preempt the thread. That's why we add FUZZ to the expected
|
|
* delay time. Also applies to similar cases below.
|
|
*/
|
|
zassert_true(tstamp <= FUZZ, "");
|
|
zassert_equal(res, 0, "");
|
|
|
|
zassert_false(ZSOCK_FD_ISSET(c_sock, &readfds), "");
|
|
zassert_false(ZSOCK_FD_ISSET(s_sock, &readfds), "");
|
|
|
|
/* Poll non-ready fd's with timeout of 10ms */
|
|
ZSOCK_FD_SET(c_sock, &readfds);
|
|
ZSOCK_FD_SET(s_sock, &readfds);
|
|
tval.tv_sec = 0;
|
|
tval.tv_usec = TIMEOUT_MS * 1000;
|
|
tstamp = k_uptime_get_32();
|
|
res = zsock_select(s_sock + 1, &readfds, NULL, NULL, &tval);
|
|
tstamp = k_uptime_get_32() - tstamp;
|
|
zassert_true(tstamp >= TIMEOUT_MS && tstamp <= TIMEOUT_MS + FUZZ, "");
|
|
zassert_equal(res, 0, "");
|
|
|
|
|
|
/* Send pkt for s_sock and poll with timeout of 10ms */
|
|
len = zsock_send(c_sock, BUF_AND_SIZE(TEST_STR_SMALL), 0);
|
|
zassert_equal(len, STRLEN(TEST_STR_SMALL), "invalid send len");
|
|
|
|
ZSOCK_FD_SET(c_sock, &readfds);
|
|
ZSOCK_FD_SET(s_sock, &readfds);
|
|
tval.tv_sec = 0;
|
|
tval.tv_usec = TIMEOUT_MS * 1000;
|
|
tstamp = k_uptime_get_32();
|
|
res = zsock_select(s_sock + 1, &readfds, NULL, NULL, &tval);
|
|
tstamp = k_uptime_get_32() - tstamp;
|
|
zassert_true(tstamp <= FUZZ, "");
|
|
zassert_equal(res, 1, "");
|
|
|
|
zassert_false(ZSOCK_FD_ISSET(c_sock, &readfds), "");
|
|
zassert_true(ZSOCK_FD_ISSET(s_sock, &readfds), "");
|
|
|
|
|
|
/* Recv pkt from s_sock and ensure no poll events happen */
|
|
len = zsock_recv(s_sock, BUF_AND_SIZE(buf), 0);
|
|
zassert_equal(len, STRLEN(TEST_STR_SMALL), "invalid recv len");
|
|
|
|
ZSOCK_FD_SET(c_sock, &readfds);
|
|
ZSOCK_FD_SET(s_sock, &readfds);
|
|
tval.tv_sec = tval.tv_usec = 0;
|
|
tstamp = k_uptime_get_32();
|
|
res = zsock_select(s_sock + 1, &readfds, NULL, NULL, &tval);
|
|
zassert_true(k_uptime_get_32() - tstamp <= FUZZ, "");
|
|
zassert_equal(res, 0, "");
|
|
zassert_false(ZSOCK_FD_ISSET(s_sock, &readfds), "");
|
|
|
|
|
|
/* Close one socket and ensure POLLNVAL happens */
|
|
res = zsock_close(c_sock);
|
|
zassert_equal(res, 0, "close failed");
|
|
|
|
ZSOCK_FD_SET(c_sock, &readfds);
|
|
ZSOCK_FD_SET(s_sock, &readfds);
|
|
tval.tv_sec = tval.tv_usec = 0;
|
|
tstamp = k_uptime_get_32();
|
|
res = zsock_select(s_sock + 1, &readfds, NULL, NULL, &tval);
|
|
zassert_true(k_uptime_get_32() - tstamp <= FUZZ, "");
|
|
zassert_true(res < 0, "");
|
|
zassert_equal(errno, EBADF, "");
|
|
|
|
res = zsock_close(s_sock);
|
|
zassert_equal(res, 0, "close failed");
|
|
}
|
|
|
|
static void *setup(void)
|
|
{
|
|
if (IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE)) {
|
|
k_thread_priority_set(k_current_get(),
|
|
K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1));
|
|
} else {
|
|
k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(9));
|
|
}
|
|
|
|
k_thread_system_pool_assign(k_current_get());
|
|
return NULL;
|
|
}
|
|
|
|
ZTEST_SUITE(net_socket_select, NULL, setup, NULL, NULL, NULL);
|