Skip to content

Commit

Permalink
drivers: wifi: eswifi: Rework offloading mechanism
Browse files Browse the repository at this point in the history
Switch to `NET_SOCKET_REGISTER` mechanism over the offloaded API
registration.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
  • Loading branch information
rlubos authored and nashif committed Jan 31, 2020
1 parent e434725 commit aa17850
Showing 1 changed file with 178 additions and 23 deletions.
201 changes: 178 additions & 23 deletions drivers/wifi/eswifi/eswifi_socket_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,22 @@ LOG_MODULE_REGISTER(wifi_eswifi, CONFIG_WIFI_LOG_LEVEL);

#include <net/socket_offload.h>
#include <net/tls_credentials.h>

#include "sockets_internal.h"
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
#include "tls_internal.h"
#endif
#include "eswifi.h"
#include <net/net_pkt.h>

/* Increment by 1 to make sure we do not store the value of 0, which has
* a special meaning in the fdtable subsys.
*/
#define SD_TO_OBJ(sd) ((void *)(sd + 1))
#define OBJ_TO_SD(obj) (((int)obj) - 1)

static struct eswifi_dev *eswifi;
static const struct socket_op_vtable eswifi_socket_fd_op_vtable;

static void __process_received(struct net_context *context,
struct net_pkt *pkt,
Expand All @@ -39,9 +48,10 @@ static void __process_received(struct net_context *context,
eswifi_unlock(eswifi);
}

static int eswifi_socket_connect(int sock, const struct sockaddr *addr,
static int eswifi_socket_connect(void *obj, const struct sockaddr *addr,
socklen_t addrlen)
{
int sock = OBJ_TO_SD(obj);
struct eswifi_off_socket *socket;
int ret;

Expand Down Expand Up @@ -77,9 +87,10 @@ static int eswifi_socket_connect(int sock, const struct sockaddr *addr,
return ret;
}

static int eswifi_socket_accept(int sock, struct sockaddr *addr,
socklen_t *addrlen)
static int __eswifi_socket_accept(void *obj, struct sockaddr *addr,
socklen_t *addrlen)
{
int sock = OBJ_TO_SD(obj);
struct eswifi_off_socket *socket;
int ret;

Expand All @@ -97,6 +108,29 @@ static int eswifi_socket_accept(int sock, struct sockaddr *addr,
return ret;
}

static int eswifi_socket_accept(void *obj, struct sockaddr *addr,
socklen_t *addrlen)
{
int fd = z_reserve_fd();
int sock;

if (fd < 0) {
return -1;
}

sock = __eswifi_socket_accept(obj, addr, addrlen);
if (sock < 0) {
z_free_fd(fd);
return -1;
}

z_finalize_fd(fd, SD_TO_OBJ(sock),
(const struct fd_op_vtable *)
&eswifi_socket_fd_op_vtable);

return fd;
}

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
static int map_credentials(int sd, const void *optval, socklen_t optlen)
{
Expand Down Expand Up @@ -169,9 +203,10 @@ static int map_credentials(int sd, const void *optval, socklen_t optlen)
}
#endif

static int eswifi_socket_setsockopt(int sd, int level, int optname,
static int eswifi_socket_setsockopt(void *obj, int level, int optname,
const void *optval, socklen_t optlen)
{
int sd = OBJ_TO_SD(obj);
int ret;

if (IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS) && level == SOL_TLS) {
Expand All @@ -193,9 +228,10 @@ static int eswifi_socket_setsockopt(int sd, int level, int optname,
return ret;
}

static ssize_t eswifi_socket_send(int sock, const void *buf, size_t len,
static ssize_t eswifi_socket_send(void *obj, const void *buf, size_t len,
int flags)
{
int sock = OBJ_TO_SD(obj);
struct eswifi_off_socket *socket;
int ret;
int offset;
Expand Down Expand Up @@ -235,9 +271,22 @@ static ssize_t eswifi_socket_send(int sock, const void *buf, size_t len,
return ret;
}

static ssize_t eswifi_socket_recv(int sock, void *buf, size_t max_len,
static ssize_t eswifi_socket_sendto(void *obj, const void *buf, size_t len,
int flags, const struct sockaddr *to,
socklen_t tolen)
{
if (to != NULL) {
errno = EOPNOTSUPP;
return -1;
}

return eswifi_socket_send(obj, buf, len, flags);
}

static ssize_t eswifi_socket_recv(void *obj, void *buf, size_t max_len,
int flags)
{
int sock = OBJ_TO_SD(obj);
struct eswifi_off_socket *socket;
int len = 0, ret = 0;
struct net_pkt *pkt;
Expand Down Expand Up @@ -287,6 +336,18 @@ static ssize_t eswifi_socket_recv(int sock, void *buf, size_t max_len,
return len;
}

static ssize_t eswifi_socket_recvfrom(void *obj, void *buf, size_t len,
int flags, struct sockaddr *from,
socklen_t *fromlen)
{
if (fromlen != NULL) {
errno = EOPNOTSUPP;
return -1;
}

return eswifi_socket_recv(obj, buf, len, flags);
}

static int eswifi_socket_close(int sock)
{
struct eswifi_off_socket *socket;
Expand Down Expand Up @@ -355,27 +416,45 @@ static int eswifi_socket_poll(struct pollfd *fds, int nfds, int msecs)
{
struct eswifi_off_socket *socket;
int sock, ret;
void *obj;

if (nfds > 1 ||
fds[0].fd > ESWIFI_OFFLOAD_MAX_SOCKETS) {
return -EINVAL;
if (nfds > 1) {
errno = EINVAL;
return -1;
}

obj = z_get_fd_obj(fds[0].fd,
(const struct fd_op_vtable *)
&eswifi_socket_fd_op_vtable,
0);
if (obj != NULL) {
sock = OBJ_TO_SD(obj);
} else {
errno = EINVAL;
return -1;
}

if (sock > ESWIFI_OFFLOAD_MAX_SOCKETS) {
errno = EINVAL;
return -1;
}

eswifi_lock(eswifi);
sock = fds[0].fd;
socket = &eswifi->socket[sock];
eswifi_unlock(eswifi);
if (socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
return -EINVAL;
errno = EINVAL;
return -1;
}

ret = k_sem_take(&socket->read_sem, msecs);
return ret;
}

static int ewifi_socket_bind(int sock, const struct sockaddr *addr,
socklen_t addrlen)
static int eswifi_socket_bind(void *obj, const struct sockaddr *addr,
socklen_t addrlen)
{
int sock = OBJ_TO_SD(obj);
struct eswifi_off_socket *socket;
int ret;

Expand All @@ -392,22 +471,98 @@ static int ewifi_socket_bind(int sock, const struct sockaddr *addr,
return ret;
}

const struct socket_offload eswifi_socket_ops = {
/* POSIX Socket Functions: */
.socket = eswifi_socket_open,
.close = eswifi_socket_close,
.accept = eswifi_socket_accept,
.bind = ewifi_socket_bind,
static bool eswifi_socket_is_supported(int family, int type, int proto)
{
return true;
}

static int eswifi_socket_create(int family, int type, int proto)
{
int fd = z_reserve_fd();
int sock;

if (fd < 0) {
return -1;
}

sock = eswifi_socket_open(family, type, proto);
if (sock < 0) {
z_free_fd(fd);
return -1;
}

z_finalize_fd(fd, SD_TO_OBJ(sock),
(const struct fd_op_vtable *)
&eswifi_socket_fd_op_vtable);

return fd;
}

static int eswifi_socket_ioctl(void *obj, unsigned int request, va_list args)
{
int sd = OBJ_TO_SD(obj);

switch (request) {
/* Handle close specifically. */
case ZFD_IOCTL_CLOSE:
return eswifi_socket_close(sd);

case ZFD_IOCTL_POLL_PREPARE:
return -EXDEV;

case ZFD_IOCTL_POLL_UPDATE:
return -EOPNOTSUPP;

case ZFD_IOCTL_POLL_OFFLOAD: {
struct zsock_pollfd *fds;
int nfds;
int timeout;

fds = va_arg(args, struct zsock_pollfd *);
nfds = va_arg(args, int);
timeout = va_arg(args, int);

return eswifi_socket_poll(fds, nfds, timeout);
}

default:
errno = EINVAL;
return -1;
}
}

static ssize_t eswifi_socket_read(void *obj, void *buffer, size_t count)
{
return eswifi_socket_recvfrom(obj, buffer, count, 0, NULL, 0);
}

static ssize_t eswifi_socket_write(void *obj, const void *buffer,
size_t count)
{
return eswifi_socket_sendto(obj, buffer, count, 0, NULL, 0);
}

static const struct socket_op_vtable eswifi_socket_fd_op_vtable = {
.fd_vtable = {
.read = eswifi_socket_read,
.write = eswifi_socket_write,
.ioctl = eswifi_socket_ioctl,
},
.bind = eswifi_socket_bind,
.connect = eswifi_socket_connect,
.accept = eswifi_socket_accept,
.sendto = eswifi_socket_sendto,
.recvfrom = eswifi_socket_recvfrom,
.setsockopt = eswifi_socket_setsockopt,
.recv = eswifi_socket_recv,
.send = eswifi_socket_send,
.poll = eswifi_socket_poll,
};

#ifdef CONFIG_NET_SOCKETS_OFFLOAD
NET_SOCKET_REGISTER(eswifi, AF_UNSPEC, eswifi_socket_is_supported,
eswifi_socket_create);
#endif

int eswifi_socket_offload_init(struct eswifi_dev *leswifi)
{
eswifi = leswifi;
socket_offload_register(&eswifi_socket_ops);
return 0;
}

0 comments on commit aa17850

Please sign in to comment.