Skip to content

Commit 647d712

Browse files
author
Scott Powell
committed
* Companion: long-press in first 8 seconds now enters CLI Rescue mode
1 parent 5d15a68 commit 647d712

File tree

5 files changed

+99
-5
lines changed

5 files changed

+99
-5
lines changed

examples/companion_radio/MyMesh.cpp

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
728728
: BaseChatMesh(radio, *new ArduinoMillis(), rng, rtc, *new StaticPoolPacketManager(16), tables),
729729
_serial(NULL), telemetry(MAX_PACKET_PAYLOAD - 4) {
730730
_iter_started = false;
731+
_cli_rescue = false;
731732
offline_queue_len = 0;
732733
app_target_ver = 0;
733734
_identity_store = NULL;
@@ -1529,9 +1530,78 @@ void MyMesh::handleCmdFrame(size_t len) {
15291530
}
15301531
}
15311532

1532-
void MyMesh::loop() {
1533-
BaseChatMesh::loop();
1533+
void MyMesh::enterCLIRescue() {
1534+
_cli_rescue = true;
1535+
cli_command[0] = 0;
1536+
Serial.println("========= CLI Rescue =========");
1537+
}
1538+
1539+
bool MyMesh::formatFileSystem() {
1540+
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
1541+
return InternalFS.format();
1542+
#elif defined(RP2040_PLATFORM)
1543+
return LittleFS.format();
1544+
#elif defined(ESP32)
1545+
return SPIFFS.format();
1546+
#else
1547+
#error "need to implement file system erase"
1548+
return false;
1549+
#endif
1550+
}
1551+
1552+
void MyMesh::checkCLIRescueCmd() {
1553+
int len = strlen(cli_command);
1554+
while (Serial.available() && len < sizeof(cli_command)-1) {
1555+
char c = Serial.read();
1556+
if (c != '\n') {
1557+
cli_command[len++] = c;
1558+
cli_command[len] = 0;
1559+
}
1560+
Serial.print(c); // echo
1561+
}
1562+
if (len == sizeof(cli_command)-1) { // command buffer full
1563+
cli_command[sizeof(cli_command)-1] = '\r';
1564+
}
1565+
1566+
if (len > 0 && cli_command[len - 1] == '\r') { // received complete line
1567+
cli_command[len - 1] = 0; // replace newline with C string null terminator
1568+
1569+
if (memcmp(cli_command, "set ", 4) == 0) {
1570+
const char* config = &cli_command[4];
1571+
if (memcmp(config, "pin ", 4) == 0) {
1572+
_prefs.ble_pin = atoi(&config[4]);
1573+
savePrefs();
1574+
Serial.printf(" > pin is now %06d\n", _prefs.ble_pin);
1575+
} else {
1576+
Serial.printf(" Error: unknown config: %s\n", config);
1577+
}
1578+
} else if (strcmp(cli_command, "rebuild") == 0) {
1579+
bool success = formatFileSystem();
1580+
if (success) {
1581+
saveMainIdentity(self_id);
1582+
saveContacts();
1583+
Serial.println(" > erase and rebuild done");
1584+
} else {
1585+
Serial.println(" Error: erase failed");
1586+
}
1587+
} else if (strcmp(cli_command, "erase") == 0) {
1588+
bool success = formatFileSystem();
1589+
if (success) {
1590+
Serial.println(" > erase done");
1591+
} else {
1592+
Serial.println(" Error: erase failed");
1593+
}
1594+
} else if (strcmp(cli_command, "reboot") == 0) {
1595+
board.reboot(); // doesn't return
1596+
} else {
1597+
Serial.println(" Error: unknown command");
1598+
}
1599+
1600+
cli_command[0] = 0; // reset command buffer
1601+
}
1602+
}
15341603

1604+
void MyMesh::checkSerialInterface() {
15351605
size_t len = _serial->checkRecvFrame(cmd_frame);
15361606
if (len > 0) {
15371607
handleCmdFrame(len);
@@ -1556,6 +1626,16 @@ void MyMesh::loop() {
15561626
} else if (!_serial->isWriteBusy()) {
15571627
checkConnections();
15581628
}
1629+
}
1630+
1631+
void MyMesh::loop() {
1632+
BaseChatMesh::loop();
1633+
1634+
if (_cli_rescue) {
1635+
checkCLIRescueCmd();
1636+
} else {
1637+
checkSerialInterface();
1638+
}
15591639

15601640
// is there are pending dirty contacts write needed?
15611641
if (dirty_contacts_expiry && millisHasNowPassed(dirty_contacts_expiry)) {

examples/companion_radio/MyMesh.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class MyMesh : public BaseChatMesh {
9292
void loop();
9393
void handleCmdFrame(size_t len);
9494
bool advert();
95+
void enterCLIRescue();
9596

9697
protected:
9798
float getAirtimeBudgetFactor() const override;
@@ -143,6 +144,10 @@ class MyMesh : public BaseChatMesh {
143144
int getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]) override;
144145
bool putBlobByKey(const uint8_t key[], int key_len, const uint8_t src_buf[], int len) override;
145146

147+
void checkCLIRescueCmd();
148+
void checkSerialInterface();
149+
bool formatFileSystem();
150+
146151
private:
147152
FILESYSTEM *_fs;
148153
IdentityStore *_identity_store;
@@ -157,6 +162,8 @@ class MyMesh : public BaseChatMesh {
157162
uint32_t _most_recent_lastmod;
158163
uint32_t _active_ble_pin;
159164
bool _iter_started;
165+
bool _cli_rescue;
166+
char cli_command[80];
160167
uint8_t app_target_ver;
161168
uint8_t *sign_data;
162169
uint32_t sign_data_len;

examples/companion_radio/UITask.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ void UITask::begin(DisplayDriver* display, NodePrefs* node_prefs) {
7575
_userButton->onLongPress([this]() { handleButtonLongPress(); });
7676
_userButton->onAnyPress([this]() { handleButtonAnyPress(); });
7777
#endif
78+
ui_started_at = millis();
7879
}
7980

8081
void UITask::soundBuzzer(UIEventType bet) {
@@ -365,5 +366,9 @@ void UITask::handleButtonTriplePress() {
365366

366367
void UITask::handleButtonLongPress() {
367368
MESH_DEBUG_PRINTLN("UITask: long press triggered");
368-
shutdown();
369+
if (millis() - ui_started_at < 8000) { // long press in first 8 seconds since startup -> CLI/rescue
370+
the_mesh.enterCLIRescue();
371+
} else {
372+
shutdown();
373+
}
369374
}

examples/companion_radio/UITask.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class UITask {
3636
int _msgcount;
3737
bool _need_refresh = true;
3838
bool _displayWasOn = false; // Track display state before button press
39+
unsigned long ui_started_at;
3940

4041
// Button handlers
4142
#if defined(PIN_USER_BTN) || defined(PIN_USER_BTN_ANA)
@@ -57,7 +58,8 @@ class UITask {
5758
public:
5859

5960
UITask(mesh::MainBoard* board) : _board(board), _display(NULL) {
60-
_next_refresh = 0;
61+
_next_refresh = 0;
62+
ui_started_at = 0;
6163
_connected = false;
6264
}
6365
void begin(DisplayDriver* display, NodePrefs* node_prefs);

variants/heltec_tracker/platformio.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ extends = Heltec_tracker_base
3939
build_flags =
4040
${Heltec_tracker_base.build_flags}
4141
-I src/helpers/ui
42-
; -D ARDUINO_USB_CDC_ON_BOOT=1 ; need for debugging
42+
-D ARDUINO_USB_CDC_ON_BOOT=1 ; need for Serial
4343
-D DISPLAY_ROTATION=1
4444
-D DISPLAY_CLASS=ST7735Display
4545
-D MAX_CONTACTS=100

0 commit comments

Comments
 (0)