drivers: net: nsos: implement sendmsg()
Implement sendmsg() socket API to have increased compatibility with components like MQTT client. Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
This commit is contained in:
parent
26bc2e2952
commit
bf637bf623
|
@ -89,6 +89,21 @@ struct nsos_mid_addrinfo {
|
||||||
struct nsos_mid_addrinfo *ai_next;
|
struct nsos_mid_addrinfo *ai_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nsos_mid_iovec {
|
||||||
|
void *iov_base;
|
||||||
|
size_t iov_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nsos_mid_msghdr {
|
||||||
|
void *msg_name; /* optional socket address, big endian */
|
||||||
|
size_t msg_namelen; /* size of socket address */
|
||||||
|
struct nsos_mid_iovec *msg_iov; /* scatter/gather array */
|
||||||
|
size_t msg_iovlen; /* number of elements in msg_iov */
|
||||||
|
void *msg_control; /* ancillary data */
|
||||||
|
size_t msg_controllen; /* ancillary data buffer len */
|
||||||
|
int msg_flags; /* flags on received message */
|
||||||
|
};
|
||||||
|
|
||||||
static inline void nsos_socket_flag_convert(int *flags_a, int flag_a,
|
static inline void nsos_socket_flag_convert(int *flags_a, int flag_a,
|
||||||
int *flags_b, int flag_b)
|
int *flags_b, int flag_b)
|
||||||
{
|
{
|
||||||
|
@ -108,6 +123,7 @@ int nsos_adapt_listen(int fd, int backlog);
|
||||||
int nsos_adapt_accept(int fd, struct nsos_mid_sockaddr *addr, size_t *addrlen);
|
int nsos_adapt_accept(int fd, struct nsos_mid_sockaddr *addr, size_t *addrlen);
|
||||||
int nsos_adapt_sendto(int fd, const void *buf, size_t len, int flags,
|
int nsos_adapt_sendto(int fd, const void *buf, size_t len, int flags,
|
||||||
const struct nsos_mid_sockaddr *addr, size_t addrlen);
|
const struct nsos_mid_sockaddr *addr, size_t addrlen);
|
||||||
|
int nsos_adapt_sendmsg(int fd, const struct nsos_mid_msghdr *msg_mid, int flags);
|
||||||
int nsos_adapt_recvfrom(int fd, void *buf, size_t len, int flags,
|
int nsos_adapt_recvfrom(int fd, void *buf, size_t len, int flags,
|
||||||
struct nsos_mid_sockaddr *addr, size_t *addrlen);
|
struct nsos_mid_sockaddr *addr, size_t *addrlen);
|
||||||
|
|
||||||
|
|
|
@ -445,6 +445,49 @@ int nsos_adapt_sendto(int fd, const void *buf, size_t len, int flags,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nsos_adapt_sendmsg(int fd, const struct nsos_mid_msghdr *msg_mid, int flags)
|
||||||
|
{
|
||||||
|
struct sockaddr_storage addr_storage;
|
||||||
|
struct sockaddr *addr = (struct sockaddr *)&addr_storage;
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec *msg_iov;
|
||||||
|
socklen_t addrlen;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = sockaddr_from_nsos_mid(&addr, &addrlen, msg_mid->msg_name, msg_mid->msg_namelen);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_iov = calloc(msg_mid->msg_iovlen, sizeof(*msg_iov));
|
||||||
|
if (!msg_iov) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < msg_mid->msg_iovlen; i++) {
|
||||||
|
msg_iov[i].iov_base = msg_mid->msg_iov[i].iov_base;
|
||||||
|
msg_iov[i].iov_len = msg_mid->msg_iov[i].iov_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.msg_name = addr;
|
||||||
|
msg.msg_namelen = addrlen;
|
||||||
|
msg.msg_iov = msg_iov;
|
||||||
|
msg.msg_iovlen = msg_mid->msg_iovlen;
|
||||||
|
msg.msg_control = NULL;
|
||||||
|
msg.msg_controllen = 0;
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
|
ret = sendmsg(fd, &msg, socket_flags_from_nsos_mid(flags) | MSG_NOSIGNAL);
|
||||||
|
if (ret < 0) {
|
||||||
|
ret = -errno_to_nsos_mid(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(msg_iov);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int nsos_adapt_recvfrom(int fd, void *buf, size_t len, int flags,
|
int nsos_adapt_recvfrom(int fd, void *buf, size_t len, int flags,
|
||||||
struct nsos_mid_sockaddr *addr_mid, size_t *addrlen_mid)
|
struct nsos_mid_sockaddr *addr_mid, size_t *addrlen_mid)
|
||||||
{
|
{
|
||||||
|
|
|
@ -672,8 +672,57 @@ return_ret:
|
||||||
|
|
||||||
static ssize_t nsos_sendmsg(void *obj, const struct msghdr *msg, int flags)
|
static ssize_t nsos_sendmsg(void *obj, const struct msghdr *msg, int flags)
|
||||||
{
|
{
|
||||||
errno = ENOTSUP;
|
struct nsos_socket *sock = obj;
|
||||||
return -1;
|
struct nsos_mid_sockaddr_storage addr_storage_mid;
|
||||||
|
struct nsos_mid_sockaddr *addr_mid = (struct nsos_mid_sockaddr *)&addr_storage_mid;
|
||||||
|
size_t addrlen_mid = sizeof(addr_storage_mid);
|
||||||
|
struct nsos_mid_msghdr msg_mid;
|
||||||
|
struct nsos_mid_iovec *msg_iov;
|
||||||
|
int flags_mid;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = socket_flags_to_nsos_mid(flags);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto return_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags_mid = ret;
|
||||||
|
|
||||||
|
ret = sockaddr_to_nsos_mid(msg->msg_name, msg->msg_namelen, &addr_mid, &addrlen_mid);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto return_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_iov = k_calloc(msg->msg_iovlen, sizeof(*msg_iov));
|
||||||
|
if (!msg_iov) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto return_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < msg->msg_iovlen; i++) {
|
||||||
|
msg_iov[i].iov_base = msg->msg_iov[i].iov_base;
|
||||||
|
msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_mid.msg_name = addr_mid;
|
||||||
|
msg_mid.msg_namelen = addrlen_mid;
|
||||||
|
msg_mid.msg_iov = msg_iov;
|
||||||
|
msg_mid.msg_iovlen = msg->msg_iovlen;
|
||||||
|
msg_mid.msg_control = NULL;
|
||||||
|
msg_mid.msg_controllen = 0;
|
||||||
|
msg_mid.msg_flags = 0;
|
||||||
|
|
||||||
|
ret = nsos_adapt_sendmsg(sock->pollfd.fd, &msg_mid, flags_mid);
|
||||||
|
|
||||||
|
k_free(msg_iov);
|
||||||
|
|
||||||
|
return_ret:
|
||||||
|
if (ret < 0) {
|
||||||
|
errno = errno_from_nsos_mid(-ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nsos_recvfrom_with_poll(struct nsos_socket *sock, void *buf, size_t len, int flags,
|
static int nsos_recvfrom_with_poll(struct nsos_socket *sock, void *buf, size_t len, int flags,
|
||||||
|
|
Loading…
Reference in a new issue