rpmsg_socket: add shutdown support

Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2023-11-22 20:46:26 +08:00 committed by Xiang Xiao
parent 6ce7b70a3a
commit f7f8f6c104

View file

@ -52,6 +52,7 @@
#define RPMSG_SOCKET_CMD_SYNC 1
#define RPMSG_SOCKET_CMD_DATA 2
#define RPMSG_SOCKET_CMD_SHUTDOWN 3
#define RPMSG_SOCKET_NAME_PREFIX "sk:"
#define RPMSG_SOCKET_NAME_PREFIX_LEN 3
#define RPMSG_SOCKET_NAME_ID_LEN 13
@ -83,6 +84,12 @@ begin_packed_struct struct rpmsg_socket_data_s
char data[0];
} end_packed_struct;
begin_packed_struct struct rpmsg_socket_shutdown_s
{
uint32_t cmd;
uint32_t how;
} end_packed_struct;
struct rpmsg_socket_conn_s
{
/* Common prologue of all connection structures. */
@ -95,6 +102,7 @@ struct rpmsg_socket_conn_s
struct sockaddr_rpmsg rpaddr;
char nameid[RPMSG_SOCKET_NAME_ID_LEN];
uint16_t crefs;
uint32_t how;
FAR struct pollfd *fds[CONFIG_NET_RPMSG_NPOLLWAITERS];
mutex_t polllock;
@ -172,6 +180,7 @@ static ssize_t rpmsg_socket_recvmsg(FAR struct socket *psock,
static int rpmsg_socket_close(FAR struct socket *psock);
static int rpmsg_socket_ioctl(FAR struct socket *psock,
int cmd, unsigned long arg);
static int rpmsg_socket_shutdown(FAR struct socket *psock, int how);
#ifdef CONFIG_NET_SOCKOPTS
static int rpmsg_socket_getsockopt(FAR struct socket *psock,
int level, int option,
@ -204,7 +213,7 @@ const struct sock_intf_s g_rpmsg_sockif =
rpmsg_socket_close, /* si_close */
rpmsg_socket_ioctl, /* si_ioctl */
NULL, /* si_socketpair */
NULL /* si_shutdown */
rpmsg_socket_shutdown /* si_shutdown */
#ifdef CONFIG_NET_SOCKOPTS
, rpmsg_socket_getsockopt /* si_getsockopt */
, rpmsg_socket_setsockopt /* si_setsockopt */
@ -340,7 +349,7 @@ static int rpmsg_socket_ept_cb(FAR struct rpmsg_endpoint *ept,
rpmsg_socket_poll_notify(conn, POLLOUT);
nxmutex_unlock(&conn->recvlock);
}
else
else if (head->cmd == RPMSG_SOCKET_CMD_DATA)
{
FAR struct rpmsg_socket_data_s *msg = data;
FAR uint8_t *buf = (FAR uint8_t *)msg->data;
@ -408,6 +417,26 @@ static int rpmsg_socket_ept_cb(FAR struct rpmsg_endpoint *ept,
nxmutex_unlock(&conn->recvlock);
}
}
else if (head->cmd == RPMSG_SOCKET_CMD_SHUTDOWN)
{
FAR struct rpmsg_socket_shutdown_s *msg = data;
if (msg->how & SHUT_WR)
{
conn->how |= SHUT_RD;
rpmsg_socket_post(&conn->recvsem);
rpmsg_socket_poll_notify(conn, POLLIN | POLLHUP);
}
if (msg->how & SHUT_RD)
{
conn->how |= SHUT_WR;
rpmsg_socket_post(&conn->sendsem);
rpmsg_socket_poll_notify(conn, POLLOUT | POLLHUP);
}
}
return 0;
}
@ -1221,6 +1250,11 @@ static ssize_t rpmsg_socket_sendmsg(FAR struct socket *psock,
return -ECONNRESET;
}
if (conn->how & SHUT_WR)
{
return -EPIPE;
}
nonblock = _SS_ISNONBLOCK(conn->sconn.s_flags) ||
(flags & MSG_DONTWAIT) != 0;
@ -1259,6 +1293,11 @@ static ssize_t rpmsg_socket_recvmsg(FAR struct socket *psock,
return -EISCONN;
}
if (conn->how & SHUT_RD)
{
return 0;
}
nxmutex_lock(&conn->recvlock);
if (psock->s_type != SOCK_STREAM)
@ -1425,6 +1464,29 @@ static int rpmsg_socket_ioctl(FAR struct socket *psock,
return ret;
}
static int rpmsg_socket_shutdown(FAR struct socket *psock, int how)
{
FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
struct rpmsg_socket_shutdown_s msg;
int ret;
if (!conn->ept.rdev || conn->unbind)
{
return -ENOTCONN;
}
conn->how |= how;
msg.cmd = RPMSG_SOCKET_CMD_SHUTDOWN;
msg.how = how;
ret = rpmsg_send(&conn->ept, &msg, sizeof(msg));
if (ret < 0)
return ret;
return OK;
}
#ifdef CONFIG_NET_SOCKOPTS
static int rpmsg_socket_getsockopt(FAR struct socket *psock, int level,
int option, FAR void *value,