Merge pull request #6737 from gblues/master

Implement UDP broadcast network logging on Wii U
This commit is contained in:
Twinaphex 2018-05-08 01:47:04 +02:00 committed by GitHub
commit a9e7bd9ee1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 133 additions and 30 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,9 +586,14 @@ 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));
}
/* RFC 791 specifies that any IP host must be able to receive a datagram of 576 bytes.
* Since we're generally never logging more than a line or two's worth of data (~100 bytes)
* this is a reasonable size for our use. */
#define DGRAM_SIZE 576
static ssize_t wiiu_log_write(struct _reent *r, void *fd, const char *ptr, size_t len)
{
if( wiiu_log_socket < 0)
@ -554,19 +604,19 @@ static ssize_t wiiu_log_write(struct _reent *r, void *fd, const char *ptr, size_
wiiu_log_lock = 1;
int ret;
int sent;
int remaining = len;
while(remaining > 0)
{
int block = remaining < 1400 ? remaining : 1400;
ret = send(wiiu_log_socket, ptr, block, 0);
int block = remaining < DGRAM_SIZE ? remaining : DGRAM_SIZE;
sent = sendto(wiiu_log_socket, ptr, block, 0, (struct sockaddr *)&broadcast, sizeof(broadcast));
if(ret < 0)
if(sent < 0)
break;
remaining -= ret;
ptr += ret;
remaining -= sent;
ptr += sent;
}
wiiu_log_lock = 0;

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);