make mii sharing not crash - ldn not functional yet

This commit is contained in:
Babib3l 2026-05-18 20:43:59 +02:00 committed by Gabriel
parent 81468c1d25
commit c7a385a6aa
4 changed files with 113 additions and 10 deletions

View file

@ -1,8 +1,28 @@
using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator;
namespace Ryujinx.HLE.HOS.Services.Ldn
{
[Service("ldn:s")]
class ISystemServiceCreator : IpcService
{
public ISystemServiceCreator(ServiceCtx context) { }
public ISystemServiceCreator(ServiceCtx context) : base(context.Device.System.LdnServer) { }
[CommandCmif(0)]
// CreateSystemLocalCommunicationService() -> object<nn::ldn::detail::ISystemLocalCommunicationService>
public ResultCode CreateSystemLocalCommunicationService(ServiceCtx context)
{
MakeObject(context, new ISystemLocalCommunicationService(context));
return ResultCode.Success;
}
[CommandCmif(1)] // 18.0.0+
// CreateClientProcessMonitor() -> object<nn::ldn::detail::IClientProcessMonitor>
public ResultCode CreateClientProcessMonitor(ServiceCtx context)
{
MakeObject(context, new IClientProcessMonitor(context));
return ResultCode.Success;
}
}
}

View file

@ -0,0 +1,45 @@
using Ryujinx.Common.Logging;
namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
{
class ISystemLocalCommunicationService : IUserLocalCommunicationService
{
private const int NifmRequestId = 90;
public ISystemLocalCommunicationService(ServiceCtx context) : base(context) { }
// NOTE: This overrides the parent's Initialize method with the same command ID (402)
// The CommandCmif attribute is inherited from the parent class
public override ResultCode Initialize(ServiceCtx context)
{
uint operationMode = context.RequestData.ReadUInt32();
Logger.Stub?.PrintStub(LogClass.ServiceLdn, new { operationMode });
return ResultCode.Success;
}
[CommandCmif(403)]
// InitializeWithVersion(s32 version, pid)
public ResultCode InitializeWithVersion(ServiceCtx context)
{
int version = context.RequestData.ReadInt32();
Logger.Stub?.PrintStub(LogClass.ServiceLdn, new { version });
return InitializeImpl(context, context.Process.Pid, NifmRequestId);
}
[CommandCmif(404)] // 11.0.0+
// InitializeWithPriority(s32 version, s32 priority, pid)
public ResultCode InitializeWithPriority(ServiceCtx context)
{
int version = context.RequestData.ReadInt32();
int priority = context.RequestData.ReadInt32();
Logger.Stub?.PrintStub(LogClass.ServiceLdn, new { version, priority });
return InitializeImpl(context, context.Process.Pid, NifmRequestId);
}
}
}

View file

@ -21,9 +21,18 @@ using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
{
class IUserLocalCommunicationService : IpcService, IDisposable
class IUserLocalCommunicationService : IpcService
{
public INetworkClient NetworkClient { get; private set; }
private readonly ServiceCtx _context;
public IUserLocalCommunicationService(ServiceCtx context) : base(context.Device.System.LdnServer)
{
_context = context;
_stateChangeEvent = new KEvent(context.Device.System.KernelContext);
_state = NetworkState.None;
_disconnectReason = DisconnectReason.None;
}
private const int NifmRequestID = 90;
private const string DefaultIPAddress = "127.0.0.1";
@ -40,13 +49,6 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
private AccessPoint _accessPoint;
private Station _station;
public IUserLocalCommunicationService(ServiceCtx context)
{
_stateChangeEvent = new KEvent(context.Device.System.KernelContext);
_state = NetworkState.None;
_disconnectReason = DisconnectReason.None;
}
private ushort CheckDevelopmentChannel(ushort channel)
{
return (ushort)(!IsDevelopment ? 0 : channel);
@ -457,6 +459,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
}
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, $"ScanImpl: resultCode = {resultCode}");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"ScanImpl: resultCode={resultCode}, state={_state}, private={isPrivate}");
return resultCode;
}
@ -482,6 +485,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
}
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, $"ScanInternal: availableGames = {availableGames}");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"ScanInternal: availableGames={availableGames.Length}, channel={channel}");
return ResultCode.Success;
}
@ -534,12 +538,14 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
if (_nifmResultCode != ResultCode.Success)
{
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, $"OpenAccessPoint: _nifmResultCode = {_nifmResultCode}");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"OpenAccessPoint: nifmResultCode={_nifmResultCode}, state={_state}");
return _nifmResultCode;
}
if (_state != NetworkState.Initialized)
{
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, "OpenAccessPoint: Invalid state!");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"OpenAccessPoint: invalid state={_state}");
return ResultCode.InvalidState;
}
@ -551,6 +557,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
// NOTE: Calls nifm service and return related result codes.
// Since we use our own implementation we can return ResultCode.Success.
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"OpenAccessPoint: state={_state}");
return ResultCode.Success;
}
@ -628,6 +635,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
if (_nifmResultCode != ResultCode.Success)
{
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, $"CreateNetworkImpl: _nifmResultCode = {_nifmResultCode}");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"CreateNetworkImpl: nifmResultCode={_nifmResultCode}, state={_state}, private={isPrivate}");
return _nifmResultCode;
}
@ -672,6 +680,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
else
{
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, "CreateNetworkImpl: Invalid state!");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"CreateNetworkImpl: invalid state={_state}, private={isPrivate}");
return ResultCode.InvalidState;
}
}
@ -679,6 +688,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
}
}
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"CreateNetworkImpl: invalid argument, state={_state}, private={isPrivate}");
return ResultCode.InvalidArgument;
}
@ -845,12 +855,14 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
if (_nifmResultCode != ResultCode.Success)
{
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, $"OpenStation: _nifmResultCode = {_nifmResultCode}");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"OpenStation: nifmResultCode={_nifmResultCode}, state={_state}");
return _nifmResultCode;
}
if (_state != NetworkState.Initialized)
{
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, "OpenStation: Invalid state!");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"OpenStation: invalid state={_state}");
return ResultCode.InvalidState;
}
@ -865,6 +877,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
// Since we use our own implementation we can return ResultCode.Success.
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, $"OpenStation: _station = {_station}");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"OpenStation: state={_state}");
return ResultCode.Success;
}
@ -963,6 +976,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
if (_nifmResultCode != ResultCode.Success)
{
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, $"ConnectImpl: _nifmResultCode = {_nifmResultCode}");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"ConnectImpl: nifmResultCode={_nifmResultCode}, state={_state}, private={isPrivate}");
return _nifmResultCode;
}
@ -1008,6 +1022,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
}
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, $"ConnectImpl: resultCode = {resultCode}");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"ConnectImpl: resultCode={resultCode}, state={_state}, private={isPrivate}");
return resultCode;
}
@ -1148,7 +1163,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
[CommandCmif(402)] // 7.0.0+
// Initialize(u64 ip_addresses, pid)
public ResultCode Initialize(ServiceCtx context)
public virtual ResultCode Initialize(ServiceCtx context)
{
_ = new IPAddress(context.RequestData.ReadUInt32());
_ = new IPAddress(context.RequestData.ReadUInt32());
@ -1225,6 +1240,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
}
Logger.NetLog?.PrintMsg(LogClass.ServiceLdn, $"InitializeImpl: resultCode = {resultCode}");
Logger.Info?.PrintMsg(LogClass.ServiceLdn, $"InitializeImpl: resultCode={resultCode}, state={_state}, nifmRequestId={nifmRequestId}");
return resultCode;
}

View file

@ -129,6 +129,17 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
return ResultCode.Success;
}
[CommandCmif(17)]
// IsWirelessCommunicationEnabled() -> bool
public ResultCode IsWirelessCommunicationEnabled(ServiceCtx context)
{
context.ResponseData.Write(true);
Logger.Stub?.PrintStub(LogClass.ServiceNifm);
return ResultCode.Success;
}
[CommandCmif(18)]
// GetInternetConnectionStatus() -> nn::nifm::detail::sf::InternetConnectionStatus
public ResultCode GetInternetConnectionStatus(ServiceCtx context)
@ -166,6 +177,17 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
return ResultCode.Success;
}
[CommandCmif(22)]
// IsAnyForegroundRequestAccepted() -> bool
public ResultCode IsAnyForegroundRequestAccepted(ServiceCtx context)
{
context.ResponseData.Write(false);
Logger.Stub?.PrintStub(LogClass.ServiceNifm);
return ResultCode.Success;
}
private (IPInterfaceProperties, UnicastIPAddressInformation) GetLocalInterface(ServiceCtx context)
{
if (!NetworkInterface.GetIsNetworkAvailable())