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 1/2] 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 2/2] 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];