early-access version 4165
This commit is contained in:
		| @@ -1,7 +1,7 @@ | ||||
| yuzu emulator early access | ||||
| ============= | ||||
|  | ||||
| This is the source code for early-access 4164. | ||||
| This is the source code for early-access 4165. | ||||
|  | ||||
| ## Legal Notice | ||||
|  | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
| #include <atomic> | ||||
| #include <cstddef> | ||||
| #include <cstring> | ||||
| #include <limits> | ||||
| #include <new> | ||||
| #include <span> | ||||
| #include <type_traits> | ||||
|   | ||||
| @@ -138,7 +138,7 @@ Result IAudioController::SetOutputModeSetting(Set::AudioOutputModeTarget target, | ||||
| } | ||||
|  | ||||
| Result IAudioController::SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode) { | ||||
|     LOG_WARNING(Audio, "(STUBBED) called"); | ||||
|     LOG_WARNING(Audio, "(STUBBED) called, output_level_mode={}", output_level_mode); | ||||
|     R_SUCCEED(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/btdrv/btdrv.h" | ||||
| #include "core/hle/service/cmif_serialization.h" | ||||
| #include "core/hle/service/ipc_helpers.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/server_manager.h" | ||||
| @@ -13,9 +14,9 @@ | ||||
|  | ||||
| namespace Service::BtDrv { | ||||
|  | ||||
| class Bt final : public ServiceFramework<Bt> { | ||||
| class IBluetoothUser final : public ServiceFramework<IBluetoothUser> { | ||||
| public: | ||||
|     explicit Bt(Core::System& system_) | ||||
|     explicit IBluetoothUser(Core::System& system_) | ||||
|         : ServiceFramework{system_, "bt"}, service_context{system_, "bt"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
| @@ -28,7 +29,7 @@ public: | ||||
|             {6, nullptr, "SetLeResponse"}, | ||||
|             {7, nullptr, "LeSendIndication"}, | ||||
|             {8, nullptr, "GetLeEventInfo"}, | ||||
|             {9, &Bt::RegisterBleEvent, "RegisterBleEvent"}, | ||||
|             {9, C<&IBluetoothUser::RegisterBleEvent>, "RegisterBleEvent"}, | ||||
|         }; | ||||
|         // clang-format on | ||||
|         RegisterHandlers(functions); | ||||
| @@ -36,17 +37,16 @@ public: | ||||
|         register_event = service_context.CreateEvent("BT:RegisterEvent"); | ||||
|     } | ||||
|  | ||||
|     ~Bt() override { | ||||
|     ~IBluetoothUser() override { | ||||
|         service_context.CloseEvent(register_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void RegisterBleEvent(HLERequestContext& ctx) { | ||||
|     Result RegisterBleEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||||
|         LOG_WARNING(Service_BTM, "(STUBBED) called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(register_event->GetReadableEvent()); | ||||
|         *out_event = ®ister_event->GetReadableEvent(); | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
| @@ -54,9 +54,9 @@ private: | ||||
|     Kernel::KEvent* register_event; | ||||
| }; | ||||
|  | ||||
| class BtDrv final : public ServiceFramework<BtDrv> { | ||||
| class IBluetoothDriver final : public ServiceFramework<IBluetoothDriver> { | ||||
| public: | ||||
|     explicit BtDrv(Core::System& system_) : ServiceFramework{system_, "btdrv"} { | ||||
|     explicit IBluetoothDriver(Core::System& system_) : ServiceFramework{system_, "btdrv"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, nullptr, "InitializeBluetoothDriver"}, | ||||
| @@ -93,7 +93,7 @@ public: | ||||
|             {31, nullptr, "EnableMcMode"}, | ||||
|             {32, nullptr, "EnableLlrScan"}, | ||||
|             {33, nullptr, "DisableLlrScan"}, | ||||
|             {34, nullptr, "EnableRadio"}, | ||||
|             {34, C<&IBluetoothDriver::EnableRadio>, "EnableRadio"}, | ||||
|             {35, nullptr, "SetVisibility"}, | ||||
|             {36, nullptr, "EnableTbfcScan"}, | ||||
|             {37, nullptr, "RegisterHidReportEvent"}, | ||||
| @@ -195,13 +195,19 @@ public: | ||||
|  | ||||
|         RegisterHandlers(functions); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     Result EnableRadio() { | ||||
|         LOG_WARNING(Service_BTDRV, "(STUBBED) called"); | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| void LoopProcess(Core::System& system) { | ||||
|     auto server_manager = std::make_unique<ServerManager>(system); | ||||
|  | ||||
|     server_manager->RegisterNamedService("btdrv", std::make_shared<BtDrv>(system)); | ||||
|     server_manager->RegisterNamedService("bt", std::make_shared<Bt>(system)); | ||||
|     server_manager->RegisterNamedService("btdrv", std::make_shared<IBluetoothDriver>(system)); | ||||
|     server_manager->RegisterNamedService("bt", std::make_shared<IBluetoothUser>(system)); | ||||
|     ServerManager::RunServer(std::move(server_manager)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -42,13 +42,13 @@ public: | ||||
|             {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"}, | ||||
|             {10702, nullptr, "AddPlayHistory"}, | ||||
|             {11000, nullptr, "GetProfileImageUrl"}, | ||||
|             {20100, nullptr, "GetFriendCount"}, | ||||
|             {20101, nullptr, "GetNewlyFriendCount"}, | ||||
|             {20100, &IFriendService::GetFriendCount, "GetFriendCount"}, | ||||
|             {20101, &IFriendService::GetNewlyFriendCount, "GetNewlyFriendCount"}, | ||||
|             {20102, nullptr, "GetFriendDetailedInfo"}, | ||||
|             {20103, nullptr, "SyncFriendList"}, | ||||
|             {20104, nullptr, "RequestSyncFriendList"}, | ||||
|             {20110, nullptr, "LoadFriendSetting"}, | ||||
|             {20200, nullptr, "GetReceivedFriendRequestCount"}, | ||||
|             {20200, &IFriendService::GetReceivedFriendRequestCount, "GetReceivedFriendRequestCount"}, | ||||
|             {20201, nullptr, "GetFriendRequestList"}, | ||||
|             {20300, nullptr, "GetFriendCandidateList"}, | ||||
|             {20301, nullptr, "GetNintendoNetworkIdInfo"}, | ||||
| @@ -61,14 +61,14 @@ public: | ||||
|             {20501, nullptr, "GetRelationship"}, | ||||
|             {20600, nullptr, "GetUserPresenceView"}, | ||||
|             {20700, nullptr, "GetPlayHistoryList"}, | ||||
|             {20701, nullptr, "GetPlayHistoryStatistics"}, | ||||
|             {20701, &IFriendService::GetPlayHistoryStatistics, "GetPlayHistoryStatistics"}, | ||||
|             {20800, nullptr, "LoadUserSetting"}, | ||||
|             {20801, nullptr, "SyncUserSetting"}, | ||||
|             {20900, nullptr, "RequestListSummaryOverlayNotification"}, | ||||
|             {21000, nullptr, "GetExternalApplicationCatalog"}, | ||||
|             {22000, nullptr, "GetReceivedFriendInvitationList"}, | ||||
|             {22001, nullptr, "GetReceivedFriendInvitationDetailedInfo"}, | ||||
|             {22010, nullptr, "GetReceivedFriendInvitationCountCache"}, | ||||
|             {22010, &IFriendService::GetReceivedFriendInvitationCountCache, "GetReceivedFriendInvitationCountCache"}, | ||||
|             {30100, nullptr, "DropFriendNewlyFlags"}, | ||||
|             {30101, nullptr, "DeleteFriend"}, | ||||
|             {30110, nullptr, "DropFriendNewlyFlag"}, | ||||
| @@ -144,6 +144,33 @@ private: | ||||
|         rb.PushCopyObjects(completion_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void GetFriendList(HLERequestContext& ctx) { | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|         const auto friend_offset = rp.Pop<u32>(); | ||||
|         const auto uuid = rp.PopRaw<Common::UUID>(); | ||||
|         [[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>(); | ||||
|         const auto pid = rp.Pop<u64>(); | ||||
|         LOG_WARNING(Service_Friend, "(STUBBED) called, offset={}, uuid=0x{}, pid={}", friend_offset, | ||||
|                     uuid.RawString(), pid); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|  | ||||
|         rb.Push<u32>(0); // Friend count | ||||
|         // TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId" | ||||
|     } | ||||
|  | ||||
|     void CheckFriendListAvailability(HLERequestContext& ctx) { | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|         const auto uuid{rp.PopRaw<Common::UUID>()}; | ||||
|  | ||||
|         LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push(true); | ||||
|     } | ||||
|  | ||||
|     void GetBlockedUserListIds(HLERequestContext& ctx) { | ||||
|         // This is safe to stub, as there should be no adverse consequences from reporting no | ||||
|         // blocked users. | ||||
| @@ -153,6 +180,17 @@ private: | ||||
|         rb.Push<u32>(0); // Indicates there are no blocked users | ||||
|     } | ||||
|  | ||||
|     void CheckBlockedUserListAvailability(HLERequestContext& ctx) { | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|         const auto uuid{rp.PopRaw<Common::UUID>()}; | ||||
|  | ||||
|         LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push(true); | ||||
|     } | ||||
|  | ||||
|     void DeclareCloseOnlinePlaySession(HLERequestContext& ctx) { | ||||
|         // Stub used by Splatoon 2 | ||||
|         LOG_WARNING(Service_Friend, "(STUBBED) called"); | ||||
| @@ -179,42 +217,43 @@ private: | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
|  | ||||
|     void GetFriendList(HLERequestContext& ctx) { | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|         const auto friend_offset = rp.Pop<u32>(); | ||||
|         const auto uuid = rp.PopRaw<Common::UUID>(); | ||||
|         [[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>(); | ||||
|         const auto pid = rp.Pop<u64>(); | ||||
|         LOG_WARNING(Service_Friend, "(STUBBED) called, offset={}, uuid=0x{}, pid={}", friend_offset, | ||||
|                     uuid.RawString(), pid); | ||||
|     void GetFriendCount(HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_Friend, "(STUBBED) called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|  | ||||
|         rb.Push<u32>(0); // Friend count | ||||
|         // TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId" | ||||
|         rb.Push(0); | ||||
|     } | ||||
|  | ||||
|     void CheckFriendListAvailability(HLERequestContext& ctx) { | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|         const auto uuid{rp.PopRaw<Common::UUID>()}; | ||||
|  | ||||
|         LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | ||||
|     void GetNewlyFriendCount(HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_Friend, "(STUBBED) called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push(true); | ||||
|         rb.Push(0); | ||||
|     } | ||||
|  | ||||
|     void CheckBlockedUserListAvailability(HLERequestContext& ctx) { | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|         const auto uuid{rp.PopRaw<Common::UUID>()}; | ||||
|  | ||||
|         LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); | ||||
|     void GetReceivedFriendRequestCount(HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_Friend, "(STUBBED) called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push(true); | ||||
|         rb.Push(0); | ||||
|     } | ||||
|  | ||||
|     void GetPlayHistoryStatistics(HLERequestContext& ctx) { | ||||
|         LOG_ERROR(Service_Friend, "(STUBBED) called, check in out"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
|  | ||||
|     void GetReceivedFriendInvitationCountCache(HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_Friend, "(STUBBED) called, check in out"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push(0); | ||||
|     } | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|   | ||||
| @@ -201,7 +201,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour | ||||
|         {1269, nullptr, "DeleteButtonConfigStorageLeft"}, | ||||
|         {1270, nullptr, "DeleteButtonConfigStorageRight"}, | ||||
|         {1271, &IHidSystemServer::IsUsingCustomButtonConfig, "IsUsingCustomButtonConfig"}, | ||||
|         {1272, nullptr, "IsAnyCustomButtonConfigEnabled"}, | ||||
|         {1272, &IHidSystemServer::IsAnyCustomButtonConfigEnabled, "IsAnyCustomButtonConfigEnabled"}, | ||||
|         {1273, nullptr, "SetAllCustomButtonConfigEnabled"}, | ||||
|         {1274, nullptr, "SetDefaultButtonConfig"}, | ||||
|         {1275, nullptr, "SetAllDefaultButtonConfig"}, | ||||
| @@ -926,6 +926,16 @@ void IHidSystemServer::IsUsingCustomButtonConfig(HLERequestContext& ctx) { | ||||
|     rb.Push(is_enabled); | ||||
| } | ||||
|  | ||||
| void IHidSystemServer::IsAnyCustomButtonConfigEnabled(HLERequestContext& ctx) { | ||||
|     const bool is_enabled = false; | ||||
|  | ||||
|     LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(is_enabled); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() { | ||||
|     resource_manager->Initialize(); | ||||
|     return resource_manager; | ||||
|   | ||||
| @@ -77,6 +77,7 @@ private: | ||||
|     void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx); | ||||
|     void SetForceHandheldStyleVibration(HLERequestContext& ctx); | ||||
|     void IsUsingCustomButtonConfig(HLERequestContext& ctx); | ||||
|     void IsAnyCustomButtonConfigEnabled(HLERequestContext& ctx); | ||||
|  | ||||
|     std::shared_ptr<ResourceManager> GetResourceManager(); | ||||
|  | ||||
|   | ||||
| @@ -18,8 +18,8 @@ public: | ||||
|     explicit LBL(Core::System& system_) : ServiceFramework{system_, "lbl"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, nullptr, "SaveCurrentSetting"}, | ||||
|             {1, nullptr, "LoadCurrentSetting"}, | ||||
|             {0, &LBL::SaveCurrentSetting, "SaveCurrentSetting"}, | ||||
|             {1, &LBL::LoadCurrentSetting, "LoadCurrentSetting"}, | ||||
|             {2, &LBL::SetCurrentBrightnessSetting, "SetCurrentBrightnessSetting"}, | ||||
|             {3, &LBL::GetCurrentBrightnessSetting, "GetCurrentBrightnessSetting"}, | ||||
|             {4, nullptr, "ApplyCurrentBrightnessSettingToBacklight"}, | ||||
| @@ -47,7 +47,7 @@ public: | ||||
|             {26, &LBL::EnableVrMode, "EnableVrMode"}, | ||||
|             {27, &LBL::DisableVrMode, "DisableVrMode"}, | ||||
|             {28, &LBL::IsVrModeEnabled, "IsVrModeEnabled"}, | ||||
|             {29, nullptr, "IsAutoBrightnessControlSupported"}, | ||||
|             {29, &LBL::IsAutoBrightnessControlSupported, "IsAutoBrightnessControlSupported"}, | ||||
|         }; | ||||
|         // clang-format on | ||||
|  | ||||
| @@ -60,6 +60,20 @@ private: | ||||
|         On = 1, | ||||
|     }; | ||||
|  | ||||
|     void SaveCurrentSetting(HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service_LBL, "(STUBBED) called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
|  | ||||
|     void LoadCurrentSetting(HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service_LBL, "(STUBBED) called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
|  | ||||
|     void SetCurrentBrightnessSetting(HLERequestContext& ctx) { | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|         auto brightness = rp.Pop<float>(); | ||||
| @@ -310,6 +324,14 @@ private: | ||||
|         rb.Push(vr_mode_enabled); | ||||
|     } | ||||
|  | ||||
|     void IsAutoBrightnessControlSupported(HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_LBL, "called"); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 3}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push<u8>(auto_brightness_supported); | ||||
|     } | ||||
|  | ||||
|     bool vr_mode_enabled = false; | ||||
|     float current_brightness = 1.0f; | ||||
|     float ambient_light_value = 0.0f; | ||||
| @@ -317,7 +339,8 @@ private: | ||||
|     bool dimming = true; | ||||
|     bool backlight_enabled = true; | ||||
|     bool update_instantly = false; | ||||
|     bool auto_brightness = false; // TODO(ogniK): Move to system settings | ||||
|     bool auto_brightness = false; | ||||
|     bool auto_brightness_supported = true; // TODO(ogniK): Move to system settings | ||||
| }; | ||||
|  | ||||
| void LoopProcess(Core::System& system) { | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
| #include "core/hle/service/nfc/nfc_result.h" | ||||
| #include "core/hle/service/psc/time/steady_clock.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/set/system_settings_server.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
| #include "hid_core/hid_types.h" | ||||
| #include "hid_core/hid_util.h" | ||||
| @@ -32,6 +33,9 @@ DeviceManager::DeviceManager(Core::System& system_, KernelHelpers::ServiceContex | ||||
|     } | ||||
|  | ||||
|     is_initialized = false; | ||||
|  | ||||
|     m_set_sys = | ||||
|         system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); | ||||
| } | ||||
|  | ||||
| DeviceManager ::~DeviceManager() { | ||||
| @@ -774,8 +778,8 @@ Result DeviceManager::CheckDeviceState(std::shared_ptr<NfcDevice> device) const | ||||
| } | ||||
|  | ||||
| Result DeviceManager::IsNfcEnabled() const { | ||||
|     // TODO: This calls nn::settings::detail::GetNfcEnableFlag | ||||
|     const bool is_enabled = true; | ||||
|     bool is_enabled{}; | ||||
|     R_TRY(m_set_sys->GetNfcEnableFlag(&is_enabled)); | ||||
|     if (!is_enabled) { | ||||
|         return ResultNfcDisabled; | ||||
|     } | ||||
|   | ||||
| @@ -15,6 +15,10 @@ | ||||
| #include "core/hle/service/service.h" | ||||
| #include "hid_core/hid_types.h" | ||||
|  | ||||
| namespace Service::Set { | ||||
| class ISystemSettingsServer; | ||||
| } | ||||
|  | ||||
| namespace Service::NFC { | ||||
| class NfcDevice; | ||||
|  | ||||
| @@ -98,6 +102,7 @@ private: | ||||
|     Core::System& system; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|     Kernel::KEvent* availability_change_event; | ||||
|     std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; | ||||
| }; | ||||
|  | ||||
| } // namespace Service::NFC | ||||
|   | ||||
| @@ -57,7 +57,7 @@ public: | ||||
|             {1, &NfcInterface::Finalize, "FinalizeOld"}, | ||||
|             {2, &NfcInterface::GetState, "GetStateOld"}, | ||||
|             {3, &NfcInterface::IsNfcEnabled, "IsNfcEnabledOld"}, | ||||
|             {100, nullptr, "SetNfcEnabledOld"}, | ||||
|             {100, &NfcInterface::SetNfcEnabled, "SetNfcEnabledOld"}, | ||||
|             {400, &NfcInterface::Initialize, "Initialize"}, | ||||
|             {401, &NfcInterface::Finalize, "Finalize"}, | ||||
|             {402, &NfcInterface::GetState, "GetState"}, | ||||
| @@ -71,7 +71,7 @@ public: | ||||
|             {410, &NfcInterface::GetTagInfo, "GetTagInfo"}, | ||||
|             {411, &NfcInterface::AttachActivateEvent, "AttachActivateEvent"}, | ||||
|             {412, &NfcInterface::AttachDeactivateEvent, "AttachDeactivateEvent"}, | ||||
|             {500, nullptr, "SetNfcEnabled"}, | ||||
|             {500, &NfcInterface::SetNfcEnabled, "SetNfcEnabled"}, | ||||
|             {510, nullptr, "OutputTestWave"}, | ||||
|             {1000, &NfcInterface::ReadMifare, "ReadMifare"}, | ||||
|             {1001, &NfcInterface::WriteMifare, "WriteMifare"}, | ||||
|   | ||||
| @@ -13,13 +13,18 @@ | ||||
| #include "core/hle/service/nfc/nfc_result.h" | ||||
| #include "core/hle/service/nfc/nfc_types.h" | ||||
| #include "core/hle/service/nfp/nfp_result.h" | ||||
| #include "core/hle/service/set/system_settings_server.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
| #include "hid_core/hid_types.h" | ||||
|  | ||||
| namespace Service::NFC { | ||||
|  | ||||
| NfcInterface::NfcInterface(Core::System& system_, const char* name, BackendType service_backend) | ||||
|     : ServiceFramework{system_, name}, service_context{system_, service_name}, | ||||
|       backend_type{service_backend} {} | ||||
|       backend_type{service_backend} { | ||||
|     m_set_sys = | ||||
|         system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); | ||||
| } | ||||
|  | ||||
| NfcInterface ::~NfcInterface() = default; | ||||
|  | ||||
| @@ -65,11 +70,11 @@ void NfcInterface::GetState(HLERequestContext& ctx) { | ||||
| void NfcInterface::IsNfcEnabled(HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_NFC, "called"); | ||||
|  | ||||
|     // TODO: This calls nn::settings::detail::GetNfcEnableFlag | ||||
|     const bool is_enabled = true; | ||||
|     bool is_enabled{}; | ||||
|     const auto result = m_set_sys->GetNfcEnableFlag(&is_enabled); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(result); | ||||
|     rb.Push(is_enabled); | ||||
| } | ||||
|  | ||||
| @@ -212,6 +217,17 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) { | ||||
|     rb.PushCopyObjects(out_event); | ||||
| } | ||||
|  | ||||
| void NfcInterface::SetNfcEnabled(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto is_enabled{rp.Pop<bool>()}; | ||||
|     LOG_DEBUG(Service_NFC, "called, is_enabled={}", is_enabled); | ||||
|  | ||||
|     const auto result = m_set_sys->SetNfcEnableFlag(is_enabled); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(result); | ||||
| } | ||||
|  | ||||
| void NfcInterface::ReadMifare(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto device_handle{rp.Pop<u64>()}; | ||||
|   | ||||
| @@ -7,6 +7,10 @@ | ||||
| #include "core/hle/service/nfc/nfc_types.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Service::Set { | ||||
| class ISystemSettingsServer; | ||||
| } | ||||
|  | ||||
| namespace Service::NFC { | ||||
| class DeviceManager; | ||||
|  | ||||
| @@ -29,6 +33,7 @@ public: | ||||
|     void AttachActivateEvent(HLERequestContext& ctx); | ||||
|     void AttachDeactivateEvent(HLERequestContext& ctx); | ||||
|     void ReadMifare(HLERequestContext& ctx); | ||||
|     void SetNfcEnabled(HLERequestContext& ctx); | ||||
|     void WriteMifare(HLERequestContext& ctx); | ||||
|     void SendCommandByPassThrough(HLERequestContext& ctx); | ||||
|  | ||||
| @@ -44,6 +49,7 @@ protected: | ||||
|     BackendType backend_type; | ||||
|     State state{State::NonInitialized}; | ||||
|     std::shared_ptr<DeviceManager> device_manager = nullptr; | ||||
|     std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; | ||||
| }; | ||||
|  | ||||
| } // namespace Service::NFC | ||||
|   | ||||
| @@ -3,22 +3,26 @@ | ||||
|  | ||||
| #include <memory> | ||||
|  | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/cmif_serialization.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/npns/npns.h" | ||||
| #include "core/hle/service/server_manager.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Service::NPNS { | ||||
|  | ||||
| class NPNS_S final : public ServiceFramework<NPNS_S> { | ||||
| class INpnsSystem final : public ServiceFramework<INpnsSystem> { | ||||
| public: | ||||
|     explicit NPNS_S(Core::System& system_) : ServiceFramework{system_, "npns:s"} { | ||||
|     explicit INpnsSystem(Core::System& system_) | ||||
|         : ServiceFramework{system_, "npns:s"}, service_context{system, "npns:s"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {1, nullptr, "ListenAll"}, | ||||
|             {2, nullptr, "ListenTo"}, | ||||
|             {2, C<&INpnsSystem::ListenTo>, "ListenTo"}, | ||||
|             {3, nullptr, "Receive"}, | ||||
|             {4, nullptr, "ReceiveRaw"}, | ||||
|             {5, nullptr, "GetReceiveEvent"}, | ||||
|             {5, C<&INpnsSystem::GetReceiveEvent>, "GetReceiveEvent"}, | ||||
|             {6, nullptr, "ListenUndelivered"}, | ||||
|             {7, nullptr, "GetStateChangeEVent"}, | ||||
|             {11, nullptr, "SubscribeTopic"}, | ||||
| @@ -59,12 +63,34 @@ public: | ||||
|         // clang-format on | ||||
|  | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         get_receive_event = service_context.CreateEvent("npns:s:GetReceiveEvent"); | ||||
|     } | ||||
|  | ||||
|     ~INpnsSystem() override { | ||||
|         service_context.CloseEvent(get_receive_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     Result ListenTo(u32 program_id) { | ||||
|         LOG_WARNING(Service_AM, "(STUBBED) called, program_id={}", program_id); | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
|  | ||||
|     Result GetReceiveEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { | ||||
|         LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
|  | ||||
|         *out_event = &get_receive_event->GetReadableEvent(); | ||||
|         R_SUCCEED(); | ||||
|     } | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|     Kernel::KEvent* get_receive_event; | ||||
| }; | ||||
|  | ||||
| class NPNS_U final : public ServiceFramework<NPNS_U> { | ||||
| class INpnsUser final : public ServiceFramework<INpnsUser> { | ||||
| public: | ||||
|     explicit NPNS_U(Core::System& system_) : ServiceFramework{system_, "npns:u"} { | ||||
|     explicit INpnsUser(Core::System& system_) : ServiceFramework{system_, "npns:u"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {1, nullptr, "ListenAll"}, | ||||
| @@ -97,8 +123,8 @@ public: | ||||
| void LoopProcess(Core::System& system) { | ||||
|     auto server_manager = std::make_unique<ServerManager>(system); | ||||
|  | ||||
|     server_manager->RegisterNamedService("npns:s", std::make_shared<NPNS_S>(system)); | ||||
|     server_manager->RegisterNamedService("npns:u", std::make_shared<NPNS_U>(system)); | ||||
|     server_manager->RegisterNamedService("npns:s", std::make_shared<INpnsSystem>(system)); | ||||
|     server_manager->RegisterNamedService("npns:u", std::make_shared<INpnsUser>(system)); | ||||
|     ServerManager::RunServer(std::move(server_manager)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -405,8 +405,7 @@ struct EulaVersion { | ||||
|     SystemRegionCode region_code; | ||||
|     EulaVersionClockType clock_type; | ||||
|     INSERT_PADDING_BYTES(0x4); | ||||
|     s64 posix_time; | ||||
|     Service::PSC::Time::SteadyClockTimePoint timestamp; | ||||
|     Service::PSC::Time::SystemClockContext system_clock_context; | ||||
| }; | ||||
| static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size"); | ||||
|  | ||||
|   | ||||
| @@ -306,6 +306,17 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) | ||||
|     RegisterHandlers(functions); | ||||
|  | ||||
|     SetupSettings(); | ||||
|  | ||||
|     // TODO: Remove this when starter applet is fully functional | ||||
|     EulaVersion eula_version{ | ||||
|         .version = 0x10000, | ||||
|         .region_code = m_system_settings.region_code, | ||||
|         .clock_type = EulaVersionClockType::SteadyClock, | ||||
|         .system_clock_context = m_system_settings.user_system_clock_context, | ||||
|     }; | ||||
|     m_system_settings.eula_versions[0] = eula_version; | ||||
|     m_system_settings.eula_version_count = 1; | ||||
|  | ||||
|     m_save_thread = | ||||
|         std::jthread([this](std::stop_token stop_token) { StoreSettingsThreadFunc(stop_token); }); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user