diff --git a/sysmodules/rosalina/include/menus/miscellaneous.h b/sysmodules/rosalina/include/menus/miscellaneous.h index c715ef6..ff38803 100644 --- a/sysmodules/rosalina/include/menus/miscellaneous.h +++ b/sysmodules/rosalina/include/menus/miscellaneous.h @@ -35,4 +35,5 @@ void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void); void MiscellaneousMenu_ChangeMenuCombo(void); void MiscellaneousMenu_SaveSettings(void); void MiscellaneousMenu_InputRedirection(void); -void MiscellaneousMenu_SyncTimeDate(void); +void MiscellaneousMenu_UpdateTimeDateNtp(void); +void MiscellaneousMenu_NullifyUserTimeOffset(void); diff --git a/sysmodules/rosalina/include/ntp.h b/sysmodules/rosalina/include/ntp.h index 89cff94..242e20f 100644 --- a/sysmodules/rosalina/include/ntp.h +++ b/sysmodules/rosalina/include/ntp.h @@ -31,3 +31,4 @@ Result ntpGetTimeStamp(time_t *outTimestamp); Result ntpSetTimeDate(time_t timestamp); +Result ntpNullifyUserTimeOffset(void); // not actually used for NTP diff --git a/sysmodules/rosalina/source/menus/miscellaneous.c b/sysmodules/rosalina/source/menus/miscellaneous.c index 4f294eb..ae59e38 100644 --- a/sysmodules/rosalina/source/menus/miscellaneous.c +++ b/sysmodules/rosalina/source/menus/miscellaneous.c @@ -43,7 +43,8 @@ Menu miscellaneousMenu = { { "Switch the hb. title to the current app.", METHOD, .method = &MiscellaneousMenu_SwitchBoot3dsxTargetTitle }, { "Change the menu combo", METHOD, .method = &MiscellaneousMenu_ChangeMenuCombo }, { "Start InputRedirection", METHOD, .method = &MiscellaneousMenu_InputRedirection }, - { "Sync time and date via NTP", METHOD, .method = &MiscellaneousMenu_SyncTimeDate }, + { "Update time and date via NTP", METHOD, .method = &MiscellaneousMenu_UpdateTimeDateNtp }, + { "Nullify user time offset", METHOD, .method = &MiscellaneousMenu_NullifyUserTimeOffset }, { "Save settings", METHOD, .method = &MiscellaneousMenu_SaveSettings }, {}, } @@ -344,7 +345,7 @@ void MiscellaneousMenu_InputRedirection(void) while(!(waitInput() & KEY_B) && !menuShouldExit); } -void MiscellaneousMenu_SyncTimeDate(void) +void MiscellaneousMenu_UpdateTimeDateNtp(void) { u32 posY; u32 input = 0; @@ -415,7 +416,7 @@ void MiscellaneousMenu_SyncTimeDate(void) else if (R_FAILED(res)) Draw_DrawFormattedString(10, posY + 2 * SPACING_Y, COLOR_WHITE, "Operation failed (%08lx).", (u32)res) + SPACING_Y; else - Draw_DrawFormattedString(10, posY + 2 * SPACING_Y, COLOR_WHITE, "Timedate & RTC updated successfully.\nYou may need to reboot to see the changes.") + SPACING_Y; + Draw_DrawFormattedString(10, posY + 2 * SPACING_Y, COLOR_WHITE, "Time/date updated successfully.") + SPACING_Y; input = waitInput(); @@ -425,3 +426,27 @@ void MiscellaneousMenu_SyncTimeDate(void) while(!(input & KEY_B) && !menuShouldExit); } + + +void MiscellaneousMenu_NullifyUserTimeOffset(void) +{ + Result res = ntpNullifyUserTimeOffset(); + + Draw_Lock(); + Draw_ClearFramebuffer(); + Draw_FlushFramebuffer(); + Draw_Unlock(); + + do + { + Draw_Lock(); + Draw_DrawString(10, 10, COLOR_TITLE, "Miscellaneous options menu"); + if(R_SUCCEEDED(res)) + Draw_DrawString(10, 30, COLOR_WHITE, "Operation succeeded.\n\nPlease reboot to finalize the changes."); + else + Draw_DrawFormattedString(10, 30, COLOR_WHITE, "Operation failed (0x%08lx).", res); + Draw_FlushFramebuffer(); + Draw_Unlock(); + } + while(!(waitInput() & KEY_B) && !menuShouldExit); +} diff --git a/sysmodules/rosalina/source/ntp.c b/sysmodules/rosalina/source/ntp.c index b721834..548ebb2 100644 --- a/sysmodules/rosalina/source/ntp.c +++ b/sysmodules/rosalina/source/ntp.c @@ -29,6 +29,7 @@ #include #include "utils.h" #include "minisoc.h" +#include "ntp.h" #define NUM2BCD(n) ((n<99) ? (((n/10)*0x10)|(n%10)) : 0x99) @@ -144,6 +145,21 @@ Result ntpSetTimeDate(time_t timestamp) Result res = ptmSysmInit(); if (R_FAILED(res)) return res; + // Update the user time offset + // 946684800 is the timestamp of 01/01/2000 00:00 relative to the Unix Epoch + s64 msY2k = (timestamp - 946684800) * 1000; + res = PTMSYSM_SetUserTime(msY2k); + + ptmSysmExit(); + return res; +} + +// Not actually used for NTP, but... +Result ntpNullifyUserTimeOffset(void) +{ + Result res = ptmSysmInit(); + if (R_FAILED(res)) return res; + res = cfguInit(); if (R_FAILED(res)) { @@ -151,19 +167,25 @@ Result ntpSetTimeDate(time_t timestamp) return res; } - // First, set the config RTC offset to 0 - u8 rtcOff[8] = {0}; - res = CFG_SetConfigInfoBlk4(8, 0x30001, rtcOff); + // First, set the user time offset to 0 (user time = rtc time + user time offset) + s64 userTimeOff = 0; + res = CFG_SetConfigInfoBlk4(8, 0x30001, &userTimeOff); if (R_FAILED(res)) goto cleanup; - // Update the RTC - // 946684800 is the timestamp of 01/01/2000 00:00 relative to the Unix Epoch - s64 msY2k = (timestamp - 946684800) * 1000; - res = PTMSYSM_SetRtcTime(msY2k); + // Get the user time from shared data... there might be up to 0.5s drift from {mcu+offset} but we don't care here + s64 userTime = osGetTime() - 3155673600000LL; // 1900 -> 2000 time base + + // Apply user time to RTC + res = PTMSYSM_SetRtcTime(userTime); if (R_FAILED(res)) goto cleanup; + // Invalidate system (absolute, server) time, which gets fixed on "friends" login anyway -- don't care if we fail here. + // It has become invalid because we changed the RTC time + PTMSYSM_InvalidateSystemTime(); + // Save the config changes res = CFG_UpdateConfigSavegame(); + cleanup: ptmSysmExit(); cfguExit();