Improve companion setup and USB session recovery

This commit is contained in:
mikecarper committed 2026-09-02 03:44:28 -07:00
1 parent ecaa5ac2a0
commit cf70478c51
34 files changed
+6283 -2147

No files matched your search

+162
View File
@@ -0,0 +1,162 @@
#include "StorageLayout.h"
#if defined(ESP32_PLATFORM)
#include <Arduino.h>
#include <esp_ota_ops.h>
#include <esp_partition.h>
#elif defined(NRF52_PLATFORM)
#include <stdarg.h>
#include <nrf.h>
#include "ota/OtaFlashLayout_nrf52.h"
#elif defined(STM32_PLATFORM)
#include <InternalFileSystem.h>
#endif
#if defined(ENABLE_OTA)
#include "ota/OtaContext.h"
#endif
namespace mesh {
namespace cli {
#if defined(NRF52_PLATFORM)
static void appendStorageLayout(char* reply, size_t reply_size,
const char* format, ...) {
if (reply == nullptr || reply_size == 0) return;
const size_t used = strlen(reply);
if (used >= reply_size) return;
va_list args;
va_start(args, format);
vsnprintf(reply + used, reply_size - used, format, args);
va_end(args);
}
#endif
void formatStorageLayout(MainBoard& board, char* reply, size_t reply_size) {
if (reply == nullptr || reply_size == 0) return;
reply[0] = 0;
#if defined(ESP32_PLATFORM)
(void)board;
Esp32StorageLayoutWriter writer(reply, reply_size,
ESP.getFlashChipSize());
const esp_partition_t* running = esp_ota_get_running_partition();
esp_partition_iterator_t iterator = esp_partition_find(
ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL);
while (iterator != NULL) {
const esp_partition_t* partition = esp_partition_get(iterator);
if (!writer.append(
partition->label, partition->address, partition->size,
running != NULL && partition->address == running->address)) {
break;
}
iterator = esp_partition_next(iterator);
}
if (iterator != NULL) esp_partition_iterator_release(iterator);
writer.finish();
#elif defined(NRF52_PLATFORM)
const uint32_t flash_bytes =
(uint32_t)NRF_FICR->CODEPAGESIZE * (uint32_t)NRF_FICR->CODESIZE;
const uint32_t app_start = mesh::ota::mota_nrf52_app_base();
const uint32_t app_end =
(uint32_t)(uintptr_t)mesh::ota::__flash_arduino_end;
#if defined(NRF52840_XXAA)
const uint32_t internal_fs_start = 0x000ED000UL;
#else
const uint32_t internal_fs_start = 0x0006D000UL;
#endif
const uint32_t internal_fs_size = 7UL * 4096UL;
snprintf(reply, reply_size,
"> int:nrf52=%luK app=0x%lX-0x%lX ifs=0x%lX+%luK",
(unsigned long)(flash_bytes / 1024UL),
(unsigned long)app_start, (unsigned long)app_end,
(unsigned long)internal_fs_start,
(unsigned long)(internal_fs_size / 1024UL));
#if defined(ENABLE_OTA) && defined(OTA_QSPI_STORE)
(void)board;
mesh::ota::OtaStoreQspiNrf52& store = mesh::ota::ota_ctx().fetch_store;
const uint32_t capacity = store.capacity();
if (capacity != 0) {
appendStorageLayout(reply, reply_size,
"; ext:qspi=%luK owner=ota-raw id=%06lX",
(unsigned long)(capacity / 1024UL),
(unsigned long)store.jedec_id());
} else {
appendStorageLayout(reply, reply_size, "; ext:qspi=error(%s)",
store.last_error());
}
#elif defined(ENABLE_OTA) && defined(OTA_SD_STORE)
uint64_t used_bytes = 0;
uint64_t free_bytes = 0;
mesh::ota::OtaStoreSdNrf52& store = mesh::ota::ota_ctx().fetch_store;
if (store.getSpace(board, used_bytes, free_bytes)) {
char total[24];
char used[24];
char free[24];
formatStorageBytes(total, sizeof(total), used_bytes + free_bytes);
formatStorageBytes(used, sizeof(used), used_bytes);
formatStorageBytes(free, sizeof(free), free_bytes);
appendStorageLayout(reply, reply_size,
"; ext:sd=%s used=%s free=%s owner=ota", total,
used, free);
} else {
appendStorageLayout(reply, reply_size, "; ext:sd=error(%s)",
store.last_error());
}
#elif defined(QSPIFLASH)
(void)board;
appendStorageLayout(reply, reply_size,
"; ext:qspi=configured owner=littlefs");
#else
(void)board;
appendStorageLayout(reply, reply_size, "; ext:none");
#endif
#elif defined(RP2040_PLATFORM)
(void)board;
#if defined(PICO_FLASH_SIZE_BYTES) && defined(FS_START) && defined(FS_END)
snprintf(reply, reply_size,
"> int:rp2040=%luK ifs=%luK layout=fixed; ext:none",
(unsigned long)(PICO_FLASH_SIZE_BYTES / 1024UL),
(unsigned long)(((uintptr_t)FS_END - (uintptr_t)FS_START) /
1024UL));
#elif defined(PICO_FLASH_SIZE_BYTES)
snprintf(reply, reply_size,
"> int:rp2040=%luK layout=fixed; ext:none",
(unsigned long)(PICO_FLASH_SIZE_BYTES / 1024UL));
#else
snprintf(reply, reply_size, "> int:rp2040 layout=fixed; ext:none");
#endif
#elif defined(STM32_PLATFORM)
(void)board;
snprintf(reply, reply_size,
"> int:stm32=%luK ifs=0x%lX+%luK layout=fixed; ext:none",
(unsigned long)((FLASH_END_ADDR - FLASH_BASE + 1UL) / 1024UL),
(unsigned long)LFS_FLASH_ADDR_BASE,
(unsigned long)(LFS_FLASH_TOTAL_SIZE / 1024UL));
#else
(void)board;
snprintf(reply, reply_size,
"Error: storage layout unsupported on this platform");
#endif
}
bool handleStorageLayoutGet(const char* config, MainBoard& board, char* reply,
size_t reply_size) {
const StorageLayoutGetMatch match = classifyStorageLayoutGet(config);
if (match == StorageLayoutGetMatch::NotMatched) return false;
if (reply == nullptr || reply_size == 0) return true;
if (match == StorageLayoutGetMatch::InvalidArguments) {
snprintf(reply, reply_size, "Error: use get storage.layout");
} else {
formatStorageLayout(board, reply, reply_size);
}
return true;
}
} // namespace cli
} // namespace mesh