Skip to content

Re-resolve held sends when routing information changes - #95

Merged
puddly merged 30 commits into
devfrom
puddly/re-resolve-held-sends
Nov 13, 2026
Merged

puddly merged 30 commits into
devfrom
puddly/re-resolve-held-sends

Conversation

@puddly

@puddly puddly commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Currently, Ziggurat only considers a route resolved when a route discovery is explicitly answered.

This isn't the only way a route can be discovered, there are some implicit sources that this PR now allows Ziggurat to consider:

  • With source routing, a route record arrives after discovery has started. This provides routing information independent from the discovery and can be used immediately.
  • A device-originated route request
  • A route reply that passes through the coordinator

To simplify the design, I've consolidated route discovery logic into the routing table. This slowly drifted during the various redesigns and is now roped back into one spot.

Copilot AI balanced review requested due to automatic review settings November 12, 2026 19:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Discovery cleanup can incorrectly mark a successfully learned active route as failed, while conditional wakeups can leave held sends blocked despite available routes.

2 open issues
What changed in this PR

This PR lets held Zigbee unicasts use newly learned routing information without waiting for an explicit reply to their own route discovery.

Changes:

  • Moves route re-resolution, discovery retries, and deadline scheduling into the send-table timer pass.
  • Adds timer wakeups for route records and fails stale held sends when a device rejoins.
  • Removes the obsolete “route inactive after discovery” error and protocol status.
File Description
crates/​ziggurat-zigbee/​src/​sends/​unrouted.rs Adds per-send access and discovery cleanup helpers.
crates/​ziggurat-zigbee/​src/​sends/​mod.rs Re-resolves held sends and coordinates discovery timing.
crates/​ziggurat-protocol/​src/​wire.rs Removes the obsolete send-status variant.
crates/​ziggurat-protocol/​src/​bridge.rs Removes the corresponding error-to-status mapping.
crates/​ziggurat-driver/​src/​zigbee_stack/​sends.rs Integrates route resolution with the revised timer API.
crates/​ziggurat-driver/​src/​zigbee_stack/​nwk.rs Wakes sends on route records and shares leave/rejoin cleanup.
crates/​ziggurat-driver/​src/​zigbee_stack.rs Removes the obsolete delivery-error variant.

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Discovery entries are retired before held sends are routed and without matching request IDs, risking stranded sends and accidental removal of newer discoveries.

1 open issue
2 resolved since last review

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Removing legacy wire status 3 breaks compatibility with older v2 firmware, while discovery lifecycle issues can leave broadcasts running and suppress fresh route requests.

No open issues 🎉

3 previously missed issues

In code that hasn't changed since last review

High severity Preserve legacy wire status value 3 for v2 decoding

crates/​ziggurat-protocol/​src/​wire.rs:715

Please retain wire value 3 as a legacy status even though the driver no longer emits it. PROTOCOL_VERSION is still 2, and older v2 firmware can send this value; removing the variant makes SendStatus::try_from(3) and confirmation-payload decoding reject a previously valid notification. Keeping the wire variant does not require retaining the driver's obsolete error or its bridge mapping.

Medium severity Retire discovery after implicit route releases held sends

crates/​ziggurat-zigbee/​src/​nwk/​routing.rs:331

An implicit route can release all held sends without setting answered, so the old discovery remains tracked until its deadline. If that path then fails and another send arrives before the deadline, want_route suppresses a new request; with the default single attempt, the later send fails when the old discovery expires without ever trying a fresh route. Retire the discovery when an implicit route actually releases its sends, while retaining unanswered discoveries when sends were merely cancelled.

Medium severity Stop route broadcasts when abandoned discoveries expire

crates/​ziggurat-zigbee/​src/​nwk/​routing.rs:341

When a discovery lapses after its last held send was cancelled, this branch drops the discovery without stopping its registered route-request broadcast. Copies delayed beyond the discovery lifetime, or spaced out by a long retry interval, can therefore still transmit. Report abandoned destinations separately so drive_sends can stop those copies without invalidating a usable route.

1 resolved since last review

Review effort: Max

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved wire-compatibility and route-discovery lifecycle bugs can reject legacy confirmations, accept late or conflicted route replies, and delay or prematurely fail held sends.

5 open issues

Review effort: Max

Comment thread crates/ziggurat-protocol/src/wire.rs Resolved
@puddly
puddly merged commit 08f89ea into dev Nov 13, 2026
2 checks passed
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.

2 participants