diff --git a/libraries/libstratosphere/include/stratosphere/cs/cs_command_processor.hpp b/libraries/libstratosphere/include/stratosphere/cs/cs_command_processor.hpp index 22912c523..0a250ce49 100644 --- a/libraries/libstratosphere/include/stratosphere/cs/cs_command_processor.hpp +++ b/libraries/libstratosphere/include/stratosphere/cs/cs_command_processor.hpp @@ -25,6 +25,8 @@ namespace ams::cs { class CommandProcessor : public scs::CommandProcessor { public: virtual bool ProcessCommand(const CommandHeader &header, const u8 *body, s32 socket) override; + private: + static void SendFirmwareVersion(s32 socket, const CommandHeader &header); }; } diff --git a/libraries/libstratosphere/include/stratosphere/scs/scs_command_processor.hpp b/libraries/libstratosphere/include/stratosphere/scs/scs_command_processor.hpp index adfe97b39..77aaef917 100644 --- a/libraries/libstratosphere/include/stratosphere/scs/scs_command_processor.hpp +++ b/libraries/libstratosphere/include/stratosphere/scs/scs_command_processor.hpp @@ -56,10 +56,15 @@ namespace ams::scs { }; enum Response { - Response_None = 0, - Response_Success = 1, - Response_Error = 2, - /* ... */ + Response_None = 0, + Response_Success = 1, + Response_Error = 2, + Response_ProgramExited = 3, + Response_FirmwareVersion = 4, + Response_JitDebug = 5, + Response_ProgramLaunched = 6, + Response_TitleName = 7, + Response_ScreenShot = 8, }; public: constexpr CommandProcessor() = default; @@ -68,16 +73,20 @@ namespace ams::scs { public: virtual bool ProcessCommand(const CommandHeader &header, const u8 *body, s32 socket); protected: + static std::scoped_lock MakeSendGuardBlock(); + static void Send(s32 socket, const void *data, size_t size); + static void SendSuccess(s32 socket, const CommandHeader &header); static void SendErrorResult(s32 socket, const CommandHeader &header, Result result); private: static void SendErrorResult(s32 socket, u64 id, Result result); + static void SendExited(s32 socket, u64 id, u64 process_id); + static void SendJitDebug(s32 socket, u64 id); + static void SendLaunched(s32 socket, u64 id, u64 process_id); static void OnProcessStart(u64 id, s32 socket, os::ProcessId process_id); static void OnProcessExit(u64 id, s32 socket, os::ProcessId process_id); static void OnProcessJitDebug(u64 id, s32 socket, os::ProcessId process_id); }; - os::SdkMutex &GetHtcsSendMutex(); - } diff --git a/libraries/libstratosphere/source/cs/cs_command_impl.cpp b/libraries/libstratosphere/source/cs/cs_command_impl.cpp new file mode 100644 index 000000000..c2615eead --- /dev/null +++ b/libraries/libstratosphere/source/cs/cs_command_impl.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "cs_command_impl.hpp" + +namespace ams::cs { + + Result DoGetFirmwareVersionCommand(settings::system::FirmwareVersion *out) { + settings::system::GetFirmwareVersion(out); + return ResultSuccess(); + } + +} diff --git a/libraries/libstratosphere/source/cs/cs_command_impl.hpp b/libraries/libstratosphere/source/cs/cs_command_impl.hpp new file mode 100644 index 000000000..7ad92ac2b --- /dev/null +++ b/libraries/libstratosphere/source/cs/cs_command_impl.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::cs { + + Result DoGetFirmwareVersionCommand(settings::system::FirmwareVersion *out); + +} diff --git a/libraries/libstratosphere/source/cs/cs_command_processor.cpp b/libraries/libstratosphere/source/cs/cs_command_processor.cpp index 2fd4e9e6d..d00ae2a72 100644 --- a/libraries/libstratosphere/source/cs/cs_command_processor.cpp +++ b/libraries/libstratosphere/source/cs/cs_command_processor.cpp @@ -14,11 +14,24 @@ * along with this program. If not, see . */ #include +#include "cs_command_impl.hpp" namespace ams::cs { + namespace { + + struct ResponseFirmwareVersion { + ResponseHeader header; + settings::system::FirmwareVersion firmware_version; + }; + + } + bool CommandProcessor::ProcessCommand(const CommandHeader &header, const u8 *body, s32 socket) { switch (header.command) { + case Command_GetFirmwareVersion: + SendFirmwareVersion(socket, header); + break; /* TODO: Command support. */ default: scs::CommandProcessor::ProcessCommand(header, body, socket); @@ -28,4 +41,26 @@ namespace ams::cs { return true; } + void CommandProcessor::SendFirmwareVersion(s32 socket, const CommandHeader &header) { + /* Build the response. */ + ResponseFirmwareVersion response = { + .header = { + .id = header.id, + .response = Response_FirmwareVersion, + .body_size = sizeof(response) - sizeof(response.header), + }, + .firmware_version = {}, + }; + + /* Get the firmware version. */ + const Result result = DoGetFirmwareVersionCommand(std::addressof(response.firmware_version)); + if (R_SUCCEEDED(result)) { + /* Send the response. */ + auto lk = MakeSendGuardBlock(); + Send(socket, std::addressof(response), sizeof(response)); + } else { + SendErrorResult(socket, header, result); + } + } + } diff --git a/libraries/libstratosphere/source/scs/scs_command_processor.cpp b/libraries/libstratosphere/source/scs/scs_command_processor.cpp index b3da75937..a0a64db6f 100644 --- a/libraries/libstratosphere/source/scs/scs_command_processor.cpp +++ b/libraries/libstratosphere/source/scs/scs_command_processor.cpp @@ -24,12 +24,26 @@ namespace ams::scs { u32 result; }; + struct ResponseProgramExited { + ResponseHeader header; + u64 process_id; + }; + + struct ResponseProgramLaunched { + ResponseHeader header; + u64 process_id; + }; + constinit os::SdkMutex g_htcs_send_mutex; } - os::SdkMutex &GetHtcsSendMutex() { - return g_htcs_send_mutex; + std::scoped_lock CommandProcessor::MakeSendGuardBlock() { + return std::scoped_lock{g_htcs_send_mutex}; + } + + void CommandProcessor::Send(s32 socket, const void *data, size_t size) { + htcs::Send(socket, data, size, 0); } void CommandProcessor::SendSuccess(s32 socket, const CommandHeader &header) { @@ -41,8 +55,8 @@ namespace ams::scs { }; /* Send the response. */ - std::scoped_lock lk(GetHtcsSendMutex()); - htcs::Send(socket, std::addressof(response), sizeof(response), 0); + auto lk = MakeSendGuardBlock(); + Send(socket, std::addressof(response), sizeof(response)); } void CommandProcessor::SendErrorResult(s32 socket, const CommandHeader &header, Result result) { @@ -61,23 +75,65 @@ namespace ams::scs { }; /* Send the response. */ - std::scoped_lock lk(GetHtcsSendMutex()); - htcs::Send(socket, std::addressof(response), sizeof(response), 0); + auto lk = MakeSendGuardBlock(); + Send(socket, std::addressof(response), sizeof(response)); + } + + void CommandProcessor::SendExited(s32 socket, u64 id, u64 process_id) { + /* Build the response. */ + const ResponseProgramExited response = { + .header = { + .id = id, + .response = Response_ProgramExited, + .body_size = sizeof(response) - sizeof(response.header), + }, + .process_id = process_id, + }; + + /* Send the response. */ + auto lk = MakeSendGuardBlock(); + Send(socket, std::addressof(response), sizeof(response)); + } + + void CommandProcessor::SendJitDebug(s32 socket, u64 id) { + /* Build the response. */ + const ResponseHeader response = { + .id = id, + .response = Response_JitDebug, + .body_size = 0, + }; + + /* Send the response. */ + auto lk = MakeSendGuardBlock(); + Send(socket, std::addressof(response), sizeof(response)); + } + + void CommandProcessor::SendLaunched(s32 socket, u64 id, u64 process_id) { + /* Build the response. */ + const ResponseProgramLaunched response = { + .header = { + .id = id, + .response = Response_ProgramLaunched, + .body_size = sizeof(response) - sizeof(response.header), + }, + .process_id = process_id, + }; + + /* Send the response. */ + auto lk = MakeSendGuardBlock(); + Send(socket, std::addressof(response), sizeof(response)); } void CommandProcessor::OnProcessStart(u64 id, s32 socket, os::ProcessId process_id) { - /* TODO */ - AMS_ABORT("CommandProcessor::OnProcessStart"); + SendLaunched(socket, id, process_id.value); } void CommandProcessor::OnProcessExit(u64 id, s32 socket, os::ProcessId process_id) { - /* TODO */ - AMS_ABORT("CommandProcessor::OnProcessExit"); + SendExited(socket, id, process_id.value); } void CommandProcessor::OnProcessJitDebug(u64 id, s32 socket, os::ProcessId process_id) { - /* TODO */ - AMS_ABORT("CommandProcessor::OnProcessJitDebug"); + SendJitDebug(socket, id); } void CommandProcessor::Initialize() { diff --git a/stratosphere/cs/source/cs_main.cpp b/stratosphere/cs/source/cs_main.cpp index 85de59736..b72898285 100644 --- a/stratosphere/cs/source/cs_main.cpp +++ b/stratosphere/cs/source/cs_main.cpp @@ -120,6 +120,7 @@ void __appInit(void) { lr::Initialize(); R_ABORT_UNLESS(ldr::InitializeForShell()); R_ABORT_UNLESS(pgl::Initialize()); + R_ABORT_UNLESS(setsysInitialize()); /* TODO: Other services? */ ams::CheckApiVersion(); @@ -127,6 +128,7 @@ void __appInit(void) { void __appExit(void) { /* TODO: Other services? */ + setsysExit(); pgl::Finalize(); ldr::FinalizeForShell(); lr::Finalize();