Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timelock system #1727

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open

Timelock system #1727

wants to merge 17 commits into from

Conversation

valx76
Copy link

@valx76 valx76 commented Mar 19, 2022

This PR adds a new feature to Rosalina: locking the console after a certain time with a PIN code. Inputting it will reset the timer.
Something which is missing from the original parental control, in my opinion.
The main use is for parents not wanting their kids to use the console for too long.

It provides a new config menu in Rosalina letting the user handle the following options:

  • Enabling/Disabling the timelock system
  • Set the time limit
  • Set the PIN code

It uses a config file storing the properties listed above, as well as an elapsed time value to keep track of the time spent using the console. This lets us keep track of the usage time even after a reboot.

Default PIN: 0000


Next to that, there is also a fix for Rosalina to handle dynamic menus (valx76@c307dc6) - It initially had some issues handling changing items visibility dynamically.


Here are some screenshots:

  1. Rosalina menu
    1-RosalinaMenu

  2. Locked timelock menu
    2-LockedTimelockMenu

  3. Unlocking timelock menu
    3-UnlockingTimelockMenu

  4. Unlocked timelock menu
    4-UnlockedTimelockMenu

  5. Timelocked console
    5-Timelocked

@t33st33r
Copy link

t33st33r commented Apr 29, 2022

Hello,

The project doesn't have a place to post issues so I don't know where to post this. Sorry I am noob at GitHub, and sorry for my bad english (this is not my native language).

I want to report an issue with the configuration file:

I came from here and I understood your mod probably isn't respecting the original format of sdmc:/luma/config.bin and that is causing to reset the config and forcing the configuration screen to show again on boot.

I've searched for you on gbatemp forum with no luck.
I don't know where to post this. In case there is a place for that tell me where, please.
Thanks in advance.

@urherenow
Copy link

@teesteer, just stop. The only problem here is you. A mod is a mod, a fork is a fork. If you insist on switching versions all the time, it’s on you. Period. If one version remained compatible with the other, there would be no reason for a fork in the first place.

@TuxSH
Copy link
Member

TuxSH commented Jun 4, 2022

Hey, sorry for the late answer. Your work looks interesting, but I'm not sure I want to merge it for the upcoming release.

On a technical level, I don't think saving to the SD card every minute is a good idea (wear?)

@Dakkaron
Copy link

Dakkaron commented Oct 2, 2022

I'd really like to see this PR in Luma. Regarding the wear, a regular SD card can handle ~10k writes per block. So writing once a minute would statistically kill the SD after ~150h, which is bad.

But if there is some wear leveling, that would be no issue. Even if only 1k blocks are used (because there is no more free space on the SD) this would allow for 17 years of continuous use.

I couldn't find anything on the function FSUSER_OpenFileDirectly(), which is used to create the file, so I don't know how it chooses which block to write to.

I would venture to say, it probably wear-levels on file creation but probably not on just writing to the same file. Would it be an option to delete and recreate the file once per minute?

We could also write only every 5-10 mins and otherwise on power-off? This could be circumvented by pulling the battery every 4 or 9 minutes, but that seems a lot of effort to circumvent that system.

@Nuck-TH
Copy link

Nuck-TH commented Oct 2, 2022

any flash memory device with controller(SD and other memory cards, usb flash drives, SSDs, , EMMC, etc) has transparent wear leveling done by it. no filesystem level actions are needed for that.

@Dakkaron
Copy link

Dakkaron commented Oct 2, 2022

@Nuck-TH I thought so as well, but apparently many cheap SDs don't do that. At least according to the results I found on Google. I don't know, though, if Google is correct in that respect.

@profi200
Copy link
Contributor

profi200 commented Oct 3, 2022

You would be surprised how fast SD cards get killed by many small writes. See for example the Raspberry Pi. Some people reported dead SD cards after just a few months usually caused by log files being written to it.

@SirLoopy
Copy link

SirLoopy commented Oct 3, 2022 via email

@valx76
Copy link
Author

valx76 commented Oct 3, 2022

@SirLoopy It won't work because it would mean you can bypass the timelock by just changing the console's time.

@Querela
Copy link

Querela commented Oct 3, 2022

Can you detect a system time change? E.g. first storing the current time on startup and then some custom clock interrupt handling that analyzes the expected time delta?
Or is it possible to disable changing the system time by patching system calls? So, you would only be able to change the time if no time-lock is enabled.
Both would probably be deeper changes if they are possible but would allow to keep it in memory.

@SirLoopy
Copy link

SirLoopy commented Oct 3, 2022 via email

@Dakkaron
Copy link

Dakkaron commented Oct 3, 2022

@SirLoopy It won't work because it would mean you can bypass the timelock by just changing the console's time.

This could be blocked it the timelock system doesn't go with the console's date.

Basically, let it keep it's own time variable, which count down the seconds until the timelock. And this variable is counted down every second. That way, the console's time system is only used to trigger the counter, but the mechanism is completely independent of the console's system time.

The only way around would be for the player to remove the battery, so that the counter doesn't write to the SD. Won't be much of an issue on the OG 3DS, which needs to be taken apart to remove the battery. But on the 3DS XL, which has a user replacable battery, it's easier.

Does the 3DS have some kind of internal flash memory that could survive high write counts? Probably not...

Another idea: The Timelock System creates 1000 files that are each 1 block in size. Every minute it writes to the next file in the row, ring-buffer style. Each file contains a 64 bit numer that is counting up on every write, and the amount of remaining minutes (and other necessary metadata like the current date).

On boot it finds the file with the highest ID and picks up from there.

The files with the size of the block make sure that each file is on a different block, as some kind of makeshift wear level. This will take a sizable chunk of storage, but should extend the lifetime.

Or we just keep it as is and when activating the issue, the user gets a warning that it could damage the SD and that the user should only use high-quality SD cards with hardware wear leveling, like the Western Digital Purple SDs.

@valx76
Copy link
Author

valx76 commented Jul 14, 2023

Just FYI - The PR has been updated to support the latest Luma3DS build (12.0.1).
I think you're still against it @TuxSH but just in case - I see @Frenzoid approved the PR, so we never know 😄

@Masamune3210
Copy link

The problem is that it could be the most high dollar, supported and validated, certified piece of magic SD card ever and still die randomly from being wrote to a bit too much. Flash is, by its nature, somewhat unpredictable. Yes, it can be validated for durability standards, but I still don't think it's a good idea to rapidly write to one repeatedly and semi-constantly like that. There is no way to tell the SD card what block to put data in either, it's all handled by the controller opaquely.

@SirLoopy It won't work because it would mean you can bypass the timelock by just changing the console's time.

This could be blocked it the timelock system doesn't go with the console's date.

Basically, let it keep it's own time variable, which count down the seconds until the timelock. And this variable is counted down every second. That way, the console's time system is only used to trigger the counter, but the mechanism is completely independent of the console's system time.

The only way around would be for the player to remove the battery, so that the counter doesn't write to the SD. Won't be much of an issue on the OG 3DS, which needs to be taken apart to remove the battery. But on the 3DS XL, which has a user replacable battery, it's easier.

Does the 3DS have some kind of internal flash memory that could survive high write counts? Probably not...

Another idea: The Timelock System creates 1000 files that are each 1 block in size. Every minute it writes to the next file in the row, ring-buffer style. Each file contains a 64 bit numer that is counting up on every write, and the amount of remaining minutes (and other necessary metadata like the current date).

On boot it finds the file with the highest ID and picks up from there.

The files with the size of the block make sure that each file is on a different block, as some kind of makeshift wear level. This will take a sizable chunk of storage, but should extend the lifetime.

Or we just keep it as is and when activating the issue, the user gets a warning that it could damage the SD and that the user should only use high-quality SD cards with hardware wear leveling, like the Western Digital Purple SDs.

@evan
Copy link

evan commented Jul 15, 2023

I've used this branch with my kids and made some modifications. I believe it only writes to the card when the console is awake and unlocked. This is not 24/7, but more like 1-2 hours a day max. At a 5 minute write interval, which is what I set it to, that's up to 24 writes a day. Likely that's less than the number of writes they generate by actually playing games and whatever the OS is up to.

I will note that to truly be usable with my kids I need it to reset the time allowance at midnight instead of requiring the full time to be used and then the passcode to unlock the next block of time. I haven't tried to add the reset feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet