mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-10-19 03:52:05 +00:00
feat: Add lockpass setting to configure lock screen password
This commit is contained in:
@@ -90,7 +90,7 @@ void DataStore::begin() {
|
|||||||
#include <CustomLFS_QSPIFlash.h>
|
#include <CustomLFS_QSPIFlash.h>
|
||||||
#elif defined(EXTRAFS)
|
#elif defined(EXTRAFS)
|
||||||
#include <CustomLFS.h>
|
#include <CustomLFS.h>
|
||||||
#else
|
#else
|
||||||
#include <InternalFileSystem.h>
|
#include <InternalFileSystem.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -622,6 +622,11 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
|
|||||||
rd(&_prefs.loc_share_duration_idx, sizeof(_prefs.loc_share_duration_idx));
|
rd(&_prefs.loc_share_duration_idx, sizeof(_prefs.loc_share_duration_idx));
|
||||||
if (_prefs.loc_share_duration_idx >= NodePrefs::LOC_SHARE_DURATION_COUNT) _prefs.loc_share_duration_idx = 0;
|
if (_prefs.loc_share_duration_idx >= NodePrefs::LOC_SHARE_DURATION_COUNT) _prefs.loc_share_duration_idx = 0;
|
||||||
|
|
||||||
|
// append the lock-screen password. Should be empty by default
|
||||||
|
// since struct was zero initialized in begin(), meaning password is disabled
|
||||||
|
rd(_prefs.lock_screen_password, sizeof(_prefs.lock_screen_password));
|
||||||
|
_prefs.lock_screen_password[sizeof(_prefs.lock_screen_password) - 1] = '\0';
|
||||||
|
|
||||||
// Schema sentinel: bumped on layout changes. Mismatch means an older file
|
// Schema sentinel: bumped on layout changes. Mismatch means an older file
|
||||||
// (or a different schema); rd() and the clamps above already keep every
|
// (or a different schema); rd() and the clamps above already keep every
|
||||||
// field within its valid range regardless, so we just log it here —
|
// field within its valid range regardless, so we just log it here —
|
||||||
@@ -819,6 +824,7 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_
|
|||||||
file.write((uint8_t *)&_prefs.contact_expiry_idx, sizeof(_prefs.contact_expiry_idx));
|
file.write((uint8_t *)&_prefs.contact_expiry_idx, sizeof(_prefs.contact_expiry_idx));
|
||||||
file.write((uint8_t *)&_prefs.loc_share_scope, sizeof(_prefs.loc_share_scope));
|
file.write((uint8_t *)&_prefs.loc_share_scope, sizeof(_prefs.loc_share_scope));
|
||||||
file.write((uint8_t *)&_prefs.loc_share_duration_idx, sizeof(_prefs.loc_share_duration_idx));
|
file.write((uint8_t *)&_prefs.loc_share_duration_idx, sizeof(_prefs.loc_share_duration_idx));
|
||||||
|
file.write((uint8_t *)_prefs.lock_screen_password, sizeof(_prefs.lock_screen_password));
|
||||||
|
|
||||||
// Tail sentinel — must be last. See NodePrefs::SCHEMA_SENTINEL. Its write is
|
// Tail sentinel — must be last. See NodePrefs::SCHEMA_SENTINEL. Its write is
|
||||||
// the one we check: once the flash fills, writes return 0, so a good
|
// the one we check: once the flash fills, writes return 0, so a good
|
||||||
@@ -1360,7 +1366,7 @@ bool DataStore::deleteBlobByKey(const uint8_t key[], int key_len) {
|
|||||||
makeBlobPath(key, key_len, path, sizeof(path));
|
makeBlobPath(key, key_len, path, sizeof(path));
|
||||||
|
|
||||||
_fs->remove(path);
|
_fs->remove(path);
|
||||||
|
|
||||||
return true; // return true even if file did not exist
|
return true; // return true even if file did not exist
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -536,6 +536,11 @@ struct NodePrefs { // persisted to file
|
|||||||
// ── Custom messages ────────────────────────────────────────────────────
|
// ── Custom messages ────────────────────────────────────────────────────
|
||||||
char custom_msgs[10][140]; // user-defined quick messages (supports {loc}, {time})
|
char custom_msgs[10][140]; // user-defined quick messages (supports {loc}, {time})
|
||||||
|
|
||||||
|
// Lock-screen password, empty by default. If set, a password is required to
|
||||||
|
// unlock the lock screen.
|
||||||
|
static const uint8_t LOCK_PASSWORD_MAX_LEN = 32;
|
||||||
|
char lock_screen_password[LOCK_PASSWORD_MAX_LEN];
|
||||||
|
|
||||||
// Single source of truth for the live-share option tables (shared by the Map
|
// Single source of truth for the live-share option tables (shared by the Map
|
||||||
// UI labels and the auto-send engine in UITask).
|
// UI labels and the auto-send engine in UITask).
|
||||||
static const uint8_t LOC_SHARE_MOVE_COUNT = 4;
|
static const uint8_t LOC_SHARE_MOVE_COUNT = 4;
|
||||||
@@ -623,7 +628,7 @@ struct NodePrefs { // persisted to file
|
|||||||
// repeat_* fields) instead of at the tail, which shifted every field after
|
// repeat_* fields) instead of at the tail, which shifted every field after
|
||||||
// them by 25 bytes when loading an older file. Never released, but a dev
|
// them by 25 bytes when loading an older file. Never released, but a dev
|
||||||
// build wrote it, so the number must not be reused for anything else.
|
// build wrote it, so the number must not be reused for anything else.
|
||||||
static const uint32_t SCHEMA_SENTINEL = 0xC0DE002E;
|
static const uint32_t SCHEMA_SENTINEL = 0xC0DE002F;
|
||||||
|
|
||||||
// Bit-index for each home page. Used by page_order (entries store bit+1) and
|
// Bit-index for each home page. Used by page_order (entries store bit+1) and
|
||||||
// by home_pages_mask. Single source of truth — both HomeScreen::pageBit/bitToPage
|
// by home_pages_mask. Single source of truth — both HomeScreen::pageBit/bitToPage
|
||||||
@@ -763,6 +768,7 @@ struct NodePrefs { // persisted to file
|
|||||||
// msg_wake_screen_off (0xC0DE002A) landed in the 1 byte of padding the
|
// msg_wake_screen_off (0xC0DE002A) landed in the 1 byte of padding the
|
||||||
// 0xC0DE0029 bump left over -- confirmed via a real sim_companion_radio
|
// 0xC0DE0029 bump left over -- confirmed via a real sim_companion_radio
|
||||||
// (native) build, sizeof unchanged at 2760.
|
// (native) build, sizeof unchanged at 2760.
|
||||||
|
|
||||||
// repeat_extra_scope_mask + ch_scope_idx[64] (0xC0DE002B) added 64 bytes,
|
// repeat_extra_scope_mask + ch_scope_idx[64] (0xC0DE002B) added 64 bytes,
|
||||||
// not 66 -- the struct had 2 bytes of spare tail padding left over from an
|
// not 66 -- the struct had 2 bytes of spare tail padding left over from an
|
||||||
// earlier bump -- confirmed via a real sim_companion_radio (native) build
|
// earlier bump -- confirmed via a real sim_companion_radio (native) build
|
||||||
@@ -777,7 +783,8 @@ struct NodePrefs { // persisted to file
|
|||||||
// WioTrackerL1_companion_solo_dual (nRF52/ARM) and Heltec_v3_companion_radio_ble
|
// WioTrackerL1_companion_solo_dual (nRF52/ARM) and Heltec_v3_companion_radio_ble
|
||||||
// (ESP32) builds, sizeof unchanged at 2824. loc_share_duration_idx (0xC0DE002E)
|
// (ESP32) builds, sizeof unchanged at 2824. loc_share_duration_idx (0xC0DE002E)
|
||||||
// likewise (sim build; see the check below).
|
// likewise (sim build; see the check below).
|
||||||
static_assert(sizeof(NodePrefs) == 2824,
|
// 0xC0DE002F 32 byte bump for lock_screen_password
|
||||||
|
static_assert(sizeof(NodePrefs) == 2856,
|
||||||
"NodePrefs layout changed — sync DataStore save/load + clamp, bump "
|
"NodePrefs layout changed — sync DataStore save/load + clamp, bump "
|
||||||
"SCHEMA_SENTINEL, then update this size (see steps above).");
|
"SCHEMA_SENTINEL, then update this size (see steps above).");
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class SettingsScreen : public UIScreen {
|
|||||||
AUTO_OFF,
|
AUTO_OFF,
|
||||||
#endif
|
#endif
|
||||||
AUTO_LOCK,
|
AUTO_LOCK,
|
||||||
|
LOCK_PASSWORD,
|
||||||
BATT_DISPLAY,
|
BATT_DISPLAY,
|
||||||
#if FEAT_CLOCK_SECONDS_SETTING
|
#if FEAT_CLOCK_SECONDS_SETTING
|
||||||
CLOCK_SECONDS,
|
CLOCK_SECONDS,
|
||||||
@@ -589,6 +590,10 @@ class SettingsScreen : public UIScreen {
|
|||||||
display.print("Auto lock");
|
display.print("Auto lock");
|
||||||
display.setCursor(valCol(display), y);
|
display.setCursor(valCol(display), y);
|
||||||
display.print((p && p->auto_lock) ? "ON" : "OFF");
|
display.print((p && p->auto_lock) ? "ON" : "OFF");
|
||||||
|
} else if (item == LOCK_PASSWORD) {
|
||||||
|
display.print("LockPass");
|
||||||
|
display.setCursor(valCol(display), y);
|
||||||
|
display.print((p && p->lock_screen_password[0]) ? "ON" : "OFF");
|
||||||
} else if (item == TIMEZONE) {
|
} else if (item == TIMEZONE) {
|
||||||
display.print("Time zone");
|
display.print("Time zone");
|
||||||
char buf[8];
|
char buf[8];
|
||||||
@@ -715,6 +720,7 @@ class SettingsScreen : public UIScreen {
|
|||||||
// Keyboard state for editing message slots
|
// Keyboard state for editing message slots
|
||||||
int _edit_slot = -1; // -1 = not editing, 0..9 = slot being edited
|
int _edit_slot = -1; // -1 = not editing, 0..9 = slot being edited
|
||||||
bool _edit_name = false; // editing DEVICE_NAME via the keyboard
|
bool _edit_name = false; // editing DEVICE_NAME via the keyboard
|
||||||
|
bool _edit_lock_pass = false; // editing the lock-screen password via the keyboard
|
||||||
KeyboardWidget* _kb;
|
KeyboardWidget* _kb;
|
||||||
|
|
||||||
// Scope list management (SCOPE_NAME row -> a full-screen add/rename/
|
// Scope list management (SCOPE_NAME row -> a full-screen add/rename/
|
||||||
@@ -786,6 +792,7 @@ public:
|
|||||||
_scope_action_menu.active = false;
|
_scope_action_menu.active = false;
|
||||||
_scope_delete_confirm_active = false;
|
_scope_delete_confirm_active = false;
|
||||||
_prune_confirm.active = false;
|
_prune_confirm.active = false;
|
||||||
|
_edit_lock_pass = false;
|
||||||
resetList();
|
resetList();
|
||||||
_editor.freq.active = false;
|
_editor.freq.active = false;
|
||||||
}
|
}
|
||||||
@@ -793,7 +800,7 @@ public:
|
|||||||
int render(DisplayDriver& display) override {
|
int render(DisplayDriver& display) override {
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
|
|
||||||
if (_edit_slot >= 0 || _edit_name || _scope_rename_idx != -2 || _picker.saving) {
|
if (_edit_slot >= 0 || _edit_name || _edit_lock_pass || _scope_rename_idx != -2 || _picker.saving) {
|
||||||
return _kb->render(display);
|
return _kb->render(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,6 +868,22 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keyboard editing mode for the lock-screen password
|
||||||
|
if (_edit_lock_pass) {
|
||||||
|
auto res = _kb->handleInput(c);
|
||||||
|
if (res == KeyboardWidget::DONE) {
|
||||||
|
if (p) {
|
||||||
|
strncpy(p->lock_screen_password, _kb->buf, sizeof(p->lock_screen_password) - 1);
|
||||||
|
p->lock_screen_password[sizeof(p->lock_screen_password) - 1] = '\0';
|
||||||
|
_dirty = true; // savePrefsIfDirty persists new password
|
||||||
|
}
|
||||||
|
_edit_lock_pass = false;
|
||||||
|
} else if (res == KeyboardWidget::CANCELLED) {
|
||||||
|
_edit_lock_pass = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Keyboard editing mode for adding/renaming a scope-list entry
|
// Keyboard editing mode for adding/renaming a scope-list entry
|
||||||
if (_scope_rename_idx != -2) {
|
if (_scope_rename_idx != -2) {
|
||||||
auto res = _kb->handleInput(c);
|
auto res = _kb->handleInput(c);
|
||||||
@@ -1111,6 +1134,18 @@ public:
|
|||||||
_dirty = true;
|
_dirty = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// LockPass: Clear password if defined or get input from keyboard
|
||||||
|
if (_selected == LOCK_PASSWORD && p && enter) {
|
||||||
|
if (p->lock_screen_password[0]) {
|
||||||
|
p->lock_screen_password[0] = '\0';
|
||||||
|
_dirty = true;
|
||||||
|
} else {
|
||||||
|
_edit_lock_pass = true;
|
||||||
|
_kb->begin("", (int)sizeof(p->lock_screen_password) - 1);
|
||||||
|
_kb->clearPlaceholders(); // a password is literal, not a template message
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (_selected == TIMEZONE && p) {
|
if (_selected == TIMEZONE && p) {
|
||||||
if (right && p->tz_offset_hours < 14) { p->tz_offset_hours++; _dirty = true; return true; }
|
if (right && p->tz_offset_hours < 14) { p->tz_offset_hours++; _dirty = true; return true; }
|
||||||
if (left && p->tz_offset_hours > -12) { p->tz_offset_hours--; _dirty = true; return true; }
|
if (left && p->tz_offset_hours > -12) { p->tz_offset_hours--; _dirty = true; return true; }
|
||||||
|
|||||||
Reference in New Issue
Block a user