diff options
| author | Ac_K <Acoustik666@gmail.com> | 2019-09-19 02:45:11 +0200 |
|---|---|---|
| committer | jduncanator <1518948+jduncanator@users.noreply.github.com> | 2019-09-19 10:45:11 +1000 |
| commit | a0720b5681852f3d786d77bd3793b0359dea321c (patch) | |
| tree | 9d8f61e540d1d1d827999902dad95e5c0c1e076e /Ryujinx.HLE/HOS/Services/Sockets/Nsd | |
| parent | 4af3101b22e6957d6aa48a2768566d658699f4ed (diff) | |
Refactoring HOS folder structure (#771)
* Refactoring HOS folder structure
Refactoring HOS folder structure:
- Added some subfolders when needed (Following structure decided in private).
- Added some `Types` folders when needed.
- Little cleanup here and there.
- Add services placeholders for every HOS services (close #766 and #753).
* Remove Types namespaces
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Sockets/Nsd')
4 files changed, 427 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs new file mode 100644 index 00000000..277bc374 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs @@ -0,0 +1,268 @@ +using Ryujinx.Common.Logging; +using Ryujinx.HLE.Exceptions; +using Ryujinx.HLE.HOS.Services.Settings; +using Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager; +using System.Text; + +namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd +{ + [Service("nsd:a")] // Max sessions: 5 + [Service("nsd:u")] // Max sessions: 20 + class IManager : IpcService + { + private NsdSettings _nsdSettings; + private FqdnResolver _fqdnResolver; + + private bool _isInitialized = false; + + public IManager(ServiceCtx context) + { + // TODO: Load nsd settings through the savedata 0x80000000000000B0 (nsdsave:/). + + NxSettings.Settings.TryGetValue("nsd!test_mode", out object testMode); + + _nsdSettings = new NsdSettings + { + Initialized = true, + TestMode = (bool)testMode + }; + + _fqdnResolver = new FqdnResolver(_nsdSettings); + + _isInitialized = true; + } + + [Command(10)] + // GetSettingName() -> buffer<unknown<0x100>, 0x16> + public ResultCode GetSettingName(ServiceCtx context) + { + (long outputPosition, long outputSize) = context.Request.GetBufferType0x22(); + + ResultCode result = _fqdnResolver.GetSettingName(context, out string settingName); + + if (result == ResultCode.Success) + { + byte[] settingNameBuffer = Encoding.UTF8.GetBytes(settingName + '\0'); + + context.Memory.WriteBytes(outputPosition, settingNameBuffer); + } + + return result; + } + + [Command(11)] + // GetEnvironmentIdentifier() -> buffer<unknown<8>, 0x16> + public ResultCode GetEnvironmentIdentifier(ServiceCtx context) + { + (long outputPosition, long outputSize) = context.Request.GetBufferType0x22(); + + ResultCode result = _fqdnResolver.GetEnvironmentIdentifier(context, out string identifier); + + if (result == ResultCode.Success) + { + byte[] identifierBuffer = Encoding.UTF8.GetBytes(identifier + '\0'); + + context.Memory.WriteBytes(outputPosition, identifierBuffer); + } + + return result; + } + + [Command(12)] + // GetDeviceId() -> bytes<0x10, 1> + public ResultCode GetDeviceId(ServiceCtx context) + { + // NOTE: Stubbed in system module. + + return ResultCode.Success; + } + + [Command(13)] + // DeleteSettings(u32) + public ResultCode DeleteSettings(ServiceCtx context) + { + uint unknown = context.RequestData.ReadUInt32(); + + if (!_isInitialized) + { + return ResultCode.ServiceNotInitialized; + } + + if (unknown > 1) + { + return ResultCode.InvalidArgument; + } + + if (unknown == 1) + { + NxSettings.Settings.TryGetValue("nsd!environment_identifier", out object environmentIdentifier); + + if ((string)environmentIdentifier == _nsdSettings.Environment) + { + // TODO: Call nn::fs::DeleteSystemFile() to delete the savedata file and return ResultCode. + } + else + { + // TODO: Mount the savedata file and return ResultCode. + } + } + else + { + // TODO: Call nn::fs::DeleteSystemFile() to delete the savedata file and return ResultCode. + } + + return ResultCode.Success; + } + + [Command(14)] + // ImportSettings(u32, buffer<unknown, 5>) -> buffer<unknown, 6> + public ResultCode ImportSettings(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + + [Command(15)] + // Unknown(bytes<1>) + public ResultCode Unknown(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + + [Command(20)] + // Resolve(buffer<unknown<0x100>, 0x15>) -> buffer<unknown<0x100>, 0x16> + public ResultCode Resolve(ServiceCtx context) + { + (long outputPosition, long outputSize) = context.Request.GetBufferType0x22(); + + ResultCode result = _fqdnResolver.ResolveEx(context, out ResultCode errorCode, out string resolvedAddress); + + byte[] resolvedAddressBuffer = Encoding.UTF8.GetBytes(resolvedAddress + '\0'); + + context.Memory.WriteBytes(outputPosition, resolvedAddressBuffer); + + return result; + } + + [Command(21)] + // ResolveEx(buffer<unknown<0x100>, 0x15>) -> (u32, buffer<unknown<0x100>, 0x16>) + public ResultCode ResolveEx(ServiceCtx context) + { + (long outputPosition, long outputSize) = context.Request.GetBufferType0x22(); + + ResultCode result = _fqdnResolver.ResolveEx(context, out ResultCode errorCode, out string resolvedAddress); + + byte[] resolvedAddressBuffer = Encoding.UTF8.GetBytes(resolvedAddress + '\0'); + + context.Memory.WriteBytes(outputPosition, resolvedAddressBuffer); + + context.ResponseData.Write((int)errorCode); + + return result; + } + + [Command(30)] + // GetNasServiceSetting(buffer<unknown<0x10>, 0x15>) -> buffer<unknown<0x108>, 0x16> + public ResultCode GetNasServiceSetting(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + + [Command(31)] + // GetNasServiceSettingEx(buffer<unknown<0x10>, 0x15>) -> (u32, buffer<unknown<0x108>, 0x16>) + public ResultCode GetNasServiceSettingEx(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + + [Command(40)] + // GetNasRequestFqdn() -> buffer<unknown<0x100>, 0x16> + public ResultCode GetNasRequestFqdn(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + + [Command(41)] + // GetNasRequestFqdnEx() -> (u32, buffer<unknown<0x100>, 0x16>) + public ResultCode GetNasRequestFqdnEx(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + + [Command(42)] + // GetNasApiFqdn() -> buffer<unknown<0x100>, 0x16> + public ResultCode GetNasApiFqdn(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + + [Command(43)] + // GetNasApiFqdnEx() -> (u32, buffer<unknown<0x100>, 0x16>) + public ResultCode GetNasApiFqdnEx(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + + [Command(50)] + // GetCurrentSetting() -> buffer<unknown<0x12bf0>, 0x16> + public ResultCode GetCurrentSetting(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + + [Command(60)] + // ReadSaveDataFromFsForTest() -> buffer<unknown<0x12bf0>, 0x16> + public ResultCode ReadSaveDataFromFsForTest(ServiceCtx context) + { + if (!_isInitialized) + { + return ResultCode.ServiceNotInitialized; + } + + // TODO: Call nn::nsd::detail::fs::ReadSaveDataWithOffset() at offset 0 to write the + // whole savedata inside the buffer. + + Logger.PrintStub(LogClass.ServiceNsd); + + return ResultCode.Success; + } + + [Command(61)] + // WriteSaveDataToFsForTest(buffer<unknown<0x12bf0>, 0x15>) + public ResultCode WriteSaveDataToFsForTest(ServiceCtx context) + { + // NOTE: Stubbed in system module. + + if (_isInitialized) + { + return ResultCode.NotImplemented; + } + else + { + return ResultCode.ServiceNotInitialized; + } + } + + [Command(62)] + // DeleteSaveDataOfFsForTest() + public ResultCode DeleteSaveDataOfFsForTest(ServiceCtx context) + { + // NOTE: Stubbed in system module. + + if (_isInitialized) + { + return ResultCode.NotImplemented; + } + else + { + return ResultCode.ServiceNotInitialized; + } + } + + [Command(63)] + // IsChangeEnvironmentIdentifierDisabled() -> bytes<1> + public ResultCode IsChangeEnvironmentIdentifierDisabled(ServiceCtx context) + { + throw new ServiceNotImplementedException(context); + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs new file mode 100644 index 00000000..aaab7b3b --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs @@ -0,0 +1,131 @@ +using System.Text; + +namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager +{ + class FqdnResolver + { + private const string _dummyAddress = "unknown.dummy.nintendo.net"; + + private NsdSettings _nsdSettings; + + public FqdnResolver(NsdSettings nsdSettings) + { + _nsdSettings = nsdSettings; + } + + public ResultCode GetSettingName(ServiceCtx context, out string settingName) + { + if (_nsdSettings.TestMode) + { + settingName = ""; + + return ResultCode.NotImplemented; + } + else + { + settingName = ""; + + if (true) // TODO: Determine field (struct + 0x2C) + { + settingName = _nsdSettings.Environment; + + return ResultCode.Success; + } + + return ResultCode.NullOutputObject; + } + } + + public ResultCode GetEnvironmentIdentifier(ServiceCtx context, out string identifier) + { + if (_nsdSettings.TestMode) + { + identifier = "rre"; + + return ResultCode.NotImplemented; + } + else + { + identifier = _nsdSettings.Environment; + } + + return ResultCode.Success; + } + + public ResultCode Resolve(ServiceCtx context, string address, out string resolvedAddress) + { + if (address != "api.sect.srv.nintendo.net" || address != "conntest.nintendowifi.net") + { + // TODO: Load Environment from the savedata. + address = address.Replace("%", _nsdSettings.Environment); + + resolvedAddress = ""; + + if (_nsdSettings == null) + { + return ResultCode.SettingsNotInitialized; + } + + if (!_nsdSettings.Initialized) + { + return ResultCode.SettingsNotLoaded; + } + + switch (address) + { + case "e97b8a9d672e4ce4845ec6947cd66ef6-sb-api.accounts.nintendo.com": // dp1 environment + resolvedAddress = "e97b8a9d672e4ce4845ec6947cd66ef6-sb.baas.nintendo.com"; + break; + case "api.accounts.nintendo.com": // dp1 environment + resolvedAddress = "e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com"; + break; + case "e97b8a9d672e4ce4845ec6947cd66ef6-sb.accounts.nintendo.com": // lp1 environment + resolvedAddress = "e97b8a9d672e4ce4845ec6947cd66ef6-sb.baas.nintendo.com"; + break; + case "accounts.nintendo.com": // lp1 environment + resolvedAddress = "e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com"; + break; + /* + // TODO: Determine fields of the struct. + case "": // + 0xEB8 || + 0x2BE8 + resolvedAddress = ""; // + 0xEB8 + 0x300 || + 0x2BE8 + 0x300 + break; + */ + default: + resolvedAddress = address; + break; + } + } + else + { + resolvedAddress = address; + } + + return ResultCode.Success; + } + + public ResultCode ResolveEx(ServiceCtx context, out ResultCode resultCode, out string resolvedAddress) + { + (long inputPosition, long inputSize) = context.Request.GetBufferType0x21(); + + byte[] addressBuffer = context.Memory.ReadBytes(inputPosition, inputSize); + string address = Encoding.UTF8.GetString(addressBuffer); + + resultCode = Resolve(context, address, out resolvedAddress); + + if (resultCode != ResultCode.Success) + { + resolvedAddress = _dummyAddress; + } + + if (_nsdSettings.TestMode) + { + return ResultCode.Success; + } + else + { + return resultCode; + } + } + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/ResultCode.cs new file mode 100644 index 00000000..0e636f9a --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/ResultCode.cs @@ -0,0 +1,19 @@ +namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd +{ + enum ResultCode + { + ModuleId = 141, + ErrorCodeShift = 9, + + Success = 0, + + NotImplemented = ( 1 << ErrorCodeShift) | ModuleId, + InvalidObject1 = ( 3 << ErrorCodeShift) | ModuleId, + InvalidObject2 = ( 4 << ErrorCodeShift) | ModuleId, + NullOutputObject = ( 5 << ErrorCodeShift) | ModuleId, + SettingsNotLoaded = ( 6 << ErrorCodeShift) | ModuleId, + InvalidArgument = ( 8 << ErrorCodeShift) | ModuleId, + SettingsNotInitialized = ( 10 << ErrorCodeShift) | ModuleId, + ServiceNotInitialized = (400 << ErrorCodeShift) | ModuleId, + } +}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs new file mode 100644 index 00000000..2b31cb1d --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Types/NsdSettings.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd +{ + class NsdSettings + { + public bool Initialized; + public bool TestMode; + public string Environment = "lp1"; // or "dd1" if devkit. + } +}
\ No newline at end of file |
