Moved all Wi-Fi configuration from launcher to rg_gui

More apps might want to use wifi.

The file server remains in the launcher for now. But it could make sense to move it to retro-go at some point.

Big part of the new code in rg_gui is copy pasted from the launcher and needs some cleanup...
This commit is contained in:
Alex Duchesne 2024-08-29 22:00:48 -04:00
parent a6406d5d3e
commit 3d3cbb0ff9
11 changed files with 194 additions and 213 deletions

View File

@ -36,10 +36,11 @@ static struct
bool initialized;
} gui;
static const char *SETTING_FONTTYPE = "FontType";
static const char *SETTING_CLOCK = "Clock";
static const char *SETTING_THEME = "Theme";
#define SETTING_FONTTYPE "FontType"
#define SETTING_CLOCK "Clock"
#define SETTING_THEME "Theme"
#define SETTING_WIFI_ENABLE "Enable"
#define SETTING_WIFI_SLOT "Slot"
static uint16_t *get_draw_buffer(int width, int height, rg_color_t fill_color)
{
@ -1349,6 +1350,135 @@ static rg_gui_event_t border_update_cb(rg_gui_option_t *option, rg_gui_event_t e
return RG_DIALOG_VOID;
}
#ifdef RG_ENABLE_NETWORKING
static void wifi_toggle_interactive(bool enable, int slot)
{
rg_network_state_t target_state = enable ? RG_NETWORK_CONNECTED : RG_NETWORK_DISCONNECTED;
int64_t timeout = rg_system_timer() + 20 * 1000000;
rg_gui_draw_message(enable ? "Connecting..." : "Disconnecting...");
rg_network_wifi_stop();
if (enable)
{
rg_wifi_config_t config = {0};
rg_network_wifi_read_config(slot, &config);
rg_network_wifi_set_config(&config);
if (slot == 9000)
{
const rg_wifi_config_t config = {
.ssid = "retro-go",
.password = "retro-go",
.channel = 6,
.ap_mode = true,
};
rg_network_wifi_set_config(&config);
}
if (!rg_network_wifi_start())
return;
}
do // Always loop at least once, in case we're in a transition
{
rg_task_delay(100);
if (rg_system_timer() > timeout)
break;
if (rg_input_read_gamepad())
break;
} while (rg_network_get_info().state != target_state);
}
static rg_gui_event_t wifi_status_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
rg_network_t info = rg_network_get_info();
if (info.state != RG_NETWORK_CONNECTED)
strcpy(option->value, "Not connected");
else if (option->arg == 0x10)
strcpy(option->value, info.name);
else if (option->arg == 0x11)
strcpy(option->value, info.ip_addr);
return RG_DIALOG_VOID;
}
static rg_gui_event_t wifi_profile_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
int slot = rg_settings_get_number(NS_WIFI, SETTING_WIFI_SLOT, -1);
char labels[5][40] = {0};
for (size_t i = 0; i < 5; i++)
{
rg_wifi_config_t config;
strncpy(labels[i], rg_network_wifi_read_config(i, &config) ? config.ssid : "(empty)", 32);
}
if (event == RG_DIALOG_ENTER)
{
const rg_gui_option_t options[] = {
{0, "0", labels[0], RG_DIALOG_FLAG_NORMAL, NULL},
{1, "1", labels[1], RG_DIALOG_FLAG_NORMAL, NULL},
{2, "2", labels[2], RG_DIALOG_FLAG_NORMAL, NULL},
{3, "3", labels[3], RG_DIALOG_FLAG_NORMAL, NULL},
{4, "4", labels[4], RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END,
};
int sel = rg_gui_dialog("Wi-Fi Profile", options, slot);
if (sel != RG_DIALOG_CANCELLED)
{
rg_settings_set_number(NS_WIFI, SETTING_WIFI_ENABLE, 1);
rg_settings_set_number(NS_WIFI, SETTING_WIFI_SLOT, sel);
wifi_toggle_interactive(true, sel);
}
return RG_DIALOG_REDRAW;
}
if (slot >= 0 && slot < RG_COUNT(labels))
sprintf(option->value, "%d - %s", slot, labels[slot]);
else
strcpy(option->value, "none");
return RG_DIALOG_VOID;
}
static rg_gui_event_t wifi_access_point_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
if (event == RG_DIALOG_ENTER)
{
if (rg_gui_confirm("Wi-Fi AP", "Start access point?\n\nSSID: retro-go\nPassword: retro-go\n\nBrowse: http://192.168.4.1/", true))
{
wifi_toggle_interactive(true, 9000);
}
return RG_DIALOG_REDRAW;
}
return RG_DIALOG_VOID;
}
static rg_gui_event_t wifi_enable_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
bool enabled = rg_settings_get_number(NS_WIFI, SETTING_WIFI_ENABLE, false);
if (event == RG_DIALOG_PREV || event == RG_DIALOG_NEXT || event == RG_DIALOG_ENTER)
{
enabled = !enabled;
rg_settings_set_number(NS_WIFI, SETTING_WIFI_ENABLE, enabled);
wifi_toggle_interactive(enabled, rg_settings_get_number(NS_WIFI, SETTING_WIFI_SLOT, -1));
return RG_DIALOG_REDRAW;
}
strcpy(option->value, enabled ? "On " : "Off");
return RG_DIALOG_VOID;
}
static rg_gui_event_t wifi_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
if (event == RG_DIALOG_ENTER)
{
const rg_gui_option_t options[] = {
{0x00, "Wi-Fi enable ", "-", RG_DIALOG_FLAG_NORMAL, &wifi_enable_cb },
{0x01, "Wi-Fi profile", "-", RG_DIALOG_FLAG_NORMAL, &wifi_profile_cb },
RG_DIALOG_SEPARATOR,
{0x02, "Wi-Fi access point", NULL, RG_DIALOG_FLAG_NORMAL, &wifi_access_point_cb},
RG_DIALOG_SEPARATOR,
{0x10, "Network ", "-", RG_DIALOG_FLAG_MESSAGE, &wifi_status_cb },
{0x11, "IP address", "-", RG_DIALOG_FLAG_MESSAGE, &wifi_status_cb },
RG_DIALOG_END,
};
rg_gui_dialog("Wifi Options", options, 0);
}
return RG_DIALOG_VOID;
}
#endif
void rg_gui_options_menu(void)
{
const rg_app_t *app = rg_system_get_app();
@ -1370,6 +1500,9 @@ void rg_gui_options_menu(void)
*opt++ = (rg_gui_option_t){0, "Timezone ", "-", RG_DIALOG_FLAG_NORMAL, &timezone_cb};
#ifdef RG_GPIO_LED // Only show disk LED option if disk LED GPIO pin is defined
*opt++ = (rg_gui_option_t){0, "LED options", NULL, RG_DIALOG_FLAG_NORMAL, &led_indicator_cb};
#endif
#ifdef RG_ENABLE_NETWORKING
*opt++ = (rg_gui_option_t){0, "Wi-Fi options", NULL, RG_DIALOG_FLAG_NORMAL, &wifi_cb};
#endif
}
// App settings that are shown only inside a game

View File

@ -11,6 +11,13 @@
goto fail; \
}
#define SETTING_WIFI_ENABLE "Enable"
#define SETTING_WIFI_SLOT "Slot"
#define SETTING_WIFI_SSID "ssid"
#define SETTING_WIFI_PASSWORD "password"
#define SETTING_WIFI_CHANNEL "channel"
#define SETTING_WIFI_MODE "mode"
#ifdef RG_ENABLE_NETWORKING
#include <esp_idf_version.h>
#include <esp_http_client.h>
@ -33,12 +40,6 @@ static rg_network_t network = {0};
static rg_wifi_config_t wifi_config = {0};
static bool initialized = false;
static const char *SETTING_WIFI_SSID = "ssid";
static const char *SETTING_WIFI_PASSWORD = "password";
static const char *SETTING_WIFI_CHANNEL = "channel";
static const char *SETTING_WIFI_MODE = "mode";
static const char *SETTING_WIFI_SLOT = "slot";
static void network_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT)
@ -105,22 +106,21 @@ static void network_event_handler(void *arg, esp_event_base_t event_base, int32_
}
#endif
bool rg_network_wifi_load_config(int slot)
bool rg_network_wifi_read_config(int slot, rg_wifi_config_t *out)
{
#ifdef RG_ENABLE_NETWORKING
char key_ssid[16], key_password[16], key_channel[16], key_mode[16];
if (slot < 0 || slot > 9)
if (slot < 0 || slot > 99)
return false;
char key_ssid[16], key_password[16], key_channel[16], key_mode[16];
rg_wifi_config_t config = {0};
char *ptr;
snprintf(key_ssid, 16, "%s%d", SETTING_WIFI_SSID, slot);
snprintf(key_password, 16, "%s%d", SETTING_WIFI_PASSWORD, slot);
snprintf(key_channel, 16, "%s%d", SETTING_WIFI_CHANNEL, slot);
snprintf(key_mode, 16, "%s%d", SETTING_WIFI_MODE, slot);
RG_LOGI("Looking for '%s' (slot %d)\n", key_ssid, slot);
rg_wifi_config_t config = {0};
char *ptr;
RG_LOGD("Looking for '%s' (slot %d)\n", key_ssid, slot);
if ((ptr = rg_settings_get_string(NS_WIFI, key_ssid, NULL)))
memccpy(config.ssid, ptr, 0, 32), free(ptr);
@ -142,17 +142,17 @@ bool rg_network_wifi_load_config(int slot)
if (!config.ssid[0])
return false;
return rg_network_wifi_set_config(&config);
#else
return false;
#endif
*out = config;
return true;
}
bool rg_network_wifi_set_config(const rg_wifi_config_t *config)
{
#ifdef RG_ENABLE_NETWORKING
RG_ASSERT_ARG(config != NULL);
wifi_config = *config;
if (config)
memcpy(&wifi_config, config, sizeof(wifi_config));
else
memset(&wifi_config, 0, sizeof(wifi_config));
return true;
#else
return false;
@ -234,6 +234,8 @@ bool rg_network_init(void)
if (initialized)
return true;
initialized = true;
// Init event loop first
esp_err_t err;
TRY(esp_event_loop_create_default());
@ -262,11 +264,14 @@ bool rg_network_init(void)
// Tell rg_network_get_info() that we're enabled but not yet connected
network.state = RG_NETWORK_DISCONNECTED;
// We try loading the specified slot (if any)
// Load the user's chosen config profile, if any
int slot = rg_settings_get_number(NS_WIFI, SETTING_WIFI_SLOT, 0);
rg_network_wifi_load_config(slot);
rg_network_wifi_read_config(slot, &wifi_config);
// Auto-start?
if (rg_settings_get_number(NS_WIFI, SETTING_WIFI_ENABLE, false))
rg_network_wifi_start();
initialized = true;
return true;
fail:
#else

View File

@ -24,7 +24,7 @@ typedef enum
typedef struct
{
char name[33];
char name[36];
char ip_addr[16];
int channel, rssi;
int state;
@ -33,7 +33,7 @@ typedef struct
bool rg_network_init(void);
void rg_network_deinit(void);
bool rg_network_wifi_set_config(const rg_wifi_config_t *config);
bool rg_network_wifi_load_config(int slot);
bool rg_network_wifi_read_config(int slot, rg_wifi_config_t *out);
bool rg_network_wifi_start(void);
void rg_network_wifi_stop(void);
rg_network_t rg_network_get_info(void);

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.5)
set(COMPONENTS "main retro-go fmsx app_trace bootloader esptool_py")
set(RG_ENABLE_NETWORKING 0)
include(../base.cmake)
project(fmsx)

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.5)
set(COMPONENTS "main retro-go gwenesis app_trace bootloader esptool_py")
set(RG_ENABLE_NETWORKING 0)
include(../base.cmake)
project(gwenesis)

View File

@ -21,7 +21,6 @@ retro_gui_t gui;
#define SETTING_SCROLL_MODE "ScrollMode"
#define SETTING_HIDDEN_TABS "HiddenTabs"
#define SETTING_HIDE_TAB(name) strcat((char[99]){"HideTab."}, (name))
#define SETTING_WIFI_ENABLE "Enable"
static int max_visible_lines(const tab_t *tab, int *_line_height)
{

View File

@ -12,12 +12,13 @@
#include "applications.h"
#include "bookmarks.h"
#include "gui.h"
#include "wifi.h"
#include "webui.h"
#include "updater.h"
static rg_app_t *app;
#define SETTING_WEBUI "HTTPFileServer"
static rg_gui_event_t toggle_tab_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
tab_t *tab = gui.tabs[option->arg];
@ -160,16 +161,6 @@ static rg_gui_event_t launcher_options_cb(rg_gui_option_t *option, rg_gui_event_
}
#ifdef RG_ENABLE_NETWORKING
static rg_gui_event_t wifi_options_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
if (event == RG_DIALOG_ENTER)
{
wifi_show_dialog();
return RG_DIALOG_REDRAW;
}
return RG_DIALOG_VOID;
}
static rg_gui_event_t updater_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
if (rg_network_get_info().state != RG_NETWORK_CONNECTED)
@ -184,6 +175,21 @@ static rg_gui_event_t updater_cb(rg_gui_option_t *option, rg_gui_event_t event)
}
return RG_DIALOG_VOID;
}
static rg_gui_event_t webui_switch_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
bool enabled = rg_settings_get_number(NS_APP, SETTING_WEBUI, 0);
if (event == RG_DIALOG_PREV || event == RG_DIALOG_NEXT || event == RG_DIALOG_ENTER)
{
enabled = !enabled;
webui_stop();
if (enabled)
webui_start();
rg_settings_set_number(NS_APP, SETTING_WEBUI, enabled);
}
strcpy(option->value, enabled ? "On " : "Off");
return RG_DIALOG_VOID;
}
#endif
static rg_gui_event_t prebuild_cache_cb(rg_gui_option_t *option, rg_gui_event_t event)
@ -227,7 +233,9 @@ static void retro_loop(void)
bookmarks_init();
#ifdef RG_ENABLE_NETWORKING
wifi_init();
rg_network_init();
if (rg_settings_get_number(NS_APP, SETTING_WEBUI, true))
webui_start();
#endif
if (!gui_get_current_tab())
@ -424,11 +432,11 @@ void app_main(void)
.event = &event_handler,
};
const rg_gui_option_t options[] = {
#ifdef RG_ENABLE_NETWORKING
{0, "File server" , "-", RG_DIALOG_FLAG_NORMAL, &webui_switch_cb},
#endif
{0, "Startup app ", "...", 1, &startup_app_cb},
{0, "Launcher options", NULL, 1, &launcher_options_cb},
#ifdef RG_ENABLE_NETWORKING
{0, "Wi-Fi options", NULL, 1, &wifi_options_cb},
#endif
RG_DIALOG_END,
};

View File

@ -1,166 +0,0 @@
#include "rg_system.h"
#include "gui.h"
#include "webui.h"
#include "wifi.h"
#ifdef RG_ENABLE_NETWORKING
#include <malloc.h>
#include <string.h>
#include <stdio.h>
static bool wifi_enable = false;
static bool webui_enable = false;
static const char *SETTING_WIFI_ENABLE = "Enable";
static const char *SETTING_WIFI_SLOT = "Slot";
static const char *SETTING_WEBUI = "HTTPFileServer";
static const size_t MAX_AP_LIST = 5;
static void wifi_toggle(bool enable)
{
if (wifi_enable)
rg_network_wifi_stop();
if (enable)
rg_network_wifi_start();
if (webui_enable && enable)
webui_start();
wifi_enable = enable;
}
static void webui_toggle(bool enable)
{
if (webui_enable)
webui_stop();
if (wifi_enable && enable)
webui_start();
webui_enable = enable;
}
static void wifi_toggle_interactive(bool enable)
{
rg_network_state_t target_state = enable ? RG_NETWORK_CONNECTED : RG_NETWORK_DISCONNECTED;
int64_t timeout = rg_system_timer() + 20 * 1000000;
rg_gui_draw_message(enable ? "Connecting..." : "Disconnecting...");
wifi_toggle(enable);
do // Always loop at least once, in case we're in a transition
{
rg_task_delay(100);
if (rg_system_timer() > timeout)
break;
if (rg_input_read_gamepad())
break;
} while (rg_network_get_info().state != target_state);
}
static rg_gui_event_t wifi_switch_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
if (event == RG_DIALOG_PREV || event == RG_DIALOG_NEXT || event == RG_DIALOG_ENTER)
{
wifi_toggle_interactive(!wifi_enable);
rg_settings_set_number(NS_WIFI, SETTING_WIFI_ENABLE, wifi_enable);
return RG_DIALOG_REDRAW;
}
strcpy(option->value, wifi_enable ? "On " : "Off");
return RG_DIALOG_VOID;
}
static rg_gui_event_t webui_switch_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
if (event == RG_DIALOG_PREV || event == RG_DIALOG_NEXT || event == RG_DIALOG_ENTER)
{
webui_toggle(!webui_enable);
rg_settings_set_number(NS_APP, SETTING_WEBUI, webui_enable);
}
strcpy(option->value, webui_enable ? "On " : "Off");
return RG_DIALOG_VOID;
}
static rg_gui_event_t wifi_select_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
if (event == RG_DIALOG_ENTER)
{
rg_gui_option_t options[MAX_AP_LIST + 2];
rg_gui_option_t *opt = options;
for (size_t i = 0; i < MAX_AP_LIST; i++)
{
char slot[6];
sprintf(slot, "ssid%d", i);
char *ap_name = rg_settings_get_string(NS_WIFI, slot, NULL);
*opt++ = (rg_gui_option_t){i, ap_name ?: "(empty)", NULL, ap_name ? 1 : 0, NULL};
}
char *ap_name = rg_settings_get_string(NS_WIFI, "ssid", NULL);
*opt++ = (rg_gui_option_t){-1, ap_name ?: "(empty)", NULL, ap_name ? 1 : 0, NULL};
*opt++ = (rg_gui_option_t)RG_DIALOG_END;
int sel = rg_gui_dialog("Select saved AP", options, rg_settings_get_number(NS_WIFI, SETTING_WIFI_SLOT, 0));
if (sel != RG_DIALOG_CANCELLED)
{
rg_settings_set_number(NS_WIFI, SETTING_WIFI_ENABLE, true);
rg_settings_set_number(NS_WIFI, SETTING_WIFI_SLOT, sel);
rg_network_wifi_stop();
rg_network_wifi_load_config(sel);
wifi_toggle_interactive(true);
}
return RG_DIALOG_REDRAW;
}
return RG_DIALOG_VOID;
}
static rg_gui_event_t wifi_access_point_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
if (event == RG_DIALOG_ENTER)
{
if (rg_gui_confirm("Wi-Fi AP", "Start access point?\n\nSSID: retro-go\nPassword: retro-go\n\nBrowse: http://192.168.4.1/", true))
{
rg_network_wifi_stop();
rg_network_wifi_set_config(&(const rg_wifi_config_t){
.ssid = "retro-go",
.password = "retro-go",
.channel = 6,
.ap_mode = true,
});
wifi_toggle_interactive(true);
}
return RG_DIALOG_REDRAW;
}
return RG_DIALOG_VOID;
}
static rg_gui_event_t wifi_status_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
rg_network_t info = rg_network_get_info();
if (info.state != RG_NETWORK_CONNECTED)
strcpy(option->value, "Not connected");
else if (option->arg == 1)
strcpy(option->value, info.name);
else if (option->arg == 2)
strcpy(option->value, info.ip_addr);
return RG_DIALOG_VOID;
}
void wifi_show_dialog(void)
{
const rg_gui_option_t options[] = {
{0, "Wi-Fi ", "-", RG_DIALOG_FLAG_NORMAL, &wifi_switch_cb},
{0, "Wi-Fi select", "-", RG_DIALOG_FLAG_NORMAL, &wifi_select_cb},
{0, "Wi-Fi Access Point", NULL, RG_DIALOG_FLAG_NORMAL, &wifi_access_point_cb},
RG_DIALOG_SEPARATOR,
{0, "File server" , "-", RG_DIALOG_FLAG_NORMAL, &webui_switch_cb},
{0, "Time sync " , "On", RG_DIALOG_FLAG_DISABLED, NULL},
RG_DIALOG_SEPARATOR,
{1, "Network " , "-", RG_DIALOG_FLAG_MESSAGE, &wifi_status_cb},
{2, "IP address" , "-", RG_DIALOG_FLAG_MESSAGE, &wifi_status_cb},
RG_DIALOG_END,
};
gui_redraw(); // clear main menu
rg_gui_dialog("Wifi Options", options, 0);
}
void wifi_init(void)
{
rg_network_init();
wifi_toggle(rg_settings_get_number(NS_WIFI, SETTING_WIFI_ENABLE, false));
webui_toggle(rg_settings_get_number(NS_APP, SETTING_WEBUI, true));
}
#endif

View File

@ -1,2 +0,0 @@
void wifi_show_dialog(void);
void wifi_init(void);

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.5)
set(COMPONENTS "main retro-go prboom bootloader esptool_py")
set(RG_ENABLE_NETWORKING 0)
include(../base.cmake)
project(prboom-go)

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.5)
set(COMPONENTS "main retro-go nofrendo gnuboy pce-go gw-emulator handy smsplus snes9x app_trace bootloader esptool_py")
set(RG_ENABLE_NETWORKING 0)
include(../base.cmake)
project(retro-core)