From bb7a96e9a875aff15b38f3a8745e4a4bfd54bbdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Wed, 30 Nov 2016 00:18:27 +0100 Subject: [PATCH 01/32] Async Wi-Fi scan --- Makefile.common | 3 +- menu/menu_displaylist.c | 36 +++++++++---- retroarch.c | 4 ++ runloop.h | 3 ++ tasks/task_wifi.c | 116 ++++++++++++++++++++++++++++++++++++++++ tasks/tasks_internal.h | 3 ++ 6 files changed, 153 insertions(+), 12 deletions(-) create mode 100644 tasks/task_wifi.c diff --git a/Makefile.common b/Makefile.common index f3cfaf753a..a3fe4bd212 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1087,7 +1087,8 @@ ifeq ($(HAVE_NETWORKING), 1) $(LIBRETRO_COMM_DIR)/net/net_http.o \ $(LIBRETRO_COMM_DIR)/net/net_socket.o \ network/net_http_special.o \ - tasks/task_http.o + tasks/task_http.o \ + tasks/task_wifi.o ifneq ($(HAVE_SOCKET_LEGACY),1) OBJ += $(LIBRETRO_COMM_DIR)/net/net_ifinfo.o diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 2a3868681f..a5415d1af8 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -69,7 +69,7 @@ #include "../list_special.h" #include "../performance_counters.h" #include "../core_info.h" -#include "../wifi/wifi_driver.h" +#include "../tasks/tasks_internal.h" #ifdef HAVE_NETWORKING static void print_buf_lines(file_list_t *list, char *buf, @@ -4893,19 +4893,33 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) 0, 0, 0); else { - unsigned i; - struct string_list *ssid_list = string_list_new(); - driver_wifi_scan(); - driver_wifi_get_ssids(ssid_list); + global_t *global = global_get_ptr(); - for (i = 0; i < ssid_list->size; i++) + if (!global) + break; + + if (global->ssid_list->size == 0) { - const char *ssid = ssid_list->elems[i].data; + task_push_wifi_scan(); + menu_entries_append_enum(info->list, - ssid, - msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_WIFI), - MENU_ENUM_LABEL_CONNECT_WIFI, - MENU_WIFI, 0, 0); + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); + } + else + { + unsigned i; + for (i = 0; i < global->ssid_list->size; i++) + { + const char *ssid = global->ssid_list->elems[i].data; + menu_entries_append_enum(info->list, + ssid, + msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_WIFI), + MENU_ENUM_LABEL_CONNECT_WIFI, + MENU_WIFI, 0, 0); + } } } diff --git a/retroarch.c b/retroarch.c index bb375b4c0b..8205093eaf 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1011,6 +1011,10 @@ bool retroarch_main_init(int argc, char *argv[]) { bool init_failed = false; + global_t *global = global_get_ptr(); + if (global) + global->ssid_list = string_list_new(); + retroarch_init_state(); if (setjmp(error_sjlj_context) > 0) diff --git a/runloop.h b/runloop.h index 35fada6eb1..0e45e50252 100644 --- a/runloop.h +++ b/runloop.h @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include "config.h" @@ -191,6 +192,8 @@ typedef struct global bool flickerfilter_enable; bool softfilter_enable; } console; + + struct string_list *ssid_list; } global_t; typedef struct runloop_ctx_msg_info diff --git a/tasks/task_wifi.c b/tasks/task_wifi.c new file mode 100644 index 0000000000..1fd9223d68 --- /dev/null +++ b/tasks/task_wifi.c @@ -0,0 +1,116 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2016 - Jean-André Santoni + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tasks_internal.h" +#include "../verbosity.h" +#include "../runloop.h" +#include "../wifi/wifi_driver.h" +#include "../menu/menu_entries.h" +#include "../menu/menu_driver.h" + +typedef struct +{ + struct string_list *ssid_list; +} wifi_handle_t; + +static void wifi_scan_callback(void *task_data, + void *user_data, const char *error) +{ + unsigned menu_type = 0; + const char *path = NULL; + const char *label = NULL; + enum msg_hash_enums enum_idx = MSG_UNKNOWN; + global_t *global = global_get_ptr(); + + menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL); + + /* Don't push the results if we left the wifi menu */ + if (!global || !string_is_equal(label, + msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_WIFI_SETTINGS_LIST))) + return; + + file_list_t *file_list = menu_entries_get_selection_buf_ptr(0); + + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, file_list); + + unsigned i; + for (i = 0; i < global->ssid_list->size; i++) + { + const char *ssid = global->ssid_list->elems[i].data; + menu_entries_append_enum(file_list, + ssid, + msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_WIFI), + MENU_ENUM_LABEL_CONNECT_WIFI, + MENU_WIFI, 0, 0); + } +} + +static void task_wifi_scan_handler(retro_task_t *task) +{ + global_t *global = global_get_ptr(); + wifi_handle_t *state = (wifi_handle_t*)task->state; + + driver_wifi_scan(); + task->progress = 50; + task->title = strdup("Parsing SSID list..."); + driver_wifi_get_ssids(global->ssid_list); + task->progress = 100; + task->title = strdup("Wi-Fi scan complete"); + task->finished = true; + task->task_data = state; + + return; +} + +bool task_push_wifi_scan() +{ + retro_task_t *task = (retro_task_t*)calloc(1, sizeof(*task)); + wifi_handle_t *state = (wifi_handle_t*)calloc(1, sizeof(*state)); + + if (!task || !state) + goto error; + + state->ssid_list = string_list_new(); + + /* blocking means no other task can run while this one is running, which is the default */ + task->type = TASK_TYPE_BLOCKING; + task->state = state; + task->handler = task_wifi_scan_handler; + task->callback = wifi_scan_callback; + task->title = strdup("Scanning wireless networks..."); + + task_queue_ctl(TASK_QUEUE_CTL_PUSH, task); + + return true; + +error: + if (state) + free(state); + if (task) + free(task); + + return false; +} \ No newline at end of file diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index f39636f89a..850c709edb 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -83,6 +83,9 @@ void *task_push_http_transfer(const char *url, bool mute, const char *type, retro_task_callback_t cb, void *userdata); task_retriever_info_t *http_task_get_transfer_list(void); + +bool task_push_wifi_scan(); + #endif bool task_push_image_load(const char *fullpath, From 99ab41be4a25ed22f4f6255d51e8fbf00aa16853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Wed, 30 Nov 2016 01:21:21 +0100 Subject: [PATCH 02/32] Don't use structs in global_t. Also simplifies the async wifi code. --- menu/menu_displaylist.c | 13 ++++++------- retroarch.c | 4 ---- runloop.h | 3 --- tasks/task_wifi.c | 15 ++++++--------- wifi/drivers/connmanctl.c | 3 +++ 5 files changed, 15 insertions(+), 23 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index a5415d1af8..5def784767 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -69,6 +69,7 @@ #include "../list_special.h" #include "../performance_counters.h" #include "../core_info.h" +#include "../wifi/wifi_driver.h" #include "../tasks/tasks_internal.h" #ifdef HAVE_NETWORKING @@ -4893,12 +4894,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) 0, 0, 0); else { - global_t *global = global_get_ptr(); + struct string_list *ssid_list = string_list_new(); + driver_wifi_get_ssids(ssid_list); - if (!global) - break; - - if (global->ssid_list->size == 0) + if (ssid_list->size == 0) { task_push_wifi_scan(); @@ -4911,9 +4910,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) else { unsigned i; - for (i = 0; i < global->ssid_list->size; i++) + for (i = 0; i < ssid_list->size; i++) { - const char *ssid = global->ssid_list->elems[i].data; + const char *ssid = ssid_list->elems[i].data; menu_entries_append_enum(info->list, ssid, msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_WIFI), diff --git a/retroarch.c b/retroarch.c index 8205093eaf..bb375b4c0b 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1011,10 +1011,6 @@ bool retroarch_main_init(int argc, char *argv[]) { bool init_failed = false; - global_t *global = global_get_ptr(); - if (global) - global->ssid_list = string_list_new(); - retroarch_init_state(); if (setjmp(error_sjlj_context) > 0) diff --git a/runloop.h b/runloop.h index 0e45e50252..35fada6eb1 100644 --- a/runloop.h +++ b/runloop.h @@ -20,7 +20,6 @@ #include #include #include -#include #ifdef HAVE_CONFIG_H #include "config.h" @@ -192,8 +191,6 @@ typedef struct global bool flickerfilter_enable; bool softfilter_enable; } console; - - struct string_list *ssid_list; } global_t; typedef struct runloop_ctx_msg_info diff --git a/tasks/task_wifi.c b/tasks/task_wifi.c index 1fd9223d68..ec2b83e616 100644 --- a/tasks/task_wifi.c +++ b/tasks/task_wifi.c @@ -43,12 +43,11 @@ static void wifi_scan_callback(void *task_data, const char *path = NULL; const char *label = NULL; enum msg_hash_enums enum_idx = MSG_UNKNOWN; - global_t *global = global_get_ptr(); menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL); /* Don't push the results if we left the wifi menu */ - if (!global || !string_is_equal(label, + if (!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_WIFI_SETTINGS_LIST))) return; @@ -56,10 +55,13 @@ static void wifi_scan_callback(void *task_data, menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, file_list); + struct string_list *ssid_list = string_list_new(); + driver_wifi_get_ssids(ssid_list); + unsigned i; - for (i = 0; i < global->ssid_list->size; i++) + for (i = 0; i < ssid_list->size; i++) { - const char *ssid = global->ssid_list->elems[i].data; + const char *ssid = ssid_list->elems[i].data; menu_entries_append_enum(file_list, ssid, msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_WIFI), @@ -70,17 +72,12 @@ static void wifi_scan_callback(void *task_data, static void task_wifi_scan_handler(retro_task_t *task) { - global_t *global = global_get_ptr(); wifi_handle_t *state = (wifi_handle_t*)task->state; driver_wifi_scan(); - task->progress = 50; - task->title = strdup("Parsing SSID list..."); - driver_wifi_get_ssids(global->ssid_list); task->progress = 100; task->title = strdup("Wi-Fi scan complete"); task->finished = true; - task->task_data = state; return; } diff --git a/wifi/drivers/connmanctl.c b/wifi/drivers/connmanctl.c index 773b3ba26b..b9a7b2d068 100644 --- a/wifi/drivers/connmanctl.c +++ b/wifi/drivers/connmanctl.c @@ -81,6 +81,9 @@ static void connmanctl_get_ssids(struct string_list* ssids) union string_list_elem_attr attr; attr.i = RARCH_FILETYPE_UNSET; + if (!lines) + return; + for (i = 0; i < lines->size; i++) { char ssid[20]; From 65355994b34ee0289bd87ca05d9a105af5e677d6 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 21:00:53 -0500 Subject: [PATCH 03/32] NAT traversal Adding NAT traveral interface to libretro-common, with (currently) a backend support MiniUPNPC. Sensible future backends would be libupnp and a direct implementation of PCP/NAT-PMP. --- Makefile.common | 5 + libretro-common/include/net/net_natt.h | 47 ++++++ libretro-common/net/net_natt.c | 192 +++++++++++++++++++++++++ qb/config.libs.sh | 4 + qb/config.params.sh | 1 + 5 files changed, 249 insertions(+) create mode 100644 libretro-common/include/net/net_natt.h create mode 100644 libretro-common/net/net_natt.c diff --git a/Makefile.common b/Makefile.common index f3cfaf753a..2980615ee3 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1086,6 +1086,7 @@ ifeq ($(HAVE_NETWORKING), 1) OBJ += $(LIBRETRO_COMM_DIR)/net/net_compat.o \ $(LIBRETRO_COMM_DIR)/net/net_http.o \ $(LIBRETRO_COMM_DIR)/net/net_socket.o \ + $(LIBRETRO_COMM_DIR)/net/net_natt.o \ network/net_http_special.o \ tasks/task_http.o @@ -1123,6 +1124,10 @@ ifeq ($(HAVE_NETWORKING), 1) OBJ += input/input_remote.o \ cores/libretro-net-retropad/net_retropad_core.o endif + + ifeq ($(HAVE_MINIUPNPC), 1) + LIBS += -lminiupnpc + endif endif ifneq ($(findstring Win32,$(OS)),) diff --git a/libretro-common/include/net/net_natt.h b/libretro-common/include/net/net_natt.h new file mode 100644 index 0000000000..ec09780711 --- /dev/null +++ b/libretro-common/include/net/net_natt.h @@ -0,0 +1,47 @@ +#include + +struct natt_status { + /** The fdset to be selected upon to check for responses */ + fd_set fds; + + /** True if we've resolved an external IPv4 address */ + bool have_inet4; + + /** External IPv4 address */ + struct sockaddr_in ext_inet4_addr; + + /** True if we've resolved an external IPv6 address */ + bool have_inet6; + +#ifdef AF_INET6 + /** External IPv6 address */ + struct sockaddr_in6 ext_inet6_addr; +#endif + + /** Internal status (currently unused) */ + void *internal; +}; + +/** + * Initialize global NAT traversal structures (must be called once to use other + * functions) */ +void natt_init(void); + +/** Initialize a NAT traversal status object */ +bool natt_new(struct natt_status *status); + +/** Free a NAT traversal status object */ +void natt_free(struct natt_status *status); + +/** + * Make a port forwarding request. This may finish immediately or just send a + * request to the network. */ +bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t addrlen); + +/** + * Make a port forwarding request when only the port is known. Forwards any + * address it can find. */ +bool natt_open_port_any(struct natt_status *status, uint16_t port); + +/** Check for port forwarding responses */ +bool natt_read(struct natt_status *status); diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c new file mode 100644 index 0000000000..5f116a69cd --- /dev/null +++ b/libretro-common/net/net_natt.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include + +#if HAVE_MINIUPNPC +#include +#include +#include + +static struct UPNPUrls urls; +static struct IGDdatas data; +#endif + +void natt_init(void) +{ +#if HAVE_MINIUPNPC + struct UPNPDev * devlist; + struct UPNPDev * dev; + char * descXML; + int descXMLsize = 0; + int upnperror = 0; + memset(&urls, 0, sizeof(struct UPNPUrls)); + memset(&data, 0, sizeof(struct IGDdatas)); + devlist = upnpDiscover(2000, NULL, NULL, 0, 0, &upnperror); + if (devlist) + { + dev = devlist; + while (dev) + { + if (strstr (dev->st, "InternetGatewayDevice")) + break; + dev = dev->pNext; + } + if (!dev) + dev = devlist; + + descXML = miniwget(dev->descURL, &descXMLsize, 0); + if (descXML) + { + parserootdesc (descXML, descXMLsize, &data); + free (descXML); descXML = 0; + GetUPNPUrls (&urls, &data, dev->descURL, 0); + } + freeUPNPDevlist(devlist); + } +#endif +} + +bool natt_new(struct natt_status *status) +{ + memset(status, 0, sizeof(struct natt_status)); + return true; +} + +void natt_free(struct natt_status *status) +{ + /* Nothing */ +} + +bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t addrlen) +{ +#if HAVE_MINIUPNPC + char host[PATH_MAX_LENGTH], ext_host[PATH_MAX_LENGTH], + port_str[6], ext_port_str[6]; + struct addrinfo hints = {0}, *ext_addrinfo; + int r; + + /* if NAT traversal is uninitialized or unavailable, oh well */ + if (!urls.controlURL[0]) + return false; + + /* figure out the internal info */ + if (getnameinfo(addr, addrlen, host, PATH_MAX_LENGTH, port_str, 6, 0) != 0) + return false; + + /* add the port mapping */ + r = UPNP_AddAnyPortMapping(urls.controlURL, data.first.servicetype, port_str, + port_str, host, "retroarch", "TCP", NULL, "3600", ext_port_str); + if (r == 501 /* Action Failed */) + { + /* try the older AddPortMapping */ + memcpy(ext_port_str, port_str, 6); + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port_str, + port_str, host, "retroarch", "TCP", NULL, "3600"); + } + fprintf(stderr, "ERROR: %d\n", r); + if (r != 0) + return false; + + /* get the external IP */ + r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, ext_host); + if (r != 0) + return false; + + /* update the status */ + if (getaddrinfo_retro(ext_host, ext_port_str, &hints, &ext_addrinfo) != 0) + return false; + + if (ext_addrinfo->ai_family == AF_INET && + ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in)) + { + status->have_inet4 = true; + status->ext_inet4_addr = *((struct sockaddr_in *) ext_addrinfo->ai_addr); + } +#ifdef AF_INET6 + else if (ext_addrinfo->ai_family == AF_INET6 && + ext_addrinfo->ai_addrlen >= sizeof(struct sockaddr_in6)) + { + status->have_inet6 = true; + status->ext_inet6_addr = *((struct sockaddr_in6 *) ext_addrinfo->ai_addr); + } + else + { + freeaddrinfo_retro(ext_addrinfo); + return false; + } +#endif + + return true; + +#else + return false; +#endif +} + +bool natt_open_port_any(struct natt_status *status, uint16_t port) +{ + struct net_ifinfo list; + bool ret = false; + size_t i; + struct addrinfo hints = {0}, *addr; + char port_str[6]; + + sprintf(port_str, "%hu", port); + + /* get our interfaces */ + if (!net_ifinfo_new(&list)) + return false; + + /* loop through them */ + for (i = 0; i < list.size; i++) + { + struct net_ifinfo_entry *entry = list.entries + i; + + /* ignore localhost */ + if (!strcmp(entry->host, "127.0.0.1") || !strcmp(entry->host, "::1")) + continue; + + /* make a request for this host */ + if (getaddrinfo_retro(entry->host, port_str, &hints, &addr) == 0) + { + ret = natt_open_port(status, addr->ai_addr, addr->ai_addrlen) || ret; + freeaddrinfo_retro(addr); + } + } + + /* BUGS! net_ifinfo_free(&list); */ + + return ret; +} + +bool natt_read(struct natt_status *status) +{ + /* MiniUPNPC is always synchronous, so there's nothing to read here. + * Reserved for future backends. */ + return false; +} + +#if 0 +/* If we want to remove redirects in the future, this is a sample of how to do + * that */ +void upnp_rem_redir (int port) +{ + char port_str[16]; + int t; + printf("TB : upnp_rem_redir (%d)\n", port); + if(urls.controlURL[0] == '\0') + { + printf("TB : the init was not done !\n"); + return; + } + sprintf(port_str, "%d", port); + UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port_str, "TCP", NULL); +} +#endif diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 3d68a861a8..6d789eac9f 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -182,6 +182,10 @@ if [ "$HAVE_NETWORKING" = 'yes' ]; then fi HAVE_NETWORK_CMD=yes HAVE_NETWORKGAMEPAD=yes + + if [ "$HAVE_MINIUPNPC" != "no" ]; then + check_lib MINIUPNPC "-lminiupnpc" + fi else echo "Warning: All networking features have been disabled." HAVE_NETWORK_CMD='no' diff --git a/qb/config.params.sh b/qb/config.params.sh index 61d5a41861..9254edba6b 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -28,6 +28,7 @@ HAVE_DYLIB=auto # Dynamic loading support HAVE_NETWORKING=auto # Networking features (recommended) HAVE_NETWORKGAMEPAD=auto # Networked game pad (plus baked-in core) C89_NETWORKGAMEPAD=no +HAVE_MINIUPNPC=auto # Mini UPnP client library (for NAT traversal) HAVE_D3D9=yes # Direct3D 9 support HAVE_OPENGL=auto # OpenGL support HAVE_MALI_FBDEV=no # Mali fbdev context support From da406c3abb1dfef2c9cbf3149bb741ef40acc8df Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 21:09:47 -0500 Subject: [PATCH 04/32] Adding copyright headers and support for specifying protocol (TCP/UDP) --- libretro-common/include/net/net_natt.h | 34 ++++++++++++++++++++++++-- libretro-common/net/net_natt.c | 34 ++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/libretro-common/include/net/net_natt.h b/libretro-common/include/net/net_natt.h index ec09780711..a4bbd29f00 100644 --- a/libretro-common/include/net/net_natt.h +++ b/libretro-common/include/net/net_natt.h @@ -1,4 +1,30 @@ +/* Copyright (C) 2016 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (net_natt.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _LIBRETRO_SDK_NET_NATT_H +#define _LIBRETRO_SDK_NET_NATT_H + #include +#include struct natt_status { /** The fdset to be selected upon to check for responses */ @@ -36,12 +62,16 @@ void natt_free(struct natt_status *status); /** * Make a port forwarding request. This may finish immediately or just send a * request to the network. */ -bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t addrlen); +bool natt_open_port(struct natt_status *status, struct sockaddr *addr, + socklen_t addrlen, enum socket_protocol proto); /** * Make a port forwarding request when only the port is known. Forwards any * address it can find. */ -bool natt_open_port_any(struct natt_status *status, uint16_t port); +bool natt_open_port_any(struct natt_status *status, uint16_t port, + enum socket_protocol proto); /** Check for port forwarding responses */ bool natt_read(struct natt_status *status); + +#endif diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index 5f116a69cd..5bb6b380ee 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -1,3 +1,25 @@ +/* Copyright (C) 2016 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (net_natt.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + #include #include #include @@ -64,11 +86,12 @@ void natt_free(struct natt_status *status) /* Nothing */ } -bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t addrlen) +bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t addrlen, enum socket_protocol proto) { #if HAVE_MINIUPNPC char host[PATH_MAX_LENGTH], ext_host[PATH_MAX_LENGTH], port_str[6], ext_port_str[6]; + const char *proto_str; struct addrinfo hints = {0}, *ext_addrinfo; int r; @@ -79,16 +102,17 @@ bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t /* figure out the internal info */ if (getnameinfo(addr, addrlen, host, PATH_MAX_LENGTH, port_str, 6, 0) != 0) return false; + proto_str = (proto == SOCKET_PROTOCOL_UDP) ? "UDP" : "TCP"; /* add the port mapping */ r = UPNP_AddAnyPortMapping(urls.controlURL, data.first.servicetype, port_str, - port_str, host, "retroarch", "TCP", NULL, "3600", ext_port_str); + port_str, host, "retroarch", proto_str, NULL, "3600", ext_port_str); if (r == 501 /* Action Failed */) { /* try the older AddPortMapping */ memcpy(ext_port_str, port_str, 6); r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port_str, - port_str, host, "retroarch", "TCP", NULL, "3600"); + port_str, host, "retroarch", proto_str, NULL, "3600"); } fprintf(stderr, "ERROR: %d\n", r); if (r != 0) @@ -130,7 +154,7 @@ bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t #endif } -bool natt_open_port_any(struct natt_status *status, uint16_t port) +bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_protocol proto) { struct net_ifinfo list; bool ret = false; @@ -156,7 +180,7 @@ bool natt_open_port_any(struct natt_status *status, uint16_t port) /* make a request for this host */ if (getaddrinfo_retro(entry->host, port_str, &hints, &addr) == 0) { - ret = natt_open_port(status, addr->ai_addr, addr->ai_addrlen) || ret; + ret = natt_open_port(status, addr->ai_addr, addr->ai_addrlen, proto) || ret; freeaddrinfo_retro(addr); } } From 8f61e2b9788dcb3bf57e9b89fdb2d3da778d7011 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 21:16:04 -0500 Subject: [PATCH 05/32] Spacing correction (three spaces, not four) --- libretro-common/include/net/net_natt.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libretro-common/include/net/net_natt.h b/libretro-common/include/net/net_natt.h index a4bbd29f00..f50f6fa45f 100644 --- a/libretro-common/include/net/net_natt.h +++ b/libretro-common/include/net/net_natt.h @@ -27,25 +27,25 @@ #include struct natt_status { - /** The fdset to be selected upon to check for responses */ - fd_set fds; + /** The fdset to be selected upon to check for responses */ + fd_set fds; - /** True if we've resolved an external IPv4 address */ - bool have_inet4; + /** True if we've resolved an external IPv4 address */ + bool have_inet4; - /** External IPv4 address */ - struct sockaddr_in ext_inet4_addr; + /** External IPv4 address */ + struct sockaddr_in ext_inet4_addr; - /** True if we've resolved an external IPv6 address */ - bool have_inet6; + /** True if we've resolved an external IPv6 address */ + bool have_inet6; #ifdef AF_INET6 - /** External IPv6 address */ - struct sockaddr_in6 ext_inet6_addr; + /** External IPv6 address */ + struct sockaddr_in6 ext_inet6_addr; #endif - /** Internal status (currently unused) */ - void *internal; + /** Internal status (currently unused) */ + void *internal; }; /** From 50ec1bc9cdc07350481eadb98c30eb61843ad9b5 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 21:16:25 -0500 Subject: [PATCH 06/32] Add NAT traversal code to griffin --- griffin/griffin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/griffin/griffin.c b/griffin/griffin.c index b57420f4a5..4785559281 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -879,6 +879,7 @@ NETPLAY #include "../libretro-common/net/net_compat.c" #include "../libretro-common/net/net_socket.c" #include "../libretro-common/net/net_http.c" +#include "../libretro-common/net/net_nett.c" #ifndef HAVE_SOCKET_LEGACY #include "../libretro-common/net/net_ifinfo.c" #endif From 48240c2806bd612f716440d842676c64fb0c402a Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 22:18:37 -0500 Subject: [PATCH 07/32] Adding Netplay NAT traversal option (but not implementation yet) --- configuration.c | 3 ++- configuration.h | 1 + intl/msg_hash_us.c | 6 ++++++ intl/msg_hash_us.h | 2 ++ menu/menu_displaylist.c | 4 ++++ menu/menu_setting.c | 15 +++++++++++++++ msg_hash.h | 1 + 7 files changed, 31 insertions(+), 1 deletion(-) diff --git a/configuration.c b/configuration.c index 9256fde0b9..e1e6964bdd 100644 --- a/configuration.c +++ b/configuration.c @@ -799,6 +799,7 @@ static int populate_settings_bool(settings_t *settings, struct config_bool_setti #endif #ifdef HAVE_NETWORKING SETTING_BOOL("netplay_spectator_mode_enable",&settings->netplay.is_spectate, false, false /* TODO */, false); + SETTING_BOOL("netplay_nat_traversal", &settings->netplay.nat_traversal, true, true, false); #endif SETTING_BOOL("block_sram_overwrite", &settings->block_sram_overwrite, true, block_sram_overwrite, false); SETTING_BOOL("savestate_auto_index", &settings->savestate_auto_index, true, savestate_auto_index, false); @@ -921,7 +922,7 @@ static int populate_settings_int(settings_t *settings, struct config_int_setting #ifdef HAVE_NETWORKING SETTING_INT("netplay_ip_port", &settings->netplay.port, false, 0 /* TODO */, false); SETTING_INT("netplay_delay_frames", &settings->netplay.sync_frames, true, 16, false); - SETTING_INT("netplay_check_frames", &settings->netplay.check_frames, false, 30, false); + SETTING_INT("netplay_check_frames", &settings->netplay.check_frames, true, 30, false); #endif #ifdef HAVE_LANGEXTRA SETTING_INT("user_language", &settings->user_language, true, RETRO_LANGUAGE_ENGLISH, false); diff --git a/configuration.h b/configuration.h index bef8bbb67e..10ad4b7d17 100644 --- a/configuration.h +++ b/configuration.h @@ -403,6 +403,7 @@ typedef struct settings unsigned check_frames; bool is_spectate; bool swap_input; + bool nat_traversal; } netplay; #endif diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index d5abdde020..e15ac8cee9 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1548,6 +1548,12 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) "no checks. This value is only used on the \n" "netplay host. \n"); break; + case MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL: + snprintf(s, len, + "When hosting, attempt to listen for\n" + "connections from the public internet, using\n" + "UPnP or similar technologies to escape LANs. \n"); + break; case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES: snprintf(s, len, "Maximum amount of swapchain images. This \n" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 8240988031..a70808f908 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -920,6 +920,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, "Netplay Spectator Enable") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, "Netplay TCP/UDP Port") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, + "Netplay NAT Traversal") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, "Network Commands") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 2a3868681f..4d0e99f658 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4942,6 +4942,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT, PARSE_ONLY_BOOL, false) != -1) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL, + PARSE_ONLY_BOOL, false) != -1) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETWORK_CMD_ENABLE, PARSE_ONLY_BOOL, false) != -1) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 651f4a2aa5..3dec0627f0 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -5583,6 +5583,21 @@ static bool setting_append_list( general_read_handler, SD_FLAG_NONE); + CONFIG_BOOL( + list, list_info, + &settings->netplay.is_spectate, + MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL, + MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, + false, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + CONFIG_BOOL( list, list_info, &settings->netplay.swap_input, diff --git a/msg_hash.h b/msg_hash.h index 8e5477a7c0..702453f0ec 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -974,6 +974,7 @@ enum msg_hash_enums MENU_LABEL(NETPLAY_CHECK_FRAMES), MENU_LABEL(NETPLAY_SPECTATOR_MODE_ENABLE), MENU_LABEL(NETPLAY_TCP_UDP_PORT), + MENU_LABEL(NETPLAY_NAT_TRAVERSAL), MENU_LABEL(SORT_SAVEFILES_ENABLE), MENU_LABEL(SORT_SAVESTATES_ENABLE), MENU_LABEL(NETPLAY_IP_ADDRESS), From 42da0a01845be4769b699ba1965ae8dc491cf56a Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 22:59:46 -0500 Subject: [PATCH 08/32] NAT traversal in Netplay For the time being, if NAT traversal is successful it simply announces it as an OSD message. In the future it will be used to inform a matchmaking server of the public port. This patch also included minor fixes to the NAT traversal implementation to make the select it demands actually doable. --- intl/msg_hash_us.h | 4 ++ libretro-common/include/net/net_natt.h | 6 ++ msg_hash.h | 1 + network/netplay/netplay.c | 83 ++++++++++++++++++++++++-- network/netplay/netplay.h | 3 +- network/netplay/netplay_net.c | 14 +++++ network/netplay/netplay_private.h | 4 ++ 7 files changed, 108 insertions(+), 7 deletions(-) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index a70808f908..9e865016d2 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -22,6 +22,10 @@ MSG_HASH( MSG_GOT_CONNECTION_FROM, "Got connection from" ) +MSG_HASH( + MSG_PUBLIC_ADDRESS, + "Public address" + ) MSG_HASH( MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, "No arguments supplied and no menu builtin, displaying help..." diff --git a/libretro-common/include/net/net_natt.h b/libretro-common/include/net/net_natt.h index f50f6fa45f..bb9c791f61 100644 --- a/libretro-common/include/net/net_natt.h +++ b/libretro-common/include/net/net_natt.h @@ -27,9 +27,15 @@ #include struct natt_status { + /** nfds for select when checking for input */ + int nfds; + /** The fdset to be selected upon to check for responses */ fd_set fds; + /** True if there might be a request outstanding */ + bool request_outstanding; + /** True if we've resolved an external IPv4 address */ bool have_inet4; diff --git a/msg_hash.h b/msg_hash.h index 702453f0ec..089559365e 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -173,6 +173,7 @@ enum msg_hash_enums MSG_NO_STATE_HAS_BEEN_LOADED_YET, MSG_GOT_CONNECTION_FROM, MSG_CONNECTION_SLOT, + MSG_PUBLIC_ADDRESS, MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, MSG_CANNOT_INFER_NEW_CONFIG_PATH, MSG_UNDID_LOAD_STATE, diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index 074b70e6ea..b2d33088f3 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -63,6 +63,8 @@ static netplay_t *netplay_data = NULL; /* Used to avoid recursive netplay calls */ static bool in_netplay = false; +static void announce_nat_traversal(netplay_t *netplay); + static int init_tcp_connection(const struct addrinfo *res, bool server, bool spectate, struct sockaddr *other_addr, socklen_t addr_size) @@ -172,6 +174,22 @@ static bool init_tcp_socket(netplay_t *netplay, const char *server, return ret; } +static void init_nat_traversal(netplay_t *netplay) +{ + natt_init(); + + if (!natt_new(&netplay->nat_traversal_state)) + { + netplay->nat_traversal = false; + return; + } + + natt_open_port_any(&netplay->nat_traversal_state, netplay->tcp_port, SOCKET_PROTOCOL_TCP); + + if (!netplay->nat_traversal_state.request_outstanding) + announce_nat_traversal(netplay); +} + static bool init_ad_socket(netplay_t *netplay, uint16_t port) { int fd = socket_init((void**)&netplay->addr, port, NULL, SOCKET_TYPE_DATAGRAM); @@ -202,6 +220,9 @@ static bool init_socket(netplay_t *netplay, const char *server, uint16_t port) if (!init_tcp_socket(netplay, server, port, netplay->spectate.enabled)) return false; + if (netplay->is_server && netplay->nat_traversal) + init_nat_traversal(netplay); + return true; } @@ -1047,6 +1068,36 @@ void netplay_log_connection(const struct sockaddr_storage *their_addr, #endif +static void announce_nat_traversal(netplay_t *netplay) +{ + char msg[512], host[PATH_MAX_LENGTH], port[6]; + + if (netplay->nat_traversal_state.have_inet4) + { + if (getnameinfo((const struct sockaddr *) &netplay->nat_traversal_state.ext_inet4_addr, + sizeof(struct sockaddr_in), + host, PATH_MAX_LENGTH, port, 6, 0) != 0) + return; + + } +#ifdef AF_INET6 + else if (netplay->nat_traversal_state.have_inet6) + { + if (getnameinfo((const struct sockaddr *) &netplay->nat_traversal_state.ext_inet6_addr, + sizeof(struct sockaddr_in6), + host, PATH_MAX_LENGTH, port, 6, 0) != 0) + return; + + } +#endif + else return; + + snprintf(msg, sizeof(msg), "%s: %s:%s\n", + msg_hash_to_str(MSG_PUBLIC_ADDRESS), + host, port); + runloop_msg_queue_push(msg, 1, 180, false); + RARCH_LOG("%s\n", msg); +} bool netplay_try_init_serialization(netplay_t *netplay) @@ -1166,6 +1217,7 @@ static bool netplay_init_buffers(netplay_t *netplay, unsigned frames) * @check_frames : Frequency with which to check CRCs. * @cb : Libretro callbacks. * @spectate : If true, enable spectator mode. + * @nat_traversal : If true, attempt NAT traversal. * @nick : Nickname of user. * @quirks : Netplay quirks required for this session. * @@ -1174,10 +1226,9 @@ static bool netplay_init_buffers(netplay_t *netplay, unsigned frames) * * Returns: new netplay handle. **/ -netplay_t *netplay_new(const char *server, uint16_t port, - unsigned frames, unsigned check_frames, - const struct retro_callbacks *cb, - bool spectate, const char *nick, uint64_t quirks) +netplay_t *netplay_new(const char *server, uint16_t port, unsigned frames, + unsigned check_frames, const struct retro_callbacks *cb, bool spectate, + bool nat_traversal, const char *nick, uint64_t quirks) { netplay_t *netplay = (netplay_t*)calloc(1, sizeof(*netplay)); if (!netplay) @@ -1189,6 +1240,7 @@ netplay_t *netplay_new(const char *server, uint16_t port, netplay->port = server ? 0 : 1; netplay->spectate.enabled = spectate; netplay->is_server = server == NULL; + netplay->nat_traversal = netplay->is_server ? nat_traversal : false; netplay->stall_frames = frames; netplay->check_frames = check_frames; netplay->quirks = quirks; @@ -1324,6 +1376,9 @@ void netplay_free(netplay_t *netplay) free(netplay->spectate.input); } + if (netplay->nat_traversal) + natt_free(&netplay->nat_traversal_state); + if (netplay->buffer) { for (i = 0; i < netplay->buffer_size; i++) @@ -1369,11 +1424,26 @@ bool netplay_pre_frame(netplay_t *netplay) netplay_try_init_serialization(netplay); } - /* Advertise our server if applicable */ if (netplay->is_server) { + /* Advertise our server if applicable */ if (netplay_ad_fd >= 0 || init_ad_socket(netplay, RARCH_DEFAULT_PORT)) netplay_ad_server(netplay, netplay_ad_fd); + + /* NAT traversal if applicable */ + if (netplay->nat_traversal && + netplay->nat_traversal_state.request_outstanding && + !netplay->nat_traversal_state.have_inet4) + { + struct timeval tmptv = {0}; + fd_set fds = netplay->nat_traversal_state.fds; + if (socket_select(netplay->nat_traversal_state.nfds, &fds, NULL, NULL, &tmptv) > 0) + natt_read(&netplay->nat_traversal_state); + + if (!netplay->nat_traversal_state.request_outstanding || + netplay->nat_traversal_state.have_inet4) + announce_nat_traversal(netplay); + } } if (!netplay->net_cbs->pre_frame(netplay)) @@ -1599,7 +1669,8 @@ bool init_netplay(bool is_spectate, const char *server, unsigned port) netplay_is_client ? server : NULL, port ? port : RARCH_DEFAULT_PORT, settings->netplay.sync_frames, settings->netplay.check_frames, &cbs, - is_spectate, settings->username, quirks); + is_spectate, settings->netplay.nat_traversal, settings->username, + quirks); if (netplay_data) return true; diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index 83b41b69a1..b1470bb96b 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -137,6 +137,7 @@ size_t audio_sample_batch_net(const int16_t *data, size_t frames); * @check_frames : Frequency with which to check CRCs. * @cb : Libretro callbacks. * @spectate : If true, enable spectator mode. + * @nat_traversal : If true, attempt NAT traversal. * @nick : Nickname of user. * @quirks : Netplay quirks. * @@ -147,7 +148,7 @@ size_t audio_sample_batch_net(const int16_t *data, size_t frames); **/ netplay_t *netplay_new(const char *server, uint16_t port, unsigned frames, unsigned check_frames, - const struct retro_callbacks *cb, bool spectate, + const struct retro_callbacks *cb, bool spectate, bool nat_traversal, const char *nick, uint64_t quirks); /** diff --git a/network/netplay/netplay_net.c b/network/netplay/netplay_net.c index c594587e0f..cc6e409fc6 100644 --- a/network/netplay/netplay_net.c +++ b/network/netplay/netplay_net.c @@ -20,6 +20,7 @@ #include #include +#include #include "netplay_private.h" @@ -337,6 +338,19 @@ static bool netplay_net_info_cb(netplay_t* netplay, unsigned frames) netplay->has_connection = true; } + { + struct natt_status status; + natt_init(); + if (natt_new(&status) && natt_open_port_any(&status, netplay->tcp_port, SOCKET_PROTOCOL_TCP)) + { + fprintf(stderr, "Forwarded to %d!\n", status.ext_inet4_addr.sin_port); + } + else + { + fprintf(stderr, "Forwarding failed :(\n"); + } + } + return true; } diff --git a/network/netplay/netplay_private.h b/network/netplay/netplay_private.h index 40689561c0..9318a70681 100644 --- a/network/netplay/netplay_private.h +++ b/network/netplay/netplay_private.h @@ -20,6 +20,7 @@ #include "netplay.h" #include +#include #include #include #include @@ -124,6 +125,9 @@ struct netplay int fd; /* TCP port (if serving) */ uint16_t tcp_port; + /* NAT traversal info (if NAT traversal is used and serving) */ + bool nat_traversal; + struct natt_status nat_traversal_state; /* Which port is governed by netplay (other user)? */ unsigned port; bool has_connection; From c342c103aed089345182bdeee2633520e594272b Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 23:08:26 -0500 Subject: [PATCH 09/32] Always get numeric host/ports instead of names. --- libretro-common/net/net_natt.c | 2 +- network/netplay/netplay.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index 5bb6b380ee..6c37fa225d 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -100,7 +100,7 @@ bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t return false; /* figure out the internal info */ - if (getnameinfo(addr, addrlen, host, PATH_MAX_LENGTH, port_str, 6, 0) != 0) + if (getnameinfo(addr, addrlen, host, PATH_MAX_LENGTH, port_str, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0) return false; proto_str = (proto == SOCKET_PROTOCOL_UDP) ? "UDP" : "TCP"; diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index b2d33088f3..5bf7bdaf58 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -1076,7 +1076,7 @@ static void announce_nat_traversal(netplay_t *netplay) { if (getnameinfo((const struct sockaddr *) &netplay->nat_traversal_state.ext_inet4_addr, sizeof(struct sockaddr_in), - host, PATH_MAX_LENGTH, port, 6, 0) != 0) + host, PATH_MAX_LENGTH, port, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0) return; } @@ -1085,7 +1085,7 @@ static void announce_nat_traversal(netplay_t *netplay) { if (getnameinfo((const struct sockaddr *) &netplay->nat_traversal_state.ext_inet6_addr, sizeof(struct sockaddr_in6), - host, PATH_MAX_LENGTH, port, 6, 0) != 0) + host, PATH_MAX_LENGTH, port, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0) return; } From 025993231fb6f09b2fed1d4c2dcda862b6c5ea5e Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 23:08:48 -0500 Subject: [PATCH 10/32] Use net_ifinfo how it's intended (?) to be used --- libretro-common/net/net_natt.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index 6c37fa225d..2fb9dbe2eb 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -156,7 +156,7 @@ bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_protocol proto) { - struct net_ifinfo list; + struct net_ifinfo *list; bool ret = false; size_t i; struct addrinfo hints = {0}, *addr; @@ -165,13 +165,15 @@ bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_p sprintf(port_str, "%hu", port); /* get our interfaces */ - if (!net_ifinfo_new(&list)) + if ((list = calloc(1, sizeof(struct net_ifinfo))) == NULL) + return false; + if (!net_ifinfo_new(list)) return false; /* loop through them */ - for (i = 0; i < list.size; i++) + for (i = 0; i < list->size; i++) { - struct net_ifinfo_entry *entry = list.entries + i; + struct net_ifinfo_entry *entry = list->entries + i; /* ignore localhost */ if (!strcmp(entry->host, "127.0.0.1") || !strcmp(entry->host, "::1")) @@ -185,7 +187,8 @@ bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_p } } - /* BUGS! net_ifinfo_free(&list); */ + /* This really shouldn't free list, but does */ + net_ifinfo_free(list); return ret; } From 2522f688707a5cf72d3a60be62039d1f6c897fbb Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 23:10:19 -0500 Subject: [PATCH 11/32] C++ fixes --- libretro-common/net/net_natt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index 2fb9dbe2eb..ea3a32a539 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -63,7 +63,7 @@ void natt_init(void) if (!dev) dev = devlist; - descXML = miniwget(dev->descURL, &descXMLsize, 0); + descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0); if (descXML) { parserootdesc (descXML, descXMLsize, &data); @@ -165,7 +165,7 @@ bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_p sprintf(port_str, "%hu", port); /* get our interfaces */ - if ((list = calloc(1, sizeof(struct net_ifinfo))) == NULL) + if ((list = (struct net_ifinfo *) calloc(1, sizeof(struct net_ifinfo))) == NULL) return false; if (!net_ifinfo_new(list)) return false; From 0b13f7dc4a93fa7719b81cb95639c9e11af026c2 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 23:26:53 -0500 Subject: [PATCH 12/32] Tpyo in griffin include of net_natt --- griffin/griffin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/griffin/griffin.c b/griffin/griffin.c index 4785559281..80de9a08b5 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -879,7 +879,7 @@ NETPLAY #include "../libretro-common/net/net_compat.c" #include "../libretro-common/net/net_socket.c" #include "../libretro-common/net/net_http.c" -#include "../libretro-common/net/net_nett.c" +#include "../libretro-common/net/net_natt.c" #ifndef HAVE_SOCKET_LEGACY #include "../libretro-common/net/net_ifinfo.c" #endif From 8e5e760773bc20e528663129d205f84aea9fd879 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 23:30:12 -0500 Subject: [PATCH 13/32] Remove accidentally-left debug printf --- libretro-common/net/net_natt.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index ea3a32a539..a3f28534aa 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -114,7 +114,6 @@ bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port_str, port_str, host, "retroarch", proto_str, NULL, "3600"); } - fprintf(stderr, "ERROR: %d\n", r); if (r != 0) return false; From b1f9ef6073b3ca1820d23f0b600c2e5ab227435e Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Tue, 29 Nov 2016 23:31:35 -0500 Subject: [PATCH 14/32] Since I've allocated net_ifinfo, I'd better free it in all returns --- libretro-common/net/net_natt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index a3f28534aa..2bd7d1f865 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -167,7 +167,10 @@ bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_p if ((list = (struct net_ifinfo *) calloc(1, sizeof(struct net_ifinfo))) == NULL) return false; if (!net_ifinfo_new(list)) + { + free(list); return false; + } /* loop through them */ for (i = 0; i < list->size; i++) From 5cf668c30280a13603ec2e86d2b844a0c54067ee Mon Sep 17 00:00:00 2001 From: radius Date: Wed, 30 Nov 2016 00:39:32 -0500 Subject: [PATCH 15/32] set the option as false by default for the time being --- config.def.h | 2 +- tasks/task_content.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 9afa317c8c..78cb4e3ee7 100644 --- a/config.def.h +++ b/config.def.h @@ -437,7 +437,7 @@ static const bool load_dummy_on_core_shutdown = false; #else static const bool load_dummy_on_core_shutdown = true; #endif -static const bool check_firmware_before_loading = true; +static const bool check_firmware_before_loading = false; /* Forcibly disable composition. * Only valid on Windows Vista/7/8 for now. */ static const bool disable_composition = false; diff --git a/tasks/task_content.c b/tasks/task_content.c index 6092f5611e..9dad03364d 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -1221,6 +1221,8 @@ bool task_push_content_load_default( default: break; } + + RARCH_LOG("MODE: %d\n", mode); /* Load content */ switch (mode) { From ef65f6c57afdff8eb86340de378ac038ff10e399 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Wed, 30 Nov 2016 10:48:11 -0500 Subject: [PATCH 16/32] Support for both MiniUPNPC 2.0 and MiniUPNPC < 2.0 MiniUPNPC 2.0 was a backwards-incompatible change (as .0s tend to be) but configure detects them the same. This adds support for the changed functions. --- libretro-common/net/net_natt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index 2bd7d1f865..851f5e5a65 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -50,7 +50,11 @@ void natt_init(void) int upnperror = 0; memset(&urls, 0, sizeof(struct UPNPUrls)); memset(&data, 0, sizeof(struct IGDdatas)); +#if MINIUPNPC_API_VERSION < 16 devlist = upnpDiscover(2000, NULL, NULL, 0, 0, &upnperror); +#else + devlist = upnpDiscover(2000, NULL, NULL, 0, 0, 2, &upnperror); +#endif if (devlist) { dev = devlist; @@ -63,7 +67,11 @@ void natt_init(void) if (!dev) dev = devlist; +#if MINIUPNPC_API_VERSION < 16 descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0); +#else + descXML = (char *) miniwget(dev->descURL, &descXMLsize, 0, NULL); +#endif if (descXML) { parserootdesc (descXML, descXMLsize, &data); From 981cbf93c93243b078d86ba4b4875e0366677299 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 30 Nov 2016 17:37:32 +0100 Subject: [PATCH 17/32] Add task_wifi to Griffin --- griffin/griffin.c | 1 + tasks/task_wifi.c | 4 ++-- tasks/tasks_internal.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/griffin/griffin.c b/griffin/griffin.c index 80de9a08b5..ab734ccd0d 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -884,6 +884,7 @@ NETPLAY #include "../libretro-common/net/net_ifinfo.c" #endif #include "../tasks/task_http.c" +#include "../tasks/task_wifi.c" #endif /*============================================================ diff --git a/tasks/task_wifi.c b/tasks/task_wifi.c index ec2b83e616..68ee0a374b 100644 --- a/tasks/task_wifi.c +++ b/tasks/task_wifi.c @@ -82,7 +82,7 @@ static void task_wifi_scan_handler(retro_task_t *task) return; } -bool task_push_wifi_scan() +bool task_push_wifi_scan(void) { retro_task_t *task = (retro_task_t*)calloc(1, sizeof(*task)); wifi_handle_t *state = (wifi_handle_t*)calloc(1, sizeof(*state)); @@ -110,4 +110,4 @@ error: free(task); return false; -} \ No newline at end of file +} diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index 850c709edb..0975ccd120 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -84,7 +84,7 @@ void *task_push_http_transfer(const char *url, bool mute, const char *type, task_retriever_info_t *http_task_get_transfer_list(void); -bool task_push_wifi_scan(); +bool task_push_wifi_scan(void); #endif From d26905389bd9d0e6e8349bc7c0514a34be6b5f7b Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 30 Nov 2016 17:38:14 +0100 Subject: [PATCH 18/32] Cleanup --- tasks/task_wifi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasks/task_wifi.c b/tasks/task_wifi.c index 68ee0a374b..5a661afa9a 100644 --- a/tasks/task_wifi.c +++ b/tasks/task_wifi.c @@ -72,9 +72,8 @@ static void wifi_scan_callback(void *task_data, static void task_wifi_scan_handler(retro_task_t *task) { - wifi_handle_t *state = (wifi_handle_t*)task->state; - driver_wifi_scan(); + task->progress = 100; task->title = strdup("Wi-Fi scan complete"); task->finished = true; From 3f0a4183110b8b766005d75d2b9a59fbd4edbc3c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 30 Nov 2016 19:21:21 +0100 Subject: [PATCH 19/32] Fix Emscripten build --- menu/menu_displaylist.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index b5fa679d16..e60413d6de 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4892,6 +4892,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), MENU_ENUM_LABEL_NO_SETTINGS_FOUND, 0, 0, 0); +#ifdef HAVE_NETWORKING else { struct string_list *ssid_list = string_list_new(); @@ -4921,6 +4922,13 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) } } } +#else + menu_entries_append_enum(info->list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), + MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + 0, 0, 0); +#endif info->need_refresh = true; info->need_push = true; From 1f1a8eec893507f064ae748334e5a9ce044ec862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Thu, 1 Dec 2016 00:35:20 +0100 Subject: [PATCH 20/32] New message 'no networks found' --- intl/msg_hash_lbl.h | 2 ++ intl/msg_hash_us.h | 2 ++ menu/menu_displaylist.c | 18 +++++++++--------- msg_hash.h | 1 + 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a553a2e312..ba73b123d8 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -624,6 +624,8 @@ MSG_HASH(MENU_ENUM_LABEL_NO_HISTORY_AVAILABLE, "no_history") MSG_HASH(MENU_ENUM_LABEL_NO_ITEMS, "no_items") +MSG_HASH(MENU_ENUM_LABEL_NO_NETWORKS_FOUND, + "no_networks_found") MSG_HASH(MENU_ENUM_LABEL_NO_PERFORMANCE_COUNTERS, "no_performance_counters") MSG_HASH(MENU_ENUM_LABEL_NO_PLAYLISTS, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 83ae437b73..396720b17c 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -964,6 +964,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, "No information is available.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ITEMS, "No items.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, + "No networks found.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, "No performance counters.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index e60413d6de..52a373c9e4 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4888,9 +4888,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) case DISPLAYLIST_WIFI_SETTINGS_LIST: if (string_is_equal(settings->wifi.driver, "null")) menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), - msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), - MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_NETWORKS_FOUND), + MENU_ENUM_LABEL_NO_NETWORKS_FOUND, 0, 0, 0); #ifdef HAVE_NETWORKING else @@ -4903,9 +4903,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) task_push_wifi_scan(); menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), - msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), - MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_NETWORKS_FOUND), + MENU_ENUM_LABEL_NO_NETWORKS_FOUND, 0, 0, 0); } else @@ -4924,9 +4924,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) } #else menu_entries_append_enum(info->list, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND), - msg_hash_to_str(MENU_ENUM_LABEL_NO_SETTINGS_FOUND), - MENU_ENUM_LABEL_NO_SETTINGS_FOUND, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND), + msg_hash_to_str(MENU_ENUM_LABEL_NO_NETWORKS_FOUND), + MENU_ENUM_LABEL_NO_NETWORKS_FOUND, 0, 0, 0); #endif diff --git a/msg_hash.h b/msg_hash.h index c9c3f1c4aa..670926979b 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -862,6 +862,7 @@ enum msg_hash_enums MENU_LABEL(CONTENT_SETTINGS), MENU_LABEL(LOAD_CONTENT_LIST), MENU_LABEL(NO_SETTINGS_FOUND), + MENU_LABEL(NO_NETWORKS_FOUND), MENU_LABEL(NO_PERFORMANCE_COUNTERS), MENU_LABEL(FRAME_THROTTLE_SETTINGS), MENU_LABEL(FRAME_THROTTLE_ENABLE), From f41e420b446c3e2c1dd1e8903c2d4ffa6f0caeb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Thu, 1 Dec 2016 00:49:48 +0100 Subject: [PATCH 21/32] Unhardcode more strings --- intl/msg_hash_us.h | 4 ++++ msg_hash.h | 2 ++ tasks/task_wifi.c | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 396720b17c..1315f26510 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2241,3 +2241,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, "Database - Filter : Edge Magazine Rating") MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, "Database Info") +MSG_HASH(MSG_WIFI_SCAN_COMPLETE, + "Wi-Fi scan complete.") +MSG_HASH(MSG_SCANNING_WIRELESS_NETWORKS, + "Scanning wireless networks...") \ No newline at end of file diff --git a/msg_hash.h b/msg_hash.h index 670926979b..7d65595c13 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -278,6 +278,8 @@ enum msg_hash_enums MSG_MOVIE_RECORD_STOPPED, MSG_MOVIE_PLAYBACK_ENDED, MSG_TAKING_SCREENSHOT, + MSG_WIFI_SCAN_COMPLETE, + MSG_SCANNING_WIRELESS_NETWORKS, MSG_FAILED_TO_TAKE_SCREENSHOT, MSG_CUSTOM_TIMING_GIVEN, MSG_SAVING_STATE, diff --git a/tasks/task_wifi.c b/tasks/task_wifi.c index 5a661afa9a..387b5a65fb 100644 --- a/tasks/task_wifi.c +++ b/tasks/task_wifi.c @@ -75,7 +75,7 @@ static void task_wifi_scan_handler(retro_task_t *task) driver_wifi_scan(); task->progress = 100; - task->title = strdup("Wi-Fi scan complete"); + task->title = strdup(msg_hash_to_str(MSG_WIFI_SCAN_COMPLETE)); task->finished = true; return; @@ -96,7 +96,7 @@ bool task_push_wifi_scan(void) task->state = state; task->handler = task_wifi_scan_handler; task->callback = wifi_scan_callback; - task->title = strdup("Scanning wireless networks..."); + task->title = strdup(msg_hash_to_str(MSG_SCANNING_WIRELESS_NETWORKS)); task_queue_ctl(TASK_QUEUE_CTL_PUSH, task); From c7f8cd3c6873367e897f441d8f88c448f8aabd26 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Wed, 30 Nov 2016 19:01:32 -0500 Subject: [PATCH 22/32] Adding NAT traversal announcement for SOCKET_LEGACY --- network/netplay/netplay.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index a5916c249d..3ea2095969 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -1086,6 +1086,7 @@ static void announce_nat_traversal(netplay_t *netplay) { char msg[512], host[PATH_MAX_LENGTH], port[6]; +#ifndef HAVE_SOCKET_LEGACY if (netplay->nat_traversal_state.have_inet4) { if (getnameinfo((const struct sockaddr *) &netplay->nat_traversal_state.ext_inet4_addr, @@ -1106,6 +1107,22 @@ static void announce_nat_traversal(netplay_t *netplay) #endif else return; +#else + if (netplay->nat_traversal_state.have_inet4) + { + strncpy(host, + inet_ntoa(netplay->nat_traversal_state.ext_inet4_addr.sin_addr), + PATH_MAX_LENGTH); + host[PATH_MAX_LENGTH-1] = '\0'; + snprintf(port, 6, "%hu", + ntohs(netplay->nat_traversal_state.ext_inet4_addr.sin_port)); + port[5] = '\0'; + + } + else return; + +#endif + snprintf(msg, sizeof(msg), "%s: %s:%s\n", msg_hash_to_str(MSG_PUBLIC_ADDRESS), host, port); From 4ad1aa7eff46216e1f78a860fb2e1437e886ed69 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Wed, 30 Nov 2016 19:21:33 -0500 Subject: [PATCH 23/32] Don't double-free net_ifinfo structure. --- libretro-common/net/net_natt.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index 851f5e5a65..ffc871c131 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -175,10 +175,7 @@ bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_p if ((list = (struct net_ifinfo *) calloc(1, sizeof(struct net_ifinfo))) == NULL) return false; if (!net_ifinfo_new(list)) - { - free(list); return false; - } /* loop through them */ for (i = 0; i < list->size; i++) From a0ac7e6a683271b69f7734b36ac59fa19079b696 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Wed, 30 Nov 2016 19:57:18 -0500 Subject: [PATCH 24/32] Make net_ifinfo's allocation behavior simpler and clearer --- libretro-common/net/net_ifinfo.c | 5 ++++- libretro-common/net/net_natt.c | 13 +++++-------- libretro-common/samples/net/net_ifinfo_test.c | 14 +++++--------- menu/menu_displaylist.c | 14 +++++--------- 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/libretro-common/net/net_ifinfo.c b/libretro-common/net/net_ifinfo.c index b119d207ce..5432f5a73d 100644 --- a/libretro-common/net/net_ifinfo.c +++ b/libretro-common/net/net_ifinfo.c @@ -65,7 +65,6 @@ void net_ifinfo_free(net_ifinfo_t *list) ptr->host = NULL; } free(list->entries); - free(list); } bool net_ifinfo_new(net_ifinfo_t *list) @@ -82,6 +81,8 @@ bool net_ifinfo_new(net_ifinfo_t *list) rv = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adapter_addresses, &size); + memset(list, 0, sizeof(net_ifinfo_t)); + if (rv != ERROR_SUCCESS) goto error; @@ -122,6 +123,8 @@ bool net_ifinfo_new(net_ifinfo_t *list) struct ifaddrs *ifa = NULL; struct ifaddrs *ifaddr = NULL; + memset(list, 0, sizeof(net_ifinfo_t)); + if (getifaddrs(&ifaddr) == -1) goto error; diff --git a/libretro-common/net/net_natt.c b/libretro-common/net/net_natt.c index ffc871c131..f66d81205c 100644 --- a/libretro-common/net/net_natt.c +++ b/libretro-common/net/net_natt.c @@ -163,7 +163,7 @@ bool natt_open_port(struct natt_status *status, struct sockaddr *addr, socklen_t bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_protocol proto) { - struct net_ifinfo *list; + struct net_ifinfo list; bool ret = false; size_t i; struct addrinfo hints = {0}, *addr; @@ -172,15 +172,13 @@ bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_p sprintf(port_str, "%hu", port); /* get our interfaces */ - if ((list = (struct net_ifinfo *) calloc(1, sizeof(struct net_ifinfo))) == NULL) - return false; - if (!net_ifinfo_new(list)) + if (!net_ifinfo_new(&list)) return false; /* loop through them */ - for (i = 0; i < list->size; i++) + for (i = 0; i < list.size; i++) { - struct net_ifinfo_entry *entry = list->entries + i; + struct net_ifinfo_entry *entry = list.entries + i; /* ignore localhost */ if (!strcmp(entry->host, "127.0.0.1") || !strcmp(entry->host, "::1")) @@ -194,8 +192,7 @@ bool natt_open_port_any(struct natt_status *status, uint16_t port, enum socket_p } } - /* This really shouldn't free list, but does */ - net_ifinfo_free(list); + net_ifinfo_free(&list); return ret; } diff --git a/libretro-common/samples/net/net_ifinfo_test.c b/libretro-common/samples/net/net_ifinfo_test.c index 4ac96bcbe0..1b825b3093 100644 --- a/libretro-common/samples/net/net_ifinfo_test.c +++ b/libretro-common/samples/net/net_ifinfo_test.c @@ -29,21 +29,17 @@ int main(int argc, const char *argv[]) { unsigned k = 0; - net_ifinfo_t *list = - (net_ifinfo_t*)calloc(1, sizeof(*list)); + net_ifinfo_t list; - if (!list) + if (!net_ifinfo_new(&list)) return -1; - if (!net_ifinfo_new(list)) - return -1; - - for (k = 0; k < list->size; k++) + for (k = 0; k < list.size; k++) { - printf("%s:%s\n", list->entries[k].name, list->entries[k].host); + printf("%s:%s\n", list.entries[k].name, list.entries[k].host); } - net_ifinfo_free(list); + net_ifinfo_free(&list); return 0; } diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 52a373c9e4..5a8790bb4e 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -430,16 +430,12 @@ static int menu_displaylist_parse_core_info(menu_displaylist_info_t *info) static int menu_displaylist_parse_network_info(menu_displaylist_info_t *info) { unsigned k = 0; - net_ifinfo_t *list = - (net_ifinfo_t*)calloc(1, sizeof(*list)); + net_ifinfo_t list; - if (!list) + if (!net_ifinfo_new(&list)) return -1; - if (!net_ifinfo_new(list)) - return -1; - - for (k = 0; k < list->size; k++) + for (k = 0; k < list.size; k++) { char tmp[255]; @@ -447,12 +443,12 @@ static int menu_displaylist_parse_network_info(menu_displaylist_info_t *info) snprintf(tmp, sizeof(tmp), "%s (%s) : %s\n", msg_hash_to_str(MSG_INTERFACE), - list->entries[k].name, list->entries[k].host); + list.entries[k].name, list.entries[k].host); menu_entries_append_enum(info->list, tmp, "", MENU_ENUM_LABEL_NETWORK_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0); } - net_ifinfo_free(list); + net_ifinfo_free(&list); return 0; } #endif From 09aa219eb312c70770ba6cbf7b68507b4dcfc164 Mon Sep 17 00:00:00 2001 From: meleu Date: Wed, 30 Nov 2016 23:32:19 -0200 Subject: [PATCH 25/32] added menu_swap_ok_cancel Removed the deprecated `menu_ok_btn` and `menu_cancel_btn`. It's somehow related with this issue: https://github.com/libretro/RetroArch/issues/4111 --- retroarch.cfg | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/retroarch.cfg b/retroarch.cfg index d54ef28f6a..bd5f90b9f2 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -497,14 +497,15 @@ # input_player1_r3_btn = # Menu buttons. -# menu_ok_btn = -# menu_cancel_btn = # menu_search_btn = # menu_info_btn = # menu_default_btn = # menu_scroll_down_btn = # menu_scroll_up_btn = +# Swap buttons for OK/Cancel +# menu_swap_ok_cancel = false + # Axis for RetroArch D-Pad. # Needs to be either '+' or '-' in the first character signaling either positive or negative direction of the axis, then the axis number. # Do note that every other input option has the corresponding _btn and _axis binds as well; they are omitted here for clarity. From e6eeb8e5599cdd0ac3a24d80b61a667c7bd79c12 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 1 Dec 2016 02:23:10 +0100 Subject: [PATCH 26/32] Simplify check_input_driver_block_hotkey --- input/input_driver.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/input/input_driver.c b/input/input_driver.c index 17db604604..f23ba4f42a 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -539,12 +539,12 @@ static bool check_input_driver_block_hotkey(bool enable_hotkey) bool kb_mapping_is_blocked = current_input->keyboard_mapping_is_blocked && current_input->keyboard_mapping_is_blocked(current_input_data); + input_driver_block_hotkey = false; + /* Don't block the check to RARCH_ENABLE_HOTKEY * unless we're really supposed to. */ if (kb_mapping_is_blocked) input_driver_block_hotkey = true; - else - input_driver_block_hotkey = false; /* If we haven't bound anything to this, * always allow hotkeys. */ @@ -556,10 +556,8 @@ static bool check_input_driver_block_hotkey(bool enable_hotkey) || (autoconf_bind->joykey != NO_BTN) || (autoconf_bind->joyaxis != AXIS_NONE); - if (kb_mapping_is_blocked || (use_hotkey_enable && !enable_hotkey)) + if (use_hotkey_enable && !enable_hotkey) input_driver_block_hotkey = true; - else - input_driver_block_hotkey = false; /* If we hold ENABLE_HOTKEY button, block all libretro input to allow * hotkeys to be bound to same keys as RetroPad. */ From 5337e494c6b23bc7289431a5c5e7490edb757919 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 1 Dec 2016 03:01:21 +0100 Subject: [PATCH 27/32] More small cleanups --- input/input_driver.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/input/input_driver.c b/input/input_driver.c index f23ba4f42a..a9ef6981f5 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -561,7 +561,7 @@ static bool check_input_driver_block_hotkey(bool enable_hotkey) /* If we hold ENABLE_HOTKEY button, block all libretro input to allow * hotkeys to be bound to same keys as RetroPad. */ - return (use_hotkey_enable && enable_hotkey); + return use_hotkey_enable; } static const unsigned buttons[] = { @@ -678,14 +678,13 @@ static INLINE bool input_keys_pressed_internal(unsigned i, uint64_t input_keys_pressed(void) { unsigned i; - uint64_t ret = 0; - settings_t *settings = config_get_ptr(); + uint64_t ret = 0; + settings_t *settings = config_get_ptr(); const struct retro_keybind *binds = settings->input.binds[0]; + bool enable_hotkey = current_input->input_state(current_input_data, &binds, 0, + RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY); - if ( - check_input_driver_block_hotkey( - current_input->input_state(current_input_data, &binds, 0, - RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY))) + if (check_input_driver_block_hotkey(enable_hotkey) && enable_hotkey) input_driver_block_libretro_input = true; else input_driver_block_libretro_input = false; @@ -785,6 +784,7 @@ uint64_t input_menu_keys_pressed(void) { unsigned i; uint64_t ret = 0; + bool enable_hotkey = false; settings_t *settings = config_get_ptr(); const struct retro_keybind *binds[MAX_USERS] = {NULL}; @@ -795,10 +795,10 @@ uint64_t input_menu_keys_pressed(void) input_push_analog_dpad(settings->input.autoconf_binds[i], ANALOG_DPAD_LSTICK); - if ( - check_input_driver_block_hotkey( - current_input->input_state(current_input_data, &binds[0], 0, - RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY))) + enable_hotkey = current_input->input_state(current_input_data, &binds[0], 0, + RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY); + + if (check_input_driver_block_hotkey(enable_hotkey) && enable_hotkey) input_driver_block_libretro_input = true; else input_driver_block_libretro_input = false; From c351aed0017f76b707568e14ce6cbebaeff6fc76 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 1 Dec 2016 03:38:25 +0100 Subject: [PATCH 28/32] (input_driver.c) Cleanups --- input/input_driver.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/input/input_driver.c b/input/input_driver.c index a9ef6981f5..562c27e1de 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -536,14 +536,11 @@ static bool check_input_driver_block_hotkey(bool enable_hotkey) &settings->input.binds[0][RARCH_ENABLE_HOTKEY]; const struct retro_keybind *autoconf_bind = &settings->input.autoconf_binds[0][RARCH_ENABLE_HOTKEY]; - bool kb_mapping_is_blocked = current_input->keyboard_mapping_is_blocked && - current_input->keyboard_mapping_is_blocked(current_input_data); - - input_driver_block_hotkey = false; /* Don't block the check to RARCH_ENABLE_HOTKEY * unless we're really supposed to. */ - if (kb_mapping_is_blocked) + if (current_input->keyboard_mapping_is_blocked && + current_input->keyboard_mapping_is_blocked(current_input_data)) input_driver_block_hotkey = true; /* If we haven't bound anything to this, @@ -684,10 +681,11 @@ uint64_t input_keys_pressed(void) bool enable_hotkey = current_input->input_state(current_input_data, &binds, 0, RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY); + input_driver_block_libretro_input = false; + input_driver_block_hotkey = false; + if (check_input_driver_block_hotkey(enable_hotkey) && enable_hotkey) input_driver_block_libretro_input = true; - else - input_driver_block_libretro_input = false; for (i = 0; i < RARCH_BIND_LIST_END; i++) { @@ -798,11 +796,11 @@ uint64_t input_menu_keys_pressed(void) enable_hotkey = current_input->input_state(current_input_data, &binds[0], 0, RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY); + input_driver_block_libretro_input = false; + input_driver_block_hotkey = false; + if (check_input_driver_block_hotkey(enable_hotkey) && enable_hotkey) input_driver_block_libretro_input = true; - else - input_driver_block_libretro_input = false; - for (i = 0; i < RARCH_BIND_LIST_END; i++) { From bd53c330699862c500fc0830724caf88a85af0c9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 1 Dec 2016 03:43:51 +0100 Subject: [PATCH 29/32] Move input_get_auto_bind to input_config.c --- input/input_autodetect.c | 13 ------------- input/input_autodetect.h | 3 --- input/input_config.c | 13 +++++++++++++ input/input_config.h | 2 ++ menu/cbs/menu_cbs_get_value.c | 2 +- menu/widgets/menu_dialog.c | 2 +- setting_list.c | 2 +- 7 files changed, 18 insertions(+), 19 deletions(-) diff --git a/input/input_autodetect.c b/input/input_autodetect.c index 85a3bfa6b1..43cede3528 100644 --- a/input/input_autodetect.c +++ b/input/input_autodetect.c @@ -322,19 +322,6 @@ error: return false; } -const struct retro_keybind *input_get_auto_bind(unsigned port, unsigned id) -{ - settings_t *settings = config_get_ptr(); - unsigned joy_idx = 0; - - if (settings) - joy_idx = settings->input.joypad_map[port]; - - if (joy_idx < MAX_USERS) - return &settings->input.autoconf_binds[joy_idx][id]; - return NULL; -} - void input_config_autoconfigure_disconnect(unsigned i, const char *ident) { char msg[255]; diff --git a/input/input_autodetect.h b/input/input_autodetect.h index 542e525219..6e6bb9b912 100644 --- a/input/input_autodetect.h +++ b/input/input_autodetect.h @@ -32,9 +32,6 @@ typedef struct autoconfig_params int32_t pid; } autoconfig_params_t; -const struct retro_keybind *input_get_auto_bind(unsigned port, - unsigned id); - bool input_config_autoconfigure_joypad(autoconfig_params_t *params); void input_config_autoconfigure_disconnect(unsigned i, const char *ident); diff --git a/input/input_config.c b/input/input_config.c index b8f713422e..1f7f6531fd 100644 --- a/input/input_config.c +++ b/input/input_config.c @@ -470,3 +470,16 @@ void input_config_get_bind_string(char *buf, const struct retro_keybind *bind, strlcat(buf, keybuf, size); #endif } + +const struct retro_keybind *input_config_get_bind_auto(unsigned port, unsigned id) +{ + settings_t *settings = config_get_ptr(); + unsigned joy_idx = 0; + + if (settings) + joy_idx = settings->input.joypad_map[port]; + + if (joy_idx < MAX_USERS) + return &settings->input.autoconf_binds[joy_idx][id]; + return NULL; +} diff --git a/input/input_config.h b/input/input_config.h index 8822f30d5a..79dd7f8acb 100644 --- a/input/input_config.h +++ b/input/input_config.h @@ -69,4 +69,6 @@ void input_config_parse_joy_button(config_file_t *conf, const char *prefix, void input_config_parse_joy_axis(config_file_t *conf, const char *prefix, const char *axis, struct retro_keybind *bind); +const struct retro_keybind *input_config_get_bind_auto(unsigned port, unsigned id); + #endif diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index c1a11ce419..271a5977fb 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -475,7 +475,7 @@ static void menu_action_setting_disp_set_label_input_desc( keybind = (const struct retro_keybind*) &settings->input.binds[inp_desc_user][remap_id]; auto_bind = (const struct retro_keybind*) - input_get_auto_bind(inp_desc_user, remap_id); + input_config_get_bind_auto(inp_desc_user, remap_id); input_config_get_bind_string(descriptor, keybind, auto_bind, sizeof(descriptor)); diff --git a/menu/widgets/menu_dialog.c b/menu/widgets/menu_dialog.c index f272685156..19205dcbfb 100644 --- a/menu/widgets/menu_dialog.c +++ b/menu/widgets/menu_dialog.c @@ -111,7 +111,7 @@ int menu_dialog_iterate(char *s, size_t len, const char *label) &settings->input.binds[0][binds[i]]; const struct retro_keybind *auto_bind = (const struct retro_keybind*) - input_get_auto_bind(0, binds[i]); + input_config_get_bind_auto(0, binds[i]); input_config_get_bind_string(desc[i], keybind, auto_bind, sizeof(desc[i])); diff --git a/setting_list.c b/setting_list.c index 9949da39c1..97fcfca679 100644 --- a/setting_list.c +++ b/setting_list.c @@ -610,7 +610,7 @@ static void setting_get_string_representation_st_bind(void *data, index_offset = setting->index_offset; keybind = (const struct retro_keybind*)setting->value.target.keybind; auto_bind = (const struct retro_keybind*) - input_get_auto_bind(index_offset, keybind->id); + input_config_get_bind_auto(index_offset, keybind->id); input_config_get_bind_string(s, keybind, auto_bind, len); } From eee077fe3137731467cbc731751de9e45e2de927 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 1 Dec 2016 03:50:35 +0100 Subject: [PATCH 30/32] (udev) Simplify udev_joypad_handle_hotplug --- input/drivers_joypad/udev_joypad.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index bac6829b8d..df7660f927 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -420,18 +420,11 @@ static void udev_joypad_destroy(void) g_udev = NULL; } -static void udev_joypad_handle_hotplug(void) +static void udev_joypad_handle_hotplug(struct udev_device *dev) { - struct udev_device *dev = udev_monitor_receive_device(g_udev_mon); - const char *val; - const char *action; - const char *devnode; - if (!dev) - return; - - val = udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"); - action = udev_device_get_action(dev); - devnode = udev_device_get_devnode(dev); + const char *val = udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"); + const char *action = udev_device_get_action(dev); + const char *devnode = udev_device_get_devnode(dev); if (!val || !string_is_equal(val, "1") || !devnode) goto end; @@ -523,8 +516,13 @@ static bool udev_set_rumble(unsigned i, enum retro_rumble_effect effect, uint16_ static void udev_joypad_poll(void) { unsigned i; + while (udev_hotplug_available()) - udev_joypad_handle_hotplug(); + { + struct udev_device *dev = udev_monitor_receive_device(g_udev_mon); + if (dev) + udev_joypad_handle_hotplug(dev); + } for (i = 0; i < MAX_USERS; i++) udev_poll_pad(&udev_pads[i], i); From 468644e21346579a4b9617f8a50376f0d328399f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 1 Dec 2016 03:59:02 +0100 Subject: [PATCH 31/32] Simplify udev_hotplug_available and prevent implicit memset --- input/drivers_joypad/udev_joypad.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index df7660f927..c576f47a9b 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -160,15 +160,13 @@ static void udev_poll_pad(struct udev_joypad *pad, unsigned p) } } -static bool udev_hotplug_available(void) +static INLINE bool udev_hotplug_available(void) { - struct pollfd fds = {0}; + struct pollfd fds; - if (!g_udev_mon) - return false; - - fds.fd = udev_monitor_get_fd(g_udev_mon); - fds.events = POLLIN; + fds.fd = udev_monitor_get_fd(g_udev_mon); + fds.events = POLLIN; + fds.revents = 0; return (poll(&fds, 1, 0) == 1) && (fds.revents & POLLIN); } @@ -517,7 +515,7 @@ static void udev_joypad_poll(void) { unsigned i; - while (udev_hotplug_available()) + while (g_udev_mon && udev_hotplug_available()) { struct udev_device *dev = udev_monitor_receive_device(g_udev_mon); if (dev) From a726fc2d8e4caa369d22ad64ae4db3678921d741 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 1 Dec 2016 04:12:56 +0100 Subject: [PATCH 32/32] Further cleanups --- input/input_driver.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/input/input_driver.c b/input/input_driver.c index 562c27e1de..733c35348e 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -524,13 +524,11 @@ int16_t input_state(unsigned port, unsigned device, /** * check_input_driver_block_hotkey: - * @enable_hotkey : Is hotkey enable key enabled? * * Checks if 'hotkey enable' key is pressed. **/ -static bool check_input_driver_block_hotkey(bool enable_hotkey) +static bool check_input_driver_block_hotkey(void) { - bool use_hotkey_enable = false; settings_t *settings = config_get_ptr(); const struct retro_keybind *bind = &settings->input.binds[0][RARCH_ENABLE_HOTKEY]; @@ -545,7 +543,10 @@ static bool check_input_driver_block_hotkey(bool enable_hotkey) /* If we haven't bound anything to this, * always allow hotkeys. */ - use_hotkey_enable = + + /* If we hold ENABLE_HOTKEY button, block all libretro input to allow + * hotkeys to be bound to same keys as RetroPad. */ + return (bind->key != RETROK_UNKNOWN) || (bind->joykey != NO_BTN) || (bind->joyaxis != AXIS_NONE) @@ -553,12 +554,6 @@ static bool check_input_driver_block_hotkey(bool enable_hotkey) || (autoconf_bind->joykey != NO_BTN) || (autoconf_bind->joyaxis != AXIS_NONE); - if (use_hotkey_enable && !enable_hotkey) - input_driver_block_hotkey = true; - - /* If we hold ENABLE_HOTKEY button, block all libretro input to allow - * hotkeys to be bound to same keys as RetroPad. */ - return use_hotkey_enable; } static const unsigned buttons[] = { @@ -678,14 +673,18 @@ uint64_t input_keys_pressed(void) uint64_t ret = 0; settings_t *settings = config_get_ptr(); const struct retro_keybind *binds = settings->input.binds[0]; - bool enable_hotkey = current_input->input_state(current_input_data, &binds, 0, - RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY); input_driver_block_libretro_input = false; input_driver_block_hotkey = false; - if (check_input_driver_block_hotkey(enable_hotkey) && enable_hotkey) - input_driver_block_libretro_input = true; + if (check_input_driver_block_hotkey()) + { + if (current_input->input_state(current_input_data, &binds, 0, + RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY)) + input_driver_block_libretro_input = true; + else + input_driver_block_hotkey = true; + } for (i = 0; i < RARCH_BIND_LIST_END; i++) { @@ -782,7 +781,6 @@ uint64_t input_menu_keys_pressed(void) { unsigned i; uint64_t ret = 0; - bool enable_hotkey = false; settings_t *settings = config_get_ptr(); const struct retro_keybind *binds[MAX_USERS] = {NULL}; @@ -793,14 +791,17 @@ uint64_t input_menu_keys_pressed(void) input_push_analog_dpad(settings->input.autoconf_binds[i], ANALOG_DPAD_LSTICK); - enable_hotkey = current_input->input_state(current_input_data, &binds[0], 0, - RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY); - input_driver_block_libretro_input = false; input_driver_block_hotkey = false; - if (check_input_driver_block_hotkey(enable_hotkey) && enable_hotkey) - input_driver_block_libretro_input = true; + if (check_input_driver_block_hotkey()) + { + if (current_input->input_state(current_input_data, &binds[0], 0, + RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY)) + input_driver_block_libretro_input = true; + else + input_driver_block_hotkey = true; + } for (i = 0; i < RARCH_BIND_LIST_END; i++) {