Skip to content

Commit

Permalink
Refactor network implementations to be more reusable and less buggy (#…
Browse files Browse the repository at this point in the history
…2107)

encapsulate network interfaces
  • Loading branch information
JesseTG authored Aug 1, 2024
1 parent c6bf5d5 commit 327ce45
Show file tree
Hide file tree
Showing 20 changed files with 711 additions and 435 deletions.
1 change: 1 addition & 0 deletions src/Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ u16 MP_RecvReplies(u8* data, u64 timestamp, u16 aidmask, void* userdata);
// packet type: Ethernet (802.3)
int Net_SendPacket(u8* data, int len, void* userdata);
int Net_RecvPacket(u8* data, void* userdata);
using SendPacketCallback = std::function<void(const u8* data, int len)>;


// interface for camera emulation
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/qt_sdl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
9 changes: 5 additions & 4 deletions src/frontend/qt_sdl/EmuInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -97,7 +99,7 @@ EmuInstance::EmuInstance(int inst) : instanceID(inst),
audioInit();
inputInit();

Net::RegisterInstance(instanceID);
net.RegisterInstance(instanceID);

emuThread = new EmuThread(this);

Expand All @@ -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();
Expand Down
25 changes: 13 additions & 12 deletions src/frontend/qt_sdl/Platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
#endif // __WIN32__

extern CameraManager* camManager[2];

extern melonDS::LocalMP localMp;
extern melonDS::Net net;

namespace melonDS::Platform
{
Expand Down Expand Up @@ -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);
}


Expand Down
35 changes: 20 additions & 15 deletions src/frontend/qt_sdl/WifiSettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -51,22 +54,26 @@ 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)");

ui->lblAdapterMAC->setText("(none)");
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);
Expand Down Expand Up @@ -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);

Expand All @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/qt_sdl/WifiSettingsDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#define WIFISETTINGSDIALOG_H

#include <QDialog>
#include <vector>
#include "Net_PCap.h"

namespace Ui { class WifiSettingsDialog; }
class WifiSettingsDialog;
Expand Down Expand Up @@ -68,6 +70,7 @@ private slots:
bool haspcap;

void updateAdapterControls();
std::vector<melonDS::AdapterData> adapters;
};

#endif // WIFISETTINGSDIALOG_H
3 changes: 2 additions & 1 deletion src/frontend/qt_sdl/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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();
}
Expand Down
47 changes: 37 additions & 10 deletions src/frontend/qt_sdl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@

#include "CLI.h"

#include "Net_PCap.h"
#include "Net_Slirp.h"

using namespace melonDS;

QString* systemThemeName;
Expand All @@ -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()
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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];

Expand Down
1 change: 1 addition & 0 deletions src/net/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ if (USE_SYSTEM_LIBSLIRP)
target_link_libraries(net-utils PRIVATE PkgConfig::Slirp)
else()
add_subdirectory(libslirp EXCLUDE_FROM_ALL)
target_include_directories(net-utils SYSTEM PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/libslirp/glib")
target_link_libraries(net-utils PRIVATE slirp)
endif()
Loading

0 comments on commit 327ce45

Please sign in to comment.