diff --git a/lib/connector/meshcore_protocol.dart b/lib/connector/meshcore_protocol.dart index e3e9886f..55a609f9 100644 --- a/lib/connector/meshcore_protocol.dart +++ b/lib/connector/meshcore_protocol.dart @@ -552,6 +552,15 @@ const int offbandCapBlock = 0x02; /// FEM-bearing boards report false today. const int offbandCapFemLna = 0x04; +// POPULATION INVARIANT (#875-#877): every `offbandCaps`-anchored gate below is +// safe against stock 1.18+ devices ONLY because the connector nulls the caps +// bytes unless the population classifier corroborates the fork layout +// (device_population.dart). The ver-code floors in these gates are FORK +// contract numbers; stock reuses 14+ with different meanings, so a bare +// `firmwareVerCode >=` comparison may only be added for codes BELOW 14 +// (pre-split, same meaning everywhere: see supportsCompanionRadioStats >= 8 +// and firmwareSupportsRegionScope >= 13) or behind a caps-anchored gate here. + bool firmwareSupportsOffbandFemLna(int? offbandCaps) => offbandCaps != null && (offbandCaps & offbandCapFemLna) != 0; diff --git a/test/device_population_test.dart b/test/device_population_test.dart index 4f100e87..f1c60259 100644 --- a/test/device_population_test.dart +++ b/test/device_population_test.dart @@ -242,5 +242,22 @@ void main() { ); expect(connector.offbandCaps, isNull); }); + + test('fork gates never open on a stock device, whatever its ver code' + ' (#877): stock reuses the fork range 14+ with other meanings', () { + // A hypothetical future stock device reporting ver 22 (the fork's + // current contract number) must not light any Offband capability. + connector.handleFrameForTest( + deviceInfo(verCode: 22, version: 'v9.9.9'), + ); + expect(connector.supportsOffbandGps, isFalse); + expect(connector.supportsOffbandBlock, isFalse); + expect(connector.supportsOffbandFemLna, isFalse); + expect(connector.supportsButtonMatrix, isFalse); + expect(connector.supportsNotifyScope, isFalse); + expect(connector.supportsPktHash, isFalse); + // Pre-split floors (same meaning on every population) stay available. + expect(connector.supportsCompanionRadioStats, isTrue); + }); }); }