net/usrsock: add send multi-elements support

Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
chao.an 2021-03-19 22:09:56 +08:00 committed by Xiang Xiao
parent 083a11a3c3
commit 03f899f302
1 changed files with 25 additions and 35 deletions

View File

@ -148,24 +148,18 @@ static uint16_t sendto_event(FAR struct net_driver_s *dev, FAR void *pvconn,
****************************************************************************/ ****************************************************************************/
static int do_sendto_request(FAR struct usrsock_conn_s *conn, static int do_sendto_request(FAR struct usrsock_conn_s *conn,
FAR const void *buf, size_t buflen, FAR struct msghdr *msg, int flags)
FAR const struct sockaddr *addr,
socklen_t addrlen, int32_t flags)
{ {
struct usrsock_request_sendto_s req = struct usrsock_request_sendto_s req =
{ {
}; };
struct iovec bufs[3]; struct iovec bufs[2 + msg->msg_iovlen];
int i;
if (addrlen > UINT16_MAX) if (msg->msg_namelen > UINT16_MAX)
{ {
addrlen = UINT16_MAX; msg->msg_namelen = UINT16_MAX;
}
if (buflen > UINT16_MAX)
{
buflen = UINT16_MAX;
} }
/* Prepare request for daemon to read. */ /* Prepare request for daemon to read. */
@ -173,15 +167,24 @@ static int do_sendto_request(FAR struct usrsock_conn_s *conn,
req.head.reqid = USRSOCK_REQUEST_SENDTO; req.head.reqid = USRSOCK_REQUEST_SENDTO;
req.usockid = conn->usockid; req.usockid = conn->usockid;
req.flags = flags; req.flags = flags;
req.addrlen = addrlen; req.addrlen = msg->msg_namelen;
req.buflen = buflen;
for (i = 0; i < msg->msg_iovlen; i++)
{
req.buflen += msg->msg_iov[i].iov_len;
}
if (req.buflen > UINT16_MAX)
{
req.buflen = UINT16_MAX;
}
bufs[0].iov_base = (FAR void *)&req; bufs[0].iov_base = (FAR void *)&req;
bufs[0].iov_len = sizeof(req); bufs[0].iov_len = sizeof(req);
bufs[1].iov_base = (FAR void *)addr; bufs[1].iov_base = msg->msg_name;
bufs[1].iov_len = addrlen; bufs[1].iov_len = msg->msg_namelen;
bufs[2].iov_base = (FAR void *)buf;
bufs[2].iov_len = buflen; memcpy(&bufs[2], msg->msg_iov, sizeof(struct iovec) * msg->msg_iovlen);
return usrsockdev_do_request(conn, bufs, ARRAY_SIZE(bufs)); return usrsockdev_do_request(conn, bufs, ARRAY_SIZE(bufs));
} }
@ -210,13 +213,9 @@ static int do_sendto_request(FAR struct usrsock_conn_s *conn,
* *
****************************************************************************/ ****************************************************************************/
ssize_t usrsock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg, ssize_t usrsock_sendmsg(FAR struct socket *psock,
int flags) FAR struct msghdr *msg, int flags)
{ {
FAR const void *buf = msg->msg_iov->iov_base;
size_t len = msg->msg_iov->iov_len;
FAR const struct sockaddr *to = msg->msg_name;
socklen_t tolen = msg->msg_namelen;
FAR struct usrsock_conn_s *conn = psock->s_conn; FAR struct usrsock_conn_s *conn = psock->s_conn;
struct usrsock_reqstate_s state = struct usrsock_reqstate_s state =
{ {
@ -226,13 +225,6 @@ ssize_t usrsock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
DEBUGASSERT(conn); DEBUGASSERT(conn);
/* Validity check, only single iov supported */
if (msg->msg_iovlen != 1)
{
return -ENOTSUP;
}
net_lock(); net_lock();
if (conn->state == USRSOCK_CONN_STATE_UNINITIALIZED || if (conn->state == USRSOCK_CONN_STATE_UNINITIALIZED ||
@ -271,7 +263,7 @@ ssize_t usrsock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
} }
} }
if (to || tolen) if (msg->msg_name || msg->msg_namelen)
{ {
/* Address provided for connection-mode socket */ /* Address provided for connection-mode socket */
@ -394,15 +386,13 @@ ssize_t usrsock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
/* Request user-space daemon to close socket. */ /* Request user-space daemon to close socket. */
ret = do_sendto_request(conn, buf, len, to, tolen, flags); ret = do_sendto_request(conn, msg, flags);
if (ret >= 0) if (ret >= 0)
{ {
/* Wait for completion of request. */ /* Wait for completion of request. */
net_lockedwait_uninterruptible(&state.recvsem); net_lockedwait_uninterruptible(&state.recvsem);
ret = state.result; ret = state.result;
DEBUGASSERT(ret <= (ssize_t)len);
} }
usrsock_teardown_request_callback(&state); usrsock_teardown_request_callback(&state);