netutls/usrsock_rpmsg_server: add support for send reassemble

Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
chao.an 2021-04-12 18:43:32 +08:00 committed by Xiang Xiao
parent 0146e88001
commit 2214e51457
2 changed files with 118 additions and 11 deletions

View File

@ -25,9 +25,15 @@ config NETUTILS_USRSOCK_RPMSG_STACKSIZE
The stack size allocated for the usrsock task.
config NETUTILS_USRSOCK_NSOCK_DESCRIPTORS
int "the maximum number of socket descriptors for usrsock monitoring"
int "The maximum number of socket descriptors for usrsock monitoring"
default 64
---help---
The maximum number of socket description for usrsosck monitoring.
config NETUTILS_USRSOCK_NIOVEC
int "The maximum number of I/O vector for reassemble buffer"
default 8
---help---
The maximum number of I/O vector for reassemble buffer.
endif # NETUTILS_USRSOCK_RPMSG

View File

@ -42,6 +42,7 @@ struct usrsock_rpmsg_s
pid_t pid;
pthread_mutex_t mutex;
pthread_cond_t cond;
struct iovec iov[CONFIG_NETUTILS_USRSOCK_NIOVEC];
struct socket socks[CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS];
struct rpmsg_endpoint *epts[CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS];
struct pollfd pfds[CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS];
@ -320,20 +321,100 @@ static int usrsock_rpmsg_sendto_handler(struct rpmsg_endpoint *ept,
void *data, size_t len,
uint32_t src, void *priv_)
{
struct usrsock_request_sendto_s *req = data;
struct usrsock_request_sendto_s *req;
struct usrsock_rpmsg_s *priv = priv_;
ssize_t ret = -EBADF;
size_t total;
int retr;
int i;
if (req->usockid >= 0 &&
req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS)
if (priv->iov[0].iov_base)
{
ret = psock_sendto(&priv->socks[req->usockid],
(const void *)(req + 1) + req->addrlen, req->buflen,
req->flags,
req->addrlen ? (const struct sockaddr *)(req + 1) : NULL,
req->addrlen);
size_t hlen;
struct msghdr msg =
{
};
req = priv->iov[0].iov_base;
hlen = sizeof(*req) + req->addrlen;
total = len;
for (i = 0; i < CONFIG_NETUTILS_USRSOCK_NIOVEC; i++)
{
if (!priv->iov[i].iov_base)
{
priv->iov[i].iov_base = data;
priv->iov[i].iov_len = len;
rpmsg_hold_rx_buffer(ept, data);
break;
}
total += priv->iov[i].iov_len;
}
if (i == CONFIG_NETUTILS_USRSOCK_NIOVEC)
{
ret = -ENOMEM;
goto out;
}
/* Partial packet ? continue to fetch */
if (req->buflen > total - hlen)
{
return 0;
}
else if (req->buflen < total - hlen)
{
ret = -EINVAL;
goto out;
}
/* Skip the sendto header from I/O vector */
priv->iov[0].iov_base = (char *)priv->iov[0].iov_base + hlen;
priv->iov[0].iov_len -= hlen;
msg.msg_name = req->addrlen ? (void *)(req + 1) : NULL;
msg.msg_namelen = req->addrlen;
msg.msg_iov = priv->iov;
msg.msg_iovlen = i + 1;
ret = psock_sendmsg(&priv->socks[req->usockid], &msg, req->flags);
/* Recover the I/O vector */
priv->iov[0].iov_base = (char *)priv->iov[0].iov_base - hlen;
priv->iov[0].iov_len += hlen;
}
else
{
req = data;
if (req->usockid >= 0 &&
req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS)
{
total = sizeof(*req) + req->addrlen + req->buflen;
if (total > len)
{
priv->iov[0].iov_base = data;
priv->iov[0].iov_len = len;
rpmsg_hold_rx_buffer(ept, data);
return 0;
}
else
{
ret = psock_sendto(&priv->socks[req->usockid],
(const void *)(req + 1) + req->addrlen, req->buflen,
req->flags,
req->addrlen ? (const struct sockaddr *)(req + 1) : NULL,
req->addrlen);
}
}
}
out:
retr = usrsock_rpmsg_send_ack(ept, req->head.xid, ret);
if (retr >= 0 && ret >= 0)
@ -351,6 +432,21 @@ static int usrsock_rpmsg_sendto_handler(struct rpmsg_endpoint *ept,
pthread_mutex_unlock(&priv->mutex);
}
if (priv->iov[0].iov_base)
{
for (i = 0; i < CONFIG_NETUTILS_USRSOCK_NIOVEC; i++)
{
if (priv->iov[i].iov_base == NULL)
{
break;
}
rpmsg_release_rx_buffer(ept, priv->iov[i].iov_base);
priv->iov[i].iov_base = NULL;
priv->iov[i].iov_len = 0;
}
}
return retr;
}
@ -726,11 +822,16 @@ static void usrsock_rpmsg_ns_unbind(struct rpmsg_endpoint *ept)
}
static int usrsock_rpmsg_ept_cb(struct rpmsg_endpoint *ept, void *data,
size_t len, uint32_t src, void *priv)
size_t len, uint32_t src, void *priv_)
{
struct usrsock_request_common_s *common = data;
struct usrsock_rpmsg_s *priv = priv_;
if (common->reqid >= 0 && common->reqid < USRSOCK_REQUEST__MAX)
if (priv->iov[0].iov_base)
{
return usrsock_rpmsg_sendto_handler(ept, data, len, src, priv);
}
else if (common->reqid >= 0 && common->reqid < USRSOCK_REQUEST__MAX)
{
return g_usrsock_rpmsg_handler[common->reqid](ept, data, len,
src, priv);