fix(#836): one discovery auto-retry over LoRa

D1: first Discover attempt sometimes drops (normal LoRa packet loss); the retry gets through. Per owner (Option A), discoverRegions now makes up to 2 attempts (_discoverRegionsOnce), each using the firmware est_timeout; an unreachable repeater still ends in a timeout after both. Test: first attempt times out, second succeeds, two sends.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat/844-per-radio-notify
diffwireauto 4 weeks ago committed by Benjamin Wiechel
parent e44f47b9df
commit a69cb9987d

@ -5839,6 +5839,20 @@ class MeshCoreConnector extends ChangeNotifier {
Duration timeout = const Duration(seconds: 10),
}) async {
_guardRegionScope();
// One auto-retry: a single anon-request round-trip can drop over LoRa and a
// retry usually gets through; a genuinely unreachable repeater still ends in
// a timeout after both attempts (#836, D1 Option A).
for (var attempt = 0; attempt < 2; attempt++) {
final reply = await _discoverRegionsOnce(repeaterPubKey, timeout);
if (reply != null) return reply;
}
return null;
}
Future<RegionsReply?> _discoverRegionsOnce(
Uint8List repeaterPubKey,
Duration timeout,
) async {
// Reply travels back along the repeater's own stored path (firmware routes
// it as-is), so a multi-hop repeater can answer. Empty => zero-hop.
final (replyPathLenByte, replyPath) = _regionReplyPathFor(repeaterPubKey);

@ -146,6 +146,30 @@ void main() {
expect(sent![34], 2); // packed path-len byte: 2 hops, 1-byte hashes
expect(sent!.sublist(35), [0xAA, 0xBB]);
});
test(
'auto-retries once: first attempt times out, second succeeds',
() async {
var sends = 0;
connector.sendFrameOverrideForTest = (_) {
sends++;
// First send injects nothing (that attempt times out); second answers.
if (sends >= 2) {
connector.handleFrameForTest(_respSent(0x77));
connector.handleFrameForTest(
_regionsReply(0x77, clock: 1, csv: 'oki'),
);
}
};
final reply = await connector.discoverRegions(
repeaterPubKey: pub,
timeout: const Duration(milliseconds: 60),
);
expect(reply, isNotNull);
expect(reply!.regionNames, ['oki']);
expect(sends, 2);
},
);
});
group('send-scope setters', () {

Loading…
Cancel
Save

Powered by TurnKey Linux.