Split out of the #37 work (PR #98) rather than decided inside it, because it is a specification-reading question rather than a defect, and the reading it questions is the one that PR just shipped.
The rule as implemented
J1939Spn.Classify generalises the SAE J1939-71 §5.1.1 indicator tables to widths the standard does not tabulate by keeping the leading group fixed per width class: 8 bits for any field of a byte or wider, 4 bits for 4..7 bits, 2 bits for 2..3 bits. The consequence is that the indicator fraction of the range is whatever the tabulated width of that class already spends:
| Width |
Leading group |
Indicator values |
Fraction |
| 8, 16, 32, 64 (tabulated) |
8 bits |
5 of every 256 leading patterns |
~2 % |
| 12 (inferred) |
8 bits |
same |
~2 % |
| 4 (tabulated) |
4 bits |
11..15 |
31 % |
| 5, 6, 7 (inferred) |
4 bits |
proportional bands |
31 % |
| 2 (tabulated) |
2 bits |
0b10 error, 0b11 n/a |
50 % |
| 3 (inferred) |
2 bits |
4..7 |
50 % |
| 1 |
— |
none |
0 % |
That is internally consistent, and PR #98 documents it. All of these are now pinned by known-answer tests, including the inferred widths, so the reading cannot drift silently.
The question
For a 3-bit field the inferred reading classifies raw 4, 5, 6 and 7 as indicators:
0,1,2,3 -> Valid 4,5 -> Error 6,7 -> NotAvailable
A 3-bit SPN that genuinely carries eight states would therefore have half its states reported as "no reading". The alternative reading — scale by value rather than by leading group, so only the top one or two raw counts indicate (7 = not available, 6 = error) — costs a 3-bit parameter two states instead of four.
Neither is written down in J1939-71. What makes this worth a second look is that Classify already declines to infer in two other places, on exactly the argument that cuts against the 3-bit choice:
A 1-bit field has no room for an indicator and is always Valid, as is a signed field narrower than a byte — J1939-71 defines no indicator codes there, and inventing some would report real measurements as missing.
The same sentence applies to 3 bits. The counter-argument is that 3 bits is closer to the 2-bit table than to nothing, and silently scaling a real 5 into a measurement is the failure mode #37 was filed about.
Two arguments that bear on the choice
Raised on the PR review thread (#98) and worth recording here so they are not lost with the PR.
1. The standard scales indicator ranges by fraction, not by absolute code count. Measured against the widths J1939-71 actually tabulates:
| Width |
"not available" |
Fraction of range |
| 2 bits |
0b11 |
1/4 |
| 4 bits |
0xF |
1/16 |
| 8 bits |
0xFF |
1/256 |
| 16 bits |
0xFF00..0xFFFF |
1/256 |
| 32 bits |
0xFF000000..0xFFFFFFFF |
1/256 |
A 16-bit SPN spends 256 raw values on "not available", not one; the fraction is what stays constant from 8 bits to 32. The leading-group rule is that observation carried down to sub-byte widths. A terminal-code reading (option 4 below) would give 5-bit "not available" a 1/32 share — a fraction that appears nowhere in the tables.
2. The two readings fail in opposite directions, and only one fails safely. Classifying too widely reports a real measurement as "no reading": data loss, visible, never a wrong number. Classifying too narrowly scales an indicator into a plausible physical value — which is precisely the defect #37 was filed about (0xFFFF as 8191.875 rpm). Whichever option wins should account for the fact that the conservative error is the recoverable one.
Deciding it
Needs a real 3-bit SPN from J1939-71 or a DBC to settle rather than more reasoning from the tables. Four outcomes are defensible:
- Keep the leading-group rule — consistent, already tested, documented, and the fail-safe direction.
- Top-value scaling for 2..3 bits — a 3-bit field keeps six states.
- No inference below 4 bits — 3-bit fields become always-
Valid, matching the 1-bit precedent, and callers that need indicator semantics there pass a wider definition.
- Terminal codes at every sub-byte width — the five codes stay five individual values scaled to the field top, so 5-bit becomes 27..31 and 3-bit becomes
0b110 error / 0b111 not available. Consistent with the 4-bit and 8-bit tables read as literal code lists; inconsistent with how the 8→16→32-bit ranges scale, and it is the narrowing direction, so it trades data loss for the risk of scaling an indicator.
Whichever wins, it is a behavioural change to a public classifier and belongs in its own PR with the case table updated, not folded into #98.
Refs #37, PR #98, FR-J1939-002.
Split out of the #37 work (PR #98) rather than decided inside it, because it is a specification-reading question rather than a defect, and the reading it questions is the one that PR just shipped.
The rule as implemented
J1939Spn.Classifygeneralises the SAE J1939-71 §5.1.1 indicator tables to widths the standard does not tabulate by keeping the leading group fixed per width class: 8 bits for any field of a byte or wider, 4 bits for 4..7 bits, 2 bits for 2..3 bits. The consequence is that the indicator fraction of the range is whatever the tabulated width of that class already spends:0b10error,0b11n/aThat is internally consistent, and PR #98 documents it. All of these are now pinned by known-answer tests, including the inferred widths, so the reading cannot drift silently.
The question
For a 3-bit field the inferred reading classifies raw 4, 5, 6 and 7 as indicators:
A 3-bit SPN that genuinely carries eight states would therefore have half its states reported as "no reading". The alternative reading — scale by value rather than by leading group, so only the top one or two raw counts indicate (
7= not available,6= error) — costs a 3-bit parameter two states instead of four.Neither is written down in J1939-71. What makes this worth a second look is that
Classifyalready declines to infer in two other places, on exactly the argument that cuts against the 3-bit choice:The same sentence applies to 3 bits. The counter-argument is that 3 bits is closer to the 2-bit table than to nothing, and silently scaling a real 5 into a measurement is the failure mode #37 was filed about.
Two arguments that bear on the choice
Raised on the PR review thread (#98) and worth recording here so they are not lost with the PR.
1. The standard scales indicator ranges by fraction, not by absolute code count. Measured against the widths J1939-71 actually tabulates:
0b110xF0xFF0xFF00..0xFFFF0xFF000000..0xFFFFFFFFA 16-bit SPN spends 256 raw values on "not available", not one; the fraction is what stays constant from 8 bits to 32. The leading-group rule is that observation carried down to sub-byte widths. A terminal-code reading (option 4 below) would give 5-bit "not available" a 1/32 share — a fraction that appears nowhere in the tables.
2. The two readings fail in opposite directions, and only one fails safely. Classifying too widely reports a real measurement as "no reading": data loss, visible, never a wrong number. Classifying too narrowly scales an indicator into a plausible physical value — which is precisely the defect #37 was filed about (
0xFFFFas 8191.875 rpm). Whichever option wins should account for the fact that the conservative error is the recoverable one.Deciding it
Needs a real 3-bit SPN from J1939-71 or a DBC to settle rather than more reasoning from the tables. Four outcomes are defensible:
Valid, matching the 1-bit precedent, and callers that need indicator semantics there pass a wider definition.0b110error /0b111not available. Consistent with the 4-bit and 8-bit tables read as literal code lists; inconsistent with how the 8→16→32-bit ranges scale, and it is the narrowing direction, so it trades data loss for the risk of scaling an indicator.Whichever wins, it is a behavioural change to a public classifier and belongs in its own PR with the case table updated, not folded into #98.
Refs #37, PR #98, FR-J1939-002.