improves sig_ctx handling, sys_net logging and fixes udpp2p protocol (#15235)

This commit is contained in:
RipleyTom 2024-02-24 12:40:53 +01:00 committed by GitHub
parent 3067c86d65
commit ac8e914a25
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 201 additions and 81 deletions

View file

@ -618,6 +618,13 @@ error_code sceNpTerm()
nph.terminate_NP(); nph.terminate_NP();
nph.is_NP_init = false; nph.is_NP_init = false;
idm::clear<signaling_ctx>();
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.clear_sig_ctx();
// TODO: Other contexts(special handling for transaction contexts?)
return CELL_OK; return CELL_OK;
} }
@ -6636,15 +6643,17 @@ error_code sceNpSignalingCreateCtx(vm::ptr<SceNpId> npId, vm::ptr<SceNpSignaling
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT; return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
} }
// if (current_contexts > SCE_NP_SIGNALING_CTX_MAX) u32 id = create_signaling_context(npId, handler, arg);
//{
// return SCE_NP_SIGNALING_ERROR_CTX_MAX;
//}
*ctx_id = create_signaling_context(npId, handler, arg); if (!id)
{
return SCE_NP_SIGNALING_ERROR_CTX_MAX;
}
*ctx_id = id;
auto& sigh = g_fxo->get<named_thread<signaling_handler>>(); auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.set_sig_cb(*ctx_id, handler, arg); sigh.add_sig_ctx(id);
return CELL_OK; return CELL_OK;
} }
@ -6665,6 +6674,9 @@ error_code sceNpSignalingDestroyCtx(u32 ctx_id)
return SCE_NP_SIGNALING_ERROR_CTX_NOT_FOUND; return SCE_NP_SIGNALING_ERROR_CTX_NOT_FOUND;
} }
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.remove_sig_ctx(ctx_id);
return CELL_OK; return CELL_OK;
} }
@ -6679,8 +6691,16 @@ error_code sceNpSignalingAddExtendedHandler(u32 ctx_id, vm::ptr<SceNpSignalingHa
return SCE_NP_SIGNALING_ERROR_NOT_INITIALIZED; return SCE_NP_SIGNALING_ERROR_NOT_INITIALIZED;
} }
auto& sigh = g_fxo->get<named_thread<signaling_handler>>(); auto ctx = get_signaling_context(ctx_id);
sigh.set_ext_sig_cb(ctx_id, handler, arg);
if (!ctx)
{
return SCE_NP_SIGNALING_ERROR_CTX_NOT_FOUND;
}
std::lock_guard lock(ctx->mutex);
ctx->ext_handler = handler;
ctx->ext_arg = arg;
return CELL_OK; return CELL_OK;
} }
@ -6701,6 +6721,15 @@ error_code sceNpSignalingSetCtxOpt(u32 ctx_id, s32 optname, s32 optval)
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT; return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
} }
auto ctx = get_signaling_context(ctx_id);
if (!ctx)
{
return SCE_NP_SIGNALING_ERROR_CTX_NOT_FOUND;
}
// TODO
return CELL_OK; return CELL_OK;
} }
@ -6720,6 +6749,15 @@ error_code sceNpSignalingGetCtxOpt(u32 ctx_id, s32 optname, vm::ptr<s32> optval)
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT; return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
} }
auto ctx = get_signaling_context(ctx_id);
if (!ctx)
{
return SCE_NP_SIGNALING_ERROR_CTX_NOT_FOUND;
}
// TODO
return CELL_OK; return CELL_OK;
} }

View file

@ -313,7 +313,10 @@ error_code sceNpMatching2Term2()
nph.is_NP2_Match2_init = false; nph.is_NP2_Match2_init = false;
} }
// TODO: for all contexts: sceNpMatching2DestroyContext idm::clear<match2_ctx>();
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.clear_match2_ctx();
return CELL_OK; return CELL_OK;
} }
@ -332,6 +335,9 @@ error_code sceNpMatching2DestroyContext(SceNpMatching2ContextId ctxId)
if (!destroy_match2_context(ctxId)) if (!destroy_match2_context(ctxId))
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND; return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.remove_match2_ctx(ctxId);
return CELL_OK; return CELL_OK;
} }
@ -439,7 +445,7 @@ error_code sceNpMatching2SearchRoom(
} }
error_code sceNpMatching2SignalingGetConnectionStatus( error_code sceNpMatching2SignalingGetConnectionStatus(
SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId memberId, vm::ptr<int> connStatus, vm::ptr<np_in_addr> peerAddr, vm::ptr<np_in_port_t> peerPort) SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId memberId, vm::ptr<s32> connStatus, vm::ptr<np_in_addr> peerAddr, vm::ptr<np_in_port_t> peerPort)
{ {
sceNp2.warning("sceNpMatching2SignalingGetConnectionStatus(ctxId=%d, roomId=%d, memberId=%d, connStatus=*0x%x, peerAddr=*0x%x, peerPort=*0x%x)", ctxId, roomId, memberId, connStatus, peerAddr, peerPort); sceNp2.warning("sceNpMatching2SignalingGetConnectionStatus(ctxId=%d, roomId=%d, memberId=%d, connStatus=*0x%x, peerAddr=*0x%x, peerPort=*0x%x)", ctxId, roomId, memberId, connStatus, peerAddr, peerPort);
@ -1333,8 +1339,19 @@ error_code sceNpMatching2RegisterSignalingCallback(SceNpMatching2ContextId ctxId
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED; return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
} }
auto ctx = get_match2_context(ctxId);
if (!ctx)
{
return SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND;
}
std::lock_guard lock(ctx->mutex);
ctx->signaling_cb = cbFunc;
ctx->signaling_cb_arg = cbFuncArg;
auto& sigh = g_fxo->get<named_thread<signaling_handler>>(); auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.set_sig2_cb(ctxId, cbFunc, cbFuncArg); sigh.add_match2_ctx(ctxId);
return CELL_OK; return CELL_OK;
} }

View file

@ -329,9 +329,14 @@ void lv2_socket::save(utils::serial& ar, bool save_only_this_class)
} }
} }
void sys_net_dump_data(std::string_view desc, const u8* data, s32 len) void sys_net_dump_data(std::string_view desc, const u8* data, s32 len, const void* addr)
{ {
sys_net_dump.trace("%s:%s", desc, fmt::buf_to_hexstring(data, len)); const sys_net_sockaddr_in_p2p* p2p_addr = reinterpret_cast<const sys_net_sockaddr_in_p2p*>(addr);
if (p2p_addr)
sys_net_dump.trace("%s(%s:%d:%d): %s", desc, np::ip_to_string(std::bit_cast<u32>(p2p_addr->sin_addr)), p2p_addr->sin_port, p2p_addr->sin_vport, fmt::buf_to_hexstring(data, len));
else
sys_net_dump.trace("%s: %s", desc, fmt::buf_to_hexstring(data, len));
} }
error_code sys_net_bnet_accept(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen) error_code sys_net_bnet_accept(ppu_thread& ppu, s32 s, vm::ptr<sys_net_sockaddr> addr, vm::ptr<u32> paddrlen)
@ -797,7 +802,7 @@ error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr<void> buf, u32
{ {
sn_addr = res_addr; sn_addr = res_addr;
std::memcpy(buf.get_ptr(), vec.data(), res); std::memcpy(buf.get_ptr(), vec.data(), res);
sys_net_dump_data("recvfrom", vec.data(), res); sys_net_dump_data("recvfrom", vec.data(), res, &res_addr);
} }
result = res; result = res;
@ -819,7 +824,7 @@ error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr<void> buf, u32
{ {
sn_addr = res_addr; sn_addr = res_addr;
std::memcpy(buf.get_ptr(), vec.data(), res); std::memcpy(buf.get_ptr(), vec.data(), res);
sys_net_dump_data("recvfrom", vec.data(), res); sys_net_dump_data("recvfrom", vec.data(), res, &res_addr);
} }
result = res; result = res;
lv2_obj::awake(&ppu); lv2_obj::awake(&ppu);
@ -1003,7 +1008,7 @@ error_code sys_net_bnet_sendto(ppu_thread& ppu, s32 s, vm::cptr<void> buf, u32 l
return -SYS_NET_EAFNOSUPPORT; return -SYS_NET_EAFNOSUPPORT;
} }
sys_net_dump_data("sendto", static_cast<const u8 *>(buf.get_ptr()), len); sys_net_dump_data("sendto", static_cast<const u8*>(buf.get_ptr()), len, addr ? addr.get_ptr() : nullptr);
const std::optional<sys_net_sockaddr> sn_addr = addr ? std::optional<sys_net_sockaddr>(*addr) : std::nullopt; const std::optional<sys_net_sockaddr> sn_addr = addr ? std::optional<sys_net_sockaddr>(*addr) : std::nullopt;
const std::vector<u8> buf_copy(vm::_ptr<const char>(buf.addr()), vm::_ptr<const char>(buf.addr()) + len); const std::vector<u8> buf_copy(vm::_ptr<const char>(buf.addr()), vm::_ptr<const char>(buf.addr()) + len);

View file

@ -241,8 +241,6 @@ std::optional<std::tuple<s32, std::vector<u8>, sys_net_sockaddr>> lv2_socket_p2p
lock.lock(); lock.lock();
} }
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());
if (data.empty()) if (data.empty())
{ {
if (so_nbio || (flags & SYS_NET_MSG_DONTWAIT)) if (so_nbio || (flags & SYS_NET_MSG_DONTWAIT))
@ -251,6 +249,8 @@ std::optional<std::tuple<s32, std::vector<u8>, sys_net_sockaddr>> lv2_socket_p2p
return std::nullopt; return std::nullopt;
} }
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());
std::vector<u8> res_buf(len); std::vector<u8> res_buf(len);
const auto& p2p_data = data.front(); const auto& p2p_data = data.front();
@ -288,9 +288,11 @@ std::optional<s32> lv2_socket_p2p::sendto(s32 flags, const std::vector<u8>& buf,
std::vector<u8> p2p_data(buf.size() + VPORT_P2P_HEADER_SIZE); std::vector<u8> p2p_data(buf.size() + VPORT_P2P_HEADER_SIZE);
const le_t<u16> p2p_vport_le = p2p_vport; const le_t<u16> p2p_vport_le = p2p_vport;
const le_t<u16> src_vport_le = vport;
const le_t<u16> p2p_flags_le = P2P_FLAG_P2P; const le_t<u16> p2p_flags_le = P2P_FLAG_P2P;
memcpy(p2p_data.data(), &p2p_vport_le, sizeof(u16)); memcpy(p2p_data.data(), &p2p_vport_le, sizeof(u16));
memcpy(p2p_data.data() + sizeof(u16), &p2p_flags_le, sizeof(u16)); memcpy(p2p_data.data() + sizeof(u16), &src_vport_le, sizeof(u16));
memcpy(p2p_data.data() + sizeof(u16) + sizeof(u16), &p2p_flags_le, sizeof(u16));
memcpy(p2p_data.data() + VPORT_P2P_HEADER_SIZE, buf.data(), buf.size()); memcpy(p2p_data.data() + VPORT_P2P_HEADER_SIZE, buf.data(), buf.size());
int native_flags = 0; int native_flags = 0;
@ -363,7 +365,7 @@ s32 lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native
{ {
std::lock_guard lock(mutex); std::lock_guard lock(mutex);
ensure(vport); ensure(vport);
sys_net.trace("[P2P] poll checking for 0x%X", sn_pfd.events);
// Check if it's a bound P2P socket // Check if it's a bound P2P socket
if ((sn_pfd.events & SYS_NET_POLLIN) && !data.empty()) if ((sn_pfd.events & SYS_NET_POLLIN) && !data.empty())
{ {
@ -396,7 +398,6 @@ std::tuple<bool, bool, bool> lv2_socket_p2p::select(bs_t<lv2_socket::poll_t> sel
if (selected & lv2_socket::poll_t::write) if (selected & lv2_socket::poll_t::write)
{ {
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());
write_set = true; write_set = true;
} }

View file

@ -225,10 +225,12 @@ std::vector<u8> generate_u2s_packet(const p2ps_encapsulated_tcp& header, const u
std::vector<u8> packet(packet_size); std::vector<u8> packet(packet_size);
u8* packet_data = packet.data(); u8* packet_data = packet.data();
le_t<u16> dst_port_le = +header.dst_port; le_t<u16> dst_port_le = +header.dst_port;
le_t<u16> src_port_le = +header.src_port;
le_t<u16> p2p_flags_le = P2P_FLAG_P2PS; le_t<u16> p2p_flags_le = P2P_FLAG_P2PS;
memcpy(packet_data, &dst_port_le, sizeof(u16)); memcpy(packet_data, &dst_port_le, sizeof(u16));
memcpy(packet_data + sizeof(u16), &p2p_flags_le, sizeof(u16)); memcpy(packet_data + sizeof(u16), &src_port_le, sizeof(u16));
memcpy(packet_data + sizeof(u16) + sizeof(u16), &p2p_flags_le, sizeof(u16));
memcpy(packet_data + VPORT_P2P_HEADER_SIZE, &header, sizeof(p2ps_encapsulated_tcp)); memcpy(packet_data + VPORT_P2P_HEADER_SIZE, &header, sizeof(p2ps_encapsulated_tcp));
if (datasize) if (datasize)
memcpy(packet_data + VPORT_P2P_HEADER_SIZE + sizeof(p2ps_encapsulated_tcp), data, datasize); memcpy(packet_data + VPORT_P2P_HEADER_SIZE + sizeof(p2ps_encapsulated_tcp), data, datasize);

View file

@ -204,7 +204,8 @@ bool nt_p2p_port::recv_data()
return true; return true;
} }
const u16 vport_flags = *reinterpret_cast<le_t<u16>*>(p2p_recv_data.data() + sizeof(u16)); const u16 src_vport = *reinterpret_cast<le_t<u16>*>(p2p_recv_data.data() + sizeof(u16));
const u16 vport_flags = *reinterpret_cast<le_t<u16>*>(p2p_recv_data.data() + sizeof(u16) + sizeof(u16));
std::vector<u8> p2p_data(recv_res - VPORT_P2P_HEADER_SIZE); std::vector<u8> p2p_data(recv_res - VPORT_P2P_HEADER_SIZE);
memcpy(p2p_data.data(), p2p_recv_data.data() + VPORT_P2P_HEADER_SIZE, p2p_data.size()); memcpy(p2p_data.data(), p2p_recv_data.data() + VPORT_P2P_HEADER_SIZE, p2p_data.size());
@ -218,7 +219,7 @@ bool nt_p2p_port::recv_data()
p2p_addr.sin_len = sizeof(sys_net_sockaddr_in); p2p_addr.sin_len = sizeof(sys_net_sockaddr_in);
p2p_addr.sin_family = SYS_NET_AF_INET; p2p_addr.sin_family = SYS_NET_AF_INET;
p2p_addr.sin_addr = std::bit_cast<be_t<u32>, u32>(reinterpret_cast<struct sockaddr_in*>(&native_addr)->sin_addr.s_addr); p2p_addr.sin_addr = std::bit_cast<be_t<u32>, u32>(reinterpret_cast<struct sockaddr_in*>(&native_addr)->sin_addr.s_addr);
p2p_addr.sin_vport = dst_vport; p2p_addr.sin_vport = src_vport;
p2p_addr.sin_port = std::bit_cast<be_t<u16>, u16>(reinterpret_cast<struct sockaddr_in*>(&native_addr)->sin_port); p2p_addr.sin_port = std::bit_cast<be_t<u16>, u16>(reinterpret_cast<struct sockaddr_in*>(&native_addr)->sin_port);
auto& bound_sockets = ::at32(bound_p2p_vports, dst_vport); auto& bound_sockets = ::at32(bound_p2p_vports, dst_vport);
@ -313,6 +314,6 @@ bool nt_p2p_port::recv_data()
} }
} }
sys_net.notice("Received a STREAM-P2P packet with no bound target"); sys_net.notice("Received a P2P packet with no bound target(dst_vport = %d)", dst_vport);
return true; return true;
} }

View file

@ -20,7 +20,8 @@
#endif #endif
#endif #endif
constexpr s32 VPORT_P2P_HEADER_SIZE = sizeof(u16) + sizeof(u16); // dst_vport src_vport flags
constexpr s32 VPORT_P2P_HEADER_SIZE = sizeof(u16) + sizeof(u16) + sizeof(u16);
enum VPORT_P2P_FLAGS enum VPORT_P2P_FLAGS
{ {

View file

@ -221,3 +221,7 @@ bool destroy_signaling_context(s32 ctx_id)
{ {
return idm::remove<signaling_ctx>(static_cast<u32>(ctx_id)); return idm::remove<signaling_ctx>(static_cast<u32>(ctx_id));
} }
std::shared_ptr<signaling_ctx> get_signaling_context(u32 ctx_id)
{
return idm::get_unlocked<signaling_ctx>(ctx_id);
}

View file

@ -7,6 +7,7 @@
#include "Utilities/mutex.h" #include "Utilities/mutex.h"
#include "Emu/IdManager.h"
#include "Emu/Memory/vm_ptr.h" #include "Emu/Memory/vm_ptr.h"
#include "Emu/Cell/Modules/sceNp.h" #include "Emu/Cell/Modules/sceNp.h"
#include "Emu/Cell/Modules/sceNp2.h" #include "Emu/Cell/Modules/sceNp2.h"
@ -190,6 +191,8 @@ struct match2_ctx
static const u32 id_count = 255; // TODO: constant here? static const u32 id_count = 255; // TODO: constant here?
SAVESTATE_INIT_POS(27); SAVESTATE_INIT_POS(27);
shared_mutex mutex;
SceNpCommunicationId communicationId{}; SceNpCommunicationId communicationId{};
SceNpCommunicationPassphrase passphrase{}; SceNpCommunicationPassphrase passphrase{};
@ -197,6 +200,9 @@ struct match2_ctx
vm::ptr<void> context_callback_param{}; vm::ptr<void> context_callback_param{};
SceNpMatching2RequestOptParam default_match2_optparam{}; SceNpMatching2RequestOptParam default_match2_optparam{};
vm::ptr<SceNpMatching2SignalingCallback> signaling_cb{};
vm::ptr<void> signaling_cb_arg{};
}; };
u16 create_match2_context(vm::cptr<SceNpCommunicationId> communicationId, vm::cptr<SceNpCommunicationPassphrase> passphrase); u16 create_match2_context(vm::cptr<SceNpCommunicationId> communicationId, vm::cptr<SceNpCommunicationPassphrase> passphrase);
bool check_match2_context(u16 ctx_id); bool check_match2_context(u16 ctx_id);
@ -259,9 +265,14 @@ struct signaling_ctx
static const u32 id_count = SCE_NP_SIGNALING_CTX_MAX; static const u32 id_count = SCE_NP_SIGNALING_CTX_MAX;
SAVESTATE_INIT_POS(31); SAVESTATE_INIT_POS(31);
shared_mutex mutex;
SceNpId npid{}; SceNpId npid{};
vm::ptr<SceNpSignalingHandler> handler{}; vm::ptr<SceNpSignalingHandler> handler{};
vm::ptr<void> arg{}; vm::ptr<void> arg{};
vm::ptr<SceNpSignalingHandler> ext_handler{};
vm::ptr<void> ext_arg{};
}; };
s32 create_signaling_context(vm::ptr<SceNpId> npid, vm::ptr<SceNpSignalingHandler> handler, vm::ptr<void> arg); s32 create_signaling_context(vm::ptr<SceNpId> npid, vm::ptr<SceNpSignalingHandler> handler, vm::ptr<void> arg);
std::shared_ptr<signaling_ctx> get_signaling_context(u32 ctx_id);
bool destroy_signaling_context(s32 ctx_id); bool destroy_signaling_context(s32 ctx_id);

View file

@ -84,7 +84,7 @@ namespace rpcn
rpcn_log.notice("online: %s, pr_com_id: %s, pr_title: %s, pr_status: %s, pr_comment: %s, pr_data: %s", online ? "true" : "false", pr_com_id.data, pr_title, pr_status, pr_comment, fmt::buf_to_hexstring(pr_data.data(), pr_data.size())); rpcn_log.notice("online: %s, pr_com_id: %s, pr_title: %s, pr_status: %s, pr_comment: %s, pr_data: %s", online ? "true" : "false", pr_com_id.data, pr_title, pr_status, pr_comment, fmt::buf_to_hexstring(pr_data.data(), pr_data.size()));
} }
constexpr u32 RPCN_PROTOCOL_VERSION = 23; constexpr u32 RPCN_PROTOCOL_VERSION = 24;
constexpr usz RPCN_HEADER_SIZE = 15; constexpr usz RPCN_HEADER_SIZE = 15;
bool is_error(ErrorType err) bool is_error(ErrorType err)

View file

@ -46,70 +46,113 @@ signaling_handler::signaling_handler()
//// SIGNALING CALLBACKS //// //// SIGNALING CALLBACKS ////
///////////////////////////// /////////////////////////////
void signaling_handler::set_sig_cb(u32 sig_cb_ctx, vm::ptr<SceNpSignalingHandler> sig_cb, vm::ptr<void> sig_cb_arg) void signaling_handler::add_sig_ctx(u32 ctx_id)
{ {
std::lock_guard lock(data_mutex); std::lock_guard lock(data_mutex);
this->sig_cb_ctx = sig_cb_ctx; sig_ctx_lst.insert(ctx_id);
this->sig_cb = sig_cb;
this->sig_cb_arg = sig_cb_arg;
} }
void signaling_handler::set_ext_sig_cb(u32 sig_ext_cb_ctx, vm::ptr<SceNpSignalingHandler> sig_ext_cb, vm::ptr<void> sig_ext_cb_arg) void signaling_handler::remove_sig_ctx(u32 ctx_id)
{ {
std::lock_guard lock(data_mutex); std::lock_guard lock(data_mutex);
this->sig_ext_cb_ctx = sig_ext_cb_ctx; sig_ctx_lst.erase(ctx_id);
this->sig_ext_cb = sig_ext_cb;
this->sig_ext_cb_arg = sig_ext_cb_arg;
} }
void signaling_handler::set_sig2_cb(u16 sig2_cb_ctx, vm::ptr<SceNpMatching2SignalingCallback> sig2_cb, vm::ptr<void> sig2_cb_arg) void signaling_handler::clear_sig_ctx()
{ {
std::lock_guard lock(data_mutex); std::lock_guard lock(data_mutex);
this->sig2_cb_ctx = sig2_cb_ctx; sig_ctx_lst.clear();
this->sig2_cb = sig2_cb;
this->sig2_cb_arg = sig2_cb_arg;
} }
void signaling_handler::signal_sig_callback(u32 conn_id, int event, int error_code) void signaling_handler::add_match2_ctx(u16 ctx_id)
{ {
if (sig_cb) std::lock_guard lock(data_mutex);
match2_ctx_lst.insert(ctx_id);
}
void signaling_handler::remove_match2_ctx(u16 ctx_id)
{
std::lock_guard lock(data_mutex);
match2_ctx_lst.erase(ctx_id);
}
void signaling_handler::clear_match2_ctx()
{
std::lock_guard lock(data_mutex);
match2_ctx_lst.clear();
}
void signaling_handler::signal_sig_callback(u32 conn_id, s32 event, s32 error_code)
{
for (const auto& ctx_id : sig_ctx_lst)
{ {
sysutil_register_cb([sig_cb = this->sig_cb, sig_cb_ctx = this->sig_cb_ctx, conn_id, event, error_code, sig_cb_arg = this->sig_cb_arg](ppu_thread& cb_ppu) -> s32 const auto ctx = get_signaling_context(ctx_id);
if (!ctx)
continue;
std::lock_guard lock(ctx->mutex);
if (ctx->handler)
{
sysutil_register_cb([sig_cb = ctx->handler, sig_cb_ctx = ctx_id, conn_id, event, error_code, sig_cb_arg = ctx->arg](ppu_thread& cb_ppu) -> s32
{ {
sig_cb(cb_ppu, sig_cb_ctx, conn_id, event, error_code, sig_cb_arg); sig_cb(cb_ppu, sig_cb_ctx, conn_id, event, error_code, sig_cb_arg);
return 0; return 0;
}); });
sign_log.notice("Called sig CB: 0x%x (conn_id: %d)", event, conn_id); sign_log.notice("Called sig CB: 0x%x (conn_id: %d)", event, conn_id);
} }
}
// extended callback also receives normal events // extended callback also receives normal events
signal_ext_sig_callback(conn_id, event, error_code); signal_ext_sig_callback(conn_id, event, error_code);
} }
void signaling_handler::signal_ext_sig_callback(u32 conn_id, int event, int error_code) const void signaling_handler::signal_ext_sig_callback(u32 conn_id, s32 event, s32 error_code) const
{ {
if (sig_ext_cb) for (const auto ctx_id : sig_ctx_lst)
{ {
sysutil_register_cb([sig_ext_cb = this->sig_ext_cb, sig_ext_cb_ctx = this->sig_ext_cb_ctx, conn_id, event, error_code, sig_ext_cb_arg = this->sig_ext_cb_arg](ppu_thread& cb_ppu) -> s32 const auto ctx = get_signaling_context(ctx_id);
if (!ctx)
continue;
std::lock_guard lock(ctx->mutex);
if (ctx->ext_handler)
{
sysutil_register_cb([sig_ext_cb = ctx->ext_handler, sig_ext_cb_ctx = ctx_id, conn_id, event, error_code, sig_ext_cb_arg = ctx->ext_arg](ppu_thread& cb_ppu) -> s32
{ {
sig_ext_cb(cb_ppu, sig_ext_cb_ctx, conn_id, event, error_code, sig_ext_cb_arg); sig_ext_cb(cb_ppu, sig_ext_cb_ctx, conn_id, event, error_code, sig_ext_cb_arg);
return 0; return 0;
}); });
sign_log.notice("Called EXT sig CB: 0x%x (conn_id: %d)", event, conn_id); sign_log.notice("Called EXT sig CB: 0x%x (conn_id: %d)", event, conn_id);
} }
}
} }
void signaling_handler::signal_sig2_callback(u64 room_id, u16 member_id, SceNpMatching2Event event, int error_code) const void signaling_handler::signal_sig2_callback(u64 room_id, u16 member_id, SceNpMatching2Event event, s32 error_code) const
{ {
if (room_id && sig2_cb) if (room_id)
{ {
sysutil_register_cb([sig2_cb = this->sig2_cb, sig2_cb_ctx = this->sig2_cb_ctx, room_id, member_id, event, error_code, sig2_cb_arg = this->sig2_cb_arg](ppu_thread& cb_ppu) -> s32 for (const auto ctx_id : match2_ctx_lst)
{
const auto ctx = get_match2_context(ctx_id);
if (!ctx)
continue;
if (ctx->signaling_cb)
{
sysutil_register_cb([sig2_cb = ctx->signaling_cb, sig2_cb_ctx = ctx_id, room_id, member_id, event, error_code, sig2_cb_arg = ctx->signaling_cb_arg](ppu_thread& cb_ppu) -> s32
{ {
sig2_cb(cb_ppu, sig2_cb_ctx, room_id, member_id, event, error_code, sig2_cb_arg); sig2_cb(cb_ppu, sig2_cb_ctx, room_id, member_id, event, error_code, sig2_cb_arg);
return 0; return 0;
}); });
sign_log.notice("Called sig2 CB: 0x%x (room_id: %d, member_id: %d)", event, room_id, member_id); sign_log.notice("Called sig2 CB: 0x%x (room_id: %d, member_id: %d)", event, room_id, member_id);
} }
}
}
} }
/////////////////////////////////// ///////////////////////////////////
@ -524,7 +567,7 @@ void signaling_handler::update_si_mapped_addr(std::shared_ptr<signaling_info>& s
} }
} }
void signaling_handler::update_si_status(std::shared_ptr<signaling_info>& si, s32 new_status, int error_code) void signaling_handler::update_si_status(std::shared_ptr<signaling_info>& si, s32 new_status, s32 error_code)
{ {
if (!si) if (!si)
return; return;
@ -666,7 +709,10 @@ void signaling_handler::stop_sig_nl(u32 conn_id, bool forceful)
// If forceful we don't go through any transition and don't call any CB // If forceful we don't go through any transition and don't call any CB
if (forceful) if (forceful)
{
si->conn_status = SCE_NP_SIGNALING_CONN_STATUS_INACTIVE; si->conn_status = SCE_NP_SIGNALING_CONN_STATUS_INACTIVE;
si->op_activated = false;
}
// Do not queue packets for an already dead connection // Do not queue packets for an already dead connection
if (si->conn_status == SCE_NP_SIGNALING_CONN_STATUS_INACTIVE) if (si->conn_status == SCE_NP_SIGNALING_CONN_STATUS_INACTIVE)

View file

@ -68,9 +68,12 @@ public:
std::optional<u32> get_conn_id_from_npid(const SceNpId& npid); std::optional<u32> get_conn_id_from_npid(const SceNpId& npid);
std::optional<u32> get_conn_id_from_addr(u32 addr, u16 port); std::optional<u32> get_conn_id_from_addr(u32 addr, u16 port);
void set_sig_cb(u32 sig_cb_ctx, vm::ptr<SceNpSignalingHandler> sig_cb, vm::ptr<void> sig_cb_arg); void add_sig_ctx(u32 ctx_id);
void set_ext_sig_cb(u32 sig_ext_cb_ctx, vm::ptr<SceNpSignalingHandler> sig_ext_cb, vm::ptr<void> sig_ext_cb_arg); void remove_sig_ctx(u32 ctx_id);
void set_sig2_cb(u16 sig2_cb_ctx, vm::ptr<SceNpMatching2SignalingCallback> sig2_cb, vm::ptr<void> sig2_cb_arg); void clear_sig_ctx();
void add_match2_ctx(u16 ctx_id);
void remove_match2_ctx(u16 ctx_id);
void clear_match2_ctx();
void start_sig(u32 conn_id, u32 addr, u16 port); void start_sig(u32 conn_id, u32 addr, u16 port);
void stop_sig(u32 conn_id, bool forceful); void stop_sig(u32 conn_id, bool forceful);
@ -106,28 +109,19 @@ private:
std::shared_ptr<signaling_info> sig_info; std::shared_ptr<signaling_info> sig_info;
}; };
u32 sig_cb_ctx = 0; std::set<u32> sig_ctx_lst;
vm::ptr<SceNpSignalingHandler> sig_cb{}; std::set<u16> match2_ctx_lst;
vm::ptr<void> sig_cb_arg{};
u32 sig_ext_cb_ctx = 0;
vm::ptr<SceNpSignalingHandler> sig_ext_cb{};
vm::ptr<void> sig_ext_cb_arg{};
u16 sig2_cb_ctx = 0;
vm::ptr<SceNpMatching2SignalingCallback> sig2_cb{};
vm::ptr<void> sig2_cb_arg{};
static u64 get_micro_timestamp(const std::chrono::steady_clock::time_point& time_point); static u64 get_micro_timestamp(const std::chrono::steady_clock::time_point& time_point);
u32 get_always_conn_id(const SceNpId& npid); u32 get_always_conn_id(const SceNpId& npid);
static void update_si_addr(std::shared_ptr<signaling_info>& si, u32 new_addr, u16 new_port); static void update_si_addr(std::shared_ptr<signaling_info>& si, u32 new_addr, u16 new_port);
static void update_si_mapped_addr(std::shared_ptr<signaling_info>& si, u32 new_addr, u16 new_port); static void update_si_mapped_addr(std::shared_ptr<signaling_info>& si, u32 new_addr, u16 new_port);
void update_si_status(std::shared_ptr<signaling_info>& si, s32 new_status, int error_code); void update_si_status(std::shared_ptr<signaling_info>& si, s32 new_status, s32 error_code);
void update_ext_si_status(std::shared_ptr<signaling_info>& si, bool op_activated); void update_ext_si_status(std::shared_ptr<signaling_info>& si, bool op_activated);
void signal_sig_callback(u32 conn_id, int event, int error_code); void signal_sig_callback(u32 conn_id, s32 event, s32 error_code);
void signal_ext_sig_callback(u32 conn_id, int event, int error_code) const; void signal_ext_sig_callback(u32 conn_id, s32 event, s32 error_code) const;
void signal_sig2_callback(u64 room_id, u16 member_id, SceNpMatching2Event event, int error_code) const; void signal_sig2_callback(u64 room_id, u16 member_id, SceNpMatching2Event event, s32 error_code) const;
static bool validate_signaling_packet(const signaling_packet* sp); static bool validate_signaling_packet(const signaling_packet* sp);
void reschedule_packet(std::shared_ptr<signaling_info>& si, SignalingCommand cmd, steady_clock::time_point new_timepoint); void reschedule_packet(std::shared_ptr<signaling_info>& si, SignalingCommand cmd, steady_clock::time_point new_timepoint);