2026-10-13 01:52:34 +02:00
|
|
|
#include "system/settings_store.h"
|
|
|
|
|
|
|
|
|
|
#include <Preferences.h>
|
2026-10-15 01:29:01 +02:00
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <string.h>
|
2026-10-13 01:52:34 +02:00
|
|
|
|
|
|
|
|
static const char *NAMESPACE = "flipdot";
|
|
|
|
|
static const char *KEY = "settings";
|
2026-10-15 01:29:01 +02:00
|
|
|
// Increase when the Settings struct changes; old records are then ignored (defaults),
|
|
|
|
|
// unless OLD_VERSIONS says how to read them
|
|
|
|
|
static const uint16_t VERSION = 3;
|
|
|
|
|
|
|
|
|
|
// Older versions: fields were only added at the end, so the start of an old record has
|
|
|
|
|
// the same layout. New fields keep their defaults.
|
|
|
|
|
struct OldVersion
|
|
|
|
|
{
|
|
|
|
|
uint16_t version;
|
|
|
|
|
size_t fields; // bytes of Settings that version had
|
|
|
|
|
};
|
|
|
|
|
static const OldVersion OLD_VERSIONS[] = {
|
|
|
|
|
{1, offsetof(Settings, off_page)},
|
|
|
|
|
{2, offsetof(Settings, drive)},
|
|
|
|
|
};
|
2026-10-13 01:52:34 +02:00
|
|
|
|
|
|
|
|
struct StoredSettings
|
|
|
|
|
{
|
|
|
|
|
uint16_t version;
|
|
|
|
|
uint16_t size;
|
|
|
|
|
Settings settings;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void loadSettings(Settings &settings)
|
|
|
|
|
{
|
|
|
|
|
settings = Settings();
|
|
|
|
|
StoredSettings stored;
|
2026-10-15 01:29:01 +02:00
|
|
|
memset(&stored, 0, sizeof(stored));
|
2026-10-13 01:52:34 +02:00
|
|
|
Preferences prefs;
|
|
|
|
|
prefs.begin(NAMESPACE, true);
|
|
|
|
|
size_t read = prefs.getBytes(KEY, &stored, sizeof(stored));
|
|
|
|
|
prefs.end();
|
2026-10-15 01:29:01 +02:00
|
|
|
|
|
|
|
|
Settings loaded;
|
|
|
|
|
if (read == sizeof(stored) && stored.version == VERSION && stored.size == sizeof(Settings))
|
|
|
|
|
loaded = stored.settings;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const OldVersion *old = nullptr;
|
|
|
|
|
for (const OldVersion &o : OLD_VERSIONS)
|
|
|
|
|
if (o.version == stored.version)
|
|
|
|
|
old = &o;
|
|
|
|
|
if (!old || stored.size < old->fields || stored.size > sizeof(Settings) ||
|
|
|
|
|
read != offsetof(StoredSettings, settings) + stored.size)
|
|
|
|
|
return;
|
|
|
|
|
memcpy((void *)&loaded, &stored.settings, old->fields);
|
|
|
|
|
}
|
|
|
|
|
if (validateSettings(loaded) == nullptr)
|
|
|
|
|
settings = loaded;
|
2026-10-13 01:52:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void saveSettings(const Settings &settings)
|
|
|
|
|
{
|
|
|
|
|
StoredSettings stored;
|
|
|
|
|
stored.version = VERSION;
|
|
|
|
|
stored.size = sizeof(Settings);
|
|
|
|
|
stored.settings = settings;
|
|
|
|
|
Preferences prefs;
|
|
|
|
|
prefs.begin(NAMESPACE, false);
|
|
|
|
|
prefs.putBytes(KEY, &stored, sizeof(stored));
|
|
|
|
|
prefs.end();
|
|
|
|
|
}
|