diff --git a/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_logger.cpp b/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_logger.cpp
new file mode 100644
index 000000000..34ff1dc9e
--- /dev/null
+++ b/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_logger.cpp
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2018-2020 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 "uart_mitm_logger.hpp"
+#include "../amsmitm_fs_utils.hpp"
+
+namespace ams::mitm::uart {
+
+ alignas(os::ThreadStackAlignment) u8 g_logger_stack[0x4000];
+
+ std::shared_ptr g_logger;
+
+ UartLogger::UartLogger() : m_request_event(os::EventClearMode_ManualClear), m_finish_event(os::EventClearMode_ManualClear), m_client_queue(m_client_queue_list, this->QueueSize), m_thread_queue(m_thread_queue_list, this->QueueSize) {
+ for (size_t i=0; iQueueSize; i++) {
+ UartLogMessage *msg = &this->m_queue_list_msgs[i];
+ std::memset(msg, 0, sizeof(UartLogMessage));
+
+ msg->data = static_cast(std::malloc(this->QueueBufferSize));
+ if (msg->data != nullptr) {
+ std::memset(msg->data, 0, this->QueueBufferSize);
+ }
+
+ this->m_client_queue.Send(reinterpret_cast(msg));
+ }
+
+ /* Create and start the logger thread. */
+ R_ABORT_UNLESS(os::CreateThread(std::addressof(this->m_thread), this->ThreadEntry, this, g_logger_stack, sizeof(g_logger_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(uart, IpcServer) - 2));
+ os::StartThread(std::addressof(this->m_thread));
+ }
+
+ UartLogger::~UartLogger() {
+ /* Tell the logger thread to exit. */
+ UartLogMessage *msg=nullptr;
+ this->m_client_queue.Receive(reinterpret_cast(&msg));
+
+ msg->type = 0;
+
+ this->m_finish_event.Clear();
+ this->m_thread_queue.Send(reinterpret_cast(msg));
+ this->m_request_event.Signal();
+
+ /* Wait on the logger thread, then destroy it. */
+ os::WaitThread(std::addressof(this->m_thread));
+ os::DestroyThread(std::addressof(this->m_thread));
+
+ for (size_t i=0; iQueueSize; i++) {
+ UartLogMessage *msg = &this->m_queue_list_msgs[i];
+ std::free(msg->data);
+ msg->data = nullptr;
+ }
+ }
+
+ void UartLogger::ThreadFunction() {
+ bool exit_flag=false;
+
+ this->m_cache_count = 0;
+ this->m_cache_pos = 0;
+ std::memset(this->m_cache_list, 0, sizeof(this->m_cache_list));
+ std::memset(this->m_cache_buffer, 0, sizeof(this->m_cache_buffer));
+
+ while (!exit_flag) {
+ this->m_request_event.Wait();
+
+ /* Receive messages, process them, then Send them. */
+ UartLogMessage *msg=nullptr;
+ while (this->m_thread_queue.TryReceive(reinterpret_cast(&msg))) {
+ if (msg->type==0) {
+ exit_flag = true;
+ }
+ else if (msg->type==1) {
+ this->WriteCache(msg);
+ }
+ else if (msg->type==2) {
+ this->WriteCmdLog(reinterpret_cast(msg->data), reinterpret_cast(&msg->data[std::strlen((const char*)msg->data)+1]), msg->file_pos);
+ }
+ else if (msg->type==3) {
+ this->FlushCache();
+ }
+ this->m_client_queue.Send(reinterpret_cast(msg));
+ }
+
+ this->m_request_event.Clear();
+ this->m_finish_event.Signal();
+ }
+ }
+
+ /* Wait for the thread to finish processing messages. */
+ void UartLogger::WaitFinished() {
+ /* Tell the thread to flush the cache. */
+ UartLogMessage *msg=nullptr;
+ this->m_client_queue.Receive(reinterpret_cast(&msg));
+
+ msg->type = 3;
+
+ this->m_finish_event.Clear();
+ this->m_thread_queue.Send(reinterpret_cast(msg));
+ this->m_request_event.Signal();
+
+ /* Wait for processing to finish. */
+ m_finish_event.Wait();
+ }
+
+ /* Initialize the specified btsnoop log file. */
+ void UartLogger::InitializeDataLog(FsFile *f, size_t *datalog_pos) {
+ *datalog_pos = 0;
+
+ /* Setup the btsnoop header. */
+
+ struct {
+ char id[8];
+ u32 version;
+ u32 datalink_type;
+ } btsnoop_header = { .id = "btsnoop" };
+
+ u32 version = 1;
+ u32 datalink_type = 1002; /* HCI UART (H4) */
+ ams::util::StoreBigEndian(&btsnoop_header.version, version);
+ ams::util::StoreBigEndian(&btsnoop_header.datalink_type, datalink_type);
+
+ /* Write the btsnoop header to the datalog. */
+ this->WriteLog(f, datalog_pos, &btsnoop_header, sizeof(btsnoop_header));
+ }
+
+ /* Flush the cache into the file. */
+ void UartLogger::FlushCache() {
+ for (size_t i=0; im_cache_count; i++) {
+ UartLogMessage *cache_msg=&this->m_cache_list[i];
+ this->WriteLogPacket(cache_msg->datalog_file, cache_msg->file_pos, cache_msg->dir, cache_msg->data, cache_msg->size);
+ }
+
+ this->m_cache_count = 0;
+ this->m_cache_pos = 0;
+ }
+
+ /* Write the specified message into the cache. */
+ /* dir: false = Send (host->controller), true = Receive (controller->host). */
+ void UartLogger::WriteCache(UartLogMessage *msg) {
+ if (this->m_cache_count >= this->CacheListSize || this->m_cache_pos + msg->size >= this->CacheBufferSize) {
+ this->FlushCache();
+ }
+
+ UartLogMessage *cache_msg=&this->m_cache_list[this->m_cache_count];
+ *cache_msg = *msg;
+ cache_msg->data = &this->m_cache_buffer[this->m_cache_pos];
+ std::memcpy(cache_msg->data, msg->data, msg->size);
+ this->m_cache_count++;
+ this->m_cache_pos+= msg->size;
+ }
+
+ /* Append the specified string to the text file. */
+ void UartLogger::WriteCmdLog(const char *path, const char *str, size_t *file_pos) {
+ Result rc=0;
+ FsFile file={};
+ size_t len = std::strlen(str);
+ rc = ams::mitm::fs::OpenAtmosphereSdFile(&file, path, FsOpenMode_Read | FsOpenMode_Write | FsOpenMode_Append);
+ if (R_SUCCEEDED(rc)) {
+ rc = fsFileWrite(&file, *file_pos, str, len, FsWriteOption_None);
+ }
+ if (R_SUCCEEDED(rc)) {
+ *file_pos += len;
+ }
+ fsFileClose(&file);
+ }
+
+ /* Append the specified data to the datalog file. */
+ void UartLogger::WriteLog(FsFile *f, size_t *datalog_pos, const void* buffer, size_t size) {
+ if (R_SUCCEEDED(fsFileWrite(f, *datalog_pos, buffer, size, FsWriteOption_None))) {
+ *datalog_pos += size;
+ }
+ }
+
+ /* Append the specified packet to the datalog via WriteLog. */
+ /* dir: false = Send (host->controller), true = Receive (controller->host). */
+ void UartLogger::WriteLogPacket(FsFile *f, size_t *datalog_pos, bool dir, const void* buffer, size_t size) {
+ struct {
+ u32 original_length;
+ u32 included_length;
+ u32 packet_flags;
+ u32 cumulative_drops;
+ s64 timestamp_microseconds;
+ } pkt_hdr = {};
+
+ u32 flags = 0;
+ if (dir) {
+ flags |= BIT(0);
+ }
+ ams::util::StoreBigEndian(&pkt_hdr.original_length, static_cast(size));
+ ams::util::StoreBigEndian(&pkt_hdr.included_length, static_cast(size));
+ ams::util::StoreBigEndian(&pkt_hdr.packet_flags, flags);
+
+ /* Currently we leave the timestamp at value 0. */
+
+ this->WriteLog(f, datalog_pos, &pkt_hdr, sizeof(pkt_hdr));
+ this->WriteLog(f, datalog_pos, buffer, size);
+ }
+
+ /* Send the specified data to the Logger thread. */
+ /* dir: false = Send (host->controller), true = Receive (controller->host). */
+ void UartLogger::SendLogData(FsFile *f, size_t *file_pos, bool dir, const void* buffer, size_t size) {
+ /* Ignore log data which is too large. */
+ if (size > this->QueueBufferSize) return;
+
+ UartLogMessage *msg=nullptr;
+ this->m_client_queue.Receive(reinterpret_cast(&msg));
+ if (msg->data == nullptr) return;
+
+ /* Setup the msg and send it. */
+ msg->type = 1;
+ msg->dir = dir;
+ msg->datalog_file = f;
+ msg->file_pos = file_pos;
+ msg->size = size;
+ std::memcpy(msg->data, buffer, size);
+
+ this->m_finish_event.Clear();
+ this->m_thread_queue.Send(reinterpret_cast(msg));
+ this->m_request_event.Signal();
+ }
+
+ /* Send the specified text log to the Logger thread. */
+ void UartLogger::SendTextLogData(const char *path, size_t *file_pos, const char *str) {
+ /* Ignore log data which is too large. */
+ if (std::strlen(path)+1 + std::strlen(str)+1 > this->QueueBufferSize) return;
+
+ UartLogMessage *msg=nullptr;
+ this->m_client_queue.Receive(reinterpret_cast(&msg));
+ if (msg->data == nullptr) return;
+
+ /* Setup the msg and send it. */
+ msg->type = 2;
+ msg->file_pos = file_pos;
+ std::memcpy(msg->data, path, std::strlen(path)+1);
+ std::memcpy(&msg->data[std::strlen(path)+1], str, std::strlen(str)+1);
+
+ this->m_finish_event.Clear();
+ this->m_thread_queue.Send(reinterpret_cast(msg));
+ this->m_request_event.Signal();
+ }
+}
diff --git a/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_logger.hpp b/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_logger.hpp
new file mode 100644
index 000000000..db52c265f
--- /dev/null
+++ b/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_logger.hpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018-2020 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
+
+namespace ams::mitm::uart {
+
+ struct UartLogMessage {
+ u8 type;
+ bool dir;
+ FsFile *datalog_file;
+ size_t *file_pos;
+ size_t size;
+ u8 *data;
+ };
+
+ class UartLogger {
+ private:
+ ams::os::ThreadType m_thread;
+ os::Event m_request_event;
+ os::Event m_finish_event;
+ os::MessageQueue m_client_queue;
+ os::MessageQueue m_thread_queue;
+
+ static constexpr inline size_t QueueSize = 0x20;
+ static constexpr inline size_t QueueBufferSize = 0x400;
+ static constexpr inline size_t CacheListSize = 0x80;
+ static constexpr inline size_t CacheBufferSize = 0x1000;
+
+ uintptr_t m_client_queue_list[QueueSize];
+ uintptr_t m_thread_queue_list[QueueSize];
+ UartLogMessage m_queue_list_msgs[QueueSize];
+
+ size_t m_cache_count;
+ size_t m_cache_pos;
+ UartLogMessage m_cache_list[CacheListSize];
+ u8 m_cache_buffer[CacheBufferSize];
+
+ static void ThreadEntry(void *arg) { static_cast(arg)->ThreadFunction(); }
+ void ThreadFunction();
+
+ void FlushCache();
+ void WriteCache(UartLogMessage *msg);
+
+ void WriteCmdLog(const char *path, const char *str, size_t *file_pos);
+ void WriteLog(FsFile *f, size_t *datalog_pos, const void* buffer, size_t size);
+ void WriteLogPacket(FsFile *f, size_t *datalog_pos, bool dir, const void* buffer, size_t size);
+ public:
+ UartLogger();
+ ~UartLogger();
+
+ void WaitFinished();
+
+ void InitializeDataLog(FsFile *f, size_t *datalog_pos);
+
+ void SendLogData(FsFile *f, size_t *file_pos, bool dir, const void* buffer, size_t size);
+ void SendTextLogData(const char *path, size_t *file_pos, const char *str);
+ };
+
+ extern std::shared_ptr g_logger;
+}
diff --git a/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_service.cpp b/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_service.cpp
index 14a165feb..1fb3a5773 100644
--- a/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_service.cpp
+++ b/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_service.cpp
@@ -15,10 +15,9 @@
*/
#include
#include "uart_mitm_service.hpp"
+#include "uart_mitm_logger.hpp"
#include "../amsmitm_fs_utils.hpp"
-/* TODO: This should really use async fs-writing, there's a slowdown with bluetooth communications with current fs-writing. */
-
namespace ams::mitm::uart {
/* Helper functions. */
@@ -41,7 +40,7 @@ namespace ams::mitm::uart {
}
}
- UartPortService::UartPortService(const sm::MitmProcessInfo &cl, std::unique_ptr<::UartPortSession> s) : client_info(cl), srv(std::move(s)) {
+ UartPortService::UartPortService(const sm::MitmProcessInfo &cl, std::unique_ptr<::UartPortSession> s) : m_client_info(cl), m_srv(std::move(s)) {
Result rc=0;
/* Get a timestamp. */
u64 timestamp0=0, timestamp1;
@@ -49,122 +48,66 @@ namespace ams::mitm::uart {
timestamp1 = svcGetSystemTick();
/* Setup/create the logging directory. */
- std::snprintf(this->base_path, sizeof(this->base_path), "uart_logs/%011lu_%011lu_%016lx", timestamp0, timestamp1, static_cast(this->client_info.program_id));
+ std::snprintf(this->m_base_path, sizeof(this->m_base_path), "uart_logs/%011lu_%011lu_%016lx", timestamp0, timestamp1, static_cast(this->m_client_info.program_id));
ams::mitm::fs::CreateAtmosphereSdDirectory("uart_logs");
- ams::mitm::fs::CreateAtmosphereSdDirectory(this->base_path);
+ ams::mitm::fs::CreateAtmosphereSdDirectory(this->m_base_path);
/* Create/initialize the text cmd_log. */
char tmp_path[256];
- std::snprintf(tmp_path, sizeof(tmp_path), "%s/%s", this->base_path, "cmd_log");
+ std::snprintf(tmp_path, sizeof(tmp_path), "%s/%s", this->m_base_path, "cmd_log");
ams::mitm::fs::CreateAtmosphereSdFile(tmp_path, 0, 0);
- this->cmdlog_pos = 0;
+ this->m_cmdlog_pos = 0;
/* Initialize the Send cache-buffer. */
- this->send_cache_buffer = static_cast(std::malloc(this->CacheBufferSize));
- if (this->send_cache_buffer != nullptr) {
- std::memset(this->send_cache_buffer, 0, this->CacheBufferSize);
+ this->m_send_cache_buffer = static_cast(std::malloc(this->CacheBufferSize));
+ if (this->m_send_cache_buffer != nullptr) {
+ std::memset(this->m_send_cache_buffer, 0, this->CacheBufferSize);
}
- this->send_cache_pos = 0;
+ this->m_send_cache_pos = 0;
/* Initialize the Receive cache-buffer. */
- this->receive_cache_buffer = static_cast(std::malloc(this->CacheBufferSize));
- if (this->receive_cache_buffer != nullptr) {
- std::memset(this->receive_cache_buffer, 0, this->CacheBufferSize);
+ this->m_receive_cache_buffer = static_cast(std::malloc(this->CacheBufferSize));
+ if (this->m_receive_cache_buffer != nullptr) {
+ std::memset(this->m_receive_cache_buffer, 0, this->CacheBufferSize);
}
- this->receive_cache_pos = 0;
+ this->m_receive_cache_pos = 0;
+
+ this->m_datalog_ready = false;
/* When the above is successful, initialize the datalog. */
- if (this->send_cache_buffer != nullptr && this->receive_cache_buffer != nullptr) {
- std::snprintf(tmp_path, sizeof(tmp_path), "%s/%s", this->base_path, "btsnoop_hci.log");
+ if (this->m_send_cache_buffer != nullptr && this->m_receive_cache_buffer != nullptr) {
+ std::snprintf(tmp_path, sizeof(tmp_path), "%s/%s", this->m_base_path, "btsnoop_hci.log");
ams::mitm::fs::CreateAtmosphereSdFile(tmp_path, 0, 0);
- rc = ams::mitm::fs::OpenAtmosphereSdFile(&this->datalog_file, tmp_path, FsOpenMode_Read | FsOpenMode_Write | FsOpenMode_Append);
+ rc = ams::mitm::fs::OpenAtmosphereSdFile(&this->m_datalog_file, tmp_path, FsOpenMode_Read | FsOpenMode_Write | FsOpenMode_Append);
/* Set datalog_ready to whether initialization was successful. */
- this->datalog_ready = R_SUCCEEDED(rc);
+ this->m_datalog_ready = R_SUCCEEDED(rc);
}
- this->datalog_pos = 0;
- /* Setup the btsnoop header. */
+ if (this->m_datalog_ready) {
+ std::shared_ptr logger = mitm::uart::g_logger;
+ logger->InitializeDataLog(&this->m_datalog_file, &this->m_datalog_pos);
+ }
- struct {
- char id[8];
- u32 version;
- u32 datalink_type;
- } btsnoop_header = { .id = "btsnoop" };
-
- u32 version = 1;
- u32 datalink_type = 1002; /* HCI UART (H4) */
- ams::util::StoreBigEndian(&btsnoop_header.version, version);
- ams::util::StoreBigEndian(&btsnoop_header.datalink_type, datalink_type);
-
- /* Enable data-logging, required for WriteLog() to write anything. */
- this->data_logging_enabled = true;
-
- /* Write the btsnoop header to the datalog. */
- this->WriteLog(&btsnoop_header, sizeof(btsnoop_header));
-
- /* This will be re-enabled by WriteUartData once a certain command is detected. */
- /* If you want to log all HCI traffic during system-boot initialization, you can comment out the below line, however there will be a slowdown. */
- this->data_logging_enabled = false;
+ /* This will be enabled by WriteUartData once a certain command is detected. */
+ /* If you want to log all HCI traffic during system-boot initialization, you can change this field to true. */
+ /* When changed to true, qlaunch will hang at a black-screen during system-boot, due to the bluetooth slowdown. */
+ this->m_data_logging_enabled = false;
}
/* Append the specified string to the text cmd_log file. */
void UartPortService::WriteCmdLog(const char *str) {
- Result rc=0;
- FsFile file={};
char tmp_path[256];
- size_t len = strlen(str);
- std::snprintf(tmp_path, sizeof(tmp_path), "%s/%s", this->base_path, "cmd_log");
- rc = ams::mitm::fs::OpenAtmosphereSdFile(&file, tmp_path, FsOpenMode_Read | FsOpenMode_Write | FsOpenMode_Append);
- if (R_SUCCEEDED(rc)) {
- rc = fsFileWrite(&file, this->cmdlog_pos, str, len, FsWriteOption_None);
- }
- if (R_SUCCEEDED(rc)) {
- this->cmdlog_pos += len;
- }
- fsFileClose(&file);
- }
-
- /* Append the specified data to the datalog file. */
- void UartPortService::WriteLog(const void* buffer, size_t size) {
- /* Only write to the file if data-logging is enabled and initialized. */
- if (this->data_logging_enabled && this->datalog_ready) {
- if (R_SUCCEEDED(fsFileWrite(&this->datalog_file, this->datalog_pos, buffer, size, FsWriteOption_None))) {
- this->datalog_pos += size;
- }
- }
- }
-
- /* Append the specified packet to the datalog via WriteLog. */
- /* dir: false = Send (host->controller), true = Receive (controller->host). */
- void UartPortService::WriteLogPacket(bool dir, const void* buffer, size_t size) {
- struct {
- u32 original_length;
- u32 included_length;
- u32 packet_flags;
- u32 cumulative_drops;
- s64 timestamp_microseconds;
- } pkt_hdr = {};
-
- u32 flags = 0;
- if (dir) {
- flags |= BIT(0);
- }
- ams::util::StoreBigEndian(&pkt_hdr.original_length, static_cast(size));
- ams::util::StoreBigEndian(&pkt_hdr.included_length, static_cast(size));
- ams::util::StoreBigEndian(&pkt_hdr.packet_flags, flags);
-
- /* Currently we leave the timestamp at value 0. */
-
- this->WriteLog(&pkt_hdr, sizeof(pkt_hdr));
- this->WriteLog(buffer, size);
+ std::snprintf(tmp_path, sizeof(tmp_path), "%s/%s", this->m_base_path, "cmd_log");
+ std::shared_ptr logger = mitm::uart::g_logger;
+ logger->SendTextLogData(tmp_path, &this->m_cmdlog_pos, str);
}
/* Log data from Send/Receive. */
/* dir: false = Send (host->controller), true = Receive (controller->host). */
void UartPortService::WriteUartData(bool dir, const void* buffer, size_t size) {
/* Select which cache buffer/pos to use via dir. */
- u8 *cache_buffer = !dir ? this->send_cache_buffer : this->receive_cache_buffer;
- size_t *cache_pos = !dir ? &this->send_cache_pos : &this->receive_cache_pos;
+ u8 *cache_buffer = !dir ? this->m_send_cache_buffer : this->m_receive_cache_buffer;
+ size_t *cache_pos = !dir ? &this->m_send_cache_pos : &this->m_receive_cache_pos;
/* Verify that the input size is non-zero, and within cache buffer bounds. */
if (size && *cache_pos + size <= this->CacheBufferSize) {
@@ -217,8 +160,8 @@ namespace ams::mitm::uart {
/* Check for the first command used in the port which is opened last by bluetooth-sysmodule. */
/* This is a vendor command. */
/* Once detected, data-logging will be enabled. */
- if (!this->data_logging_enabled && hci_cmd->opcode[1] == 0xFC && hci_cmd->opcode[0] == 0x16) {
- this->data_logging_enabled = true;
+ if (!this->m_data_logging_enabled && hci_cmd->opcode[1] == 0xFC && hci_cmd->opcode[0] == 0x16) {
+ this->m_data_logging_enabled = true;
}
}
}
@@ -258,7 +201,11 @@ namespace ams::mitm::uart {
/* If a packet is available, log it and update the cache. */
if (pkt_len>0x1) {
- this->WriteLogPacket(dir, cache_buffer, pkt_len);
+ /* Only write to the file if data-logging is enabled and initialized. */
+ if (this->m_data_logging_enabled && this->m_datalog_ready) {
+ std::shared_ptr logger = mitm::uart::g_logger;
+ logger->SendLogData(&this->m_datalog_file, &this->m_datalog_pos, dir, cache_buffer, pkt_len);
+ }
(*cache_pos)-= pkt_len;
if (*cache_pos) {
std::memmove(cache_buffer, &cache_buffer[pkt_len], *cache_pos);
@@ -272,7 +219,7 @@ namespace ams::mitm::uart {
/* Forward OpenPort and write to the cmd_log. */
Result UartPortService::OpenPort(sf::Out out, u32 port, u32 baud_rate, UartFlowControlMode flow_control_mode, u32 device_variation, bool is_invert_tx, bool is_invert_rx, bool is_invert_rts, bool is_invert_cts, sf::CopyHandle send_handle, sf::CopyHandle receive_handle, u64 send_buffer_length, u64 receive_buffer_length) {
- Result rc = uartPortSessionOpenPortFwd(this->srv.get(), reinterpret_cast(out.GetPointer()), port, baud_rate, flow_control_mode, device_variation, is_invert_tx, is_invert_rx, is_invert_rts, is_invert_cts, send_handle.GetValue(), receive_handle.GetValue(), send_buffer_length, receive_buffer_length);
+ Result rc = uartPortSessionOpenPortFwd(this->m_srv.get(), reinterpret_cast(out.GetPointer()), port, baud_rate, flow_control_mode, device_variation, is_invert_tx, is_invert_rx, is_invert_rts, is_invert_cts, send_handle.GetValue(), receive_handle.GetValue(), send_buffer_length, receive_buffer_length);
svcCloseHandle(send_handle.GetValue());
svcCloseHandle(receive_handle.GetValue());
@@ -284,7 +231,7 @@ namespace ams::mitm::uart {
/* Forward OpenPortForDev and write to the cmd_log. */
Result UartPortService::OpenPortForDev(sf::Out out, u32 port, u32 baud_rate, UartFlowControlMode flow_control_mode, u32 device_variation, bool is_invert_tx, bool is_invert_rx, bool is_invert_rts, bool is_invert_cts, sf::CopyHandle send_handle, sf::CopyHandle receive_handle, u64 send_buffer_length, u64 receive_buffer_length) {
- Result rc = uartPortSessionOpenPortForDevFwd(this->srv.get(), reinterpret_cast(out.GetPointer()), port, baud_rate, flow_control_mode, device_variation, is_invert_tx, is_invert_rx, is_invert_rts, is_invert_cts, send_handle.GetValue(), receive_handle.GetValue(), send_buffer_length, receive_buffer_length);
+ Result rc = uartPortSessionOpenPortForDevFwd(this->m_srv.get(), reinterpret_cast(out.GetPointer()), port, baud_rate, flow_control_mode, device_variation, is_invert_tx, is_invert_rx, is_invert_rts, is_invert_cts, send_handle.GetValue(), receive_handle.GetValue(), send_buffer_length, receive_buffer_length);
svcCloseHandle(send_handle.GetValue());
svcCloseHandle(receive_handle.GetValue());
@@ -296,7 +243,7 @@ namespace ams::mitm::uart {
/* Forward GetWritableLength and write to the cmd_log. */
Result UartPortService::GetWritableLength(sf::Out out) {
- Result rc = uartPortSessionGetWritableLength(this->srv.get(), reinterpret_cast(out.GetPointer()));
+ Result rc = uartPortSessionGetWritableLength(this->m_srv.get(), reinterpret_cast(out.GetPointer()));
char str[256];
std::snprintf(str, sizeof(str), "GetWritableLength(): rc = 0x%x, out = 0x%lx\n", rc.GetValue(), out.GetValue());
@@ -307,7 +254,7 @@ namespace ams::mitm::uart {
/* Forward Send and log the data if the out_size is non-zero. */
Result UartPortService::Send(sf::Out out_size, const sf::InAutoSelectBuffer &data) {
- Result rc = uartPortSessionSend(this->srv.get(), data.GetPointer(), data.GetSize(), reinterpret_cast(out_size.GetPointer()));
+ Result rc = uartPortSessionSend(this->m_srv.get(), data.GetPointer(), data.GetSize(), reinterpret_cast(out_size.GetPointer()));
if (R_SUCCEEDED(rc) && out_size.GetValue()) {
this->WriteUartData(false, data.GetPointer(), out_size.GetValue());
@@ -317,7 +264,7 @@ namespace ams::mitm::uart {
/* Forward GetReadableLength and write to the cmd_log. */
Result UartPortService::GetReadableLength(sf::Out out) {
- Result rc = uartPortSessionGetReadableLength(this->srv.get(), reinterpret_cast(out.GetPointer()));
+ Result rc = uartPortSessionGetReadableLength(this->m_srv.get(), reinterpret_cast(out.GetPointer()));
char str[256];
std::snprintf(str, sizeof(str), "GetReadableLength(): rc = 0x%x, out = 0x%lx\n", rc.GetValue(), out.GetValue());
@@ -328,7 +275,7 @@ namespace ams::mitm::uart {
/* Forward Receive and log the data if the out_size is non-zero. */
Result UartPortService::Receive(sf::Out out_size, const sf::OutAutoSelectBuffer &data) {
- Result rc = uartPortSessionReceive(this->srv.get(), data.GetPointer(), data.GetSize(), reinterpret_cast(out_size.GetPointer()));
+ Result rc = uartPortSessionReceive(this->m_srv.get(), data.GetPointer(), data.GetSize(), reinterpret_cast(out_size.GetPointer()));
if (R_SUCCEEDED(rc) && out_size.GetValue()) {
this->WriteUartData(true, data.GetPointer(), out_size.GetValue());
@@ -338,7 +285,7 @@ namespace ams::mitm::uart {
/* Forward BindPortEvent and write to the cmd_log. */
Result UartPortService::BindPortEvent(sf::Out out, sf::OutCopyHandle out_event_handle, UartPortEventType port_event_type, s64 threshold) {
- Result rc = uartPortSessionBindPortEventFwd(this->srv.get(), port_event_type, threshold, reinterpret_cast(out.GetPointer()), out_event_handle.GetHandlePointer());
+ Result rc = uartPortSessionBindPortEventFwd(this->m_srv.get(), port_event_type, threshold, reinterpret_cast(out.GetPointer()), out_event_handle.GetHandlePointer());
char str[256];
std::snprintf(str, sizeof(str), "BindPortEvent(port_event_type = 0x%x, threshold = 0x%lx): rc = 0x%x, out = %d\n", port_event_type, threshold, rc.GetValue(), out.GetValue());
@@ -348,7 +295,7 @@ namespace ams::mitm::uart {
/* Forward UnbindPortEvent and write to the cmd_log. */
Result UartPortService::UnbindPortEvent(sf::Out out, UartPortEventType port_event_type) {
- Result rc = uartPortSessionUnbindPortEvent(this->srv.get(), port_event_type, reinterpret_cast(out.GetPointer()));
+ Result rc = uartPortSessionUnbindPortEvent(this->m_srv.get(), port_event_type, reinterpret_cast(out.GetPointer()));
char str[256];
std::snprintf(str, sizeof(str), "UnbindPortEvent(port_event_type = 0x%x): rc = 0x%x, out = %d\n", port_event_type, rc.GetValue(), out.GetValue());
diff --git a/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_service.hpp b/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_service.hpp
index 0b0b4471b..2a9c0917d 100644
--- a/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_service.hpp
+++ b/stratosphere/ams_mitm/source/uart_mitm/uart_mitm_service.hpp
@@ -16,6 +16,7 @@
#pragma once
#include
+#include "uart_mitm_logger.hpp"
#include "uart_shim.h"
#define AMS_UART_IPORTSESSION_MITM_INTERFACE_INFO(C, H) \
@@ -39,39 +40,39 @@ namespace ams::mitm::uart {
class UartPortService {
private:
- sm::MitmProcessInfo client_info;
- std::unique_ptr<::UartPortSession> srv;
+ sm::MitmProcessInfo m_client_info;
+ std::unique_ptr<::UartPortSession> m_srv;
static constexpr inline size_t CacheBufferSize = 0x1000;
- char base_path[256];
+ char m_base_path[256];
- size_t cmdlog_pos;
- size_t datalog_pos;
+ size_t m_cmdlog_pos;
+ size_t m_datalog_pos;
- bool datalog_ready;
- bool data_logging_enabled;
+ bool m_datalog_ready;
+ bool m_data_logging_enabled;
- FsFile datalog_file;
+ FsFile m_datalog_file;
- u8 *send_cache_buffer;
- u8 *receive_cache_buffer;
- size_t send_cache_pos;
- size_t receive_cache_pos;
+ u8 *m_send_cache_buffer;
+ u8 *m_receive_cache_buffer;
+ size_t m_send_cache_pos;
+ size_t m_receive_cache_pos;
bool TryGetCurrentTimestamp(u64 *out);
void WriteCmdLog(const char *str);
- void WriteLog(const void* buffer, size_t size);
- void WriteLogPacket(bool dir, const void* buffer, size_t size);
void WriteUartData(bool dir, const void* buffer, size_t size);
public:
UartPortService(const sm::MitmProcessInfo &cl, std::unique_ptr<::UartPortSession> s);
virtual ~UartPortService() {
- uartPortSessionClose(this->srv.get());
- fsFileClose(&this->datalog_file);
- std::free(this->send_cache_buffer);
- std::free(this->receive_cache_buffer);
+ std::shared_ptr logger = mitm::uart::g_logger;
+ logger->WaitFinished();
+ uartPortSessionClose(this->m_srv.get());
+ fsFileClose(&this->m_datalog_file);
+ std::free(this->m_send_cache_buffer);
+ std::free(this->m_receive_cache_buffer);
}
public:
/* Actual command API. */
diff --git a/stratosphere/ams_mitm/source/uart_mitm/uartmitm_module.cpp b/stratosphere/ams_mitm/source/uart_mitm/uartmitm_module.cpp
index dfe75342f..4229f6e3b 100644
--- a/stratosphere/ams_mitm/source/uart_mitm/uartmitm_module.cpp
+++ b/stratosphere/ams_mitm/source/uart_mitm/uartmitm_module.cpp
@@ -17,6 +17,7 @@
#include "../amsmitm_initialization.hpp"
#include "uartmitm_module.hpp"
#include "uart_mitm_service.hpp"
+#include "uart_mitm_logger.hpp"
namespace ams::mitm::uart {
@@ -84,8 +85,12 @@ namespace ams::mitm::uart {
/* Create mitm servers. */
R_ABORT_UNLESS((g_server_manager.RegisterMitmServer(PortIndex_Mitm, UartMitmServiceName)));
+ mitm::uart::g_logger = std::make_shared();
+
/* Loop forever, servicing our services. */
g_server_manager.LoopProcess();
+
+ mitm::uart::g_logger.reset();
}
}