Merge pull request #262 from SlEePlEs5/master
Added BBA TAP backend for OS X.
This commit is contained in:
commit
f034983b62
|
@ -2,38 +2,110 @@
|
||||||
// Licensed under GPLv2
|
// Licensed under GPLv2
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
#include "Core/HW/EXI_Device.h"
|
#include "Core/HW/EXI_Device.h"
|
||||||
#include "Core/HW/EXI_DeviceEthernet.h"
|
#include "Core/HW/EXI_DeviceEthernet.h"
|
||||||
|
|
||||||
bool CEXIETHERNET::Activate()
|
bool CEXIETHERNET::Activate()
|
||||||
{
|
{
|
||||||
return false;
|
if (IsActivated())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Assumes TunTap OS X is installed, and /dev/tun0 is not in use
|
||||||
|
// and readable / writable by the logged-in user
|
||||||
|
|
||||||
|
if ((fd = open("/dev/tap0", O_RDWR)) < 0)
|
||||||
|
{
|
||||||
|
ERROR_LOG(SP1, "Couldn't open /dev/tap0, unable to init BBA");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
readEnabled = false;
|
||||||
|
|
||||||
|
INFO_LOG(SP1, "BBA initialized.");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEXIETHERNET::Deactivate()
|
void CEXIETHERNET::Deactivate()
|
||||||
{
|
{
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
|
||||||
|
readEnabled = false;
|
||||||
|
if (readThread.joinable())
|
||||||
|
readThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEXIETHERNET::IsActivated()
|
bool CEXIETHERNET::IsActivated()
|
||||||
{
|
{
|
||||||
return false;
|
return fd != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEXIETHERNET::SendFrame(u8 *, u32)
|
bool CEXIETHERNET::SendFrame(u8* frame, u32 size)
|
||||||
{
|
{
|
||||||
return false;
|
INFO_LOG(SP1, "SendFrame %x\n%s", size, ArrayToString(frame, size, 0x10).c_str());
|
||||||
|
|
||||||
|
int writtenBytes = write(fd, frame, size);
|
||||||
|
if ((u32)writtenBytes != size)
|
||||||
|
{
|
||||||
|
ERROR_LOG(SP1, "SendFrame(): expected to write %d bytes, instead wrote %d",
|
||||||
|
size, writtenBytes);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendComplete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadThreadHandler(CEXIETHERNET* self)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (self->fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fd_set rfds;
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(self->fd, &rfds);
|
||||||
|
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 50000;
|
||||||
|
if (select(self->fd + 1, &rfds, nullptr, nullptr, &timeout) <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int readBytes = read(self->fd, self->mRecvBuffer, BBA_RECV_SIZE);
|
||||||
|
if (readBytes < 0)
|
||||||
|
{
|
||||||
|
ERROR_LOG(SP1, "Failed to read from BBA, err=%d", readBytes);
|
||||||
|
}
|
||||||
|
else if (self->readEnabled)
|
||||||
|
{
|
||||||
|
INFO_LOG(SP1, "Read data: %s", ArrayToString(self->mRecvBuffer, readBytes, 0x10).c_str());
|
||||||
|
self->mRecvBufferLength = readBytes;
|
||||||
|
self->RecvHandlePacket();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEXIETHERNET::RecvInit()
|
bool CEXIETHERNET::RecvInit()
|
||||||
{
|
{
|
||||||
return false;
|
readThread = std::thread(ReadThreadHandler, this);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEXIETHERNET::RecvStart()
|
bool CEXIETHERNET::RecvStart()
|
||||||
{
|
{
|
||||||
return false;
|
if (!readThread.joinable())
|
||||||
|
RecvInit();
|
||||||
|
|
||||||
|
readEnabled = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEXIETHERNET::RecvStop()
|
void CEXIETHERNET::RecvStop()
|
||||||
{
|
{
|
||||||
|
readEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ CEXIETHERNET::CEXIETHERNET()
|
||||||
mHAdapter = INVALID_HANDLE_VALUE;
|
mHAdapter = INVALID_HANDLE_VALUE;
|
||||||
mHRecvEvent = INVALID_HANDLE_VALUE;
|
mHRecvEvent = INVALID_HANDLE_VALUE;
|
||||||
mHReadWait = INVALID_HANDLE_VALUE;
|
mHReadWait = INVALID_HANDLE_VALUE;
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__) || defined(__APPLE__)
|
||||||
fd = -1;
|
fd = -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,7 +319,7 @@ public:
|
||||||
DWORD mMtu;
|
DWORD mMtu;
|
||||||
OVERLAPPED mReadOverlapped;
|
OVERLAPPED mReadOverlapped;
|
||||||
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
|
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__) || defined(__APPLE__)
|
||||||
int fd;
|
int fd;
|
||||||
std::thread readThread;
|
std::thread readThread;
|
||||||
volatile bool readEnabled;
|
volatile bool readEnabled;
|
||||||
|
|
Loading…
Reference in New Issue