diff --git a/include/mocha/commands.h b/include/mocha/commands.h
index ed6e275..37eb1d0 100644
--- a/include/mocha/commands.h
+++ b/include/mocha/commands.h
@@ -12,6 +12,9 @@ extern "C" {
#define IPC_CUSTOM_START_USB_LOGGING 0xFA
#define IPC_CUSTOM_COPY_ENVIRONMENT_PATH 0xF9
#define IPC_CUSTOM_GET_MOCHA_API_VERSION 0xF8
+#define IPC_CUSTOM_START_TCP_LOGGING 0xF7
+#define IPC_CUSTOM_STOP_TCP_LOGGING 0xF6
+#define IPC_CUSTOM_START_IOPSHELL_SERVER 0xF5
typedef enum LoadRPXTargetEnum {
LOAD_RPX_TARGET_SD_CARD = 0,
diff --git a/include/mocha/mocha.h b/include/mocha/mocha.h
index da99d2e..3dd063d 100644
--- a/include/mocha/mocha.h
+++ b/include/mocha/mocha.h
@@ -153,10 +153,39 @@ MochaUtilsStatus Mocha_GetEnvironmentPath(char *environmentPathBuffer, uint32_t
* @return MOCHA_RESULT_SUCCESS: Logging via USB starts or has already been started
* MOCHA_RESULT_LIB_UNINITIALIZED: Library was not initialized. Call Mocha_InitLibrary() before using this function.
* MOCHA_RESULT_UNSUPPORTED_COMMAND: Command not supported by the currently loaded mocha version.
- * MOCHA_RESULT_UNKNOWN_ERROR: Failed to retrieve the environment path.
+ * MOCHA_RESULT_UNKNOWN_ERROR: Failed to start the usb logging.
*/
MochaUtilsStatus Mocha_StartUSBLogging(bool notSkipExistingLogs);
+/**
+ * Enables logging via TCP via OSReport and friends. See the tcp script for receiving logs
+ * @param limitToIp If set to true, only connection to the ip specified in "ipFilter" will be accepted
+ * @param ipFilter Defined the ip address the console will connect for usb logs
+ * @return MOCHA_RESULT_SUCCESS: Logging via TCP starts or has already been started
+ * MOCHA_RESULT_LIB_UNINITIALIZED: Library was not initialized. Call Mocha_InitLibrary() before using this function.
+ * MOCHA_RESULT_UNSUPPORTED_COMMAND: Command not supported by the currently loaded mocha version.
+ * MOCHA_RESULT_UNKNOWN_ERROR: Failed to start
+ */
+MochaUtilsStatus Mocha_StartTCPSyslogLogging(bool limitToIp, uint32_t ipFilter);
+
+/**
+ * Disabled logging via TCP.
+ * @return MOCHA_RESULT_SUCCESS: Logging via stops
+ * MOCHA_RESULT_LIB_UNINITIALIZED: Library was not initialized. Call Mocha_InitLibrary() before using this function.
+ * MOCHA_RESULT_UNSUPPORTED_COMMAND: Command not supported by the currently loaded mocha version.
+ * MOCHA_RESULT_UNKNOWN_ERROR: Failed to stop
+ */
+MochaUtilsStatus Mocha_StopTCPSyslogLogging();
+
+/**
+ * Starts the iopshell server.
+ * @return MOCHA_RESULT_SUCCESS: IOPShell server starts or has already been started
+ * MOCHA_RESULT_LIB_UNINITIALIZED: Library was not initialized. Call Mocha_InitLibrary() before using this function.
+ * MOCHA_RESULT_UNSUPPORTED_COMMAND: Command not supported by the currently loaded mocha version.
+ * MOCHA_RESULT_UNKNOWN_ERROR: Failed to start
+ */
+MochaUtilsStatus Mocha_StartIOPShellServer();
+
/**
* Gives a FSClient full permissions.
* Requires Mocha API Version: 1
diff --git a/source/utils.cpp b/source/utils.cpp
index ea1d3fe..8112ff1 100644
--- a/source/utils.cpp
+++ b/source/utils.cpp
@@ -23,6 +23,27 @@ uint32_t mochaApiVersion = 0;
#define IOCTL_KERN_WRITE32 0x07
#define IOCTL_READ_OTP 0x08
+namespace {
+ MochaUtilsStatus doSimpleCustomIPCCommand(const uint32_t cmd, const uint32_t arg1 = 0, const uint32_t arg2 = 0) {
+ MochaUtilsStatus res = MOCHA_RESULT_UNKNOWN_ERROR;
+ int mcpFd = IOS_Open("/dev/mcp", static_cast(0));
+ if (mcpFd >= 0) {
+ ALIGN_0x40 uint32_t io_buffer[0x40 / 4];
+ io_buffer[0] = cmd;
+ io_buffer[1] = arg1;
+ io_buffer[2] = arg2;
+
+ if (IOS_Ioctl(mcpFd, 100, io_buffer, 0xC, io_buffer, 0x4) == IOS_ERROR_OK) {
+ res = MOCHA_RESULT_SUCCESS;
+ }
+
+ IOS_Close(mcpFd);
+ }
+ return res;
+ }
+} // namespace
+
+
const char *Mocha_GetStatusStr(MochaUtilsStatus status) {
switch (status) {
case MOCHA_RESULT_SUCCESS:
@@ -341,21 +362,41 @@ MochaUtilsStatus Mocha_StartUSBLogging(bool notSkipExistingLogs) {
if (mochaApiVersion < 1) {
return MOCHA_RESULT_UNSUPPORTED_COMMAND;
}
- MochaUtilsStatus res = MOCHA_RESULT_UNKNOWN_ERROR;
- int mcpFd = IOS_Open("/dev/mcp", (IOSOpenMode) 0);
- if (mcpFd >= 0) {
- ALIGN_0x40 uint32_t io_buffer[0x40 / 4];
- io_buffer[0] = IPC_CUSTOM_START_USB_LOGGING;
- io_buffer[1] = notSkipExistingLogs;
- if (IOS_Ioctl(mcpFd, 100, io_buffer, 8, io_buffer, 0x4) == IOS_ERROR_OK) {
- res = MOCHA_RESULT_SUCCESS;
- }
+ return doSimpleCustomIPCCommand(IPC_CUSTOM_START_USB_LOGGING, notSkipExistingLogs);
+}
- IOS_Close(mcpFd);
+MochaUtilsStatus Mocha_StartTCPSyslogLogging(bool limitToIp, uint32_t ipFilter) {
+ if (!mochaInitDone) {
+ return MOCHA_RESULT_LIB_UNINITIALIZED;
+ }
+ if (mochaApiVersion < 2) {
+ return MOCHA_RESULT_UNSUPPORTED_COMMAND;
}
- return res;
+ return doSimpleCustomIPCCommand(IPC_CUSTOM_START_TCP_LOGGING, limitToIp, ipFilter);
+}
+
+MochaUtilsStatus Mocha_StopTCPSyslogLogging() {
+ if (!mochaInitDone) {
+ return MOCHA_RESULT_LIB_UNINITIALIZED;
+ }
+ if (mochaApiVersion < 2) {
+ return MOCHA_RESULT_UNSUPPORTED_COMMAND;
+ }
+
+ return doSimpleCustomIPCCommand(IPC_CUSTOM_STOP_TCP_LOGGING);
+}
+
+MochaUtilsStatus Mocha_StartIOPShellServer() {
+ if (!mochaInitDone) {
+ return MOCHA_RESULT_LIB_UNINITIALIZED;
+ }
+ if (mochaApiVersion < 2) {
+ return MOCHA_RESULT_UNSUPPORTED_COMMAND;
+ }
+
+ return doSimpleCustomIPCCommand(IPC_CUSTOM_START_IOPSHELL_SERVER);
}
MochaUtilsStatus Mocha_UnlockFSClient(FSClient *client) {