mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-23 07:32:27 +00:00
82 lines
3.3 KiB
Python
82 lines
3.3 KiB
Python
"""Build-local NVS preservation for callback-free USB migration bridges.
|
|
|
|
Arduino normally erases the entire NVS partition on NO_FREE_PAGES or a newer
|
|
NVS version before setup() runs. That destroys staged identity/configuration.
|
|
For dedicated USB bridges only, retain the initialization error and leave NVS
|
|
untouched; the runtime then refuses and returns to its recovery transport.
|
|
The shared Arduino SDK and normal firmware builds are never modified.
|
|
"""
|
|
|
|
import hashlib
|
|
from pathlib import Path
|
|
|
|
|
|
PINNED_MISC_SHA256 = "d6374832d4e7d987e8c9eb71aa36f12e6f03a5d16c298a139a6b222a108788d1"
|
|
GUARD_MARKER = " // MeshCore USB migrator: preserve NVS on initialization failure.\n"
|
|
BINARY_MARKER = "MeshCore USB NVS no-autoerase guard v1"
|
|
MARKER_FUNCTION = '''
|
|
// Referenced by the dedicated USB runtime: a missing middleware must not link.
|
|
const char* meshEsp32MigrationNvsGuardMarker(void) {
|
|
return "MeshCore USB NVS no-autoerase guard v1";
|
|
}
|
|
'''
|
|
AUTOFORMAT = ''' if(err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND){
|
|
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
|
|
if (partition != NULL) {
|
|
err = esp_partition_erase_range(partition, 0, partition->size);
|
|
if(!err){
|
|
err = nvs_flash_init();
|
|
} else {
|
|
log_e("Failed to format the broken NVS partition!");
|
|
}
|
|
} else {
|
|
log_e("Could not find NVS partition");
|
|
}
|
|
}
|
|
'''
|
|
|
|
|
|
def patched_misc_source(source):
|
|
source = source.replace("\r\n", "\n")
|
|
# Permit our own exact transformation to be read again without relaxing the
|
|
# original SDK pin. A stray marker or altered surrounding code is rejected.
|
|
original = source.replace(GUARD_MARKER, AUTOFORMAT) if source.count(GUARD_MARKER) == 1 else source
|
|
if original.endswith(MARKER_FUNCTION):
|
|
original = original[:-len(MARKER_FUNCTION)]
|
|
if (hashlib.sha256(original.encode("utf-8")).hexdigest() != PINNED_MISC_SHA256
|
|
or original.count(AUTOFORMAT) != 1):
|
|
raise RuntimeError("ESP32 USB migration NVS guard: changed Arduino startup; review SDK update")
|
|
return original.replace(AUTOFORMAT, GUARD_MARKER) + MARKER_FUNCTION
|
|
|
|
|
|
def usb_migration_enabled(build_env):
|
|
defines = {}
|
|
for definition in build_env.get("CPPDEFINES", []):
|
|
if isinstance(definition, (tuple, list)):
|
|
defines[definition[0]] = str(definition[1])
|
|
else:
|
|
defines[str(definition)] = "1"
|
|
return defines.get("MESHCORE_MIGRATION_USB") == "1"
|
|
|
|
|
|
def replace_source(build_env, node):
|
|
if not usb_migration_enabled(build_env):
|
|
return node
|
|
source = Path(node.srcnode().get_abspath())
|
|
patched = patched_misc_source(source.read_text(encoding="utf-8"))
|
|
destination = Path(build_env.subst("$BUILD_DIR")) / "patched-esp32-migration" / source.name
|
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
if not destination.exists() or destination.read_text(encoding="utf-8") != patched:
|
|
destination.write_text(patched, encoding="utf-8")
|
|
build_env.AppendUnique(CPPPATH=[str(source.parent)])
|
|
return build_env.File(str(destination))
|
|
|
|
|
|
def install(build_env):
|
|
build_env.AddBuildMiddleware(replace_source, "*cores*esp32*esp32-hal-misc.c")
|
|
|
|
|
|
if "Import" in globals():
|
|
Import("env")
|
|
install(env)
|