Accept live S300 frames with bad checksum
This commit is contained in:
parent
1424cafbb4
commit
0886bef200
@ -85,7 +85,11 @@ class BtPoller {
|
|||||||
final Uint8List frame =
|
final Uint8List frame =
|
||||||
Uint8List.fromList(_rxBuf.sublist(startIdx, startIdx + 128));
|
Uint8List.fromList(_rxBuf.sublist(startIdx, startIdx + 128));
|
||||||
|
|
||||||
if (validateFrame(frame)) {
|
final checksumOk = validateFrame(frame);
|
||||||
|
final canUseFrame = checksumOk || ecuType == EcuType.s300;
|
||||||
|
|
||||||
|
if (canUseFrame) {
|
||||||
|
if (!checksumOk) droppedFrames++;
|
||||||
validFrames++;
|
validFrames++;
|
||||||
_frameController.add(frame);
|
_frameController.add(frame);
|
||||||
_rxBuf.removeRange(0, startIdx + 128);
|
_rxBuf.removeRange(0, startIdx + 128);
|
||||||
|
|||||||
@ -4,12 +4,13 @@ import 'temp_table.dart';
|
|||||||
import 'neg8.dart';
|
import 'neg8.dart';
|
||||||
|
|
||||||
/// Parses a 128-byte S300 ECU response frame into a [SensorState].
|
/// Parses a 128-byte S300 ECU response frame into a [SensorState].
|
||||||
/// Throws [ArgumentError] if frame length is wrong or NEG8 checksum fails.
|
/// Throws [ArgumentError] if frame length is wrong, or if [validateChecksum]
|
||||||
SensorState parseS300(Uint8List frame) {
|
/// is true and the NEG8 checksum fails.
|
||||||
|
SensorState parseS300(Uint8List frame, {bool validateChecksum = true}) {
|
||||||
if (frame.length != 128) {
|
if (frame.length != 128) {
|
||||||
throw ArgumentError('S300 frame must be 128 bytes, got ${frame.length}');
|
throw ArgumentError('S300 frame must be 128 bytes, got ${frame.length}');
|
||||||
}
|
}
|
||||||
if (!validateFrame(frame)) {
|
if (validateChecksum && !validateFrame(frame)) {
|
||||||
throw ArgumentError('S300 frame NEG8 checksum failed');
|
throw ArgumentError('S300 frame NEG8 checksum failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,9 @@ final sensorStateProvider = StreamProvider<SensorState>((ref) {
|
|||||||
final btNotifier = ref.watch(btProvider.notifier);
|
final btNotifier = ref.watch(btProvider.notifier);
|
||||||
|
|
||||||
return btNotifier.frameStream.map((frame) {
|
return btNotifier.frameStream.map((frame) {
|
||||||
if (ecuType == EcuType.s300) return parseS300(frame);
|
if (ecuType == EcuType.s300) {
|
||||||
|
return parseS300(frame, validateChecksum: false);
|
||||||
|
}
|
||||||
return parseKPro(frame);
|
return parseKPro(frame);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -22,8 +24,6 @@ final sensorStateProvider = StreamProvider<SensorState>((ref) {
|
|||||||
/// Last successfully parsed sensor state (never null after first frame).
|
/// Last successfully parsed sensor state (never null after first frame).
|
||||||
/// Falls back to SensorState.zero() before any data arrives.
|
/// Falls back to SensorState.zero() before any data arrives.
|
||||||
final latestSensorProvider = Provider<SensorState>((ref) {
|
final latestSensorProvider = Provider<SensorState>((ref) {
|
||||||
return ref
|
return ref.watch(sensorStateProvider).whenData((s) => s).value ??
|
||||||
.watch(sensorStateProvider)
|
SensorState.zero();
|
||||||
.whenData((s) => s)
|
|
||||||
.value ?? SensorState.zero();
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -51,7 +51,10 @@ class RawFrameDebugScreen extends ConsumerWidget {
|
|||||||
_RowData('Dropped', bt.droppedFrames.toString()),
|
_RowData('Dropped', bt.droppedFrames.toString()),
|
||||||
_RowData('Last frame bytes', frame?.length.toString() ?? 'none'),
|
_RowData('Last frame bytes', frame?.length.toString() ?? 'none'),
|
||||||
if (frame != null)
|
if (frame != null)
|
||||||
_RowData('Checksum', validateFrame(frame) ? 'valid' : 'bad'),
|
_RowData(
|
||||||
|
'Checksum',
|
||||||
|
validateFrame(frame) ? 'valid' : 'bad, accepted for S300',
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
|||||||
@ -152,5 +152,12 @@ void main() {
|
|||||||
frame[127] = 0x00; // corrupt checksum
|
frame[127] = 0x00; // corrupt checksum
|
||||||
expect(() => parseS300(frame), throwsArgumentError);
|
expect(() => parseS300(frame), throwsArgumentError);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('can parse bad checksum frame when validation is disabled', () {
|
||||||
|
final frame = _buildS300Frame(rpm: 1000);
|
||||||
|
frame[127] = 0x00; // corrupt checksum
|
||||||
|
final state = parseS300(frame, validateChecksum: false);
|
||||||
|
expect(state.rpm, equals(1000.0));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user