ui: Add interface to configure socket networking

This commit is contained in:
Matt Borgerson 2020-03-30 00:18:33 -07:00
parent 8bfb9913ae
commit d31e10cc59
7 changed files with 283 additions and 1 deletions

View File

@ -115,6 +115,7 @@
#include "ui/xemu-settings.h"
#include "ui/xemu-notifications.h"
#include "ui/xemu-net.h"
#define MAX_VIRTIO_CONSOLES 1
@ -4381,6 +4382,14 @@ void qemu_init(int argc, char **argv, char **envp)
exit(1);
}
#ifdef XBOX
int xemu_net_enabled;
xemu_settings_get_bool(XEMU_SETTINGS_NETWORK_ENABLED, &xemu_net_enabled);
if (xemu_net_enabled) {
xemu_net_enable();
}
#endif
qemu_opts_foreach(qemu_find_opts("object"),
user_creatable_add_opts_foreach,
object_create_delayed, &error_fatal);

View File

@ -37,6 +37,7 @@ sdl.mo-objs := \
xemu-hud.o \
xemu-input.o \
xemu-monitor.o \
xemu-net.o \
xemu-settings.o \
xemu-shaders.o \

View File

@ -30,6 +30,7 @@
#include "xemu-monitor.h"
#include "xemu-version.h"
#include "xemu-data.h"
#include "xemu-net.h"
#include "imgui/imgui.h"
#include "imgui/examples/imgui_impl_sdl.h"
@ -95,6 +96,9 @@ static void ShowSettingsWindow(bool* p_open);
bool show_about_window = false;
static void ShowAboutWindow(bool* p_open);
bool show_network_window = false;
static void ShowNetworkWindow(bool* p_open);
bool show_demo_window = false;
float ui_scale = 1.0;
@ -244,7 +248,8 @@ static void ShowMainMenu()
{
if (ImGui::BeginMenu("Machine"))
{
ImGui::MenuItem("Input", NULL, &show_input_window);
ImGui::MenuItem("Input", NULL, &show_input_window);
ImGui::MenuItem("Network", NULL, &show_network_window);
ImGui::MenuItem("Settings", NULL, &show_settings_window);
ImGui::Separator();
if (ImGui::MenuItem(running ? "Pause" : "Run")) {
@ -526,6 +531,7 @@ void xemu_hud_render(SDL_Window *window)
if (show_settings_window) ShowSettingsWindow(&show_settings_window);
if (show_monitor_window) ShowMonitorConsole(&show_monitor_window);
if (show_about_window) ShowAboutWindow(&show_about_window);
if (show_network_window) ShowNetworkWindow(&show_network_window);
if (show_demo_window) ImGui::ShowDemoWindow(&show_demo_window);
if (notification.active) {
@ -1280,3 +1286,102 @@ static void ShowFirstBootWindow(bool* p_open)
static FirstBootWindow console;
console.Draw("First Boot", p_open);
}
struct NetworkWindow
{
char remote_addr[64];
char local_addr[64];
NetworkWindow()
{
const char *tmp;
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, &tmp);
strncpy(remote_addr, tmp, sizeof(remote_addr)-1);
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, &tmp);
strncpy(local_addr, tmp, sizeof(local_addr)-1);
}
~NetworkWindow()
{
}
void Draw(const char* title, bool* p_open)
{
ImVec2 size(400*ui_scale, 250*ui_scale);
ImGui::SetNextWindowSize(size, ImGuiCond_Appearing);
if (!ImGui::Begin(title, p_open, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
ImGui::End();
return;
}
bool is_enabled = xemu_net_is_enabled();
ImGui::TextWrapped(
"xemu socket networking works by sending and recieving packets over "
"UDP which encapsulate the network traffic that the machine would "
"send or recieve when connected to a Local Area Network (LAN)."
);
ImGui::Dummy(ImVec2(0, 5*ui_scale));
ImGui::Separator();
ImGui::Dummy(ImVec2(0, 5*ui_scale));
ImGui::Columns(2, "", false);
ImGui::SetColumnWidth(0, ImGui::GetWindowWidth()*0.33);
ImGuiInputTextFlags flg = 0;
if (is_enabled) {
flg |= ImGuiInputTextFlags_ReadOnly;
}
ImGui::Text("Remote Host");
ImGui::SameLine(); HelpMarker("The remote <IP address>:<Port> to forward packets to (e.g. 1.2.3.4:9368)");
ImGui::NextColumn();
float w = ImGui::GetColumnWidth()-10*ui_scale;
ImGui::SetNextItemWidth(w);
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
ImGui::InputText("###remote_host", remote_addr, sizeof(remote_addr), flg);
if (is_enabled) ImGui::PopStyleVar();
ImGui::NextColumn();
ImGui::Text("Local Host");
ImGui::SameLine(); HelpMarker("The local <IP address>:<Port> to recieve packets on (e.g. 0.0.0.0:9368)");
ImGui::NextColumn();
ImGui::SetNextItemWidth(w);
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
ImGui::InputText("###local_host", local_addr, sizeof(local_addr), flg);
if (is_enabled) ImGui::PopStyleVar();
ImGui::NextColumn();
ImGui::Columns(1);
ImGui::SetCursorPosY(ImGui::GetWindowHeight()-(10+20)*ui_scale);
ImGui::Text("Status: %sEnabled", is_enabled ? "" : "Not ");
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetWindowHeight()-(10+25)*ui_scale);
ImGui::SetCursorPosX(ImGui::GetWindowWidth()-(120+10)*ui_scale);
ImGui::SetItemDefaultFocus();
if (ImGui::Button(is_enabled ? "Disable" : "Enable", ImVec2(120*ui_scale, 0))) {
if (!is_enabled) {
xemu_settings_set_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, remote_addr);
xemu_settings_set_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, local_addr);
xemu_net_enable();
} else {
xemu_net_disable();
}
xemu_settings_set_bool(XEMU_SETTINGS_NETWORK_ENABLED, xemu_net_is_enabled());
xemu_settings_save();
}
ImGui::End();
}
};
static void ShowNetworkWindow(bool* p_open)
{
static NetworkWindow console;
console.Draw("Network", p_open);
}

118
ui/xemu-net.c Normal file
View File

@ -0,0 +1,118 @@
/*
* xemu Network Management
*
* Wrapper functions to configure network settings at runtime.
*
* Copyright (C) 2020 Matt Borgerson
*
* This program 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 Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "xemu-net.h"
#include "xemu-settings.h"
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "monitor/qdev.h"
#include "qapi/qmp/qdict.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "net/net.h"
#include "net/hub.h"
static const char *id = "xemu-netdev";
static const char *id_hubport = "xemu-netdev-hubport";
void xemu_net_enable(void)
{
Error *local_err = NULL;
NetClientState *nc = qemu_find_netdev(id);
if (nc != NULL) {
return;
}
const char *local_addr, *remote_addr;
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, &remote_addr);
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, &local_addr);
// Create the UDP netdev
QDict *qdict = qdict_new();
qdict_put_str(qdict, "id", id);
qdict_put_str(qdict, "type", "socket");
qdict_put_str(qdict, "udp", remote_addr);
qdict_put_str(qdict, "localaddr", local_addr);
QemuOpts *opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &error_abort);
qobject_unref(qdict);
netdev_add(opts, &local_err);
if (local_err) {
qemu_opts_del(opts);
error_report_err(local_err);
// error_propagate(errp, local_err);
return;
}
// Create the hubport
qdict = qdict_new();
qdict_put_str(qdict, "id", id_hubport);
qdict_put_str(qdict, "type", "hubport");
qdict_put_int(qdict, "hubid", 0);
qdict_put_str(qdict, "netdev", id);
opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &error_abort);
qobject_unref(qdict);
netdev_add(opts, &local_err);
if (local_err) {
qemu_opts_del(opts);
error_report_err(local_err);
// error_propagate(errp, local_err);
}
}
static void remove_netdev(const char *name)
{
NetClientState *nc;
QemuOpts *opts;
nc = qemu_find_netdev(name);
if (!nc) {
// error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
// "Device '%s' not found", name);
return;
}
opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), name);
if (!opts) {
// error_setg(errp, "Device '%s' is not a netdev", name);
return;
}
qemu_opts_del(opts);
qemu_del_net_client(nc);
}
void xemu_net_disable(void)
{
remove_netdev(id);
remove_netdev(id_hubport);
}
int xemu_net_is_enabled(void)
{
NetClientState *nc;
nc = qemu_find_netdev(id);
return (nc != NULL);
}

37
ui/xemu-net.h Normal file
View File

@ -0,0 +1,37 @@
/*
* xemu Network Management
*
* Wrapper functions to configure network settings at runtime.
*
* Copyright (C) 2020 Matt Borgerson
*
* This program 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 Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XEMU_NETWORK_H
#define XEMU_NETWORK_H
#ifdef __cplusplus
extern "C" {
#endif
void xemu_net_enable(void);
void xemu_net_disable(void);
int xemu_net_is_enabled(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -53,6 +53,11 @@ struct xemu_settings {
char *controller_2_guid;
char *controller_3_guid;
char *controller_4_guid;
// [network]
int net_enabled; // Boolean
char *net_local_addr;
char *net_remote_addr;
};
struct enum_str_map {
@ -95,6 +100,10 @@ struct config_offset_table {
[XEMU_SETTINGS_INPUT_CONTROLLER_2_GUID] = { CONFIG_TYPE_STRING, "input", "controller_2_guid", offsetof(struct xemu_settings, controller_2_guid), { .default_str = "" } },
[XEMU_SETTINGS_INPUT_CONTROLLER_3_GUID] = { CONFIG_TYPE_STRING, "input", "controller_3_guid", offsetof(struct xemu_settings, controller_3_guid), { .default_str = "" } },
[XEMU_SETTINGS_INPUT_CONTROLLER_4_GUID] = { CONFIG_TYPE_STRING, "input", "controller_4_guid", offsetof(struct xemu_settings, controller_4_guid), { .default_str = "" } },
[XEMU_SETTINGS_NETWORK_ENABLED] = { CONFIG_TYPE_BOOL, "network", "enabled", offsetof(struct xemu_settings, net_enabled), { .default_bool = 0 } },
[XEMU_SETTINGS_NETWORK_LOCAL_ADDR] = { CONFIG_TYPE_STRING, "network", "local_addr", offsetof(struct xemu_settings, net_local_addr), { .default_str = "0.0.0.0:9368" } },
[XEMU_SETTINGS_NETWORK_REMOTE_ADDR] = { CONFIG_TYPE_STRING, "network", "remote_addr", offsetof(struct xemu_settings, net_remote_addr), { .default_str = "1.2.3.4:9368" } },
};
static const char *settings_path;

View File

@ -42,6 +42,9 @@ enum xemu_settings_keys {
XEMU_SETTINGS_INPUT_CONTROLLER_2_GUID,
XEMU_SETTINGS_INPUT_CONTROLLER_3_GUID,
XEMU_SETTINGS_INPUT_CONTROLLER_4_GUID,
XEMU_SETTINGS_NETWORK_ENABLED,
XEMU_SETTINGS_NETWORK_LOCAL_ADDR,
XEMU_SETTINGS_NETWORK_REMOTE_ADDR,
XEMU_SETTINGS__COUNT,
XEMU_SETTINGS_INVALID = -1
};