diff --git a/Makefile.common b/Makefile.common index 2980615ee3..2fdc341072 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1088,7 +1088,8 @@ ifeq ($(HAVE_NETWORKING), 1) $(LIBRETRO_COMM_DIR)/net/net_socket.o \ $(LIBRETRO_COMM_DIR)/net/net_natt.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 c180123bb3..b5fa679d16 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -70,6 +70,7 @@ #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 +4894,31 @@ 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); - for (i = 0; i < ssid_list->size; i++) + if (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 < ssid_list->size; i++) + { + const char *ssid = 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/tasks/task_wifi.c b/tasks/task_wifi.c new file mode 100644 index 0000000000..ec2b83e616 --- /dev/null +++ b/tasks/task_wifi.c @@ -0,0 +1,113 @@ +/* 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; + + menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL); + + /* Don't push the results if we left the wifi menu */ + if (!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); + + struct string_list *ssid_list = string_list_new(); + driver_wifi_get_ssids(ssid_list); + + unsigned i; + for (i = 0; i < ssid_list->size; i++) + { + const char *ssid = 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) +{ + 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; + + 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, 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];