Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3143e7e1d0 | ||
|
|
d03396d272 | ||
|
|
c8aa2e8a89 | ||
|
|
c7a3a0278c | ||
|
|
5924f60d06 | ||
|
|
cd68b66c03 | ||
|
|
44cd3928fb | ||
|
|
8c54613e44 | ||
|
|
7dfa83b8c0 | ||
|
|
b551061264 | ||
|
|
3e228c33c9 | ||
|
|
2b23be8f44 |
2
.github/ISSUE_TEMPLATE/bug-report.md
vendored
2
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -34,7 +34,7 @@ about: Use this to report bugs you encounter with Luma3DS. Make sure you upload
|
|||||||
|
|
||||||
**Luma3DS version:**
|
**Luma3DS version:**
|
||||||
|
|
||||||
[e.g. v10.1.1 stable or if using nightly/hourly specify the commit like this https://github.com/AuroraWright/Luma3DS/commit/0543c208fd154e6326ea5da8cbf66ffcbdef010c]
|
[e.g. v10.1.2 stable or if using nightly/hourly specify the commit like this https://github.com/AuroraWright/Luma3DS/commit/0543c208fd154e6326ea5da8cbf66ffcbdef010c]
|
||||||
|
|
||||||
**Luma3DS configuration/options:**
|
**Luma3DS configuration/options:**
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,8 @@
|
|||||||
#include "arm9_exception_handlers.h"
|
#include "arm9_exception_handlers.h"
|
||||||
#include "large_patches.h"
|
#include "large_patches.h"
|
||||||
|
|
||||||
|
#define K11EXT_VA 0x70000000
|
||||||
|
|
||||||
u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
||||||
{
|
{
|
||||||
u8 *temp = memsearch(pos, "NCCH", size, 4);
|
u8 *temp = memsearch(pos, "NCCH", size, 4);
|
||||||
@@ -134,7 +136,7 @@ u32 installK11Extension(u8 *pos, u32 size, bool needToInitSd, u32 baseK11VA, u32
|
|||||||
static const u8 patternHook3_4[] = {0x00, 0x00, 0xA0, 0xE1, 0x03, 0xF0, 0x20, 0xE3, 0xFD, 0xFF, 0xFF, 0xEA}; //SGI0 setup code, etc.
|
static const u8 patternHook3_4[] = {0x00, 0x00, 0xA0, 0xE1, 0x03, 0xF0, 0x20, 0xE3, 0xFD, 0xFF, 0xFF, 0xEA}; //SGI0 setup code, etc.
|
||||||
|
|
||||||
//Our kernel11 extension is initially loaded in VRAM
|
//Our kernel11 extension is initially loaded in VRAM
|
||||||
u32 kextTotalSize = *(u32 *)0x18000020 - 0x40000000;
|
u32 kextTotalSize = *(u32 *)0x18000020 - K11EXT_VA;
|
||||||
u32 dstKextPA = (ISN3DS ? 0x2E000000 : 0x26C00000) - kextTotalSize;
|
u32 dstKextPA = (ISN3DS ? 0x2E000000 : 0x26C00000) - kextTotalSize;
|
||||||
|
|
||||||
u32 *hookVeneers = (u32 *)*freeK11Space;
|
u32 *hookVeneers = (u32 *)*freeK11Space;
|
||||||
@@ -143,11 +145,11 @@ u32 installK11Extension(u8 *pos, u32 size, bool needToInitSd, u32 baseK11VA, u32
|
|||||||
hookVeneers[0] = 0xE51FF004; //ldr pc, [pc, #-8+4]
|
hookVeneers[0] = 0xE51FF004; //ldr pc, [pc, #-8+4]
|
||||||
hookVeneers[1] = 0x18000004;
|
hookVeneers[1] = 0x18000004;
|
||||||
hookVeneers[2] = 0xE51FF004;
|
hookVeneers[2] = 0xE51FF004;
|
||||||
hookVeneers[3] = 0x40000000;
|
hookVeneers[3] = K11EXT_VA;
|
||||||
hookVeneers[4] = 0xE51FF004;
|
hookVeneers[4] = 0xE51FF004;
|
||||||
hookVeneers[5] = 0x40000008;
|
hookVeneers[5] = K11EXT_VA + 8;
|
||||||
hookVeneers[6] = 0xE51FF004;
|
hookVeneers[6] = 0xE51FF004;
|
||||||
hookVeneers[7] = 0x4000000C;
|
hookVeneers[7] = K11EXT_VA + 0xC;
|
||||||
|
|
||||||
(*freeK11Space) += 32;
|
(*freeK11Space) += 32;
|
||||||
|
|
||||||
@@ -175,14 +177,14 @@ u32 installK11Extension(u8 *pos, u32 size, bool needToInitSd, u32 baseK11VA, u32
|
|||||||
off += 4;
|
off += 4;
|
||||||
*off = MAKE_BRANCH_LINK(baseK11VA + ((u8 *)off - pos), relocBase + 24);
|
*off = MAKE_BRANCH_LINK(baseK11VA + ((u8 *)off - pos), relocBase + 24);
|
||||||
|
|
||||||
struct KExtParameters *p = (struct KExtParameters *)(*(u32 *)0x18000024 - 0x40000000 + 0x18000000);
|
struct KExtParameters *p = (struct KExtParameters *)(*(u32 *)0x18000024 - K11EXT_VA + 0x18000000);
|
||||||
p->basePA = dstKextPA;
|
p->basePA = dstKextPA;
|
||||||
|
|
||||||
for(u32 i = 0; i < 4; i++)
|
for(u32 i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
u32 *handlerPos = getKernel11HandlerVAPos(pos, arm11ExceptionsPage, baseK11VA, 1 + i);
|
u32 *handlerPos = getKernel11HandlerVAPos(pos, arm11ExceptionsPage, baseK11VA, 1 + i);
|
||||||
p->originalHandlers[i] = (void *)*handlerPos;
|
p->originalHandlers[i] = (void *)*handlerPos;
|
||||||
*handlerPos = 0x40000010 + 4 * i;
|
*handlerPos = K11EXT_VA + 0x10 + 4 * i;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CfwInfo *info = &p->info;
|
struct CfwInfo *info = &p->info;
|
||||||
@@ -248,14 +250,14 @@ u32 patchKernel11(u8 *pos, u32 size, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm
|
|||||||
|
|
||||||
//Redirect enableUserExceptionHandlersForCPUExc (= true)
|
//Redirect enableUserExceptionHandlersForCPUExc (= true)
|
||||||
for(off = arm11ExceptionsPage; *off != 0x96007F9; off++);
|
for(off = arm11ExceptionsPage; *off != 0x96007F9; off++);
|
||||||
off[1] = 0x40000028;
|
off[1] = K11EXT_VA + 0x28;
|
||||||
|
|
||||||
off = (u32 *)memsearch(pos, patternKThreadDebugReschedule, size, sizeof(patternKThreadDebugReschedule));
|
off = (u32 *)memsearch(pos, patternKThreadDebugReschedule, size, sizeof(patternKThreadDebugReschedule));
|
||||||
if(off == NULL)
|
if(off == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
off[-5] = 0xE51FF004;
|
off[-5] = 0xE51FF004;
|
||||||
off[-4] = 0x4000002C;
|
off[-4] = K11EXT_VA + 0x2C;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ ENTRY(_start)
|
|||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
vram : ORIGIN = 0x18000000, LENGTH = 0x18180000 - 0x18000000 /* Up to the kernel builtins. */
|
vram : ORIGIN = 0x18000000, LENGTH = 0x18180000 - 0x18000000 /* Up to the kernel builtins. */
|
||||||
main : ORIGIN = 0x40000000, LENGTH = 1M
|
main : ORIGIN = 0x70000000, LENGTH = 1M
|
||||||
}
|
}
|
||||||
|
|
||||||
PHDRS
|
PHDRS
|
||||||
@@ -15,7 +15,7 @@ PHDRS
|
|||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
PROVIDE(__start__ = 0x40000000);
|
PROVIDE(__start__ = ORIGIN(main));
|
||||||
. = ABSOLUTE(__start__);
|
. = ABSOLUTE(__start__);
|
||||||
|
|
||||||
.text :
|
.text :
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
#include "svc/ConnectToPort.h"
|
#include "svc/ConnectToPort.h"
|
||||||
#include "svcHandler.h"
|
#include "svcHandler.h"
|
||||||
|
|
||||||
|
#define K11EXT_VA 0x70000000
|
||||||
|
|
||||||
struct KExtParameters
|
struct KExtParameters
|
||||||
{
|
{
|
||||||
u32 basePA;
|
u32 basePA;
|
||||||
@@ -41,13 +43,13 @@ struct KExtParameters
|
|||||||
CfwInfo cfwInfo;
|
CfwInfo cfwInfo;
|
||||||
} kExtParameters = { .basePA = 0x12345678 }; // place this in .data
|
} kExtParameters = { .basePA = 0x12345678 }; // place this in .data
|
||||||
|
|
||||||
static ALIGN(1024) u32 L2TableFor0x40000000[256] = {0};
|
static ALIGN(1024) u32 g_L2Table[256] = {0};
|
||||||
|
|
||||||
void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
|
void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
|
||||||
{
|
{
|
||||||
struct KExtParameters *p0 = (struct KExtParameters *)((u32)&kExtParameters - 0x40000000 + 0x18000000);
|
struct KExtParameters *p0 = (struct KExtParameters *)((u32)&kExtParameters - K11EXT_VA + 0x18000000);
|
||||||
struct KExtParameters *p = (struct KExtParameters *)((u32)&kExtParameters - 0x40000000 + p0->basePA);
|
struct KExtParameters *p = (struct KExtParameters *)((u32)&kExtParameters - K11EXT_VA + p0->basePA);
|
||||||
u32 *L2Table = (u32 *)((u32)L2TableFor0x40000000 - 0x40000000 + p0->basePA);
|
u32 *L2Table = (u32 *)((u32)g_L2Table - K11EXT_VA + p0->basePA);
|
||||||
|
|
||||||
if(coreId == 0)
|
if(coreId == 0)
|
||||||
{
|
{
|
||||||
@@ -56,7 +58,7 @@ void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
|
|||||||
memcpy((void *)p0->basePA, (const void *)0x18000000, __bss_start__ - __start__);
|
memcpy((void *)p0->basePA, (const void *)0x18000000, __bss_start__ - __start__);
|
||||||
memset((u32 *)(p0->basePA + (__bss_start__ - __start__)), 0, __bss_end__ - __bss_start__);
|
memset((u32 *)(p0->basePA + (__bss_start__ - __start__)), 0, __bss_end__ - __bss_start__);
|
||||||
|
|
||||||
// Map the kernel ext to 0x40000000
|
// Map the kernel ext at K11EXT_VA
|
||||||
// 4KB extended small pages: [SYS:RW USR:-- X TYP:NORMAL SHARED OUTER NOCACHE, INNER CACHED WB WA]
|
// 4KB extended small pages: [SYS:RW USR:-- X TYP:NORMAL SHARED OUTER NOCACHE, INNER CACHED WB WA]
|
||||||
for(u32 offset = 0; offset < (u32)(__end__ - __start__); offset += 0x1000)
|
for(u32 offset = 0; offset < (u32)(__end__ - __start__); offset += 0x1000)
|
||||||
L2Table[offset >> 12] = (p0->basePA + offset) | 0x516;
|
L2Table[offset >> 12] = (p0->basePA + offset) | 0x516;
|
||||||
@@ -76,7 +78,7 @@ void relocateAndSetupMMU(u32 coreId, u32 *L1Table)
|
|||||||
L1Table[i + (VA >> 20)] = PA | attribs;
|
L1Table[i + (VA >> 20)] = PA | attribs;
|
||||||
}
|
}
|
||||||
|
|
||||||
L1Table[0x40000000 >> 20] = (u32)L2Table | 1;
|
L1Table[K11EXT_VA >> 20] = (u32)L2Table | 1;
|
||||||
|
|
||||||
p->L1MMUTableAddrs[coreId] = (u32)L1Table;
|
p->L1MMUTableAddrs[coreId] = (u32)L1Table;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
*out = 0;
|
||||||
res = 0xF8C007F4; // not implemented
|
res = 0xF8C007F4; // not implemented
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -105,13 +106,16 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
|||||||
*out = L2C_CTRL & 1;
|
*out = L2C_CTRL & 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
*out = 0;
|
||||||
res = 0xF8C007F4;
|
res = 0xF8C007F4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
*out = 0;
|
||||||
res = 0xF8C007F4;
|
res = 0xF8C007F4;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +132,10 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
|||||||
if((u32)param <= getNumberOfCores())
|
if((u32)param <= getNumberOfCores())
|
||||||
*out = L1MMUTableAddrs[param - 1];
|
*out = L1MMUTableAddrs[param - 1];
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
*out = 0;
|
||||||
res = 0xF8C007F4;
|
res = 0xF8C007F4;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -136,6 +143,13 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0x20000:
|
||||||
|
{
|
||||||
|
*out = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
GetSystemInfo(out, type, param);
|
GetSystemInfo(out, type, param);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -29,18 +29,18 @@ static inline void loadCFWInfo(void)
|
|||||||
{
|
{
|
||||||
s64 out;
|
s64 out;
|
||||||
|
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 3));
|
if(svcGetSystemInfo(&out, 0x20000, 0) != 1) panic(0xDEADCAFE);
|
||||||
|
|
||||||
|
svcGetSystemInfo(&out, 0x10000, 3);
|
||||||
config = (u32)out;
|
config = (u32)out;
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 4));
|
svcGetSystemInfo(&out, 0x10000, 4);
|
||||||
multiConfig = (u32)out;
|
multiConfig = (u32)out;
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 5));
|
svcGetSystemInfo(&out, 0x10000, 5);
|
||||||
bootConfig = (u32)out;
|
bootConfig = (u32)out;
|
||||||
|
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 0x201));
|
svcGetSystemInfo(&out, 0x10000, 0x201);
|
||||||
isN3DS = (bool)out;
|
isN3DS = (bool)out;
|
||||||
//assertSuccess(svcGetSystemInfo(&out, 0x10000, 0x202));
|
svcGetSystemInfo(&out, 0x10000, 0x203);
|
||||||
//needToInitSd = (bool)out;
|
|
||||||
assertSuccess(svcGetSystemInfo(&out, 0x10000, 0x203));
|
|
||||||
isSdMode = (bool)out;
|
isSdMode = (bool)out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -311,6 +311,11 @@ ProcessData *terminateAllProcesses(u32 callerPid, s64 timeout)
|
|||||||
|
|
||||||
ProcessList_Lock(&g_manager.processList);
|
ProcessList_Lock(&g_manager.processList);
|
||||||
|
|
||||||
|
// Send custom notification to at least Rosalina to make it relinquish some non-KIP services handles, stop the debugger, etc.
|
||||||
|
if (numKips >= 6) {
|
||||||
|
notifySubscribers(0x2000);
|
||||||
|
}
|
||||||
|
|
||||||
// Send notification 0x100 to the currently running application
|
// Send notification 0x100 to the currently running application
|
||||||
if (g_manager.runningApplicationData != NULL) {
|
if (g_manager.runningApplicationData != NULL) {
|
||||||
g_manager.runningApplicationData->flags &= ~PROCESSFLAG_DEPENDENCIES_LOADED;
|
g_manager.runningApplicationData->flags &= ~PROCESSFLAG_DEPENDENCIES_LOADED;
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ static inline void exitPXI(void)
|
|||||||
static u8 ALIGN(8) receiverStack[THREAD_STACK_SIZE];
|
static u8 ALIGN(8) receiverStack[THREAD_STACK_SIZE];
|
||||||
static u8 ALIGN(8) senderStack[THREAD_STACK_SIZE];
|
static u8 ALIGN(8) senderStack[THREAD_STACK_SIZE];
|
||||||
static u8 ALIGN(8) PXISRV11HandlerStack[THREAD_STACK_SIZE];
|
static u8 ALIGN(8) PXISRV11HandlerStack[THREAD_STACK_SIZE];
|
||||||
|
static MyThread receiverThread = {0}, senderThread = {0}, PXISRV11HandlerThread = {0};
|
||||||
|
|
||||||
Result __sync_init(void);
|
Result __sync_init(void);
|
||||||
Result __sync_fini(void);
|
Result __sync_fini(void);
|
||||||
@@ -152,7 +153,6 @@ void initSystem(void)
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
Handle handles[10] = {0}; //notification handle + service handles
|
Handle handles[10] = {0}; //notification handle + service handles
|
||||||
MyThread receiverThread = {0}, senderThread = {0}, PXISRV11HandlerThread = {0};
|
|
||||||
|
|
||||||
for(u32 i = 0; i < 9; i++)
|
for(u32 i = 0; i < 9; i++)
|
||||||
assertSuccess(srvRegisterService(handles + 1 + i, serviceNames[i], 1));
|
assertSuccess(srvRegisterService(handles + 1 + i, serviceNames[i], 1));
|
||||||
|
|||||||
@@ -36,4 +36,5 @@ extern int inputRedirectionStartResult;
|
|||||||
|
|
||||||
MyThread *inputRedirectionCreateThread(void);
|
MyThread *inputRedirectionCreateThread(void);
|
||||||
void inputRedirectionThreadMain(void);
|
void inputRedirectionThreadMain(void);
|
||||||
|
Result InputRedirection_Disable(s64 timeout);
|
||||||
Result InputRedirection_DoOrUndoPatches(void);
|
Result InputRedirection_DoOrUndoPatches(void);
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
extern Menu debuggerMenu;
|
extern Menu debuggerMenu;
|
||||||
|
|
||||||
void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata);
|
void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata);
|
||||||
|
Result debuggerDisable(s64 timeout);
|
||||||
|
|
||||||
void DebuggerMenu_EnableDebugger(void);
|
void DebuggerMenu_EnableDebugger(void);
|
||||||
void DebuggerMenu_DisableDebugger(void);
|
void DebuggerMenu_DisableDebugger(void);
|
||||||
void DebuggerMenu_DebugNextApplicationByForce(void);
|
void DebuggerMenu_DebugNextApplicationByForce(void);
|
||||||
|
|||||||
@@ -30,8 +30,12 @@
|
|||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
extern Menu sysconfigMenu;
|
extern Menu sysconfigMenu;
|
||||||
|
extern bool isConnectionForced;
|
||||||
|
|
||||||
|
void SysConfigMenu_UpdateStatus(bool control);
|
||||||
|
|
||||||
void SysConfigMenu_ToggleLEDs(void);
|
void SysConfigMenu_ToggleLEDs(void);
|
||||||
void SysConfigMenu_ToggleWireless(void);
|
void SysConfigMenu_ToggleWireless(void);
|
||||||
void SysConfigMenu_TogglePowerButton(void);
|
void SysConfigMenu_TogglePowerButton(void);
|
||||||
void SysConfigMenu_ControlWifi(void);
|
void SysConfigMenu_ControlWifi(void);
|
||||||
|
void SysConfigMenu_DisableForcedWifiConnection(void);
|
||||||
|
|||||||
@@ -18,13 +18,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define SYNC_ERROR ENODEV
|
#define SYNC_ERROR ENODEV
|
||||||
|
|
||||||
extern Handle SOCU_handle;
|
|
||||||
extern Handle socMemhandle;
|
|
||||||
|
|
||||||
extern bool miniSocEnabled;
|
extern bool miniSocEnabled;
|
||||||
|
|
||||||
Result miniSocInit();
|
Result miniSocInit(void);
|
||||||
|
Result miniSocExitDirect(void);
|
||||||
Result miniSocExit(void);
|
Result miniSocExit(void);
|
||||||
|
|
||||||
s32 _net_convert_error(s32 sock_retval);
|
s32 _net_convert_error(s32 sock_retval);
|
||||||
|
|||||||
@@ -68,10 +68,11 @@ typedef struct sock_server
|
|||||||
sock_free_func free;
|
sock_free_func free;
|
||||||
|
|
||||||
Handle shall_terminate_event;
|
Handle shall_terminate_event;
|
||||||
|
Result init_result;
|
||||||
} sock_server;
|
} sock_server;
|
||||||
|
|
||||||
Result server_init(struct sock_server *serv);
|
Result server_init(struct sock_server *serv);
|
||||||
void server_bind(struct sock_server *serv, u16 port);
|
Result server_bind(struct sock_server *serv, u16 port);
|
||||||
void server_run(struct sock_server *serv);
|
void server_run(struct sock_server *serv);
|
||||||
void server_kill_connections(struct sock_server *serv);
|
void server_kill_connections(struct sock_server *serv);
|
||||||
void server_set_should_close_all(struct sock_server *serv);
|
void server_set_should_close_all(struct sock_server *serv);
|
||||||
|
|||||||
@@ -262,7 +262,10 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMemRegions)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (address < 0x40000000 ///< Limit to check for regions
|
s64 TTBCR;
|
||||||
|
svcGetSystemInfo(&TTBCR, 0x10002, 0);
|
||||||
|
|
||||||
|
while (address < (1u << (32 - (u32)TTBCR)) ///< Limit to check for regions
|
||||||
&& posInBuffer < maxPosInBuffer
|
&& posInBuffer < maxPosInBuffer
|
||||||
&& R_SUCCEEDED(svcQueryProcessMemory(&memi, &pagei, handle, address)))
|
&& R_SUCCEEDED(svcQueryProcessMemory(&memi, &pagei, handle, address)))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,13 +74,14 @@ void GDB_DecrementServerReferenceCount(GDBServer *server)
|
|||||||
|
|
||||||
void GDB_RunServer(GDBServer *server)
|
void GDB_RunServer(GDBServer *server)
|
||||||
{
|
{
|
||||||
server_bind(&server->super, GDB_PORT_BASE);
|
Result res = server_bind(&server->super, GDB_PORT_BASE);
|
||||||
server_bind(&server->super, GDB_PORT_BASE + 1);
|
if(R_SUCCEEDED(res)) res = server_bind(&server->super, GDB_PORT_BASE + 1);
|
||||||
server_bind(&server->super, GDB_PORT_BASE + 2);
|
if(R_SUCCEEDED(res)) res = server_bind(&server->super, GDB_PORT_BASE + 2);
|
||||||
|
|
||||||
server_bind(&server->super, GDB_PORT_BASE + 3); // next application
|
if(R_SUCCEEDED(res)) res = server_bind(&server->super, GDB_PORT_BASE + 3); // next application
|
||||||
|
|
||||||
server_run(&server->super);
|
if(R_SUCCEEDED(res))
|
||||||
|
server_run(&server->super);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDB_LockAllContexts(GDBServer *server)
|
void GDB_LockAllContexts(GDBServer *server)
|
||||||
|
|||||||
@@ -55,17 +55,38 @@ int inputRedirectionStartResult;
|
|||||||
void inputRedirectionThreadMain(void)
|
void inputRedirectionThreadMain(void)
|
||||||
{
|
{
|
||||||
Result res = 0;
|
Result res = 0;
|
||||||
|
inputRedirectionStartResult = 0;
|
||||||
|
|
||||||
res = miniSocInit();
|
res = miniSocInit();
|
||||||
if(R_FAILED(res))
|
if(R_FAILED(res))
|
||||||
|
{
|
||||||
|
// Socket services broken
|
||||||
|
inputRedirectionStartResult = res;
|
||||||
|
|
||||||
|
miniSocExit();
|
||||||
|
// Still signal the event
|
||||||
|
svcSignalEvent(inputRedirectionThreadStartedEvent);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int sock = socSocket(AF_INET, SOCK_DGRAM, 0);
|
int sock = socSocket(AF_INET, SOCK_DGRAM, 0);
|
||||||
while(sock == -1)
|
u32 tries = 15;
|
||||||
|
while(sock == -1 && --tries > 0)
|
||||||
{
|
{
|
||||||
svcSleepThread(1000 * 0000 * 0000LL);
|
svcSleepThread(100 * 1000 * 1000LL);
|
||||||
sock = socSocket(AF_INET, SOCK_DGRAM, 0);
|
sock = socSocket(AF_INET, SOCK_DGRAM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sock < -10000 || tries == 0) {
|
||||||
|
// Socket services broken
|
||||||
|
inputRedirectionStartResult = -1;
|
||||||
|
|
||||||
|
miniSocExit();
|
||||||
|
// Still signal the event
|
||||||
|
svcSignalEvent(inputRedirectionThreadStartedEvent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct sockaddr_in saddr;
|
struct sockaddr_in saddr;
|
||||||
saddr.sin_family = AF_INET;
|
saddr.sin_family = AF_INET;
|
||||||
saddr.sin_port = htons(4950);
|
saddr.sin_port = htons(4950);
|
||||||
@@ -76,6 +97,9 @@ void inputRedirectionThreadMain(void)
|
|||||||
socClose(sock);
|
socClose(sock);
|
||||||
miniSocExit();
|
miniSocExit();
|
||||||
inputRedirectionStartResult = res;
|
inputRedirectionStartResult = res;
|
||||||
|
|
||||||
|
// Still signal the event
|
||||||
|
svcSignalEvent(inputRedirectionThreadStartedEvent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,21 +149,40 @@ void inputRedirectionThreadMain(void)
|
|||||||
srvPublishToSubscriber(0x203, 0);
|
srvPublishToSubscriber(0x203, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(pollres < -10000)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inputRedirectionEnabled = false;
|
||||||
struct linger linger;
|
struct linger linger;
|
||||||
linger.l_onoff = 1;
|
linger.l_onoff = 1;
|
||||||
linger.l_linger = 0;
|
linger.l_linger = 0;
|
||||||
|
|
||||||
socSetsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(struct linger));
|
socSetsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(struct linger));
|
||||||
|
|
||||||
socClose(sock);
|
socClose(sock);
|
||||||
|
|
||||||
miniSocExit();
|
miniSocExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidCodePatchFunc(void);
|
void hidCodePatchFunc(void);
|
||||||
void irCodePatchFunc(void);
|
void irCodePatchFunc(void);
|
||||||
|
|
||||||
|
Result InputRedirection_Disable(s64 timeout)
|
||||||
|
{
|
||||||
|
if(!inputRedirectionEnabled)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Result res = InputRedirection_DoOrUndoPatches();
|
||||||
|
if(R_FAILED(res))
|
||||||
|
return res;
|
||||||
|
|
||||||
|
inputRedirectionEnabled = false;
|
||||||
|
res = MyThread_Join(&inputRedirectionThread, timeout);
|
||||||
|
svcCloseHandle(inputRedirectionThreadStartedEvent);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
Result InputRedirection_DoOrUndoPatches(void)
|
Result InputRedirection_DoOrUndoPatches(void)
|
||||||
{
|
{
|
||||||
s64 startAddress, textTotalRoundedSize, rodataTotalRoundedSize, dataTotalRoundedSize;
|
s64 startAddress, textTotalRoundedSize, rodataTotalRoundedSize, dataTotalRoundedSize;
|
||||||
@@ -147,6 +190,8 @@ Result InputRedirection_DoOrUndoPatches(void)
|
|||||||
Handle processHandle;
|
Handle processHandle;
|
||||||
|
|
||||||
Result res = OpenProcessByName("hid", &processHandle);
|
Result res = OpenProcessByName("hid", &processHandle);
|
||||||
|
static bool hidPatched = false;
|
||||||
|
static bool irPatched = false;
|
||||||
|
|
||||||
if(R_SUCCEEDED(res))
|
if(R_SUCCEEDED(res))
|
||||||
{
|
{
|
||||||
@@ -173,11 +218,12 @@ Result InputRedirection_DoOrUndoPatches(void)
|
|||||||
static u32 *hidRegPatchOffsets[2];
|
static u32 *hidRegPatchOffsets[2];
|
||||||
static u32 *hidPatchJumpLoc;
|
static u32 *hidPatchJumpLoc;
|
||||||
|
|
||||||
if(inputRedirectionEnabled)
|
if(hidPatched)
|
||||||
{
|
{
|
||||||
memcpy(hidRegPatchOffsets[0], &hidOrigRegisterAndValue, sizeof(hidOrigRegisterAndValue));
|
memcpy(hidRegPatchOffsets[0], &hidOrigRegisterAndValue, sizeof(hidOrigRegisterAndValue));
|
||||||
memcpy(hidRegPatchOffsets[1], &hidOrigRegisterAndValue, sizeof(hidOrigRegisterAndValue));
|
memcpy(hidRegPatchOffsets[1], &hidOrigRegisterAndValue, sizeof(hidOrigRegisterAndValue));
|
||||||
memcpy(hidPatchJumpLoc, &hidOrigCode, sizeof(hidOrigCode));
|
memcpy(hidPatchJumpLoc, &hidOrigCode, sizeof(hidOrigCode));
|
||||||
|
hidPatched = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -218,6 +264,7 @@ Result InputRedirection_DoOrUndoPatches(void)
|
|||||||
|
|
||||||
*off = *off2 = hidDataPhys;
|
*off = *off2 = hidDataPhys;
|
||||||
memcpy(off3, &hidHook, sizeof(hidHook));
|
memcpy(off3, &hidHook, sizeof(hidHook));
|
||||||
|
hidPatched = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +311,7 @@ Result InputRedirection_DoOrUndoPatches(void)
|
|||||||
|
|
||||||
static u32 *irHookLoc, *irWaitSyncLoc, *irCppFlagLoc;
|
static u32 *irHookLoc, *irWaitSyncLoc, *irCppFlagLoc;
|
||||||
|
|
||||||
if(inputRedirectionEnabled)
|
if(irPatched)
|
||||||
{
|
{
|
||||||
memcpy(irHookLoc, &irOrigReadingCode, sizeof(irOrigReadingCode));
|
memcpy(irHookLoc, &irOrigReadingCode, sizeof(irOrigReadingCode));
|
||||||
if(useOldSyncCode)
|
if(useOldSyncCode)
|
||||||
@@ -272,6 +319,8 @@ Result InputRedirection_DoOrUndoPatches(void)
|
|||||||
else
|
else
|
||||||
memcpy(irWaitSyncLoc, &irOrigWaitSyncCode, sizeof(irOrigWaitSyncCode));
|
memcpy(irWaitSyncLoc, &irOrigWaitSyncCode, sizeof(irOrigWaitSyncCode));
|
||||||
memcpy(irCppFlagLoc, &irOrigCppFlagCode, sizeof(irOrigCppFlagCode));
|
memcpy(irCppFlagLoc, &irOrigCppFlagCode, sizeof(irOrigCppFlagCode));
|
||||||
|
|
||||||
|
irPatched = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -331,6 +380,8 @@ Result InputRedirection_DoOrUndoPatches(void)
|
|||||||
|
|
||||||
// This NOPs out a flag check in ir:user's CPP emulation
|
// This NOPs out a flag check in ir:user's CPP emulation
|
||||||
*irCppFlagLoc = 0xE3150000; // tst r5, #0
|
*irCppFlagLoc = 0xE3150000; // tst r5, #0
|
||||||
|
|
||||||
|
irPatched = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,9 @@
|
|||||||
#include "menus/debugger.h"
|
#include "menus/debugger.h"
|
||||||
#include "menus/screen_filters.h"
|
#include "menus/screen_filters.h"
|
||||||
#include "menus/cheats.h"
|
#include "menus/cheats.h"
|
||||||
|
#include "menus/sysconfig.h"
|
||||||
|
#include "input_redirection.h"
|
||||||
|
#include "minisoc.h"
|
||||||
|
|
||||||
#include "task_runner.h"
|
#include "task_runner.h"
|
||||||
|
|
||||||
@@ -161,6 +164,26 @@ static void handleTermNotification(u32 notificationId)
|
|||||||
svcSignalEvent(terminationRequestEvent);
|
svcSignalEvent(terminationRequestEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void relinquishConnectionSessions(u32 notificationId)
|
||||||
|
{
|
||||||
|
(void)notificationId;
|
||||||
|
// Might be subject to a race condition, but heh.
|
||||||
|
|
||||||
|
// Disable input redirection
|
||||||
|
InputRedirection_Disable(100 * 1000 * 1000LL);
|
||||||
|
|
||||||
|
// Ask the debugger to terminate in approx 2 * 100ms
|
||||||
|
debuggerDisable(100 * 1000 * 1000LL);
|
||||||
|
|
||||||
|
// Kill the ac session if needed
|
||||||
|
if(isConnectionForced)
|
||||||
|
{
|
||||||
|
acExit();
|
||||||
|
isConnectionForced = false;
|
||||||
|
SysConfigMenu_UpdateStatus(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handleNextApplicationDebuggedByForce(u32 notificationId)
|
static void handleNextApplicationDebuggedByForce(u32 notificationId)
|
||||||
{
|
{
|
||||||
(void)notificationId;
|
(void)notificationId;
|
||||||
@@ -175,7 +198,9 @@ static const ServiceManagerServiceEntry services[] = {
|
|||||||
|
|
||||||
static const ServiceManagerNotificationEntry notifications[] = {
|
static const ServiceManagerNotificationEntry notifications[] = {
|
||||||
{ 0x100 , handleTermNotification },
|
{ 0x100 , handleTermNotification },
|
||||||
|
//{ 0x103 , relinquishConnectionSessions }, // Sleep mode entry <=== causes issues
|
||||||
{ 0x1000, handleNextApplicationDebuggedByForce },
|
{ 0x1000, handleNextApplicationDebuggedByForce },
|
||||||
|
{ 0x2000, relinquishConnectionSessions },
|
||||||
{ 0x000, NULL },
|
{ 0x000, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1858,15 +1858,15 @@ static void Cheat_LoadCheatsIntoMemory(u64 titleId)
|
|||||||
memset(cheatPage, 0, 0x1000);
|
memset(cheatPage, 0, 0x1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 Cheat_GetCurrentTitleId(u64* titleId)
|
static u32 Cheat_GetCurrentProcessAndTitleId(u64* titleId)
|
||||||
{
|
{
|
||||||
u32 pid;
|
u32 pid;
|
||||||
Result res = PMDBG_GetCurrentAppTitleIdAndPid(titleId, &pid);
|
Result res = PMDBG_GetCurrentAppTitleIdAndPid(titleId, &pid);
|
||||||
if (R_FAILED(res)) {
|
if (R_FAILED(res)) {
|
||||||
*titleId = 0;
|
*titleId = 0;
|
||||||
return res;
|
return 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
return res;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cheat_SeedRng(u64 seed)
|
void Cheat_SeedRng(u64 seed)
|
||||||
@@ -1882,7 +1882,7 @@ void Cheat_ApplyCheats(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
u64 titleId = 0;
|
u64 titleId = 0;
|
||||||
u32 pid = Cheat_GetCurrentTitleId(&titleId);
|
u32 pid = Cheat_GetCurrentProcessAndTitleId(&titleId);
|
||||||
|
|
||||||
if (!titleId)
|
if (!titleId)
|
||||||
{
|
{
|
||||||
@@ -1908,7 +1908,7 @@ void Cheat_ApplyCheats(void)
|
|||||||
void RosalinaMenu_Cheats(void)
|
void RosalinaMenu_Cheats(void)
|
||||||
{
|
{
|
||||||
u64 titleId = 0;
|
u64 titleId = 0;
|
||||||
u32 pid = Cheat_GetCurrentTitleId(&titleId);
|
u32 pid = Cheat_GetCurrentProcessAndTitleId(&titleId);
|
||||||
|
|
||||||
if (titleId != 0)
|
if (titleId != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -84,6 +84,30 @@ void debuggerFetchAndSetNextApplicationDebugHandleTask(void *argdata)
|
|||||||
GDB_UnlockAllContexts(&gdbServer);
|
GDB_UnlockAllContexts(&gdbServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result debuggerDisable(s64 timeout)
|
||||||
|
{
|
||||||
|
Result res = 0;
|
||||||
|
bool initialized = gdbServer.referenceCount != 0;
|
||||||
|
if(initialized)
|
||||||
|
{
|
||||||
|
svcSignalEvent(gdbServer.super.shall_terminate_event);
|
||||||
|
server_kill_connections(&gdbServer.super);
|
||||||
|
|
||||||
|
res = MyThread_Join(&debuggerDebugThread, timeout);
|
||||||
|
if(res == 0)
|
||||||
|
res = MyThread_Join(&debuggerSocketThread, timeout);
|
||||||
|
|
||||||
|
Handle dummy = 0;
|
||||||
|
PMDBG_RunQueuedProcess(&dummy);
|
||||||
|
svcCloseHandle(dummy);
|
||||||
|
PMDBG_DebugNextApplicationByForce(false);
|
||||||
|
nextApplicationGdbCtx = NULL;
|
||||||
|
svcKernelSetState(0x10000, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerMenu_EnableDebugger(void)
|
void DebuggerMenu_EnableDebugger(void)
|
||||||
{
|
{
|
||||||
bool done = false, alreadyEnabled = gdbServer.super.running;
|
bool done = false, alreadyEnabled = gdbServer.super.running;
|
||||||
@@ -115,16 +139,18 @@ void DebuggerMenu_EnableDebugger(void)
|
|||||||
if(!done)
|
if(!done)
|
||||||
{
|
{
|
||||||
res = GDB_InitializeServer(&gdbServer);
|
res = GDB_InitializeServer(&gdbServer);
|
||||||
|
Handle handles[3] = { gdbServer.super.started_event, gdbServer.super.shall_terminate_event, terminationRequestEvent };
|
||||||
|
s32 idx;
|
||||||
if(R_SUCCEEDED(res))
|
if(R_SUCCEEDED(res))
|
||||||
{
|
{
|
||||||
debuggerCreateSocketThread();
|
debuggerCreateSocketThread();
|
||||||
debuggerCreateDebugThread();
|
debuggerCreateDebugThread();
|
||||||
res = svcWaitSynchronization(gdbServer.super.started_event, 10 * 1000 * 1000 * 1000LL);
|
res = svcWaitSynchronizationN(&idx, handles, 3, false, 10 * 1000 * 1000 * 1000LL);
|
||||||
|
if(res == 0) res = gdbServer.super.init_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(res != 0)
|
if(res != 0)
|
||||||
sprintf(buf, "Starting debugger... failed (0x%08lx).", (u32)res);
|
sprintf(buf, "Starting debugger... failed (0x%08lx).", (u32)res);
|
||||||
|
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
if(res == 0)
|
if(res == 0)
|
||||||
@@ -142,27 +168,10 @@ void DebuggerMenu_EnableDebugger(void)
|
|||||||
void DebuggerMenu_DisableDebugger(void)
|
void DebuggerMenu_DisableDebugger(void)
|
||||||
{
|
{
|
||||||
bool initialized = gdbServer.referenceCount != 0;
|
bool initialized = gdbServer.referenceCount != 0;
|
||||||
Result res = 0;
|
|
||||||
|
Result res = initialized ? debuggerDisable(2 * 1000 * 1000 * 1000LL) : 0;
|
||||||
char buf[65];
|
char buf[65];
|
||||||
|
|
||||||
if(initialized)
|
|
||||||
{
|
|
||||||
svcSignalEvent(gdbServer.super.shall_terminate_event);
|
|
||||||
server_kill_connections(&gdbServer.super);
|
|
||||||
//server_set_should_close_all(&gdbServer.super);
|
|
||||||
|
|
||||||
res = MyThread_Join(&debuggerDebugThread, 2 * 1000 * 1000 * 1000LL);
|
|
||||||
if(res == 0)
|
|
||||||
res = MyThread_Join(&debuggerSocketThread, 2 * 1000 * 1000 * 1000LL);
|
|
||||||
|
|
||||||
Handle dummy = 0;
|
|
||||||
PMDBG_RunQueuedProcess(&dummy);
|
|
||||||
svcCloseHandle(dummy);
|
|
||||||
PMDBG_DebugNextApplicationByForce(false);
|
|
||||||
nextApplicationGdbCtx = NULL;
|
|
||||||
svcKernelSetState(0x10000, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(res != 0)
|
if(res != 0)
|
||||||
sprintf(buf, "Failed to disable debugger (0x%08lx).", (u32)res);
|
sprintf(buf, "Failed to disable debugger (0x%08lx).", (u32)res);
|
||||||
|
|
||||||
|
|||||||
@@ -221,7 +221,6 @@ void MiscellaneousMenu_SaveSettings(void)
|
|||||||
|
|
||||||
void MiscellaneousMenu_InputRedirection(void)
|
void MiscellaneousMenu_InputRedirection(void)
|
||||||
{
|
{
|
||||||
static MyThread *inputRedirectionThread = NULL;
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
Result res;
|
Result res;
|
||||||
@@ -231,11 +230,7 @@ void MiscellaneousMenu_InputRedirection(void)
|
|||||||
|
|
||||||
if(wasEnabled)
|
if(wasEnabled)
|
||||||
{
|
{
|
||||||
res = InputRedirection_DoOrUndoPatches();
|
res = InputRedirection_Disable(5 * 1000 * 1000 * 1000LL);
|
||||||
inputRedirectionEnabled = false;
|
|
||||||
res = MyThread_Join(inputRedirectionThread, 5 * 1000 * 1000 * 1000LL);
|
|
||||||
svcCloseHandle(inputRedirectionThreadStartedEvent);
|
|
||||||
|
|
||||||
if(res != 0)
|
if(res != 0)
|
||||||
sprintf(buf, "Failed to stop InputRedirection (0x%08lx).", (u32)res);
|
sprintf(buf, "Failed to stop InputRedirection (0x%08lx).", (u32)res);
|
||||||
else
|
else
|
||||||
@@ -282,13 +277,18 @@ void MiscellaneousMenu_InputRedirection(void)
|
|||||||
res = svcCreateEvent(&inputRedirectionThreadStartedEvent, RESET_STICKY);
|
res = svcCreateEvent(&inputRedirectionThreadStartedEvent, RESET_STICKY);
|
||||||
if(R_SUCCEEDED(res))
|
if(R_SUCCEEDED(res))
|
||||||
{
|
{
|
||||||
inputRedirectionThread = inputRedirectionCreateThread();
|
inputRedirectionCreateThread();
|
||||||
res = svcWaitSynchronization(inputRedirectionThreadStartedEvent, 10 * 1000 * 1000 * 1000LL);
|
res = svcWaitSynchronization(inputRedirectionThreadStartedEvent, 10 * 1000 * 1000 * 1000LL);
|
||||||
if(res == 0)
|
if(res == 0)
|
||||||
res = (Result)inputRedirectionStartResult;
|
res = (Result)inputRedirectionStartResult;
|
||||||
|
|
||||||
if(res != 0)
|
if(res != 0)
|
||||||
|
{
|
||||||
|
svcCloseHandle(inputRedirectionThreadStartedEvent);
|
||||||
InputRedirection_DoOrUndoPatches();
|
InputRedirection_DoOrUndoPatches();
|
||||||
|
inputRedirectionEnabled = false;
|
||||||
|
}
|
||||||
|
inputRedirectionStartResult = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ Menu sysconfigMenu = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool isConnectionForced = false;
|
||||||
|
|
||||||
void SysConfigMenu_ToggleLEDs(void)
|
void SysConfigMenu_ToggleLEDs(void)
|
||||||
{
|
{
|
||||||
Draw_Lock();
|
Draw_Lock();
|
||||||
@@ -149,11 +151,29 @@ void SysConfigMenu_ToggleWireless(void)
|
|||||||
while(!terminationRequest);
|
while(!terminationRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SysConfigMenu_ForceWifiConnection(int slot)
|
void SysConfigMenu_UpdateStatus(bool control)
|
||||||
|
{
|
||||||
|
MenuItem *item = &sysconfigMenu.items[3];
|
||||||
|
|
||||||
|
if(control)
|
||||||
|
{
|
||||||
|
item->title = "Control Wireless connection";
|
||||||
|
item->method = &SysConfigMenu_ControlWifi;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->title = "Disable forced wireless connection";
|
||||||
|
item->method = &SysConfigMenu_DisableForcedWifiConnection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SysConfigMenu_ForceWifiConnection(int slot)
|
||||||
{
|
{
|
||||||
char ssid[0x20 + 1] = {0};
|
char ssid[0x20 + 1] = {0};
|
||||||
|
isConnectionForced = false;
|
||||||
|
|
||||||
acInit();
|
if(R_FAILED(acInit()))
|
||||||
|
return false;
|
||||||
|
|
||||||
acuConfig config = {0};
|
acuConfig config = {0};
|
||||||
ACU_CreateDefaultConfig(&config);
|
ACU_CreateDefaultConfig(&config);
|
||||||
@@ -167,15 +187,18 @@ static void SysConfigMenu_ForceWifiConnection(int slot)
|
|||||||
bool forcedConnection = false;
|
bool forcedConnection = false;
|
||||||
if(R_SUCCEEDED(ACU_ConnectAsync(&config, connectEvent)))
|
if(R_SUCCEEDED(ACU_ConnectAsync(&config, connectEvent)))
|
||||||
{
|
{
|
||||||
if(R_SUCCEEDED(svcWaitSynchronization(connectEvent, -1)))
|
if(R_SUCCEEDED(svcWaitSynchronization(connectEvent, -1)) && R_SUCCEEDED(ACU_GetSSID(ssid)))
|
||||||
{
|
|
||||||
ACU_GetSSID(ssid);
|
|
||||||
forcedConnection = true;
|
forcedConnection = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
svcCloseHandle(connectEvent);
|
svcCloseHandle(connectEvent);
|
||||||
|
|
||||||
acExit();
|
if(forcedConnection)
|
||||||
|
{
|
||||||
|
isConnectionForced = true;
|
||||||
|
SysConfigMenu_UpdateStatus(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
acExit();
|
||||||
|
|
||||||
char infoString[80] = {0};
|
char infoString[80] = {0};
|
||||||
u32 infoStringColor = forcedConnection ? COLOR_GREEN : COLOR_RED;
|
u32 infoStringColor = forcedConnection ? COLOR_GREEN : COLOR_RED;
|
||||||
@@ -202,9 +225,11 @@ static void SysConfigMenu_ForceWifiConnection(int slot)
|
|||||||
u32 pressed = waitInputWithTimeout(1000);
|
u32 pressed = waitInputWithTimeout(1000);
|
||||||
|
|
||||||
if(pressed & BUTTON_B)
|
if(pressed & BUTTON_B)
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
while(!terminationRequest);
|
while(!terminationRequest);
|
||||||
|
|
||||||
|
return forcedConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysConfigMenu_TogglePowerButton(void)
|
void SysConfigMenu_TogglePowerButton(void)
|
||||||
@@ -273,7 +298,11 @@ void SysConfigMenu_ControlWifi(void)
|
|||||||
|
|
||||||
if(pressed & BUTTON_A)
|
if(pressed & BUTTON_A)
|
||||||
{
|
{
|
||||||
SysConfigMenu_ForceWifiConnection(slot);
|
if(SysConfigMenu_ForceWifiConnection(slot))
|
||||||
|
{
|
||||||
|
// Connection successfully forced, return from this menu to prevent ac handle refcount leakage.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Draw_Lock();
|
Draw_Lock();
|
||||||
Draw_ClearFramebuffer();
|
Draw_ClearFramebuffer();
|
||||||
@@ -305,3 +334,26 @@ void SysConfigMenu_ControlWifi(void)
|
|||||||
}
|
}
|
||||||
while(!terminationRequest);
|
while(!terminationRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SysConfigMenu_DisableForcedWifiConnection(void)
|
||||||
|
{
|
||||||
|
Draw_Lock();
|
||||||
|
Draw_ClearFramebuffer();
|
||||||
|
Draw_FlushFramebuffer();
|
||||||
|
Draw_Unlock();
|
||||||
|
|
||||||
|
acExit();
|
||||||
|
SysConfigMenu_UpdateStatus(true);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Draw_Lock();
|
||||||
|
Draw_DrawString(10, 10, COLOR_TITLE, "System configuration menu");
|
||||||
|
Draw_DrawString(10, 30, COLOR_WHITE, "Forced connection successfully disabled.\nNote: auto-connection may remain broken.");
|
||||||
|
|
||||||
|
u32 pressed = waitInputWithTimeout(1000);
|
||||||
|
if(pressed & BUTTON_B)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(!terminationRequest);
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,16 @@
|
|||||||
#include <3ds/ipc.h>
|
#include <3ds/ipc.h>
|
||||||
#include <3ds/os.h>
|
#include <3ds/os.h>
|
||||||
#include <3ds/synchronization.h>
|
#include <3ds/synchronization.h>
|
||||||
#include "memory.h"
|
#include <3ds/result.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
s32 miniSocRefCount = 0;
|
||||||
|
static u32 socContextAddr = 0x08000000;
|
||||||
|
static u32 socContextSize = 0x60000;
|
||||||
|
static Handle miniSocHandle;
|
||||||
|
static Handle miniSocMemHandle;
|
||||||
|
|
||||||
|
bool miniSocEnabled = false;
|
||||||
|
|
||||||
s32 _net_convert_error(s32 sock_retval);
|
s32 _net_convert_error(s32 sock_retval);
|
||||||
|
|
||||||
@@ -25,7 +34,7 @@ static Result SOCU_Initialize(Handle memhandle, u32 memsize)
|
|||||||
cmdbuf[4] = IPC_Desc_SharedHandles(1);
|
cmdbuf[4] = IPC_Desc_SharedHandles(1);
|
||||||
cmdbuf[5] = memhandle;
|
cmdbuf[5] = memhandle;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0)
|
if(ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -39,22 +48,14 @@ static Result SOCU_Shutdown(void)
|
|||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x19,0,0); // 0x190000
|
cmdbuf[0] = IPC_MakeHeader(0x19,0,0); // 0x190000
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0)
|
if(ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return cmdbuf[1];
|
return cmdbuf[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32 miniSocRefCount = 0;
|
Result miniSocInit(void)
|
||||||
static u32 socContextAddr = 0x08000000;
|
|
||||||
static u32 socContextSize = 0x60000;
|
|
||||||
// SOCU_handle from ctrulib
|
|
||||||
// socMemhandle from ctrulib
|
|
||||||
|
|
||||||
bool miniSocEnabled = false;
|
|
||||||
|
|
||||||
Result miniSocInit()
|
|
||||||
{
|
{
|
||||||
if(AtomicPostIncrement(&miniSocRefCount))
|
if(AtomicPostIncrement(&miniSocRefCount))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -71,7 +72,7 @@ Result miniSocInit()
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = srvGetServiceHandle(&SOCU_handle, "soc:U");
|
ret = srvGetServiceHandle(&miniSocHandle, "soc:U");
|
||||||
if(ret != 0) goto cleanup;
|
if(ret != 0) goto cleanup;
|
||||||
|
|
||||||
ret = svcControlMemory(&tmp, socContextAddr, 0, socContextSize, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
ret = svcControlMemory(&tmp, socContextAddr, 0, socContextSize, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
||||||
@@ -79,12 +80,12 @@ Result miniSocInit()
|
|||||||
|
|
||||||
socContextAddr = tmp;
|
socContextAddr = tmp;
|
||||||
|
|
||||||
ret = svcCreateMemoryBlock(&socMemhandle, (u32)socContextAddr, socContextSize, 0, 3);
|
ret = svcCreateMemoryBlock(&miniSocMemHandle, (u32)socContextAddr, socContextSize, 0, 3);
|
||||||
if(ret != 0) goto cleanup;
|
if(ret != 0) goto cleanup;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ret = SOCU_Initialize(socMemhandle, socContextSize);
|
ret = SOCU_Initialize(miniSocMemHandle, socContextSize);
|
||||||
if(ret != 0) goto cleanup;
|
if(ret != 0) goto cleanup;
|
||||||
|
|
||||||
svcKernelSetState(0x10000, 2);
|
svcKernelSetState(0x10000, 2);
|
||||||
@@ -94,17 +95,17 @@ Result miniSocInit()
|
|||||||
cleanup:
|
cleanup:
|
||||||
AtomicDecrement(&miniSocRefCount);
|
AtomicDecrement(&miniSocRefCount);
|
||||||
|
|
||||||
if(socMemhandle != 0)
|
if(miniSocMemHandle != 0)
|
||||||
{
|
{
|
||||||
svcCloseHandle(socMemhandle);
|
svcCloseHandle(miniSocMemHandle);
|
||||||
socMemhandle = 0;
|
miniSocMemHandle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SOCU_handle != 0)
|
if(miniSocHandle != 0)
|
||||||
{
|
{
|
||||||
SOCU_Shutdown();
|
SOCU_Shutdown();
|
||||||
svcCloseHandle(SOCU_handle);
|
svcCloseHandle(miniSocHandle);
|
||||||
SOCU_handle = 0;
|
miniSocHandle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tmp != 0)
|
if(tmp != 0)
|
||||||
@@ -113,21 +114,19 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result miniSocExit(void)
|
Result miniSocExitDirect(void)
|
||||||
{
|
{
|
||||||
if(AtomicDecrement(&miniSocRefCount))
|
//if (miniSocRefCount != 0) __builtin_trap();
|
||||||
return 0;
|
|
||||||
|
|
||||||
Result ret = 0;
|
Result ret = 0;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
|
|
||||||
svcCloseHandle(socMemhandle);
|
svcCloseHandle(miniSocMemHandle);
|
||||||
socMemhandle = 0;
|
miniSocMemHandle = 0;
|
||||||
|
|
||||||
ret = SOCU_Shutdown();
|
ret = SOCU_Shutdown();
|
||||||
|
|
||||||
svcCloseHandle(SOCU_handle);
|
svcCloseHandle(miniSocHandle);
|
||||||
SOCU_handle = 0;
|
miniSocHandle = 0;
|
||||||
|
|
||||||
svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE);
|
svcControlMemory(&tmp, socContextAddr, socContextAddr, socContextSize, MEMOP_FREE, MEMPERM_DONTCARE);
|
||||||
if(ret == 0)
|
if(ret == 0)
|
||||||
@@ -138,6 +137,14 @@ Result miniSocExit(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result miniSocExit(void)
|
||||||
|
{
|
||||||
|
if(!miniSocEnabled || AtomicDecrement(&miniSocRefCount))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return miniSocExitDirect();
|
||||||
|
}
|
||||||
|
|
||||||
int socSocket(int domain, int type, int protocol)
|
int socSocket(int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -163,11 +170,11 @@ int socSocket(int domain, int type, int protocol)
|
|||||||
cmdbuf[3] = protocol;
|
cmdbuf[3] = protocol;
|
||||||
cmdbuf[4] = IPC_Desc_CurProcessId();
|
cmdbuf[4] = IPC_Desc_CurProcessId();
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0)
|
if(ret != 0)
|
||||||
{
|
{
|
||||||
//errno = SYNC_ERROR;
|
//errno = SYNC_ERROR;
|
||||||
return ret;
|
return R_FAILED(ret) ? ret : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (int)cmdbuf[1];
|
ret = (int)cmdbuf[1];
|
||||||
@@ -213,7 +220,7 @@ int socBind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
|||||||
cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
||||||
cmdbuf[6] = (u32)tmpaddr;
|
cmdbuf[6] = (u32)tmpaddr;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
//errno = SYNC_ERROR;
|
//errno = SYNC_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -241,7 +248,7 @@ int socListen(int sockfd, int max_connections)
|
|||||||
cmdbuf[2] = (u32)max_connections;
|
cmdbuf[2] = (u32)max_connections;
|
||||||
cmdbuf[3] = IPC_Desc_CurProcessId();
|
cmdbuf[3] = IPC_Desc_CurProcessId();
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0)
|
if(ret != 0)
|
||||||
{
|
{
|
||||||
//errno = SYNC_ERROR;
|
//errno = SYNC_ERROR;
|
||||||
@@ -283,7 +290,7 @@ int socAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
|||||||
staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
||||||
staticbufs[1] = (u32)tmpaddr;
|
staticbufs[1] = (u32)tmpaddr;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
|
|
||||||
staticbufs[0] = saved_threadstorage[0];
|
staticbufs[0] = saved_threadstorage[0];
|
||||||
staticbufs[1] = saved_threadstorage[1];
|
staticbufs[1] = saved_threadstorage[1];
|
||||||
@@ -340,7 +347,7 @@ int socConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
|||||||
cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
cmdbuf[5] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
||||||
cmdbuf[6] = (u32)tmpaddr;
|
cmdbuf[6] = (u32)tmpaddr;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0) return -1;
|
if(ret != 0) return -1;
|
||||||
|
|
||||||
ret = (int)cmdbuf[1];
|
ret = (int)cmdbuf[1];
|
||||||
@@ -383,13 +390,13 @@ int socPoll(struct pollfd *fds, nfds_t nfds, int timeout)
|
|||||||
staticbufs[0] = IPC_Desc_StaticBuffer(size,0);
|
staticbufs[0] = IPC_Desc_StaticBuffer(size,0);
|
||||||
staticbufs[1] = (u32)fds;
|
staticbufs[1] = (u32)fds;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
|
|
||||||
staticbufs[0] = saved_threadstorage[0];
|
staticbufs[0] = saved_threadstorage[0];
|
||||||
staticbufs[1] = saved_threadstorage[1];
|
staticbufs[1] = saved_threadstorage[1];
|
||||||
|
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
return ret;
|
return R_FAILED(ret) ? ret : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = (int)cmdbuf[1];
|
ret = (int)cmdbuf[1];
|
||||||
@@ -408,7 +415,7 @@ int socClose(int sockfd)
|
|||||||
cmdbuf[1] = (u32)sockfd;
|
cmdbuf[1] = (u32)sockfd;
|
||||||
cmdbuf[2] = IPC_Desc_CurProcessId();
|
cmdbuf[2] = IPC_Desc_CurProcessId();
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
//errno = SYNC_ERROR;
|
//errno = SYNC_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -440,7 +447,7 @@ int socSetsockopt(int sockfd, int level, int optname, const void *optval, sockle
|
|||||||
cmdbuf[7] = IPC_Desc_StaticBuffer(optlen,9);
|
cmdbuf[7] = IPC_Desc_StaticBuffer(optlen,9);
|
||||||
cmdbuf[8] = (u32)optval;
|
cmdbuf[8] = (u32)optval;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -464,7 +471,7 @@ long socGethostid(void)
|
|||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x16,0,0); // 0x160000
|
cmdbuf[0] = IPC_MakeHeader(0x16,0,0); // 0x160000
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
//errno = SYNC_ERROR;
|
//errno = SYNC_ERROR;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -506,7 +513,7 @@ static ssize_t _socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struc
|
|||||||
staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0);
|
||||||
staticbufs[1] = (u32)tmpaddr;
|
staticbufs[1] = (u32)tmpaddr;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
|
|
||||||
staticbufs[0] = saved_threadstorage[0];
|
staticbufs[0] = saved_threadstorage[0];
|
||||||
staticbufs[1] = saved_threadstorage[1];
|
staticbufs[1] = saved_threadstorage[1];
|
||||||
@@ -565,7 +572,7 @@ static ssize_t _socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struc
|
|||||||
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
|
cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2;
|
||||||
cmdbuf[0x10c>>2] = (u32)tmpaddr;
|
cmdbuf[0x10c>>2] = (u32)tmpaddr;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
//errno = SYNC_ERROR;
|
//errno = SYNC_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -631,7 +638,7 @@ static ssize_t _socuipc_cmd9(int sockfd, const void *buf, size_t len, int flags,
|
|||||||
cmdbuf[9] = IPC_Desc_Buffer(len,IPC_BUFFER_R);
|
cmdbuf[9] = IPC_Desc_Buffer(len,IPC_BUFFER_R);
|
||||||
cmdbuf[10] = (u32)buf;
|
cmdbuf[10] = (u32)buf;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
//errno = SYNC_ERROR;
|
//errno = SYNC_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -685,7 +692,7 @@ static ssize_t _socuipc_cmda(int sockfd, const void *buf, size_t len, int flags,
|
|||||||
cmdbuf[9] = IPC_Desc_StaticBuffer(tmp_addrlen,1);
|
cmdbuf[9] = IPC_Desc_StaticBuffer(tmp_addrlen,1);
|
||||||
cmdbuf[10] = (u32)tmpaddr;
|
cmdbuf[10] = (u32)tmpaddr;
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
ret = svcSendSyncRequest(miniSocHandle);
|
||||||
if(ret != 0) {
|
if(ret != 0) {
|
||||||
//errno = SYNC_ERROR;
|
//errno = SYNC_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -104,6 +104,11 @@ Result ntpGetTimeStamp(time_t *outTimestamp)
|
|||||||
return res;
|
return res;
|
||||||
|
|
||||||
int sock = socSocket(AF_INET, SOCK_DGRAM, 0);
|
int sock = socSocket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (sock < -10000) {
|
||||||
|
// Socket services broken
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
struct sockaddr_in servAddr = {0}; // Server address data structure.
|
struct sockaddr_in servAddr = {0}; // Server address data structure.
|
||||||
NtpPacket packet = {0};
|
NtpPacket packet = {0};
|
||||||
|
|
||||||
@@ -167,11 +172,8 @@ Result ntpSetTimeDate(const struct tm *localt)
|
|||||||
if (R_FAILED(res)) goto cleanup;
|
if (R_FAILED(res)) goto cleanup;
|
||||||
|
|
||||||
// First, set the config RTC offset to 0
|
// First, set the config RTC offset to 0
|
||||||
u8 rtcOff = 0;
|
u8 rtcOff[8] = {0};
|
||||||
u8 rtcOff2[8] = {0};
|
res = CFG_SetConfigInfoBlk4(8, 0x30001, rtcOff);
|
||||||
res = CFG_SetConfigInfoBlk4(1, 0x10000, &rtcOff);
|
|
||||||
if (R_FAILED(res)) goto cleanup;
|
|
||||||
res = CFG_SetConfigInfoBlk4(8, 0x30001, rtcOff2);
|
|
||||||
if (R_FAILED(res)) goto cleanup;
|
if (R_FAILED(res)) goto cleanup;
|
||||||
|
|
||||||
u8 yr = (u8)(localt->tm_year - 100);
|
u8 yr = (u8)(localt->tm_year - 100);
|
||||||
|
|||||||
@@ -101,29 +101,36 @@ Result server_init(struct sock_server *serv)
|
|||||||
return svcCreateEvent(&serv->shall_terminate_event, RESET_STICKY);
|
return svcCreateEvent(&serv->shall_terminate_event, RESET_STICKY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_bind(struct sock_server *serv, u16 port)
|
Result server_bind(struct sock_server *serv, u16 port)
|
||||||
{
|
{
|
||||||
int server_sockfd;
|
int server_sockfd;
|
||||||
Handle handles[2] = { terminationRequestEvent, serv->shall_terminate_event };
|
Handle handles[2] = { terminationRequestEvent, serv->shall_terminate_event };
|
||||||
s32 idx = -1;
|
s32 idx = -1;
|
||||||
server_sockfd = socSocket(AF_INET, SOCK_STREAM, 0);
|
server_sockfd = socSocket(AF_INET, SOCK_STREAM, 0);
|
||||||
int res;
|
|
||||||
|
|
||||||
while(server_sockfd == -1)
|
int res;
|
||||||
|
u32 tries = 15;
|
||||||
|
while(server_sockfd == -1 && --tries > 0)
|
||||||
{
|
{
|
||||||
if(svcWaitSynchronizationN(&idx, handles, 2, false, 100 * 1000 * 1000LL) == 0)
|
if(svcWaitSynchronizationN(&idx, handles, 2, false, 100 * 1000 * 1000LL) == 0)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
server_sockfd = socSocket(AF_INET, SOCK_STREAM, 0);
|
server_sockfd = socSocket(AF_INET, SOCK_STREAM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (server_sockfd < -10000 || tries == 0) {
|
||||||
|
// Socket services broken
|
||||||
|
serv->init_result = -1;
|
||||||
|
svcSignalEvent(serv->shall_terminate_event);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
struct sockaddr_in saddr;
|
struct sockaddr_in saddr;
|
||||||
saddr.sin_family = AF_INET;
|
saddr.sin_family = AF_INET;
|
||||||
saddr.sin_port = htons(port);
|
saddr.sin_port = htons(port);
|
||||||
saddr.sin_addr.s_addr = socGethostid();
|
saddr.sin_addr.s_addr = socGethostid();
|
||||||
|
|
||||||
res = socBind(server_sockfd, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in));
|
res = socBind(server_sockfd, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
if(res == 0)
|
if(res == 0)
|
||||||
{
|
{
|
||||||
res = socListen(server_sockfd, 2);
|
res = socListen(server_sockfd, 2);
|
||||||
@@ -143,6 +150,15 @@ void server_bind(struct sock_server *serv, u16 port)
|
|||||||
serv->ctx_ptrs[idx] = new_ctx;
|
serv->ctx_ptrs[idx] = new_ctx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res != 0) {
|
||||||
|
// Socket services broken
|
||||||
|
serv->init_result = res;
|
||||||
|
svcSignalEvent(serv->shall_terminate_event);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool server_should_exit(struct sock_server *serv)
|
static bool server_should_exit(struct sock_server *serv)
|
||||||
@@ -171,7 +187,7 @@ void server_run(struct sock_server *serv)
|
|||||||
fds[i].revents = 0;
|
fds[i].revents = 0;
|
||||||
int pollres = socPoll(fds, serv->nfds, 50);
|
int pollres = socPoll(fds, serv->nfds, 50);
|
||||||
|
|
||||||
if(server_should_exit(serv))
|
if(server_should_exit(serv) || pollres < -10000)
|
||||||
goto abort_connections;
|
goto abort_connections;
|
||||||
|
|
||||||
for(nfds_t i = 0; pollres > 0 && i < serv->nfds; i++)
|
for(nfds_t i = 0; pollres > 0 && i < serv->nfds; i++)
|
||||||
@@ -256,6 +272,7 @@ abort_connections:
|
|||||||
server_kill_connections(serv);
|
server_kill_connections(serv);
|
||||||
serv->running = false;
|
serv->running = false;
|
||||||
svcClearEvent(serv->started_event);
|
svcClearEvent(serv->started_event);
|
||||||
|
svcSignalEvent(serv->shall_terminate_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_set_should_close_all(struct sock_server *serv)
|
void server_set_should_close_all(struct sock_server *serv)
|
||||||
@@ -284,7 +301,8 @@ void server_kill_connections(struct sock_server *serv)
|
|||||||
socClose(fds[i].fd);
|
socClose(fds[i].fd);
|
||||||
fds[i].fd = -1;
|
fds[i].fd = -1;
|
||||||
|
|
||||||
serv->ctx_ptrs[i]->should_close = true;
|
if(serv->ctx_ptrs[i] != NULL)
|
||||||
|
serv->ctx_ptrs[i]->should_close = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user