@@ -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)) {
0 commit comments