From 3385f2acaa7e8a48e24fd6dd323458e7d46454bd Mon Sep 17 00:00:00 2001 From: mikecarper Date: Wed, 28 Oct 2026 03:03:48 -0700 Subject: [PATCH] Avoid repeated channel alias parsing in constrained companions --- examples/companion_radio/MyMesh.cpp | 2 +- scripts/nrf52_flash_trim.py | 10 ++++++---- src/helpers/CompanionChannelAlias.h | 9 ++++++--- test/test_companion_channel_alias.py | 10 ++++++++++ test/test_nrf52_flash_trim.py | 3 ++- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 1462194ca..6f34b2d85 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -1785,7 +1785,7 @@ bool MyMesh::resolveChannelAlias(ChannelDetails& channel) const { })) return false; const auto kind = parseCompanionChannelAlias(channel.name).kind; #if MESH_ENABLE_MESHTEXT_CHAT - if (isMeshtextChannel(channel)) channel.channel.tx_radio = mesh::RADIO_TX_OFF; + if (kind == CompanionChannelKind::Meshtext) channel.channel.tx_radio = mesh::RADIO_TX_OFF; #endif if (isAliasRadio2Defined() && (kind == CompanionChannelKind::Radio2 || kind == CompanionChannelKind::Meshtext)) { diff --git a/scripts/nrf52_flash_trim.py b/scripts/nrf52_flash_trim.py index 104243055..0433ccd20 100644 --- a/scripts/nrf52_flash_trim.py +++ b/scripts/nrf52_flash_trim.py @@ -259,7 +259,7 @@ def compile_packed_help(build_env, node): return build_env.Object(node, **flags) -def _compile_shared_reply_copies(build_env, node, relative_path): +def _compile_shared_reply_copies(build_env, node, relative_path, extra_flags=()): source = Path(node.srcnode().get_abspath()).resolve() expected = Path(build_env.subst("$PROJECT_DIR/" + relative_path)).resolve() if source != expected: @@ -267,8 +267,9 @@ def _compile_shared_reply_copies(build_env, node, relative_path): # GCC otherwise expands many constant strcpy replies into repeated stores. # Use the same libc function and strings, with no parser or output changes. flags = list(build_env.get("CCFLAGS", ())) - if "-fno-builtin-strcpy" not in flags: - flags.append("-fno-builtin-strcpy") + for flag in ("-fno-builtin-strcpy", *extra_flags): + if flag not in flags: + flags.append(flag) return build_env.Object(node, CCFLAGS=flags) @@ -278,7 +279,8 @@ def compile_shared_cli_replies(build_env, node): def compile_shared_companion_replies(build_env, node): - return _compile_shared_reply_copies(build_env, node, "examples/companion_radio/MyMesh.cpp") + return _compile_shared_reply_copies(build_env, node, "examples/companion_radio/MyMesh.cpp", + ("-fno-builtin-strncpy",)) def companion_shared_replies_policy(platform, mcu, env_name, src_filter, diff --git a/src/helpers/CompanionChannelAlias.h b/src/helpers/CompanionChannelAlias.h index 7c434b595..1c741bcc3 100644 --- a/src/helpers/CompanionChannelAlias.h +++ b/src/helpers/CompanionChannelAlias.h @@ -34,9 +34,12 @@ inline CompanionChannelAlias parseCompanionChannelAlias(const char* name) { // Only exact named radio2 aliases request RF setup. Ordinary channels and // arbitrary r2 labels keep the operator's existing profile. inline const char* companionChannelRadio2Preset(const char* name) { - const auto alias = parseCompanionChannelAlias(name); - return alias.kind == CompanionChannelKind::Radio2 - && mesh::cli::radio2PresetTuple(alias.tail) ? alias.tail : nullptr; + if (!name) return nullptr; + if (*name == '#') ++name; + if (strncmp(name, "r2-", 3)) return nullptr; + name += 3; + // An exact preset tail also excludes every invalid/nested alias form. + return mesh::cli::radio2PresetTuple(name) ? name : nullptr; } inline bool companionChannelCanonicalName(const char* name, char* out, size_t size) { diff --git a/test/test_companion_channel_alias.py b/test/test_companion_channel_alias.py index f70154efd..bf18b9e7f 100644 --- a/test/test_companion_channel_alias.py +++ b/test/test_companion_channel_alias.py @@ -94,6 +94,16 @@ static void grammar() { assert(!companionChannelRadio2Preset(name)); } assert(!companionChannelRadio2Preset(nullptr)); + for (const char* prefix : {"", "#", "r2-", "#r2-", "mt-", "#mt-", "r2-r2-", "#r2-mt-"}) { + for (const char* tail : {"", "r", "r2", "#", "mediamesh", "mediamesh-range", + "MediaMesh", "mediamesh-extra", "mediamesh,32"}) { + char name[64]; snprintf(name, sizeof(name), "%s%s", prefix, tail); + const auto alias = parseCompanionChannelAlias(name); + const char* expected = alias.kind == CompanionChannelKind::Radio2 + && mesh::cli::radio2PresetTuple(alias.tail) ? alias.tail : nullptr; + assert(companionChannelRadio2Preset(name) == expected); + } + } puts("PASS grammar"); } static void canonical() { diff --git a/test/test_nrf52_flash_trim.py b/test/test_nrf52_flash_trim.py index 74dad3fbc..55a3ebf89 100644 --- a/test/test_nrf52_flash_trim.py +++ b/test/test_nrf52_flash_trim.py @@ -127,7 +127,8 @@ class Nrf52FlashTrimTest(unittest.TestCase): companion = Node(ROOT / "examples/companion_radio/MyMesh.cpp") result, flags = TRIM.compile_shared_companion_replies(env, companion) self.assertIs(result, companion) - self.assertEqual(flags["CCFLAGS"], ["-Os", "-flto", "-fno-builtin-strcpy"]) + self.assertEqual(flags["CCFLAGS"], ["-Os", "-flto", "-fno-builtin-strcpy", + "-fno-builtin-strncpy"]) self.assertEqual(env["CCFLAGS"], ["-Os", "-flto"]) for path in ("examples/simple_repeater/MyMesh.cpp", "test/fixtures/MyMesh.cpp", "src/helpers/CommonCLI.cpp", "src/helpers/RadioProfileCLI.cpp"):