DEV9: Add shared internal server code

This commit is contained in:
TheLastRar 2021-03-08 15:34:07 +00:00 committed by lightningterror
parent c1ab094938
commit 7e35c7750e
3 changed files with 159 additions and 10 deletions

View File

@ -17,6 +17,7 @@
#include <chrono>
#include <thread>
#include <mutex>
#if defined(__POSIX__)
#include <pthread.h>
#endif
@ -27,14 +28,15 @@
#endif
#include "pcap_io.h"
#ifdef _WIN32
#include "Win32\tap.h"
#endif
#include "pcap_io.h"
#include "PacketReader/EthernetFrame.h"
#include "PacketReader/IP/IP_Packet.h"
#include "PacketReader/IP/UDP/UDP_Packet.h"
NetAdapter* nif;
std::thread rx_thread;
std::mutex rx_mutex;
volatile bool RxRunning = false;
//rx thread
void NetRxThread()
@ -44,8 +46,14 @@ void NetRxThread()
{
while (rx_fifo_can_rx() && nif->recv(&tmp))
{
rx_process(&tmp);
std::lock_guard rx_lock(rx_mutex);
//Check if we can still rx
if (rx_fifo_can_rx())
rx_process(&tmp);
else
Console.Error("DEV9: rx_fifo_can_rx() false after nif->recv(), dropping");
}
std::this_thread::yield();
}
}
@ -158,7 +166,11 @@ const wchar_t* NetApiToWstring(NetApi api)
}
}
const PacketReader::IP::IP_Address NetAdapter::internalIP{192, 0, 2, 1};
using namespace PacketReader;
using namespace PacketReader::IP;
using namespace PacketReader::IP::UDP;
const IP_Address NetAdapter::internalIP{192, 0, 2, 1};
const u8 NetAdapter::broadcastMAC[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
const u8 NetAdapter::internalMAC[6] = {0x76, 0x6D, 0xF4, 0x63, 0x30, 0x31};
@ -168,6 +180,36 @@ NetAdapter::NetAdapter()
SetMACAddress(nullptr);
}
bool NetAdapter::recv(NetPacket* pkt)
{
if (!internalRxThreadRunning.load())
return InternalServerRecv(pkt);
return false;
}
bool NetAdapter::send(NetPacket* pkt)
{
return InternalServerSend(pkt);
}
//RxRunning must be set false before this
NetAdapter::~NetAdapter()
{
//unblock InternalServerRX thread
if (internalRxThreadRunning.load())
{
internalRxThreadRunning.store(false);
{
std::lock_guard srvlock(internalRxMutex);
internalRxHasData = true;
}
internalRxCV.notify_all();
internalRxThread.join();
}
}
void NetAdapter::SetMACAddress(u8* mac)
{
if (mac == nullptr)
@ -198,3 +240,72 @@ bool NetAdapter::VerifyPkt(NetPacket* pkt, int read_size)
pkt->size = read_size;
return true;
}
#ifdef _WIN32
void NetAdapter::InitInternalServer(PIP_ADAPTER_ADDRESSES adapter)
#elif defined(__POSIX__)
void NetAdapter::InitInternalServer(ifaddrs* adapter)
#endif
{
if (adapter == nullptr)
Console.Error("DEV9: InitInternalServer() got nullptr for adapter");
if (blocks())
{
internalRxThreadRunning.store(true);
internalRxThread = std::thread(&NetAdapter::InternalServerThread, this);
}
}
bool NetAdapter::InternalServerRecv(NetPacket* pkt)
{
return false;
}
bool NetAdapter::InternalServerSend(NetPacket* pkt)
{
EthernetFrame frame(pkt);
if (frame.protocol == (u16)EtherType::IPv4)
{
PayloadPtr* payload = static_cast<PayloadPtr*>(frame.GetPayload());
IP_Packet ippkt(payload->data, payload->GetLength());
if (ippkt.destinationIP == internalIP)
{
return true;
}
}
return false;
}
void NetAdapter::InternalSignalReceived()
{
//Signal internal server thread to read
if (internalRxThreadRunning.load())
{
{
std::lock_guard srvlock(internalRxMutex);
internalRxHasData = true;
}
internalRxCV.notify_all();
}
}
void NetAdapter::InternalServerThread()
{
NetPacket tmp;
while (internalRxThreadRunning.load())
{
std::unique_lock srvLock(internalRxMutex);
internalRxCV.wait(srvLock, [&] { return internalRxHasData; });
{
std::lock_guard rx_lock(rx_mutex);
while (rx_fifo_can_rx() && InternalServerRecv(&tmp))
rx_process(&tmp);
}
internalRxHasData = false;
}
}

View File

@ -17,6 +17,20 @@
#include <stdlib.h>
#include <string>
#include <functional>
#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#ifdef _WIN32
#include <winsock2.h>
#include <iphlpapi.h>
#elif defined(__POSIX__)
#include <sys/types.h>
#include <ifaddrs.h>
#endif
#include "PacketReader/IP/IP_Address.h"
// first three recognized by Xlink as Sony PS2
@ -69,18 +83,39 @@ protected:
static const u8 broadcastMAC[6];
static const u8 internalMAC[6];
private:
std::thread internalRxThread;
std::atomic<bool> internalRxThreadRunning{false};
std::mutex internalRxMutex;
std::condition_variable internalRxCV;
bool internalRxHasData = false;
public:
NetAdapter();
virtual bool blocks() = 0;
virtual bool isInitialised() = 0;
virtual bool recv(NetPacket* pkt) = 0; //gets a packet
virtual bool send(NetPacket* pkt) = 0; //sends the packet and deletes it when done
virtual void close() {}
virtual ~NetAdapter() {}
virtual bool recv(NetPacket* pkt); //gets a packet
virtual bool send(NetPacket* pkt); //sends the packet and deletes it when done
virtual void close(){};
virtual ~NetAdapter();
protected:
void SetMACAddress(u8* mac);
bool VerifyPkt(NetPacket* pkt, int read_size);
#ifdef _WIN32
void InitInternalServer(PIP_ADAPTER_ADDRESSES adapter);
#elif defined(__POSIX__)
void InitInternalServer(ifaddrs* adapter);
#endif
private:
bool InternalServerRecv(NetPacket* pkt);
bool InternalServerSend(NetPacket* pkt);
void InternalSignalReceived();
void InternalServerThread();
};
void tx_put(NetPacket* ptr);

View File

@ -178,6 +178,9 @@
<Filter Include="System\Ps2\DEV9\ATA\Commands">
<UniqueIdentifier>{9e9b52d7-7b1c-44b2-82d8-1e0d8085e7e0}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\InternalServers">
<UniqueIdentifier>{93da3d51-9457-4fde-b374-c2fbe4780f59}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader">
<UniqueIdentifier>{57c4be94-9a2c-469b-9b02-b3b324857fc5}</UniqueIdentifier>
</Filter>