From 0f601752e4e9089a866c2e6d70c439e709c93b94 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sat, 7 Jun 2025 15:23:55 +1200 Subject: [PATCH 1/7] implement ls and cat commands for rescue mode --- examples/companion_radio/DataStore.cpp | 10 ++++++ examples/companion_radio/DataStore.h | 1 + examples/companion_radio/MyMesh.cpp | 48 ++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index a37cfa49..795e38cc 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -42,6 +42,16 @@ void DataStore::begin() { #include #endif +File DataStore::openRead(const char* filename) { +#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM) + return _fs->open(filename, FILE_O_READ); +#elif defined(RP2040_PLATFORM) + return _fs->open(filename, "r"); +#else + return _fs->open(filename, "r", true); +#endif +} + bool DataStore::formatFileSystem() { #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM) return _fs->format(); diff --git a/examples/companion_radio/DataStore.h b/examples/companion_radio/DataStore.h index 139131e1..201dac01 100644 --- a/examples/companion_radio/DataStore.h +++ b/examples/companion_radio/DataStore.h @@ -37,4 +37,5 @@ public: void saveChannels(DataStoreHost* host); uint8_t getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]); bool putBlobByKey(const uint8_t key[], int key_len, const uint8_t src_buf[], uint8_t len); + File openRead(const char* filename); }; diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 054d0cba..79910aee 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1305,6 +1305,54 @@ void MyMesh::checkCLIRescueCmd() { } else { Serial.println(" Error: erase failed"); } + } else if (memcmp(cli_command, "ls", 2) == 0) { + + // get path from command e.g: "ls /adafruit" + const char *path = &cli_command[3]; + + // log each file and directory + File root = _store->openRead(path); + File file = root.openNextFile(); + while (file) { + + if (file.isDirectory()) { + Serial.print("[dir] "); + Serial.println(file.name()); + } else { + Serial.print("[file] "); + Serial.print(file.name()); + Serial.print(" ("); + Serial.print(file.size()); + Serial.println(" bytes)"); + } + + // move to next file + file = root.openNextFile(); + + } + + } else if (memcmp(cli_command, "cat", 3) == 0) { + + // get path from command e.g: "cat /contacts3" + const char *path = &cli_command[4]; + + // log file content as hex + File file = _store->openRead(path); + if(file){ + + // get file content + int file_size = file.available(); + uint8_t buffer[file_size]; + file.read(buffer, file_size); + + // print hex + mesh::Utils::printHex(Serial, buffer, file_size); + Serial.print("\n"); + + file.close(); + + } + } else if (strcmp(cli_command, "reboot") == 0) { board.reboot(); // doesn't return } else { From a22c176d45123361523c9d0209056e78dae8ef3b Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sat, 7 Jun 2025 15:44:36 +1200 Subject: [PATCH 2/7] add rm command to remove file --- examples/companion_radio/DataStore.cpp | 4 ++++ examples/companion_radio/DataStore.h | 1 + examples/companion_radio/MyMesh.cpp | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index 795e38cc..508b270e 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -52,6 +52,10 @@ File DataStore::openRead(const char* filename) { #endif } +bool DataStore::removeFile(const char* filename) { + return _fs->remove(filename); +} + bool DataStore::formatFileSystem() { #if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM) return _fs->format(); diff --git a/examples/companion_radio/DataStore.h b/examples/companion_radio/DataStore.h index 201dac01..32ccd196 100644 --- a/examples/companion_radio/DataStore.h +++ b/examples/companion_radio/DataStore.h @@ -38,4 +38,5 @@ public: uint8_t getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]); bool putBlobByKey(const uint8_t key[], int key_len, const uint8_t src_buf[], uint8_t len); File openRead(const char* filename); + bool removeFile(const char* filename); }; diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 79910aee..63fbf142 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1353,6 +1353,19 @@ void MyMesh::checkCLIRescueCmd() { } + } else if (memcmp(cli_command, "rm ", 3) == 0) { + + // get path from command e.g: "rm /adv_blobs" + const char *path = &cli_command[4]; + + // remove file + bool removed = _store->removeFile(path); + if(removed){ + Serial.println("File removed"); + } else { + Serial.println("Failed to remove file"); + } + } else if (strcmp(cli_command, "reboot") == 0) { board.reboot(); // doesn't return } else { From 9d574b2de0a3ba9cd2ef27359d745343c02420fc Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sat, 7 Jun 2025 16:03:04 +1200 Subject: [PATCH 3/7] ensure user isn't removing invalid path --- examples/companion_radio/MyMesh.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 63fbf142..4d3860c3 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1357,13 +1357,20 @@ void MyMesh::checkCLIRescueCmd() { // get path from command e.g: "rm /adv_blobs" const char *path = &cli_command[4]; - - // remove file - bool removed = _store->removeFile(path); - if(removed){ - Serial.println("File removed"); + + // ensure path is not empty, or root dir + if(!path || strlen(path) == 0 || strcmp(path, "/") == 0){ + Serial.println("Invalid path provided"); } else { - Serial.println("Failed to remove file"); + + // remove file + bool removed = _store->removeFile(path); + if(removed){ + Serial.println("File removed"); + } else { + Serial.println("Failed to remove file"); + } + } } else if (strcmp(cli_command, "reboot") == 0) { From a814bfb00be1fabb164c1986fc5c8ab850b7bbeb Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sat, 7 Jun 2025 16:17:45 +1200 Subject: [PATCH 4/7] don't create file when trying to open for read --- examples/companion_radio/DataStore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index 508b270e..2ba5ccfb 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -48,7 +48,7 @@ File DataStore::openRead(const char* filename) { #elif defined(RP2040_PLATFORM) return _fs->open(filename, "r"); #else - return _fs->open(filename, "r", true); + return _fs->open(filename, "r", false); #endif } From a50f89f16f1a67b066e3414ae2e6fff4184ecc8b Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sat, 7 Jun 2025 17:38:22 +1200 Subject: [PATCH 5/7] ensure root path is usable --- examples/companion_radio/MyMesh.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 4d3860c3..68e9d615 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1312,8 +1312,9 @@ void MyMesh::checkCLIRescueCmd() { // log each file and directory File root = _store->openRead(path); - File file = root.openNextFile(); - while (file) { + if(root){ + File file = root.openNextFile(); + while (file) { if (file.isDirectory()) { Serial.print("[dir] "); @@ -1329,6 +1330,7 @@ void MyMesh::checkCLIRescueCmd() { // move to next file file = root.openNextFile(); + } } } else if (memcmp(cli_command, "cat", 3) == 0) { From 28edff43fd91038456046a095e2a399a1c78dab6 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sat, 7 Jun 2025 17:42:18 +1200 Subject: [PATCH 6/7] simplify serial print --- examples/companion_radio/MyMesh.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 68e9d615..9c8b96b1 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1317,14 +1317,9 @@ void MyMesh::checkCLIRescueCmd() { while (file) { if (file.isDirectory()) { - Serial.print("[dir] "); - Serial.println(file.name()); + Serial.printf("[dir] %s\n", file.name()); } else { - Serial.print("[file] "); - Serial.print(file.name()); - Serial.print(" ("); - Serial.print(file.size()); - Serial.println(" bytes)"); + Serial.printf("[file] %s (%d bytes)\n", file.name(), file.size()); } // move to next file From 7f79d0c5142a9b43e87d29d1e865c368ca3bf934 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Sat, 7 Jun 2025 17:56:20 +1200 Subject: [PATCH 7/7] close roor dir after listing files --- examples/companion_radio/MyMesh.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 9c8b96b1..2b98ec04 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1326,6 +1326,7 @@ void MyMesh::checkCLIRescueCmd() { file = root.openNextFile(); } + root.close(); } } else if (memcmp(cli_command, "cat", 3) == 0) {