Merge pull request #262 from SlEePlEs5/master

Added BBA TAP backend for OS X.
This commit is contained in:
Pierre Bourdon 2014-04-14 02:15:10 +02:00
commit f034983b62
3 changed files with 80 additions and 8 deletions

View File

@ -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;
} }

View File

@ -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
} }

View File

@ -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;