diff --git a/stratosphere/tma/Makefile b/stratosphere/tma/Makefile index 9d0408a23..161caed02 100644 --- a/stratosphere/tma/Makefile +++ b/stratosphere/tma/Makefile @@ -19,7 +19,7 @@ include $(DEVKITPRO)/libnx/switch_rules #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) BUILD := build -SOURCES := source source/test +SOURCES := source source/test source/settings DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src diff --git a/stratosphere/tma/client/Main.py b/stratosphere/tma/client/Main.py index 3ea150608..0a81509c6 100644 --- a/stratosphere/tma/client/Main.py +++ b/stratosphere/tma/client/Main.py @@ -20,9 +20,16 @@ def main(argc, argv): print 'Waiting for connection...' c.wait_connected() print 'Connected!' - c.intf.send_packet(Packet().set_service(ServiceId.ATMOSPHERE_TEST_SERVICE).set_task(0x01000000).write_u32(0x40)) + c.intf.send_packet(Packet().set_service(ServiceId.SETTINGS_SERVICE).set_task(0x01000000).set_cmd(0).write_str('lm').write_str('sd_card_log_output_directory')) resp = c.intf.read_packet() - print resp.body + success = resp.read_u8() != 0 + print 'Succeeded: %s' % str(success) + if success: + size = resp.read_u32() + value = resp.body[resp.offset:resp.offset+size] + print 'Value Size: 0x%x' % size + print 'Value: %s' % repr(value) + return 0 if __name__ == '__main__': diff --git a/stratosphere/tma/client/Packet.py b/stratosphere/tma/client/Packet.py index 465be93e8..9f623b28d 100644 --- a/stratosphere/tma/client/Packet.py +++ b/stratosphere/tma/client/Packet.py @@ -70,6 +70,8 @@ class Packet(): self.offset = 0 return self def write_str(self, s): + if s[-1] != '\x00': + s += '\x00' self.body += s self.body_len += len(s) return self @@ -94,6 +96,8 @@ class Packet(): while self.body[self.offset] != '\x00' and self.offset < self.body_len: s += self.body[self.offset] self.offset += 1 + if self.offset < self.body_len and self.body[self.offset] == '\x00': + self.offset += 1 def read_u8(self): x, = up('. + */ + +#include +#include + +#include "settings_service.hpp" +#include "settings_task.hpp" + +TmaTask *SettingsService::NewTask(TmaPacket *packet) { + TmaTask *new_task = nullptr; + switch (packet->GetCommand()) { + case SettingsServiceCmd_GetSetting: + { + new_task = new GetSettingTask(this->manager); + } + break; + default: + new_task = nullptr; + break; + } + if (new_task != nullptr) { + new_task->SetServiceId(this->GetServiceId()); + new_task->SetTaskId(packet->GetTaskId()); + new_task->OnStart(packet); + new_task->SetNeedsPackets(true); + } + + return new_task; +} diff --git a/stratosphere/tma/source/settings/settings_service.hpp b/stratosphere/tma/source/settings/settings_service.hpp new file mode 100644 index 000000000..3b21c891b --- /dev/null +++ b/stratosphere/tma/source/settings/settings_service.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018 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 +#include + +#include "../tma_conn_service_ids.hpp" +#include "../tma_service.hpp" + +enum SettingsServiceCmd : u32 { + SettingsServiceCmd_GetSetting = 0, +}; + +class SettingsService : public TmaService { + public: + SettingsService(TmaServiceManager *m) : TmaService(m, "SettingsService") { } + virtual ~SettingsService() { } + + virtual TmaTask *NewTask(TmaPacket *packet) override; +}; \ No newline at end of file diff --git a/stratosphere/tma/source/settings/settings_task.cpp b/stratosphere/tma/source/settings/settings_task.cpp new file mode 100644 index 000000000..650cc6c15 --- /dev/null +++ b/stratosphere/tma/source/settings/settings_task.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 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 + +#include "settings_task.hpp" + +void GetSettingTask::OnStart(TmaPacket *packet) { + size_t length; + packet->ReadString(this->name, sizeof(this->name), &length); + packet->ReadString(this->item_key, sizeof(this->item_key), &length); + + if (R_SUCCEEDED(setsysGetSettingsItemValueSize(this->name, this->item_key, &this->value_size))) { + if (this->value_size <= sizeof(this->value)) { + if (R_SUCCEEDED(setsysGetSettingsItemValue(this->name, this->item_key, this->value, this->value_size))) { + this->succeeded = true; + } + } + } +} + +void GetSettingTask::OnReceivePacket(TmaPacket *packet) { + std::abort(); +} + +void GetSettingTask::OnSendPacket(TmaPacket *packet) { + packet->Write((u8)this->succeeded); + packet->Write((u32)this->value_size); + packet->Write(this->value, this->value_size); + + this->Complete(); +} \ No newline at end of file diff --git a/stratosphere/tma/source/settings/settings_task.hpp b/stratosphere/tma/source/settings/settings_task.hpp new file mode 100644 index 000000000..5d2bd13be --- /dev/null +++ b/stratosphere/tma/source/settings/settings_task.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 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 +#include + +#include "../tma_task.hpp" + +class GetSettingTask : public TmaTask { + private: + char name[0x40] = {0}; + char item_key[0x40] = {0}; + u8 value[0x40] = {0}; + u64 value_size = 0; + bool succeeded = false; + + public: + GetSettingTask(TmaServiceManager *m) : TmaTask(m) { } + virtual ~GetSettingTask() { } + + virtual void OnStart(TmaPacket *packet) override; + virtual void OnReceivePacket(TmaPacket *packet) override; + virtual void OnSendPacket(TmaPacket *packet) override; +}; diff --git a/stratosphere/tma/source/tma_main.cpp b/stratosphere/tma/source/tma_main.cpp index fb1491cc3..d314ed16a 100644 --- a/stratosphere/tma/source/tma_main.cpp +++ b/stratosphere/tma/source/tma_main.cpp @@ -65,11 +65,17 @@ void __appInit(void) { fatalSimple(rc); } + rc = setsysInitialize(); + if (R_FAILED(rc)) { + fatalSimple(rc); + } + CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION); } void __appExit(void) { /* Cleanup services. */ + setsysExit(); pscExit(); smExit(); } diff --git a/stratosphere/tma/source/tma_target.cpp b/stratosphere/tma/source/tma_target.cpp index 9873d952d..9cfcb335f 100644 --- a/stratosphere/tma/source/tma_target.cpp +++ b/stratosphere/tma/source/tma_target.cpp @@ -26,6 +26,7 @@ #include "tma_target.hpp" #include "test/atmosphere_test_service.hpp" +#include "settings/settings_service.hpp" struct TmaTargetConfig { char configuration_id1[0x80]; @@ -208,6 +209,7 @@ void TmaTarget::Initialize() { g_service_manager = new TmaServiceManager(); /* TODO: Make this better. */ g_service_manager->AddService(new AtmosphereTestService(g_service_manager)); + g_service_manager->AddService(new SettingsService(g_service_manager)); RefreshTargetConfig();