Skip to content

Commit

Permalink
improves sig_ctx handling, sys_net logging and fixes udpp2p protocol (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
RipleyTom authored Feb 24, 2024
1 parent 3067c86 commit ac8e914
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 81 deletions.
54 changes: 46 additions & 8 deletions rpcs3/Emu/Cell/Modules/sceNp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,13 @@ error_code sceNpTerm()
nph.terminate_NP();
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;
}

Expand Down Expand Up @@ -6636,15 +6643,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 +6674,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 +6691,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 +6721,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 +6749,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
23 changes: 20 additions & 3 deletions rpcs3/Emu/Cell/Modules/sceNp2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,10 @@ error_code sceNpMatching2Term2()
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;
}
Expand All @@ -332,6 +335,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 +445,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 +1339,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
11 changes: 6 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,8 +241,6 @@ 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())
{
if (so_nbio || (flags & SYS_NET_MSG_DONTWAIT))
Expand All @@ -251,6 +249,8 @@ std::optional<std::tuple<s32, std::vector<u8>, sys_net_sockaddr>> lv2_socket_p2p
return std::nullopt;
}

sys_net.trace("[P2P] p2p_data for vport %d contains %d elements", vport, data.size());

std::vector<u8> res_buf(len);

const auto& p2p_data = data.front();
Expand Down Expand Up @@ -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);
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 @@ -363,7 +365,7 @@ s32 lv2_socket_p2p::poll(sys_net_pollfd& sn_pfd, [[maybe_unused]] pollfd& native
{
std::lock_guard lock(mutex);
ensure(vport);
sys_net.trace("[P2P] poll checking for 0x%X", sn_pfd.events);

// Check if it's a bound P2P socket
if ((sn_pfd.events & SYS_NET_POLLIN) && !data.empty())
{
Expand Down Expand Up @@ -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)
{
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);
}
11 changes: 11 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,14 @@ 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);
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

0 comments on commit ac8e914

Please sign in to comment.