2018-02-02 06:31:27 -05:00
|
|
|
// Copyright 2018 yuzu emulator team
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
2018-08-28 12:30:33 -04:00
|
|
|
#include "core/core.h"
|
2018-02-02 06:31:27 -05:00
|
|
|
#include "core/hle/ipc_helpers.h"
|
2018-11-26 18:34:07 -05:00
|
|
|
#include "core/hle/kernel/kernel.h"
|
|
|
|
#include "core/hle/kernel/readable_event.h"
|
|
|
|
#include "core/hle/kernel/writable_event.h"
|
2018-02-02 06:31:27 -05:00
|
|
|
#include "core/hle/service/nifm/nifm.h"
|
2018-07-25 17:07:32 -04:00
|
|
|
#include "core/hle/service/service.h"
|
2018-02-02 06:31:27 -05:00
|
|
|
|
2018-04-19 21:41:44 -04:00
|
|
|
namespace Service::NIFM {
|
2018-02-02 06:31:27 -05:00
|
|
|
|
|
|
|
class IScanRequest final : public ServiceFramework<IScanRequest> {
|
|
|
|
public:
|
|
|
|
explicit IScanRequest() : ServiceFramework("IScanRequest") {
|
|
|
|
static const FunctionInfo functions[] = {
|
|
|
|
{0, nullptr, "Submit"},
|
|
|
|
{1, nullptr, "IsProcessing"},
|
|
|
|
{2, nullptr, "GetResult"},
|
|
|
|
{3, nullptr, "GetSystemEventReadableHandle"},
|
|
|
|
};
|
|
|
|
RegisterHandlers(functions);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class IRequest final : public ServiceFramework<IRequest> {
|
|
|
|
public:
|
|
|
|
explicit IRequest() : ServiceFramework("IRequest") {
|
|
|
|
static const FunctionInfo functions[] = {
|
2018-02-22 09:28:15 -05:00
|
|
|
{0, &IRequest::GetRequestState, "GetRequestState"},
|
|
|
|
{1, &IRequest::GetResult, "GetResult"},
|
|
|
|
{2, &IRequest::GetSystemEventReadableHandles, "GetSystemEventReadableHandles"},
|
2018-03-16 04:08:22 -04:00
|
|
|
{3, &IRequest::Cancel, "Cancel"},
|
2018-09-20 10:47:30 -04:00
|
|
|
{4, &IRequest::Submit, "Submit"},
|
2018-02-02 06:31:27 -05:00
|
|
|
{5, nullptr, "SetRequirement"},
|
|
|
|
{6, nullptr, "SetRequirementPreset"},
|
|
|
|
{8, nullptr, "SetPriority"},
|
|
|
|
{9, nullptr, "SetNetworkProfileId"},
|
|
|
|
{10, nullptr, "SetRejectable"},
|
2018-06-05 18:43:43 -04:00
|
|
|
{11, &IRequest::SetConnectionConfirmationOption, "SetConnectionConfirmationOption"},
|
2018-02-02 06:31:27 -05:00
|
|
|
{12, nullptr, "SetPersistent"},
|
|
|
|
{13, nullptr, "SetInstant"},
|
|
|
|
{14, nullptr, "SetSustainable"},
|
|
|
|
{15, nullptr, "SetRawPriority"},
|
|
|
|
{16, nullptr, "SetGreedy"},
|
|
|
|
{17, nullptr, "SetSharable"},
|
|
|
|
{18, nullptr, "SetRequirementByRevision"},
|
|
|
|
{19, nullptr, "GetRequirement"},
|
|
|
|
{20, nullptr, "GetRevision"},
|
|
|
|
{21, nullptr, "GetAppletInfo"},
|
|
|
|
{22, nullptr, "GetAdditionalInfo"},
|
|
|
|
{23, nullptr, "SetKeptInSleep"},
|
|
|
|
{24, nullptr, "RegisterSocketDescriptor"},
|
|
|
|
{25, nullptr, "UnregisterSocketDescriptor"},
|
|
|
|
};
|
|
|
|
RegisterHandlers(functions);
|
2018-02-22 09:28:15 -05:00
|
|
|
|
2018-08-28 12:30:33 -04:00
|
|
|
auto& kernel = Core::System::GetInstance().Kernel();
|
2018-11-26 18:34:07 -05:00
|
|
|
event1 = Kernel::WritableEvent::CreateRegisteredEventPair(
|
|
|
|
kernel, Kernel::ResetType::OneShot, "IRequest:Event1");
|
|
|
|
event2 = Kernel::WritableEvent::CreateRegisteredEventPair(
|
|
|
|
kernel, Kernel::ResetType::OneShot, "IRequest:Event2");
|
2018-02-22 09:28:15 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-09-20 10:47:30 -04:00
|
|
|
void Submit(Kernel::HLERequestContext& ctx) {
|
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-09-20 10:51:13 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
2018-09-20 10:47:30 -04:00
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2018-02-22 09:28:15 -05:00
|
|
|
void GetRequestState(Kernel::HLERequestContext& ctx) {
|
2018-07-02 12:13:26 -04:00
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-02-22 09:28:15 -05:00
|
|
|
IPC::ResponseBuilder rb{ctx, 3};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
2018-09-20 22:15:49 -04:00
|
|
|
rb.Push<u32>(0);
|
2018-02-02 06:31:27 -05:00
|
|
|
}
|
2018-06-05 18:43:43 -04:00
|
|
|
|
2018-02-22 09:28:15 -05:00
|
|
|
void GetResult(Kernel::HLERequestContext& ctx) {
|
2018-07-02 12:13:26 -04:00
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-04-02 23:30:27 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
2018-02-22 09:28:15 -05:00
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
}
|
2018-06-05 18:43:43 -04:00
|
|
|
|
2018-02-22 09:28:15 -05:00
|
|
|
void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) {
|
2018-07-02 12:13:26 -04:00
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-02-22 09:28:15 -05:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 2};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
2018-11-26 18:34:07 -05:00
|
|
|
|
|
|
|
const auto& event1{Core::System::GetInstance().Kernel().FindNamedEvent("IRequest:Event1")};
|
|
|
|
const auto& event2{Core::System::GetInstance().Kernel().FindNamedEvent("IRequest:Event2")};
|
|
|
|
|
|
|
|
rb.PushCopyObjects(event1->second, event2->second);
|
2018-02-22 09:28:15 -05:00
|
|
|
}
|
2018-06-05 18:43:43 -04:00
|
|
|
|
2018-03-16 04:08:22 -04:00
|
|
|
void Cancel(Kernel::HLERequestContext& ctx) {
|
2018-07-02 12:13:26 -04:00
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-03-16 04:08:22 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
}
|
2018-02-22 09:28:15 -05:00
|
|
|
|
2018-06-05 18:43:43 -04:00
|
|
|
void SetConnectionConfirmationOption(Kernel::HLERequestContext& ctx) {
|
2018-07-02 12:13:26 -04:00
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-06-05 18:43:43 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2018-11-26 18:34:07 -05:00
|
|
|
Kernel::SharedPtr<Kernel::WritableEvent> event1, event2;
|
2018-02-02 06:31:27 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
class INetworkProfile final : public ServiceFramework<INetworkProfile> {
|
|
|
|
public:
|
|
|
|
explicit INetworkProfile() : ServiceFramework("INetworkProfile") {
|
|
|
|
static const FunctionInfo functions[] = {
|
|
|
|
{0, nullptr, "Update"},
|
|
|
|
{1, nullptr, "PersistOld"},
|
|
|
|
{2, nullptr, "Persist"},
|
|
|
|
};
|
|
|
|
RegisterHandlers(functions);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-03-16 04:00:29 -04:00
|
|
|
class IGeneralService final : public ServiceFramework<IGeneralService> {
|
|
|
|
public:
|
|
|
|
IGeneralService();
|
|
|
|
|
|
|
|
private:
|
|
|
|
void GetClientId(Kernel::HLERequestContext& ctx) {
|
2018-09-19 11:59:01 -04:00
|
|
|
static constexpr u32 client_id = 1;
|
2018-07-02 12:13:26 -04:00
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-03-16 04:00:29 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 4};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
2018-09-19 11:59:01 -04:00
|
|
|
rb.Push<u64>(client_id); // Client ID needs to be non zero otherwise it's considered invalid
|
2018-03-16 04:00:29 -04:00
|
|
|
}
|
|
|
|
void CreateScanRequest(Kernel::HLERequestContext& ctx) {
|
2018-11-26 01:06:13 -05:00
|
|
|
LOG_DEBUG(Service_NIFM, "called");
|
|
|
|
|
2018-03-16 04:00:29 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
|
|
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
rb.PushIpcInterface<IScanRequest>();
|
|
|
|
}
|
|
|
|
void CreateRequest(Kernel::HLERequestContext& ctx) {
|
2018-11-26 01:06:13 -05:00
|
|
|
LOG_DEBUG(Service_NIFM, "called");
|
|
|
|
|
2018-03-16 04:00:29 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
|
|
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
rb.PushIpcInterface<IRequest>();
|
|
|
|
}
|
|
|
|
void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
|
2018-07-02 12:13:26 -04:00
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-03-16 04:00:29 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
}
|
|
|
|
void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) {
|
2018-11-26 01:06:13 -05:00
|
|
|
LOG_DEBUG(Service_NIFM, "called");
|
|
|
|
|
2018-09-19 11:59:01 -04:00
|
|
|
ASSERT_MSG(ctx.GetReadBufferSize() == 0x17c, "NetworkProfileData is not the correct size");
|
|
|
|
u128 uuid{};
|
|
|
|
auto buffer = ctx.ReadBuffer();
|
|
|
|
std::memcpy(&uuid, buffer.data() + 8, sizeof(u128));
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 6, 0, 1};
|
2018-03-16 04:00:29 -04:00
|
|
|
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
rb.PushIpcInterface<INetworkProfile>();
|
2018-09-19 11:59:01 -04:00
|
|
|
rb.PushRaw<u128>(uuid);
|
2018-03-16 04:00:29 -04:00
|
|
|
}
|
2018-07-12 02:40:17 -04:00
|
|
|
void IsWirelessCommunicationEnabled(Kernel::HLERequestContext& ctx) {
|
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-07-12 02:40:17 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 3};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
rb.Push<u8>(0);
|
|
|
|
}
|
|
|
|
void IsEthernetCommunicationEnabled(Kernel::HLERequestContext& ctx) {
|
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-07-12 02:40:17 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 3};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
rb.Push<u8>(0);
|
|
|
|
}
|
|
|
|
void IsAnyInternetRequestAccepted(Kernel::HLERequestContext& ctx) {
|
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
2018-11-26 01:06:13 -05:00
|
|
|
|
2018-07-12 02:40:17 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 3};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
rb.Push<u8>(0);
|
|
|
|
}
|
2018-03-16 04:00:29 -04:00
|
|
|
};
|
|
|
|
|
2018-02-02 06:31:27 -05:00
|
|
|
IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") {
|
|
|
|
static const FunctionInfo functions[] = {
|
|
|
|
{1, &IGeneralService::GetClientId, "GetClientId"},
|
|
|
|
{2, &IGeneralService::CreateScanRequest, "CreateScanRequest"},
|
|
|
|
{4, &IGeneralService::CreateRequest, "CreateRequest"},
|
2018-03-16 09:34:12 -04:00
|
|
|
{5, nullptr, "GetCurrentNetworkProfile"},
|
|
|
|
{6, nullptr, "EnumerateNetworkInterfaces"},
|
|
|
|
{7, nullptr, "EnumerateNetworkProfiles"},
|
2018-02-02 06:31:27 -05:00
|
|
|
{8, nullptr, "GetNetworkProfile"},
|
|
|
|
{9, nullptr, "SetNetworkProfile"},
|
|
|
|
{10, &IGeneralService::RemoveNetworkProfile, "RemoveNetworkProfile"},
|
|
|
|
{11, nullptr, "GetScanDataOld"},
|
|
|
|
{12, nullptr, "GetCurrentIpAddress"},
|
|
|
|
{13, nullptr, "GetCurrentAccessPointOld"},
|
|
|
|
{14, &IGeneralService::CreateTemporaryNetworkProfile, "CreateTemporaryNetworkProfile"},
|
|
|
|
{15, nullptr, "GetCurrentIpConfigInfo"},
|
|
|
|
{16, nullptr, "SetWirelessCommunicationEnabled"},
|
2018-07-12 02:40:17 -04:00
|
|
|
{17, &IGeneralService::IsWirelessCommunicationEnabled, "IsWirelessCommunicationEnabled"},
|
2018-02-02 06:31:27 -05:00
|
|
|
{18, nullptr, "GetInternetConnectionStatus"},
|
|
|
|
{19, nullptr, "SetEthernetCommunicationEnabled"},
|
2018-07-12 02:40:17 -04:00
|
|
|
{20, &IGeneralService::IsEthernetCommunicationEnabled, "IsEthernetCommunicationEnabled"},
|
|
|
|
{21, &IGeneralService::IsAnyInternetRequestAccepted, "IsAnyInternetRequestAccepted"},
|
2018-02-02 06:31:27 -05:00
|
|
|
{22, nullptr, "IsAnyForegroundRequestAccepted"},
|
|
|
|
{23, nullptr, "PutToSleep"},
|
|
|
|
{24, nullptr, "WakeUp"},
|
|
|
|
{25, nullptr, "GetSsidListVersion"},
|
|
|
|
{26, nullptr, "SetExclusiveClient"},
|
|
|
|
{27, nullptr, "GetDefaultIpSetting"},
|
|
|
|
{28, nullptr, "SetDefaultIpSetting"},
|
|
|
|
{29, nullptr, "SetWirelessCommunicationEnabledForTest"},
|
|
|
|
{30, nullptr, "SetEthernetCommunicationEnabledForTest"},
|
|
|
|
{31, nullptr, "GetTelemetorySystemEventReadableHandle"},
|
|
|
|
{32, nullptr, "GetTelemetryInfo"},
|
|
|
|
{33, nullptr, "ConfirmSystemAvailability"},
|
|
|
|
{34, nullptr, "SetBackgroundRequestEnabled"},
|
|
|
|
{35, nullptr, "GetScanData"},
|
|
|
|
{36, nullptr, "GetCurrentAccessPoint"},
|
|
|
|
{37, nullptr, "Shutdown"},
|
2018-10-19 04:00:39 -04:00
|
|
|
{38, nullptr, "GetAllowedChannels"},
|
2018-02-02 06:31:27 -05:00
|
|
|
};
|
|
|
|
RegisterHandlers(functions);
|
|
|
|
}
|
|
|
|
|
2018-07-25 17:07:32 -04:00
|
|
|
class NetworkInterface final : public ServiceFramework<NetworkInterface> {
|
|
|
|
public:
|
|
|
|
explicit NetworkInterface(const char* name) : ServiceFramework{name} {
|
|
|
|
static const FunctionInfo functions[] = {
|
|
|
|
{4, &NetworkInterface::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
|
|
|
|
{5, &NetworkInterface::CreateGeneralService, "CreateGeneralService"},
|
|
|
|
};
|
|
|
|
RegisterHandlers(functions);
|
|
|
|
}
|
2018-02-02 06:31:27 -05:00
|
|
|
|
2018-07-25 17:07:32 -04:00
|
|
|
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
|
2018-11-26 01:06:13 -05:00
|
|
|
LOG_DEBUG(Service_NIFM, "called");
|
|
|
|
|
2018-07-25 17:07:32 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
rb.PushIpcInterface<IGeneralService>();
|
|
|
|
}
|
2018-02-02 06:31:27 -05:00
|
|
|
|
2018-07-25 17:07:32 -04:00
|
|
|
void CreateGeneralService(Kernel::HLERequestContext& ctx) {
|
2018-11-26 01:06:13 -05:00
|
|
|
LOG_DEBUG(Service_NIFM, "called");
|
|
|
|
|
2018-07-25 17:07:32 -04:00
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
|
rb.PushIpcInterface<IGeneralService>();
|
|
|
|
}
|
|
|
|
};
|
2018-02-02 06:31:27 -05:00
|
|
|
|
|
|
|
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
2018-07-25 17:07:32 -04:00
|
|
|
std::make_shared<NetworkInterface>("nifm:a")->InstallAsService(service_manager);
|
|
|
|
std::make_shared<NetworkInterface>("nifm:s")->InstallAsService(service_manager);
|
|
|
|
std::make_shared<NetworkInterface>("nifm:u")->InstallAsService(service_manager);
|
2018-02-02 06:31:27 -05:00
|
|
|
}
|
|
|
|
|
2018-04-19 21:41:44 -04:00
|
|
|
} // namespace Service::NIFM
|