rpmsg_socket: add shutdown support
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
6ce7b70a3a
commit
f7f8f6c104
1 changed files with 64 additions and 2 deletions
|
@ -52,6 +52,7 @@
|
||||||
|
|
||||||
#define RPMSG_SOCKET_CMD_SYNC 1
|
#define RPMSG_SOCKET_CMD_SYNC 1
|
||||||
#define RPMSG_SOCKET_CMD_DATA 2
|
#define RPMSG_SOCKET_CMD_DATA 2
|
||||||
|
#define RPMSG_SOCKET_CMD_SHUTDOWN 3
|
||||||
#define RPMSG_SOCKET_NAME_PREFIX "sk:"
|
#define RPMSG_SOCKET_NAME_PREFIX "sk:"
|
||||||
#define RPMSG_SOCKET_NAME_PREFIX_LEN 3
|
#define RPMSG_SOCKET_NAME_PREFIX_LEN 3
|
||||||
#define RPMSG_SOCKET_NAME_ID_LEN 13
|
#define RPMSG_SOCKET_NAME_ID_LEN 13
|
||||||
|
@ -83,6 +84,12 @@ begin_packed_struct struct rpmsg_socket_data_s
|
||||||
char data[0];
|
char data[0];
|
||||||
} end_packed_struct;
|
} 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
|
struct rpmsg_socket_conn_s
|
||||||
{
|
{
|
||||||
/* Common prologue of all connection structures. */
|
/* Common prologue of all connection structures. */
|
||||||
|
@ -95,6 +102,7 @@ struct rpmsg_socket_conn_s
|
||||||
struct sockaddr_rpmsg rpaddr;
|
struct sockaddr_rpmsg rpaddr;
|
||||||
char nameid[RPMSG_SOCKET_NAME_ID_LEN];
|
char nameid[RPMSG_SOCKET_NAME_ID_LEN];
|
||||||
uint16_t crefs;
|
uint16_t crefs;
|
||||||
|
uint32_t how;
|
||||||
|
|
||||||
FAR struct pollfd *fds[CONFIG_NET_RPMSG_NPOLLWAITERS];
|
FAR struct pollfd *fds[CONFIG_NET_RPMSG_NPOLLWAITERS];
|
||||||
mutex_t polllock;
|
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_close(FAR struct socket *psock);
|
||||||
static int rpmsg_socket_ioctl(FAR struct socket *psock,
|
static int rpmsg_socket_ioctl(FAR struct socket *psock,
|
||||||
int cmd, unsigned long arg);
|
int cmd, unsigned long arg);
|
||||||
|
static int rpmsg_socket_shutdown(FAR struct socket *psock, int how);
|
||||||
#ifdef CONFIG_NET_SOCKOPTS
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
static int rpmsg_socket_getsockopt(FAR struct socket *psock,
|
static int rpmsg_socket_getsockopt(FAR struct socket *psock,
|
||||||
int level, int option,
|
int level, int option,
|
||||||
|
@ -204,7 +213,7 @@ const struct sock_intf_s g_rpmsg_sockif =
|
||||||
rpmsg_socket_close, /* si_close */
|
rpmsg_socket_close, /* si_close */
|
||||||
rpmsg_socket_ioctl, /* si_ioctl */
|
rpmsg_socket_ioctl, /* si_ioctl */
|
||||||
NULL, /* si_socketpair */
|
NULL, /* si_socketpair */
|
||||||
NULL /* si_shutdown */
|
rpmsg_socket_shutdown /* si_shutdown */
|
||||||
#ifdef CONFIG_NET_SOCKOPTS
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
, rpmsg_socket_getsockopt /* si_getsockopt */
|
, rpmsg_socket_getsockopt /* si_getsockopt */
|
||||||
, rpmsg_socket_setsockopt /* si_setsockopt */
|
, 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);
|
rpmsg_socket_poll_notify(conn, POLLOUT);
|
||||||
nxmutex_unlock(&conn->recvlock);
|
nxmutex_unlock(&conn->recvlock);
|
||||||
}
|
}
|
||||||
else
|
else if (head->cmd == RPMSG_SOCKET_CMD_DATA)
|
||||||
{
|
{
|
||||||
FAR struct rpmsg_socket_data_s *msg = data;
|
FAR struct rpmsg_socket_data_s *msg = data;
|
||||||
FAR uint8_t *buf = (FAR uint8_t *)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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1221,6 +1250,11 @@ static ssize_t rpmsg_socket_sendmsg(FAR struct socket *psock,
|
||||||
return -ECONNRESET;
|
return -ECONNRESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conn->how & SHUT_WR)
|
||||||
|
{
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
nonblock = _SS_ISNONBLOCK(conn->sconn.s_flags) ||
|
nonblock = _SS_ISNONBLOCK(conn->sconn.s_flags) ||
|
||||||
(flags & MSG_DONTWAIT) != 0;
|
(flags & MSG_DONTWAIT) != 0;
|
||||||
|
|
||||||
|
@ -1259,6 +1293,11 @@ static ssize_t rpmsg_socket_recvmsg(FAR struct socket *psock,
|
||||||
return -EISCONN;
|
return -EISCONN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conn->how & SHUT_RD)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
nxmutex_lock(&conn->recvlock);
|
nxmutex_lock(&conn->recvlock);
|
||||||
|
|
||||||
if (psock->s_type != SOCK_STREAM)
|
if (psock->s_type != SOCK_STREAM)
|
||||||
|
@ -1425,6 +1464,29 @@ static int rpmsg_socket_ioctl(FAR struct socket *psock,
|
||||||
return ret;
|
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
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
static int rpmsg_socket_getsockopt(FAR struct socket *psock, int level,
|
static int rpmsg_socket_getsockopt(FAR struct socket *psock, int level,
|
||||||
int option, FAR void *value,
|
int option, FAR void *value,
|
||||||
|
|
Loading…
Reference in a new issue