mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-20 22:01:58 +00:00
60 lines
2.6 KiB
Python
60 lines
2.6 KiB
Python
"""Build private AsyncTCP fixes and the current vendored OTA implementation."""
|
|
import hashlib
|
|
from pathlib import Path
|
|
|
|
|
|
PINNED_ASYNCTCP_SHA256 = "27e3e22a6030cc5c9c9f32f28d0a3a36189b1ea6a5fa270777b2d2790a89c365"
|
|
ORIGINAL_BIND = " msg->err = tcp_bind(pcb, msg->bind.addr, msg->bind.port);"
|
|
REUSABLE_BIND = """ // A stopped HTTP listener may still have completed connections in
|
|
// TIME_WAIT. Permit immediate rebinding during WebConfig/OTA handoffs.
|
|
#if SO_REUSE
|
|
ip_set_option(pcb, SOF_REUSEADDR);
|
|
#endif
|
|
""" + ORIGINAL_BIND
|
|
|
|
|
|
def patched_async_tcp(source):
|
|
source = source.replace("\r\n", "\n")
|
|
if (hashlib.sha256(source.encode("ascii")).hexdigest() != PINNED_ASYNCTCP_SHA256
|
|
or source.count(ORIGINAL_BIND) != 1):
|
|
raise RuntimeError("AsyncTCP restart fix: changed pinned source; review library update")
|
|
return source.replace(ORIGINAL_BIND, REUSABLE_BIND, 1)
|
|
|
|
|
|
def replace_async_source(build_env, node):
|
|
source = Path(node.srcnode().get_abspath())
|
|
if source.name == "AsyncTCP.cpp":
|
|
content = patched_async_tcp(source.read_text(encoding="utf-8"))
|
|
include_dir = source.parent
|
|
elif source.name == "AsyncElegantOTA.cpp":
|
|
# file:// dependencies can retain an earlier copy in .pio/libdeps.
|
|
# Compile this checkout's vendored source without editing that cache.
|
|
include_dir = Path(build_env.subst("$PROJECT_DIR")) / "arch/esp32/AsyncElegantOTA/src"
|
|
content = (include_dir / source.name).read_text(encoding="ascii")
|
|
else:
|
|
return node
|
|
destination = Path(build_env.subst("$BUILD_DIR")) / "patched-esp32-web" / source.name
|
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
if source.name == "AsyncElegantOTA.cpp":
|
|
# Quoted includes resolve beside this private source, ahead of any
|
|
# stale library include path inherited by PlatformIO's build clone.
|
|
for name in ("AsyncElegantOTA.h", "Hash.h", "elegantWebpage.h"):
|
|
header = (include_dir / name).read_bytes()
|
|
target = destination.parent / name
|
|
if not target.exists() or target.read_bytes() != header:
|
|
target.write_bytes(header)
|
|
if not destination.exists() or destination.read_text(encoding="ascii") != content:
|
|
destination.write_text(content, encoding="ascii")
|
|
build_env.PrependUnique(CPPPATH=[str(include_dir)])
|
|
return build_env.File(str(destination))
|
|
|
|
|
|
def install(build_env):
|
|
build_env.AddBuildMiddleware(replace_async_source, "*AsyncTCP*src*AsyncTCP.cpp")
|
|
build_env.AddBuildMiddleware(replace_async_source, "*AsyncElegantOTA*src*AsyncElegantOTA.cpp")
|
|
|
|
|
|
if "Import" in globals():
|
|
Import("env")
|
|
install(env)
|