1
0
forked from iarv/Meck

fixed repeater admin password entry display mode and updated readme

This commit is contained in:
pelgraine
2026-02-10 15:06:48 +11:00
parent 87a5f185d3
commit d42c283fb4
2 changed files with 42 additions and 6 deletions

View File

@@ -36,13 +36,38 @@ Press **N** from the home screen to open the contacts list. All known mesh conta
|-----|--------|
| W / S | Scroll up / down through contacts |
| A / D | Cycle filter: All → Chat → Repeater → Room → Sensor |
| Enter / C | Open DM compose to selected chat contact |
| Enter | Open DM compose (Chat contact) or repeater admin (Repeater contact) |
| C | Open DM compose to selected chat contact |
| Q | Back to home screen |
### Sending a Direct Message
Select a **Chat** contact in the contacts list and press **Enter** or **C** to start composing a direct message. The compose screen will show `DM: ContactName` in the header. Type your message and press **Enter** to send. The DM is sent encrypted directly to that contact (or flooded if no direct path is known). After sending or cancelling, you're returned to the contacts list.
### Repeater Admin Screen
Select a **Repeater** contact in the contacts list and press **Enter** to open the repeater admin screen. You'll be prompted for the repeater's admin password. Characters briefly appear as you type them before being masked, making it easier to enter symbols and numbers on the T-Deck Pro keyboard.
After a successful login, you'll see a menu with the following remote administration commands:
| Menu Item | Description |
|-----------|-------------|
| Clock Sync | Push your device's clock time to the repeater |
| Send Advert | Trigger the repeater to broadcast an advertisement |
| Neighbors | View other repeaters heard via zero-hop adverts |
| Get Clock | Read the repeater's current clock value |
| Version | Query the repeater's firmware version |
| Get Status | Retrieve repeater status information |
| Key | Action |
|-----|--------|
| W / S | Navigate menu items |
| Enter | Execute selected command |
| C | Enter compose mode (send raw CLI command) |
| Q | Back to contacts (from menu) or cancel login |
Command responses are displayed in a scrollable view. Use **W / S** to scroll long responses and **Q** to return to the menu.
### Compose Mode
| Key | Action |
@@ -178,7 +203,7 @@ There are a number of fairly major features in the pipeline, with no particular
- [X] View and compose all channel messages Companion BLE firmware
- [X] Standalone DM functionality for Companion BLE firmware
- [X] Contacts list with filtering for Companion BLE firmware
- [ ] Standalone repeater admin access for Companion BLE firmware
- [X] Standalone repeater admin access for Companion BLE firmware
- [ ] Companion radio: USB
- [ ] Simple Repeater firmware for the T-Deck Pro
- [ ] Get pin 45 with the screen backlight functioning for the T-Deck Pro v1.1

View File

@@ -48,6 +48,7 @@ private:
// Password entry
char _password[ADMIN_PASSWORD_MAX];
int _pwdLen;
unsigned long _lastCharAt; // millis() when last char typed (for brief reveal)
// Menu
int _menuSel; // Currently selected menu item
@@ -101,7 +102,7 @@ public:
RepeaterAdminScreen(UITask* task, mesh::RTCClock* rtc)
: _task(task), _rtc(rtc), _state(STATE_PASSWORD_ENTRY),
_contactIdx(-1), _permissions(0), _serverTime(0),
_pwdLen(0), _menuSel(0),
_pwdLen(0), _lastCharAt(0), _menuSel(0),
_responseLen(0), _responseScroll(0),
_cmdSentAt(0), _waitingForLogin(false) {
_password[0] = '\0';
@@ -118,6 +119,7 @@ public:
// Reset state
_state = STATE_PASSWORD_ENTRY;
_pwdLen = 0;
_lastCharAt = 0;
_password[0] = '\0';
_menuSel = 0;
_permissions = 0;
@@ -257,7 +259,12 @@ public:
break;
}
return (_state == STATE_LOGGING_IN || _state == STATE_COMMAND_PENDING) ? 1000 : 5000;
if (_state == STATE_LOGGING_IN || _state == STATE_COMMAND_PENDING) return 1000;
// During password reveal, refresh when the reveal expires
if (_state == STATE_PASSWORD_ENTRY && _lastCharAt > 0 && (millis() - _lastCharAt) < 800) {
return _lastCharAt + 800 - millis() + 50; // refresh shortly after reveal ends
}
return 5000;
}
bool handleInput(char c) override {
@@ -293,11 +300,13 @@ private:
display.setColor(DisplayDriver::YELLOW);
display.setCursor(0, y);
// Show asterisks for password characters
// Show asterisks for password characters, with brief reveal of last char
char masked[ADMIN_PASSWORD_MAX];
int i;
bool revealing = (_pwdLen > 0 && (millis() - _lastCharAt) < 800);
int revealIdx = revealing ? _pwdLen - 1 : -1;
for (i = 0; i < _pwdLen && i < ADMIN_PASSWORD_MAX - 1; i++) {
masked[i] = '*';
masked[i] = (i == revealIdx) ? _password[i] : '*';
}
masked[i] = '\0';
display.print(masked);
@@ -325,6 +334,7 @@ private:
if (_pwdLen > 0) {
_pwdLen--;
_password[_pwdLen] = '\0';
_lastCharAt = 0; // no reveal after delete
}
return true;
}
@@ -333,6 +343,7 @@ private:
if (c >= 32 && c < 127 && _pwdLen < ADMIN_PASSWORD_MAX - 1) {
_password[_pwdLen++] = c;
_password[_pwdLen] = '\0';
_lastCharAt = millis(); // start brief reveal
return true;
}