mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-15 09:36:35 +00:00
3b662122f9
* troposphere: add haze MTP server * haze: adjust banner, new lines between class sections, single-statement if * haze: remove additional newlines between sections * haze: avoid use of reference out parameter * haze: console_main_loop: style * haze: event_reactor, file_system_proxy, ptp: style * haze: ptp_data_builder, ptp_object_database, ptp_object_heap, results, usb_session: style * haze: event_reactor, ptp_data_parser, async_usb_server, ptp_object_database, ptp_object_heap: style * haze: ptp_responder: style * haze: usb_session: style * haze: use svc defs from vapours * haze: misc comments * haze: fix pointer overflow check * haze: fix copy paste error * haze: use alignment, invalidate cached use values in console * haze: fix stray hex constant * haze: misc style * haze: fixes for windows * haze: add GetObjectPropsSupported, GetObjectPropDesc, GetObjectPropValue * haze: add SetObjectPropValue * haze: improve object database API * haze: improve WriteVariableLengthData readability * haze: fix directory renames on windows * haze: ptp_object_database: fix collation * haze: event_reactor: fix size validation * haze: ptp_responder: improve documentation * haze: ptp_responder: avoid unnecessary fs interaction in GetObjectPropValue * haze: ptp_responder: fix object deletion on windows * haze: tear down sessions on suspension * haze: prefer more specific data types * haze: misc * haze: fix usb 3.0 support * haze: improve host-to-device file transfer performance * haze: report device serial * haze: move static_assert to requires, fix alignment
114 lines
3.9 KiB
C++
114 lines
3.9 KiB
C++
/*
|
|
* Copyright (c) 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 <haze/async_usb_server.hpp>
|
|
#include <haze/common.hpp>
|
|
#include <haze/ptp.hpp>
|
|
|
|
namespace haze {
|
|
|
|
class PtpDataParser final {
|
|
private:
|
|
AsyncUsbServer *m_server;
|
|
u32 m_received_size;
|
|
u32 m_offset;
|
|
u8 *m_data;
|
|
bool m_eot;
|
|
private:
|
|
Result Flush() {
|
|
R_UNLESS(!m_eot, haze::ResultEndOfTransmission());
|
|
|
|
m_received_size = 0;
|
|
m_offset = 0;
|
|
|
|
ON_SCOPE_EXIT {
|
|
/* End of transmission occurs when receiving a bulk transfer less than the buffer size. */
|
|
/* PTP uses zero-length termination, so zero is a possible size to receive. */
|
|
m_eot = m_received_size < haze::UsbBulkPacketBufferSize;
|
|
};
|
|
|
|
R_RETURN(m_server->ReadPacket(m_data, haze::UsbBulkPacketBufferSize, std::addressof(m_received_size)));
|
|
}
|
|
public:
|
|
constexpr explicit PtpDataParser(void *data, AsyncUsbServer *server) : m_server(server), m_received_size(), m_offset(), m_data(static_cast<u8 *>(data)), m_eot() { /* ... */ }
|
|
|
|
Result Finalize() {
|
|
/* Read until the transmission completes. */
|
|
while (true) {
|
|
Result rc = this->Flush();
|
|
|
|
R_SUCCEED_IF(m_eot || haze::ResultEndOfTransmission::Includes(rc));
|
|
R_TRY(rc);
|
|
}
|
|
}
|
|
|
|
Result ReadBuffer(u8 *buffer, u32 count, u32 *out_read_count) {
|
|
*out_read_count = 0;
|
|
|
|
while (count > 0) {
|
|
/* If we cannot read more bytes now, flush. */
|
|
if (m_offset == m_received_size) {
|
|
R_TRY(this->Flush());
|
|
}
|
|
|
|
/* Calculate how many bytes we can read now. */
|
|
u32 read_size = std::min<u32>(count, m_received_size - m_offset);
|
|
|
|
/* Read this number of bytes. */
|
|
std::memcpy(buffer + *out_read_count, m_data + m_offset, read_size);
|
|
*out_read_count += read_size;
|
|
m_offset += read_size;
|
|
count -= read_size;
|
|
}
|
|
|
|
R_SUCCEED();
|
|
}
|
|
|
|
template <typename T>
|
|
Result Read(T *out_t) {
|
|
u32 read_count;
|
|
u8 bytes[sizeof(T)];
|
|
|
|
R_TRY(this->ReadBuffer(bytes, sizeof(T), std::addressof(read_count)));
|
|
|
|
std::memcpy(out_t, bytes, sizeof(T));
|
|
|
|
R_SUCCEED();
|
|
}
|
|
|
|
/* NOTE: out_string must contain room for 256 bytes. */
|
|
/* The result will be null-terminated on successful completion. */
|
|
Result ReadString(char *out_string) {
|
|
u8 len;
|
|
R_TRY(this->Read(std::addressof(len)));
|
|
|
|
/* Read characters one by one. */
|
|
for (size_t i = 0; i < len; i++) {
|
|
u16 chr;
|
|
R_TRY(this->Read(std::addressof(chr)));
|
|
|
|
*out_string++ = static_cast<char>(chr);
|
|
}
|
|
|
|
/* Write null terminator. */
|
|
*out_string++ = '\x00';
|
|
|
|
R_SUCCEED();
|
|
}
|
|
};
|
|
|
|
}
|