diff --git a/CMakeLists.txt b/CMakeLists.txt index 9101af9df..0cbfe9626 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/src/core/libraries/network/net_ctl_codes.h b/src/core/libraries/network/net_ctl_codes.h new file mode 100644 index 000000000..a38565c1e --- /dev/null +++ b/src/core/libraries/network/net_ctl_codes.h @@ -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; diff --git a/src/core/libraries/network/net_ctl_obj.cpp b/src/core/libraries/network/net_ctl_obj.cpp new file mode 100644 index 000000000..076498299 --- /dev/null +++ b/src/core/libraries/network/net_ctl_obj.cpp @@ -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); + } + } +} diff --git a/src/core/libraries/network/net_ctl_obj.h b/src/core/libraries/network/net_ctl_obj.h new file mode 100644 index 000000000..3178677f4 --- /dev/null +++ b/src/core/libraries/network/net_ctl_obj.h @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#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 nptoolCallbacks; + std::array callbacks; + std::mutex m_mutex; +}; +} // namespace Libraries::NetCtl diff --git a/src/core/libraries/network/netctl.cpp b/src/core/libraries/network/netctl.cpp index 29c4038f4..d1ea0ecee 100644 --- a/src/core/libraries/network/netctl.cpp +++ b/src/core/libraries/network/netctl.cpp @@ -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::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::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::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::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; } diff --git a/src/core/libraries/network/netctl.h b/src/core/libraries/network/netctl.h index 2b40f263c..850650f97 100644 --- a/src/core/libraries/network/netctl.h +++ b/src/core/libraries/network/netctl.h @@ -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();