From 24be9ffc57de237962f85e7846eb71976d1bf12a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 5 Dec 2018 08:33:56 -0800 Subject: [PATCH] tma: Add working AtmosphereTestService (echoes As) --- stratosphere/tma/Makefile | 2 +- stratosphere/tma/client/Main.py | 5 ++ stratosphere/tma/client/ServiceId.py | 2 + .../source/test/atmosphere_test_service.cpp | 31 +++++++ .../source/test/atmosphere_test_service.hpp | 30 +++++++ .../tma/source/test/atmosphere_test_task.cpp | 36 ++++++++ .../tma/source/test/atmosphere_test_task.hpp | 33 ++++++++ .../tma/source/tma_conn_usb_connection.cpp | 84 ++++++++++--------- .../tma/source/tma_service_manager.cpp | 2 + stratosphere/tma/source/tma_target.cpp | 4 + stratosphere/tma/source/tma_task.cpp | 9 +- stratosphere/tma/source/tma_task.hpp | 3 + stratosphere/tma/source/tma_task_list.cpp | 4 +- 13 files changed, 200 insertions(+), 45 deletions(-) create mode 100644 stratosphere/tma/source/test/atmosphere_test_service.cpp create mode 100644 stratosphere/tma/source/test/atmosphere_test_service.hpp create mode 100644 stratosphere/tma/source/test/atmosphere_test_task.cpp create mode 100644 stratosphere/tma/source/test/atmosphere_test_task.hpp diff --git a/stratosphere/tma/Makefile b/stratosphere/tma/Makefile index 7dc12f262..9d0408a23 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 +SOURCES := source source/test 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 b1469a1e1..3ea150608 100644 --- a/stratosphere/tma/client/Main.py +++ b/stratosphere/tma/client/Main.py @@ -12,12 +12,17 @@ # You should have received a copy of the GNU General Public License from UsbConnection import UsbConnection import sys, time +from Packet import Packet +import ServiceId def main(argc, argv): with UsbConnection(None) as c: 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)) + resp = c.intf.read_packet() + print resp.body return 0 if __name__ == '__main__': diff --git a/stratosphere/tma/client/ServiceId.py b/stratosphere/tma/client/ServiceId.py index 5207d2ae3..27b314f93 100644 --- a/stratosphere/tma/client/ServiceId.py +++ b/stratosphere/tma/client/ServiceId.py @@ -24,4 +24,6 @@ USB_SEND_HOST_INFO = hash("USBSendHostInfo") USB_CONNECT = hash("USBConnect") USB_DISCONNECT = hash("USBDisconnect") +ATMOSPHERE_TEST_SERVICE = hash("AtmosphereTestService") + \ No newline at end of file diff --git a/stratosphere/tma/source/test/atmosphere_test_service.cpp b/stratosphere/tma/source/test/atmosphere_test_service.cpp new file mode 100644 index 000000000..7433882fa --- /dev/null +++ b/stratosphere/tma/source/test/atmosphere_test_service.cpp @@ -0,0 +1,31 @@ +/* + * 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 "atmosphere_test_service.hpp" +#include "atmosphere_test_task.hpp" + +TmaTask *AtmosphereTestService::NewTask(TmaPacket *packet) { + auto new_task = new AtmosphereTestTask(this->manager); + 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/test/atmosphere_test_service.hpp b/stratosphere/tma/source/test/atmosphere_test_service.hpp new file mode 100644 index 000000000..c01e7e5cb --- /dev/null +++ b/stratosphere/tma/source/test/atmosphere_test_service.hpp @@ -0,0 +1,30 @@ +/* + * 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" + +class AtmosphereTestService : public TmaService { + public: + AtmosphereTestService(TmaServiceManager *m) : TmaService(m, "AtmosphereTestService") { } + virtual ~AtmosphereTestService() { } + + virtual TmaTask *NewTask(TmaPacket *packet) override; +}; \ No newline at end of file diff --git a/stratosphere/tma/source/test/atmosphere_test_task.cpp b/stratosphere/tma/source/test/atmosphere_test_task.cpp new file mode 100644 index 000000000..57cb6078b --- /dev/null +++ b/stratosphere/tma/source/test/atmosphere_test_task.cpp @@ -0,0 +1,36 @@ +/* + * 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 "atmosphere_test_task.hpp" + +void AtmosphereTestTask::OnStart(TmaPacket *packet) { + packet->Read(this->arg); +} + +void AtmosphereTestTask::OnReceivePacket(TmaPacket *packet) { + std::abort(); +} + +void AtmosphereTestTask::OnSendPacket(TmaPacket *packet) { + for (size_t i = 0; i < this->arg && i < 0x100; i++) { + packet->Write('A'); + } + + this->Complete(); +} \ No newline at end of file diff --git a/stratosphere/tma/source/test/atmosphere_test_task.hpp b/stratosphere/tma/source/test/atmosphere_test_task.hpp new file mode 100644 index 000000000..ebbb62b03 --- /dev/null +++ b/stratosphere/tma/source/test/atmosphere_test_task.hpp @@ -0,0 +1,33 @@ +/* + * 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 AtmosphereTestTask : public TmaTask { + private: + u32 arg; + public: + AtmosphereTestTask(TmaServiceManager *m) : TmaTask(m) { } + virtual ~AtmosphereTestTask() { } + + 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_conn_usb_connection.cpp b/stratosphere/tma/source/tma_conn_usb_connection.cpp index ed7c2f707..d7c89199f 100644 --- a/stratosphere/tma/source/tma_conn_usb_connection.cpp +++ b/stratosphere/tma/source/tma_conn_usb_connection.cpp @@ -81,49 +81,53 @@ void TmaUsbConnection::RecvThreadFunc(void *arg) { res = TmaUsbComms::ReceivePacket(packet); if (res == TmaConnResult::Success) { - switch (packet->GetServiceId()) { - case TmaServiceId::UsbQueryTarget: { - this_ptr->SetConnected(false); - - res = this_ptr->SendQueryReply(packet); - - if (!this_ptr->has_woken_up) { - this_ptr->CancelTasks(); + if (!IsMetaService(packet->GetServiceId())) { + this_ptr->OnReceivePacket(packet); + } else { + switch (packet->GetServiceId()) { + case TmaServiceId::UsbQueryTarget: { + this_ptr->SetConnected(false); + + res = this_ptr->SendQueryReply(packet); + + if (!this_ptr->has_woken_up) { + this_ptr->CancelTasks(); + } } - } - break; - case TmaServiceId::UsbSendHostInfo: { - struct { - u32 version; - u32 sleeping; - } host_info; - packet->Read(host_info); - - if (!this_ptr->has_woken_up || !host_info.sleeping) { - this_ptr->CancelTasks(); - } - } - break; - case TmaServiceId::UsbConnect: { - res = this_ptr->SendQueryReply(packet); - - if (res == TmaConnResult::Success) { - this_ptr->SetConnected(true); - this_ptr->OnConnectionEvent(ConnectionEvent::Connected); - } - } - break; - case TmaServiceId::UsbDisconnect: { - this_ptr->SetConnected(false); - this_ptr->OnDisconnected(); - - this_ptr->CancelTasks(); - } - break; - default: break; + case TmaServiceId::UsbSendHostInfo: { + struct { + u32 version; + u32 sleeping; + } host_info; + packet->Read(host_info); + + if (!this_ptr->has_woken_up || !host_info.sleeping) { + this_ptr->CancelTasks(); + } + } + break; + case TmaServiceId::UsbConnect: { + res = this_ptr->SendQueryReply(packet); + + if (res == TmaConnResult::Success) { + this_ptr->SetConnected(true); + this_ptr->OnConnectionEvent(ConnectionEvent::Connected); + } + } + break; + case TmaServiceId::UsbDisconnect: { + this_ptr->SetConnected(false); + this_ptr->OnDisconnected(); + + this_ptr->CancelTasks(); + } + break; + default: + break; + } + this_ptr->FreePacket(packet); } - this_ptr->FreePacket(packet); } else { this_ptr->FreePacket(packet); } diff --git a/stratosphere/tma/source/tma_service_manager.cpp b/stratosphere/tma/source/tma_service_manager.cpp index 2d2b18cec..e684f7e0c 100644 --- a/stratosphere/tma/source/tma_service_manager.cpp +++ b/stratosphere/tma/source/tma_service_manager.cpp @@ -327,6 +327,8 @@ void TmaServiceManager::HandleFreeTaskWork(TmaWorkItem *work_item) { } void TmaServiceManager::HandleReceivePacketWork(TmaWorkItem *work_item) { + ON_SCOPE_EXIT { this->FreePacket(work_item->packet); }; + /* Handle continuation packets. */ if (work_item->packet->GetContinuation()) { this->task_list.ReceivePacket(work_item->packet); diff --git a/stratosphere/tma/source/tma_target.cpp b/stratosphere/tma/source/tma_target.cpp index 227975c70..9873d952d 100644 --- a/stratosphere/tma/source/tma_target.cpp +++ b/stratosphere/tma/source/tma_target.cpp @@ -25,6 +25,8 @@ #include "tma_target.hpp" +#include "test/atmosphere_test_service.hpp" + struct TmaTargetConfig { char configuration_id1[0x80]; char serial_number[0x80]; @@ -204,6 +206,8 @@ void TmaTarget::Initialize() { g_active_connection = nullptr; g_service_manager = new TmaServiceManager(); + /* TODO: Make this better. */ + g_service_manager->AddService(new AtmosphereTestService(g_service_manager)); RefreshTargetConfig(); diff --git a/stratosphere/tma/source/tma_task.cpp b/stratosphere/tma/source/tma_task.cpp index a9450be76..6133b5c5e 100644 --- a/stratosphere/tma/source/tma_task.cpp +++ b/stratosphere/tma/source/tma_task.cpp @@ -19,14 +19,19 @@ #include "tma_task.hpp" #include "tma_service_manager.hpp" +void TmaTask::SetNeedsPackets(bool n) { + this->needs_packets = n; + this->manager->Tick(); +} + void TmaTask::Complete() { - /* TODO: Set packet state */ + SetNeedsPackets(false); this->state = TmaTaskState::Complete; this->manager->Tick(); } void TmaTask::Cancel() { - /* TODO: Set packet state */ + SetNeedsPackets(false); this->state = TmaTaskState::Canceled; this->manager->Tick(); } \ No newline at end of file diff --git a/stratosphere/tma/source/tma_task.hpp b/stratosphere/tma/source/tma_task.hpp index 9e115893f..686a7a50d 100644 --- a/stratosphere/tma/source/tma_task.hpp +++ b/stratosphere/tma/source/tma_task.hpp @@ -43,6 +43,7 @@ class TmaTask { HosSignal signal; bool owned_by_task_list = true; bool sleep_allowed = true; + bool needs_packets = false; public: TmaTask(TmaServiceManager *m) : manager(m) { } virtual ~TmaTask() { } @@ -54,6 +55,7 @@ class TmaTask { TmaTaskState GetState() const { return this->state; } bool GetOwnedByTaskList() const { return this->owned_by_task_list; } bool GetSleepAllowed() const { return this->sleep_allowed; } + bool GetNeedsPackets() const { return this->needs_packets; } void SetPriority(u32 p) { this->priority = p; } void SetServiceId(TmaServiceId s) { this->service_id = s; } @@ -61,6 +63,7 @@ class TmaTask { void SetCommand(u32 c) { this->command = c; } void SetOwnedByTaskList(bool o) { this->owned_by_task_list = o; } void SetSleepAllowed(bool a) { this->sleep_allowed = a; } + void SetNeedsPackets(bool n); void Signal() { this->signal.Signal(); } void ResetSignal() { this->signal.Reset(); } diff --git a/stratosphere/tma/source/tma_task_list.cpp b/stratosphere/tma/source/tma_task_list.cpp index 2cb28b487..36f54bef9 100644 --- a/stratosphere/tma/source/tma_task_list.cpp +++ b/stratosphere/tma/source/tma_task_list.cpp @@ -70,9 +70,9 @@ bool TmaTaskList::SendPacket(bool connected, TmaPacket *packet) { switch (task->GetState()) { case TmaTaskState::InProgress: it++; - if (target_task == nullptr) { + if (target_task == nullptr && task->GetNeedsPackets()) { if (connected || IsMetaService(task->GetServiceId())) { - target_task = nullptr; + target_task = task; } } break;