mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #17485 from benpicco/sock_udp_sendv
sys/net/sock: add sock_udp_sendv() API
This commit is contained in:
commit
a17ff53ecf
@ -573,14 +573,15 @@ int lwip_sock_recv(struct netconn *conn, uint32_t timeout, struct netbuf **buf)
|
||||
}
|
||||
#endif /* defined(MODULE_LWIP_SOCK_UDP) || defined(MODULE_LWIP_SOCK_IP) */
|
||||
|
||||
ssize_t lwip_sock_send(struct netconn *conn, const void *data, size_t len,
|
||||
int proto, const struct _sock_tl_ep *remote, int type)
|
||||
ssize_t lwip_sock_sendv(struct netconn *conn, const iolist_t *snips,
|
||||
int proto, const struct _sock_tl_ep *remote, int type)
|
||||
{
|
||||
ip_addr_t remote_addr;
|
||||
struct netconn *tmp;
|
||||
struct netbuf *buf;
|
||||
struct netbuf *buf = NULL;
|
||||
size_t payload_len = 0;
|
||||
int res;
|
||||
err_t err;
|
||||
err_t err= ERR_OK;
|
||||
u16_t remote_port = 0;
|
||||
|
||||
#if LWIP_IPV6
|
||||
@ -598,11 +599,19 @@ ssize_t lwip_sock_send(struct netconn *conn, const void *data, size_t len,
|
||||
}
|
||||
|
||||
buf = netbuf_new();
|
||||
if ((buf == NULL) || (netbuf_alloc(buf, len) == NULL) ||
|
||||
(netbuf_take(buf, data, len) != ERR_OK)) {
|
||||
if (netbuf_alloc(buf, iolist_size(snips)) == NULL) {
|
||||
netbuf_delete(buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (const iolist_t *snip = snips; snip != NULL; snip = snip->iol_next) {
|
||||
if (pbuf_take_at(buf->p, snip->iol_base, snip->iol_len, payload_len) != ERR_OK) {
|
||||
netbuf_delete(buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
payload_len += snip->iol_len;
|
||||
}
|
||||
|
||||
if ((conn == NULL) && (remote != NULL)) {
|
||||
if ((res = _create(type, proto, 0, &tmp)) < 0) {
|
||||
netbuf_delete(buf);
|
||||
@ -625,13 +634,13 @@ ssize_t lwip_sock_send(struct netconn *conn, const void *data, size_t len,
|
||||
netbuf_delete(buf);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
res = len; /* set for non-TCP calls */
|
||||
res = payload_len; /* set for non-TCP calls */
|
||||
if (remote != NULL) {
|
||||
err = netconn_sendto(tmp, buf, &remote_addr, remote_port);
|
||||
}
|
||||
#if LWIP_TCP
|
||||
else if (tmp->type & NETCONN_TCP) {
|
||||
err = netconn_write_partly(tmp, data, len, 0, (size_t *)(&res));
|
||||
err = netconn_write_partly(tmp, buf->p->payload, buf->p->len, 0, (size_t *)(&res));
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
else {
|
||||
|
@ -163,18 +163,17 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **ctx,
|
||||
return (ssize_t)buf->ptr->len;
|
||||
}
|
||||
|
||||
ssize_t sock_udp_send_aux(sock_udp_t *sock, const void *data, size_t len,
|
||||
const sock_udp_ep_t *remote, sock_udp_aux_tx_t *aux)
|
||||
ssize_t sock_udp_sendv_aux(sock_udp_t *sock, const iolist_t *snips,
|
||||
const sock_udp_ep_t *remote, sock_udp_aux_tx_t *aux)
|
||||
{
|
||||
(void)aux;
|
||||
assert((sock != NULL) || (remote != NULL));
|
||||
assert((len == 0) || (data != NULL)); /* (len != 0) => (data != NULL) */
|
||||
|
||||
if ((remote != NULL) && (remote->port == 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return lwip_sock_send((sock) ? sock->base.conn : NULL, data, len, 0,
|
||||
(struct _sock_tl_ep *)remote, NETCONN_UDP);
|
||||
return lwip_sock_sendv((sock) ? sock->base.conn : NULL, snips, 0,
|
||||
(struct _sock_tl_ep *)remote, NETCONN_UDP);
|
||||
}
|
||||
|
||||
#ifdef SOCK_HAS_ASYNC
|
||||
|
@ -56,8 +56,19 @@ int lwip_sock_get_addr(struct netconn *conn, struct _sock_tl_ep *ep, u8_t local)
|
||||
#if defined(MODULE_LWIP_SOCK_UDP) || defined(MODULE_LWIP_SOCK_IP)
|
||||
int lwip_sock_recv(struct netconn *conn, uint32_t timeout, struct netbuf **buf);
|
||||
#endif
|
||||
ssize_t lwip_sock_send(struct netconn *conn, const void *data, size_t len,
|
||||
int proto, const struct _sock_tl_ep *remote, int type);
|
||||
ssize_t lwip_sock_sendv(struct netconn *conn, const iolist_t *snips,
|
||||
int proto, const struct _sock_tl_ep *remote, int type);
|
||||
static inline ssize_t lwip_sock_send(struct netconn *conn,
|
||||
const void *data, size_t len,
|
||||
int proto, const struct _sock_tl_ep *remote, int type)
|
||||
{
|
||||
iolist_t snip = {
|
||||
.iol_base = (void *)data,
|
||||
.iol_len = len,
|
||||
};
|
||||
|
||||
return lwip_sock_sendv(conn, &snip, proto, remote, type);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -215,12 +215,15 @@ int sock_udp_create(sock_udp_t *sock, const sock_udp_ep_t *local,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t sock_udp_send_aux(sock_udp_t *sock, const void *data, size_t len,
|
||||
const sock_udp_ep_t *remote, sock_udp_aux_tx_t *aux)
|
||||
ssize_t sock_udp_sendv_aux(sock_udp_t *sock,
|
||||
const iolist_t *snips,
|
||||
const sock_udp_ep_t *remote, sock_udp_aux_tx_t *aux)
|
||||
{
|
||||
(void)aux;
|
||||
OpenQueueEntry_t *pkt;
|
||||
open_addr_t dst_addr, src_addr;
|
||||
size_t payload_len = 0;
|
||||
uint8_t *payload_dst;
|
||||
|
||||
memset(&dst_addr, 0, sizeof(open_addr_t));
|
||||
memset(&src_addr, 0, sizeof(open_addr_t));
|
||||
@ -228,7 +231,6 @@ ssize_t sock_udp_send_aux(sock_udp_t *sock, const void *data, size_t len,
|
||||
|
||||
/* asserts for sock_udp_send "pre" */
|
||||
assert((sock != NULL) || (remote != NULL));
|
||||
assert((len == 0) || (data != NULL)); /* (len != 0) => (data != NULL) */
|
||||
|
||||
/* check remote */
|
||||
if (remote != NULL) {
|
||||
@ -302,19 +304,29 @@ ssize_t sock_udp_send_aux(sock_udp_t *sock, const void *data, size_t len,
|
||||
pkt->l4_destination_port = dst_port;
|
||||
pkt->l4_sourcePortORicmpv6Type = src_port;
|
||||
|
||||
/* calculate payload size */
|
||||
payload_len = iolist_size(snips);
|
||||
|
||||
/* set payload */
|
||||
if (packetfunctions_reserveHeader(&pkt, len)) {
|
||||
if (packetfunctions_reserveHeader(&pkt, payload_len)) {
|
||||
openqueue_freePacketBuffer(pkt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(pkt->payload, data, len);
|
||||
|
||||
/* copy payload into packet */
|
||||
payload_dst = pkt->payload;
|
||||
while (snips) {
|
||||
memcpy(payload_dst, snips->iol_base, snips->iol_len);
|
||||
payload_dst += snips->iol_len;
|
||||
snips = snips->iol_next;
|
||||
}
|
||||
pkt->l4_payload = pkt->payload;
|
||||
pkt->l4_length = pkt->length;
|
||||
|
||||
/* push task to scheduler send */
|
||||
scheduler_push_task(_sock_transmit_internal, TASKPRIO_UDP);
|
||||
|
||||
return len;
|
||||
return payload_len;
|
||||
}
|
||||
|
||||
void sock_udp_close(sock_udp_t *sock)
|
||||
|
@ -137,6 +137,10 @@ ifneq (,$(filter sntp,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter sock_%,$(USEMODULE)))
|
||||
USEMODULE += iolist
|
||||
endif
|
||||
|
||||
ifneq (,$(filter netdev_ieee802154,$(USEMODULE)))
|
||||
USEMODULE += ieee802154
|
||||
USEMODULE += random
|
||||
|
@ -103,6 +103,8 @@
|
||||
#define NET_SOCK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "iolist.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -605,6 +605,43 @@ static inline ssize_t sock_udp_recv_buf(sock_udp_t *sock,
|
||||
return sock_udp_recv_buf_aux(sock, data, buf_ctx, timeout, remote, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends a UDP message to remote end point with non-continous payload
|
||||
*
|
||||
* @pre `((sock != NULL || remote != NULL))`
|
||||
*
|
||||
* @param[in] sock A UDP sock object. May be `NULL`.
|
||||
* A sensible local end point should be selected by the
|
||||
* implementation in that case.
|
||||
* @param[in] snips List of payload chunks, will be processed in order.
|
||||
* May be `NULL`.
|
||||
* @param[in] remote Remote end point for the sent data.
|
||||
* May be `NULL`, if @p sock has a remote end point.
|
||||
* sock_udp_ep_t::family may be AF_UNSPEC, if local
|
||||
* end point of @p sock provides this information.
|
||||
* sock_udp_ep_t::port may not be 0.
|
||||
* @param[out] aux Auxiliary data about the transmission.
|
||||
* May be `NULL`, if it is not required by the application.
|
||||
*
|
||||
* @return The number of bytes sent on success.
|
||||
* @return -EADDRINUSE, if `sock` has no local end-point or was `NULL` and the
|
||||
* pool of available ephemeral ports is depleted.
|
||||
* @return -EAFNOSUPPORT, if `remote != NULL` and sock_udp_ep_t::family of
|
||||
* @p remote is != AF_UNSPEC and not supported.
|
||||
* @return -EHOSTUNREACH, if @p remote or remote end point of @p sock is not
|
||||
* reachable.
|
||||
* @return -EINVAL, if sock_udp_ep_t::addr of @p remote is an invalid address.
|
||||
* @return -EINVAL, if sock_udp_ep_t::netif of @p remote is not a valid
|
||||
* interface or contradicts the given local interface (i.e.
|
||||
* neither the local end point of `sock` nor remote are assigned to
|
||||
* `SOCK_ADDR_ANY_NETIF` but are nevertheless different.
|
||||
* @return -EINVAL, if sock_udp_ep_t::port of @p remote is 0.
|
||||
* @return -ENOMEM, if no memory was available to send @p data.
|
||||
* @return -ENOTCONN, if `remote == NULL`, but @p sock has no remote end point.
|
||||
*/
|
||||
ssize_t sock_udp_sendv_aux(sock_udp_t *sock, const iolist_t *snips,
|
||||
const sock_udp_ep_t *remote, sock_udp_aux_tx_t *aux);
|
||||
|
||||
/**
|
||||
* @brief Sends a UDP message to remote end point
|
||||
*
|
||||
@ -640,8 +677,18 @@ static inline ssize_t sock_udp_recv_buf(sock_udp_t *sock,
|
||||
* @return -ENOMEM, if no memory was available to send @p data.
|
||||
* @return -ENOTCONN, if `remote == NULL`, but @p sock has no remote end point.
|
||||
*/
|
||||
ssize_t sock_udp_send_aux(sock_udp_t *sock, const void *data, size_t len,
|
||||
const sock_udp_ep_t *remote, sock_udp_aux_tx_t *aux);
|
||||
static inline ssize_t sock_udp_send_aux(sock_udp_t *sock,
|
||||
const void *data, size_t len,
|
||||
const sock_udp_ep_t *remote,
|
||||
sock_udp_aux_tx_t *aux)
|
||||
{
|
||||
const iolist_t snip = {
|
||||
.iol_base = (void *)data,
|
||||
.iol_len = len,
|
||||
};
|
||||
|
||||
return sock_udp_sendv_aux(sock, &snip, remote, aux);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends a UDP message to remote end point
|
||||
@ -683,6 +730,45 @@ static inline ssize_t sock_udp_send(sock_udp_t *sock,
|
||||
return sock_udp_send_aux(sock, data, len, remote, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends a UDP message to remote end point with non-continous payload
|
||||
*
|
||||
* @pre `((sock != NULL || remote != NULL))`
|
||||
*
|
||||
* @param[in] sock A UDP sock object. May be `NULL`.
|
||||
* A sensible local end point should be selected by the
|
||||
* implementation in that case.
|
||||
* @param[in] snips List of payload chunks, will be processed in order.
|
||||
* May be `NULL`.
|
||||
* @param[in] remote Remote end point for the sent data.
|
||||
* May be `NULL`, if @p sock has a remote end point.
|
||||
* sock_udp_ep_t::family may be AF_UNSPEC, if local
|
||||
* end point of @p sock provides this information.
|
||||
* sock_udp_ep_t::port may not be 0.
|
||||
*
|
||||
* @return The number of bytes sent on success.
|
||||
* @return -EADDRINUSE, if `sock` has no local end-point or was `NULL` and the
|
||||
* pool of available ephemeral ports is depleted.
|
||||
* @return -EAFNOSUPPORT, if `remote != NULL` and sock_udp_ep_t::family of
|
||||
* @p remote is != AF_UNSPEC and not supported.
|
||||
* @return -EHOSTUNREACH, if @p remote or remote end point of @p sock is not
|
||||
* reachable.
|
||||
* @return -EINVAL, if sock_udp_ep_t::addr of @p remote is an invalid address.
|
||||
* @return -EINVAL, if sock_udp_ep_t::netif of @p remote is not a valid
|
||||
* interface or contradicts the given local interface (i.e.
|
||||
* neither the local end point of `sock` nor remote are assigned to
|
||||
* `SOCK_ADDR_ANY_NETIF` but are nevertheless different.
|
||||
* @return -EINVAL, if sock_udp_ep_t::port of @p remote is 0.
|
||||
* @return -ENOMEM, if no memory was available to send @p data.
|
||||
* @return -ENOTCONN, if `remote == NULL`, but @p sock has no remote end point.
|
||||
*/
|
||||
static inline ssize_t sock_udp_sendv(sock_udp_t *sock,
|
||||
const iolist_t *snips,
|
||||
const sock_udp_ep_t *remote)
|
||||
{
|
||||
return sock_udp_sendv_aux(sock, snips, remote, NULL);
|
||||
}
|
||||
|
||||
#include "sock_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -278,19 +278,20 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx,
|
||||
return res;
|
||||
}
|
||||
|
||||
ssize_t sock_udp_send_aux(sock_udp_t *sock, const void *data, size_t len,
|
||||
const sock_udp_ep_t *remote, sock_udp_aux_tx_t *aux)
|
||||
ssize_t sock_udp_sendv_aux(sock_udp_t *sock,
|
||||
const iolist_t *snips,
|
||||
const sock_udp_ep_t *remote, sock_udp_aux_tx_t *aux)
|
||||
{
|
||||
(void)aux;
|
||||
int res;
|
||||
gnrc_pktsnip_t *payload, *pkt;
|
||||
gnrc_pktsnip_t *pkt, *payload = NULL;
|
||||
uint16_t src_port = 0, dst_port;
|
||||
sock_ip_ep_t local;
|
||||
sock_udp_ep_t remote_cpy;
|
||||
sock_ip_ep_t *rem;
|
||||
uint8_t *payload_buf;
|
||||
|
||||
assert((sock != NULL) || (remote != NULL));
|
||||
assert((len == 0) || (data != NULL)); /* (len != 0) => (data != NULL) */
|
||||
|
||||
if (remote != NULL) {
|
||||
if (remote->port == 0) {
|
||||
@ -362,11 +363,21 @@ ssize_t sock_udp_send_aux(sock_udp_t *sock, const void *data, size_t len,
|
||||
else if (local.family != rem->family) {
|
||||
return -EINVAL;
|
||||
}
|
||||
/* generate payload and header snips */
|
||||
payload = gnrc_pktbuf_add(NULL, (void *)data, len, GNRC_NETTYPE_UNDEF);
|
||||
|
||||
/* allocate snip for payload */
|
||||
payload = gnrc_pktbuf_add(NULL, NULL, iolist_size(snips), GNRC_NETTYPE_UNDEF);
|
||||
if (payload == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* copy payload data into payload snip */
|
||||
payload_buf = payload->data;
|
||||
while (snips) {
|
||||
memcpy(payload_buf, snips->iol_base, snips->iol_len);
|
||||
payload_buf += snips->iol_len;
|
||||
snips = snips->iol_next;
|
||||
}
|
||||
|
||||
pkt = gnrc_udp_hdr_build(payload, src_port, dst_port);
|
||||
if (pkt == NULL) {
|
||||
gnrc_pktbuf_release(payload);
|
||||
|
@ -629,6 +629,37 @@ static void test_sock_udp_send__socketed(void)
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_sendv__socketed(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_REMOTE };
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
const iolist_t tail = {
|
||||
.iol_base = "EFGH",
|
||||
.iol_len = sizeof("EFGH"),
|
||||
};
|
||||
|
||||
const iolist_t head = {
|
||||
.iol_next = (void *)&tail,
|
||||
.iol_base = "ABCD",
|
||||
.iol_len = sizeof("ABCD") - 1,
|
||||
};
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCDEFGH") == sock_udp_sendv(&_sock, &head, NULL));
|
||||
expect(_check_packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL,
|
||||
_TEST_PORT_REMOTE, "ABCDEFGH", sizeof("ABCDEFGH"),
|
||||
_TEST_NETIF, false));
|
||||
xtimer_usleep(1000); /* let GNRC stack finish */
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send__socketed_other_remote(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_LOCAL };
|
||||
@ -808,6 +839,7 @@ int main(void)
|
||||
CALL(test_sock_udp_send__socketed_no_netif());
|
||||
CALL(test_sock_udp_send__socketed_no_local());
|
||||
CALL(test_sock_udp_send__socketed());
|
||||
CALL(test_sock_udp_sendv__socketed());
|
||||
CALL(test_sock_udp_send__socketed_other_remote());
|
||||
CALL(test_sock_udp_send__unsocketed_no_local_no_netif());
|
||||
CALL(test_sock_udp_send__unsocketed_no_netif());
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
static msg_t _msg_queue[_MSG_QUEUE_SIZE];
|
||||
static gnrc_netreg_entry_t _udp_handler;
|
||||
static char _rx_buf[32];
|
||||
|
||||
void _net_init(void)
|
||||
{
|
||||
@ -130,9 +131,11 @@ bool _check_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||
void *data, size_t data_len, uint16_t iface,
|
||||
bool random_src_port)
|
||||
{
|
||||
gnrc_pktsnip_t *pkt, *ipv6, *udp;
|
||||
gnrc_pktsnip_t *pkt, *ipv6, *udp, *payload;
|
||||
ipv6_hdr_t *ipv6_hdr;
|
||||
udp_hdr_t *udp_hdr;
|
||||
size_t payload_len;
|
||||
char *payload_buf;
|
||||
msg_t msg;
|
||||
|
||||
msg_receive(&msg);
|
||||
@ -164,12 +167,22 @@ bool _check_packet(const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||
return _res(pkt, false);
|
||||
}
|
||||
udp_hdr = udp->data;
|
||||
|
||||
payload = udp->next;
|
||||
payload_buf = _rx_buf;
|
||||
while (payload) {
|
||||
memcpy(payload_buf, payload->data, payload->size);
|
||||
payload_buf += payload->size;
|
||||
payload = payload->next;
|
||||
}
|
||||
payload_len = payload_buf - _rx_buf;
|
||||
|
||||
return _res(pkt, (memcmp(src, &ipv6_hdr->src, sizeof(ipv6_addr_t)) == 0) &&
|
||||
(memcmp(dst, &ipv6_hdr->dst, sizeof(ipv6_addr_t)) == 0) &&
|
||||
(ipv6_hdr->nh == PROTNUM_UDP) &&
|
||||
(random_src_port || (src_port == byteorder_ntohs(udp_hdr->src_port))) &&
|
||||
(dst_port == byteorder_ntohs(udp_hdr->dst_port)) &&
|
||||
(udp->next != NULL) &&
|
||||
(data_len == udp->next->size) &&
|
||||
(memcmp(data, udp->next->data, data_len) == 0));
|
||||
(data_len ==payload_len ) &&
|
||||
(memcmp(data, _rx_buf, data_len) == 0));
|
||||
}
|
||||
|
@ -1288,6 +1288,38 @@ static void test_sock_udp_send6__socketed(void)
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_sendv6__socketed(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR6_LOCAL };
|
||||
static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR6_REMOTE };
|
||||
static const sock_udp_ep_t local = { .addr = { .ipv6 = _TEST_ADDR6_LOCAL },
|
||||
.family = AF_INET6,
|
||||
.netif = _TEST_NETIF,
|
||||
.port = _TEST_PORT_LOCAL };
|
||||
static const sock_udp_ep_t remote = { .addr = { .ipv6 = _TEST_ADDR6_REMOTE },
|
||||
.family = AF_INET6,
|
||||
.port = _TEST_PORT_REMOTE };
|
||||
|
||||
const iolist_t tail = {
|
||||
.iol_base = "EFGH",
|
||||
.iol_len = sizeof("EFGH"),
|
||||
};
|
||||
|
||||
const iolist_t head = {
|
||||
.iol_next = (void *)&tail,
|
||||
.iol_base = "ABCD",
|
||||
.iol_len = sizeof("ABCD") - 1,
|
||||
};
|
||||
|
||||
expect(0 == sock_udp_create(&_sock, &local, &remote, SOCK_FLAGS_REUSE_EP));
|
||||
expect(sizeof("ABCDEFGH") == sock_udp_sendv(&_sock, &head, NULL));
|
||||
expect(_check_6packet(&src_addr, &dst_addr, _TEST_PORT_LOCAL,
|
||||
_TEST_PORT_REMOTE, "ABCDEFGH", sizeof("ABCDEFGH"),
|
||||
_TEST_NETIF, false));
|
||||
xtimer_usleep(1000); /* let GNRC stack finish */
|
||||
expect(_check_net());
|
||||
}
|
||||
|
||||
static void test_sock_udp_send6__socketed_other_remote(void)
|
||||
{
|
||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR6_LOCAL };
|
||||
@ -1531,6 +1563,7 @@ int main(void)
|
||||
CALL(test_sock_udp_send6__socketed_no_netif());
|
||||
CALL(test_sock_udp_send6__socketed_no_local());
|
||||
CALL(test_sock_udp_send6__socketed());
|
||||
CALL(test_sock_udp_sendv6__socketed());
|
||||
CALL(test_sock_udp_send6__socketed_other_remote());
|
||||
CALL(test_sock_udp_send6__unsocketed_no_local_no_netif());
|
||||
CALL(test_sock_udp_send6__unsocketed_no_netif());
|
||||
|
Loading…
Reference in New Issue
Block a user