fix: gate Ford VP44 unlock on CAN liveness to prevent false-unlocked reads
Before this fix, StartUnlockIfRequired was called immediately after registering the pump's CAN parameters, before any frames had been decoded. The TestUnlock parameter's zero-initialised Value was interpreted as "unlocked" for Type 1 pumps, causing Phase 1 to be skipped and UnlockCompleted(true) to fire falsely. Changes: - ICanService: add IsPumpAlive property (volatile-backed in PcanAdapter) - PcanAdapter: implement IsPumpAlive; mark _pumpAlive/_benchAlive volatile for safe cross-thread reads - MainViewModel: replace direct StartUnlockIfRequired call with a fire-and-forget WaitForPumpCanThenUnlockAsync that waits for PumpLivenessChanged(true) + 250 ms grace, then invokes unlock on the UI thread; cancellation on pump change or CAN disconnect via _pumpLivenessCts - UnlockService.UnlockAsync: skip Phase 2 state-machine when observer seed already reports unlocked (senders still run to prevent re-lock) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -64,8 +64,10 @@ namespace HC_APTBS.Infrastructure.Pcan
|
||||
private HashSet<uint> _pumpMessageIds = new();
|
||||
private DateTime _lastBenchFrameUtc = DateTime.MinValue;
|
||||
private DateTime _lastPumpFrameUtc = DateTime.MinValue;
|
||||
private bool _benchAlive;
|
||||
private bool _pumpAlive;
|
||||
// volatile so IsPumpAlive/IsBenchAlive getters on other threads see transitions
|
||||
// without relying on the memory-model guarantees of the event handler path.
|
||||
private volatile bool _benchAlive;
|
||||
private volatile bool _pumpAlive;
|
||||
|
||||
// ── ICanService ──────────────────────────────────────────────────────────
|
||||
|
||||
@@ -84,6 +86,9 @@ namespace HC_APTBS.Infrastructure.Pcan
|
||||
/// <inheritdoc/>
|
||||
public bool IsConnected => !_stopRead;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsPumpAlive => _pumpAlive;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public TPCANHandle SelectedChannel
|
||||
{
|
||||
@@ -246,11 +251,11 @@ namespace HC_APTBS.Infrastructure.Pcan
|
||||
{
|
||||
lock (_mapLock)
|
||||
{
|
||||
// Replace-on-conflict: callers may re-register on pump switch; the
|
||||
// new pump's parameter objects must take precedence over any stale
|
||||
// objects from the previous pump that shared CAN IDs.
|
||||
foreach (var kv in parameters)
|
||||
{
|
||||
if (!_parameterMap.ContainsKey(kv.Key))
|
||||
_parameterMap.Add(kv.Key, kv.Value);
|
||||
}
|
||||
_parameterMap[kv.Key] = kv.Value;
|
||||
ResolveBenchRpmParam();
|
||||
}
|
||||
}
|
||||
@@ -563,6 +568,11 @@ namespace HC_APTBS.Infrastructure.Pcan
|
||||
// result = prev + alpha * (new - prev)
|
||||
param.Value = PassFilterUpdate(previousValue, param.Value, param.Alpha);
|
||||
param.NeedsUpdate = true;
|
||||
|
||||
// Notify observers (e.g. UnlockService) that the decoded value changed.
|
||||
// The filter rounds to 4 decimals so this does not fire on float noise.
|
||||
if (param.Value != previousValue)
|
||||
param.RaiseValueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user