Revert "hoc-clk: add live vdd2, live boost clock and basic pwm dimming"
This reverts commit 15b7df8ef1.
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* 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/device_properties.hpp>
|
||||
#include <haze/event_reactor.hpp>
|
||||
#include <haze/file_system_proxy.hpp>
|
||||
#include <haze/ptp.hpp>
|
||||
#include <haze/ptp_object_database.hpp>
|
||||
#include <haze/ptp_object_heap.hpp>
|
||||
#include <haze/ptp_responder.hpp>
|
||||
#include <haze/usb_session.hpp>
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#define HAZE_ASSERT(expr) \
|
||||
{ \
|
||||
const bool __tmp_haze_assert_val = static_cast<bool>(expr); \
|
||||
if (AMS_UNLIKELY(!__tmp_haze_assert_val)) { \
|
||||
svcBreak(BreakReason_Assert, 0, 0); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define HAZE_R_ABORT_UNLESS(res_expr) \
|
||||
{ \
|
||||
const auto _tmp_r_abort_rc = (res_expr); \
|
||||
HAZE_ASSERT(R_SUCCEEDED(_tmp_r_abort_rc)); \
|
||||
}
|
||||
|
||||
#define HAZE_UNREACHABLE_DEFAULT_CASE() default: HAZE_ASSERT(false)
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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/common.hpp>
|
||||
#include <haze/event_reactor.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
class AsyncUsbServer final {
|
||||
private:
|
||||
EventReactor *m_reactor;
|
||||
public:
|
||||
constexpr explicit AsyncUsbServer() : m_reactor() { /* ... */ }
|
||||
|
||||
Result Initialize(const UsbCommsInterfaceInfo *interface_info, u16 id_vendor, u16 id_product, EventReactor *reactor);
|
||||
void Finalize();
|
||||
private:
|
||||
Result TransferPacketImpl(bool read, void *page, u32 size, u32 *out_size_transferred) const;
|
||||
public:
|
||||
Result ReadPacket(void *page, u32 size, u32 *out_size_transferred) const {
|
||||
R_RETURN(this->TransferPacketImpl(true, page, size, out_size_transferred));
|
||||
}
|
||||
|
||||
Result WritePacket(void *page, u32 size) const {
|
||||
u32 size_transferred;
|
||||
R_RETURN(this->TransferPacketImpl(false, page, size, std::addressof(size_transferred)));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#define ATMOSPHERE_IS_TROPOSPHERE
|
||||
#define ATMOSPHERE_OS_HORIZON
|
||||
#define ATMOSPHERE_BOARD_NINTENDO_NX
|
||||
#define ATMOSPHERE_ARCH_ARM64
|
||||
#define ATMOSPHERE_ARCH_ARM_V8A
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <bit>
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <switch.h>
|
||||
#include <haze/results.hpp>
|
||||
#include <haze/assert.hpp>
|
||||
|
||||
#include <vapours/literals.hpp>
|
||||
#include <vapours/svc/svc_common.hpp>
|
||||
#include <vapours/svc/svc_types_common.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
using namespace ::ams::literals;
|
||||
using namespace ::ams;
|
||||
|
||||
using Result = ::ams::Result;
|
||||
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
/*
|
||||
* 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/event_reactor.hpp>
|
||||
#include <haze/ptp_object_heap.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
class ConsoleMainLoop : public EventConsumer {
|
||||
private:
|
||||
static constexpr size_t FrameDelayNs = 33'333'333;
|
||||
private:
|
||||
EventReactor *m_reactor;
|
||||
PtpObjectHeap *m_object_heap;
|
||||
|
||||
PadState m_pad;
|
||||
|
||||
Thread m_thread;
|
||||
UEvent m_event;
|
||||
UEvent m_cancel_event;
|
||||
|
||||
u32 m_last_heap_used;
|
||||
u32 m_last_heap_total;
|
||||
bool m_is_applet_mode;
|
||||
private:
|
||||
static void Run(void *arg) {
|
||||
static_cast<ConsoleMainLoop *>(arg)->Run();
|
||||
}
|
||||
|
||||
void Run() {
|
||||
int idx;
|
||||
|
||||
while (true) {
|
||||
/* Wait for up to 1 frame delay time to be cancelled. */
|
||||
Waiter cancel_waiter = waiterForUEvent(std::addressof(m_cancel_event));
|
||||
Result rc = waitObjects(std::addressof(idx), std::addressof(cancel_waiter), 1, FrameDelayNs);
|
||||
|
||||
/* Finish if we were cancelled. */
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Otherwise, signal the console update event. */
|
||||
if (svc::ResultTimedOut::Includes(rc)) {
|
||||
ueventSignal(std::addressof(m_event));
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
explicit ConsoleMainLoop() : m_reactor(), m_pad(), m_thread(), m_event(), m_cancel_event(), m_last_heap_used(), m_last_heap_total(), m_is_applet_mode() { /* ... */ }
|
||||
|
||||
Result Initialize(EventReactor *reactor, PtpObjectHeap *object_heap) {
|
||||
/* Register event reactor and heap. */
|
||||
m_reactor = reactor;
|
||||
m_object_heap = object_heap;
|
||||
|
||||
/* Set cached use amounts to invalid values. */
|
||||
m_last_heap_used = 0xffffffffu;
|
||||
m_last_heap_total = 0xffffffffu;
|
||||
|
||||
/* Get whether we are launched in applet mode. */
|
||||
AppletType applet_type = appletGetAppletType();
|
||||
m_is_applet_mode = applet_type != AppletType_Application && applet_type != AppletType_SystemApplication;
|
||||
|
||||
/* Initialize events. */
|
||||
ueventCreate(std::addressof(m_event), true);
|
||||
ueventCreate(std::addressof(m_cancel_event), true);
|
||||
|
||||
/* Set up pad inputs to allow exiting the program. */
|
||||
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
||||
padInitializeAny(std::addressof(m_pad));
|
||||
|
||||
/* Create the delay thread with higher priority than the main thread (which runs at priority 0x2c). */
|
||||
R_TRY(threadCreate(std::addressof(m_thread), ConsoleMainLoop::Run, this, nullptr, 4_KB, 0x2b, svc::IdealCoreUseProcessValue));
|
||||
|
||||
/* Ensure we close the thread on failure. */
|
||||
ON_RESULT_FAILURE { threadClose(std::addressof(m_thread)); };
|
||||
|
||||
/* Connect ourselves to the event loop. */
|
||||
R_UNLESS(m_reactor->AddConsumer(this, waiterForUEvent(std::addressof(m_event))), haze::ResultRegistrationFailed());
|
||||
|
||||
/* Start the delay thread. */
|
||||
R_RETURN(threadStart(std::addressof(m_thread)));
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
/* Signal the delay thread to shut down. */
|
||||
ueventSignal(std::addressof(m_cancel_event));
|
||||
|
||||
/* Wait for the delay thread to exit and close it. */
|
||||
HAZE_R_ABORT_UNLESS(threadWaitForExit(std::addressof(m_thread)));
|
||||
|
||||
HAZE_R_ABORT_UNLESS(threadClose(std::addressof(m_thread)));
|
||||
|
||||
/* Disconnect from the event loop.*/
|
||||
m_reactor->RemoveConsumer(this);
|
||||
}
|
||||
private:
|
||||
void RedrawConsole() {
|
||||
/* Get use amounts from the heap. */
|
||||
u32 heap_used = m_object_heap->GetUsedSize();
|
||||
u32 heap_total = m_object_heap->GetTotalSize();
|
||||
u32 heap_pct = heap_total > 0 ? static_cast<u32>((heap_used * 100ul) / heap_total) : 0;
|
||||
|
||||
if (heap_used == m_last_heap_used && heap_total == m_last_heap_total) {
|
||||
/* If usage didn't change, skip redrawing the console. */
|
||||
/* This provides a substantial performance improvement in file transfer speed. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update cached use amounts. */
|
||||
m_last_heap_used = heap_used;
|
||||
m_last_heap_total = heap_total;
|
||||
|
||||
/* Determine units to use for printing to the console. */
|
||||
const char *used_unit = "B";
|
||||
if (heap_used >= 1_KB) { heap_used >>= 10; used_unit = "KiB"; }
|
||||
if (heap_used >= (1_MB / 1_KB)) { heap_used >>= 10; used_unit = "MiB"; }
|
||||
|
||||
const char *total_unit = "B";
|
||||
if (heap_total >= 1_KB) { heap_total >>= 10; total_unit = "KiB"; }
|
||||
if (heap_total >= (1_MB / 1_KB)) { heap_total >>= 10; total_unit = "MiB"; }
|
||||
|
||||
/* Draw the console UI. */
|
||||
consoleClear();
|
||||
printf("USB File Transfer\n\n");
|
||||
printf("Connect console to computer. Press [+] to exit.\n");
|
||||
printf("Heap used: %u %s / %u %s (%u%%)\n", heap_used, used_unit, heap_total, total_unit, heap_pct);
|
||||
|
||||
if (m_is_applet_mode) {
|
||||
/* Print "Applet Mode" in red text. */
|
||||
printf("\n" CONSOLE_ESC(31;1m) "Applet Mode" CONSOLE_ESC(0m) "\n");
|
||||
}
|
||||
|
||||
consoleUpdate(nullptr);
|
||||
}
|
||||
protected:
|
||||
void ProcessEvent() override {
|
||||
/* Update the console. */
|
||||
this->RedrawConsole();
|
||||
|
||||
/* Check buttons. */
|
||||
padUpdate(std::addressof(m_pad));
|
||||
|
||||
/* If the plus button is held, request immediate exit. */
|
||||
if (padGetButtonsDown(std::addressof(m_pad)) & HidNpadButton_Plus) {
|
||||
m_reactor->SetResult(haze::ResultStopRequested());
|
||||
}
|
||||
|
||||
/* Pump applet events, and check if exit was requested. */
|
||||
if (!appletMainLoop()) {
|
||||
m_reactor->SetResult(haze::ResultStopRequested());
|
||||
}
|
||||
|
||||
/* Check if focus was lost. */
|
||||
if (appletGetFocusState() == AppletFocusState_Background) {
|
||||
m_reactor->SetResult(haze::ResultFocusLost());
|
||||
}
|
||||
}
|
||||
private:
|
||||
static bool SuspendAndWaitForFocus() {
|
||||
/* Enable suspension with resume notification. */
|
||||
appletSetFocusHandlingMode(AppletFocusHandlingMode_SuspendHomeSleepNotify);
|
||||
|
||||
/* Pump applet events. */
|
||||
while (appletMainLoop()) {
|
||||
/* Check if focus was regained. */
|
||||
if (appletGetFocusState() != AppletFocusState_Background) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Exit was requested. */
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
static void RunApplication() {
|
||||
/* Declare the object heap, to hold the database for an active session. */
|
||||
PtpObjectHeap ptp_object_heap;
|
||||
|
||||
/* Declare the event reactor, and components which use it. */
|
||||
EventReactor event_reactor;
|
||||
PtpResponder ptp_responder;
|
||||
ConsoleMainLoop console_main_loop;
|
||||
|
||||
/* Initialize the console.*/
|
||||
consoleInit(nullptr);
|
||||
|
||||
while (true) {
|
||||
/* Disable suspension. */
|
||||
appletSetFocusHandlingMode(AppletFocusHandlingMode_NoSuspend);
|
||||
|
||||
/* Declare result from serving to use. */
|
||||
Result rc;
|
||||
{
|
||||
/* Ensure we don't go to sleep while transferring files. */
|
||||
appletSetAutoSleepDisabled(true);
|
||||
|
||||
/* Clear the event reactor. */
|
||||
event_reactor.SetResult(ResultSuccess());
|
||||
|
||||
/* Configure the PTP responder and console main loop. */
|
||||
ptp_responder.Initialize(std::addressof(event_reactor), std::addressof(ptp_object_heap));
|
||||
console_main_loop.Initialize(std::addressof(event_reactor), std::addressof(ptp_object_heap));
|
||||
|
||||
/* Ensure we maintain a clean state on exit. */
|
||||
ON_SCOPE_EXIT {
|
||||
/* Finalize the console main loop and PTP responder. */
|
||||
console_main_loop.Finalize();
|
||||
ptp_responder.Finalize();
|
||||
|
||||
/* Restore auto sleep setting. */
|
||||
appletSetAutoSleepDisabled(false);
|
||||
};
|
||||
|
||||
/* Begin processing requests. */
|
||||
rc = ptp_responder.LoopProcess();
|
||||
}
|
||||
|
||||
/* If focus was lost, try to pump the applet main loop until we receive focus again. */
|
||||
if (haze::ResultFocusLost::Includes(rc) && SuspendAndWaitForFocus()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Otherwise, enable suspension and finish. */
|
||||
appletSetFocusHandlingMode(AppletFocusHandlingMode_SuspendHomeSleep);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Finalize the console. */
|
||||
consoleExit(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace haze {
|
||||
|
||||
Result LoadDeviceProperties();
|
||||
|
||||
const char *GetSerialNumber();
|
||||
|
||||
const char *GetFirmwareVersion();
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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/common.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
class EventConsumer {
|
||||
public:
|
||||
virtual ~EventConsumer() = default;
|
||||
virtual void ProcessEvent() = 0;
|
||||
};
|
||||
|
||||
class EventReactor {
|
||||
private:
|
||||
EventConsumer *m_consumers[svc::ArgumentHandleCountMax];
|
||||
Waiter m_waiters[svc::ArgumentHandleCountMax];
|
||||
s32 m_num_wait_objects;
|
||||
Result m_result;
|
||||
public:
|
||||
constexpr explicit EventReactor() : m_consumers(), m_waiters(), m_num_wait_objects(), m_result(ResultSuccess()) { /* ... */ }
|
||||
|
||||
bool AddConsumer(EventConsumer *consumer, Waiter waiter);
|
||||
void RemoveConsumer(EventConsumer *consumer);
|
||||
public:
|
||||
void SetResult(Result r) { m_result = r; }
|
||||
Result GetResult() const { return m_result; }
|
||||
public:
|
||||
template <typename... Args> requires (sizeof...(Args) > 0)
|
||||
Result WaitFor(s32 *out_arg_waiter, Args &&... arg_waiters) {
|
||||
const Waiter arg_waiter_array[] = { arg_waiters... };
|
||||
return this->WaitForImpl(out_arg_waiter, arg_waiter_array, sizeof...(Args));
|
||||
}
|
||||
private:
|
||||
Result WaitForImpl(s32 *out_arg_waiter, const Waiter *arg_waiters, s32 num_arg_waiters);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* 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/common.hpp>
|
||||
#include <haze/event_reactor.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
class FileSystemProxy final {
|
||||
private:
|
||||
EventReactor *m_reactor;
|
||||
FsFileSystem *m_filesystem;
|
||||
public:
|
||||
constexpr explicit FileSystemProxy() : m_reactor(), m_filesystem() { /* ... */ }
|
||||
|
||||
void Initialize(EventReactor *reactor, FsFileSystem *fs) {
|
||||
HAZE_ASSERT(fs != nullptr);
|
||||
|
||||
m_reactor = reactor;
|
||||
m_filesystem = fs;
|
||||
}
|
||||
|
||||
void Finalize() {
|
||||
m_reactor = nullptr;
|
||||
m_filesystem = nullptr;
|
||||
}
|
||||
private:
|
||||
template <typename F, typename... Args>
|
||||
Result ForwardResult(F func, Args &&... args) {
|
||||
/* Perform the method call, collecting its result. */
|
||||
const Result rc = func(std::forward<Args>(args)...);
|
||||
|
||||
/* If the event loop was stopped, return that here. */
|
||||
R_TRY(m_reactor->GetResult());
|
||||
|
||||
/* Otherwise, return the call result. */
|
||||
R_RETURN(rc);
|
||||
}
|
||||
public:
|
||||
Result GetTotalSpace(const char *path, s64 *out) {
|
||||
R_RETURN(this->ForwardResult(fsFsGetTotalSpace, m_filesystem, path, out));
|
||||
}
|
||||
|
||||
Result GetFreeSpace(const char *path, s64 *out) {
|
||||
R_RETURN(this->ForwardResult(fsFsGetFreeSpace, m_filesystem, path, out));
|
||||
}
|
||||
|
||||
Result GetEntryType(const char *path, FsDirEntryType *out_entry_type) {
|
||||
R_RETURN(this->ForwardResult(fsFsGetEntryType, m_filesystem, path, out_entry_type));
|
||||
}
|
||||
|
||||
Result CreateFile(const char* path, s64 size, u32 option) {
|
||||
R_RETURN(this->ForwardResult(fsFsCreateFile, m_filesystem, path, size, option));
|
||||
}
|
||||
|
||||
Result DeleteFile(const char* path) {
|
||||
R_RETURN(this->ForwardResult(fsFsDeleteFile, m_filesystem, path));
|
||||
}
|
||||
|
||||
Result RenameFile(const char *old_path, const char *new_path) {
|
||||
R_RETURN(this->ForwardResult(fsFsRenameFile, m_filesystem, old_path, new_path));
|
||||
}
|
||||
|
||||
Result OpenFile(const char *path, u32 mode, FsFile *out_file) {
|
||||
R_RETURN(this->ForwardResult(fsFsOpenFile, m_filesystem, path, mode, out_file));
|
||||
}
|
||||
|
||||
Result GetFileSize(FsFile *file, s64 *out_size) {
|
||||
R_RETURN(this->ForwardResult(fsFileGetSize, file, out_size));
|
||||
}
|
||||
|
||||
Result SetFileSize(FsFile *file, s64 size) {
|
||||
R_RETURN(this->ForwardResult(fsFileSetSize, file, size));
|
||||
}
|
||||
|
||||
Result ReadFile(FsFile *file, s64 off, void *buf, u64 read_size, u32 option, u64 *out_bytes_read) {
|
||||
R_RETURN(this->ForwardResult(fsFileRead, file, off, buf, read_size, option, out_bytes_read));
|
||||
}
|
||||
|
||||
Result WriteFile(FsFile *file, s64 off, const void *buf, u64 write_size, u32 option) {
|
||||
R_RETURN(this->ForwardResult(fsFileWrite, file, off, buf, write_size, option));
|
||||
}
|
||||
|
||||
void CloseFile(FsFile *file) {
|
||||
fsFileClose(file);
|
||||
}
|
||||
|
||||
Result CreateDirectory(const char* path) {
|
||||
R_RETURN(this->ForwardResult(fsFsCreateDirectory, m_filesystem, path));
|
||||
}
|
||||
|
||||
Result DeleteDirectoryRecursively(const char* path) {
|
||||
R_RETURN(this->ForwardResult(fsFsDeleteDirectoryRecursively, m_filesystem, path));
|
||||
}
|
||||
|
||||
Result RenameDirectory(const char *old_path, const char *new_path) {
|
||||
R_RETURN(this->ForwardResult(fsFsRenameDirectory, m_filesystem, old_path, new_path));
|
||||
}
|
||||
|
||||
Result OpenDirectory(const char *path, u32 mode, FsDir *out_dir) {
|
||||
R_RETURN(this->ForwardResult(fsFsOpenDirectory, m_filesystem, path, mode, out_dir));
|
||||
}
|
||||
|
||||
Result ReadDirectory(FsDir *d, s64 *out_total_entries, size_t max_entries, FsDirectoryEntry *buf) {
|
||||
R_RETURN(this->ForwardResult(fsDirRead, d, out_total_entries, max_entries, buf));
|
||||
}
|
||||
|
||||
Result GetDirectoryEntryCount(FsDir *d, s64 *out_count) {
|
||||
R_RETURN(this->ForwardResult(fsDirGetEntryCount, d, out_count));
|
||||
}
|
||||
|
||||
void CloseDirectory(FsDir *d) {
|
||||
fsDirClose(d);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,493 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Atmosphère-NX
|
||||
* Copyright (c) libmtp project
|
||||
*
|
||||
* 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/common.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
constexpr inline u32 PtpUsbBulkHighSpeedMaxPacketLength = 0x200;
|
||||
constexpr inline u32 PtpUsbBulkSuperSpeedMaxPacketLength = 0x400;
|
||||
constexpr inline u32 PtpUsbBulkHeaderLength = 2 * sizeof(u32) + 2 * sizeof(u16);
|
||||
constexpr inline u32 PtpStringMaxLength = 255;
|
||||
|
||||
enum PtpUsbBulkContainerType : u16 {
|
||||
PtpUsbBulkContainerType_Undefined = 0x0000,
|
||||
PtpUsbBulkContainerType_Command = 0x0001,
|
||||
PtpUsbBulkContainerType_Data = 0x0002,
|
||||
PtpUsbBulkContainerType_Response = 0x0003,
|
||||
PtpUsbBulkContainerType_Event = 0x0004,
|
||||
};
|
||||
|
||||
enum PtpOperationCode : u16 {
|
||||
PtpOperationCode_Undefined = 0x1000,
|
||||
PtpOperationCode_GetDeviceInfo = 0x1001,
|
||||
PtpOperationCode_OpenSession = 0x1002,
|
||||
PtpOperationCode_CloseSession = 0x1003,
|
||||
PtpOperationCode_GetStorageIds = 0x1004,
|
||||
PtpOperationCode_GetStorageInfo = 0x1005,
|
||||
PtpOperationCode_GetNumObjects = 0x1006,
|
||||
PtpOperationCode_GetObjectHandles = 0x1007,
|
||||
PtpOperationCode_GetObjectInfo = 0x1008,
|
||||
PtpOperationCode_GetObject = 0x1009,
|
||||
PtpOperationCode_GetThumb = 0x100a,
|
||||
PtpOperationCode_DeleteObject = 0x100b,
|
||||
PtpOperationCode_SendObjectInfo = 0x100c,
|
||||
PtpOperationCode_SendObject = 0x100d,
|
||||
PtpOperationCode_InitiateCapture = 0x100e,
|
||||
PtpOperationCode_FormatStore = 0x100f,
|
||||
PtpOperationCode_ResetDevice = 0x1010,
|
||||
PtpOperationCode_SelfTest = 0x1011,
|
||||
PtpOperationCode_SetObjectProtection = 0x1012,
|
||||
PtpOperationCode_PowerDown = 0x1013,
|
||||
PtpOperationCode_GetDevicePropDesc = 0x1014,
|
||||
PtpOperationCode_GetDevicePropValue = 0x1015,
|
||||
PtpOperationCode_SetDevicePropValue = 0x1016,
|
||||
PtpOperationCode_ResetDevicePropValue = 0x1017,
|
||||
PtpOperationCode_TerminateOpenCapture = 0x1018,
|
||||
PtpOperationCode_MoveObject = 0x1019,
|
||||
PtpOperationCode_CopyObject = 0x101a,
|
||||
PtpOperationCode_GetPartialObject = 0x101b,
|
||||
PtpOperationCode_InitiateOpenCapture = 0x101c,
|
||||
PtpOperationCode_StartEnumHandles = 0x101d,
|
||||
PtpOperationCode_EnumHandles = 0x101e,
|
||||
PtpOperationCode_StopEnumHandles = 0x101f,
|
||||
PtpOperationCode_GetVendorExtensionMaps = 0x1020,
|
||||
PtpOperationCode_GetVendorDeviceInfo = 0x1021,
|
||||
PtpOperationCode_GetResizedImageObject = 0x1022,
|
||||
PtpOperationCode_GetFilesystemManifest = 0x1023,
|
||||
PtpOperationCode_GetStreamInfo = 0x1024,
|
||||
PtpOperationCode_GetStream = 0x1025,
|
||||
PtpOperationCode_AndroidGetPartialObject64 = 0x95c1,
|
||||
PtpOperationCode_AndroidSendPartialObject = 0x95c2,
|
||||
PtpOperationCode_AndroidTruncateObject = 0x95c3,
|
||||
PtpOperationCode_AndroidBeginEditObject = 0x95c4,
|
||||
PtpOperationCode_AndroidEndEditObject = 0x95c5,
|
||||
PtpOperationCode_MtpGetObjectPropsSupported = 0x9801,
|
||||
PtpOperationCode_MtpGetObjectPropDesc = 0x9802,
|
||||
PtpOperationCode_MtpGetObjectPropValue = 0x9803,
|
||||
PtpOperationCode_MtpSetObjectPropValue = 0x9804,
|
||||
PtpOperationCode_MtpGetObjPropList = 0x9805,
|
||||
PtpOperationCode_MtpSetObjPropList = 0x9806,
|
||||
PtpOperationCode_MtpGetInterdependendPropdesc = 0x9807,
|
||||
PtpOperationCode_MtpSendObjectPropList = 0x9808,
|
||||
PtpOperationCode_MtpGetObjectReferences = 0x9810,
|
||||
PtpOperationCode_MtpSetObjectReferences = 0x9811,
|
||||
PtpOperationCode_MtpUpdateDeviceFirmware = 0x9812,
|
||||
PtpOperationCode_MtpSkip = 0x9820,
|
||||
};
|
||||
|
||||
enum PtpResponseCode : u16 {
|
||||
PtpResponseCode_Undefined = 0x2000,
|
||||
PtpResponseCode_Ok = 0x2001,
|
||||
PtpResponseCode_GeneralError = 0x2002,
|
||||
PtpResponseCode_SessionNotOpen = 0x2003,
|
||||
PtpResponseCode_InvalidTransactionId = 0x2004,
|
||||
PtpResponseCode_OperationNotSupported = 0x2005,
|
||||
PtpResponseCode_ParameterNotSupported = 0x2006,
|
||||
PtpResponseCode_IncompleteTransfer = 0x2007,
|
||||
PtpResponseCode_InvalidStorageId = 0x2008,
|
||||
PtpResponseCode_InvalidObjectHandle = 0x2009,
|
||||
PtpResponseCode_DevicePropNotSupported = 0x200a,
|
||||
PtpResponseCode_InvalidObjectFormatCode = 0x200b,
|
||||
PtpResponseCode_StoreFull = 0x200c,
|
||||
PtpResponseCode_ObjectWriteProtected = 0x200d,
|
||||
PtpResponseCode_StoreReadOnly = 0x200e,
|
||||
PtpResponseCode_AccessDenied = 0x200f,
|
||||
PtpResponseCode_NoThumbnailPresent = 0x2010,
|
||||
PtpResponseCode_SelfTestFailed = 0x2011,
|
||||
PtpResponseCode_PartialDeletion = 0x2012,
|
||||
PtpResponseCode_StoreNotAvailable = 0x2013,
|
||||
PtpResponseCode_SpecificationByFormatUnsupported = 0x2014,
|
||||
PtpResponseCode_NoValidObjectInfo = 0x2015,
|
||||
PtpResponseCode_InvalidCodeFormat = 0x2016,
|
||||
PtpResponseCode_UnknownVendorCode = 0x2017,
|
||||
PtpResponseCode_CaptureAlreadyTerminated = 0x2018,
|
||||
PtpResponseCode_DeviceBusy = 0x2019,
|
||||
PtpResponseCode_InvalidParentObject = 0x201a,
|
||||
PtpResponseCode_InvalidDevicePropFormat = 0x201b,
|
||||
PtpResponseCode_InvalidDevicePropValue = 0x201c,
|
||||
PtpResponseCode_InvalidParameter = 0x201d,
|
||||
PtpResponseCode_SessionAlreadyOpened = 0x201e,
|
||||
PtpResponseCode_TransactionCanceled = 0x201f,
|
||||
PtpResponseCode_SpecificationOfDestinationUnsupported = 0x2020,
|
||||
PtpResponseCode_InvalidEnumHandle = 0x2021,
|
||||
PtpResponseCode_NoStreamEnabled = 0x2022,
|
||||
PtpResponseCode_InvalidDataSet = 0x2023,
|
||||
PtpResponseCode_MtpUndefined = 0xa800,
|
||||
PtpResponseCode_MtpInvalidObjectPropCode = 0xa801,
|
||||
PtpResponseCode_MtpInvalidObjectPropFormat = 0xa802,
|
||||
PtpResponseCode_MtpInvalidObjectPropValue = 0xa803,
|
||||
PtpResponseCode_MtpInvalidObjectReference = 0xa804,
|
||||
PtpResponseCode_MtpInvalidDataset = 0xa806,
|
||||
PtpResponseCode_MtpSpecificationByGroupUnsupported = 0xa807,
|
||||
PtpResponseCode_MtpSpecificationByDepthUnsupported = 0xa808,
|
||||
PtpResponseCode_MtpObjectTooLarge = 0xa809,
|
||||
PtpResponseCode_MtpObjectPropNotSupported = 0xa80a,
|
||||
};
|
||||
|
||||
enum PtpEventCode : u16 {
|
||||
PtpEventCode_Undefined = 0x4000,
|
||||
PtpEventCode_CancelTransaction = 0x4001,
|
||||
PtpEventCode_ObjectAdded = 0x4002,
|
||||
PtpEventCode_ObjectRemoved = 0x4003,
|
||||
PtpEventCode_StoreAdded = 0x4004,
|
||||
PtpEventCode_StoreRemoved = 0x4005,
|
||||
PtpEventCode_DevicePropChanged = 0x4006,
|
||||
PtpEventCode_ObjectInfoChanged = 0x4007,
|
||||
PtpEventCode_DeviceInfoChanged = 0x4008,
|
||||
PtpEventCode_RequestObjectTransfer = 0x4009,
|
||||
PtpEventCode_StoreFull = 0x400a,
|
||||
PtpEventCode_DeviceReset = 0x400b,
|
||||
PtpEventCode_StorageInfoChanged = 0x400c,
|
||||
PtpEventCode_CaptureComplete = 0x400d,
|
||||
PtpEventCode_UnreportedStatus = 0x400e,
|
||||
};
|
||||
|
||||
enum PtpDataTypeCode : u16 {
|
||||
PtpDataTypeCode_Undefined = 0x0000,
|
||||
PtpDataTypeCode_S8 = 0x0001,
|
||||
PtpDataTypeCode_U8 = 0x0002,
|
||||
PtpDataTypeCode_S16 = 0x0003,
|
||||
PtpDataTypeCode_U16 = 0x0004,
|
||||
PtpDataTypeCode_S32 = 0x0005,
|
||||
PtpDataTypeCode_U32 = 0x0006,
|
||||
PtpDataTypeCode_S64 = 0x0007,
|
||||
PtpDataTypeCode_U64 = 0x0008,
|
||||
PtpDataTypeCode_S128 = 0x0009,
|
||||
PtpDataTypeCode_U128 = 0x000a,
|
||||
|
||||
PtpDataTypeCode_ArrayMask = (1u << 14),
|
||||
|
||||
PtpDataTypeCode_S8Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_S8,
|
||||
PtpDataTypeCode_U8Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_U8,
|
||||
PtpDataTypeCode_S16Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_S16,
|
||||
PtpDataTypeCode_U16Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_U16,
|
||||
PtpDataTypeCode_S32Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_S32,
|
||||
PtpDataTypeCode_U32Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_U32,
|
||||
PtpDataTypeCode_S64Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_S64,
|
||||
PtpDataTypeCode_U64Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_U64,
|
||||
PtpDataTypeCode_S128Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_S128,
|
||||
PtpDataTypeCode_U128Array = PtpDataTypeCode_ArrayMask | PtpDataTypeCode_U128,
|
||||
|
||||
PtpDataTypeCode_String = 0xffff,
|
||||
};
|
||||
|
||||
enum PtpPropertyGetSetFlag : u8 {
|
||||
PtpPropertyGetSetFlag_Get = 0x00,
|
||||
PtpPropertyGetSetFlag_GetSet = 0x01,
|
||||
};
|
||||
|
||||
enum PtpPropertyGroupCode : u32 {
|
||||
PtpPropertyGroupCode_Default = 0x00000000,
|
||||
};
|
||||
|
||||
enum PtpPropertyFormFlag : u8 {
|
||||
PtpPropertyFormFlag_None = 0x00,
|
||||
PtpPropertyFormFlag_Range = 0x01,
|
||||
PtpPropertyFormFlag_Enumeration = 0x02,
|
||||
PtpPropertyFormFlag_DateTime = 0x03,
|
||||
PtpPropertyFormFlag_FixedLengthArray = 0x04,
|
||||
PtpPropertyFormFlag_RegularExpression = 0x05,
|
||||
PtpPropertyFormFlag_ByteArray = 0x06,
|
||||
PtpPropertyFormFlag_LongString = 0xff,
|
||||
};
|
||||
|
||||
enum PtpObjectPropertyCode : u16 {
|
||||
PtpObjectPropertyCode_StorageId = 0xdc01,
|
||||
PtpObjectPropertyCode_ObjectFormat = 0xdc02,
|
||||
PtpObjectPropertyCode_ProtectionStatus = 0xdc03,
|
||||
PtpObjectPropertyCode_ObjectSize = 0xdc04,
|
||||
PtpObjectPropertyCode_AssociationType = 0xdc05,
|
||||
PtpObjectPropertyCode_AssociationDesc = 0xdc06,
|
||||
PtpObjectPropertyCode_ObjectFileName = 0xdc07,
|
||||
PtpObjectPropertyCode_DateCreated = 0xdc08,
|
||||
PtpObjectPropertyCode_DateModified = 0xdc09,
|
||||
PtpObjectPropertyCode_Keywords = 0xdc0a,
|
||||
PtpObjectPropertyCode_ParentObject = 0xdc0b,
|
||||
PtpObjectPropertyCode_AllowedFolderContents = 0xdc0c,
|
||||
PtpObjectPropertyCode_Hidden = 0xdc0d,
|
||||
PtpObjectPropertyCode_SystemObject = 0xdc0e,
|
||||
PtpObjectPropertyCode_PersistentUniqueObjectIdentifier = 0xdc41,
|
||||
PtpObjectPropertyCode_SyncId = 0xdc42,
|
||||
PtpObjectPropertyCode_PropertyBag = 0xdc43,
|
||||
PtpObjectPropertyCode_Name = 0xdc44,
|
||||
PtpObjectPropertyCode_CreatedBy = 0xdc45,
|
||||
PtpObjectPropertyCode_Artist = 0xdc46,
|
||||
PtpObjectPropertyCode_DateAuthored = 0xdc47,
|
||||
PtpObjectPropertyCode_Description = 0xdc48,
|
||||
PtpObjectPropertyCode_UrlReference = 0xdc49,
|
||||
PtpObjectPropertyCode_LanguageLocale = 0xdc4a,
|
||||
PtpObjectPropertyCode_CopyrightInformation = 0xdc4b,
|
||||
PtpObjectPropertyCode_Source = 0xdc4c,
|
||||
PtpObjectPropertyCode_OriginLocation = 0xdc4d,
|
||||
PtpObjectPropertyCode_DateAdded = 0xdc4e,
|
||||
PtpObjectPropertyCode_NonConsumable = 0xdc4f,
|
||||
PtpObjectPropertyCode_CorruptOrUnplayable = 0xdc50,
|
||||
PtpObjectPropertyCode_ProducerSerialNumber = 0xdc51,
|
||||
PtpObjectPropertyCode_RepresentativeSampleFormat = 0xdc81,
|
||||
PtpObjectPropertyCode_RepresentativeSampleSize = 0xdc82,
|
||||
PtpObjectPropertyCode_RepresentativeSampleHeight = 0xdc83,
|
||||
PtpObjectPropertyCode_RepresentativeSampleWidth = 0xdc84,
|
||||
PtpObjectPropertyCode_RepresentativeSampleDuration = 0xdc85,
|
||||
PtpObjectPropertyCode_RepresentativeSampleData = 0xdc86,
|
||||
PtpObjectPropertyCode_Width = 0xdc87,
|
||||
PtpObjectPropertyCode_Height = 0xdc88,
|
||||
PtpObjectPropertyCode_Duration = 0xdc89,
|
||||
PtpObjectPropertyCode_Rating = 0xdc8a,
|
||||
PtpObjectPropertyCode_Track = 0xdc8b,
|
||||
PtpObjectPropertyCode_Genre = 0xdc8c,
|
||||
PtpObjectPropertyCode_Credits = 0xdc8d,
|
||||
PtpObjectPropertyCode_Lyrics = 0xdc8e,
|
||||
PtpObjectPropertyCode_SubscriptionContentId = 0xdc8f,
|
||||
PtpObjectPropertyCode_ProducedBy = 0xdc90,
|
||||
PtpObjectPropertyCode_UseCount = 0xdc91,
|
||||
PtpObjectPropertyCode_SkipCount = 0xdc92,
|
||||
PtpObjectPropertyCode_LastAccessed = 0xdc93,
|
||||
PtpObjectPropertyCode_ParentalRating = 0xdc94,
|
||||
PtpObjectPropertyCode_MetaGenre = 0xdc95,
|
||||
PtpObjectPropertyCode_Composer = 0xdc96,
|
||||
PtpObjectPropertyCode_EffectiveRating = 0xdc97,
|
||||
PtpObjectPropertyCode_Subtitle = 0xdc98,
|
||||
PtpObjectPropertyCode_OriginalReleaseDate = 0xdc99,
|
||||
PtpObjectPropertyCode_AlbumName = 0xdc9a,
|
||||
PtpObjectPropertyCode_AlbumArtist = 0xdc9b,
|
||||
PtpObjectPropertyCode_Mood = 0xdc9c,
|
||||
PtpObjectPropertyCode_DrmStatus = 0xdc9d,
|
||||
PtpObjectPropertyCode_SubDescription = 0xdc9e,
|
||||
PtpObjectPropertyCode_IsCropped = 0xdcd1,
|
||||
PtpObjectPropertyCode_IsColorCorrected = 0xdcd2,
|
||||
PtpObjectPropertyCode_ImageBitDepth = 0xdcd3,
|
||||
PtpObjectPropertyCode_Fnumber = 0xdcd4,
|
||||
PtpObjectPropertyCode_ExposureTime = 0xdcd5,
|
||||
PtpObjectPropertyCode_ExposureIndex = 0xdcd6,
|
||||
PtpObjectPropertyCode_DisplayName = 0xdce0,
|
||||
PtpObjectPropertyCode_BodyText = 0xdce1,
|
||||
PtpObjectPropertyCode_Subject = 0xdce2,
|
||||
PtpObjectPropertyCode_Priority = 0xdce3,
|
||||
PtpObjectPropertyCode_GivenName = 0xdd00,
|
||||
PtpObjectPropertyCode_MiddleNames = 0xdd01,
|
||||
PtpObjectPropertyCode_FamilyName = 0xdd02,
|
||||
PtpObjectPropertyCode_Prefix = 0xdd03,
|
||||
PtpObjectPropertyCode_Suffix = 0xdd04,
|
||||
PtpObjectPropertyCode_PhoneticGivenName = 0xdd05,
|
||||
PtpObjectPropertyCode_PhoneticFamilyName = 0xdd06,
|
||||
PtpObjectPropertyCode_EmailPrimary = 0xdd07,
|
||||
PtpObjectPropertyCode_EmailPersonal1 = 0xdd08,
|
||||
PtpObjectPropertyCode_EmailPersonal2 = 0xdd09,
|
||||
PtpObjectPropertyCode_EmailBusiness1 = 0xdd0a,
|
||||
PtpObjectPropertyCode_EmailBusiness2 = 0xdd0b,
|
||||
PtpObjectPropertyCode_EmailOthers = 0xdd0c,
|
||||
PtpObjectPropertyCode_PhoneNumberPrimary = 0xdd0d,
|
||||
PtpObjectPropertyCode_PhoneNumberPersonal = 0xdd0e,
|
||||
PtpObjectPropertyCode_PhoneNumberPersonal2 = 0xdd0f,
|
||||
PtpObjectPropertyCode_PhoneNumberBusiness = 0xdd10,
|
||||
PtpObjectPropertyCode_PhoneNumberBusiness2 = 0xdd11,
|
||||
PtpObjectPropertyCode_PhoneNumberMobile = 0xdd12,
|
||||
PtpObjectPropertyCode_PhoneNumberMobile2 = 0xdd13,
|
||||
PtpObjectPropertyCode_FaxNumberPrimary = 0xdd14,
|
||||
PtpObjectPropertyCode_FaxNumberPersonal = 0xdd15,
|
||||
PtpObjectPropertyCode_FaxNumberBusiness = 0xdd16,
|
||||
PtpObjectPropertyCode_PagerNumber = 0xdd17,
|
||||
PtpObjectPropertyCode_PhoneNumberOthers = 0xdd18,
|
||||
PtpObjectPropertyCode_PrimaryWebAddress = 0xdd19,
|
||||
PtpObjectPropertyCode_PersonalWebAddress = 0xdd1a,
|
||||
PtpObjectPropertyCode_BusinessWebAddress = 0xdd1b,
|
||||
PtpObjectPropertyCode_InstantMessengerAddress = 0xdd1c,
|
||||
PtpObjectPropertyCode_InstantMessengerAddress2 = 0xdd1d,
|
||||
PtpObjectPropertyCode_InstantMessengerAddress3 = 0xdd1e,
|
||||
PtpObjectPropertyCode_PostalAddressPersonalFull = 0xdd1f,
|
||||
PtpObjectPropertyCode_PostalAddressPersonalFullLine1 = 0xdd20,
|
||||
PtpObjectPropertyCode_PostalAddressPersonalFullLine2 = 0xdd21,
|
||||
PtpObjectPropertyCode_PostalAddressPersonalFullCity = 0xdd22,
|
||||
PtpObjectPropertyCode_PostalAddressPersonalFullRegion = 0xdd23,
|
||||
PtpObjectPropertyCode_PostalAddressPersonalFullPostalCode = 0xdd24,
|
||||
PtpObjectPropertyCode_PostalAddressPersonalFullCountry = 0xdd25,
|
||||
PtpObjectPropertyCode_PostalAddressBusinessFull = 0xdd26,
|
||||
PtpObjectPropertyCode_PostalAddressBusinessLine1 = 0xdd27,
|
||||
PtpObjectPropertyCode_PostalAddressBusinessLine2 = 0xdd28,
|
||||
PtpObjectPropertyCode_PostalAddressBusinessCity = 0xdd29,
|
||||
PtpObjectPropertyCode_PostalAddressBusinessRegion = 0xdd2a,
|
||||
PtpObjectPropertyCode_PostalAddressBusinessPostalCode = 0xdd2b,
|
||||
PtpObjectPropertyCode_PostalAddressBusinessCountry = 0xdd2c,
|
||||
PtpObjectPropertyCode_PostalAddressOtherFull = 0xdd2d,
|
||||
PtpObjectPropertyCode_PostalAddressOtherLine1 = 0xdd2e,
|
||||
PtpObjectPropertyCode_PostalAddressOtherLine2 = 0xdd2f,
|
||||
PtpObjectPropertyCode_PostalAddressOtherCity = 0xdd30,
|
||||
PtpObjectPropertyCode_PostalAddressOtherRegion = 0xdd31,
|
||||
PtpObjectPropertyCode_PostalAddressOtherPostalCode = 0xdd32,
|
||||
PtpObjectPropertyCode_PostalAddressOtherCountry = 0xdd33,
|
||||
PtpObjectPropertyCode_OrganizationName = 0xdd34,
|
||||
PtpObjectPropertyCode_PhoneticOrganizationName = 0xdd35,
|
||||
PtpObjectPropertyCode_Role = 0xdd36,
|
||||
PtpObjectPropertyCode_Birthdate = 0xdd37,
|
||||
PtpObjectPropertyCode_MessageTo = 0xdd40,
|
||||
PtpObjectPropertyCode_MessageCC = 0xdd41,
|
||||
PtpObjectPropertyCode_MessageBCC = 0xdd42,
|
||||
PtpObjectPropertyCode_MessageRead = 0xdd43,
|
||||
PtpObjectPropertyCode_MessageReceivedTime = 0xdd44,
|
||||
PtpObjectPropertyCode_MessageSender = 0xdd45,
|
||||
PtpObjectPropertyCode_ActivityBeginTime = 0xdd50,
|
||||
PtpObjectPropertyCode_ActivityEndTime = 0xdd51,
|
||||
PtpObjectPropertyCode_ActivityLocation = 0xdd52,
|
||||
PtpObjectPropertyCode_ActivityRequiredAttendees = 0xdd54,
|
||||
PtpObjectPropertyCode_ActivityOptionalAttendees = 0xdd55,
|
||||
PtpObjectPropertyCode_ActivityResources = 0xdd56,
|
||||
PtpObjectPropertyCode_ActivityAccepted = 0xdd57,
|
||||
PtpObjectPropertyCode_Owner = 0xdd5d,
|
||||
PtpObjectPropertyCode_Editor = 0xdd5e,
|
||||
PtpObjectPropertyCode_Webmaster = 0xdd5f,
|
||||
PtpObjectPropertyCode_UrlSource = 0xdd60,
|
||||
PtpObjectPropertyCode_UrlDestination = 0xdd61,
|
||||
PtpObjectPropertyCode_TimeBookmark = 0xdd62,
|
||||
PtpObjectPropertyCode_ObjectBookmark = 0xdd63,
|
||||
PtpObjectPropertyCode_ByteBookmark = 0xdd64,
|
||||
PtpObjectPropertyCode_LastBuildDate = 0xdd70,
|
||||
PtpObjectPropertyCode_TimetoLive = 0xdd71,
|
||||
PtpObjectPropertyCode_MediaGuid = 0xdd72,
|
||||
PtpObjectPropertyCode_TotalBitRate = 0xde91,
|
||||
PtpObjectPropertyCode_BitRateType = 0xde92,
|
||||
PtpObjectPropertyCode_SampleRate = 0xde93,
|
||||
PtpObjectPropertyCode_NumberOfChannels = 0xde94,
|
||||
PtpObjectPropertyCode_AudioBitDepth = 0xde95,
|
||||
PtpObjectPropertyCode_ScanDepth = 0xde97,
|
||||
PtpObjectPropertyCode_AudioWaveCodec = 0xde99,
|
||||
PtpObjectPropertyCode_AudioBitRate = 0xde9a,
|
||||
PtpObjectPropertyCode_VideoFourCcCodec = 0xde9b,
|
||||
PtpObjectPropertyCode_VideoBitRate = 0xde9c,
|
||||
PtpObjectPropertyCode_FramesPerThousandSeconds = 0xde9d,
|
||||
PtpObjectPropertyCode_KeyFrameDistance = 0xde9e,
|
||||
PtpObjectPropertyCode_BufferSize = 0xde9f,
|
||||
PtpObjectPropertyCode_EncodingQuality = 0xdea0,
|
||||
PtpObjectPropertyCode_EncodingProfile = 0xdea1,
|
||||
PtpObjectPropertyCode_BuyFlag = 0xd901,
|
||||
};
|
||||
|
||||
enum PtpDevicePropertyCode : u16 {
|
||||
PtpDevicePropertyCode_Undefined = 0x5000,
|
||||
PtpDevicePropertyCode_BatteryLevel = 0x5001,
|
||||
PtpDevicePropertyCode_FunctionalMode = 0x5002,
|
||||
PtpDevicePropertyCode_ImageSize = 0x5003,
|
||||
PtpDevicePropertyCode_CompressionSetting = 0x5004,
|
||||
PtpDevicePropertyCode_WhiteBalance = 0x5005,
|
||||
PtpDevicePropertyCode_RgbGain = 0x5006,
|
||||
PtpDevicePropertyCode_FNumber = 0x5007,
|
||||
PtpDevicePropertyCode_FocalLength = 0x5008,
|
||||
PtpDevicePropertyCode_FocusDistance = 0x5009,
|
||||
PtpDevicePropertyCode_FocusMode = 0x500a,
|
||||
PtpDevicePropertyCode_ExposureMeteringMode = 0x500b,
|
||||
PtpDevicePropertyCode_FlashMode = 0x500c,
|
||||
PtpDevicePropertyCode_ExposureTime = 0x500d,
|
||||
PtpDevicePropertyCode_ExposureProgramMode = 0x500e,
|
||||
PtpDevicePropertyCode_ExposureIndex = 0x500f,
|
||||
PtpDevicePropertyCode_ExposureBiasCompensation = 0x5010,
|
||||
PtpDevicePropertyCode_DateTime = 0x5011,
|
||||
PtpDevicePropertyCode_CaptureDelay = 0x5012,
|
||||
PtpDevicePropertyCode_StillCaptureMode = 0x5013,
|
||||
PtpDevicePropertyCode_Contrast = 0x5014,
|
||||
PtpDevicePropertyCode_Sharpness = 0x5015,
|
||||
PtpDevicePropertyCode_DigitalZoom = 0x5016,
|
||||
PtpDevicePropertyCode_EffectMode = 0x5017,
|
||||
PtpDevicePropertyCode_BurstNumber = 0x5018,
|
||||
PtpDevicePropertyCode_BurstInterval = 0x5019,
|
||||
PtpDevicePropertyCode_TimelapseNumber = 0x501a,
|
||||
PtpDevicePropertyCode_TimelapseInterval = 0x501b,
|
||||
PtpDevicePropertyCode_FocusMeteringMode = 0x501c,
|
||||
PtpDevicePropertyCode_UploadUrl = 0x501d,
|
||||
PtpDevicePropertyCode_Artist = 0x501e,
|
||||
PtpDevicePropertyCode_CopyrightInfo = 0x501f,
|
||||
PtpDevicePropertyCode_SupportedStreams = 0x5020,
|
||||
PtpDevicePropertyCode_EnabledStreams = 0x5021,
|
||||
PtpDevicePropertyCode_VideoFormat = 0x5022,
|
||||
PtpDevicePropertyCode_VideoResolution = 0x5023,
|
||||
PtpDevicePropertyCode_VideoQuality = 0x5024,
|
||||
PtpDevicePropertyCode_VideoFrameRate = 0x5025,
|
||||
PtpDevicePropertyCode_VideoContrast = 0x5026,
|
||||
PtpDevicePropertyCode_VideoBrightness = 0x5027,
|
||||
PtpDevicePropertyCode_AudioFormat = 0x5028,
|
||||
PtpDevicePropertyCode_AudioBitrate = 0x5029,
|
||||
PtpDevicePropertyCode_AudioSamplingRate = 0x502a,
|
||||
PtpDevicePropertyCode_AudioBitPerSample = 0x502b,
|
||||
PtpDevicePropertyCode_AudioVolume = 0x502c,
|
||||
};
|
||||
|
||||
enum PtpObjectFormatCode : u16 {
|
||||
PtpObjectFormatCode_Undefined = 0x3000,
|
||||
PtpObjectFormatCode_Association = 0x3001,
|
||||
PtpObjectFormatCode_Defined = 0x3800,
|
||||
PtpObjectFormatCode_MtpMediaCard = 0xb211,
|
||||
};
|
||||
|
||||
enum PtpAssociationType : u16 {
|
||||
PtpAssociationType_Undefined = 0x0000,
|
||||
PtpAssociationType_GenericFolder = 0x0001,
|
||||
};
|
||||
|
||||
enum PtpGetObjectHandles : u32 {
|
||||
PtpGetObjectHandles_AllFormats = 0x00000000,
|
||||
PtpGetObjectHandles_AllAssocs = 0x00000000,
|
||||
PtpGetObjectHandles_AllStorage = 0xffffffff,
|
||||
PtpGetObjectHandles_RootParent = 0xffffffff,
|
||||
};
|
||||
|
||||
enum PtpStorageType : u16 {
|
||||
PtpStorageType_Undefined = 0x0000,
|
||||
PtpStorageType_FixedRom = 0x0001,
|
||||
PtpStorageType_RemovableRom = 0x0002,
|
||||
PtpStorageType_FixedRam = 0x0003,
|
||||
PtpStorageType_RemovableRam = 0x0004,
|
||||
};
|
||||
|
||||
enum PtpFilesystemType : u16 {
|
||||
PtpFilesystemType_Undefined = 0x0000,
|
||||
PtpFilesystemType_GenericFlat = 0x0001,
|
||||
PtpFilesystemType_GenericHierarchical = 0x0002,
|
||||
PtpFilesystemType_Dcf = 0x0003,
|
||||
};
|
||||
|
||||
enum PtpAccessCapability : u16 {
|
||||
PtpAccessCapability_ReadWrite = 0x0000,
|
||||
PtpAccessCapability_ReadOnly = 0x0001,
|
||||
PtpAccessCapability_ReadOnlyWithObjectDeletion = 0x0002,
|
||||
};
|
||||
|
||||
enum PtpProtectionStatus : u16 {
|
||||
PtpProtectionStatus_NoProtection = 0x0000,
|
||||
PtpProtectionStatus_ReadOnly = 0x0001,
|
||||
PtpProtectionStatus_MtpReadOnlyData = 0x8002,
|
||||
PtpProtectionStatus_MtpNonTransferableData = 0x8003,
|
||||
};
|
||||
|
||||
enum PtpThumbFormat : u16 {
|
||||
PtpThumbFormat_Undefined = 0x0000,
|
||||
};
|
||||
|
||||
struct PtpUsbBulkContainer {
|
||||
u32 length;
|
||||
u16 type;
|
||||
u16 code;
|
||||
u32 trans_id;
|
||||
};
|
||||
static_assert(sizeof(PtpUsbBulkContainer) == PtpUsbBulkHeaderLength);
|
||||
|
||||
struct PtpNewObjectInfo {
|
||||
u32 storage_id;
|
||||
u32 parent_object_id;
|
||||
u32 object_id;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* 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 PtpDataBuilder final {
|
||||
private:
|
||||
AsyncUsbServer *m_server;
|
||||
u32 m_transmitted_size;
|
||||
u32 m_offset;
|
||||
u8 *m_data;
|
||||
bool m_disabled;
|
||||
private:
|
||||
Result Flush() {
|
||||
ON_SCOPE_EXIT {
|
||||
m_transmitted_size += m_offset;
|
||||
m_offset = 0;
|
||||
};
|
||||
|
||||
/* If we're disabled, we have nothing to do. */
|
||||
R_SUCCEED_IF(m_disabled);
|
||||
|
||||
/* Otherwise, we should write our buffered data. */
|
||||
R_RETURN(m_server->WritePacket(m_data, m_offset));
|
||||
}
|
||||
public:
|
||||
constexpr explicit PtpDataBuilder(void *data, AsyncUsbServer *server) : m_server(server), m_transmitted_size(), m_offset(), m_data(static_cast<u8 *>(data)), m_disabled() { /* ... */ }
|
||||
|
||||
Result Commit() {
|
||||
if (m_offset > 0) {
|
||||
/* If there is remaining data left to write, write it now. */
|
||||
R_TRY(this->Flush());
|
||||
}
|
||||
|
||||
if (util::IsAligned(m_transmitted_size, PtpUsbBulkHighSpeedMaxPacketLength)) {
|
||||
/* If the transmission size was a multiple of wMaxPacketSize, send a zero length packet. */
|
||||
R_TRY(this->Flush());
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result AddBuffer(const u8 *buffer, u32 count) {
|
||||
while (count > 0) {
|
||||
/* Calculate how many bytes we can write now. */
|
||||
const u32 write_size = std::min<u32>(count, haze::UsbBulkPacketBufferSize - m_offset);
|
||||
|
||||
/* Write this number of bytes. */
|
||||
std::memcpy(m_data + m_offset, buffer, write_size);
|
||||
m_offset += write_size;
|
||||
buffer += write_size;
|
||||
count -= write_size;
|
||||
|
||||
/* If our buffer is full, flush it. */
|
||||
if (m_offset == haze::UsbBulkPacketBufferSize) {
|
||||
R_TRY(this->Flush());
|
||||
}
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Result Add(T value) {
|
||||
u8 bytes[sizeof(T)];
|
||||
|
||||
std::memcpy(bytes, std::addressof(value), sizeof(T));
|
||||
|
||||
R_RETURN(this->AddBuffer(bytes, sizeof(T)));
|
||||
}
|
||||
|
||||
Result AddDataHeader(PtpUsbBulkContainer &request, u32 data_size) {
|
||||
R_TRY(this->Add<u32>(PtpUsbBulkHeaderLength + data_size));
|
||||
R_TRY(this->Add<u16>(PtpUsbBulkContainerType_Data));
|
||||
R_TRY(this->Add<u16>(request.code));
|
||||
R_TRY(this->Add<u32>(request.trans_id));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result AddResponseHeader(PtpUsbBulkContainer &request, PtpResponseCode code, u32 params_size) {
|
||||
R_TRY(this->Add<u32>(PtpUsbBulkHeaderLength + params_size));
|
||||
R_TRY(this->Add<u16>(PtpUsbBulkContainerType_Response));
|
||||
R_TRY(this->Add<u16>(code));
|
||||
R_TRY(this->Add<u32>(request.trans_id));
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
Result WriteVariableLengthData(PtpUsbBulkContainer &request, F &&func) {
|
||||
HAZE_ASSERT(m_offset == 0 && m_transmitted_size == 0);
|
||||
|
||||
/* Declare how many bytes the data will require to write. */
|
||||
u32 data_size = 0;
|
||||
{
|
||||
/* Temporarily disable writing to calculate the size.*/
|
||||
m_disabled = true;
|
||||
|
||||
ON_SCOPE_EXIT {
|
||||
/* Report how many bytes were required. */
|
||||
data_size = m_transmitted_size;
|
||||
|
||||
/* On exit, enable writing and reset sizes. */
|
||||
m_transmitted_size = 0;
|
||||
m_disabled = false;
|
||||
m_offset = 0;
|
||||
};
|
||||
|
||||
R_TRY(func());
|
||||
R_TRY(this->Commit());
|
||||
}
|
||||
|
||||
/* Actually copy and write the data. */
|
||||
R_TRY(this->AddDataHeader(request, data_size));
|
||||
R_TRY(func());
|
||||
R_TRY(this->Commit());
|
||||
|
||||
/* We succeeded. */
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Result AddString(const T *str) {
|
||||
/* Use one less than the maximum string length for maximum length with null terminator. */
|
||||
const u8 len = static_cast<u8>(std::min<s32>(util::Strlen(str), PtpStringMaxLength - 1));
|
||||
|
||||
if (len > 0) {
|
||||
/* Length is padded by null terminator for non-empty strings. */
|
||||
R_TRY(this->Add<u8>(len + 1));
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
R_TRY(this->Add<u16>(str[i]));
|
||||
}
|
||||
|
||||
R_TRY(this->Add<u16>(0));
|
||||
} else {
|
||||
R_TRY(this->Add<u8>(len));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Result AddArray(const T *arr, u32 count) {
|
||||
R_TRY(this->Add<u32>(count));
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
R_TRY(this->Add<T>(arr[i]));
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* 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/common.hpp>
|
||||
#include <haze/ptp_object_heap.hpp>
|
||||
#include <vapours/util.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
struct PtpObject {
|
||||
public:
|
||||
util::IntrusiveRedBlackTreeNode m_name_node;
|
||||
util::IntrusiveRedBlackTreeNode m_object_id_node;
|
||||
u32 m_parent_id;
|
||||
u32 m_object_id;
|
||||
char m_name[];
|
||||
public:
|
||||
const char *GetName() const { return m_name; }
|
||||
u32 GetParentId() const { return m_parent_id; }
|
||||
u32 GetObjectId() const { return m_object_id; }
|
||||
public:
|
||||
bool GetIsRegistered() const { return m_object_id != 0; }
|
||||
void Register(u32 object_id) { m_object_id = object_id; }
|
||||
void Unregister() { m_object_id = 0; }
|
||||
public:
|
||||
struct NameComparator {
|
||||
struct RedBlackKeyType {
|
||||
const char *m_name;
|
||||
|
||||
constexpr RedBlackKeyType(const char *name) : m_name(name) { /* ... */ }
|
||||
|
||||
constexpr const char *GetName() const {
|
||||
return m_name;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> requires (std::same_as<T, PtpObject> || std::same_as<T, RedBlackKeyType>)
|
||||
static constexpr int Compare(const T &lhs, const PtpObject &rhs) {
|
||||
/* All SD card filesystems supported by fs are case-insensitive and case-preserving. */
|
||||
/* Account for that in collation here. */
|
||||
return strcasecmp(lhs.GetName(), rhs.GetName());
|
||||
}
|
||||
};
|
||||
|
||||
struct ObjectIdComparator {
|
||||
struct RedBlackKeyType {
|
||||
u32 m_object_id;
|
||||
|
||||
constexpr RedBlackKeyType(u32 object_id) : m_object_id(object_id) { /* ... */ }
|
||||
|
||||
constexpr u32 GetObjectId() const {
|
||||
return m_object_id;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> requires (std::same_as<T, PtpObject> || std::same_as<T, RedBlackKeyType>)
|
||||
static constexpr int Compare(const T &lhs, const PtpObject &rhs) {
|
||||
return lhs.GetObjectId() - rhs.GetObjectId();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class PtpObjectDatabase {
|
||||
private:
|
||||
using ObjectNameTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&PtpObject::m_name_node>;
|
||||
using ObjectNameTree = ObjectNameTreeTraits::TreeType<PtpObject::NameComparator>;
|
||||
|
||||
using ObjectIdTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&PtpObject::m_object_id_node>;
|
||||
using ObjectIdTree = ObjectIdTreeTraits::TreeType<PtpObject::ObjectIdComparator>;
|
||||
|
||||
PtpObjectHeap *m_object_heap;
|
||||
ObjectNameTree m_name_tree;
|
||||
ObjectIdTree m_object_id_tree;
|
||||
u32 m_next_object_id;
|
||||
public:
|
||||
constexpr explicit PtpObjectDatabase() : m_object_heap(), m_name_tree(), m_object_id_tree(), m_next_object_id() { /* ... */ }
|
||||
|
||||
void Initialize(PtpObjectHeap *object_heap);
|
||||
void Finalize();
|
||||
public:
|
||||
/* Object database API. */
|
||||
Result CreateOrFindObject(const char *parent_name, const char *name, u32 parent_id, PtpObject **out_object);
|
||||
void RegisterObject(PtpObject *object, u32 desired_id = 0);
|
||||
void UnregisterObject(PtpObject *object);
|
||||
void DeleteObject(PtpObject *obj);
|
||||
|
||||
Result CreateAndRegisterObjectId(const char *parent_name, const char *name, u32 parent_id, u32 *out_object_id);
|
||||
public:
|
||||
PtpObject *GetObjectById(u32 object_id);
|
||||
PtpObject *GetObjectByName(const char *name);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* 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/common.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
/* This simple linear allocator implementation allows us to rapidly reclaim the entire object graph. */
|
||||
/* This is critical for maintaining interactivity when a session is closed. */
|
||||
class PtpObjectHeap {
|
||||
private:
|
||||
static constexpr size_t NumHeapBlocks = 2;
|
||||
private:
|
||||
void *m_heap_blocks[NumHeapBlocks];
|
||||
void *m_next_address;
|
||||
u32 m_heap_block_size;
|
||||
u32 m_current_heap_block;
|
||||
public:
|
||||
constexpr explicit PtpObjectHeap() : m_heap_blocks(), m_next_address(), m_heap_block_size(), m_current_heap_block() { /* ... */ }
|
||||
|
||||
void Initialize();
|
||||
void Finalize();
|
||||
public:
|
||||
constexpr size_t GetTotalSize() const {
|
||||
return m_heap_block_size * NumHeapBlocks;
|
||||
}
|
||||
|
||||
constexpr size_t GetUsedSize() const {
|
||||
return (m_heap_block_size * m_current_heap_block) + this->GetNextAddress() - this->GetFirstAddress();
|
||||
}
|
||||
private:
|
||||
constexpr u8 *GetNextAddress() const { return static_cast<u8 *>(m_next_address); }
|
||||
constexpr u8 *GetFirstAddress() const { return static_cast<u8 *>(m_heap_blocks[m_current_heap_block]); }
|
||||
|
||||
constexpr u8 *GetCurrentBlockEnd() const {
|
||||
return this->GetFirstAddress() + m_heap_block_size;
|
||||
}
|
||||
|
||||
constexpr bool AllocationIsPossible(size_t n) const {
|
||||
return n <= m_heap_block_size;
|
||||
}
|
||||
|
||||
constexpr bool AllocationIsSatisfyable(size_t n) const {
|
||||
/* Check for overflow. */
|
||||
if (!util::CanAddWithoutOverflow(reinterpret_cast<uintptr_t>(this->GetNextAddress()), n)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if we would exceed the size of the current block. */
|
||||
if (this->GetNextAddress() + n > this->GetCurrentBlockEnd()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool AdvanceToNextBlock() {
|
||||
if (m_current_heap_block < NumHeapBlocks - 1) {
|
||||
m_next_address = m_heap_blocks[++m_current_heap_block];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr void *AllocateFromCurrentBlock(size_t n) {
|
||||
void *result = this->GetNextAddress();
|
||||
|
||||
m_next_address = this->GetNextAddress() + n;
|
||||
|
||||
return result;
|
||||
}
|
||||
public:
|
||||
template <typename T = void>
|
||||
constexpr T *Allocate(size_t n) {
|
||||
/* Check for overflow in alignment. */
|
||||
if (!util::CanAddWithoutOverflow(n, alignof(u64) - 1)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Align the amount to satisfy allocation for u64. */
|
||||
n = util::AlignUp(n, alignof(u64));
|
||||
|
||||
/* Check if the allocation is possible. */
|
||||
if (!this->AllocationIsPossible(n)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* If the allocation is not satisfyable now, we might be able to satisfy it on the next block. */
|
||||
/* However, if the next block would be empty, we won't be able to satisfy the request. */
|
||||
if (!this->AllocationIsSatisfyable(n) && !this->AdvanceToNextBlock()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Allocate the memory. */
|
||||
return static_cast<T *>(this->AllocateFromCurrentBlock(n));
|
||||
}
|
||||
|
||||
constexpr void Deallocate(void *p, size_t n) {
|
||||
/* Check for overflow in alignment. */
|
||||
if (!util::CanAddWithoutOverflow(n, alignof(u64) - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Align the amount to satisfy allocation for u64. */
|
||||
n = util::AlignUp(n, alignof(u64));
|
||||
|
||||
/* If the pointer was the last allocation, return the memory to the heap. */
|
||||
if (static_cast<u8 *>(p) + n == this->GetNextAddress()) {
|
||||
m_next_address = this->GetNextAddress() - n;
|
||||
}
|
||||
|
||||
/* Otherwise, do nothing. */
|
||||
/* ... */
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* 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/common.hpp>
|
||||
#include <haze/async_usb_server.hpp>
|
||||
#include <haze/ptp_object_heap.hpp>
|
||||
#include <haze/ptp_object_database.hpp>
|
||||
#include <haze/ptp_responder_types.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
class PtpDataParser;
|
||||
|
||||
class PtpResponder final {
|
||||
private:
|
||||
AsyncUsbServer m_usb_server;
|
||||
FileSystemProxy m_fs;
|
||||
PtpUsbBulkContainer m_request_header;
|
||||
PtpObjectHeap *m_object_heap;
|
||||
PtpBuffers* m_buffers;
|
||||
u32 m_send_object_id;
|
||||
bool m_session_open;
|
||||
|
||||
PtpObjectDatabase m_object_database;
|
||||
public:
|
||||
constexpr explicit PtpResponder() : m_usb_server(), m_fs(), m_request_header(), m_object_heap(), m_buffers(), m_send_object_id(), m_session_open(), m_object_database() { /* ... */ }
|
||||
|
||||
Result Initialize(EventReactor *reactor, PtpObjectHeap *object_heap);
|
||||
void Finalize();
|
||||
public:
|
||||
Result LoopProcess();
|
||||
private:
|
||||
/* Request handling. */
|
||||
Result HandleRequest();
|
||||
Result HandleRequestImpl();
|
||||
Result HandleCommandRequest(PtpDataParser &dp);
|
||||
void ForceCloseSession();
|
||||
|
||||
Result WriteResponse(PtpResponseCode code, const void* data, size_t size);
|
||||
Result WriteResponse(PtpResponseCode code);
|
||||
|
||||
template <typename Data> requires (util::is_pod<Data>::value)
|
||||
Result WriteResponse(PtpResponseCode code, const Data &data) {
|
||||
R_RETURN(this->WriteResponse(code, std::addressof(data), sizeof(data)));
|
||||
}
|
||||
|
||||
/* PTP operations. */
|
||||
Result GetDeviceInfo(PtpDataParser &dp);
|
||||
Result OpenSession(PtpDataParser &dp);
|
||||
Result CloseSession(PtpDataParser &dp);
|
||||
Result GetStorageIds(PtpDataParser &dp);
|
||||
Result GetStorageInfo(PtpDataParser &dp);
|
||||
Result GetObjectHandles(PtpDataParser &dp);
|
||||
Result GetObjectInfo(PtpDataParser &dp);
|
||||
Result GetObject(PtpDataParser &dp);
|
||||
Result SendObjectInfo(PtpDataParser &dp);
|
||||
Result SendObject(PtpDataParser &dp);
|
||||
Result DeleteObject(PtpDataParser &dp);
|
||||
|
||||
/* Android operations. */
|
||||
Result GetPartialObject64(PtpDataParser &dp);
|
||||
Result SendPartialObject(PtpDataParser &dp);
|
||||
Result TruncateObject(PtpDataParser &dp);
|
||||
Result BeginEditObject(PtpDataParser &dp);
|
||||
Result EndEditObject(PtpDataParser &dp);
|
||||
|
||||
/* MTP operations. */
|
||||
Result GetObjectPropsSupported(PtpDataParser &dp);
|
||||
Result GetObjectPropDesc(PtpDataParser &dp);
|
||||
Result GetObjectPropValue(PtpDataParser &dp);
|
||||
Result SetObjectPropValue(PtpDataParser &dp);
|
||||
Result GetObjectPropList(PtpDataParser &dp);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* 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.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
constexpr UsbCommsInterfaceInfo MtpInterfaceInfo = {
|
||||
.bInterfaceClass = 0x06,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01,
|
||||
};
|
||||
|
||||
/* This is a VID:PID recognized by libmtp. */
|
||||
constexpr u16 SwitchMtpIdVendor = 0x057e;
|
||||
constexpr u16 SwitchMtpIdProduct = 0x201d;
|
||||
|
||||
/* Constants used for MTP GetDeviceInfo response. */
|
||||
constexpr u16 MtpStandardVersion = 100;
|
||||
constexpr u32 MtpVendorExtensionId = 6;
|
||||
constexpr auto MtpVendorExtensionDesc = "microsoft.com: 1.0;";
|
||||
constexpr u16 MtpFunctionalModeDefault = 0;
|
||||
constexpr auto MtpDeviceManufacturer = "Nintendo";
|
||||
constexpr auto MtpDeviceModel = "Nintendo Switch";
|
||||
|
||||
enum StorageId : u32 {
|
||||
StorageId_SdmcFs = 0xffffffffu - 1,
|
||||
};
|
||||
|
||||
constexpr PtpOperationCode SupportedOperationCodes[] = {
|
||||
PtpOperationCode_GetDeviceInfo,
|
||||
PtpOperationCode_OpenSession,
|
||||
PtpOperationCode_CloseSession,
|
||||
PtpOperationCode_GetStorageIds,
|
||||
PtpOperationCode_GetStorageInfo,
|
||||
PtpOperationCode_GetObjectHandles,
|
||||
PtpOperationCode_GetObjectInfo,
|
||||
PtpOperationCode_GetObject,
|
||||
PtpOperationCode_SendObjectInfo,
|
||||
PtpOperationCode_SendObject,
|
||||
PtpOperationCode_DeleteObject,
|
||||
PtpOperationCode_MtpGetObjectPropsSupported,
|
||||
PtpOperationCode_MtpGetObjectPropDesc,
|
||||
PtpOperationCode_MtpGetObjectPropValue,
|
||||
PtpOperationCode_MtpSetObjectPropValue,
|
||||
PtpOperationCode_MtpGetObjPropList,
|
||||
PtpOperationCode_AndroidGetPartialObject64,
|
||||
PtpOperationCode_AndroidSendPartialObject,
|
||||
PtpOperationCode_AndroidTruncateObject,
|
||||
PtpOperationCode_AndroidBeginEditObject,
|
||||
PtpOperationCode_AndroidEndEditObject,
|
||||
};
|
||||
|
||||
constexpr const PtpEventCode SupportedEventCodes[] = { /* ... */ };
|
||||
constexpr const PtpDevicePropertyCode SupportedDeviceProperties[] = { /* ... */ };
|
||||
constexpr const PtpObjectFormatCode SupportedCaptureFormats[] = { /* ... */ };
|
||||
|
||||
constexpr const PtpObjectFormatCode SupportedPlaybackFormats[] = {
|
||||
PtpObjectFormatCode_Undefined,
|
||||
PtpObjectFormatCode_Association,
|
||||
};
|
||||
|
||||
constexpr const PtpObjectPropertyCode SupportedObjectProperties[] = {
|
||||
PtpObjectPropertyCode_StorageId,
|
||||
PtpObjectPropertyCode_ObjectFormat,
|
||||
PtpObjectPropertyCode_ObjectSize,
|
||||
PtpObjectPropertyCode_ObjectFileName,
|
||||
PtpObjectPropertyCode_ParentObject,
|
||||
PtpObjectPropertyCode_PersistentUniqueObjectIdentifier,
|
||||
};
|
||||
|
||||
constexpr bool IsSupportedObjectPropertyCode(PtpObjectPropertyCode c) {
|
||||
for (size_t i = 0; i < util::size(SupportedObjectProperties); i++) {
|
||||
if (SupportedObjectProperties[i] == c) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr const StorageId SupportedStorageIds[] = {
|
||||
StorageId_SdmcFs,
|
||||
};
|
||||
|
||||
struct PtpStorageInfo {
|
||||
PtpStorageType storage_type;
|
||||
PtpFilesystemType filesystem_type;
|
||||
PtpAccessCapability access_capability;
|
||||
u64 max_capacity;
|
||||
u64 free_space_in_bytes;
|
||||
u32 free_space_in_images;
|
||||
const char *storage_description;
|
||||
const char *volume_label;
|
||||
};
|
||||
|
||||
constexpr PtpStorageInfo DefaultStorageInfo = {
|
||||
.storage_type = PtpStorageType_FixedRam,
|
||||
.filesystem_type = PtpFilesystemType_GenericHierarchical,
|
||||
.access_capability = PtpAccessCapability_ReadWrite,
|
||||
.max_capacity = 0,
|
||||
.free_space_in_bytes = 0,
|
||||
.free_space_in_images = 0,
|
||||
.storage_description = "",
|
||||
.volume_label = "",
|
||||
};
|
||||
|
||||
struct PtpObjectInfo {
|
||||
StorageId storage_id;
|
||||
PtpObjectFormatCode object_format;
|
||||
PtpProtectionStatus protection_status;
|
||||
u32 object_compressed_size;
|
||||
u16 thumb_format;
|
||||
u32 thumb_compressed_size;
|
||||
u32 thumb_width;
|
||||
u32 thumb_height;
|
||||
u32 image_width;
|
||||
u32 image_height;
|
||||
u32 image_depth;
|
||||
u32 parent_object;
|
||||
PtpAssociationType association_type;
|
||||
u32 association_desc;
|
||||
u32 sequence_number;
|
||||
const char *filename;
|
||||
const char *capture_date;
|
||||
const char *modification_date;
|
||||
const char *keywords;
|
||||
};
|
||||
|
||||
constexpr PtpObjectInfo DefaultObjectInfo = {
|
||||
.storage_id = StorageId_SdmcFs,
|
||||
.object_format = {},
|
||||
.protection_status = PtpProtectionStatus_NoProtection,
|
||||
.object_compressed_size = 0,
|
||||
.thumb_format = 0,
|
||||
.thumb_compressed_size = 0,
|
||||
.thumb_width = 0,
|
||||
.thumb_height = 0,
|
||||
.image_width = 0,
|
||||
.image_height = 0,
|
||||
.image_depth = 0,
|
||||
.parent_object = PtpGetObjectHandles_RootParent,
|
||||
.association_type = PtpAssociationType_Undefined,
|
||||
.association_desc = 0,
|
||||
.sequence_number = 0,
|
||||
.filename = nullptr,
|
||||
.capture_date = "",
|
||||
.modification_date = "",
|
||||
.keywords = "",
|
||||
};
|
||||
|
||||
constexpr u32 UsbBulkPacketBufferSize = 1_MB;
|
||||
constexpr u64 FsBufferSize = UsbBulkPacketBufferSize;
|
||||
constexpr s64 DirectoryReadSize = 32;
|
||||
|
||||
struct PtpBuffers {
|
||||
char filename_string_buffer[PtpStringMaxLength + 1];
|
||||
char capture_date_string_buffer[PtpStringMaxLength + 1];
|
||||
char modification_date_string_buffer[PtpStringMaxLength + 1];
|
||||
char keywords_string_buffer[PtpStringMaxLength + 1];
|
||||
|
||||
FsDirectoryEntry file_system_entry_buffer[DirectoryReadSize];
|
||||
u8 file_system_data_buffer[FsBufferSize];
|
||||
|
||||
alignas(4_KB) u8 usb_bulk_write_buffer[UsbBulkPacketBufferSize];
|
||||
alignas(4_KB) u8 usb_bulk_read_buffer[UsbBulkPacketBufferSize];
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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 <vapours/results.hpp>
|
||||
|
||||
/* NOTE: These results are all custom, and not official. */
|
||||
R_DEFINE_NAMESPACE_RESULT_MODULE(haze, 420);
|
||||
|
||||
namespace haze {
|
||||
|
||||
R_DEFINE_ERROR_RESULT(RegistrationFailed, 1);
|
||||
R_DEFINE_ERROR_RESULT(NotConfigured, 2);
|
||||
R_DEFINE_ERROR_RESULT(TransferFailed, 3);
|
||||
R_DEFINE_ERROR_RESULT(StopRequested, 4);
|
||||
R_DEFINE_ERROR_RESULT(FocusLost, 5);
|
||||
R_DEFINE_ERROR_RESULT(EndOfTransmission, 6);
|
||||
R_DEFINE_ERROR_RESULT(UnknownPacketType, 7);
|
||||
R_DEFINE_ERROR_RESULT(SessionNotOpen, 8);
|
||||
R_DEFINE_ERROR_RESULT(OutOfMemory, 9);
|
||||
R_DEFINE_ERROR_RESULT(InvalidObjectId, 10);
|
||||
R_DEFINE_ERROR_RESULT(InvalidStorageId, 11);
|
||||
R_DEFINE_ERROR_RESULT(OperationNotSupported, 12);
|
||||
R_DEFINE_ERROR_RESULT(UnknownRequestType, 13);
|
||||
R_DEFINE_ERROR_RESULT(UnknownPropertyCode, 14);
|
||||
R_DEFINE_ERROR_RESULT(InvalidPropertyValue, 15);
|
||||
R_DEFINE_ERROR_RESULT(InvalidArgument, 16);
|
||||
R_DEFINE_ERROR_RESULT(GroupSpecified, 17);
|
||||
R_DEFINE_ERROR_RESULT(DepthSpecified, 18);
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* 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/common.hpp>
|
||||
|
||||
namespace haze {
|
||||
|
||||
enum UsbSessionEndpoint {
|
||||
UsbSessionEndpoint_Read = 0,
|
||||
UsbSessionEndpoint_Write = 1,
|
||||
UsbSessionEndpoint_Interrupt = 2,
|
||||
UsbSessionEndpoint_Count = 3,
|
||||
};
|
||||
|
||||
class UsbSession {
|
||||
private:
|
||||
UsbDsInterface *m_interface;
|
||||
UsbDsEndpoint *m_endpoints[UsbSessionEndpoint_Count];
|
||||
private:
|
||||
Result Initialize1x(const UsbCommsInterfaceInfo *info);
|
||||
Result Initialize5x(const UsbCommsInterfaceInfo *info);
|
||||
public:
|
||||
constexpr explicit UsbSession() : m_interface(), m_endpoints() { /* ... */ }
|
||||
|
||||
Result Initialize(const UsbCommsInterfaceInfo *info, u16 id_vendor, u16 id_product);
|
||||
void Finalize();
|
||||
|
||||
bool GetConfigured() const;
|
||||
Event *GetCompletionEvent(UsbSessionEndpoint ep) const;
|
||||
Result TransferAsync(UsbSessionEndpoint ep, void *buffer, u32 size, u32 *out_urb_id);
|
||||
Result GetTransferResult(UsbSessionEndpoint ep, u32 urb_id, u32 *out_transferred_size);
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user