From 9b7b44fff6187cc267033f0fffba2044142683d2 Mon Sep 17 00:00:00 2001 From: Sonicadvance1 Date: Wed, 13 May 2009 15:34:38 +0000 Subject: [PATCH] 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 --- Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp | 80 ++++++++++++++++--- Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp | 8 +- .../Core/Core/Src/HW/EXI_DeviceEthernet.cpp | 20 +++-- Source/Core/Core/Src/HW/EXI_DeviceEthernet.h | 3 +- 4 files changed, 84 insertions(+), 27 deletions(-) diff --git a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp index 1bcd1d2e14..b9c9a2a284 100644 --- a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp +++ b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Unix.cpp @@ -19,24 +19,82 @@ #include "../EXI_Device.h" #include "../EXI_DeviceEthernet.h" #include -#include + #include + #include + #include + #include + #include + #include + #include + 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; diff --git a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp index f123abf2a6..8d6ca3ff33 100644 --- a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp +++ b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp @@ -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); diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp index 04f3418390..0b255aa1e8 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp @@ -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; } diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h index 1b1a22fda8..0e288a0144 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h @@ -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