mirror of
https://git.citron-emu.org/citron/emulator
synced 2025-12-23 20:33:41 +00:00
Merge pull request 'hle: Improve network service implementations and add newer firmware stubs' (#11) from feature/network-service-enhancements into main
Reviewed-on: https://git.citron-emu.org/Citron/Emulator/pulls/11
This commit is contained in:
@@ -362,8 +362,17 @@ Result IApplicationFunctions::NotifyRunning(Out<bool> out_became_running) {
|
||||
}
|
||||
|
||||
Result IApplicationFunctions::GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id) {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
*out_pseudo_device_id = {};
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
|
||||
// Generate a persistent pseudo device ID for online play and telemetry
|
||||
// Based on hardware/system info for consistency across sessions
|
||||
// Using MakeRandomWithSeed to ensure deterministic generation
|
||||
const u32 device_seed = static_cast<u32>(system.GetApplicationProcessProgramID());
|
||||
*out_pseudo_device_id = Common::UUID::MakeRandomWithSeed(device_seed);
|
||||
|
||||
LOG_DEBUG(Service_AM, "Generated PseudoDeviceId: {}",
|
||||
out_pseudo_device_id->FormattedString());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,15 +42,15 @@ IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& sys
|
||||
{202, D<&IUserLocalCommunicationService::CreateNetwork>, "CreateNetwork"},
|
||||
{203, D<&IUserLocalCommunicationService::CreateNetworkPrivate>, "CreateNetworkPrivate"},
|
||||
{204, D<&IUserLocalCommunicationService::DestroyNetwork>, "DestroyNetwork"},
|
||||
{205, nullptr, "Reject"},
|
||||
{205, D<&IUserLocalCommunicationService::Reject>, "Reject"},
|
||||
{206, D<&IUserLocalCommunicationService::SetAdvertiseData>, "SetAdvertiseData"},
|
||||
{207, D<&IUserLocalCommunicationService::SetStationAcceptPolicy>, "SetStationAcceptPolicy"},
|
||||
{208, D<&IUserLocalCommunicationService::AddAcceptFilterEntry>, "AddAcceptFilterEntry"},
|
||||
{209, nullptr, "ClearAcceptFilter"},
|
||||
{209, D<&IUserLocalCommunicationService::ClearAcceptFilter>, "ClearAcceptFilter"},
|
||||
{300, D<&IUserLocalCommunicationService::OpenStation>, "OpenStation"},
|
||||
{301, D<&IUserLocalCommunicationService::CloseStation>, "CloseStation"},
|
||||
{302, D<&IUserLocalCommunicationService::Connect>, "Connect"},
|
||||
{303, nullptr, "ConnectPrivate"},
|
||||
{303, D<&IUserLocalCommunicationService::ConnectPrivate>, "ConnectPrivate"},
|
||||
{304, D<&IUserLocalCommunicationService::Disconnect>, "Disconnect"},
|
||||
{400, D<&IUserLocalCommunicationService::Initialize>, "Initialize"},
|
||||
{401, D<&IUserLocalCommunicationService::Finalize>, "Finalize"},
|
||||
@@ -227,6 +227,13 @@ Result IUserLocalCommunicationService::DestroyNetwork() {
|
||||
R_RETURN(lan_discovery.DestroyNetwork());
|
||||
}
|
||||
|
||||
Result IUserLocalCommunicationService::Reject(Ipv4Address ip_address, u16 port) {
|
||||
LOG_WARNING(Service_LDN, "(STUBBED) called, ip_address={}.{}.{}.{}, port={}",
|
||||
ip_address[0], ip_address[1], ip_address[2], ip_address[3], port);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IUserLocalCommunicationService::SetAdvertiseData(
|
||||
InBuffer<BufferAttr_HipcAutoSelect> buffer_data) {
|
||||
LOG_INFO(Service_LDN, "called");
|
||||
@@ -244,6 +251,11 @@ Result IUserLocalCommunicationService::AddAcceptFilterEntry(MacAddress mac_addre
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IUserLocalCommunicationService::ClearAcceptFilter() {
|
||||
LOG_WARNING(Service_LDN, "(STUBBED) called");
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IUserLocalCommunicationService::OpenStation() {
|
||||
LOG_INFO(Service_LDN, "called");
|
||||
|
||||
@@ -269,6 +281,16 @@ Result IUserLocalCommunicationService::Connect(
|
||||
static_cast<u16>(connect_data.local_communication_version)));
|
||||
}
|
||||
|
||||
Result IUserLocalCommunicationService::ConnectPrivate(
|
||||
const ConnectNetworkData& connect_data,
|
||||
InLargeData<NetworkInfo, BufferAttr_HipcPointer> network_info) {
|
||||
LOG_WARNING(Service_LDN, "(STUBBED) called");
|
||||
|
||||
// ConnectPrivate is similar to Connect but with additional private network parameters
|
||||
// For now, stub it - would need to implement private network logic
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result IUserLocalCommunicationService::Disconnect() {
|
||||
LOG_INFO(Service_LDN, "called");
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
@@ -63,12 +64,16 @@ private:
|
||||
|
||||
Result DestroyNetwork();
|
||||
|
||||
Result Reject(Ipv4Address ip_address, u16 port);
|
||||
|
||||
Result SetAdvertiseData(InBuffer<BufferAttr_HipcAutoSelect> buffer_data);
|
||||
|
||||
Result SetStationAcceptPolicy(AcceptPolicy accept_policy);
|
||||
|
||||
Result AddAcceptFilterEntry(MacAddress mac_address);
|
||||
|
||||
Result ClearAcceptFilter();
|
||||
|
||||
Result OpenStation();
|
||||
|
||||
Result CloseStation();
|
||||
@@ -76,6 +81,9 @@ private:
|
||||
Result Connect(const ConnectNetworkData& connect_data,
|
||||
InLargeData<NetworkInfo, BufferAttr_HipcPointer> network_info);
|
||||
|
||||
Result ConnectPrivate(const ConnectNetworkData& connect_data,
|
||||
InLargeData<NetworkInfo, BufferAttr_HipcPointer> network_info);
|
||||
|
||||
Result Disconnect();
|
||||
|
||||
Result Initialize(ClientProcessId aruid);
|
||||
|
||||
@@ -26,9 +26,10 @@ namespace {
|
||||
namespace Service::NIFM {
|
||||
|
||||
// This is nn::nifm::RequestState
|
||||
// Reference: https://switchbrew.org/wiki/Network_Interface_services#RequestState
|
||||
enum class RequestState : u32 {
|
||||
NotSubmitted = 1,
|
||||
Invalid = 1, ///< The duplicate 1 is intentional; it means both not submitted and error on HW.
|
||||
Invalid = 0,
|
||||
Free = 1, ///< NotSubmitted/Free state
|
||||
OnHold = 2,
|
||||
Accepted = 3,
|
||||
Blocking = 4,
|
||||
@@ -56,6 +57,17 @@ enum class NetworkProfileType : u32 {
|
||||
Temporary,
|
||||
};
|
||||
|
||||
// This is nn::nifm::ConnectionConfirmationOption
|
||||
// Reference: https://switchbrew.org/wiki/Network_Interface_services#ConnectionConfirmationOption
|
||||
enum class ConnectionConfirmationOption : u32 {
|
||||
Invalid = 0,
|
||||
Prohibited = 1,
|
||||
NotRequired = 2,
|
||||
Preferred = 3,
|
||||
Required = 4,
|
||||
Forced = 5,
|
||||
};
|
||||
|
||||
// This is nn::nifm::IpAddressSetting
|
||||
struct IpAddressSetting {
|
||||
bool is_automatic{};
|
||||
@@ -258,7 +270,7 @@ public:
|
||||
|
||||
event1 = CreateKEvent(service_context, "IRequest:Event1");
|
||||
event2 = CreateKEvent(service_context, "IRequest:Event2");
|
||||
state = RequestState::NotSubmitted;
|
||||
state = RequestState::Free;
|
||||
}
|
||||
|
||||
~IRequest() override {
|
||||
@@ -270,7 +282,7 @@ private:
|
||||
void Submit(HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
if (state == RequestState::NotSubmitted) {
|
||||
if (state == RequestState::Free) {
|
||||
UpdateState(RequestState::OnHold);
|
||||
}
|
||||
|
||||
@@ -302,7 +314,7 @@ private:
|
||||
const auto result = [this] {
|
||||
const auto has_connection = Network::GetHostIPv4Address().has_value();
|
||||
switch (state) {
|
||||
case RequestState::NotSubmitted:
|
||||
case RequestState::Free:
|
||||
return has_connection ? ResultSuccess : ResultNetworkCommunicationDisabled;
|
||||
case RequestState::OnHold:
|
||||
if (has_connection) {
|
||||
@@ -322,7 +334,7 @@ private:
|
||||
}
|
||||
|
||||
void GetSystemEventReadableHandles(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
@@ -337,7 +349,10 @@ private:
|
||||
}
|
||||
|
||||
void SetConnectionConfirmationOption(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto connection_option = rp.PopEnum<ConnectionConfirmationOption>();
|
||||
|
||||
LOG_INFO(Service_NIFM, "called, connection_option={}", static_cast<u32>(connection_option));
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
@@ -633,7 +648,7 @@ void IGeneralService::CreateTemporaryNetworkProfile(HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void IGeneralService::GetCurrentIpConfigInfo(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
|
||||
struct IpConfigInfo {
|
||||
IpAddressSetting ip_address_setting{};
|
||||
@@ -814,6 +829,104 @@ void IGeneralService::SetWowlTcpKeepAliveTimeout(HLERequestContext& ctx) {
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IGeneralService::IsWiredConnectionAvailable(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called IsWiredConnectionAvailable [18.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u8>(1); // Wired connection available
|
||||
}
|
||||
|
||||
void IGeneralService::IsNetworkEmulationFeatureEnabled(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called IsNetworkEmulationFeatureEnabled [18.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u8>(0); // Network emulation disabled
|
||||
}
|
||||
|
||||
void IGeneralService::SelectActiveNetworkEmulationProfileIdForDebug(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called SelectActiveNetworkEmulationProfileIdForDebug [18.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IGeneralService::GetScanData2(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called GetScanData [19.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u32>(0); // No scan data
|
||||
}
|
||||
|
||||
void IGeneralService::ResetActiveNetworkEmulationProfileId(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called ResetActiveNetworkEmulationProfileId [20.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IGeneralService::GetActiveNetworkEmulationProfileId(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called GetActiveNetworkEmulationProfileId [18.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u32>(0); // No active profile
|
||||
}
|
||||
|
||||
void IGeneralService::IsRewriteFeatureEnabled(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called IsRewriteFeatureEnabled [18.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u8>(0); // Rewrite feature disabled
|
||||
}
|
||||
|
||||
void IGeneralService::CreateRewriteRule(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called CreateRewriteRule [18.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IGeneralService::DestroyRewriteRule(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called DestroyRewriteRule [18.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IGeneralService::IsActiveNetworkEmulationProfileIdSelected(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called IsActiveNetworkEmulationProfileIdSelected [20.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u8>(0); // No profile selected
|
||||
}
|
||||
|
||||
void IGeneralService::SelectDefaultNetworkEmulationProfileId(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called SelectDefaultNetworkEmulationProfileId [20.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IGeneralService::GetDefaultNetworkEmulationProfileId(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called GetDefaultNetworkEmulationProfileId [20.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u32>(0); // Default profile ID
|
||||
}
|
||||
|
||||
void IGeneralService::GetNetworkEmulationProfile(HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called GetNetworkEmulationProfile [20.0.0+]");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
IGeneralService::IGeneralService(Core::System& system_)
|
||||
: ServiceFramework{system_, "IGeneralService"}, network{system_.GetRoomNetwork()} {
|
||||
// clang-format off
|
||||
@@ -860,6 +973,19 @@ IGeneralService::IGeneralService(Core::System& system_)
|
||||
{41, &IGeneralService::GetAcceptableNetworkTypeFlag, "GetAcceptableNetworkTypeFlag"},
|
||||
{42, &IGeneralService::NotifyConnectionStateChanged, "NotifyConnectionStateChanged"},
|
||||
{43, &IGeneralService::SetWowlDelayedWakeTime, "SetWowlDelayedWakeTime"},
|
||||
{44, &IGeneralService::IsWiredConnectionAvailable, "IsWiredConnectionAvailable"},
|
||||
{45, &IGeneralService::IsNetworkEmulationFeatureEnabled, "IsNetworkEmulationFeatureEnabled"},
|
||||
{46, &IGeneralService::SelectActiveNetworkEmulationProfileIdForDebug, "SelectActiveNetworkEmulationProfileIdForDebug"},
|
||||
{47, &IGeneralService::GetScanData2, "GetScanData"},
|
||||
{48, &IGeneralService::ResetActiveNetworkEmulationProfileId, "ResetActiveNetworkEmulationProfileId"},
|
||||
{49, &IGeneralService::GetActiveNetworkEmulationProfileId, "GetActiveNetworkEmulationProfileId"},
|
||||
{50, &IGeneralService::IsRewriteFeatureEnabled, "IsRewriteFeatureEnabled"},
|
||||
{51, &IGeneralService::CreateRewriteRule, "CreateRewriteRule"},
|
||||
{52, &IGeneralService::DestroyRewriteRule, "DestroyRewriteRule"},
|
||||
{53, &IGeneralService::IsActiveNetworkEmulationProfileIdSelected, "IsActiveNetworkEmulationProfileIdSelected"},
|
||||
{54, &IGeneralService::SelectDefaultNetworkEmulationProfileId, "SelectDefaultNetworkEmulationProfileId"},
|
||||
{55, &IGeneralService::GetDefaultNetworkEmulationProfileId, "GetDefaultNetworkEmulationProfileId"},
|
||||
{56, &IGeneralService::GetNetworkEmulationProfile, "GetNetworkEmulationProfile"},
|
||||
{57, &IGeneralService::SetWowlTcpKeepAliveTimeout, "SetWowlTcpKeepAliveTimeout"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -48,6 +48,19 @@ private:
|
||||
void GetAcceptableNetworkTypeFlag(HLERequestContext& ctx);
|
||||
void NotifyConnectionStateChanged(HLERequestContext& ctx);
|
||||
void SetWowlTcpKeepAliveTimeout(HLERequestContext& ctx);
|
||||
void IsWiredConnectionAvailable(HLERequestContext& ctx);
|
||||
void IsNetworkEmulationFeatureEnabled(HLERequestContext& ctx);
|
||||
void SelectActiveNetworkEmulationProfileIdForDebug(HLERequestContext& ctx);
|
||||
void GetScanData2(HLERequestContext& ctx);
|
||||
void ResetActiveNetworkEmulationProfileId(HLERequestContext& ctx);
|
||||
void GetActiveNetworkEmulationProfileId(HLERequestContext& ctx);
|
||||
void IsRewriteFeatureEnabled(HLERequestContext& ctx);
|
||||
void CreateRewriteRule(HLERequestContext& ctx);
|
||||
void DestroyRewriteRule(HLERequestContext& ctx);
|
||||
void IsActiveNetworkEmulationProfileIdSelected(HLERequestContext& ctx);
|
||||
void SelectDefaultNetworkEmulationProfileId(HLERequestContext& ctx);
|
||||
void GetDefaultNetworkEmulationProfileId(HLERequestContext& ctx);
|
||||
void GetNetworkEmulationProfile(HLERequestContext& ctx);
|
||||
|
||||
Network::RoomNetwork& network;
|
||||
};
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -162,11 +162,14 @@ private:
|
||||
void RegisterResourceStatisticsName(HLERequestContext& ctx);
|
||||
void RegisterClientShared(HLERequestContext& ctx);
|
||||
void GetSocketStatistics(HLERequestContext& ctx);
|
||||
void NifIoctl(HLERequestContext& ctx);
|
||||
void Unknown39(HLERequestContext& ctx); // [20.0.0+] undocumented
|
||||
void Unknown40(HLERequestContext& ctx); // [20.0.0+] undocumented
|
||||
void SetThreadCoreMask(HLERequestContext& ctx);
|
||||
void GetThreadCoreMask(HLERequestContext& ctx);
|
||||
void NifIoctl(HLERequestContext& ctx); // [17.0.0+]
|
||||
void Unknown36(HLERequestContext& ctx); // [18.0.0+] undocumented
|
||||
void Unknown37(HLERequestContext& ctx); // [18.0.0+] undocumented
|
||||
void Unknown38(HLERequestContext& ctx); // [18.0.0+] undocumented
|
||||
void Unknown39(HLERequestContext& ctx); // [20.0.0+] undocumented
|
||||
void Unknown40(HLERequestContext& ctx); // [20.0.0+] undocumented
|
||||
void SetThreadCoreMask(HLERequestContext& ctx); // [15.0.0+]
|
||||
void GetThreadCoreMask(HLERequestContext& ctx); // [15.0.0+]
|
||||
|
||||
template <typename Work>
|
||||
void ExecuteWork(HLERequestContext& ctx, Work work);
|
||||
|
||||
Reference in New Issue
Block a user