Implement UDP broadcast network logging on Wii U

== DETAILS

The broadcast address is a standard part of TCP/IP that is used to
send messages to everyone on the subnet. This patch updates the
logging code to do the following:

1. Derive the broadcast address from the Wii U's own IP address
   and subnet mask. These can all be obtained at runtime, which
   means we can...
2. Remove the PC_DEVELOPMENT_IP_ADDRESS define from Wii U's
   Makefile, because compiling in an IP is no longer needed.
3. Rewrite the net_listen script to listen for broadcast packets
   and print them out with timestamps.

Since it's using the broadcast address, the only requirement is
that the PC be on the same network subnet as the Wii U.

Because of the low overhead of UDP, I've made logging on by
default. This will make it a ton easier to get useful bug
reports from users.
This commit is contained in:
gblues 2018-05-06 14:31:17 -07:00
parent ac0b2799c5
commit 23f0a85446
7 changed files with 124 additions and 26 deletions

View File

@ -10,7 +10,6 @@ WIIU_HID = 1
HAVE_RUNAHEAD = 1
WIIU_LOG_RPX = 0
BUILD_DIR = objs/wiiu
PC_DEVELOPMENT_IP_ADDRESS ?=
PC_DEVELOPMENT_TCP_PORT ?=
ifeq ($(SALAMANDER_BUILD),1)
@ -163,10 +162,6 @@ DEFINES += -DWIIU -DMSB_FIRST -D__WUT__
DEFINES += -DHAVE_MAIN
DEFINES += -DRARCH_CONSOLE
ifneq ($(PC_DEVELOPMENT_IP_ADDRESS),)
DEFINES += -DPC_DEVELOPMENT_IP_ADDRESS='"$(PC_DEVELOPMENT_IP_ADDRESS)"'
endif
ifneq ($(PC_DEVELOPMENT_TCP_PORT),)
DEFINES += -DPC_DEVELOPMENT_TCP_PORT=$(PC_DEVELOPMENT_TCP_PORT)
endif

View File

@ -137,7 +137,6 @@ buildCore()
rm -f libretro_wiiu.a
cp $distDir/$core libretro_wiiu.a
make -f Makefile.wiiu \
PC_DEVELOPMENT_IP_ADDRESS=$PC_DEVELOPMENT_IP_ADDRESS \
PC_DEVELOPMENT_TCP_PORT=$PC_DEVELOPMENT_TCP_PORT \
-j3 || exit 1

View File

@ -23,6 +23,7 @@
#include <arpa/inet.h>
#include <wiiu/types.h>
#include <wiiu/ac.h>
#include <file/file_path.h>
#ifndef IS_SALAMANDER
@ -314,9 +315,10 @@ static void main_loop(void);
static void main_teardown(void);
static void init_network(void);
static void deinit_network(void);
static void init_logging(void);
static void deinit_logging(void);
static void wiiu_log_init(const char *ipString, int port);
static void wiiu_log_init(int port);
static void wiiu_log_deinit(void);
static ssize_t wiiu_log_write(struct _reent *r, void *fd, const char *ptr, size_t len);
static void init_pad_libraries(void);
@ -324,10 +326,14 @@ static void deinit_pad_libraries(void);
static void SaveCallback(void);
static bool swap_is_pending(void *start_time);
static struct sockaddr_in broadcast;
static int wiiu_log_socket = -1;
static volatile int wiiu_log_lock = 0;
#if defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT)
#if !defined(PC_DEVELOPMENT_TCP_PORT)
#define PC_DEVELOPMENT_TCP_PORT 4405
#endif
static devoptab_t dotab_stdout =
{
"stdout_net", /* device name */
@ -337,7 +343,6 @@ static devoptab_t dotab_stdout =
wiiu_log_write, /* device write */
NULL, /* ... */
};
#endif /* defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT) */
int main(int argc, char **argv)
{
@ -400,6 +405,7 @@ static void main_teardown(void)
deinit_pad_libraries();
ProcUIShutdown();
deinit_logging();
deinit_network();
}
static void main_loop(void)
@ -457,6 +463,8 @@ static bool swap_is_pending(void *start_time)
static void init_network(void)
{
ACInitialize();
ACConnect();
#ifdef IS_SALAMANDER
socket_lib_init();
#else
@ -464,13 +472,36 @@ static void init_network(void)
#endif /* IS_SALAMANDER */
}
static void deinit_network(void)
{
ACClose();
ACFinalize();
}
int getBroadcastAddress(ACIpAddress *broadcast)
{
ACIpAddress myIp, mySubnet;
ACResult result;
if(broadcast == NULL)
return -1;
result = ACGetAssignedAddress(&myIp);
if(result < 0)
return -1;
result = ACGetAssignedSubnet(&mySubnet);
if(result < 0)
return -1;
*broadcast = myIp | (~mySubnet);
return 0;
}
static void init_logging(void)
{
#if defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT)
wiiu_log_init(PC_DEVELOPMENT_IP_ADDRESS, PC_DEVELOPMENT_TCP_PORT);
wiiu_log_init(PC_DEVELOPMENT_TCP_PORT);
devoptab_list[STD_OUT] = &dotab_stdout;
devoptab_list[STD_ERR] = &dotab_stdout;
#endif /* defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT) */
}
static void deinit_logging(void)
@ -478,16 +509,31 @@ static void deinit_logging(void)
fflush(stdout);
fflush(stderr);
#if defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT)
wiiu_log_deinit();
#endif /* defined(PC_DEVELOPMENT_IP_ADDRESS) && defined(PC_DEVELOPMENT_TCP_PORT) */
}
static int broadcast_init(int port)
{
ACIpAddress broadcast_ip;
if(getBroadcastAddress(&broadcast_ip) < 0)
return -1;
static void wiiu_log_init(const char *ipString, int port)
memset(&broadcast, 0, sizeof(broadcast));
broadcast.sin_family = AF_INET;
broadcast.sin_port = htons(port);
broadcast.sin_addr.s_addr = htonl(broadcast_ip);
return 0;
}
static void wiiu_log_init(int port)
{
wiiu_log_lock = 0;
wiiu_log_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(broadcast_init(port) < 0)
return;
wiiu_log_socket = socket(AF_INET, SOCK_DGRAM, 0);
if(wiiu_log_socket < 0)
return;
@ -495,15 +541,14 @@ static void wiiu_log_init(const char *ipString, int port)
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = port;
inet_aton(ipString, &connect_addr.sin_addr);
connect_addr.sin_port = 0;
connect_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(connect(wiiu_log_socket,
(struct sockaddr *)&connect_addr,
sizeof(connect_addr)) < 0)
if( bind(wiiu_log_socket, (struct sockaddr *)&connect_addr, sizeof(connect_addr)) < 0)
{
socketclose(wiiu_log_socket);
wiiu_log_socket = -1;
return;
}
}
@ -541,7 +586,7 @@ void net_print(const char *str)
void net_print_exp(const char *str)
{
send(wiiu_log_socket, str, strlen(str), 0);
sendto(wiiu_log_socket, str, strlen(str), 0, (struct sockaddr *)&broadcast, sizeof(broadcast));
}
static ssize_t wiiu_log_write(struct _reent *r, void *fd, const char *ptr, size_t len)
@ -559,8 +604,8 @@ static ssize_t wiiu_log_write(struct _reent *r, void *fd, const char *ptr, size_
while(remaining > 0)
{
int block = remaining < 1400 ? remaining : 1400;
ret = send(wiiu_log_socket, ptr, block, 0);
int block = remaining < 1472 ? remaining : 1472;
ret = sendto(wiiu_log_socket, ptr, block, 0, (struct sockaddr *)&broadcast, sizeof(broadcast));
if(ret < 0)
break;

View File

@ -5,6 +5,5 @@
# port number.
#
PC_DEVELOPMENT_IP_ADDRESS=
PC_DEVELOPMENT_TCP_PORT=4405
WIIU_IP_ADDRESS=

24
wiiu/include/wiiu/ac.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
/**
* These functions manage the Wii U's AutoConnect library--basically
* connecting to the LAN/Internet via the network profile set up in
* System Preferences.
*/
typedef int ACResult;
enum {
AC_FAILED = -1,
AC_OK = 0,
AC_BUSY = 1
};
typedef unsigned long ACIpAddress;
ACResult ACInitialize(void);
void ACFinalize(void);
ACResult ACConnect(void);
ACResult ACClose(void);
ACResult ACGetAssignedAddress(ACIpAddress *addr);
ACResult ACGetAssignedSubnet(ACIpAddress *addr);

View File

@ -8,6 +8,10 @@
script_dir=$(dirname $(readlink -f $0))
IP=$(which ip 2>/dev/null | grep '^/')
IFCONFIG=$(which ifconfig 2>/dev/null | grep '^/')
TS=$(which ts 2>/dev/null | grep '^/')
# Using wiiu-devel.properties ensure your make file and this listen script
# stay in sync with each other.
#
@ -23,13 +27,35 @@ fi
exit_listen_loop=0
getBroadcastIp()
{
if [ ! -z "$IP" ]; then
$IP addr show | grep 'inet' |grep 'brd' | awk '{print $4}'
elif [ ! -z "$IFCONFIG" ]; then
$IFCONFIG | grep 'broadcast' | awk '{print $6}'
else
echo "255.255.255.255"
fi
}
#
# This prevents a tug-of-war between bash and netcat as to who gets the
# CTRL+C code.
#
trap 'exit_listen_loop=1' SIGINT
if [ -z "$TS" ]; then
echo "[WARN] 'ts' not found. Install the moreutils package to get timestamps."
fi
broadcast=$(getBroadcastIp)
echo "Listening for UDP packets on broadcast IP: $broadcast"
while [ $exit_listen_loop -eq 0 ]; do
echo ========= `date` =========
netcat -p $PC_DEVELOPMENT_TCP_PORT -l
if [ -z "$TS" ]; then
netcat -kluw 0 $broadcast $PC_DEVELOPMENT_TCP_PORT
else
netcat -kluw 0 $broadcast $PC_DEVELOPMENT_TCP_PORT |ts '[%Y-%m-%d %H:%M:%.S]'
fi
done

View File

@ -203,6 +203,16 @@ IMPORT(GX2GetSwapStatus);
IMPORT_END();
/* nn_ac */
IMPORT_BEGIN(nn_ac);
IMPORT(ACInitialize);
IMPORT(ACFinalize);
IMPORT(ACConnect);
IMPORT(ACClose);
IMPORT(ACGetAssignedAddress);
IMPORT(ACGetAssignedSubnet);
IMPORT_END();
/* proc_ui */
IMPORT_BEGIN(proc_ui);