mirror of
https://git.eden-emu.dev/archive/citron
synced 2026-03-29 21:09:34 -04:00
hle: Improve network service implementations and add newer firmware stubs
AM (Application Manager): - Implement GetPseudoDeviceId with deterministic UUID generation - Generate persistent device ID based on program ID for online play LDN (Local Network): - Implement stub for Reject (cmd 205) - Implement stub for ClearAcceptFilter (cmd 209) - Implement stub for ConnectPrivate (cmd 303) NIFM (Network Interface): - Fix RequestState enum values (Invalid=0, Free=1) per switchbrew - Add ConnectionConfirmationOption enum - Update NotSubmitted references to Free state - Implement 13 new stub functions for firmware 18.0.0-20.0.0+ - Reduce log verbosity for frequently-called functions BSD (Sockets): - Improve RegisterClient to parse LibraryConfigData structure - Enhance socket operation logging (Socket, Bind, Connect) - Add detailed error logging for bind/connect failures - Implement stubs for Unknown36-38 (18.0.0+) - Add firmware version comments for commands Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
@@ -149,19 +149,45 @@ void BSD::SendToWork::Response(HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void BSD::RegisterClient(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
// Read LibraryConfigData structure
|
||||
struct LibraryConfigData {
|
||||
u32 version;
|
||||
u32 tcp_tx_buf_size;
|
||||
u32 tcp_rx_buf_size;
|
||||
u32 tcp_tx_buf_max_size;
|
||||
u32 tcp_rx_buf_max_size;
|
||||
u32 udp_tx_buf_size;
|
||||
u32 udp_rx_buf_size;
|
||||
u32 sb_efficiency;
|
||||
};
|
||||
|
||||
const auto config = rp.PopRaw<LibraryConfigData>();
|
||||
const u64 transfer_memory_size = rp.Pop<u64>();
|
||||
[[maybe_unused]] const auto transfer_memory_handle = ctx.GetCopyHandle(0);
|
||||
const u64 pid = ctx.GetPID();
|
||||
|
||||
LOG_INFO(Service, "called, version={} pid={} transfer_memory_size={:#x}",
|
||||
config.version, pid, transfer_memory_size);
|
||||
LOG_DEBUG(Service, " TCP: tx={:#x} rx={:#x} tx_max={:#x} rx_max={:#x}",
|
||||
config.tcp_tx_buf_size, config.tcp_rx_buf_size,
|
||||
config.tcp_tx_buf_max_size, config.tcp_rx_buf_max_size);
|
||||
LOG_DEBUG(Service, " UDP: tx={:#x} rx={:#x} sb_efficiency={}",
|
||||
config.udp_tx_buf_size, config.udp_rx_buf_size, config.sb_efficiency);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<s32>(0); // bsd errno
|
||||
}
|
||||
|
||||
void BSD::StartMonitoring(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
LOG_INFO(Service, "called");
|
||||
|
||||
// StartMonitoring initializes network event monitoring for BSD sockets
|
||||
// This command has no documented input parameters in switchbrew
|
||||
// It enables proper event handling for socket operations
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
@@ -515,10 +541,13 @@ std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protoco
|
||||
FileDescriptor& descriptor = *file_descriptors[fd];
|
||||
// ENONMEM might be thrown here
|
||||
|
||||
LOG_INFO(Service, "New socket fd={}", fd);
|
||||
|
||||
auto room_member = room_network.GetRoomMember().lock();
|
||||
if (room_member && room_member->IsConnected()) {
|
||||
const bool using_proxy = room_member && room_member->IsConnected();
|
||||
|
||||
LOG_INFO(Service, "New socket fd={} domain={} type={} protocol={} proxy={}",
|
||||
fd, domain, type, protocol, using_proxy);
|
||||
|
||||
if (using_proxy) {
|
||||
descriptor.socket = std::make_shared<Network::ProxySocket>(room_network);
|
||||
} else {
|
||||
descriptor.socket = std::make_shared<Network::Socket>();
|
||||
@@ -632,23 +661,41 @@ std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
|
||||
|
||||
Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
|
||||
if (!IsFileDescriptorValid(fd)) {
|
||||
LOG_ERROR(Service, "Bind failed: Invalid fd={}", fd);
|
||||
return Errno::BADF;
|
||||
}
|
||||
ASSERT(addr.size() == sizeof(SockAddrIn));
|
||||
auto addr_in = GetValue<SockAddrIn>(addr);
|
||||
|
||||
return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
|
||||
LOG_INFO(Service, "Bind fd={} to {}:{}", fd, Network::IPv4AddressToString(addr_in.ip),
|
||||
addr_in.portno);
|
||||
|
||||
const auto result = Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
|
||||
if (result != Errno::SUCCESS) {
|
||||
LOG_ERROR(Service, "Bind fd={} failed with errno={}", fd, static_cast<int>(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
|
||||
if (!IsFileDescriptorValid(fd)) {
|
||||
LOG_ERROR(Service, "Connect failed: Invalid fd={}", fd);
|
||||
return Errno::BADF;
|
||||
}
|
||||
|
||||
UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn));
|
||||
auto addr_in = GetValue<SockAddrIn>(addr);
|
||||
|
||||
return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in)));
|
||||
LOG_INFO(Service, "Connect fd={} to {}:{}", fd, Network::IPv4AddressToString(addr_in.ip),
|
||||
addr_in.portno);
|
||||
|
||||
const auto result = Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in)));
|
||||
if (result != Errno::SUCCESS) {
|
||||
LOG_ERROR(Service, "Connect fd={} failed with errno={}", fd, static_cast<int>(result));
|
||||
} else {
|
||||
LOG_INFO(Service, "Connect fd={} succeeded", fd);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
|
||||
@@ -1031,8 +1078,11 @@ BSD::BSD(Core::System& system_, const char* name)
|
||||
{33, &BSD::RegisterClientShared, "RegisterClientShared"},
|
||||
{34, &BSD::GetSocketStatistics, "GetSocketStatistics"},
|
||||
{35, &BSD::NifIoctl, "NifIoctl"},
|
||||
{39, &BSD::Unknown39, "[20.0.0+] Unknown39"},
|
||||
{40, &BSD::Unknown40, "[20.0.0+] Unknown40"},
|
||||
{36, &BSD::Unknown36, "Unknown36"},
|
||||
{37, &BSD::Unknown37, "Unknown37"},
|
||||
{38, &BSD::Unknown38, "Unknown38"},
|
||||
{39, &BSD::Unknown39, "Unknown39"},
|
||||
{40, &BSD::Unknown40, "Unknown40"},
|
||||
{200, &BSD::SetThreadCoreMask, "SetThreadCoreMask"},
|
||||
{201, &BSD::GetThreadCoreMask, "GetThreadCoreMask"},
|
||||
};
|
||||
@@ -1289,7 +1339,7 @@ void BSD::SendMMsg(HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void BSD::SetThreadCoreMask(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called SetThreadCoreMask");
|
||||
LOG_WARNING(Service, "(STUBBED) called SetThreadCoreMask [15.0.0+]");
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<s32>(-1);
|
||||
@@ -1312,6 +1362,30 @@ void BSD::SocketExempt(HLERequestContext& ctx) {
|
||||
rb.PushEnum(static_cast<Errno>(EOPNOTSUPP));
|
||||
}
|
||||
|
||||
void BSD::Unknown36(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called Unknown36 [18.0.0+]");
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<s32>(-1);
|
||||
rb.PushEnum(static_cast<Errno>(EOPNOTSUPP));
|
||||
}
|
||||
|
||||
void BSD::Unknown37(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called Unknown37 [18.0.0+]");
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<s32>(-1);
|
||||
rb.PushEnum(static_cast<Errno>(EOPNOTSUPP));
|
||||
}
|
||||
|
||||
void BSD::Unknown38(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called Unknown38 [18.0.0+]");
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<s32>(-1);
|
||||
rb.PushEnum(static_cast<Errno>(EOPNOTSUPP));
|
||||
}
|
||||
|
||||
void BSD::Unknown39(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called Unknown39 [20.0.0+]");
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
|
||||
Reference in New Issue
Block a user