diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp index 81627080..76cfe77d 100644 --- a/src/DSi_NWifi.cpp +++ b/src/DSi_NWifi.cpp @@ -1443,19 +1443,25 @@ void DSi_NWifi::CheckRX() return; int rxlen = Platform::LAN_RecvPacket(LANBuffer, DSi.UserData); - if (rxlen > 0) + while (rxlen > 0) { //printf("WMI packet recv %04X %04X %04X\n", *(u16*)&LANBuffer[0], *(u16*)&LANBuffer[2], *(u16*)&LANBuffer[4]); // check destination MAC if (*(u32*)&LANBuffer[0] != 0xFFFFFFFF || *(u16*)&LANBuffer[4] != 0xFFFF) { if (memcmp(&LANBuffer[0], &EEPROM[0x00A], 6)) - return; + { + rxlen = Platform::LAN_RecvPacket(LANBuffer, DSi.UserData); + continue; + } } // check source MAC, in case we get a packet we just sent out if (!memcmp(&LANBuffer[6], &EEPROM[0x00A], 6)) - return; + { + rxlen = Platform::LAN_RecvPacket(LANBuffer, DSi.UserData); + continue; + } // packet is good diff --git a/src/WifiAP.cpp b/src/WifiAP.cpp index 8d26f81b..a782b323 100644 --- a/src/WifiAP.cpp +++ b/src/WifiAP.cpp @@ -369,13 +369,22 @@ int WifiAP::RecvPacket(u8* data) if (ClientStatus < 2) return 0; int rxlen = Platform::LAN_RecvPacket(LANBuffer, UserData); - if (rxlen > 0) + while (rxlen > 0) { // check destination MAC if (!MACIsBroadcast(&LANBuffer[0])) { if (!MACEqual(&LANBuffer[0], Client->GetMAC())) - return 0; + { + rxlen = Platform::LAN_RecvPacket(LANBuffer, UserData); + continue; + } + } + + if (MACEqual(&LANBuffer[6], Client->GetMAC())) + { + rxlen = Platform::LAN_RecvPacket(LANBuffer, UserData); + continue; } // packet is good diff --git a/src/frontend/qt_sdl/EmuInstance.cpp b/src/frontend/qt_sdl/EmuInstance.cpp index c6dfc158..b39bf040 100644 --- a/src/frontend/qt_sdl/EmuInstance.cpp +++ b/src/frontend/qt_sdl/EmuInstance.cpp @@ -38,6 +38,7 @@ #include "EmuInstance.h" #include "Config.h" #include "Platform.h" +#include "Net.h" #include "LocalMP.h" #include "NDS.h" @@ -82,6 +83,8 @@ EmuInstance::EmuInstance(int inst) : instanceID(inst), audioInit(); inputInit(); + Net::RegisterInstance(instanceID); + emuThread = new EmuThread(this); numWindows = 0; @@ -106,6 +109,8 @@ EmuInstance::~EmuInstance() emuThread->wait(); delete emuThread; + Net::UnregisterInstance(instanceID); + audioDeInit(); inputDeInit(); } diff --git a/src/frontend/qt_sdl/Net.cpp b/src/frontend/qt_sdl/Net.cpp index 6e64a5b6..7a71bab6 100644 --- a/src/frontend/qt_sdl/Net.cpp +++ b/src/frontend/qt_sdl/Net.cpp @@ -20,7 +20,7 @@ #include #include #include "Net.h" -#include "FIFO.h" +#include "PacketDispatcher.h" #include "Platform.h" #include "Config.h" @@ -35,22 +35,21 @@ using Platform::LogLevel; bool Inited = false; bool DirectMode; -QMutex RXMutex; -RingBuffer<0x10000> RXBuffer; +PacketDispatcher Dispatcher; bool Init() { if (Inited) DeInit(); - RXBuffer.Clear(); + Dispatcher.clear(); Config::Table cfg = Config::GetGlobalTable(); DirectMode = cfg.GetBool("LAN.DirectMode"); bool ret = false; if (DirectMode) - ret = Net_PCap::Init(); + ret = Net_PCap::Init(true); else ret = Net_Slirp::Init(); @@ -71,27 +70,24 @@ void DeInit() } -void RXEnqueue(const void* buf, int len) +void RegisterInstance(int inst) { - int totallen = len + 4; + Dispatcher.registerInstance(inst); +} - RXMutex.lock(); - - if (!RXBuffer.CanFit(totallen)) - { - RXMutex.unlock(); - Log(LogLevel::Warn, "Net: !! NOT ENOUGH SPACE IN RX BUFFER\n"); - return; - } - - u32 header = (len & 0xFFFF) | (len << 16); - RXBuffer.Write(&header, sizeof(u32)); - RXBuffer.Write(buf, len); - RXMutex.unlock(); +void UnregisterInstance(int inst) +{ + Dispatcher.unregisterInstance(inst); } -int SendPacket(u8* data, int len) +void RXEnqueue(const void* buf, int len) +{ + Dispatcher.sendPacket(nullptr, 0, buf, len, 16, 0xFFFF); +} + + +int SendPacket(u8* data, int len, int inst) { if (DirectMode) return Net_PCap::SendPacket(data, len); @@ -99,15 +95,18 @@ int SendPacket(u8* data, int len) return Net_Slirp::SendPacket(data, len); } -int RecvPacket(u8* data) +int RecvPacket(u8* data, int inst) { if (DirectMode) Net_PCap::RecvCheck(); else Net_Slirp::RecvCheck(); - // TODO: check MAC - // FIFO header | destination MAC | source MAC | frame type + int ret = 0; + if (!Dispatcher.recvPacket(nullptr, nullptr, data, &ret, inst)) + return 0; + + return ret; } } diff --git a/src/frontend/qt_sdl/Net.h b/src/frontend/qt_sdl/Net.h index dd3feff3..97c65ef3 100644 --- a/src/frontend/qt_sdl/Net.h +++ b/src/frontend/qt_sdl/Net.h @@ -30,10 +30,13 @@ using namespace melonDS; bool Init(); void DeInit(); +void RegisterInstance(int inst); +void UnregisterInstance(int inst); + void RXEnqueue(const void* buf, int len); -int SendPacket(u8* data, int len); -int RecvPacket(u8* data); +int SendPacket(u8* data, int len, int inst); +int RecvPacket(u8* data, int inst); } diff --git a/src/frontend/qt_sdl/Net_Slirp.cpp b/src/frontend/qt_sdl/Net_Slirp.cpp index a3c44844..a65d1a43 100644 --- a/src/frontend/qt_sdl/Net_Slirp.cpp +++ b/src/frontend/qt_sdl/Net_Slirp.cpp @@ -162,7 +162,7 @@ bool Init() *(u32*)&cfg.vnameserver = htonl(kDNSIP); Ctx = slirp_new(&cfg, &cb, nullptr); - +printf("SLIRP INIT\n"); return true; } @@ -373,6 +373,7 @@ void HandleDNSFrame(u8* data, int len) int SendPacket(u8* data, int len) { + printf("SLIRP SEND PACKET %p %p %d\n", Ctx, data, len); if (!Ctx) return 0; if (len > 2048) diff --git a/src/frontend/qt_sdl/PacketDispatcher.cpp b/src/frontend/qt_sdl/PacketDispatcher.cpp index 6ea4356e..28b62d71 100644 --- a/src/frontend/qt_sdl/PacketDispatcher.cpp +++ b/src/frontend/qt_sdl/PacketDispatcher.cpp @@ -64,16 +64,31 @@ void PacketDispatcher::unregisterInstance(int inst) } +void PacketDispatcher::clear() +{ + mutex.lock(); + for (int i = 0; i < 16; i++) + { + if (!(instanceMask & (1 << i))) + continue; + + PacketQueue* queue = packetQueues[i]; + queue->Clear(); + } + mutex.unlock(); +} + + void PacketDispatcher::sendPacket(const void* header, int headerlen, const void* data, int datalen, int sender, u16 recv_mask) { if (!header) headerlen = 0; if (!data) datalen = 0; if ((!headerlen) && (!datalen)) return; if ((sizeof(PacketHeader) + headerlen + datalen) >= 0x8000) return; - if (sender < 0 || sender > 15) return; + if (sender < 0 || sender > 16) return; recv_mask &= instanceMask; - recv_mask &= ~(1 << sender); + if (sender < 16) recv_mask &= ~(1 << sender); if (!recv_mask) return; PacketHeader phdr; @@ -82,6 +97,8 @@ void PacketDispatcher::sendPacket(const void* header, int headerlen, const void* phdr.headerLength = headerlen; phdr.dataLength = datalen; + int totallen = sizeof(phdr) + headerlen + datalen; + mutex.lock(); for (int i = 0; i < 16; i++) { @@ -89,6 +106,15 @@ void PacketDispatcher::sendPacket(const void* header, int headerlen, const void* continue; PacketQueue* queue = packetQueues[i]; + + // if we run out of space: discard old packets + while (!queue->CanFit(totallen)) + { + PacketHeader tmp; + queue->Read(&tmp, sizeof(tmp)); + queue->Skip(tmp.headerLength + tmp.dataLength); + } + queue->Write(&phdr, sizeof(phdr)); if (headerlen) queue->Write(header, headerlen); if (datalen) queue->Write(data, datalen); diff --git a/src/frontend/qt_sdl/PacketDispatcher.h b/src/frontend/qt_sdl/PacketDispatcher.h index b6715433..428fc805 100644 --- a/src/frontend/qt_sdl/PacketDispatcher.h +++ b/src/frontend/qt_sdl/PacketDispatcher.h @@ -34,6 +34,8 @@ public: void registerInstance(int inst); void unregisterInstance(int inst); + void clear(); + void sendPacket(const void* header, int headerlen, const void* data, int datalen, int sender, melonDS::u16 recv_mask); bool recvPacket(void* header, int* headerlen, void* data, int* datalen, int receiver); diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 760eee35..47ef60d6 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -29,7 +29,6 @@ #include #include #include -//#include #include #include #include @@ -38,8 +37,7 @@ #include "Config.h" #include "main.h" #include "CameraManager.h" -#include "Net_Slirp.h" -#include "Net_PCap.h" +#include "Net.h" #include "LocalMP.h" #include "SPI_Firmware.h" @@ -542,6 +540,8 @@ int LAN_SendPacket(u8* data, int len, void* userdata) return LAN_PCap::SendPacket(data, len); else return LAN_Socket::SendPacket(data, len);*/ + int inst = ((EmuInstance*)userdata)->getInstanceID(); + Net::SendPacket(data, len, inst); return 0; } @@ -551,7 +551,8 @@ int LAN_RecvPacket(u8* data, void* userdata) return LAN_PCap::RecvPacket(data); else return LAN_Socket::RecvPacket(data);*/ - return 0; + int inst = ((EmuInstance*)userdata)->getInstanceID(); + return Net::RecvPacket(data, inst); } diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.cpp b/src/frontend/qt_sdl/WifiSettingsDialog.cpp index aa3d7979..75f8ebc6 100644 --- a/src/frontend/qt_sdl/WifiSettingsDialog.cpp +++ b/src/frontend/qt_sdl/WifiSettingsDialog.cpp @@ -52,7 +52,7 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne emuInstance = ((MainWindow*)parent)->getEmuInstance(); auto& cfg = emuInstance->getGlobalConfig(); - haspcap = LAN_PCap::Init(false); + haspcap = Net_PCap::Init(false); ui->rbDirectMode->setText("Direct mode (requires " PCAP_NAME " and ethernet connection)"); @@ -60,9 +60,9 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne ui->lblAdapterIP->setText("(none)"); int sel = 0; - for (int i = 0; i < LAN_PCap::NumAdapters; i++) + for (int i = 0; i < Net_PCap::NumAdapters; i++) { - LAN_PCap::AdapterData* adapter = &LAN_PCap::Adapters[i]; + Net_PCap::AdapterData* adapter = &Net_PCap::Adapters[i]; ui->cbxDirectAdapter->addItem(QString(adapter->FriendlyName)); @@ -96,14 +96,14 @@ void WifiSettingsDialog::done(int r) cfg.SetBool("LAN.DirectMode", ui->rbDirectMode->isChecked()); int sel = ui->cbxDirectAdapter->currentIndex(); - if (sel < 0 || sel >= LAN_PCap::NumAdapters) sel = 0; - if (LAN_PCap::NumAdapters < 1) + if (sel < 0 || sel >= Net_PCap::NumAdapters) sel = 0; + if (Net_PCap::NumAdapters < 1) { cfg.SetString("LAN.Device", ""); } else { - cfg.SetString("LAN.Device", LAN_PCap::Adapters[sel].DeviceName); + cfg.SetString("LAN.Device", Net_PCap::Adapters[sel].DeviceName); } Config::Save(); @@ -128,10 +128,10 @@ void WifiSettingsDialog::on_cbxDirectAdapter_currentIndexChanged(int sel) { if (!haspcap) return; - if (sel < 0 || sel >= LAN_PCap::NumAdapters) return; - if (LAN_PCap::NumAdapters < 1) return; + if (sel < 0 || sel >= Net_PCap::NumAdapters) return; + if (Net_PCap::NumAdapters < 1) return; - LAN_PCap::AdapterData* adapter = &LAN_PCap::Adapters[sel]; + Net_PCap::AdapterData* adapter = &Net_PCap::Adapters[sel]; char tmp[64]; sprintf(tmp, "%02X:%02X:%02X:%02X:%02X:%02X", diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 658baa81..2ecb00ea 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -75,6 +75,7 @@ #include "ArchiveUtil.h" #include "CameraManager.h" #include "LocalMP.h" +#include "Net.h" #include "CLI.h" @@ -268,6 +269,7 @@ int main(int argc, char** argv) } LocalMP::Init(); + Net::Init(); /* mainWindow = new MainWindow(); if (options->fullscreen) @@ -322,6 +324,7 @@ int main(int argc, char** argv) deleteAllEmuInstances(); LocalMP::DeInit(); + Net::DeInit(); //AudioInOut::DeInit(); delete camManager[0];