You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Extend PM5/FTMS parser state to cover distance monotonicity and lastStroke sharing gaps
Follow-up to the earlier test-only commit, per a code review of PR #4610's
refactor. Two gaps were found by tracing real behavior differences between
master and this branch, and are now both covered by regression tests using
real device bytes from #4609 and #3872:
1. PM5-without-FTMS distance (processPm5ParserState, CE060031 branch) has no
monotonicity guard: `state.distanceKm = distance_dm / 10000.0` is a plain
assignment, so a reconnect/counter-reset packet with a smaller on-device
distance makes QZ's reported distance jump backwards instead of staying
pinned. Documented (not fixed) by
Pm5WithoutFtmsReplayingAnEarlierRealPacketMakesDistanceGoBackwards, which
replays two genuinely real CE060031 payloads from the same #4609 session
out of order since no collected log contains a live counter reset.
2. lastStroke is shared between the Concept2-native path
(processPm5ParserState, CE060032) and the FTMS stale-cadence-reset check
(previously inlined in characteristicChanged's moreData==0 branch, now
extracted into processFtmsParserState so it's testable through the same
ParserRegressionState struct as everything else, per AGENTS.md's
testability guidance). The extraction is behavior-preserving on its own,
but combined with PR #4610's PM5-path change it means lastStroke now
advances whenever carried-over cadence is > 0, even on a tick whose own
spm byte is 0 - not only when spm > 0 on that exact tick like before.
For a PM5 that exposes both FTMS and the Concept2-native characteristics
(the dual-path scenario this PR already tests via #3872), this can
suppress the FTMS stale-cadence-reset for longer than intended.
Documented by
Pm5WithFtmsCadenceCarryOverFromConcept2PathSuppressesFtmsStaleCadenceResetFromIssue3872,
composed from three real payloads in the #3872 log (no continuous capture
in the collected logs exhibits a transient mid-row cadence dip, so the
packets are real but sequenced/timed to reproduce the interaction).
ParserRegressionState gained lastStrokeMs/strokesCount/wattValue so both
gaps could be exercised through the existing static helpers instead of
duplicating parsing in the tests. Full suite: 554 tests, 0 failures.
0 commit comments