Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 48 additions & 8 deletions rpcs3/Emu/Cell/Modules/sceNp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,15 @@ error_code sceNpTerm()
nph.terminate_NP();
nph.is_NP_init = false;

const usz num_signaling_ctx = destroy_all_contexts<signaling_ctx>();
if (num_signaling_ctx)
sceNp.warning("Destroyed %d active sceNpSignalingCtxs", num_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;
}

Expand Down Expand Up @@ -6636,15 +6645,17 @@ error_code sceNpSignalingCreateCtx(vm::ptr<SceNpId> npId, vm::ptr<SceNpSignaling
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
}

// if (current_contexts > SCE_NP_SIGNALING_CTX_MAX)
//{
// return SCE_NP_SIGNALING_ERROR_CTX_MAX;
//}
u32 id = create_signaling_context(npId, handler, arg);

if (!id)
{
return SCE_NP_SIGNALING_ERROR_CTX_MAX;
}

*ctx_id = create_signaling_context(npId, handler, arg);
*ctx_id = id;

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;
}
Expand All @@ -6665,6 +6676,9 @@ error_code sceNpSignalingDestroyCtx(u32 ctx_id)
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;
}

Expand All @@ -6679,8 +6693,16 @@ error_code sceNpSignalingAddExtendedHandler(u32 ctx_id, vm::ptr<SceNpSignalingHa
return SCE_NP_SIGNALING_ERROR_NOT_INITIALIZED;
}

auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.set_ext_sig_cb(ctx_id, handler, arg);
auto ctx = get_signaling_context(ctx_id);

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;
}
Expand All @@ -6701,6 +6723,15 @@ error_code sceNpSignalingSetCtxOpt(u32 ctx_id, s32 optname, s32 optval)
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;
}

Expand All @@ -6720,6 +6751,15 @@ error_code sceNpSignalingGetCtxOpt(u32 ctx_id, s32 optname, vm::ptr<s32> optval)
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;
}

Expand Down
25 changes: 22 additions & 3 deletions rpcs3/Emu/Cell/Modules/sceNp2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,12 @@ error_code sceNpMatching2Term2()
nph.is_NP2_Match2_init = false;
}

// TODO: for all contexts: sceNpMatching2DestroyContext
const usz num_match2_ctx = destroy_all_contexts<match2_ctx>();
if (num_match2_ctx)
sceNp2.warning("Destroyed %d active SceNpMatching2Contexts", num_match2_ctx);

auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.clear_match2_ctx();

return CELL_OK;
}
Expand All @@ -332,6 +337,9 @@ error_code sceNpMatching2DestroyContext(SceNpMatching2ContextId ctxId)
if (!destroy_match2_context(ctxId))
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;
}

Expand Down Expand Up @@ -439,7 +447,7 @@ error_code sceNpMatching2SearchRoom(
}

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);

Expand Down Expand Up @@ -1333,8 +1341,19 @@ error_code sceNpMatching2RegisterSignalingCallback(SceNpMatching2ContextId ctxId
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>>();
sigh.set_sig2_cb(ctxId, cbFunc, cbFuncArg);
sigh.add_match2_ctx(ctxId);

return CELL_OK;
}
Expand Down
15 changes: 10 additions & 5 deletions rpcs3/Emu/Cell/lv2/sys_net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -797,7 +802,7 @@ error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr<void> buf, u32
{
sn_addr = res_addr;
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;
Expand All @@ -819,7 +824,7 @@ error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr<void> buf, u32
{
sn_addr = res_addr;
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;
lv2_obj::awake(&ppu);
Expand Down Expand Up @@ -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;
}

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::vector<u8> buf_copy(vm::_ptr<const char>(buf.addr()), vm::_ptr<const char>(buf.addr()) + len);
Expand Down
19 changes: 14 additions & 5 deletions rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ std::optional<std::tuple<s32, std::vector<u8>, sys_net_sockaddr>> lv2_socket_p2p
lock.lock();
}

sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());
if (!data.empty())
RipleyTom marked this conversation as resolved.
Show resolved Hide resolved
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());

if (data.empty())
{
Expand Down Expand Up @@ -288,9 +289,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);
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;
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());

int native_flags = 0;
Expand Down Expand Up @@ -367,7 +370,9 @@ s32 lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native
// Check if it's a bound P2P socket
if ((sn_pfd.events & SYS_NET_POLLIN) && !data.empty())
{
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());
if (data.size())
RipleyTom marked this conversation as resolved.
Show resolved Hide resolved
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());

sn_pfd.revents |= SYS_NET_POLLIN;
}

Expand All @@ -390,13 +395,17 @@ std::tuple<bool, bool, bool> lv2_socket_p2p::select(bs_t<lv2_socket::poll_t> sel
// Check if it's a bound P2P socket
if ((selected & lv2_socket::poll_t::read) && vport && !data.empty())
{
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());
if (!data.empty())
RipleyTom marked this conversation as resolved.
Show resolved Hide resolved
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());

read_set = true;
}

if (selected & lv2_socket::poll_t::write)
{
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());
if (!data.empty())
sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());

write_set = true;
}

Expand Down
4 changes: 3 additions & 1 deletion rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_p2ps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,12 @@ std::vector<u8> generate_u2s_packet(const p2ps_encapsulated_tcp& header, const u
std::vector<u8> packet(packet_size);
u8* packet_data = packet.data();
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;

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));
if (datasize)
memcpy(packet_data + VPORT_P2P_HEADER_SIZE + sizeof(p2ps_encapsulated_tcp), data, datasize);
Expand Down
7 changes: 4 additions & 3 deletions rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ bool nt_p2p_port::recv_data()
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);
memcpy(p2p_data.data(), p2p_recv_data.data() + VPORT_P2P_HEADER_SIZE, p2p_data.size());

Expand All @@ -218,7 +219,7 @@ bool nt_p2p_port::recv_data()
p2p_addr.sin_len = sizeof(sys_net_sockaddr_in);
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_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);

auto& bound_sockets = ::at32(bound_p2p_vports, dst_vport);
Expand Down Expand Up @@ -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;
}
3 changes: 2 additions & 1 deletion rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
#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
{
Expand Down
4 changes: 4 additions & 0 deletions rpcs3/Emu/NP/np_contexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,7 @@ bool destroy_signaling_context(s32 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);
}
29 changes: 29 additions & 0 deletions rpcs3/Emu/NP/np_contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "Utilities/mutex.h"

#include "Emu/IdManager.h"
#include "Emu/Memory/vm_ptr.h"
#include "Emu/Cell/Modules/sceNp.h"
#include "Emu/Cell/Modules/sceNp2.h"
Expand Down Expand Up @@ -190,13 +191,18 @@ struct match2_ctx
static const u32 id_count = 255; // TODO: constant here?
SAVESTATE_INIT_POS(27);

shared_mutex mutex;

SceNpCommunicationId communicationId{};
SceNpCommunicationPassphrase passphrase{};

vm::ptr<SceNpMatching2ContextCallback> context_callback{};
vm::ptr<void> context_callback_param{};

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);
bool check_match2_context(u16 ctx_id);
Expand Down Expand Up @@ -259,9 +265,32 @@ struct signaling_ctx
static const u32 id_count = SCE_NP_SIGNALING_CTX_MAX;
SAVESTATE_INIT_POS(31);

shared_mutex mutex;

SceNpId npid{};
vm::ptr<SceNpSignalingHandler> handler{};
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);
std::shared_ptr<signaling_ctx> get_signaling_context(u32 ctx_id);
bool destroy_signaling_context(s32 ctx_id);

template <typename T>
usz destroy_all_contexts()
{
std::set<u32> list_ctx;

idm::select<T>([&](u32 id, [[maybe_unused]] T& s)
RipleyTom marked this conversation as resolved.
Show resolved Hide resolved
{
list_ctx.insert(id);
});

for (const auto id : list_ctx)
{
idm::remove<T>(id);
}

return list_ctx.size();
}
2 changes: 1 addition & 1 deletion rpcs3/Emu/NP/rpcn_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}

constexpr u32 RPCN_PROTOCOL_VERSION = 23;
constexpr u32 RPCN_PROTOCOL_VERSION = 24;
constexpr usz RPCN_HEADER_SIZE = 15;

bool is_error(ErrorType err)
Expand Down
Loading