Skip to content

Align flood-scope handling with firmware semantics#91

Open
Bjorkan wants to merge 2 commits into
openhop-dev:devfrom
Bjorkan:regionfix
Open

Align flood-scope handling with firmware semantics#91
Bjorkan wants to merge 2 commits into
openhop-dev:devfrom
Bjorkan:regionfix

Conversation

@Bjorkan

@Bjorkan Bjorkan commented Jun 27, 2026

Copy link
Copy Markdown

Summary

This updates flood-scope handling to match the firmware semantics for SET_FLOOD_SCOPE.

SET_FLOOD_SCOPE mode 0 with a 16-byte all-zero key is now treated as a null override rather than as an explicit request to send unscoped. This means it falls back to the configured default scope when one is present, matching firmware behavior.

Explicit unscoped sending is now handled through mode 1 and remains sticky until a subsequent mode 0 set/reset. This matches the behavior used by Companion v12.

Changes

  • Treat mode 0 with an all-zero key as a null override.
  • Fall back to the configured default scope instead of forcing plain flood.
  • Handle explicit unscoped sending through mode 1.
  • Make mode 1 sticky until a mode 0 set/reset.
  • Tighten unsupported mode handling.
  • Add and update tests for:
    • zero-key fallback to default scope
    • sticky unscoped mode behavior
    • unsupported mode handling

Testing

Full test suite passes locally:

900 passed

Treat a 16-byte all-zero flood scope key as an explicit disabled scope instead of a transient transport key. This keeps Remote Terminal empty flood_scope sends as plain flood packets, including when a default scope is configured.

Add regression tests for zero-key disabling, persistent default-scope bypass, and clearing the disabled state.
@rightup

rightup commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

@agessaman

@agessaman

Copy link
Copy Markdown
Contributor

The inconsistency comes down to one wire message (SET_FLOOD_SCOPE mode 0 + a 16-byte all-zero key) being interpreted three different ways.

What meshcore_py (and thus RemoteTerm) means by it: its set_flood_scope sends the all-zero key whenever the caller passes None, "", "0", or "*" — and its own code labels that "disable" / "send unscoped." So in meshcore_py's model, zero key = no scope, flood plain.

What this PR does: it adds _flood_scope_disabled so that an all-zero key returns None from _resolve_flood_transport_key() and bypasses any configured default scope → plain flood. That matches meshcore_py's intent exactly.

What the firmware does: the all-zero key makes send_scope.isNull() true, which is treated as no override and falls back to the default scope (send_scope.isNull() ? &default_scope : &send_scope). It does not mean
"unscoped." The firmware's only way to force unscoped-past-default is the separate mode-1 command frame (0x36 0x01).

So the divergence is precisely the default-scope case:

zero key + default scope set Result
meshcore_py intent plain flood
This PR plain flood ✓ matches meshcore_py
Firmware scoped to the default ✗ opposite

I would prefer to conform to the firmware's interpretation and send 0x36 0x01 to toggle following messages to send unscoped, if that is the intention. This would be a change in behavior in meshcore_py.

There is also a behavior change in OpenHop_core that is necessary, because we currently treat mode-1 switches as single-shot. Instead, we need to treat them as sticky. This change was done in Companion Version 12 without any fanfare, although the app still sends the 0x36 0x01 switch before any message packet when a default scope is set if the channel's scope setting is set to *.

Basically, this PR would fix RemoteTerm and other meshcore_py-based apps, but would break firmware consistency. Let me know if you want to do the PR to fix meshcore_py or I can send one over.

Treat SET_FLOOD_SCOPE mode 0 with an all-zero key as a null override so default flood scope still applies, matching firmware behavior.

Make explicit unscoped mode sticky until a mode 0 scope set/reset, reject unsupported flood scope modes, and update tests/docs for the firmware semantics.
@Bjorkan

Bjorkan commented Jun 27, 2026

Copy link
Copy Markdown
Author

The inconsistency comes down to one wire message (SET_FLOOD_SCOPE mode 0 + a 16-byte all-zero key) being interpreted three different ways.

What meshcore_py (and thus RemoteTerm) means by it: its set_flood_scope sends the all-zero key whenever the caller passes None, "", "0", or "*" — and its own code labels that "disable" / "send unscoped." So in meshcore_py's model, zero key = no scope, flood plain.

What this PR does: it adds _flood_scope_disabled so that an all-zero key returns None from _resolve_flood_transport_key() and bypasses any configured default scope → plain flood. That matches meshcore_py's intent exactly.

What the firmware does: the all-zero key makes send_scope.isNull() true, which is treated as no override and falls back to the default scope (send_scope.isNull() ? &default_scope : &send_scope). It does not mean "unscoped." The firmware's only way to force unscoped-past-default is the separate mode-1 command frame (0x36 0x01).

So the divergence is precisely the default-scope case:
zero key + default scope set Result
meshcore_py intent plain flood
This PR plain flood ✓ matches meshcore_py
Firmware scoped to the default ✗ opposite

I would prefer to conform to the firmware's interpretation and send 0x36 0x01 to toggle following messages to send unscoped, if that is the intention. This would be a change in behavior in meshcore_py.

There is also a behavior change in OpenHop_core that is necessary, because we currently treat mode-1 switches as single-shot. Instead, we need to treat them as sticky. This change was done in Companion Version 12 without any fanfare, although the app still sends the 0x36 0x01 switch before any message packet when a default scope is set if the channel's scope setting is set to *.

Basically, this PR would fix RemoteTerm and other meshcore_py-based apps, but would break firmware consistency. Let me know if you want to do the PR to fix meshcore_py or I can send one over.

Updated this to match the firmware semantics rather than the previous meshcore_py interpretation.

SET_FLOOD_SCOPE mode 0 with an all-zero key is now treated as a null override, so it falls back to the configured default scope instead of forcing plain flood. Explicit unscoped sending is now handled via mode 1 and remains sticky until a mode 0 set/reset, matching Companion v12 behavior.

I also tightened unsupported mode handling and added/updated tests for the zero-key default-scope case and sticky unscoped behavior.

Full test suite passes locally: 900 passed.

I can send a PR to RemoteTerm aswell! jkingsman/Remote-Terminal-for-MeshCore#307

@Bjorkan Bjorkan changed the title Fix zero flood-scope key handling Align flood-scope handling with firmware semantics Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants