mirror of
https://github.com/libretro/RetroArch
synced 2024-12-28 09:29:16 +00:00
WiiU: fix network information
== DETAILS For local netplay, it's useful to have your IP address easily available. This commit makes the Information > Network Information menu display the Wii U's IP address. Change summary: - Fix the logging init to be reentrant to avoid socket consumption - Add implementation of POSIX `getifaddrs()` and `freeifaddrs()` to `missing_libc_functions.c` - Remove compiler directives protecting the code paths that call `getifaddrs()` from being used in Wii U builds == TESTING Have tested locally, successfully get IP address information in the Information > Network Information. I think this may also fix NAT traversal. Will need to be tested.
This commit is contained in:
parent
e9752fb546
commit
c5f9fc0a34
@ -137,8 +137,6 @@ endif
|
||||
WANT_IOSUHAX = 1
|
||||
|
||||
include Makefile.common
|
||||
BLACKLIST := $(LIBRETRO_COMM_DIR)/net/net_ifinfo.o
|
||||
OBJ := $(filter-out $(BLACKLIST),$(OBJ))
|
||||
|
||||
OBJ += gfx/drivers/gx2_gfx.o
|
||||
OBJ += gfx/drivers_font/wiiu_font.o
|
||||
|
@ -530,6 +530,9 @@ static void wiiu_log_init(int port)
|
||||
{
|
||||
wiiu_log_lock = 0;
|
||||
|
||||
if(wiiu_log_socket >= 0)
|
||||
return;
|
||||
|
||||
if(broadcast_init(port) < 0)
|
||||
return;
|
||||
|
||||
|
@ -184,7 +184,7 @@ static bool natt_open_port(struct natt_status *status,
|
||||
bool natt_open_port_any(struct natt_status *status,
|
||||
uint16_t port, enum socket_protocol proto)
|
||||
{
|
||||
#if !defined(HAVE_SOCKET_LEGACY) && !defined(WIIU) && !defined(SWITCH)
|
||||
#if !defined(HAVE_SOCKET_LEGACY) && !defined(SWITCH)
|
||||
size_t i;
|
||||
char port_str[6];
|
||||
struct net_ifinfo list;
|
||||
|
@ -97,7 +97,7 @@ static enum msg_hash_enums new_type = MSG_UNKNOWN;
|
||||
* function pointer callback functions that don't necessarily
|
||||
* call each other. */
|
||||
|
||||
#if !defined(HAVE_SOCKET_LEGACY) && !defined(WIIU) && !defined(SWITCH)
|
||||
#if !defined(HAVE_SOCKET_LEGACY) && !defined(SWITCH)
|
||||
#include <net/net_ifinfo.h>
|
||||
|
||||
static int menu_displaylist_parse_network_info(menu_displaylist_info_t *info)
|
||||
@ -4834,7 +4834,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
|
||||
break;
|
||||
case DISPLAYLIST_NETWORK_INFO:
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
||||
#if defined(HAVE_NETWORKING) && !defined(HAVE_SOCKET_LEGACY) && !defined(WIIU) && !defined(SWITCH)
|
||||
#if defined(HAVE_NETWORKING) && !defined(HAVE_SOCKET_LEGACY) && !defined(SWITCH)
|
||||
count = menu_displaylist_parse_network_info(info);
|
||||
#endif
|
||||
|
||||
|
@ -6,6 +6,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
char *inet_ntoa(struct in_addr in);
|
||||
const char *inet_ntop(int af, const void *cp, char *buf, socklen_t len);
|
||||
|
18
wiiu/include/ifaddrs.h
Normal file
18
wiiu/include/ifaddrs.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _IFADDRS_H_
|
||||
#define _IFADDRS_H_
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct ifaddrs {
|
||||
struct ifaddrs *ifa_next;
|
||||
char *ifa_name;
|
||||
unsigned int ifa_flags;
|
||||
struct sockaddr *ifa_addr;
|
||||
struct sockaddr *ifa_netmask;
|
||||
struct sockaddr *ifa_dstaddr;
|
||||
void *ifa_data;
|
||||
};
|
||||
|
||||
int getifaddrs(struct ifaddrs **ifap);
|
||||
void freeifaddrs(struct ifaddrs *ifp);
|
||||
#endif // _IFADDRS_H_
|
@ -5,10 +5,18 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <wiiu/os.h>
|
||||
#include <wiiu/ac.h>
|
||||
#include <wiiu/types.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/reent.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <verbosity.h>
|
||||
|
||||
/* This is usually in libogc; we can't use that on wiiu */
|
||||
int usleep(useconds_t microseconds) {
|
||||
@ -112,3 +120,124 @@ int clock_gettime(clockid_t clk_id, struct timespec* tp) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of getifaddrs() and freeifaddrs() for WiiU.
|
||||
*/
|
||||
|
||||
// the Wii U doesn't define an interface name, so we'll use something generic.
|
||||
static const char *wiiu_iface_name = "eth0";
|
||||
|
||||
/**
|
||||
* Allocate and zeroize the hunk of memory for the ifaddrs struct and its contents; the struct will be filled
|
||||
* out later.
|
||||
*
|
||||
* returns NULL if any of the memory allocations fail.
|
||||
*/
|
||||
static struct ifaddrs *buildEmptyIfa() {
|
||||
struct ifaddrs *result = (struct ifaddrs *)malloc(sizeof(struct ifaddrs));
|
||||
if(result != NULL) {
|
||||
memset(result, 0, sizeof(struct ifaddrs));
|
||||
result->ifa_name = strdup(wiiu_iface_name);
|
||||
result->ifa_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
|
||||
result->ifa_netmask = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
|
||||
result->ifa_dstaddr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
|
||||
|
||||
if(!result->ifa_name || !result->ifa_addr || !result->ifa_netmask || !result->ifa_dstaddr)
|
||||
goto error;
|
||||
|
||||
memset(result->ifa_addr, 0, sizeof(struct sockaddr_in));
|
||||
result->ifa_addr->sa_family = AF_INET;
|
||||
memset(result->ifa_netmask, 0, sizeof(struct sockaddr_in));
|
||||
result->ifa_netmask->sa_family = AF_INET;
|
||||
memset(result->ifa_dstaddr, 0, sizeof(struct sockaddr_in));
|
||||
result->ifa_dstaddr->sa_family = AF_INET;
|
||||
}
|
||||
|
||||
return result;
|
||||
error:
|
||||
freeifaddrs(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int getAssignedAddress(struct sockaddr_in *sa) {
|
||||
if(sa == NULL)
|
||||
return -1;
|
||||
ACIpAddress addr;
|
||||
int result = ACGetAssignedAddress(&addr);
|
||||
if(result == 0)
|
||||
sa->sin_addr.s_addr = addr;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int getAssignedSubnet(struct sockaddr_in *sa) {
|
||||
if(sa == NULL)
|
||||
return -1;
|
||||
|
||||
ACIpAddress mask;
|
||||
int result = ACGetAssignedSubnet(&mask);
|
||||
if(result == 0)
|
||||
sa->sin_addr.s_addr = mask;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int getBroadcastAddress(struct sockaddr_in *sa, struct sockaddr_in *addr, struct sockaddr_in *mask) {
|
||||
if(!sa || !addr || !mask)
|
||||
return -1;
|
||||
|
||||
sa->sin_addr.s_addr = addr->sin_addr.s_addr | (~mask->sin_addr.s_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ifaddrs *getWiiUInterfaceAddressData(void) {
|
||||
struct ifaddrs *result = buildEmptyIfa();
|
||||
|
||||
if(result != NULL) {
|
||||
if(getAssignedAddress((struct sockaddr_in *)result->ifa_addr) < 0 ||
|
||||
getAssignedSubnet((struct sockaddr_in *)result->ifa_netmask) < 0 ||
|
||||
getBroadcastAddress((struct sockaddr_in *)result->ifa_dstaddr,
|
||||
(struct sockaddr_in *)result->ifa_addr,
|
||||
(struct sockaddr_in *)result->ifa_netmask) < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
error:
|
||||
freeifaddrs(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int getifaddrs(struct ifaddrs **ifap) {
|
||||
if(ifap == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*ifap = getWiiUInterfaceAddressData();
|
||||
|
||||
return (*ifap == NULL) ? -1 : 0;
|
||||
}
|
||||
|
||||
void freeifaddrs(struct ifaddrs *ifp) {
|
||||
if(ifp != NULL) {
|
||||
if(ifp->ifa_name) {
|
||||
free(ifp->ifa_name);
|
||||
ifp->ifa_name = NULL;
|
||||
}
|
||||
if(ifp->ifa_addr) {
|
||||
free(ifp->ifa_addr);
|
||||
ifp->ifa_addr = NULL;
|
||||
}
|
||||
if(ifp->ifa_netmask) {
|
||||
free(ifp->ifa_netmask);
|
||||
ifp->ifa_netmask = NULL;
|
||||
}
|
||||
if(ifp->ifa_dstaddr) {
|
||||
free(ifp->ifa_dstaddr);
|
||||
ifp->ifa_dstaddr = NULL;
|
||||
}
|
||||
free(ifp);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user