Slight cleanup in the main file. Win32 tries sending the packet, but fails with error 0x57 or 0x6 in WriteFile function, depending on how I have it set up. Linux sends out the packet, or at least it says it sends it out. Requires root priv in Linux and openVPN installed to use the /dev/net/tun device.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3217 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
5cefdb2c4f
commit
9b7b44fff6
|
@ -19,24 +19,82 @@
|
|||
#include "../EXI_Device.h"
|
||||
#include "../EXI_DeviceEthernet.h"
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stropts.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
int fd = -1;
|
||||
bool CEXIETHERNET::deactivate()
|
||||
{
|
||||
close(fd);
|
||||
fd = -1;
|
||||
return true;
|
||||
// TODO: Actually deactivate
|
||||
}
|
||||
bool CEXIETHERNET::isActivated()
|
||||
{
|
||||
return false;
|
||||
//TODO: Never Activated Yet!
|
||||
return fd != -1 ? true : false;
|
||||
}
|
||||
|
||||
bool CEXIETHERNET::activate() {
|
||||
if(isActivated())
|
||||
return true;
|
||||
else
|
||||
if( (fd = open("/dev/net/tun", O_RDWR)) < 0)
|
||||
{
|
||||
DEBUGPRINT("Couldn't Open device\n");
|
||||
return false;
|
||||
//TODO: Activate Device!
|
||||
}
|
||||
struct ifreq ifr;
|
||||
int err;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TAP;
|
||||
|
||||
strncpy(ifr.ifr_name, "Dolphin", IFNAMSIZ);
|
||||
|
||||
if( (err = ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0)
|
||||
{
|
||||
close(fd);
|
||||
fd = -1;
|
||||
DEBUGPRINT(" Error with IOCTL: 0x%X\n", err);
|
||||
return false;
|
||||
}
|
||||
DEBUGPRINT("Returned Socket name is: %s\n", ifr.ifr_name);
|
||||
return true;
|
||||
|
||||
}
|
||||
bool CEXIETHERNET::startRecv() {
|
||||
DEBUGPRINT("Start Receive!\n");
|
||||
exit(0);
|
||||
/*if(!isActivated())
|
||||
return false;// Should actually be an assert
|
||||
DEBUGPRINT("startRecv... ");
|
||||
if(mWaiting) {
|
||||
DEBUGPRINT("already waiting\n");
|
||||
return true;
|
||||
}
|
||||
DWORD BytesRead = 0;
|
||||
DWORD *Buffer = (DWORD *)malloc(2048); // Should be enough
|
||||
DWORD res = ReadFile(mHAdapter, Buffer, BytesRead,
|
||||
&mRecvBufferLength, &mReadOverlapped);
|
||||
mRecvBuffer.write(BytesRead, Buffer);
|
||||
free(Buffer);
|
||||
if(res) { //Operation completed immediately
|
||||
DEBUGPRINT("completed, res %i\n", res);
|
||||
mWaiting = true;
|
||||
} else {
|
||||
res = GetLastError();
|
||||
if (res == ERROR_IO_PENDING) { //'s ok :)
|
||||
DEBUGPRINT("pending\n");
|
||||
//WaitCallback will be called
|
||||
mWaiting = true;
|
||||
} else { //error occurred
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;*/
|
||||
}
|
||||
bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
||||
{
|
||||
|
@ -46,18 +104,14 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
|||
DEBUGPRINT( "%02X", etherpckt[a]);
|
||||
}
|
||||
DEBUGPRINT( " : Size: %d\n", size);
|
||||
int raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
|
||||
DEBUGPRINT("Raw socket is : %d\n", raw_socket);
|
||||
int sm=1;
|
||||
const int *val=&sm;
|
||||
int result = setsockopt(raw_socket, IPPROTO_IP, IP_HDRINCL, val, sizeof(sm));
|
||||
DEBUGPRINT("Result is : %d\n", result);
|
||||
int numBytesWrit = write(raw_socket, etherpckt, size);
|
||||
int numBytesWrit = write(fd, etherpckt, size);
|
||||
if(numBytesWrit != size)
|
||||
{
|
||||
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
DEBUGPRINT("Sent out the correct number of bytes: %d\n", size);
|
||||
//fwrite(etherpckt, size, size, raw_socket);
|
||||
/*DWORD numBytesWrit;
|
||||
OVERLAPPED overlap;
|
||||
|
|
|
@ -137,8 +137,12 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
|||
DWORD numBytesWrit;
|
||||
OVERLAPPED overlap;
|
||||
//ZERO_OBJECT(overlap);
|
||||
//overlap.hEvent = mHRecvEvent;
|
||||
WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap);
|
||||
overlap.hEvent = mHRecvEvent;
|
||||
if(!WriteFile(mHAdapter, etherpckt, size, &numBytesWrit, &overlap))
|
||||
{ // Fail Boat
|
||||
DWORD res = GetLastError();
|
||||
DEBUGPRINT("Failed to send packet with error 0x%X\n", res);
|
||||
}
|
||||
if(numBytesWrit != size)
|
||||
{
|
||||
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!\n", size, numBytesWrit);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "EXI_Device.h"
|
||||
#include "EXI_DeviceEthernet.h"
|
||||
|
||||
//#define SONICDEBUG
|
||||
#define SONICDEBUG
|
||||
|
||||
void DEBUGPRINT (const char * format, ...)
|
||||
{
|
||||
|
@ -95,7 +95,6 @@ CEXIETHERNET::CEXIETHERNET() :
|
|||
|
||||
Expecting = EXPECT_NONE;
|
||||
mExpectVariableLengthImmWrite = false;
|
||||
mBbaMem[BBA_NWAYS] = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY | BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
|
||||
}
|
||||
|
||||
void CEXIETHERNET::SetCS(int cs)
|
||||
|
@ -130,10 +129,10 @@ bool CEXIETHERNET::IsInterruptSet()
|
|||
|
||||
void CEXIETHERNET::recordSendComplete()
|
||||
{
|
||||
mBbaMem[0x00] &= ~0x06;
|
||||
mBbaMem[BBA_NCRA] &= ~0x06;
|
||||
if(mBbaMem[0x08] & BBA_INTERRUPT_SENT)
|
||||
{
|
||||
mBbaMem[0x09] |= BBA_INTERRUPT_SENT;
|
||||
mBbaMem[BBA_IR] |= BBA_INTERRUPT_SENT;
|
||||
DEBUGPRINT( "\t\tBBA Send interrupt raised\n");
|
||||
//exit(0);
|
||||
m_bInterruptSet = true;
|
||||
|
@ -155,6 +154,8 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
DEBUGPRINT( "IMM Write, size 0x%x, data 0x%x mWriteP 0x%x\n", _uSize, _uData, mWriteP);
|
||||
if (mExpectVariableLengthImmWrite)
|
||||
{
|
||||
DEBUGPRINT("Variable Length IMM Write: Size: %d _uData: 0x%08X swapped: 0x%08X\n", _uSize, _uData, Common::swap32(_uData));
|
||||
// TODO: Use Swapped or unswapped?
|
||||
if(_uSize == 4)
|
||||
{
|
||||
_uData = Common::swap32(_uData);
|
||||
|
@ -218,16 +219,15 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
exit(0);
|
||||
//throw hardware_fatal_exception("BBA Transmit without a packet!");
|
||||
}
|
||||
// TODO: Actually Make it send a packet
|
||||
sendPacket(mWriteBuffer.p(), mWriteBuffer.size());
|
||||
mReadyToSend = false;
|
||||
//exit(0);
|
||||
}
|
||||
mBbaMem[0x00] = MAKE(u8, SwappedData);
|
||||
mBbaMem[BBA_NCRA] = MAKE(u8, SwappedData);
|
||||
}
|
||||
break;
|
||||
case BBA_NWAYC:
|
||||
DEBUGPRINT( "\t[INFO]BBA_NWAYCn");
|
||||
DEBUGPRINT( "\t[INFO]BBA_NWAYC\n");
|
||||
if(Common::swap32(_uData) & (BBA_NWAYC_ANE | BBA_NWAYC_ANS_RA))
|
||||
{
|
||||
DEBUGPRINT("ACTIVATING!\n");
|
||||
|
@ -242,7 +242,7 @@ void CEXIETHERNET::ImmWrite(u32 _uData, u32 _uSize)
|
|||
//exit(0);
|
||||
assert(_uSize == 2 || _uSize == 1);
|
||||
mRBRPP = (u8)_uData << 8; //Whinecube: I hope this works with both write sizes.
|
||||
mRBEmpty = mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET);
|
||||
mRBEmpty = (mRBRPP == ((u32)mCbw.p_write() + CB_OFFSET));
|
||||
checkRecvBuffer();
|
||||
break;
|
||||
case BBA_RWP: //RWP - Receive Buffer Write Page Pointer
|
||||
|
@ -388,8 +388,6 @@ u32 CEXIETHERNET::ImmRead(u32 _uSize)
|
|||
}
|
||||
u32 uResult = 0;
|
||||
memcpy(&uResult, mBbaMem + mReadP, _uSize);
|
||||
if(mReadP == 0x31)
|
||||
uResult = (BBA_NWAYS_LS10 | BBA_NWAYS_LPNWAY |BBA_NWAYS_ANCLPT | BBA_NWAYS_10TXF);
|
||||
// TODO: We do as well?
|
||||
uResult = Common::swap32(uResult); //Whinecube : we have a byteswap problem...
|
||||
|
||||
|
@ -410,7 +408,7 @@ void CEXIETHERNET::DMAWrite(u32 _uAddr, u32 _uSize)
|
|||
{
|
||||
if(mExpectVariableLengthImmWrite)
|
||||
{
|
||||
DEBUGPRINT("Address is 0x%x and size is 0x%x\n", _uAddr, _uSize);
|
||||
DEBUGPRINT("DMA Write: Address is 0x%x and size is 0x%x\n", _uAddr, _uSize);
|
||||
mWriteBuffer.write(_uSize, Memory::GetPointer(_uAddr));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -123,13 +123,14 @@ private:
|
|||
bool isActivated();
|
||||
bool resume();
|
||||
bool startRecv();
|
||||
|
||||
volatile bool mWaiting;
|
||||
#ifdef _WIN32
|
||||
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
|
||||
DWORD mMtu;
|
||||
OVERLAPPED mReadOverlapped;
|
||||
WriteBuffer mRecvBuffer;
|
||||
DWORD mRecvBufferLength;
|
||||
volatile bool mWaiting;
|
||||
static VOID CALLBACK ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFired);
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue