Files

143 lines
3.7 KiB
C++

#include "Common.h"
#include "Events.h"
std::vector< OrbisNetInAddr_t> Events::HostList;
OrbisPthreadMutex Events::HostListMutex;
bool Events::Init()
{
// Create the mutex to protect our host list.
auto res = scePthreadMutexInit(&HostListMutex, nullptr, "EventsHostListMutex");
if (res != 0)
{
klog("Failed to create mutex for Events Host list. Err: 0x%llX\n", res);
return false;
}
else
{
return true;
}
}
void Events::Term()
{
// Destroy for clean up.
scePthreadMutexDestroy(&HostListMutex);
}
void Events::AddHost(OrbisNetInAddr_t HostAddress)
{
// Aquire a lock for the list.
scePthreadMutexLock(&HostListMutex);
// Add the host to the list if it does not exist already.
if (std::find(HostList.begin(), HostList.end(), HostAddress) == HostList.end())
{
klog("New host (%i.%i.%i.%i)!\n", HostAddress & 0xFF, (HostAddress >> 8) & 0xFF, (HostAddress >> 16) & 0xFF, (HostAddress >> 24) & 0xFF);
HostList.push_back(HostAddress);
}
// Revoke the lock on the list.
scePthreadMutexUnlock(&HostListMutex);
}
void Events::RemoveHost(OrbisNetInAddr_t HostAddress)
{
// Aquire a lock for the list.
scePthreadMutexLock(&HostListMutex);
// Remove this host if it exists in the list.
if (std::find(HostList.begin(), HostList.end(), HostAddress) != HostList.end())
{
klog("Lost host (%i.%i.%i.%i)!\n", HostAddress & 0xFF, (HostAddress >> 8) & 0xFF, (HostAddress >> 16) & 0xFF, (HostAddress >> 24) & 0xFF);
std::remove(HostList.begin(), HostList.end(), HostAddress);
}
// Revoke the lock on the list.
scePthreadMutexUnlock(&HostListMutex);
}
OrbisNetId Events::Connect(OrbisNetInAddr_t HostAddress)
{
// Set up socket params.
OrbisNetSockaddrIn addr = { 0 };
addr.sin_family = ORBIS_NET_AF_INET;
addr.sin_addr.s_addr = HostAddress;
addr.sin_port = sceNetHtons(EVENT_PORT);
// Create socket.
auto sock = sceNetSocket("SendEventSock", ORBIS_NET_AF_INET, ORBIS_NET_SOCK_STREAM, ORBIS_NET_IPPROTO_TCP);
if (sock < 0)
{
klog("Events::Connect() Failed to allocate sock: %llX %llX\n", sock, *sceNetErrnoLoc());
return NULL;
}
int nopipe = 1;
sceNetSetsockopt(sock, ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_NOSIGPIPE, &nopipe, sizeof(nopipe));
// Set connection time out to 4s.
int sock_timeout = 4000000;
sceNetSetsockopt(sock, ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_CONNECTTIMEO, &sock_timeout, sizeof(sock_timeout));
sceNetSetsockopt(sock, ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_SNDTIMEO, &sock_timeout, sizeof(sock_timeout));
sceNetSetsockopt(sock, ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_RCVTIMEO, &sock_timeout, sizeof(sock_timeout));
auto res = sceNetConnect(sock, (OrbisNetSockaddr*)&addr, sizeof(addr));
if (!res)
return sock;
else
{
klog("Events::Connect() sceNetConnect(): %llX %llX\n", res, *sceNetErrnoLoc());
return NULL;
}
}
void Events::SendEvent(int EventId, int pid)
{
klog("SendEvent()\n");
if (HostList.empty())
{
klog("SendEvent(): Host List Empty :(\n");
return;
}
for (const auto& host : HostList)
{
klog("SendEvent(): Sending for host %i.%i.%i.%i\n", host & 0xFF, (host >> 8) & 0xFF, (host >> 16) & 0xFF, (host >> 24) & 0xFF);
// Aquire a lock for the list.
scePthreadMutexLock(&HostListMutex);
auto sock = Connect(host);
if (sock)
{
klog("Sending Event: %i\n", EventId);
// Send EventId
Sockets::SendInt(sock, EventId);
if (EventId == EVENT_ATTACH && pid != -1)
{
Sockets::SendInt(sock, pid);
}
// Close the socket.
sceNetSocketClose(sock);
// Revoke the lock on the list.
scePthreadMutexUnlock(&HostListMutex);
}
else
{
klog("SendEvent(): Failed to connect to host %i.%i.%i.%i\n", host & 0xFF, (host >> 8) & 0xFF, (host >> 16) & 0xFF, (host >> 24) & 0xFF);
// Revoke the lock on the list.
scePthreadMutexUnlock(&HostListMutex);
RemoveHost(host);
}
}
}