improved callbacks handling in sceNetCtl

This commit is contained in:
georgemoralis 2024-09-08 20:08:35 +03:00
parent 0e1bd0396a
commit bb830c95df
6 changed files with 174 additions and 24 deletions

View file

@ -212,6 +212,9 @@ set(NETWORK_LIBS src/core/libraries/network/http.cpp
src/core/libraries/network/net.cpp
src/core/libraries/network/netctl.cpp
src/core/libraries/network/netctl.h
src/core/libraries/network/net_ctl_obj.cpp
src/core/libraries/network/net_ctl_obj.h
src/core/libraries/network/net_ctl_codes.h
src/core/libraries/network/net.h
src/core/libraries/network/ssl.cpp
src/core/libraries/network/ssl.h

View file

@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// error codes
constexpr int ORBIS_NET_CTL_ERROR_CALLBACK_MAX = 0x80412103;
constexpr int ORBIS_NET_CTL_ERROR_ID_NOT_FOUND = 0x80412104;
constexpr int ORBIS_NET_CTL_ERROR_INVALID_ID = 0x80412105;
constexpr int ORBIS_NET_CTL_ERROR_INVALID_ADDR = 0x80412107;
constexpr int ORBIS_NET_CTL_ERROR_NOT_CONNECTED = 0x80412108;
constexpr int ORBIS_NET_CTL_ERROR_NOT_AVAIL = 0x80412109;
constexpr int ORBIS_NET_CTL_ERROR_NETWORK_DISABLED = 0x8041210D;
constexpr int ORBIS_NET_CTL_ERROR_DISCONNECT_REQ = 0x8041210E;
constexpr int ORBIS_NET_CTL_ERROR_ETHERNET_PLUGOUT = 0x80412115;
constexpr int ORBIS_NET_CTL_ERROR_WIFI_DEAUTHED = 0x80412116;
constexpr int ORBIS_NET_CTL_ERROR_WIFI_BEACON_LOST = 0x80412117;
// state codes
constexpr int ORBIS_NET_CTL_STATE_DISCONNECTED = 0;
constexpr int ORBIS_NET_CTL_STATE_CONNECTING = 1;
constexpr int ORBIS_NET_CTL_STATE_IPOBTAINING = 2;
constexpr int ORBIS_NET_CTL_STATE_IPOBTAINED = 3;
// event type
constexpr int ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED = 1;
constexpr int ORBIS_SCE_NET_CTL_EVENT_TYPE_DISCONNECT_REQ_FINISHED = 2;
constexpr int ORBIS_NET_CTL_EVENT_TYPE_IPOBTAINED = 3;

View file

@ -0,0 +1,71 @@
#include "net_ctl_codes.h"
#include "net_ctl_obj.h"
Libraries::NetCtl::NetCtlInternal::NetCtlInternal() {
callbacks.fill({nullptr, nullptr});
nptoolCallbacks.fill({nullptr, nullptr});
}
Libraries::NetCtl::NetCtlInternal::~NetCtlInternal() {}
s32 Libraries::NetCtl::NetCtlInternal::registerCallback(OrbisNetCtlCallback func, void* arg) {
std::unique_lock lock{m_mutex};
// Find the next available slot
int next_id = 0;
for (const auto& callback : callbacks) {
if (callback.func == nullptr) {
break;
}
next_id++;
}
if (next_id == 8) {
return ORBIS_NET_CTL_ERROR_CALLBACK_MAX;
}
callbacks[next_id].func = func;
callbacks[next_id].arg = arg;
return next_id;
}
s32 Libraries::NetCtl::NetCtlInternal::registerNpToolkitCallback(
OrbisNetCtlCallbackForNpToolkit func, void* arg) {
std::unique_lock lock{m_mutex};
// Find the next available slot
int next_id = 0;
for (const auto& callback : nptoolCallbacks) {
if (callback.func == nullptr) {
break;
}
next_id++;
}
if (next_id == 8) {
return ORBIS_NET_CTL_ERROR_CALLBACK_MAX;
}
nptoolCallbacks[next_id].func = func;
nptoolCallbacks[next_id].arg = arg;
return next_id;
}
void Libraries::NetCtl::NetCtlInternal::checkCallback() {
std::unique_lock lock{m_mutex};
for (auto& callback : callbacks) {
if (callback.func != nullptr) {
callback.func(ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, callback.arg);
}
}
}
void Libraries::NetCtl::NetCtlInternal::checkNpToolkitCallback() {
std::unique_lock lock{m_mutex};
for (auto& callback : nptoolCallbacks) {
if (callback.func != nullptr) {
callback.func(ORBIS_NET_CTL_EVENT_TYPE_DISCONNECTED, callback.arg);
}
}
}

View file

@ -0,0 +1,40 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <condition_variable>
#include <mutex>
#include "common/types.h"
namespace Libraries::NetCtl {
using OrbisNetCtlCallback = PS4_SYSV_ABI void (*)(int eventType, void* arg);
using OrbisNetCtlCallbackForNpToolkit = PS4_SYSV_ABI void (*)(int eventType, void* arg);
struct NetCtlCallback {
OrbisNetCtlCallback func;
void* arg;
};
struct NetCtlCallbackForNpToolkit {
OrbisNetCtlCallbackForNpToolkit func;
void* arg;
};
class NetCtlInternal {
public:
NetCtlInternal();
~NetCtlInternal();
s32 registerCallback(OrbisNetCtlCallback func, void* arg);
s32 registerNpToolkitCallback(OrbisNetCtlCallbackForNpToolkit func, void* arg);
void checkCallback();
void checkNpToolkitCallback();
public:
std::array<NetCtlCallback, 8> nptoolCallbacks;
std::array<NetCtlCallbackForNpToolkit, 8> callbacks;
std::mutex m_mutex;
};
} // namespace Libraries::NetCtl

View file

@ -2,8 +2,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "common/singleton.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "core/libraries/network/net_ctl_codes.h"
#include "core/libraries/network/netctl.h"
namespace Libraries::NetCtl {
@ -79,7 +81,8 @@ int PS4_SYSV_ABI sceNetCtlUnregisterCallbackV6() {
}
int PS4_SYSV_ABI sceNetCtlCheckCallback() {
LOG_TRACE(Lib_NetCtl, "(STUBBED) called");
auto* netctl = Common::Singleton<Libraries::NetCtl::NetCtlInternal>::Instance();
netctl->checkCallback();
return ORBIS_OK;
}
@ -184,7 +187,7 @@ int PS4_SYSV_ABI sceNetCtlGetNetEvConfigInfoIpcInt() {
}
int PS4_SYSV_ABI sceNetCtlGetResult(int eventType, int* errorCode) {
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
LOG_ERROR(Lib_NetCtl, "(STUBBED) called eventType = {} ", eventType);
*errorCode = 0;
return ORBIS_OK;
}
@ -225,8 +228,7 @@ int PS4_SYSV_ABI sceNetCtlGetScanInfoForSsidScanIpcInt() {
}
int PS4_SYSV_ABI sceNetCtlGetState(int* state) {
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
*state = 0;
*state = ORBIS_NET_CTL_STATE_DISCONNECTED;
return ORBIS_OK;
}
@ -261,8 +263,16 @@ int PS4_SYSV_ABI sceNetCtlIsBandwidthManagementEnabledIpcInt() {
}
int PS4_SYSV_ABI sceNetCtlRegisterCallback(OrbisNetCtlCallback func, void* arg, int* cid) {
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
*cid = 1;
if (!func || !cid) {
return ORBIS_NET_CTL_ERROR_INVALID_ADDR;
}
auto* netctl = Common::Singleton<Libraries::NetCtl::NetCtlInternal>::Instance();
s32 result = netctl->registerCallback(func, arg);
if (result < 0) {
return result;
} else {
*cid = result;
}
return ORBIS_OK;
}
@ -331,16 +341,9 @@ int PS4_SYSV_ABI Func_D8DCB6973537A3DC() {
return ORBIS_OK;
}
struct NetCtlCallbackForNpToolkit {
OrbisNetCtlCallbackForNpToolkit func;
void* arg;
};
NetCtlCallbackForNpToolkit NetCtlCbForNp;
int PS4_SYSV_ABI sceNetCtlCheckCallbackForNpToolkit() {
// LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
NetCtlCbForNp.func(1, NetCtlCbForNp.arg); // disconnect
auto* netctl = Common::Singleton<Libraries::NetCtl::NetCtlInternal>::Instance();
netctl->checkNpToolkitCallback();
return ORBIS_OK;
}
@ -350,11 +353,17 @@ int PS4_SYSV_ABI sceNetCtlClearEventForNpToolkit() {
}
int PS4_SYSV_ABI sceNetCtlRegisterCallbackForNpToolkit(OrbisNetCtlCallbackForNpToolkit func,
void* arg, int* ci) {
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
*ci = 1;
NetCtlCbForNp.func = func;
NetCtlCbForNp.arg = arg;
void* arg, int* cid) {
if (!func || !cid) {
return ORBIS_NET_CTL_ERROR_INVALID_ADDR;
}
auto* netctl = Common::Singleton<Libraries::NetCtl::NetCtlInternal>::Instance();
s32 result = netctl->registerNpToolkitCallback(func, arg);
if (result < 0) {
return result;
} else {
*cid = result;
}
return ORBIS_OK;
}
@ -494,6 +503,7 @@ int PS4_SYSV_ABI sceNetCtlApRpStop() {
}
int PS4_SYSV_ABI sceNetCtlApRpUnregisterCallback() {
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
LOG_ERROR(Lib_NetCtl, "(STUBBED) called");
return ORBIS_OK;
}

View file

@ -4,6 +4,7 @@
#pragma once
#include "common/types.h"
#include "net_ctl_obj.h"
namespace Core::Loader {
class SymbolsResolver;
@ -46,9 +47,6 @@ typedef union OrbisNetCtlInfo {
u16 http_proxy_port;
} SceNetCtlInfo;
using OrbisNetCtlCallback = PS4_SYSV_ABI void (*)(int eventType, void* arg);
using OrbisNetCtlCallbackForNpToolkit = PS4_SYSV_ABI void (*)(int eventType, void* arg);
// GetInfo codes
constexpr int ORBIS_NET_CTL_INFO_DEVICE = 1;
constexpr int ORBIS_NET_CTL_INFO_LINK = 4;
@ -118,7 +116,7 @@ int PS4_SYSV_ABI Func_D8DCB6973537A3DC();
int PS4_SYSV_ABI sceNetCtlCheckCallbackForNpToolkit();
int PS4_SYSV_ABI sceNetCtlClearEventForNpToolkit();
int PS4_SYSV_ABI sceNetCtlRegisterCallbackForNpToolkit(OrbisNetCtlCallbackForNpToolkit func,
void* arg, int* ci);
void* arg, int* cid);
int PS4_SYSV_ABI sceNetCtlUnregisterCallbackForNpToolkit();
int PS4_SYSV_ABI sceNetCtlApCheckCallback();
int PS4_SYSV_ABI sceNetCtlApClearEvent();