2026-01-24 14:15:08 +01:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
2025-11-27 19:46:41 +01:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
2022-04-23 04:59:50 -04:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2018-10-21 17:01:01 -04:00
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
2024-02-23 12:32:58 -06:00
|
|
|
#include "core/hle/kernel/k_event.h"
|
|
|
|
|
#include "core/hle/service/cmif_serialization.h"
|
|
|
|
|
#include "core/hle/service/kernel_helpers.h"
|
2018-10-21 17:01:01 -04:00
|
|
|
#include "core/hle/service/npns/npns.h"
|
2023-02-18 16:26:48 -05:00
|
|
|
#include "core/hle/service/server_manager.h"
|
2018-10-21 17:01:01 -04:00
|
|
|
#include "core/hle/service/service.h"
|
|
|
|
|
|
|
|
|
|
namespace Service::NPNS {
|
|
|
|
|
|
2024-02-23 12:32:58 -06:00
|
|
|
class INpnsSystem final : public ServiceFramework<INpnsSystem> {
|
2018-10-21 17:01:01 -04:00
|
|
|
public:
|
2024-02-23 12:32:58 -06:00
|
|
|
explicit INpnsSystem(Core::System& system_)
|
2026-01-24 14:15:08 +01:00
|
|
|
: ServiceFramework{system_, "npns:s"}, service_context{system, "npns:s"},
|
2026-09-25 15:57:13 +00:00
|
|
|
get_receive_event{service_context}, get_request_change_state_cancel_event{service_context} {}
|
|
|
|
|
|
|
|
|
|
FunctionInfoBase const* FindRequest(u32 key) override {
|
2026-09-26 06:34:09 +00:00
|
|
|
return HandlerTableGenerateWithFind(key, functions);
|
2018-10-21 17:01:01 -04:00
|
|
|
}
|
2024-02-23 12:32:58 -06:00
|
|
|
|
2026-01-24 14:15:08 +01:00
|
|
|
~INpnsSystem() override = default;
|
2024-02-23 12:32:58 -06:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Result ListenTo(u32 program_id) {
|
2025-04-14 13:13:50 +03:00
|
|
|
LOG_WARNING(Service_NPNS, "(STUBBED) called, program_id={}", program_id);
|
2024-02-23 12:32:58 -06:00
|
|
|
R_SUCCEED();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Result GetReceiveEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
2025-04-14 13:13:50 +03:00
|
|
|
LOG_WARNING(Service_NPNS, "(STUBBED) called");
|
2024-02-23 12:32:58 -06:00
|
|
|
|
2026-01-24 14:15:08 +01:00
|
|
|
*out_event = get_receive_event.GetHandle();
|
2024-02-23 12:32:58 -06:00
|
|
|
R_SUCCEED();
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-14 13:13:50 +03:00
|
|
|
Result ListenToByName() {
|
|
|
|
|
LOG_DEBUG(Service_NPNS, "(STUBBED) called.");
|
|
|
|
|
|
|
|
|
|
// TODO (jarrodnorwell)
|
|
|
|
|
|
|
|
|
|
R_SUCCEED();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Result GetState(Out<u32> out_state) {
|
|
|
|
|
LOG_WARNING(Service_NPNS, "(STUBBED) called");
|
|
|
|
|
*out_state = 0;
|
|
|
|
|
R_SUCCEED();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Result GetLastNotifiedTime(Out<s64> out_last_notified_time) {
|
|
|
|
|
LOG_WARNING(Service_NPNS, "(STUBBED) called");
|
|
|
|
|
|
|
|
|
|
*out_last_notified_time = 0;
|
|
|
|
|
R_SUCCEED();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Result GetRequestChangeStateCancelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
|
|
|
|
LOG_DEBUG(Service_NPNS, "(STUBBED) called.");
|
|
|
|
|
|
|
|
|
|
// TODO (jarrodnorwell)
|
|
|
|
|
|
2026-01-24 14:15:08 +01:00
|
|
|
*out_event = get_request_change_state_cancel_event.GetHandle();
|
2025-04-14 13:13:50 +03:00
|
|
|
|
|
|
|
|
R_SUCCEED();
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-26 06:34:09 +00:00
|
|
|
static constexpr auto functions = CreateStaticMap(
|
|
|
|
|
FunctionInfo{1, nullptr, "ListenAll"},
|
|
|
|
|
FunctionInfo{2, C<&INpnsSystem::ListenTo>, "ListenTo"},
|
|
|
|
|
FunctionInfo{3, nullptr, "Receive"},
|
|
|
|
|
FunctionInfo{4, nullptr, "ReceiveRaw"},
|
|
|
|
|
FunctionInfo{5, C<&INpnsSystem::GetReceiveEvent>, "GetReceiveEvent"},
|
|
|
|
|
FunctionInfo{6, nullptr, "ListenUndelivered"},
|
|
|
|
|
FunctionInfo{7, nullptr, "GetStateChangeEvent"},
|
|
|
|
|
FunctionInfo{8, C<&INpnsSystem::ListenToByName>, "ListenToByName"},
|
|
|
|
|
FunctionInfo{11, nullptr, "SubscribeTopic"},
|
|
|
|
|
FunctionInfo{12, nullptr, "UnsubscribeTopic"},
|
|
|
|
|
FunctionInfo{13, nullptr, "QueryIsTopicExist"},
|
|
|
|
|
FunctionInfo{14, nullptr, "SubscribeTopicByAccount"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{15, nullptr, "UnsubscribeTopicByAccount"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{16, nullptr, "DownloadSubscriptionList"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{21, nullptr, "CreateToken"},
|
|
|
|
|
FunctionInfo{22, nullptr, "CreateTokenWithApplicationId"},
|
|
|
|
|
FunctionInfo{23, nullptr, "DestroyToken"},
|
|
|
|
|
FunctionInfo{24, nullptr, "DestroyTokenWithApplicationId"},
|
|
|
|
|
FunctionInfo{25, nullptr, "QueryIsTokenValid"},
|
|
|
|
|
FunctionInfo{26, nullptr, "ListenToMyApplicationId"},
|
|
|
|
|
FunctionInfo{27, nullptr, "DestroyTokenAll"},
|
|
|
|
|
FunctionInfo{28, nullptr, "CreateTokenWithName"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{29, nullptr, "DestroyTokenWithName"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{31, nullptr, "UploadTokenToBaaS"},
|
|
|
|
|
FunctionInfo{32, nullptr, "DestroyTokenForBaaS"},
|
|
|
|
|
FunctionInfo{33, nullptr, "CreateTokenForBaaS"},
|
|
|
|
|
FunctionInfo{34, nullptr, "SetBaaSDeviceAccountIdList"},
|
|
|
|
|
FunctionInfo{35, nullptr, "LinkNsaId"}, // 17.0.0+
|
|
|
|
|
FunctionInfo{36, nullptr, "UnlinkNsaId"}, // 17.0.0+
|
|
|
|
|
FunctionInfo{37, nullptr, "RelinkNsaId"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{40, nullptr, "GetNetworkServiceAccountIdTokenRequestEvent"}, // 17.0.0+
|
|
|
|
|
FunctionInfo{41, nullptr, "TryPopNetworkServiceAccountIdTokenRequestUid"}, // 17.0.0+
|
|
|
|
|
FunctionInfo{42, nullptr, "SetNetworkServiceAccountIdTokenSuccess"}, // 17.0.0+
|
|
|
|
|
FunctionInfo{43, nullptr, "SetNetworkServiceAccountIdTokenFailure"}, // 17.0.0+
|
|
|
|
|
FunctionInfo{44, nullptr, "SetUidList"}, // 17.0.0+
|
|
|
|
|
FunctionInfo{45, nullptr, "PutDigitalTwinKeyValue"}, // 17.0.0+
|
|
|
|
|
FunctionInfo{51, nullptr, "DeleteDigitalTwinKeyValue"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{101, nullptr, "Suspend"},
|
|
|
|
|
FunctionInfo{102, nullptr, "Resume"},
|
|
|
|
|
FunctionInfo{103, C<&INpnsSystem::GetState>, "GetState"},
|
|
|
|
|
FunctionInfo{104, nullptr, "GetStatistics"},
|
|
|
|
|
FunctionInfo{105, nullptr, "GetPlayReportRequestEvent"},
|
|
|
|
|
FunctionInfo{106, C<&INpnsSystem::GetLastNotifiedTime>, "GetLastNotifiedTime"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{107, nullptr, "SetLastNotifiedTime"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{111, nullptr, "GetJid"},
|
|
|
|
|
FunctionInfo{112, nullptr, "CreateJid"},
|
|
|
|
|
FunctionInfo{113, nullptr, "DestroyJid"},
|
|
|
|
|
FunctionInfo{114, nullptr, "AttachJid"},
|
|
|
|
|
FunctionInfo{115, nullptr, "DetachJid"},
|
|
|
|
|
FunctionInfo{120, nullptr, "CreateNotificationReceiver"},
|
|
|
|
|
FunctionInfo{151, nullptr, "GetStateWithHandover"},
|
|
|
|
|
FunctionInfo{152, nullptr, "GetStateChangeEventWithHandover"},
|
|
|
|
|
FunctionInfo{153, nullptr, "GetDropEventWithHandover"},
|
|
|
|
|
FunctionInfo{154, nullptr, "CreateTokenAsync"},
|
|
|
|
|
FunctionInfo{155, nullptr, "CreateTokenAsyncWithApplicationId"},
|
|
|
|
|
FunctionInfo{156, nullptr, "CreateTokenWithNameAsync"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{161, C<&INpnsSystem::GetRequestChangeStateCancelEvent>, "GetRequestChangeStateCancelEvent"}, // 10.0.0+
|
|
|
|
|
FunctionInfo{162, nullptr, "RequestChangeStateForceTimedWithCancelEvent"},
|
|
|
|
|
FunctionInfo{201, nullptr, "RequestChangeStateForceTimed"},
|
|
|
|
|
FunctionInfo{202, nullptr, "RequestChangeStateForceAsync"},
|
|
|
|
|
FunctionInfo{301, nullptr, "GetPassword"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{302, nullptr, "GetAllImmigration"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{303, nullptr, "GetNotificationHistories"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{304, nullptr, "GetPersistentConnectionSummary"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{305, nullptr, "GetDigitalTwinSummary"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{306, nullptr, "GetDigitalTwinValue"} // 18.0.0+
|
|
|
|
|
);
|
2024-02-23 12:32:58 -06:00
|
|
|
KernelHelpers::ServiceContext service_context;
|
2026-01-24 14:15:08 +01:00
|
|
|
Event get_receive_event;
|
|
|
|
|
Event get_request_change_state_cancel_event;
|
2018-10-21 17:01:01 -04:00
|
|
|
};
|
|
|
|
|
|
2024-02-23 12:32:58 -06:00
|
|
|
class INpnsUser final : public ServiceFramework<INpnsUser> {
|
2018-10-21 17:01:01 -04:00
|
|
|
public:
|
2025-11-27 19:46:41 +01:00
|
|
|
explicit INpnsUser(Core::System& system_)
|
2026-09-25 15:57:13 +00:00
|
|
|
: ServiceFramework{system_, "npns:u"}, service_context{system, "npns:u"}, get_receive_event{service_context} {}
|
|
|
|
|
|
|
|
|
|
FunctionInfoBase const* FindRequest(u32 key) override {
|
2026-09-26 06:34:09 +00:00
|
|
|
return HandlerTableGenerateWithFind(key, functions);
|
2025-11-27 19:46:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Result ListenToByName(InBuffer<BufferAttr_HipcMapAlias> name_buffer) {
|
|
|
|
|
const std::string name(reinterpret_cast<const char*>(name_buffer.data()), name_buffer.size());
|
|
|
|
|
LOG_DEBUG(Service_NPNS, "called, name={}", name);
|
|
|
|
|
|
|
|
|
|
// Store the name for future use if needed
|
|
|
|
|
// For now, just acknowledge the registration
|
|
|
|
|
R_SUCCEED();
|
2018-10-21 17:01:01 -04:00
|
|
|
}
|
2025-11-27 19:46:41 +01:00
|
|
|
|
|
|
|
|
Result GetReceiveEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
|
|
|
|
LOG_DEBUG(Service_NPNS, "called");
|
|
|
|
|
|
2026-01-24 14:15:08 +01:00
|
|
|
*out_event = get_receive_event.GetHandle();
|
2025-11-27 19:46:41 +01:00
|
|
|
R_SUCCEED();
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-26 06:34:09 +00:00
|
|
|
static constexpr auto functions = CreateStaticMap(
|
|
|
|
|
FunctionInfo{1, nullptr, "ListenAll"},
|
|
|
|
|
FunctionInfo{2, nullptr, "ListenTo"},
|
|
|
|
|
FunctionInfo{3, nullptr, "Receive"},
|
|
|
|
|
FunctionInfo{4, nullptr, "ReceiveRaw"},
|
|
|
|
|
FunctionInfo{5, C<&INpnsUser::GetReceiveEvent>, "GetReceiveEvent"},
|
|
|
|
|
FunctionInfo{7, nullptr, "GetStateChangeEvent"},
|
|
|
|
|
FunctionInfo{8, C<&INpnsUser::ListenToByName>, "ListenToByName"}, // 18.0.0+
|
|
|
|
|
FunctionInfo{21, nullptr, "CreateToken"},
|
|
|
|
|
FunctionInfo{23, nullptr, "DestroyToken"},
|
|
|
|
|
FunctionInfo{25, nullptr, "QueryIsTokenValid"},
|
|
|
|
|
FunctionInfo{26, nullptr, "ListenToMyApplicationId"},
|
|
|
|
|
FunctionInfo{101, nullptr, "Suspend"},
|
|
|
|
|
FunctionInfo{102, nullptr, "Resume"},
|
|
|
|
|
FunctionInfo{103, nullptr, "GetState"},
|
|
|
|
|
FunctionInfo{104, nullptr, "GetStatistics"},
|
|
|
|
|
FunctionInfo{111, nullptr, "GetJid"},
|
|
|
|
|
FunctionInfo{120, nullptr, "CreateNotificationReceiver"},
|
|
|
|
|
FunctionInfo{151, nullptr, "GetStateWithHandover"},
|
|
|
|
|
FunctionInfo{152, nullptr, "GetStateChangeEventWithHandover"},
|
|
|
|
|
FunctionInfo{153, nullptr, "GetDropEventWithHandover"},
|
|
|
|
|
FunctionInfo{154, nullptr, "CreateTokenAsync"}
|
|
|
|
|
);
|
2025-11-27 19:46:41 +01:00
|
|
|
KernelHelpers::ServiceContext service_context;
|
2026-01-24 14:15:08 +01:00
|
|
|
Event get_receive_event;
|
2018-10-21 17:01:01 -04:00
|
|
|
};
|
|
|
|
|
|
2023-02-18 16:26:48 -05:00
|
|
|
void LoopProcess(Core::System& system) {
|
|
|
|
|
auto server_manager = std::make_unique<ServerManager>(system);
|
|
|
|
|
|
2024-02-23 12:32:58 -06:00
|
|
|
server_manager->RegisterNamedService("npns:s", std::make_shared<INpnsSystem>(system));
|
|
|
|
|
server_manager->RegisterNamedService("npns:u", std::make_shared<INpnsUser>(system));
|
2023-02-18 16:26:48 -05:00
|
|
|
ServerManager::RunServer(std::move(server_manager));
|
2018-10-21 17:01:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Service::NPNS
|