Refactor network implementations to be more reusable and less buggy (#2107)

encapsulate network interfaces
This commit is contained in:
Jesse Talavera
2024-08-01 16:02:45 -04:00
committed by GitHub
parent c6bf5d5181
commit 327ce45124
20 changed files with 715 additions and 439 deletions

View File

@ -163,6 +163,10 @@ endif()
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..")
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../../net")
target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../../net/libslirp/src")
get_target_property(SLIRP_BINARY_DIR slirp BINARY_DIR)
target_include_directories(melonDS PUBLIC "${SLIRP_BINARY_DIR}") # for libslirp-version.h
if (USE_QT6)
target_include_directories(melonDS PUBLIC ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
else()

View File

@ -62,6 +62,8 @@ using namespace melonDS::Platform;
MainWindow* topWindow = nullptr;
const string kWifiSettingsPath = "wfcsettings.bin";
extern LocalMP localMp;
extern Net net;
EmuInstance::EmuInstance(int inst) : instanceID(inst),
@ -97,7 +99,7 @@ EmuInstance::EmuInstance(int inst) : instanceID(inst),
audioInit();
inputInit();
Net::RegisterInstance(instanceID);
net.RegisterInstance(instanceID);
emuThread = new EmuThread(this);
@ -116,14 +118,13 @@ EmuInstance::EmuInstance(int inst) : instanceID(inst),
EmuInstance::~EmuInstance()
{
// TODO window cleanup and shit?
LocalMP::End(instanceID);
localMp.End(instanceID);
emuThread->emuExit();
emuThread->wait();
delete emuThread;
Net::UnregisterInstance(instanceID);
net.UnregisterInstance(instanceID);
audioDeInit();
inputDeInit();

View File

@ -47,7 +47,8 @@
#endif // __WIN32__
extern CameraManager* camManager[2];
extern melonDS::LocalMP localMp;
extern melonDS::Net net;
namespace melonDS::Platform
{
@ -457,69 +458,69 @@ void WriteDateTime(int year, int month, int day, int hour, int minute, int secon
void MP_Begin(void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
LocalMP::Begin(inst);
localMp.Begin(inst);
}
void MP_End(void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
LocalMP::End(inst);
localMp.End(inst);
}
int MP_SendPacket(u8* data, int len, u64 timestamp, void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
return LocalMP::SendPacket(inst, data, len, timestamp);
return localMp.SendPacket(inst, data, len, timestamp);
}
int MP_RecvPacket(u8* data, u64* timestamp, void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
return LocalMP::RecvPacket(inst, data, timestamp);
return localMp.RecvPacket(inst, data, timestamp);
}
int MP_SendCmd(u8* data, int len, u64 timestamp, void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
return LocalMP::SendCmd(inst, data, len, timestamp);
return localMp.SendCmd(inst, data, len, timestamp);
}
int MP_SendReply(u8* data, int len, u64 timestamp, u16 aid, void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
return LocalMP::SendReply(inst, data, len, timestamp, aid);
return localMp.SendReply(inst, data, len, timestamp, aid);
}
int MP_SendAck(u8* data, int len, u64 timestamp, void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
return LocalMP::SendAck(inst, data, len, timestamp);
return localMp.SendAck(inst, data, len, timestamp);
}
int MP_RecvHostPacket(u8* data, u64* timestamp, void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
return LocalMP::RecvHostPacket(inst, data, timestamp);
return localMp.RecvHostPacket(inst, data, timestamp);
}
u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask, void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
return LocalMP::RecvReplies(inst, data, timestamp, aidmask);
return localMp.RecvReplies(inst, data, timestamp, aidmask);
}
int Net_SendPacket(u8* data, int len, void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
Net::SendPacket(data, len, inst);
net.SendPacket(data, len, inst);
return 0;
}
int Net_RecvPacket(u8* data, void* userdata)
{
int inst = ((EmuInstance*)userdata)->getInstanceID();
return Net::RecvPacket(data, inst);
return net.RecvPacket(data, inst);
}

View File

@ -37,11 +37,14 @@
#define PCAP_NAME "libpcap"
#endif
extern std::optional<melonDS::LibPCap> pcap;
extern melonDS::Net net;
WifiSettingsDialog* WifiSettingsDialog::currentDlg = nullptr;
bool WifiSettingsDialog::needsReset = false;
void NetInit();
WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::WifiSettingsDialog)
{
@ -51,8 +54,12 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne
emuInstance = ((MainWindow*)parent)->getEmuInstance();
auto& cfg = emuInstance->getGlobalConfig();
Net::DeInit();
haspcap = Net_PCap::InitAdapterList();
if (!pcap)
pcap = melonDS::LibPCap::New();
haspcap = pcap.has_value();
if (pcap)
adapters = pcap->GetAdapters();
ui->rbDirectMode->setText("Direct mode (requires " PCAP_NAME " and ethernet connection)");
@ -60,13 +67,13 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne
ui->lblAdapterIP->setText("(none)");
int sel = 0;
for (int i = 0; i < Net_PCap::NumAdapters; i++)
for (int i = 0; i < adapters.size(); i++)
{
Net_PCap::AdapterData* adapter = &Net_PCap::Adapters[i];
melonDS::AdapterData& adapter = adapters[i];
ui->cbxDirectAdapter->addItem(QString(adapter->FriendlyName));
ui->cbxDirectAdapter->addItem(QString(adapter.FriendlyName));
if (!strncmp(adapter->DeviceName, cfg.GetString("LAN.Device").c_str(), 128))
if (!strncmp(adapter.DeviceName, cfg.GetString("LAN.Device").c_str(), 128))
sel = i;
}
ui->cbxDirectAdapter->setCurrentIndex(sel);
@ -96,24 +103,23 @@ void WifiSettingsDialog::done(int r)
cfg.SetBool("LAN.DirectMode", ui->rbDirectMode->isChecked());
int sel = ui->cbxDirectAdapter->currentIndex();
if (sel < 0 || sel >= Net_PCap::NumAdapters) sel = 0;
if (Net_PCap::NumAdapters < 1)
if (sel < 0 || sel >= adapters.size()) sel = 0;
if (adapters.empty())
{
cfg.SetString("LAN.Device", "");
}
else
{
cfg.SetString("LAN.Device", Net_PCap::Adapters[sel].DeviceName);
cfg.SetString("LAN.Device", adapters[sel].DeviceName);
}
Config::Save();
}
Net_PCap::DeInit();
Config::Table cfg = Config::GetGlobalTable();
bool direct = cfg.GetBool("LAN.DirectMode");
std::string devicename = cfg.GetString("LAN.Device");
Net::Init(direct, devicename.c_str());
NetInit();
QDialog::done(r);
@ -134,10 +140,9 @@ void WifiSettingsDialog::on_cbxDirectAdapter_currentIndexChanged(int sel)
{
if (!haspcap) return;
if (sel < 0 || sel >= Net_PCap::NumAdapters) return;
if (Net_PCap::NumAdapters < 1) return;
if (sel < 0 || sel >= adapters.size() || adapters.empty()) return;
Net_PCap::AdapterData* adapter = &Net_PCap::Adapters[sel];
melonDS::AdapterData* adapter = &adapters[sel];
char tmp[64];
sprintf(tmp, "%02X:%02X:%02X:%02X:%02X:%02X",

View File

@ -20,6 +20,8 @@
#define WIFISETTINGSDIALOG_H
#include <QDialog>
#include <vector>
#include "Net_PCap.h"
namespace Ui { class WifiSettingsDialog; }
class WifiSettingsDialog;
@ -68,6 +70,7 @@ private:
bool haspcap;
void updateAdapterControls();
std::vector<melonDS::AdapterData> adapters;
};
#endif // WIFISETTINGSDIALOG_H

View File

@ -87,6 +87,7 @@ using namespace melonDS;
extern CameraManager* camManager[2];
extern bool camStarted[2];
extern LocalMP localMp;
QString NdsRomMimeType = "application/x-nintendo-ds-rom";
@ -1832,7 +1833,7 @@ void MainWindow::onMPSettingsFinished(int res)
{
emuInstance->mpAudioMode = globalCfg.GetInt("MP.AudioMode");
emuInstance->audioMute();
LocalMP::SetRecvTimeout(globalCfg.GetInt("MP.RecvTimeout"));
localMp.SetRecvTimeout(globalCfg.GetInt("MP.RecvTimeout"));
emuThread->emuUnpause();
}

View File

@ -79,6 +79,9 @@
#include "CLI.h"
#include "Net_PCap.h"
#include "Net_Slirp.h"
using namespace melonDS;
QString* systemThemeName;
@ -92,6 +95,38 @@ EmuInstance* emuInstances[kMaxEmuInstances];
CameraManager* camManager[2];
bool camStarted[2];
LocalMP localMp;
std::optional<LibPCap> pcap;
Net net;
void NetInit()
{
Config::Table cfg = Config::GetGlobalTable();
if (cfg.GetBool("LAN.DirectMode"))
{
if (!pcap)
pcap = LibPCap::New();
if (pcap)
{
std::string devicename = cfg.GetString("LAN.Device");
std::unique_ptr<Net_PCap> netPcap = pcap->Open(devicename, [](const u8* data, int len) {
net.RXEnqueue(data, len);
});
if (netPcap)
{
net.SetDriver(std::move(netPcap));
}
}
}
else
{
net.SetDriver(std::make_unique<Net_Slirp>([](const u8* data, int len) {
net.RXEnqueue(data, len);
}));
}
}
bool createEmuInstance()
@ -273,13 +308,8 @@ int main(int argc, char** argv)
}
}
LocalMP::Init();
{
Config::Table cfg = Config::GetGlobalTable();
bool direct = cfg.GetBool("LAN.DirectMode");
std::string devicename = cfg.GetString("LAN.Device");
Net::Init(direct, devicename.c_str());
}
// localMp is initialized at this point
NetInit();
createEmuInstance();
@ -316,9 +346,6 @@ int main(int argc, char** argv)
// but with this we make extra sure they are all deleted
deleteAllEmuInstances();
LocalMP::DeInit();
Net::DeInit();
delete camManager[0];
delete camManager[1];