1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-11-05 19:51:45 +00:00

tma: Add working AtmosphereTestService (echoes As)

This commit is contained in:
Michael Scire 2018-12-05 08:33:56 -08:00
parent d875d84d2d
commit 24be9ffc57
13 changed files with 200 additions and 45 deletions

View file

@ -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

View file

@ -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__':

View file

@ -24,4 +24,6 @@ USB_SEND_HOST_INFO = hash("USBSendHostInfo")
USB_CONNECT = hash("USBConnect")
USB_DISCONNECT = hash("USBDisconnect")
ATMOSPHERE_TEST_SERVICE = hash("AtmosphereTestService")

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <switch.h>
#include <stratosphere.hpp>
#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;
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#include <stratosphere.hpp>
#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;
};

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <switch.h>
#include <stratosphere.hpp>
#include "atmosphere_test_task.hpp"
void AtmosphereTestTask::OnStart(TmaPacket *packet) {
packet->Read<u32>(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<u8>('A');
}
this->Complete();
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.h>
#include <stratosphere.hpp>
#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;
};

View file

@ -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<decltype(host_info)>(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<decltype(host_info)>(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);
}

View file

@ -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);

View file

@ -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();

View file

@ -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();
}

View file

@ -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(); }

View file

@ -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;