mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-10-02 11:48:10 +00:00
testing/nettest: add SO_TIMESTAMPING cmocka test
Add cmocka-based test program for SO_TIMESTAMPING socket option under testing/nettest/timestamp/. Covers all five test scenarios from the SO_TIMESTAMPING PR (apache/nuttx#20161): 1. SO_TIMESTAMPING setsockopt/getsockopt 2. SO_TIMESTAMP/SO_TIMESTAMPNS backward compatibility 3. TX timestamping + MSG_ERRQUEUE delivery 4. RX timestamp via SO_TIMESTAMP 5. TX timestamping with poll(POLLPRI) notification Enable with CONFIG_TESTING_NET_TIMESTAMP=y (requires CONFIG_NET_TIMESTAMP, CONFIG_NET_PKT, CONFIG_TESTING_CMOCKA). Tested on sim:dynconns — all 5 tests pass. Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
This commit is contained in:
parent
41a2c9d982
commit
11124141cb
6 changed files with 593 additions and 0 deletions
|
|
@ -97,4 +97,23 @@ if(CONFIG_TESTING_NET_TEST)
|
|||
${SRCS})
|
||||
endif()
|
||||
|
||||
if(CONFIG_TESTING_NET_TIMESTAMP)
|
||||
set(SRCS ${CMAKE_CURRENT_LIST_DIR}/timestamp/test_timestamp.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/timestamp/test_timestamp_common.c)
|
||||
|
||||
nuttx_add_application(
|
||||
NAME
|
||||
cmocka_net_timestamp
|
||||
PRIORITY
|
||||
${CONFIG_TESTING_NET_TEST_PRIORITY}
|
||||
STACKSIZE
|
||||
${CONFIG_TESTING_NET_TEST_STACKSIZE}
|
||||
MODULE
|
||||
${CONFIG_TESTING_NET_TEST}
|
||||
DEPENDS
|
||||
cmocka
|
||||
SRCS
|
||||
${SRCS})
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -44,4 +44,9 @@ config TESTING_NET_OTHERS
|
|||
bool "Enable cmocka net other test"
|
||||
default y
|
||||
|
||||
config TESTING_NET_TIMESTAMP
|
||||
bool "Enable cmocka net timestamp test"
|
||||
depends on NET_TIMESTAMP && NET_PKT
|
||||
default n
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -58,5 +58,11 @@ CSRCS += others/test_others_common.c others/test_others_bufpool.c \
|
|||
others/test_others_chksum.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_TESTING_NET_TIMESTAMP),y)
|
||||
MAINSRC += timestamp/test_timestamp.c
|
||||
PROGNAME += cmocka_net_timestamp
|
||||
CSRCS += timestamp/test_timestamp_common.c
|
||||
endif
|
||||
|
||||
endif
|
||||
include $(APPDIR)/Application.mk
|
||||
|
|
|
|||
51
testing/nettest/timestamp/test_timestamp.c
Normal file
51
testing/nettest/timestamp/test_timestamp.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/nettest/timestamp/test_timestamp.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
#include "test_timestamp.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, FAR char *argv[])
|
||||
{
|
||||
const struct CMUnitTest timestamp_tests[] =
|
||||
{
|
||||
cmocka_unit_test(test_timestamp_setsockopt),
|
||||
cmocka_unit_test(test_timestamp_compat),
|
||||
cmocka_unit_test(test_timestamp_tx),
|
||||
cmocka_unit_test(test_timestamp_rx),
|
||||
cmocka_unit_test(test_timestamp_poll),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(timestamp_tests,
|
||||
test_timestamp_group_setup,
|
||||
test_timestamp_group_teardown);
|
||||
}
|
||||
79
testing/nettest/timestamp/test_timestamp.h
Normal file
79
testing/nettest/timestamp/test_timestamp.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/nettest/timestamp/test_timestamp.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __APPS_TESTING_NETTEST_TIMESTAMP_TEST_TIMESTAMP_H
|
||||
#define __APPS_TESTING_NETTEST_TIMESTAMP_TEST_TIMESTAMP_H
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct nettest_timestamp_state_s
|
||||
{
|
||||
unsigned int ifindex;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_group_setup
|
||||
****************************************************************************/
|
||||
|
||||
int test_timestamp_group_setup(FAR void **state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_group_teardown
|
||||
****************************************************************************/
|
||||
|
||||
int test_timestamp_group_teardown(FAR void **state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_setsockopt
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_setsockopt(FAR void **state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_compat
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_compat(FAR void **state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_tx
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_tx(FAR void **state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_rx
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_rx(FAR void **state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_poll
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_poll(FAR void **state);
|
||||
|
||||
#endif /* __APPS_TESTING_NETTEST_TIMESTAMP_TEST_TIMESTAMP_H */
|
||||
433
testing/nettest/timestamp/test_timestamp_common.c
Normal file
433
testing/nettest/timestamp/test_timestamp_common.c
Normal file
|
|
@ -0,0 +1,433 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/nettest/timestamp/test_timestamp_common.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <poll.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
#include "test_timestamp.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define TX_PKT_SIZE 46
|
||||
#define RX_RETRY_MAX 10
|
||||
#define RX_RETRY_USEC 50000
|
||||
#define POLL_TIMEOUT 1000
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_group_setup
|
||||
****************************************************************************/
|
||||
|
||||
int test_timestamp_group_setup(FAR void **state)
|
||||
{
|
||||
FAR struct nettest_timestamp_state_s *ts_state;
|
||||
|
||||
ts_state = zalloc(sizeof(*ts_state));
|
||||
assert_non_null(ts_state);
|
||||
|
||||
*state = ts_state;
|
||||
|
||||
ts_state->ifindex = if_nametoindex("eth0");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_group_teardown
|
||||
****************************************************************************/
|
||||
|
||||
int test_timestamp_group_teardown(FAR void **state)
|
||||
{
|
||||
FAR struct nettest_timestamp_state_s *ts_state = *state;
|
||||
|
||||
free(ts_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_setsockopt
|
||||
*
|
||||
* Description:
|
||||
* Test 1: Verify SO_TIMESTAMPING setsockopt/getsockopt.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_setsockopt(FAR void **state)
|
||||
{
|
||||
socklen_t len;
|
||||
int val;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
assert_return_code(fd, errno);
|
||||
|
||||
val = SOF_TIMESTAMPING_TX_SOFTWARE;
|
||||
ret = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
|
||||
&val, sizeof(val));
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
val = 0;
|
||||
len = sizeof(val);
|
||||
ret = getsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
|
||||
&val, &len);
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
assert_true(val != 0);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_compat
|
||||
*
|
||||
* Description:
|
||||
* Test 2: SO_TIMESTAMP/SO_TIMESTAMPNS backward compatibility.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_compat(FAR void **state)
|
||||
{
|
||||
int val;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
assert_return_code(fd, errno);
|
||||
|
||||
val = 1;
|
||||
ret = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP,
|
||||
&val, sizeof(val));
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
val = 1;
|
||||
ret = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPNS,
|
||||
&val, sizeof(val));
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_tx
|
||||
*
|
||||
* Description:
|
||||
* Test 3: TX timestamping + MSG_ERRQUEUE delivery.
|
||||
* Matches PR #20161 test_tx_timestamp() exactly.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_tx(FAR void **state)
|
||||
{
|
||||
FAR struct nettest_timestamp_state_s *ts_state = *state;
|
||||
FAR struct cmsghdr *cmsg;
|
||||
FAR struct timespec *ts;
|
||||
struct sockaddr_ll addr;
|
||||
char cmsgbuf[256];
|
||||
char buf[64];
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
ssize_t n;
|
||||
int val;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
if (ts_state->ifindex == 0)
|
||||
{
|
||||
skip();
|
||||
}
|
||||
|
||||
fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
|
||||
assert_return_code(fd, errno);
|
||||
|
||||
val = SOF_TIMESTAMPING_TX_SOFTWARE;
|
||||
ret = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
|
||||
&val, sizeof(val));
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sll_family = AF_PACKET;
|
||||
addr.sll_protocol = htons(ETH_P_ALL);
|
||||
addr.sll_ifindex = ts_state->ifindex;
|
||||
|
||||
ret = bind(fd, (FAR struct sockaddr *)&addr, sizeof(addr));
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
memset(buf, 0xaa, TX_PKT_SIZE);
|
||||
addr.sll_halen = 6;
|
||||
memset(addr.sll_addr, 0xff, 6);
|
||||
|
||||
n = sendto(fd, buf, TX_PKT_SIZE, 0,
|
||||
(FAR struct sockaddr *)&addr, sizeof(addr));
|
||||
assert_true(n > 0);
|
||||
|
||||
usleep(10000);
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = sizeof(buf);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = cmsgbuf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf);
|
||||
|
||||
n = recvmsg(fd, &msg, MSG_ERRQUEUE | MSG_DONTWAIT);
|
||||
assert_true(n >= 0);
|
||||
|
||||
ts = NULL;
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg))
|
||||
{
|
||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SO_TIMESTAMPING)
|
||||
{
|
||||
ts = (FAR struct timespec *)CMSG_DATA(cmsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert_non_null(ts);
|
||||
assert_true(ts[0].tv_sec > 0);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_rx
|
||||
*
|
||||
* Description:
|
||||
* Test 4: RX timestamp via SO_TIMESTAMP.
|
||||
* Matches PR #20161 test_rx_timestamp() exactly.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_rx(FAR void **state)
|
||||
{
|
||||
FAR struct nettest_timestamp_state_s *ts_state = *state;
|
||||
FAR struct cmsghdr *cmsg;
|
||||
FAR struct timeval *tv;
|
||||
struct sockaddr_ll addr;
|
||||
char cmsgbuf[256];
|
||||
char buf[128];
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
ssize_t n;
|
||||
int retry;
|
||||
int val;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
if (ts_state->ifindex == 0)
|
||||
{
|
||||
skip();
|
||||
}
|
||||
|
||||
fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
assert_return_code(fd, errno);
|
||||
|
||||
val = 1;
|
||||
ret = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP,
|
||||
&val, sizeof(val));
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sll_family = AF_PACKET;
|
||||
addr.sll_protocol = htons(ETH_P_ALL);
|
||||
addr.sll_ifindex = ts_state->ifindex;
|
||||
|
||||
ret = bind(fd, (FAR struct sockaddr *)&addr, sizeof(addr));
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
/* Send broadcast via separate SOCK_DGRAM to trigger RX */
|
||||
|
||||
{
|
||||
struct sockaddr_ll sa;
|
||||
int sfd;
|
||||
|
||||
sfd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
|
||||
assert_return_code(sfd, errno);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sll_family = AF_PACKET;
|
||||
sa.sll_protocol = htons(ETH_P_IP);
|
||||
sa.sll_ifindex = ts_state->ifindex;
|
||||
sa.sll_halen = 6;
|
||||
memset(sa.sll_addr, 0xff, 6);
|
||||
memset(buf, 0xcc, TX_PKT_SIZE);
|
||||
|
||||
sendto(sfd, buf, TX_PKT_SIZE, 0,
|
||||
(FAR struct sockaddr *)&sa, sizeof(sa));
|
||||
close(sfd);
|
||||
}
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = sizeof(buf);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = cmsgbuf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf);
|
||||
|
||||
n = -1;
|
||||
for (retry = 0; retry < RX_RETRY_MAX; retry++)
|
||||
{
|
||||
usleep(RX_RETRY_USEC);
|
||||
n = recvmsg(fd, &msg, MSG_DONTWAIT);
|
||||
if (n > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert_true(n > 0);
|
||||
|
||||
tv = NULL;
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg))
|
||||
{
|
||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SO_TIMESTAMP)
|
||||
{
|
||||
tv = (FAR struct timeval *)CMSG_DATA(cmsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert_non_null(tv);
|
||||
assert_true(tv->tv_sec > 0);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_timestamp_poll
|
||||
*
|
||||
* Description:
|
||||
* Test 5: TX timestamping with poll(POLLPRI) notification.
|
||||
* Matches PR #20161 test_tx_timestamp_poll() exactly.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void test_timestamp_poll(FAR void **state)
|
||||
{
|
||||
FAR struct nettest_timestamp_state_s *ts_state = *state;
|
||||
FAR struct cmsghdr *cmsg;
|
||||
FAR struct timespec *ts;
|
||||
struct sockaddr_ll addr;
|
||||
struct pollfd pfd;
|
||||
char cmsgbuf[256];
|
||||
char buf[64];
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
ssize_t n;
|
||||
int val;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
if (ts_state->ifindex == 0)
|
||||
{
|
||||
skip();
|
||||
}
|
||||
|
||||
fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
|
||||
assert_return_code(fd, errno);
|
||||
|
||||
val = SOF_TIMESTAMPING_TX_SOFTWARE;
|
||||
ret = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
|
||||
&val, sizeof(val));
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sll_family = AF_PACKET;
|
||||
addr.sll_protocol = htons(ETH_P_ALL);
|
||||
addr.sll_ifindex = ts_state->ifindex;
|
||||
|
||||
ret = bind(fd, (FAR struct sockaddr *)&addr, sizeof(addr));
|
||||
assert_return_code(ret, errno);
|
||||
|
||||
addr.sll_halen = 6;
|
||||
memset(addr.sll_addr, 0xff, 6);
|
||||
|
||||
memset(buf, 0xaa, TX_PKT_SIZE);
|
||||
n = sendto(fd, buf, TX_PKT_SIZE, 0,
|
||||
(FAR struct sockaddr *)&addr, sizeof(addr));
|
||||
assert_true(n > 0);
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLPRI;
|
||||
pfd.revents = 0;
|
||||
|
||||
n = poll(&pfd, 1, POLL_TIMEOUT);
|
||||
assert_true(n > 0);
|
||||
assert_true((pfd.revents & POLLPRI) != 0);
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = sizeof(buf);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = cmsgbuf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf);
|
||||
|
||||
n = recvmsg(fd, &msg, MSG_ERRQUEUE);
|
||||
assert_true(n >= 0);
|
||||
|
||||
ts = NULL;
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg))
|
||||
{
|
||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SO_TIMESTAMPING)
|
||||
{
|
||||
ts = (FAR struct timespec *)CMSG_DATA(cmsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert_non_null(ts);
|
||||
assert_true(ts[0].tv_sec > 0);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue