Skip to content

Commit

Permalink
RPCN v0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
RipleyTom committed May 23, 2022
1 parent 608f823 commit 90a31d8
Show file tree
Hide file tree
Showing 16 changed files with 270 additions and 105 deletions.
79 changes: 73 additions & 6 deletions rpcs3/Emu/Cell/Modules/sceNp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3091,7 +3091,7 @@ error_code sceNpManagerGetOnlineId(vm::ptr<SceNpOnlineId> onlineId)

error_code sceNpManagerGetNpId(ppu_thread&, vm::ptr<SceNpId> npId)
{
sceNp.warning("sceNpManagerGetNpId(npId=*0x%x)", npId);
sceNp.trace("sceNpManagerGetNpId(npId=*0x%x)", npId);

auto& nph = g_fxo->get<named_thread<np::np_handler>>();

Expand Down Expand Up @@ -5103,7 +5103,7 @@ error_code sceNpSignalingGetConnectionStatus(u32 ctx_id, u32 conn_id, vm::ptr<s3

error_code sceNpSignalingGetConnectionInfo(u32 ctx_id, u32 conn_id, s32 code, vm::ptr<SceNpSignalingConnectionInfo> info)
{
sceNp.todo("sceNpSignalingGetConnectionInfo(ctx_id=%d, conn_id=%d, code=%d, info=*0x%x)", ctx_id, conn_id, code, info);
sceNp.warning("sceNpSignalingGetConnectionInfo(ctx_id=%d, conn_id=%d, code=%d, info=*0x%x)", ctx_id, conn_id, code, info);

auto& nph = g_fxo->get<named_thread<np::np_handler>>();

Expand All @@ -5112,17 +5112,64 @@ error_code sceNpSignalingGetConnectionInfo(u32 ctx_id, u32 conn_id, s32 code, vm
return SCE_NP_SIGNALING_ERROR_NOT_INITIALIZED;
}

if (!info)
if (!info || code < 1 || code > 6)
{
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
}

switch (code)
{
case SCE_NP_SIGNALING_CONN_INFO_RTT:
{
info->rtt = 20000; // HACK
break;
}
case SCE_NP_SIGNALING_CONN_INFO_BANDWIDTH:
{
info->bandwidth = 10'000'000; // 10 MBPS HACK
break;
}
case SCE_NP_SIGNALING_CONN_INFO_PEER_NPID:
{
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
const auto si = sigh.get_sig_infos(conn_id);
info->npId = si.npid;
break;
}
case SCE_NP_SIGNALING_CONN_INFO_PEER_ADDRESS:
{
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
const auto si = sigh.get_sig_infos(conn_id);
info->address.port = std::bit_cast<u16, be_t<u16>>(si.port);
info->address.addr.np_s_addr = si.addr;
break;
}
case SCE_NP_SIGNALING_CONN_INFO_MAPPED_ADDRESS:
{
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
const auto si = sigh.get_sig_infos(conn_id);
info->address.port = std::bit_cast<u16, be_t<u16>>(si.mapped_port);
info->address.addr.np_s_addr = si.mapped_addr;
break;
}
case SCE_NP_SIGNALING_CONN_INFO_PACKET_LOSS:
{
info->packet_loss = 1; // HACK
break;
}
default:
{
sceNp.fatal("sceNpSignalingGetConnectionInfo Unimplemented code: %d", code);
return CELL_OK;
}
}

return CELL_OK;
}

error_code sceNpSignalingGetConnectionFromNpId(u32 ctx_id, vm::ptr<SceNpId> npId, vm::ptr<u32> conn_id)
{
sceNp.todo("sceNpSignalingGetConnectionFromNpId(ctx_id=%d, npId=*0x%x, conn_id=*0x%x)", ctx_id, npId, conn_id);
sceNp.notice("sceNpSignalingGetConnectionFromNpId(ctx_id=%d, npId=*0x%x, conn_id=*0x%x)", ctx_id, npId, conn_id);

auto& nph = g_fxo->get<named_thread<np::np_handler>>();

Expand All @@ -5136,12 +5183,22 @@ error_code sceNpSignalingGetConnectionFromNpId(u32 ctx_id, vm::ptr<SceNpId> npId
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
}

auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
const auto found_conn_id = sigh.get_conn_id_from_npid(npId.get_ptr());

if (!found_conn_id)
{
return SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND;
}

*conn_id = *found_conn_id;

return CELL_OK;
}

error_code sceNpSignalingGetConnectionFromPeerAddress(u32 ctx_id, vm::ptr<np_in_addr> peer_addr, np_in_port_t peer_port, vm::ptr<u32> conn_id)
error_code sceNpSignalingGetConnectionFromPeerAddress(u32 ctx_id, np_in_addr_t peer_addr, np_in_port_t peer_port, vm::ptr<u32> conn_id)
{
sceNp.todo("sceNpSignalingGetConnectionFromPeerAddress(ctx_id=%d, peer_addr=*0x%x, peer_port=%d, conn_id=*0x%x)", ctx_id, peer_addr, peer_port, conn_id);
sceNp.warning("sceNpSignalingGetConnectionFromPeerAddress(ctx_id=%d, peer_addr=*0x%x, peer_port=%d, conn_id=*0x%x)", ctx_id, peer_addr, peer_port, conn_id);

auto& nph = g_fxo->get<named_thread<np::np_handler>>();

Expand All @@ -5155,6 +5212,16 @@ error_code sceNpSignalingGetConnectionFromPeerAddress(u32 ctx_id, vm::ptr<np_in_
return SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT;
}

auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
const auto found_conn_id = sigh.get_conn_id_from_addr(peer_addr, peer_port);

if (!found_conn_id)
{
return SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND;
}

*conn_id = *found_conn_id;

return CELL_OK;
}

Expand Down
10 changes: 8 additions & 2 deletions rpcs3/Emu/Cell/Modules/sceNp2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,11 @@ error_code sceNpMatching2SignalingGetConnectionInfo(
return SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED;
}

if (!connInfo || code < 1 || code > 6)
{
return SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT;
}

switch (code)
{
case SCE_NP_SIGNALING_CONN_INFO_RTT:
Expand All @@ -625,8 +630,9 @@ error_code sceNpMatching2SignalingGetConnectionInfo(
}
case SCE_NP_SIGNALING_CONN_INFO_PEER_NPID:
{
// TODO: need an update to whole signaling as matching2 signaling ignores npids atm
sceNp2.fatal("sceNpMatching2SignalingGetConnectionInfo Unimplemented SCE_NP_SIGNALING_CONN_INFO_PEER_NPID");
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
const auto si = sigh.get_sig2_infos(roomId, memberId);
connInfo->npId = si.npid;
break;
}
case SCE_NP_SIGNALING_CONN_INFO_PEER_ADDRESS:
Expand Down
35 changes: 18 additions & 17 deletions rpcs3/Emu/Cell/lv2/sys_net/lv2_socket_raw.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "stdafx.h"
#include "lv2_socket_raw.h"
#include "Emu/NP/vport0.h"

LOG_CHANNEL(sys_net);

Expand All @@ -10,31 +11,37 @@ lv2_socket_raw::lv2_socket_raw(lv2_socket_family family, lv2_socket_type type, l

std::tuple<bool, s32, std::shared_ptr<lv2_socket>, sys_net_sockaddr> lv2_socket_raw::accept([[maybe_unused]] bool is_lock)
{
sys_net.todo("lv2_socket_raw::accept");
return {};
}

s32 lv2_socket_raw::bind([[maybe_unused]] const sys_net_sockaddr& addr, [[maybe_unused]] s32 ps3_id)
{
sys_net.todo("lv2_socket_raw::bind");
sys_net.fatal("[RAW] accept() called on a RAW socket");
return {};
}

std::optional<s32> lv2_socket_raw::connect([[maybe_unused]] const sys_net_sockaddr& addr)
{
sys_net.todo("lv2_socket_raw::connect");
sys_net.fatal("[RAW] connect() called on a RAW socket");
return CELL_OK;
}

s32 lv2_socket_raw::connect_followup()
{
sys_net.todo("lv2_socket_raw::connect_followup");
sys_net.fatal("[RAW] connect_followup() called on a RAW socket");
return CELL_OK;
}

std::pair<s32, sys_net_sockaddr> lv2_socket_raw::getpeername()
{
sys_net.todo("lv2_socket_raw::getpeername");
sys_net.todo("[RAW] getpeername() called on a RAW socket");
return {};
}

s32 lv2_socket_raw::listen([[maybe_unused]] s32 backlog)
{
sys_net.todo("[RAW] listen() called on a RAW socket");
return {};
}

s32 lv2_socket_raw::bind([[maybe_unused]] const sys_net_sockaddr& addr, [[maybe_unused]] s32 ps3_id)
{
sys_net.todo("lv2_socket_raw::bind");
return {};
}

Expand All @@ -56,16 +63,10 @@ s32 lv2_socket_raw::setsockopt([[maybe_unused]] s32 level, [[maybe_unused]] s32
return {};
}

s32 lv2_socket_raw::listen([[maybe_unused]] s32 backlog)
{
sys_net.todo("lv2_socket_raw::listen");
return {};
}

std::optional<std::tuple<s32, std::vector<u8>, sys_net_sockaddr>> lv2_socket_raw::recvfrom([[maybe_unused]] s32 flags, [[maybe_unused]] u32 len, [[maybe_unused]] bool is_lock)
{
sys_net.todo("lv2_socket_raw::recvfrom");
return {{{}, {}, {}}};
return {};
}

std::optional<s32> lv2_socket_raw::sendto([[maybe_unused]] s32 flags, [[maybe_unused]] const std::vector<u8>& buf, [[maybe_unused]] std::optional<sys_net_sockaddr> opt_sn_addr, [[maybe_unused]] bool is_lock)
Expand Down
62 changes: 38 additions & 24 deletions rpcs3/Emu/Cell/lv2/sys_net/nt_p2p_port.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "util/asm.hpp"
#include "sys_net_helpers.h"
#include "Emu/NP/signaling_handler.h"
#include "Emu/NP/vport0.h"

LOG_CHANNEL(sys_net);

Expand Down Expand Up @@ -118,35 +119,48 @@ bool nt_p2p_port::recv_data()

u16 dst_vport = reinterpret_cast<le_t<u16>&>(p2p_recv_data[0]);

if (dst_vport == 0) // Reserved for messages from RPCN server
if (dst_vport == 0)
{
std::vector<u8> rpcn_msg(recv_res - sizeof(u16));
memcpy(rpcn_msg.data(), p2p_recv_data.data() + sizeof(u16), recv_res - sizeof(u16));

std::lock_guard lock(s_rpcn_mutex);
rpcn_msgs.push_back(std::move(rpcn_msg));
return true;
}

if (dst_vport == 65535) // Reserved for signaling
{
std::vector<u8> sign_msg(recv_res - sizeof(u16));
memcpy(sign_msg.data(), p2p_recv_data.data() + sizeof(u16), recv_res - sizeof(u16));

std::pair<std::pair<u32, u16>, std::vector<u8>> msg;
msg.first.first = reinterpret_cast<struct sockaddr_in*>(&native_addr)->sin_addr.s_addr;
msg.first.second = std::bit_cast<u16, be_t<u16>>(reinterpret_cast<struct sockaddr_in*>(&native_addr)->sin_port);
msg.second = std::move(sign_msg);

if (recv_res < VPORT_0_HEADER_SIZE)
{
std::lock_guard lock(s_sign_mutex);
sign_msgs.push_back(std::move(msg));
sys_net.error("Bad vport 0 packet(no subset)!");
return true;
}

auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.wake_up();
const u8 subset = p2p_recv_data[2];
const auto data_size = recv_res - VPORT_0_HEADER_SIZE;
std::vector<u8> vport_0_data(p2p_recv_data.data() + VPORT_0_HEADER_SIZE, p2p_recv_data.data() + VPORT_0_HEADER_SIZE + data_size);

return true;
switch (subset)
{
case SUBSET_RPCN:
{
std::lock_guard lock(s_rpcn_mutex);
rpcn_msgs.push_back(std::move(vport_0_data));
return true;
}
case SUBSET_SIGNALING:
{
std::pair<std::pair<u32, u16>, std::vector<u8>> msg;
msg.first.first = reinterpret_cast<struct sockaddr_in*>(&native_addr)->sin_addr.s_addr;
msg.first.second = std::bit_cast<u16, be_t<u16>>(reinterpret_cast<struct sockaddr_in*>(&native_addr)->sin_port);
msg.second = std::move(vport_0_data);

{
std::lock_guard lock(s_sign_mutex);
sign_msgs.push_back(std::move(msg));
}

auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.wake_up();
return true;
}
default:
{
sys_net.error("Invalid vport 0 subset!");
return true;
}
}
}

{
Expand Down
21 changes: 16 additions & 5 deletions rpcs3/Emu/NP/np_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ namespace np
return SCE_NP_MATCHING2_ERROR_ROOM_MEMBER_NOT_FOUND;
}

const auto& room = rooms.at(room_id);
const auto& room = rooms.at(room_id);
const auto& member = room.members.at(member_id);

if (ptr_member)
Expand Down Expand Up @@ -278,18 +278,18 @@ namespace np
if (num_binattrs)
{
ptr_member->roomMemberBinAttrInternal.set(mem.allocate(sizeof(SceNpMatching2RoomMemberBinAttrInternal) * num_binattrs));
ptr_member->roomMemberBinAttrInternalNum = num_binattrs;
ptr_member->roomMemberBinAttrInternalNum = num_binattrs;
SceNpMatching2RoomMemberBinAttrInternal* bin_ptr = ptr_member->roomMemberBinAttrInternal.get_ptr();

u32 actual_cnt = 0;
for (u32 i = 0; i < binattrs_list.size(); i++)
{
if (member.bins.contains(binattrs_list[i]))
{
const auto& bin = member.bins.at(binattrs_list[i]);
const auto& bin = member.bins.at(binattrs_list[i]);
bin_ptr[actual_cnt].updateDate.tick = bin.updateDate.tick;
bin_ptr[actual_cnt].data.id = bin.id;
bin_ptr[actual_cnt].data.size = bin.data.size();
bin_ptr[actual_cnt].data.id = bin.id;
bin_ptr[actual_cnt].data.size = bin.data.size();
bin_ptr[actual_cnt].data.ptr.set(mem.allocate(bin.data.size()));
memcpy(bin_ptr[actual_cnt].data.ptr.get_ptr(), bin.data.data(), bin.data.size());
actual_cnt++;
Expand All @@ -299,4 +299,15 @@ namespace np

return needed_data_size;
}

SceNpId cache_manager::get_npid(u64 room_id, u16 member_id)
{
std::lock_guard lock(mutex);

ensure(rooms.contains(room_id), "cache_manager::get_npid: Room not cached!");
ensure(rooms.at(room_id).members.contains(member_id), "cache_manager::get_npid: Member not cached!");

return rooms.at(room_id).members.at(member_id).userInfo.npId;
}

} // namespace np
1 change: 1 addition & 0 deletions rpcs3/Emu/NP/np_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ namespace np
std::pair<error_code, std::vector<SceNpMatching2RoomMemberId>> get_memberids(u64 room_id, s32 sort_method);
std::pair<error_code, std::optional<SceNpMatching2SessionPassword>> get_password(SceNpMatching2RoomId room_id);
error_code get_member_and_attrs(SceNpMatching2RoomId room_id, SceNpMatching2RoomMemberId member_id, const std::vector<SceNpMatching2AttributeId>& binattrs_list, SceNpMatching2RoomMemberDataInternal* ptr_member, u32 addr_data, u32 size_data);
SceNpId get_npid(u64 room_id, u16 member_id);

private:
shared_mutex mutex;
Expand Down
2 changes: 2 additions & 0 deletions rpcs3/Emu/NP/np_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ namespace np
{
discover_ip_address();

rpcn->update_local_addr(get_local_ip_addr());

if (!discover_ether_address())
{
nph_log.error("Failed to discover ethernet address!");
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/NP/np_notifications.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ namespace np

// Attempt Signaling
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.set_sig2_infos(room_id, member_id, SCE_NP_SIGNALING_CONN_STATUS_PENDING, addr_p2p, port_p2p);
sigh.set_sig2_infos(room_id, member_id, SCE_NP_SIGNALING_CONN_STATUS_PENDING, addr_p2p, port_p2p, np_cache.get_npid(room_id, member_id));
sigh.start_sig2(room_id, member_id);
}
} // namespace np
4 changes: 2 additions & 2 deletions rpcs3/Emu/NP/np_requests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ namespace np
// Establish Matching2 self signaling info
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.set_self_sig2_info(room_info->roomId, 1);
sigh.set_sig2_infos(room_info->roomId, 1, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), true);
sigh.set_sig2_infos(room_info->roomId, 1, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), get_npid(), true);
// TODO? Should this send a message to Signaling CB? Is this even necessary?

extra_nps::print_create_room_resp(room_resp);
Expand Down Expand Up @@ -257,7 +257,7 @@ namespace np
// Establish Matching2 self signaling info
auto& sigh = g_fxo->get<named_thread<signaling_handler>>();
sigh.set_self_sig2_info(room_info->roomId, member_id);
sigh.set_sig2_infos(room_info->roomId, member_id, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), true);
sigh.set_sig2_infos(room_info->roomId, member_id, SCE_NP_SIGNALING_CONN_STATUS_ACTIVE, rpcn->get_addr_sig(), rpcn->get_port_sig(), get_npid(), true);
// TODO? Should this send a message to Signaling CB? Is this even necessary?

if (cb_info.cb)
Expand Down

0 comments on commit 90a31d8

Please sign in to comment.