arch/sim: add native socket support based on usrsock
Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
c9d784a238
commit
b90d094138
@ -127,15 +127,28 @@ config SIM_WALLTIME_SIGNAL
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Simulated Network Interface"
|
||||
default SIM_NETDEV
|
||||
depends on NET
|
||||
optional
|
||||
|
||||
config SIM_NETDEV
|
||||
bool "Simulated Network Device"
|
||||
default y
|
||||
select ARCH_HAVE_NETDEV_STATISTICS
|
||||
select SCHED_LPWORK
|
||||
depends on NET_ETHERNET
|
||||
select NET_ETHERNET
|
||||
---help---
|
||||
Build in support for a simulated network device.
|
||||
|
||||
config SIM_NETUSRSOCK
|
||||
bool "Simulated Network Device with Native Stack via usrsock"
|
||||
select NET_USRSOCK
|
||||
---help---
|
||||
Built-in support for a simulated network device using native stack via usrsock
|
||||
|
||||
endchoice
|
||||
|
||||
if SIM_NETDEV
|
||||
|
||||
choice
|
||||
|
@ -170,6 +170,11 @@ else ifeq ($(CONFIG_SIM_NETDEV_VPNKIT),y)
|
||||
HOSTSRCS += protocol.c negotiate.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIM_NETUSRSOCK),y)
|
||||
HOSTSRCS += up_usrsock_host.c
|
||||
CSRCS += up_usrsock.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SIM_HCISOCKET),y)
|
||||
HOSTSRCS += up_hcisocket_host.c
|
||||
CSRCS += up_hcisocket.c
|
||||
|
@ -31,6 +31,7 @@
|
||||
#endif
|
||||
|
||||
NXSYMBOLS(__cxa_atexit)
|
||||
NXSYMBOLS(accept)
|
||||
NXSYMBOLS(atexit)
|
||||
NXSYMBOLS(bind)
|
||||
NXSYMBOLS(calloc)
|
||||
@ -45,13 +46,18 @@ NXSYMBOLS(dup)
|
||||
NXSYMBOLS(exit)
|
||||
NXSYMBOLS(fchmod)
|
||||
NXSYMBOLS(fchown)
|
||||
NXSYMBOLS(fcntl)
|
||||
NXSYMBOLS(free)
|
||||
NXSYMBOLS(fstat)
|
||||
NXSYMBOLS(fsync)
|
||||
NXSYMBOLS(ftruncate)
|
||||
NXSYMBOLS(futimens)
|
||||
NXSYMBOLS(getpeername)
|
||||
NXSYMBOLS(getsockname)
|
||||
NXSYMBOLS(getsockopt)
|
||||
NXSYMBOLS(if_nametoindex)
|
||||
NXSYMBOLS(ioctl)
|
||||
NXSYMBOLS(listen)
|
||||
NXSYMBOLS(longjmp)
|
||||
NXSYMBOLS(lseek)
|
||||
NXSYMBOLS(malloc)
|
||||
@ -87,14 +93,17 @@ NXSYMBOLS(read)
|
||||
NXSYMBOLS(readdir)
|
||||
NXSYMBOLS(readv)
|
||||
NXSYMBOLS(realloc)
|
||||
NXSYMBOLS(recvfrom)
|
||||
NXSYMBOLS(rename)
|
||||
NXSYMBOLS(rewinddir)
|
||||
NXSYMBOLS(rmdir)
|
||||
NXSYMBOLS(sched_yield)
|
||||
NXSYMBOLS(select)
|
||||
NXSYMBOLS(sendmsg)
|
||||
NXSYMBOLS(sendto)
|
||||
NXSYMBOLS(setitimer)
|
||||
NXSYMBOLS(setjmp)
|
||||
NXSYMBOLS(setsockopt)
|
||||
NXSYMBOLS(shutdown)
|
||||
NXSYMBOLS(sigaction)
|
||||
NXSYMBOLS(sigaddset)
|
||||
|
@ -90,6 +90,10 @@ void up_idle(void)
|
||||
netdriver_loop();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIM_NETUSRSOCK
|
||||
usrsock_loop();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RPTUN
|
||||
up_rptun_loop();
|
||||
#endif
|
||||
|
@ -246,6 +246,12 @@ void up_initialize(void)
|
||||
netdriver_init(); /* Our "real" network driver */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SIM_NETUSRSOCK
|
||||
/* Register the usrsock native socket device */
|
||||
|
||||
usrsock_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_LOOPBACK
|
||||
/* Initialize the local loopback device */
|
||||
|
||||
|
@ -316,6 +316,13 @@ void netdriver_setmacaddr(unsigned char *macaddr);
|
||||
void netdriver_setmtu(int mtu);
|
||||
void netdriver_loop(void);
|
||||
|
||||
/* up_usrsock.c *************************************************************/
|
||||
|
||||
#ifdef CONFIG_SIM_NETUSRSOCK
|
||||
int usrsock_init(void);
|
||||
void usrsock_loop(void);
|
||||
#endif
|
||||
|
||||
/* up_rptun.c ***************************************************************/
|
||||
|
||||
#ifdef CONFIG_RPTUN
|
||||
|
443
arch/sim/src/sim/up_usrsock.c
Normal file
443
arch/sim/src/sim/up_usrsock.c
Normal file
@ -0,0 +1,443 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/up_usrsock.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/usrsock.h>
|
||||
|
||||
#include "up_usrsock_host.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
struct usrsock_s
|
||||
{
|
||||
struct file usock;
|
||||
uint8_t data[4096];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
typedef int (*usrsock_handler_t)(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct usrsock_s g_usrsock;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int usrsock_send(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *buf, size_t len)
|
||||
{
|
||||
FAR uint8_t *data = (FAR uint8_t *)buf;
|
||||
ssize_t ret;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
ret = file_write(&usrsock->usock, data, len);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
data += ret;
|
||||
len -= ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usrsock_send_ack(FAR struct usrsock_s *usrsock,
|
||||
uint8_t xid, int32_t result)
|
||||
{
|
||||
struct usrsock_message_req_ack_s ack;
|
||||
|
||||
ack.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK;
|
||||
ack.head.flags = (result == -EINPROGRESS);
|
||||
|
||||
ack.xid = xid;
|
||||
ack.result = result;
|
||||
|
||||
return usrsock_send(usrsock, &ack, sizeof(ack));
|
||||
}
|
||||
|
||||
static int usrsock_send_dack(FAR struct usrsock_s *usrsock,
|
||||
FAR struct usrsock_message_datareq_ack_s *ack,
|
||||
uint8_t xid, int32_t result,
|
||||
uint16_t valuelen,
|
||||
uint16_t valuelen_nontrunc)
|
||||
{
|
||||
ack->reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK;
|
||||
ack->reqack.head.flags = 0;
|
||||
|
||||
ack->reqack.xid = xid;
|
||||
ack->reqack.result = result;
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
result = 0;
|
||||
valuelen = 0;
|
||||
valuelen_nontrunc = 0;
|
||||
}
|
||||
else if (valuelen > valuelen_nontrunc)
|
||||
{
|
||||
valuelen = valuelen_nontrunc;
|
||||
}
|
||||
|
||||
ack->valuelen = valuelen;
|
||||
ack->valuelen_nontrunc = valuelen_nontrunc;
|
||||
|
||||
return usrsock_send(usrsock, ack, sizeof(*ack) + valuelen + result);
|
||||
}
|
||||
|
||||
static int usrsock_send_event(FAR struct usrsock_s *usrsock,
|
||||
int16_t usockid, uint16_t events)
|
||||
{
|
||||
struct usrsock_message_socket_event_s event;
|
||||
|
||||
event.head.msgid = USRSOCK_MESSAGE_SOCKET_EVENT;
|
||||
event.head.flags = USRSOCK_MESSAGE_FLAG_EVENT;
|
||||
|
||||
event.usockid = usockid;
|
||||
event.events = events;
|
||||
|
||||
return usrsock_send(usrsock, &event, sizeof(event));
|
||||
}
|
||||
|
||||
static int usrsock_socket_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_socket_s *req = data;
|
||||
int fd = usrsock_host_socket(req->domain, req->type, req->protocol);
|
||||
|
||||
usrsock_send_ack(usrsock, req->head.xid, fd);
|
||||
if (fd > 0)
|
||||
{
|
||||
usrsock_send_event(usrsock, fd, USRSOCK_EVENT_SENDTO_READY);
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int usrsock_close_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_close_s *req = data;
|
||||
int ret = usrsock_host_close(req->usockid);
|
||||
|
||||
return usrsock_send_ack(usrsock, req->head.xid, ret);
|
||||
}
|
||||
|
||||
static int usrsock_connect_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_connect_s *req = data;
|
||||
int ret = usrsock_host_connect(req->usockid,
|
||||
(FAR const struct sockaddr *)(req + 1),
|
||||
req->addrlen);
|
||||
|
||||
return usrsock_send_ack(usrsock, req->head.xid, ret);
|
||||
}
|
||||
|
||||
static int usrsock_sendto_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_sendto_s *req = data;
|
||||
int ret = usrsock_host_sendto(req->usockid,
|
||||
(FAR const void *)(req + 1) + req->addrlen,
|
||||
req->buflen, req->flags,
|
||||
req->addrlen ?
|
||||
(FAR const struct sockaddr *)(req + 1) :
|
||||
NULL, req->addrlen);
|
||||
|
||||
usrsock_send_ack(usrsock, req->head.xid, ret);
|
||||
if (ret > 0)
|
||||
{
|
||||
ret = usrsock_send_event(usrsock, req->usockid,
|
||||
USRSOCK_EVENT_SENDTO_READY);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usrsock_recvfrom_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_recvfrom_s *req = data;
|
||||
FAR struct usrsock_message_datareq_ack_s *ack;
|
||||
socklen_t outaddrlen = req->max_addrlen;
|
||||
socklen_t inaddrlen = req->max_addrlen;
|
||||
size_t buflen = req->max_buflen;
|
||||
int ret;
|
||||
|
||||
ack = (struct usrsock_message_datareq_ack_s *)usrsock->data;
|
||||
if (sizeof(*ack) + inaddrlen + buflen > sizeof(usrsock->data))
|
||||
{
|
||||
buflen = sizeof(usrsock->data) - sizeof(*ack) - inaddrlen;
|
||||
}
|
||||
|
||||
ret = usrsock_host_recvfrom(req->usockid,
|
||||
(FAR void *)(ack + 1) + inaddrlen,
|
||||
buflen, req->flags,
|
||||
outaddrlen ?
|
||||
(FAR struct sockaddr *)(ack + 1) : NULL,
|
||||
outaddrlen ? &outaddrlen : NULL);
|
||||
if (ret > 0 && outaddrlen < inaddrlen)
|
||||
{
|
||||
memcpy((FAR void *)(ack + 1) + outaddrlen,
|
||||
(FAR void *)(ack + 1) + inaddrlen, ret);
|
||||
}
|
||||
|
||||
return usrsock_send_dack(usrsock, ack, req->head.xid,
|
||||
ret, inaddrlen, outaddrlen);
|
||||
}
|
||||
|
||||
static int usrsock_setsockopt_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_setsockopt_s *req = data;
|
||||
int ret = usrsock_host_setsockopt(req->usockid, req->level,
|
||||
req->option, req + 1, req->valuelen);
|
||||
|
||||
return usrsock_send_ack(usrsock, req->head.xid, ret);
|
||||
}
|
||||
|
||||
static int usrsock_getsockopt_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_getsockopt_s *req = data;
|
||||
FAR struct usrsock_message_datareq_ack_s *ack;
|
||||
socklen_t optlen = req->max_valuelen;
|
||||
int ret;
|
||||
|
||||
ack = (FAR struct usrsock_message_datareq_ack_s *)usrsock->data;
|
||||
ret = usrsock_host_getsockopt(req->usockid,
|
||||
req->level, req->option,
|
||||
ack + 1, &optlen);
|
||||
|
||||
return usrsock_send_dack(usrsock, ack, req->head.xid,
|
||||
ret, optlen, optlen);
|
||||
}
|
||||
|
||||
static int usrsock_getsockname_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_getsockname_s *req = data;
|
||||
FAR struct usrsock_message_datareq_ack_s *ack;
|
||||
socklen_t outaddrlen = req->max_addrlen;
|
||||
socklen_t inaddrlen = req->max_addrlen;
|
||||
int ret;
|
||||
|
||||
ack = (FAR struct usrsock_message_datareq_ack_s *)usrsock->data;
|
||||
ret = usrsock_host_getsockname(req->usockid,
|
||||
(FAR struct sockaddr *)(ack + 1), &outaddrlen);
|
||||
|
||||
return usrsock_send_dack(usrsock, ack, req->head.xid,
|
||||
ret, inaddrlen, outaddrlen);
|
||||
}
|
||||
|
||||
static int usrsock_getpeername_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_getpeername_s *req = data;
|
||||
FAR struct usrsock_message_datareq_ack_s *ack;
|
||||
socklen_t outaddrlen = req->max_addrlen;
|
||||
socklen_t inaddrlen = req->max_addrlen;
|
||||
int ret;
|
||||
|
||||
ack = (FAR struct usrsock_message_datareq_ack_s *)usrsock->data;
|
||||
ret = usrsock_host_getpeername(req->usockid,
|
||||
(FAR struct sockaddr *)(ack + 1), &outaddrlen);
|
||||
|
||||
return usrsock_send_dack(usrsock, ack, req->head.xid,
|
||||
ret, inaddrlen, outaddrlen);
|
||||
}
|
||||
|
||||
static int usrsock_bind_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_bind_s *req = data;
|
||||
int ret = usrsock_host_bind(req->usockid,
|
||||
(FAR const struct sockaddr *)(req + 1),
|
||||
req->addrlen);
|
||||
|
||||
return usrsock_send_ack(usrsock, req->head.xid, ret);
|
||||
}
|
||||
|
||||
static int usrsock_listen_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_listen_s *req = data;
|
||||
int ret = usrsock_host_listen(req->usockid, req->backlog);
|
||||
|
||||
return usrsock_send_ack(usrsock, req->head.xid, ret);
|
||||
}
|
||||
|
||||
static int usrsock_accept_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_accept_s *req = data;
|
||||
FAR struct usrsock_message_datareq_ack_s *ack;
|
||||
socklen_t outaddrlen = req->max_addrlen;
|
||||
socklen_t inaddrlen = req->max_addrlen;
|
||||
int sockfd;
|
||||
int ret;
|
||||
|
||||
ack = (FAR struct usrsock_message_datareq_ack_s *)usrsock->data;
|
||||
sockfd = usrsock_host_accept(req->usockid,
|
||||
outaddrlen ?
|
||||
(FAR struct sockaddr *)(ack + 1) : NULL,
|
||||
outaddrlen ? &outaddrlen : NULL);
|
||||
if (sockfd > 0)
|
||||
{
|
||||
/* Append index as usockid to the payload */
|
||||
|
||||
if (outaddrlen <= inaddrlen)
|
||||
{
|
||||
*(FAR int16_t *)((FAR void *)(ack + 1) + outaddrlen) = sockfd;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(FAR int16_t *)((FAR void *)(ack + 1) + inaddrlen) = sockfd;
|
||||
}
|
||||
|
||||
ret = sizeof(int16_t); /* Return usockid size */
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = sockfd;
|
||||
}
|
||||
|
||||
usrsock_send_dack(usrsock, ack, req->head.xid, ret,
|
||||
inaddrlen, outaddrlen);
|
||||
if (ret > 0)
|
||||
{
|
||||
usrsock_send_event(usrsock, sockfd, USRSOCK_EVENT_SENDTO_READY);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usrsock_ioctl_handler(FAR struct usrsock_s *usrsock,
|
||||
FAR const void *data, size_t len)
|
||||
{
|
||||
FAR const struct usrsock_request_ioctl_s *req = data;
|
||||
FAR struct usrsock_message_datareq_ack_s *ack;
|
||||
int ret;
|
||||
|
||||
ack = (FAR struct usrsock_message_datareq_ack_s *)usrsock->data;
|
||||
memcpy(ack + 1, req + 1, req->arglen);
|
||||
ret = usrsock_host_ioctl(req->usockid, req->cmd,
|
||||
(unsigned long)(ack + 1));
|
||||
|
||||
return usrsock_send_dack(usrsock, ack, req->head.xid, ret,
|
||||
req->arglen, req->arglen);
|
||||
}
|
||||
|
||||
static const usrsock_handler_t g_usrsock_handler[] =
|
||||
{
|
||||
[USRSOCK_REQUEST_SOCKET] = usrsock_socket_handler,
|
||||
[USRSOCK_REQUEST_CLOSE] = usrsock_close_handler,
|
||||
[USRSOCK_REQUEST_CONNECT] = usrsock_connect_handler,
|
||||
[USRSOCK_REQUEST_SENDTO] = usrsock_sendto_handler,
|
||||
[USRSOCK_REQUEST_RECVFROM] = usrsock_recvfrom_handler,
|
||||
[USRSOCK_REQUEST_SETSOCKOPT] = usrsock_setsockopt_handler,
|
||||
[USRSOCK_REQUEST_GETSOCKOPT] = usrsock_getsockopt_handler,
|
||||
[USRSOCK_REQUEST_GETSOCKNAME] = usrsock_getsockname_handler,
|
||||
[USRSOCK_REQUEST_GETPEERNAME] = usrsock_getpeername_handler,
|
||||
[USRSOCK_REQUEST_BIND] = usrsock_bind_handler,
|
||||
[USRSOCK_REQUEST_LISTEN] = usrsock_listen_handler,
|
||||
[USRSOCK_REQUEST_ACCEPT] = usrsock_accept_handler,
|
||||
[USRSOCK_REQUEST_IOCTL] = usrsock_ioctl_handler,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int usrsock_event_callback(int16_t usockid, uint16_t events)
|
||||
{
|
||||
return usrsock_send_event(&g_usrsock, usockid, events);
|
||||
}
|
||||
|
||||
int usrsock_init(void)
|
||||
{
|
||||
return file_open(&g_usrsock.usock, "/dev/usrsock", O_RDWR);
|
||||
}
|
||||
|
||||
void usrsock_loop(void)
|
||||
{
|
||||
FAR struct usrsock_request_common_s *common;
|
||||
uint8_t data[4096];
|
||||
int ret;
|
||||
struct pollfd pfd =
|
||||
{
|
||||
.ptr = &g_usrsock.usock,
|
||||
.events = POLLIN | POLLFILE,
|
||||
};
|
||||
|
||||
ret = poll(&pfd, 1, 0);
|
||||
if (ret > 0)
|
||||
{
|
||||
ret = file_read(&g_usrsock.usock, data, sizeof(data));
|
||||
if (ret > 0)
|
||||
{
|
||||
common = (FAR struct usrsock_request_common_s *)data;
|
||||
|
||||
if (common->reqid >= 0 &&
|
||||
common->reqid < USRSOCK_REQUEST__MAX)
|
||||
{
|
||||
ret = g_usrsock_handler[common->reqid](&g_usrsock,
|
||||
data, ret);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Usrsock request %d failed: %d\n",
|
||||
common->reqid, ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR, "Invalid request id: %d\n",
|
||||
common->reqid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usrsock_host_loop();
|
||||
}
|
515
arch/sim/src/sim/up_usrsock_host.c
Normal file
515
arch/sim/src/sim/up_usrsock_host.c
Normal file
@ -0,0 +1,515 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/up_usrsock_host.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "up_usrsock_host.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static int g_active_maxfd = -1;
|
||||
static fd_set g_active_read_fds;
|
||||
static fd_set g_active_write_fds;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void usrsock_host_clear_fd(int fd, fd_set *fds)
|
||||
{
|
||||
if (FD_ISSET(fd, fds))
|
||||
{
|
||||
FD_CLR(fd, fds);
|
||||
|
||||
if (fd == g_active_maxfd)
|
||||
{
|
||||
while (fd--)
|
||||
{
|
||||
if (FD_ISSET(fd, &g_active_read_fds))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (FD_ISSET(fd, &g_active_write_fds))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_active_maxfd = fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usrsock_host_set_fd(int fd, fd_set *fds)
|
||||
{
|
||||
if (!FD_ISSET(fd, fds))
|
||||
{
|
||||
FD_SET(fd, fds);
|
||||
if (fd > g_active_maxfd)
|
||||
{
|
||||
g_active_maxfd = fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sockaddr_to_native(const struct nuttx_sockaddr *addr,
|
||||
const nuttx_socklen_t addrlen,
|
||||
struct sockaddr *naddr,
|
||||
socklen_t *naddrlen)
|
||||
{
|
||||
naddr->sa_family = addr->sa_family;
|
||||
memcpy(naddr->sa_data, addr->sa_data, sizeof(naddr->sa_data));
|
||||
|
||||
*naddrlen = addrlen;
|
||||
}
|
||||
|
||||
static void sockaddr_to_nuttx(const struct sockaddr *naddr,
|
||||
const socklen_t naddrlen,
|
||||
struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t *addrlen)
|
||||
{
|
||||
addr->sa_family = naddr->sa_family;
|
||||
memcpy(addr->sa_data, naddr->sa_data, sizeof(addr->sa_data));
|
||||
|
||||
*addrlen = naddrlen;
|
||||
}
|
||||
|
||||
static void sock_nonblock(int socket, int enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
static int usrsock_host_sockopt(int sockfd, int level, int optname,
|
||||
const void *optval, nuttx_socklen_t *optlen,
|
||||
bool set)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (level == NUTTX_SOL_SOCKET)
|
||||
{
|
||||
level = SOL_SOCKET;
|
||||
}
|
||||
else if (level == NUTTX_IPPROTO_TCP)
|
||||
{
|
||||
level = IPPROTO_TCP;
|
||||
}
|
||||
else if (level == NUTTX_IPPROTO_UDP)
|
||||
{
|
||||
level = IPPROTO_UDP;
|
||||
}
|
||||
else if (level == NUTTX_IPPROTO_IP)
|
||||
{
|
||||
level = IPPROTO_IP;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (optname == NUTTX_SO_REUSEADDR)
|
||||
{
|
||||
optname = SO_REUSEADDR;
|
||||
}
|
||||
else if (optname == NUTTX_SO_ERROR)
|
||||
{
|
||||
optname = SO_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR, "Invalid optname: %x\n", optname);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (set)
|
||||
{
|
||||
ret = setsockopt(sockfd, level, optname, optval, *optlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = getsockopt(sockfd, level, optname, (void *)optval, optlen);
|
||||
}
|
||||
|
||||
return ret < 0 ? -errno : 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
int usrsock_host_socket(int domain, int type, int protocol)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (domain == NUTTX_PF_INET)
|
||||
{
|
||||
domain = PF_INET;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type == NUTTX_SOCK_STREAM)
|
||||
{
|
||||
type = SOCK_STREAM;
|
||||
}
|
||||
else if (type == NUTTX_SOCK_DGRAM)
|
||||
{
|
||||
type = SOCK_DGRAM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (protocol == NUTTX_IPPROTO_IP)
|
||||
{
|
||||
protocol = IPPROTO_IP;
|
||||
}
|
||||
else if (protocol == NUTTX_IPPROTO_ICMP)
|
||||
{
|
||||
protocol = IPPROTO_ICMP;
|
||||
}
|
||||
else if (protocol == NUTTX_IPPROTO_TCP)
|
||||
{
|
||||
protocol = IPPROTO_TCP;
|
||||
}
|
||||
else if (protocol == NUTTX_IPPROTO_UDP)
|
||||
{
|
||||
protocol = IPPROTO_UDP;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = socket(domain, type, protocol);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
sock_nonblock(ret, true);
|
||||
usrsock_host_set_fd(ret, &g_active_read_fds);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usrsock_host_close(int sockfd)
|
||||
{
|
||||
usrsock_host_clear_fd(sockfd, &g_active_read_fds);
|
||||
usrsock_host_clear_fd(sockfd, &g_active_write_fds);
|
||||
|
||||
return close(sockfd);
|
||||
}
|
||||
|
||||
int usrsock_host_connect(int sockfd,
|
||||
const struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t addrlen)
|
||||
{
|
||||
struct sockaddr naddr;
|
||||
socklen_t naddrlen;
|
||||
int ret;
|
||||
|
||||
sockaddr_to_native(addr, addrlen, &naddr, &naddrlen);
|
||||
|
||||
sock_nonblock(sockfd, false);
|
||||
ret = connect(sockfd, &naddr, naddrlen);
|
||||
sock_nonblock(sockfd, true);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
usrsock_host_set_fd(sockfd, &g_active_read_fds);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t usrsock_host_sendto(int sockfd, const void *buf,
|
||||
size_t len, int flags,
|
||||
const struct nuttx_sockaddr *dest_addr,
|
||||
nuttx_socklen_t addrlen)
|
||||
{
|
||||
struct sockaddr naddr;
|
||||
socklen_t naddrlen;
|
||||
int ret;
|
||||
|
||||
if (dest_addr && addrlen >= sizeof(*dest_addr))
|
||||
{
|
||||
sockaddr_to_native(dest_addr, addrlen, &naddr, &naddrlen);
|
||||
ret = sendto(sockfd, buf, len, flags, &naddr, naddrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = sendto(sockfd, buf, len, flags, NULL, 0);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
{
|
||||
usrsock_host_set_fd(sockfd, &g_active_write_fds);
|
||||
}
|
||||
else
|
||||
{
|
||||
usrsock_event_callback(sockfd, NUTTX_USRSOCK_EVENT_REMOTE_CLOSED);
|
||||
}
|
||||
}
|
||||
|
||||
return ret >= 0 ? ret : -errno;
|
||||
}
|
||||
|
||||
ssize_t usrsock_host_recvfrom(int sockfd, void *buf, size_t len, int flags,
|
||||
struct nuttx_sockaddr *src_addr,
|
||||
nuttx_socklen_t *addrlen)
|
||||
{
|
||||
struct sockaddr naddr;
|
||||
socklen_t naddrlen;
|
||||
int ret;
|
||||
|
||||
if (src_addr && addrlen && *addrlen >= sizeof(*src_addr))
|
||||
{
|
||||
sockaddr_to_native(src_addr, *addrlen, &naddr, &naddrlen);
|
||||
ret = recvfrom(sockfd, buf, len, flags, &naddr, &naddrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = recvfrom(sockfd, buf, len, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
if (ret == 0 || errno != EAGAIN)
|
||||
{
|
||||
usrsock_event_callback(sockfd, NUTTX_USRSOCK_EVENT_REMOTE_CLOSED);
|
||||
}
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (src_addr && addrlen && *addrlen >= sizeof(*src_addr))
|
||||
{
|
||||
sockaddr_to_nuttx(&naddr, naddrlen, src_addr, addrlen);
|
||||
}
|
||||
|
||||
usrsock_host_set_fd(sockfd, &g_active_read_fds);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usrsock_host_setsockopt(int sockfd, int level, int optname,
|
||||
const void *optval, nuttx_socklen_t optlen)
|
||||
{
|
||||
return usrsock_host_sockopt(sockfd, level, optname,
|
||||
optval, &optlen, true);
|
||||
}
|
||||
|
||||
int usrsock_host_getsockopt(int sockfd, int level, int optname,
|
||||
void *optval, nuttx_socklen_t *optlen)
|
||||
{
|
||||
return usrsock_host_sockopt(sockfd, level, optname,
|
||||
optval, optlen, false);
|
||||
}
|
||||
|
||||
int usrsock_host_getsockname(int sockfd,
|
||||
struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t *addrlen)
|
||||
{
|
||||
socklen_t naddrlen = sizeof(struct sockaddr);
|
||||
struct sockaddr naddr;
|
||||
int ret;
|
||||
|
||||
ret = getsockname(sockfd, &naddr, &naddrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (addr && addrlen && *addrlen >= sizeof(*addr))
|
||||
{
|
||||
sockaddr_to_nuttx(&naddr, naddrlen, addr, addrlen);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usrsock_host_getpeername(int sockfd,
|
||||
struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t *addrlen)
|
||||
{
|
||||
socklen_t naddrlen = sizeof(struct sockaddr);
|
||||
struct sockaddr naddr;
|
||||
int ret;
|
||||
|
||||
ret = getpeername(sockfd, &naddr, &naddrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (addr && addrlen && *addrlen >= sizeof(*addr))
|
||||
{
|
||||
sockaddr_to_nuttx(&naddr, naddrlen, addr, addrlen);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usrsock_host_bind(int sockfd,
|
||||
const struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t addrlen)
|
||||
{
|
||||
struct sockaddr naddr;
|
||||
socklen_t naddrlen;
|
||||
|
||||
sockaddr_to_native(addr, addrlen, &naddr, &naddrlen);
|
||||
|
||||
return bind(sockfd, &naddr, naddrlen) < 0 ? -errno : 0;
|
||||
}
|
||||
|
||||
int usrsock_host_listen(int sockfd, int backlog)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = listen(sockfd, backlog);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
usrsock_host_set_fd(sockfd, &g_active_read_fds);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usrsock_host_accept(int sockfd, struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t *addrlen)
|
||||
{
|
||||
struct sockaddr naddr;
|
||||
socklen_t naddrlen;
|
||||
int ret;
|
||||
|
||||
ret = accept(sockfd, &naddr, &naddrlen);
|
||||
if (ret <= 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (addr && addrlen && *addrlen >= sizeof(*addr))
|
||||
{
|
||||
sockaddr_to_nuttx(&naddr, naddrlen, addr, addrlen);
|
||||
}
|
||||
|
||||
sock_nonblock(ret, true);
|
||||
usrsock_host_set_fd(ret, &g_active_read_fds);
|
||||
usrsock_host_set_fd(sockfd, &g_active_read_fds);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usrsock_host_ioctl(int fd, unsigned long request, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usrsock_host_loop(void)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set write_fds;
|
||||
fd_set read_fds;
|
||||
uint16_t events;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (g_active_maxfd <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&timeout, 0x0, sizeof(timeout));
|
||||
memcpy(&read_fds, &g_active_read_fds, sizeof(read_fds));
|
||||
memcpy(&write_fds, &g_active_write_fds, sizeof(write_fds));
|
||||
|
||||
ret = select(g_active_maxfd + 1, &read_fds, &write_fds, NULL, &timeout);
|
||||
if (ret == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i <= g_active_maxfd; i++)
|
||||
{
|
||||
events = 0;
|
||||
|
||||
if (FD_ISSET(i, &read_fds))
|
||||
{
|
||||
usrsock_host_clear_fd(i, &g_active_read_fds);
|
||||
events |= NUTTX_USRSOCK_EVENT_RECVFROM_AVAIL;
|
||||
}
|
||||
|
||||
if (FD_ISSET(i, &write_fds))
|
||||
{
|
||||
usrsock_host_clear_fd(i, &g_active_write_fds);
|
||||
events |= NUTTX_USRSOCK_EVENT_SENDTO_READY;
|
||||
}
|
||||
|
||||
if (events)
|
||||
{
|
||||
usrsock_event_callback(i, events);
|
||||
|
||||
if (--ret == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
317
arch/sim/src/sim/up_usrsock_host.h
Normal file
317
arch/sim/src/sim/up_usrsock_host.h
Normal file
@ -0,0 +1,317 @@
|
||||
/****************************************************************************
|
||||
* arch/sim/src/sim/up_usrsock_host.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_SIM_SRC_SIM_UP_USRSOCK_HOST_H
|
||||
#define __ARCH_SIM_SRC_SIM_UP_USRSOCK_HOST_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __SIM__
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __SIM__
|
||||
|
||||
#define NUTTX_IPPROTO_IP 0
|
||||
#define NUTTX_IPPROTO_HOPOPTS 0
|
||||
#define NUTTX_IPPROTO_ICMP 1
|
||||
#define NUTTX_IPPROTO_IGMP 2
|
||||
#define NUTTX_IPPROTO_IPIP 4
|
||||
#define NUTTX_IPPROTO_TCP 6
|
||||
#define NUTTX_IPPROTO_EGP 8
|
||||
#define NUTTX_IPPROTO_PUP 12
|
||||
#define NUTTX_IPPROTO_UDP 17
|
||||
#define NUTTX_IPPROTO_IDP 22
|
||||
#define NUTTX_IPPROTO_TP 29
|
||||
#define NUTTX_IPPROTO_DCCP 33
|
||||
#define NUTTX_IPPROTO_IPV6 41
|
||||
#define NUTTX_IPPROTO_ROUTING 43
|
||||
#define NUTTX_IPPROTO_FRAGMENT 44
|
||||
#define NUTTX_IPPROTO_RSVP 46
|
||||
#define NUTTX_IPPROTO_GRE 47
|
||||
#define NUTTX_IPPROTO_ESP 50
|
||||
#define NUTTX_IPPROTO_AH 51
|
||||
#define NUTTX_IPPROTO_ICMP6 58
|
||||
#define NUTTX_IPPROTO_NONE 59
|
||||
#define NUTTX_IPPROTO_DSTOPTS 60
|
||||
#define NUTTX_IPPROTO_MTP 92
|
||||
#define NUTTX_IPPROTO_ENCAP 98
|
||||
#define NUTTX_IPPROTO_BEETPH 94
|
||||
#define NUTTX_IPPROTO_PIM 103
|
||||
#define NUTTX_IPPROTO_COMP 108
|
||||
#define NUTTX_IPPROTO_SCTP 132
|
||||
#define NUTTX_IPPROTO_UDPLITE 136
|
||||
#define NUTTX_IPPROTO_MPLS 137
|
||||
#define NUTTX_IPPROTO_RAW 255
|
||||
|
||||
#define NUTTX_PF_UNSPEC 0
|
||||
#define NUTTX_PF_UNIX 1
|
||||
#define NUTTX_PF_LOCAL 1
|
||||
#define NUTTX_PF_INET 2
|
||||
#define NUTTX_PF_INET6 10
|
||||
#define NUTTX_PF_NETLINK 16
|
||||
#define NUTTX_PF_ROUTE NUTTX_PF_NETLINK
|
||||
#define NUTTX_PF_PACKET 17
|
||||
#define NUTTX_PF_CAN 29
|
||||
#define NUTTX_PF_BLUETOOTH 31
|
||||
#define NUTTX_PF_IEEE802154 36
|
||||
#define NUTTX_PF_PKTRADIO 64
|
||||
#define NUTTX_PF_RPMSG 65
|
||||
|
||||
#define NUTTX_AF_UNSPEC NUTTX_PF_UNSPEC
|
||||
#define NUTTX_AF_UNIX NUTTX_PF_UNIX
|
||||
#define NUTTX_AF_LOCAL NUTTX_PF_LOCAL
|
||||
#define NUTTX_AF_INET NUTTX_PF_INET
|
||||
#define NUTTX_AF_INET6 NUTTX_PF_INET6
|
||||
#define NUTTX_AF_NETLINK NUTTX_PF_NETLINK
|
||||
#define NUTTX_AF_ROUTE NUTTX_PF_ROUTE
|
||||
#define NUTTX_AF_PACKET NUTTX_PF_PACKET
|
||||
#define NUTTX_AF_CAN NUTTX_PF_CAN
|
||||
#define NUTTX_AF_BLUETOOTH NUTTX_PF_BLUETOOTH
|
||||
#define NUTTX_AF_IEEE802154 NUTTX_PF_IEEE802154
|
||||
#define NUTTX_AF_PKTRADIO NUTTX_PF_PKTRADIO
|
||||
#define NUTTX_AF_RPMSG NUTTX_PF_RPMSG
|
||||
|
||||
#define NUTTX_SOCK_UNSPEC 0
|
||||
#define NUTTX_SOCK_STREAM 1
|
||||
#define NUTTX_SOCK_DGRAM 2
|
||||
#define NUTTX_SOCK_RAW 3
|
||||
#define NUTTX_SOCK_RDM 4
|
||||
#define NUTTX_SOCK_SEQPACKET 5
|
||||
#define NUTTX_SOCK_PACKET 10
|
||||
#define NUTTX_SOCK_CLOEXEC 02000000
|
||||
#define NUTTX_SOCK_NONBLOCK 00004000
|
||||
|
||||
#define NUTTX_SOCK_MAX (NUTTX_SOCK_PACKET + 1)
|
||||
#define NUTTX_SOCK_TYPE_MASK 0xf
|
||||
|
||||
#define NUTTX_MSG_OOB 0x0001
|
||||
#define NUTTX_MSG_PEEK 0x0002
|
||||
#define NUTTX_MSG_DONTROUTE 0x0004
|
||||
#define NUTTX_MSG_CTRUNC 0x0008
|
||||
#define NUTTX_MSG_PROXY 0x0010
|
||||
#define NUTTX_MSG_TRUNC 0x0020
|
||||
#define NUTTX_MSG_DONTWAIT 0x0040
|
||||
#define NUTTX_MSG_EOR 0x0080
|
||||
#define NUTTX_MSG_WAITALL 0x0100
|
||||
#define NUTTX_MSG_FIN 0x0200
|
||||
#define NUTTX_MSG_SYN 0x0400
|
||||
#define NUTTX_MSG_CONFIRM 0x0800
|
||||
#define NUTTX_MSG_RST 0x1000
|
||||
#define NUTTX_MSG_ERRQUEUE 0x2000
|
||||
#define NUTTX_MSG_NOSIGNAL 0x4000
|
||||
#define NUTTX_MSG_MORE 0x8000
|
||||
|
||||
#define NUTTX_SOL_SOCKET 1
|
||||
#define NUTTX_SO_ACCEPTCONN 0
|
||||
#define NUTTX_SO_BROADCAST 1
|
||||
#define NUTTX_SO_DEBUG 2
|
||||
#define NUTTX_SO_DONTROUTE 3
|
||||
#define NUTTX_SO_ERROR 4
|
||||
#define NUTTX_SO_KEEPALIVE 5
|
||||
#define NUTTX_SO_LINGER 6
|
||||
#define NUTTX_SO_OOBINLINE 7
|
||||
#define NUTTX_SO_RCVBUF 8
|
||||
#define NUTTX_SO_RCVLOWAT 9
|
||||
#define NUTTX_SO_RCVTIMEO 10
|
||||
#define NUTTX_SO_REUSEADDR 11
|
||||
#define NUTTX_SO_SNDBUF 12
|
||||
#define NUTTX_SO_SNDLOWAT 13
|
||||
#define NUTTX_SO_SNDTIMEO 14
|
||||
#define NUTTX_SO_TYPE 15
|
||||
#define NUTTX_SO_TIMESTAMP 16
|
||||
|
||||
#define NUTTX_SO_SNDBUFFORCE 32
|
||||
#define NUTTX_SO_RCVBUFFORCE 33
|
||||
#define NUTTX_SO_RXQ_OVFL 40
|
||||
|
||||
#define NUTTX_SOL_IP NUTTX_IPPROTO_IP
|
||||
#define NUTTX_SOL_IPV6 NUTTX_IPPROTO_IPV6
|
||||
#define NUTTX_SOL_TCP NUTTX_IPPROTO_TCP
|
||||
#define NUTTX_SOL_UDP NUTTX_IPPROTO_UDP
|
||||
|
||||
#define NUTTX_SOL_HCI 0
|
||||
#define NUTTX_SOL_L2CAP 6
|
||||
#define NUTTX_SOL_SCO 17
|
||||
#define NUTTX_SOL_RFCOMM 18
|
||||
|
||||
#define NUTTX___SO_PROTOCOL 16
|
||||
|
||||
#define NUTTX_SHUT_RD 1
|
||||
#define NUTTX_SHUT_WR 2
|
||||
#define NUTTX_SHUT_RDWR 3
|
||||
|
||||
#define NUTTX_SCM_RIGHTS 0x01
|
||||
#define NUTTX_SCM_CREDENTIALS 0x02
|
||||
#define NUTTX_SCM_SECURITY 0x03
|
||||
|
||||
#define NUTTX_IP_MULTICAST_IF (NUTTX__SO_PROTOCOL + 1)
|
||||
#define NUTTX_IP_MULTICAST_TTL (NUTTX__SO_PROTOCOL + 2)
|
||||
#define NUTTX_IP_MULTICAST_LOOP (NUTTX__SO_PROTOCOL + 3)
|
||||
#define NUTTX_IP_ADD_MEMBERSHIP (NUTTX__SO_PROTOCOL + 4)
|
||||
#define NUTTX_IP_DROP_MEMBERSHIP (NUTTX__SO_PROTOCOL + 5)
|
||||
#define NUTTX_IP_UNBLOCK_SOURCE (NUTTX__SO_PROTOCOL + 6)
|
||||
#define NUTTX_IP_BLOCK_SOURCE (NUTTX__SO_PROTOCOL + 7)
|
||||
#define NUTTX_IP_ADD_SOURCE_MEMBERSHIP (NUTTX__SO_PROTOCOL + 8)
|
||||
#define NUTTX_IP_DROP_SOURCE_MEMBERSHIP (NUTTX__SO_PROTOCOL + 9)
|
||||
#define NUTTX_IP_MSFILTER (NUTTX__SO_PROTOCOL + 10)
|
||||
#define NUTTX_IP_MULTICAST_ALL (NUTTX__SO_PROTOCOL + 11)
|
||||
#define NUTTX_IP_PKTINFO (NUTTX__SO_PROTOCOL + 12)
|
||||
#define NUTTX_IP_TOS (NUTTX__SO_PROTOCOL + 13)
|
||||
#define NUTTX_IP_TTL (NUTTX__SO_PROTOCOL + 14)
|
||||
|
||||
/* Event message flags */
|
||||
|
||||
#define NUTTX_USRSOCK_EVENT_ABORT (1 << 1)
|
||||
#define NUTTX_USRSOCK_EVENT_SENDTO_READY (1 << 2)
|
||||
#define NUTTX_USRSOCK_EVENT_RECVFROM_AVAIL (1 << 3)
|
||||
#define NUTTX_USRSOCK_EVENT_REMOTE_CLOSED (1 << 4)
|
||||
|
||||
/****************************************************************************
|
||||
* Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
typedef unsigned int nuttx_socklen_t;
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
struct nuttx_sockaddr_storage
|
||||
{
|
||||
sa_family_t ss_family; /* Address family */
|
||||
char ss_data[26]; /* 26-bytes of address data */
|
||||
};
|
||||
#else
|
||||
struct nuttx_sockaddr_storage
|
||||
{
|
||||
sa_family_t ss_family; /* Address family */
|
||||
char ss_data[14]; /* 14-bytes of address data */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct nuttx_sockaddr
|
||||
{
|
||||
sa_family_t sa_family; /* Address family: See AF_* definitions */
|
||||
char sa_data[14]; /* 14-bytes data (actually variable length) */
|
||||
};
|
||||
|
||||
struct nuttx_linger
|
||||
{
|
||||
int l_onoff; /* Indicates whether linger option is enabled. */
|
||||
int l_linger; /* Linger time, in seconds. */
|
||||
};
|
||||
|
||||
struct nuttx_iovec
|
||||
{
|
||||
void *iov_base; /* Base address of I/O memory region */
|
||||
size_t iov_len; /* Size of the memory pointed to by iov_base */
|
||||
};
|
||||
|
||||
struct nuttx_msghdr
|
||||
{
|
||||
void *msg_name; /* Socket name */
|
||||
socklen_t msg_namelen; /* Length of name */
|
||||
struct nuttx_iovec *msg_iov; /* Data blocks */
|
||||
unsigned long msg_iovlen; /* Number of blocks */
|
||||
void *msg_control; /* Per protocol magic
|
||||
* (eg BSD file descriptor passing)
|
||||
*/
|
||||
unsigned long msg_controllen; /* Length of cmsg list */
|
||||
unsigned int msg_flags;
|
||||
};
|
||||
|
||||
struct nuttx_cmsghdr
|
||||
{
|
||||
unsigned long cmsg_len; /* Data byte count, including hdr */
|
||||
int cmsg_level; /* Originating protocol */
|
||||
int cmsg_type; /* Protocol-specific type */
|
||||
};
|
||||
|
||||
#endif /* __SIM__ */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __SIM__
|
||||
int usrsock_event_callback(int16_t usockid, uint16_t events);
|
||||
|
||||
int usrsock_host_socket(int domain, int type, int protocol);
|
||||
int usrsock_host_close(int sockfd);
|
||||
int usrsock_host_connect(int sockfd, const struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t addrlen);
|
||||
ssize_t usrsock_host_sendto(int sockfd, const void *buf, size_t len,
|
||||
int flags,
|
||||
const struct nuttx_sockaddr *dest_addr,
|
||||
nuttx_socklen_t addrlen);
|
||||
ssize_t usrsock_host_recvfrom(int sockfd, void *buf, size_t len, int flags,
|
||||
struct nuttx_sockaddr *src_addr,
|
||||
nuttx_socklen_t *addrlen);
|
||||
int usrsock_host_setsockopt(int sockfd, int level, int optname,
|
||||
const void *optval, nuttx_socklen_t optlen);
|
||||
int usrsock_host_getsockopt(int sockfd, int level, int optname,
|
||||
void *optval, nuttx_socklen_t *optlen);
|
||||
int usrsock_host_getsockname(int sockfd,
|
||||
struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t *addrlen);
|
||||
int usrsock_host_getpeername(int sockfd,
|
||||
struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t *addrlen);
|
||||
int usrsock_host_bind(int sockfd, const struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t addrlen);
|
||||
int usrsock_host_listen(int sockfd, int backlog);
|
||||
int usrsock_host_accept(int sockfd, struct nuttx_sockaddr *addr,
|
||||
nuttx_socklen_t *addrlen);
|
||||
int usrsock_host_ioctl(int fd, unsigned long request, ...);
|
||||
#else
|
||||
int usrsock_host_socket(int domain, int type, int protocol);
|
||||
int usrsock_host_close(int sockfd);
|
||||
int usrsock_host_connect(int sockfd, const struct sockaddr *addr,
|
||||
socklen_t addrlen);
|
||||
ssize_t usrsock_host_sendto(int sockfd, const void *buf, size_t len,
|
||||
int flags,
|
||||
const struct sockaddr *dest_addr,
|
||||
socklen_t addrlen);
|
||||
ssize_t usrsock_host_recvfrom(int sockfd, void *buf, size_t len, int flags,
|
||||
struct sockaddr *src_addr,
|
||||
socklen_t *addrlen);
|
||||
int usrsock_host_setsockopt(int sockfd, int level, int optname,
|
||||
const void *optval, socklen_t optlen);
|
||||
int usrsock_host_getsockopt(int sockfd, int level, int optname,
|
||||
void *optval, socklen_t *optlen);
|
||||
int usrsock_host_getsockname(int sockfd, struct sockaddr *addr,
|
||||
socklen_t *addrlen);
|
||||
int usrsock_host_getpeername(int sockfd, struct sockaddr *addr,
|
||||
socklen_t *addrlen);
|
||||
int usrsock_host_bind(int sockfd, const struct sockaddr *addr,
|
||||
socklen_t addrlen);
|
||||
int usrsock_host_listen(int sockfd, int backlog);
|
||||
int usrsock_host_accept(int sockfd, struct sockaddr *addr,
|
||||
socklen_t *addrlen);
|
||||
int usrsock_host_ioctl(int fd, unsigned long request, ...);
|
||||
|
||||
void usrsock_host_loop(void);
|
||||
#endif /* __SIM__ */
|
||||
|
||||
#endif /* __ARCH_SIM_SRC_SIM_UP_USRSOCK_HOST_H */
|
Loading…
Reference in New Issue
Block a user