Wii: Add network socket support
Vicki Pfau vi@endrift.com
Sat, 08 Feb 2020 17:46:56 -0800
1 files changed,
77 insertions(+),
6 deletions(-)
jump to
M
include/mgba-util/socket.h
→
include/mgba-util/socket.h
@@ -20,15 +20,21 @@
#define SOCKET_FAILED(s) ((s) == INVALID_SOCKET) typedef SOCKET Socket; #else +#ifdef GEKKO +#include <network.h> +#else #include <arpa/inet.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <sys/socket.h> +#endif #include <errno.h> #include <fcntl.h> -#include <netinet/in.h> -#include <netinet/tcp.h> #include <sys/select.h> -#include <sys/socket.h> +#ifndef GEKKO #define INVALID_SOCKET (-1) +#endif #define SOCKET_FAILED(s) ((s) < 0) typedef int Socket; #endif@@ -70,6 +76,8 @@ socInit(SOCUBuffer, SOCU_BUFFERSIZE);
} #elif defined(__SWITCH__) socketInitializeDefault(); +#elif defined(GEKKO) + net_init(); #endif }@@ -82,6 +90,8 @@ free(SOCUBuffer);
SOCUBuffer = NULL; #elif defined(__SWITCH__) socketExit(); +#elif defined(GEKKO) + net_deinit(); #endif }@@ -104,6 +114,8 @@
static inline ssize_t SocketSend(Socket socket, const void* buffer, size_t size) { #ifdef _WIN32 return send(socket, (const char*) buffer, size, 0); +#elif defined(GEKKO) + return net_write(socket, buffer, size); #else return write(socket, buffer, size); #endif@@ -112,6 +124,8 @@
static inline ssize_t SocketRecv(Socket socket, void* buffer, size_t size) { #if defined(_WIN32) || defined(__SWITCH__) return recv(socket, (char*) buffer, size, 0); +#elif defined(GEKKO) + return net_read(socket, buffer, size); #else return read(socket, buffer, size); #endif@@ -120,13 +134,19 @@
static inline int SocketClose(Socket socket) { #ifdef _WIN32 return closesocket(socket) == 0; +#elif defined(GEKKO) + return net_close(socket) >= 0; #else return close(socket) >= 0; #endif } static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress) { +#ifdef GEKKO + Socket sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); +#else Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +#endif if (SOCKET_FAILED(sock)) { return sock; }@@ -142,15 +162,23 @@ bindInfo.sin_addr.s_addr = INADDR_ANY;
#else bindInfo.sin_addr.s_addr = gethostid(); #endif +#ifdef GEKKO + err = net_bind(sock, (struct sockaddr*) &bindInfo, sizeof(bindInfo)); +#else err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); +#endif } else if (bindAddress->version == IPV4) { struct sockaddr_in bindInfo; memset(&bindInfo, 0, sizeof(bindInfo)); bindInfo.sin_family = AF_INET; bindInfo.sin_port = htons(port); bindInfo.sin_addr.s_addr = htonl(bindAddress->ipv4); +#ifdef GEKKO + err = net_bind(sock, (struct sockaddr*) &bindInfo, sizeof(bindInfo)); +#else err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); -#ifndef _3DS +#endif +#if !defined(_3DS) && !defined(GEKKO) } else { struct sockaddr_in6 bindInfo; memset(&bindInfo, 0, sizeof(bindInfo));@@ -168,7 +196,11 @@ return sock;
} static inline Socket SocketConnectTCP(int port, const struct Address* destinationAddress) { +#ifdef GEKKO + Socket sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); +#else Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +#endif if (SOCKET_FAILED(sock)) { return sock; }@@ -179,15 +211,23 @@ struct sockaddr_in bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo)); bindInfo.sin_family = AF_INET; bindInfo.sin_port = htons(port); +#ifdef GEKKO + err = net_connect(sock, (struct sockaddr*) &bindInfo, sizeof(bindInfo)); +#else err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); +#endif } else if (destinationAddress->version == IPV4) { struct sockaddr_in bindInfo; memset(&bindInfo, 0, sizeof(bindInfo)); bindInfo.sin_family = AF_INET; bindInfo.sin_port = htons(port); bindInfo.sin_addr.s_addr = htonl(destinationAddress->ipv4); +#ifdef GEKKO + err = net_connect(sock, (struct sockaddr*) &bindInfo, sizeof(bindInfo)); +#else err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); -#ifndef _3DS +#endif +#if !defined(_3DS) && !defined(GEKKO) } else { struct sockaddr_in6 bindInfo; memset(&bindInfo, 0, sizeof(bindInfo));@@ -206,12 +246,23 @@ return sock;
} static inline Socket SocketListen(Socket socket, int queueLength) { +#ifdef GEKKO + return net_listen(socket, queueLength); +#else return listen(socket, queueLength); +#endif } static inline Socket SocketAccept(Socket socket, struct Address* address) { if (!address) { +#ifdef GEKKO + struct sockaddr_in addrInfo; + memset(&addrInfo, 0, sizeof(addrInfo)); + socklen_t len = sizeof(addrInfo); + return net_accept(socket, (struct sockaddr*) &addrInfo, &len); +#else return accept(socket, 0, 0); +#endif } if (address->version == IPV4) { struct sockaddr_in addrInfo;@@ -219,8 +270,12 @@ memset(&addrInfo, 0, sizeof(addrInfo));
addrInfo.sin_family = AF_INET; addrInfo.sin_addr.s_addr = address->ipv4; socklen_t len = sizeof(addrInfo); +#ifdef GEKKO + return net_accept(socket, (struct sockaddr*) &addrInfo, &len); +#else return accept(socket, (struct sockaddr*) &addrInfo, &len); -#ifndef _3DS +#endif +#if !defined(_3DS) && !defined(GEKKO) } else { struct sockaddr_in6 addrInfo; memset(&addrInfo, 0, sizeof(addrInfo));@@ -238,7 +293,11 @@ #ifdef _WIN32
u_long unblocking = !blocking; return ioctlsocket(socket, FIONBIO, &unblocking) == NO_ERROR; #else +#ifdef GEKKO + int flags = net_fcntl(socket, F_GETFL, 0); +#else int flags = fcntl(socket, F_GETFL); +#endif if (flags == -1) { return 0; }@@ -247,12 +306,20 @@ flags &= ~O_NONBLOCK;
} else { flags |= O_NONBLOCK; } +#ifdef GEKKO + return net_fcntl(socket, F_SETFL, flags) >= 0; +#else return fcntl(socket, F_SETFL, flags) >= 0; +#endif #endif } static inline int SocketSetTCPPush(Socket socket, int push) { +#ifdef GEKKO + return net_setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*) &push, sizeof(int)) >= 0; +#else return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*) &push, sizeof(int)) >= 0; +#endif } static inline int SocketPoll(size_t nSockets, Socket* reads, Socket* writes, Socket* errors, int64_t timeoutMillis) {@@ -304,7 +371,11 @@ ++maxFd;
struct timeval tv; tv.tv_sec = timeoutMillis / 1000; tv.tv_usec = (timeoutMillis % 1000) * 1000; +#ifdef GEKKO + int result = net_select(maxFd, &rset, &wset, &eset, timeoutMillis < 0 ? 0 : &tv); +#else int result = select(maxFd, &rset, &wset, &eset, timeoutMillis < 0 ? 0 : &tv); +#endif int r = 0; int w = 0; int e = 0;