Skip to content

Commit

Permalink
Merge pull request hrydgard#19827 from hrydgard/net-inet-socket-remap
Browse files Browse the repository at this point in the history
sceNetInet socket remap
  • Loading branch information
hrydgard authored Jan 8, 2025
2 parents 4218b39 + 440fa80 commit d4ad8c9
Show file tree
Hide file tree
Showing 14 changed files with 538 additions and 134 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2178,6 +2178,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/HLE/AtracCtx2.h
Core/HLE/NetInetConstants.cpp
Core/HLE/NetInetConstants.h
Core/HLE/SocketManager.cpp
Core/HLE/SocketManager.h
Core/HLE/sceAtrac.cpp
Core/HLE/sceAtrac.h
Core/HLE/sceAudio.cpp
Expand Down
3 changes: 3 additions & 0 deletions Common/ArmEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
#define IS_SIGNED 1 << 1
#define ROUND_TO_ZERO 1 << 2

// Unclear why we suddenly need this.
#undef VMIN

namespace ArmGen
{
enum ARMReg
Expand Down
2 changes: 2 additions & 0 deletions Core/Core.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@
<ClCompile Include="HLE\sceUsbAcc.cpp" />
<ClCompile Include="HLE\sceUsbCam.cpp" />
<ClCompile Include="HLE\sceUsbMic.cpp" />
<ClCompile Include="HLE\SocketManager.cpp" />
<ClCompile Include="HW\Atrac3Standalone.cpp" />
<ClCompile Include="HW\BufferQueue.cpp" />
<ClCompile Include="HW\Camera.cpp" />
Expand Down Expand Up @@ -1199,6 +1200,7 @@
<ClInclude Include="HLE\sceUsbAcc.h" />
<ClInclude Include="HLE\sceUsbCam.h" />
<ClInclude Include="HLE\sceUsbMic.h" />
<ClInclude Include="HLE\SocketManager.h" />
<ClInclude Include="HW\Atrac3Standalone.h" />
<ClInclude Include="HW\Camera.h" />
<ClInclude Include="HW\Display.h" />
Expand Down
6 changes: 6 additions & 0 deletions Core/Core.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,9 @@
<ClCompile Include="HLE\NetInetConstants.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
<ClCompile Include="HLE\SocketManager.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ELF\ElfReader.h">
Expand Down Expand Up @@ -2160,6 +2163,9 @@
<ClInclude Include="HLE\NetInetConstants.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
<ClInclude Include="HLE\SocketManager.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE.TXT" />
Expand Down
102 changes: 102 additions & 0 deletions Core/HLE/SocketManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "Common/Net/SocketCompat.h"
#include "Core/HLE/NetInetConstants.h"
#include "Core/HLE/SocketManager.h"
#include "Common/Log.h"

#include <mutex>

SocketManager g_socketManager;
static std::mutex g_socketMutex; // TODO: Remove once the adhoc thread is gone

InetSocket *SocketManager::CreateSocket(int *index, int *returned_errno, SocketState state, int domain, int type, int protocol) {
_dbg_assert_(state != SocketState::Unused);

int hostDomain = convertSocketDomainPSP2Host(domain);
int hostType = convertSocketTypePSP2Host(type);
int hostProtocol = convertSocketProtoPSP2Host(protocol);

SOCKET hostSock = ::socket(hostDomain, hostType, hostProtocol);
if (hostSock < 0) {
*returned_errno = socket_errno;
return nullptr;
}

std::lock_guard<std::mutex> guard(g_socketMutex);

for (int i = MIN_VALID_INET_SOCKET; i < ARRAY_SIZE(inetSockets_); i++) {
if (inetSockets_[i].state == SocketState::Unused) {
*index = i;
InetSocket *inetSock = inetSockets_ + i;
inetSock->sock = hostSock;
inetSock->state = state;
inetSock->domain = domain;
inetSock->type = type;
inetSock->protocol = protocol;
inetSock->nonblocking = false;
*returned_errno = 0;
return inetSock;
}
}
_dbg_assert_(false);

ERROR_LOG(Log::sceNet, "Ran out of socket handles! This is BAD.");
closesocket(hostSock);
*index = 0;
*returned_errno = ENOMEM; // or something..
return nullptr;
}

bool SocketManager::Close(InetSocket *inetSocket) {
_dbg_assert_(inetSocket->state != SocketState::Unused);
if (closesocket(inetSocket->sock) != 0) {
ERROR_LOG(Log::sceNet, "closesocket(%d) failed", inetSocket->sock);
return false;
}
inetSocket->state = SocketState::Unused;
inetSocket->sock = 0;
return true;
}

bool SocketManager::GetInetSocket(int sock, InetSocket **inetSocket) {
std::lock_guard<std::mutex> guard(g_socketMutex);
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
*inetSocket = nullptr;
return false;
}
*inetSocket = inetSockets_ + sock;
return true;
}

// Simplified mappers, only really useful in select/poll
SOCKET SocketManager::GetHostSocketFromInetSocket(int sock) {
std::lock_guard<std::mutex> guard(g_socketMutex);
if (sock < MIN_VALID_INET_SOCKET || sock >= ARRAY_SIZE(inetSockets_) || inetSockets_[sock].state == SocketState::Unused) {
_dbg_assert_(false);
return -1;
}
if (sock == 0) {
// Map 0 to 0, special case.
return 0;
}
return inetSockets_[sock].sock;
}

void SocketManager::CloseAll() {
for (auto &sock : inetSockets_) {
if (sock.state != SocketState::Unused) {
closesocket(sock.sock);
}
sock.state = SocketState::Unused;
sock.sock = 0;
}
}

const char *SocketStateToString(SocketState state) {
switch (state) {
case SocketState::Unused: return "unused";
case SocketState::UsedNetInet: return "netInet";
case SocketState::UsedProAdhoc: return "proAdhoc";
default:
return "N/A";
}
}
50 changes: 50 additions & 0 deletions Core/HLE/SocketManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once

#include "Common/Net/SocketCompat.h"

// Keep track of who's using a socket.
enum class SocketState {
Unused = 0,
UsedNetInet,
UsedProAdhoc,
};

const char *SocketStateToString(SocketState state);

// Internal socket state tracking
struct InetSocket {
SOCKET sock; // native socket
SocketState state;
// NOTE: These are the PSP types. Can be converted to the host types if needed.
int domain;
int type;
int protocol;
bool nonblocking;
};

// Only use this for sockets whose ID are exposed to the game.
// Don't really need to bother with the others, as the game doesn't know about them.
class SocketManager {
public:
enum {
VALID_INET_SOCKET_COUNT = 256,
MIN_VALID_INET_SOCKET = 1,
};

InetSocket *CreateSocket(int *index, int *returned_errno, SocketState state, int domain, int type, int protocol);
bool GetInetSocket(int sock, InetSocket **inetSocket);
SOCKET GetHostSocketFromInetSocket(int sock);
bool Close(InetSocket *inetSocket);
void CloseAll();

// For debugger
const InetSocket *Sockets() {
return inetSockets_;
}

private:
// We use this array from MIN_VALID_INET_SOCKET and forward. It's probably not a good idea to return 0 as a socket.
InetSocket inetSockets_[VALID_INET_SOCKET_COUNT];
};

extern SocketManager g_socketManager;
6 changes: 4 additions & 2 deletions Core/HLE/proAdhoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
#include "Core/CoreTiming.h"
#include "Core/Core.h"
#include "Core/HLE/sceKernelInterrupt.h"
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/HLE/sceNetAdhoc.h"
#include "Core/Instance.h"
Expand Down Expand Up @@ -94,7 +93,9 @@ int actionAfterMatchingMipsCall;
// Broadcast MAC
uint8_t broadcastMAC[ETHER_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

// NOTE: This does not need to be managed by the socket manager - not exposed to the game.
std::atomic<int> metasocket((int)INVALID_SOCKET);

SceNetAdhocctlParameter parameter;
SceNetAdhocctlAdhocId product_code;
std::thread friendFinderThread;
Expand Down Expand Up @@ -281,6 +282,7 @@ SceNetAdhocctlPeerInfo* findFriendByIP(uint32_t ip) {
return peer;
}

// fd is a host socket
int IsSocketReady(int fd, bool readfd, bool writefd, int* errorcode, int timeoutUS) {
fd_set readfds, writefds;
timeval tval;
Expand Down Expand Up @@ -1318,7 +1320,7 @@ int GetChatMessageCount() {
}

// TODO: We should probably change this thread into PSPThread (or merging it into the existing AdhocThread PSPThread) as there are too many global vars being used here which also being used within some HLEs
int friendFinder(){
int friendFinder() {
SetCurrentThreadName("FriendFinder");
auto n = GetI18NCategory(I18NCat::NETWORKING);
// Receive Buffer
Expand Down
Loading

0 comments on commit d4ad8c9

Please sign in to comment.