From 7ada8da8a84c0607603c91d5b57dcd8a647a440f Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 13:22:48 +0300 Subject: [PATCH 1/6] Start adding SD card support --- include/fs/archive_sdmc.hpp | 2 +- include/services/fs.hpp | 10 ++++--- src/core/fs/archive_save_data.cpp | 6 ++-- src/core/fs/archive_sdmc.cpp | 43 +++++++++++++++++++++++++-- src/core/services/fs.cpp | 19 ++++++------ src/core/services/service_manager.cpp | 2 +- 6 files changed, 62 insertions(+), 20 deletions(-) diff --git a/include/fs/archive_sdmc.hpp b/include/fs/archive_sdmc.hpp index a8d9e259..23cbe600 100644 --- a/include/fs/archive_sdmc.hpp +++ b/include/fs/archive_sdmc.hpp @@ -8,7 +8,7 @@ class SDMCArchive : public ArchiveBase { public: SDMCArchive(Memory& mem) : ArchiveBase(mem) {} - u64 getFreeBytes() override { Helpers::panic("SDMC::GetFreeBytes unimplemented"); return 0; } + u64 getFreeBytes() override { return 1_GB; } std::string name() override { return "SDMC"; } HorizonResult createFile(const FSPath& path, u64 size) override; diff --git a/include/services/fs.hpp b/include/services/fs.hpp index fb098c7d..e65be798 100644 --- a/include/services/fs.hpp +++ b/include/services/fs.hpp @@ -1,4 +1,5 @@ #pragma once +#include "config.hpp" #include "fs/archive_ext_save_data.hpp" #include "fs/archive_ncch.hpp" #include "fs/archive_save_data.hpp" @@ -8,7 +9,6 @@ #include "kernel_types.hpp" #include "logger.hpp" #include "memory.hpp" -#include "result/result.hpp" // Yay, more circular dependencies class Kernel; @@ -35,6 +35,8 @@ class FSService { std::optional openFileHandle(ArchiveBase* archive, const FSPath& path, const FSPath& archivePath, const FilePerms& perms); FSPath readPath(u32 type, u32 pointer, u32 size); + const EmulatorConfig& config; + // Service commands void createDirectory(u32 messagePointer); void createExtSaveData(u32 messagePointer); @@ -62,9 +64,9 @@ class FSService { u32 priority; public: - FSService(Memory& mem, Kernel& kernel) : mem(mem), saveData(mem), - sharedExtSaveData_nand(mem, "../SharedFiles/NAND", true), extSaveData_sdmc(mem, "SDMC"), - sdmc(mem), selfNcch(mem), ncch(mem), kernel(kernel) + FSService(Memory& mem, Kernel& kernel, const EmulatorConfig& config) : mem(mem), saveData(mem), + sharedExtSaveData_nand(mem, "../SharedFiles/NAND", true), extSaveData_sdmc(mem, "SDMC"), sdmc(mem), selfNcch(mem), + ncch(mem), kernel(kernel), config(config) {} void reset(); diff --git a/src/core/fs/archive_save_data.cpp b/src/core/fs/archive_save_data.cpp index 107aefde..97ae3229 100644 --- a/src/core/fs/archive_save_data.cpp +++ b/src/core/fs/archive_save_data.cpp @@ -92,11 +92,13 @@ HorizonResult SaveDataArchive::deleteFile(const FSPath& path) { FileDescriptor SaveDataArchive::openFile(const FSPath& path, const FilePerms& perms) { if (path.type == PathType::UTF16) { - if (!isPathSafe(path)) + if (!isPathSafe(path)) { Helpers::panic("Unsafe path in SaveData::OpenFile"); + } - if (perms.raw == 0 || (perms.create() && !perms.write())) + if (perms.raw == 0 || (perms.create() && !perms.write())) { Helpers::panic("[SaveData] Unsupported flags for OpenFile"); + } fs::path p = IOFile::getAppData() / "SaveData"; p += fs::path(path.utf16_string).make_preferred(); diff --git a/src/core/fs/archive_sdmc.cpp b/src/core/fs/archive_sdmc.cpp index 5049df14..428354d1 100644 --- a/src/core/fs/archive_sdmc.cpp +++ b/src/core/fs/archive_sdmc.cpp @@ -1,6 +1,8 @@ #include "fs/archive_sdmc.hpp" #include +namespace fs = std::filesystem; + HorizonResult SDMCArchive::createFile(const FSPath& path, u64 size) { Helpers::panic("[SDMC] CreateFile not yet supported"); return Result::Success; @@ -12,13 +14,48 @@ HorizonResult SDMCArchive::deleteFile(const FSPath& path) { } FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) { - printf("SDMCArchive::OpenFile: Failed"); + if (path.type == PathType::ASCII) { + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SaveData::OpenFile"); + } + + if (perms.raw == 0 || (perms.create() && !perms.write())) { + Helpers::panic("[SaveData] Unsupported flags for OpenFile"); + } + + fs::path p = IOFile::getAppData() / "SDMC"; + p += fs::path(path.string).make_preferred(); + + const char* permString = perms.write() ? "r+b" : "rb"; + + if (fs::exists(p)) { // Return file descriptor if the file exists + IOFile file(p.string().c_str(), permString); + return file.isOpen() ? file.getHandle() : FileError; + } else { + // If the file is not found, create it if the create flag is on + if (perms.create()) { + IOFile file(p.string().c_str(), "wb"); // Create file + file.close(); // Close it + + file.open(p.string().c_str(), permString); // Reopen with proper perms + return file.isOpen() ? file.getHandle() : FileError; + } else { + return FileError; + } + } + } + + Helpers::panic("SDMCArchive::OpenFile: Failed"); return FileError; } Rust::Result SDMCArchive::openArchive(const FSPath& path) { - printf("SDMCArchive::OpenArchive: Failed\n"); - return Err(Result::FS::NotFormatted); + // TODO: Fail here if the SD is disabled in the connfig. + if (path.type != PathType::Empty) { + Helpers::panic("Unimplemented path type for SDMC::OpenArchive"); + } + + return Ok((ArchiveBase*)this); } std::optional SDMCArchive::readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) { diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index 38a526e3..cc3c3a76 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -2,6 +2,7 @@ #include "kernel/kernel.hpp" #include "io_file.hpp" #include "ipc.hpp" +#include "result/result.hpp" #ifdef CreateFile // windows.h defines CreateFile & DeleteFile because of course it does. #undef CreateDirectory @@ -338,7 +339,8 @@ void FSService::openFileDirectly(u32 messagePointer) { std::optional handle = openFileHandle(archive, filePath, archivePath, perms); mem.write32(messagePointer, IPC::responseHeader(0x803, 1, 2)); if (!handle.has_value()) { - Helpers::panic("OpenFileDirectly: Failed to open file with given path"); + printf("OpenFileDirectly failed\n"); + mem.write32(messagePointer + 4, Result::FS::FileNotFound); } else { mem.write32(messagePointer + 4, Result::Success); mem.write32(messagePointer + 12, handle.value()); @@ -582,22 +584,21 @@ void FSService::setPriority(u32 messagePointer) { priority = value; } - -// Shows whether an SD card is inserted. At the moment stubbed to no -constexpr bool sdInserted = false; - void FSService::isSdmcDetected(u32 messagePointer) { log("FS::IsSdmcDetected\n"); + mem.write32(messagePointer, IPC::responseHeader(0x817, 2, 0)); mem.write32(messagePointer + 4, Result::Success); - mem.write8(messagePointer + 8, sdInserted ? 1 : 0); + mem.write8(messagePointer + 8, config.sdCardInserted ? 1 : 0); } -// We consider our SD card to always be writable if oen is inserted for now -// So isSdmcWritable returns 1 if an SD card is inserted (because it's always writable) and 0 if not. +// We consider our SD card to always be writable if one is inserted for now +// However we do make sure to respect the configs and properly return the correct value here void FSService::isSdmcWritable(u32 messagePointer) { log("FS::isSdmcWritable\n"); + const bool writeProtected = (!config.sdCardInserted) || (config.sdCardInserted && config.sdWriteProtected); + mem.write32(messagePointer, IPC::responseHeader(0x818, 2, 0)); mem.write32(messagePointer + 4, Result::Success); - mem.write8(messagePointer + 8, sdInserted ? 1 : 0); + mem.write8(messagePointer + 8, writeProtected ? 0 : 1); } \ No newline at end of file diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index 591d424a..15fcb401 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -7,7 +7,7 @@ ServiceManager::ServiceManager(std::span regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel, const EmulatorConfig& config) : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem, kernel), cecd(mem, kernel), cfg(mem), - dlp_srvr(mem), dsp(mem, kernel), hid(mem, kernel), http(mem), ir_user(mem, kernel), frd(mem), fs(mem, kernel), + dlp_srvr(mem), dsp(mem, kernel), hid(mem, kernel), http(mem), ir_user(mem, kernel), frd(mem), fs(mem, kernel, config), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), mcu_hwc(mem, config), mic(mem), nfc(mem, kernel), nim(mem), ndm(mem), ptm(mem, config), soc(mem), ssl(mem), y2r(mem, kernel) {} From 0ef46cf8b0ab6f3caedfc5b0ef281fbdcab5d4d3 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 13:31:02 +0300 Subject: [PATCH 2/6] SDMC archive always has read perms --- src/core/fs/archive_sdmc.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/fs/archive_sdmc.cpp b/src/core/fs/archive_sdmc.cpp index 428354d1..c8e4ebb3 100644 --- a/src/core/fs/archive_sdmc.cpp +++ b/src/core/fs/archive_sdmc.cpp @@ -19,7 +19,11 @@ FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) Helpers::panic("Unsafe path in SaveData::OpenFile"); } - if (perms.raw == 0 || (perms.create() && !perms.write())) { + FilePerms realPerms = perms; + // SD card always has read permission + realPerms.raw |= (1 << 0); + + if ((realPerms.create() && !realPerms.write())) { Helpers::panic("[SaveData] Unsupported flags for OpenFile"); } @@ -33,7 +37,7 @@ FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) return file.isOpen() ? file.getHandle() : FileError; } else { // If the file is not found, create it if the create flag is on - if (perms.create()) { + if (realPerms.create()) { IOFile file(p.string().c_str(), "wb"); // Create file file.close(); // Close it From 9ee7543f9a796d3a73d17d1b8832741cf3529ce8 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 13:55:38 +0300 Subject: [PATCH 3/6] Moar SDMC --- include/fs/archive_sdmc.hpp | 3 + src/core/fs/archive_save_data.cpp | 10 ++- src/core/fs/archive_sdmc.cpp | 112 +++++++++++++++++++++++------- 3 files changed, 96 insertions(+), 29 deletions(-) diff --git a/include/fs/archive_sdmc.hpp b/include/fs/archive_sdmc.hpp index 23cbe600..4aa80eab 100644 --- a/include/fs/archive_sdmc.hpp +++ b/include/fs/archive_sdmc.hpp @@ -13,8 +13,11 @@ public: HorizonResult createFile(const FSPath& path, u64 size) override; HorizonResult deleteFile(const FSPath& path) override; + HorizonResult createDirectory(const FSPath& path) override; Rust::Result openArchive(const FSPath& path) override; + Rust::Result openDirectory(const FSPath& path) override; + FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override; }; \ No newline at end of file diff --git a/src/core/fs/archive_save_data.cpp b/src/core/fs/archive_save_data.cpp index 97ae3229..aa94cdc4 100644 --- a/src/core/fs/archive_save_data.cpp +++ b/src/core/fs/archive_save_data.cpp @@ -39,14 +39,17 @@ HorizonResult SaveDataArchive::createFile(const FSPath& path, u64 size) { HorizonResult SaveDataArchive::createDirectory(const FSPath& path) { if (path.type == PathType::UTF16) { - if (!isPathSafe(path)) + if (!isPathSafe(path)) { Helpers::panic("Unsafe path in SaveData::OpenFile"); + } fs::path p = IOFile::getAppData() / "SaveData"; p += fs::path(path.utf16_string).make_preferred(); - if (fs::is_directory(p)) + if (fs::is_directory(p)) { return Result::FS::AlreadyExists; + } + if (fs::is_regular_file(p)) { Helpers::panic("File path passed to SaveData::CreateDirectory"); } @@ -128,8 +131,9 @@ FileDescriptor SaveDataArchive::openFile(const FSPath& path, const FilePerms& pe Rust::Result SaveDataArchive::openDirectory(const FSPath& path) { if (path.type == PathType::UTF16) { - if (!isPathSafe(path)) + if (!isPathSafe(path)) { Helpers::panic("Unsafe path in SaveData::OpenDirectory"); + } fs::path p = IOFile::getAppData() / "SaveData"; p += fs::path(path.utf16_string).make_preferred(); diff --git a/src/core/fs/archive_sdmc.cpp b/src/core/fs/archive_sdmc.cpp index c8e4ebb3..ee5c8ffb 100644 --- a/src/core/fs/archive_sdmc.cpp +++ b/src/core/fs/archive_sdmc.cpp @@ -14,43 +14,103 @@ HorizonResult SDMCArchive::deleteFile(const FSPath& path) { } FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) { - if (path.type == PathType::ASCII) { - if (!isPathSafe(path)) { - Helpers::panic("Unsafe path in SaveData::OpenFile"); + FilePerms realPerms = perms; + // SD card always has read permission + realPerms.raw |= (1 << 0); + + if ((realPerms.create() && !realPerms.write())) { + Helpers::panic("[SDMC] Unsupported flags for OpenFile"); + } + + std::filesystem::path p = IOFile::getAppData() / "SDMC"; + + switch (path.type) { + case PathType::ASCII: + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SDMCArchive::OpenFile"); + } + + p += fs::path(path.string).make_preferred(); + break; + + case PathType::UTF16: + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SDMCArchive::OpenFile"); + } + + p += fs::path(path.utf16_string).make_preferred(); + break; + + default: Helpers::panic("SDMCArchive::OpenFile: Failed. Path type: %d", path.type); return FileError; + } + + const char* permString = perms.write() ? "r+b" : "rb"; + + if (fs::exists(p)) { // Return file descriptor if the file exists + IOFile file(p.string().c_str(), permString); + return file.isOpen() ? file.getHandle() : FileError; + } else { + // If the file is not found, create it if the create flag is on + if (realPerms.create()) { + IOFile file(p.string().c_str(), "wb"); // Create file + file.close(); // Close it + + file.open(p.string().c_str(), permString); // Reopen with proper perms + return file.isOpen() ? file.getHandle() : FileError; + } else { + return FileError; } + } +} - FilePerms realPerms = perms; - // SD card always has read permission - realPerms.raw |= (1 << 0); - - if ((realPerms.create() && !realPerms.write())) { - Helpers::panic("[SaveData] Unsupported flags for OpenFile"); +HorizonResult SDMCArchive::createDirectory(const FSPath& path) { + if (path.type == PathType::UTF16) { + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SDMCArchive::OpenFile"); } fs::path p = IOFile::getAppData() / "SDMC"; - p += fs::path(path.string).make_preferred(); + p += fs::path(path.utf16_string).make_preferred(); - const char* permString = perms.write() ? "r+b" : "rb"; + if (fs::is_directory(p)) { + return Result::FS::AlreadyExists; + } - if (fs::exists(p)) { // Return file descriptor if the file exists - IOFile file(p.string().c_str(), permString); - return file.isOpen() ? file.getHandle() : FileError; + if (fs::is_regular_file(p)) { + Helpers::panic("File path passed to SDMCArchive::CreateDirectory"); + } + + std::error_code ec; + bool success = fs::create_directory(p, ec); + return success ? Result::Success : Result::FS::UnexpectedFileOrDir; + } else { + Helpers::panic("Unimplemented SDMC::CreateDirectory path type"); + } +} + +Rust::Result SDMCArchive::openDirectory(const FSPath& path) { + if (path.type == PathType::UTF16) { + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SaveData::OpenDirectory"); + } + + fs::path p = IOFile::getAppData() / "SDMC"; + p += fs::path(path.utf16_string).make_preferred(); + + if (fs::is_regular_file(p)) { + printf("SDMC: OpenDirectory used with a file path"); + return Err(Result::FS::UnexpectedFileOrDir); + } + + if (fs::is_directory(p)) { + return Ok(DirectorySession(this, p)); } else { - // If the file is not found, create it if the create flag is on - if (realPerms.create()) { - IOFile file(p.string().c_str(), "wb"); // Create file - file.close(); // Close it - - file.open(p.string().c_str(), permString); // Reopen with proper perms - return file.isOpen() ? file.getHandle() : FileError; - } else { - return FileError; - } + return Err(Result::FS::FileNotFoundAlt); } } - Helpers::panic("SDMCArchive::OpenFile: Failed"); - return FileError; + Helpers::panic("SDMCArchive::OpenDirectory: Unimplemented path type"); + return Err(Result::Success); } Rust::Result SDMCArchive::openArchive(const FSPath& path) { From 5106f251cf27211810f1e1339d1b6481f8df7c93 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 16:53:06 +0300 Subject: [PATCH 4/6] [SDMC] Handle ASCII paths for CreateDirectory --- src/core/fs/archive_sdmc.cpp | 45 +++++++++++++++++----------- src/core/renderer_gl/renderer_gl.cpp | 8 ++++- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/core/fs/archive_sdmc.cpp b/src/core/fs/archive_sdmc.cpp index ee5c8ffb..8e6010eb 100644 --- a/src/core/fs/archive_sdmc.cpp +++ b/src/core/fs/archive_sdmc.cpp @@ -64,28 +64,39 @@ FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) } HorizonResult SDMCArchive::createDirectory(const FSPath& path) { - if (path.type == PathType::UTF16) { - if (!isPathSafe(path)) { - Helpers::panic("Unsafe path in SDMCArchive::OpenFile"); - } + std::filesystem::path p = IOFile::getAppData() / "SDMC"; - fs::path p = IOFile::getAppData() / "SDMC"; - p += fs::path(path.utf16_string).make_preferred(); + switch (path.type) { + case PathType::ASCII: + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SDMCArchive::OpenFile"); + } - if (fs::is_directory(p)) { - return Result::FS::AlreadyExists; - } + p += fs::path(path.string).make_preferred(); + break; - if (fs::is_regular_file(p)) { - Helpers::panic("File path passed to SDMCArchive::CreateDirectory"); - } + case PathType::UTF16: + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SDMCArchive::OpenFile"); + } - std::error_code ec; - bool success = fs::create_directory(p, ec); - return success ? Result::Success : Result::FS::UnexpectedFileOrDir; - } else { - Helpers::panic("Unimplemented SDMC::CreateDirectory path type"); + p += fs::path(path.utf16_string).make_preferred(); + break; + + default: Helpers::panic("SDMCArchive::CreateDirectory: Failed. Path type: %d", path.type); return Result::FailurePlaceholder; } + + if (fs::is_directory(p)) { + return Result::FS::AlreadyExists; + } + + if (fs::is_regular_file(p)) { + Helpers::panic("File path passed to SDMCArchive::CreateDirectory"); + } + + std::error_code ec; + bool success = fs::create_directory(p, ec); + return success ? Result::Success : Result::FS::UnexpectedFileOrDir; } Rust::Result SDMCArchive::openDirectory(const FSPath& path) { diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index 6d29e7d3..f904dc37 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -695,6 +695,7 @@ void RendererGL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32 if (inputGap != 0 || outputGap != 0) { // Helpers::warn("Strided texture copy\n"); } + if (inputWidth != outputWidth) { Helpers::warn("Input width does not match output width, cannot accelerate texture copy!"); return; @@ -716,7 +717,12 @@ void RendererGL::textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32 // inputHeight/outputHeight are typically set to zero so they cannot be used to get the height of the copy region // in contrast to display transfer. Compute height manually by dividing the copy size with the copy width. The result // is the number of vertical tiles so multiply that by eight to get the actual copy height. - const u32 copyHeight = (copySize / inputWidth) * 8; + u32 copyHeight; + if (inputWidth != 0) [[likely]] { + copyHeight = (copySize / inputWidth) * 8; + } else { + copyHeight = 0; + } // Find the source surface. auto srcFramebuffer = getColourBuffer(inputAddr, PICA::ColorFmt::RGBA8, copyStride, copyHeight, false); From 82ded962d09c3654585bddaf88d4e793349fcfd3 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 17:06:32 +0300 Subject: [PATCH 5/6] Add PTM::GetBatteryChargeState --- include/services/ptm.hpp | 1 + src/core/services/ptm.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/include/services/ptm.hpp b/include/services/ptm.hpp index 62fa6f65..1f887aea 100644 --- a/include/services/ptm.hpp +++ b/include/services/ptm.hpp @@ -16,6 +16,7 @@ class PTMService { // Service commands void configureNew3DSCPU(u32 messagePointer); void getAdapterState(u32 messagePointer); + void getBatteryChargeState(u32 messagePointer); void getBatteryLevel(u32 messagePointer); void getStepHistory(u32 messagePointer); void getTotalStepCount(u32 messagePointer); diff --git a/src/core/services/ptm.cpp b/src/core/services/ptm.cpp index 57fbf638..1c822fcf 100644 --- a/src/core/services/ptm.cpp +++ b/src/core/services/ptm.cpp @@ -5,6 +5,7 @@ namespace PTMCommands { enum : u32 { GetAdapterState = 0x00050000, GetBatteryLevel = 0x00070000, + GetBatteryChargeState = 0x00080000, GetStepHistory = 0x000B00C2, GetTotalStepCount = 0x000C0000, ConfigureNew3DSCPU = 0x08180040, @@ -18,6 +19,7 @@ void PTMService::handleSyncRequest(u32 messagePointer) { switch (command) { case PTMCommands::ConfigureNew3DSCPU: configureNew3DSCPU(messagePointer); break; case PTMCommands::GetAdapterState: getAdapterState(messagePointer); break; + case PTMCommands::GetBatteryChargeState: getBatteryChargeState(messagePointer); break; case PTMCommands::GetBatteryLevel: getBatteryLevel(messagePointer); break; case PTMCommands::GetStepHistory: getStepHistory(messagePointer); break; case PTMCommands::GetTotalStepCount: getTotalStepCount(messagePointer); break; @@ -33,6 +35,16 @@ void PTMService::getAdapterState(u32 messagePointer) { mem.write8(messagePointer + 8, config.chargerPlugged ? 1 : 0); } +void PTMService::getBatteryChargeState(u32 messagePointer) { + log("PTM::GetBatteryChargeState"); + // We're only charging if the battery is not already full + const bool charging = config.chargerPlugged && (config.batteryPercentage < 100); + + mem.write32(messagePointer, IPC::responseHeader(0x7, 2, 0)); + mem.write32(messagePointer + 4, Result::Success); + mem.write8(messagePointer + 8, charging ? 1 : 0); +} + void PTMService::getBatteryLevel(u32 messagePointer) { log("PTM::GetBatteryLevel"); From 41ef4ad540321b4cbe8a92d70e349bfb116d4c95 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 17:50:53 +0300 Subject: [PATCH 6/6] [HTTP] Stub some certificate stuff --- include/services/http.hpp | 2 ++ src/core/services/http.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/services/http.hpp b/include/services/http.hpp index 8dccc0c5..1e7f30c3 100644 --- a/include/services/http.hpp +++ b/include/services/http.hpp @@ -12,7 +12,9 @@ class HTTPService { bool initialized = false; // Service commands + void createRootCertChain(u32 messagePointer); void initialize(u32 messagePointer); + void rootCertChainAddDefaultCert(u32 messagePointer); public: HTTPService(Memory& mem) : mem(mem) {} diff --git a/src/core/services/http.cpp b/src/core/services/http.cpp index f61eca3b..076afa06 100644 --- a/src/core/services/http.cpp +++ b/src/core/services/http.cpp @@ -6,6 +6,8 @@ namespace HTTPCommands { enum : u32 { Initialize = 0x00010044, + CreateRootCertChain = 0x002D0000, + RootCertChainAddDefaultCert = 0x00300080, }; } @@ -14,7 +16,9 @@ void HTTPService::reset() { initialized = false; } void HTTPService::handleSyncRequest(u32 messagePointer) { const u32 command = mem.read32(messagePointer); switch (command) { + case HTTPCommands::CreateRootCertChain: createRootCertChain(messagePointer); break; case HTTPCommands::Initialize: initialize(messagePointer); break; + case HTTPCommands::RootCertChainAddDefaultCert: rootCertChainAddDefaultCert(messagePointer); break; default: Helpers::panic("HTTP service requested. Command: %08X\n", command); } } @@ -39,4 +43,28 @@ void HTTPService::initialize(u32 messagePointer) { initialized = true; // We currently don't emulate HTTP properly. TODO: Prepare POST buffer here mem.write32(messagePointer + 4, Result::Success); +} + +void HTTPService::createRootCertChain(u32 messagePointer) { + log("HTTP::CreateRootCertChain (Unimplemented)\n"); + + // TODO: Verify response header + mem.write32(messagePointer, IPC::responseHeader(0x2D, 2, 0)); + mem.write32(messagePointer + 4, Result::Success); + + // RootCertChain context handle. No need to emulate this yet + mem.write32(messagePointer + 8, 0x66666666); +} + +void HTTPService::rootCertChainAddDefaultCert(u32 messagePointer) { + log("HTTP::RootCertChainAddDefaultCert (Unimplemented)\n"); + const u32 contextHandle = mem.read32(messagePointer + 4); + const u32 certID = mem.read32(messagePointer + 8); + + // TODO: Verify response header + mem.write32(messagePointer, IPC::responseHeader(0x30, 2, 0)); + mem.write32(messagePointer + 4, Result::Success); + + // Cert context handle. No need to emulate this yet + mem.write32(messagePointer + 8, 0x66666666); } \ No newline at end of file