Use compact scalar crypto, reviewed GNSS version parsing and shared CLI reply copies for RAK3401/RAK4631 repeaters. Preserve keys, protocols, commands and configured capacities. Both Reduced images save 11,580 bytes. SWD measurements on the RAK3401 found scalar-only signing still near 50.9 ms and key exchange near 38 ms. Keep compact field arithmetic off: its extra 4.3 KiB saving adds about a quarter second and delays radio servicing. Validate Full and Reduced production OTA packages on both boards, focused crypto/GPS/CLI tests, and linked ARM crypto outputs. Include the RAM benchmark harness and scoped results. No live RF packet-loss qualification is claimed.
85 lines
3.7 KiB
Python
85 lines
3.7 KiB
Python
"""Keep the reviewed GNSS version parser without linking the scanf engine.
|
|
|
|
Qualified nRF52 Companion and RAK3401/RAK4631 Repeater trims install this
|
|
middleware. Compile a private copy of the reviewed SparkFun GNSS sources;
|
|
never change downloaded dependencies.
|
|
Unknown sources or headers retain their ordinary implementation.
|
|
"""
|
|
|
|
import hashlib
|
|
from pathlib import Path
|
|
|
|
|
|
SOURCE_NAME = "SparkFun_u-blox_GNSS_Arduino_Library.cpp"
|
|
SOURCE_SHA256 = "8ed1d313177df864b6821b3cb3e4fbcc59d850d09e2460269d571f70cd2b9f1c"
|
|
# 2.2.28 has the same version parser and headers as 2.2.29. Its only source
|
|
# differences are two file-buffer boundary checks, which this trim preserves.
|
|
SOURCE_2_2_28_SHA256 = "4c6c40fe01b15b486791d9ceb045093a394bf157489c2b22d96d7afb92789c49"
|
|
HEADERS = {
|
|
"SparkFun_u-blox_GNSS_Arduino_Library.h": "5da7a95ddd4b24e26ca474d017a6a5347137a31aee58fb7b450a4ce85bbcc07a",
|
|
"u-blox_config_keys.h": "86cae35ec200871f748be21d6d59583c48db82621f4c5504e257e8358a241499",
|
|
"u-blox_structs.h": "59c0a7db1e3fe8eb78692a3ef9411f12048573a6513c41937e51e9d5ede06498",
|
|
}
|
|
ORIGINAL_CONVERSION = ''' int scanned = sscanf(ptr, "%d.%d", &protHi, &protLo);'''
|
|
VERSION_CONVERSION = ''' // Preserve %d.%d conversion, including signs and leading whitespace.
|
|
// strtol is already used by the application; scanf needs a separate engine.
|
|
char *versionEnd;
|
|
protHi = static_cast<int>(strtol(ptr, &versionEnd, 10));
|
|
int scanned = 0;
|
|
if (versionEnd != ptr && *versionEnd == '.')
|
|
{
|
|
const char *minor = versionEnd + 1;
|
|
protLo = static_cast<int>(strtol(minor, &versionEnd, 10));
|
|
if (versionEnd != minor)
|
|
scanned = 2;
|
|
}'''
|
|
INCLUDE = '#include "SparkFun_u-blox_GNSS_Arduino_Library.h"'
|
|
|
|
|
|
def digest(source):
|
|
return hashlib.sha256(source.encode("utf-8")).hexdigest()
|
|
|
|
|
|
def patched_source(source):
|
|
source = source.replace("\r\n", "\n")
|
|
if (digest(source) not in (SOURCE_SHA256, SOURCE_2_2_28_SHA256)
|
|
or source.count(ORIGINAL_CONVERSION) != 1
|
|
or source.count(INCLUDE) != 1):
|
|
raise RuntimeError("changed reviewed SparkFun GNSS source")
|
|
return source.replace(INCLUDE, "#include <stdlib.h>\n" + INCLUDE, 1).replace(
|
|
ORIGINAL_CONVERSION, VERSION_CONVERSION, 1)
|
|
|
|
|
|
def write_if_changed(path, content):
|
|
if not path.exists() or path.read_text(encoding="utf-8") != content:
|
|
path.write_text(content, encoding="utf-8")
|
|
|
|
|
|
def replace_gnss_source(build_env, node):
|
|
source = Path(node.srcnode().get_abspath())
|
|
if source.name != SOURCE_NAME or source.parent.name != "src":
|
|
return node
|
|
try:
|
|
patched = patched_source(source.read_text(encoding="utf-8"))
|
|
headers = {}
|
|
for name, expected in HEADERS.items():
|
|
header = (source.parent / name).read_text(encoding="utf-8").replace("\r\n", "\n")
|
|
if digest(header) != expected:
|
|
raise RuntimeError("changed reviewed SparkFun GNSS header: " + name)
|
|
headers[name] = header
|
|
except (OSError, UnicodeError, RuntimeError) as error:
|
|
print("nRF52 GNSS trim: ordinary source retained (" + str(error) + ")")
|
|
return node
|
|
destination = Path(build_env.subst("$BUILD_DIR")) / "trimmed-nrf52-gnss" / source.name
|
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
# Keep its quoted sibling includes bound to the same reviewed library.
|
|
for name, header in headers.items():
|
|
write_if_changed(destination.parent / name, header)
|
|
write_if_changed(destination, patched)
|
|
print("nRF52 GNSS trim: reviewed version conversion uses strtol")
|
|
return build_env.File(str(destination))
|
|
|
|
|
|
def install(build_env):
|
|
build_env.AddBuildMiddleware(replace_gnss_source, "*" + SOURCE_NAME)
|