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:
parent
d875d84d2d
commit
24be9ffc57
13 changed files with 200 additions and 45 deletions
|
@ -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
|
||||
|
|
|
@ -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__':
|
||||
|
|
|
@ -24,4 +24,6 @@ USB_SEND_HOST_INFO = hash("USBSendHostInfo")
|
|||
USB_CONNECT = hash("USBConnect")
|
||||
USB_DISCONNECT = hash("USBDisconnect")
|
||||
|
||||
ATMOSPHERE_TEST_SERVICE = hash("AtmosphereTestService")
|
||||
|
||||
|
31
stratosphere/tma/source/test/atmosphere_test_service.cpp
Normal file
31
stratosphere/tma/source/test/atmosphere_test_service.cpp
Normal 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;
|
||||
}
|
30
stratosphere/tma/source/test/atmosphere_test_service.hpp
Normal file
30
stratosphere/tma/source/test/atmosphere_test_service.hpp
Normal 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;
|
||||
};
|
36
stratosphere/tma/source/test/atmosphere_test_task.cpp
Normal file
36
stratosphere/tma/source/test/atmosphere_test_task.cpp
Normal 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();
|
||||
}
|
33
stratosphere/tma/source/test/atmosphere_test_task.hpp
Normal file
33
stratosphere/tma/source/test/atmosphere_test_task.hpp
Normal 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;
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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(); }
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue