Vendor the ASN.1 modules the codecs are verified against; untrack IDE churn
asn1/ Three tests assert exact bytes - CamEncodeGoldenTest, DenmAirReceiveTest and SpatemUperCodecTest - and their expected values came from asn1tools compiled against ETSI modules that existed only as an untracked working copy on one machine. A golden-byte fixture nobody else can regenerate is a fixture nobody can safely touch, so the modules are now in the repo. Only the seven .asn files those tests need are copied, 576 KB of a 4.2 MB checkout; the upstream Rust parser is not used by this project at all. Verified sufficient in isolation: copied into an empty directory, all three specs compile and reproduce the committed golden CAM bytes byte-identically. Source is consider it GmbH's C-ITS-Parser (github.com/consider-it/C-ITS-Parser) at f457426, MIT licensed - LICENSE is retained alongside as that requires. The schemas themselves are ETSI's standard definitions; upstream's contribution is assembling them into a compilable set. asn1/README.md records the provenance, which module pairs with which message, and the rule that matters: never regenerate a golden fixture from this project's own encoder, because sharing a mistake between encoder and decoder is exactly the failure these files exist to catch. Doc references in the codecs and tests now point at asn1/ instead of the untracked checkout, and C-ITS-Parser/ is gitignored so the working copy beside the project is never picked up. Untracked local state - .idea/deploymentTargetSelector.xml rewrites itself on every deploy, so it has been showing as modified in essentially every commit. Along with deviceManager.xml, appInsightsSettings.xml and studiobot.xml it is per-machine state, not project configuration. - obu-firmware/sdkconfig.old is ESP-IDF build output - it is the previous sdkconfig, rewritten on every build. sdkconfig.defaults remains tracked, since that is the configuration actually chosen. All five stay on disk; only the tracking is removed. Also ignores .claude/settings.local.json, which is per-machine, while leaving the skills beside it committable as project knowledge.
This commit is contained in:
@@ -262,7 +262,7 @@ object CamUperCodec {
|
||||
// Optional-presence bitmap for BasicVehicleContainerHighFrequency's 7 trailing OPTIONAL
|
||||
// fields: accelerationControl, lanePosition, steeringWheelAngle, lateralAcceleration,
|
||||
// verticalAcceleration, performanceClass, cenDsrcTollingZone (see
|
||||
// C-ITS-Parser/autogen/asn.1/cam_1_4_1.asn).
|
||||
// asn1/cam_1_4_1.asn).
|
||||
//
|
||||
// Consumed but not acted on, and that is correct: UPER writes a SEQUENCE's presence
|
||||
// bitmap up front but each field's VALUE in declaration order, and all seven of these are
|
||||
@@ -315,7 +315,7 @@ object CamUperCodec {
|
||||
// IMPORTANT: if a future change needs any of those - path history is the likely one - the
|
||||
// 7 optionals must be parsed and consumed first, in declaration order, or every read after
|
||||
// them lands at the wrong bit offset. At that point this hand-written decoder stops being
|
||||
// the right tool; use the generated codec (see C-ITS-Parser) instead.
|
||||
// the right tool; use a generated codec (see asn1/README.md) instead.
|
||||
return Cam(
|
||||
stationId = stationId,
|
||||
stationType = stationType,
|
||||
|
||||
@@ -18,8 +18,7 @@ import com.hawhamburg.micr0bu.domain.denm.DenmEvent
|
||||
* large, deeply nested, and nothing consumes them yet.
|
||||
*
|
||||
* ## Field widths
|
||||
* Every width below is taken from the ETSI ASN.1 modules in the `C-ITS-Parser` checkout
|
||||
* (`autogen/asn.1/denm_1_3_1.asn`, `cdd_1_3_1_1.asn`), and every extension marker was
|
||||
* Every width below is taken from the ETSI ASN.1 modules in `asn1/` (`denm_1_3_1.asn`, `cdd_1_3_1_1.asn`), and every extension marker was
|
||||
* cross-checked against how `rasn` renders the same type (`#[non_exhaustive]` marks an extensible
|
||||
* SEQUENCE). That cross-check matters: hand-derived widths are exactly how this project shipped a
|
||||
* one-bit `CurvatureCalculationMode` bug in CAM that was invisible until measured against real
|
||||
|
||||
@@ -13,8 +13,7 @@ import com.hawhamburg.micr0bu.domain.spat.SpatEvent
|
||||
* Decode-only: this project never transmits SPATEM, that is an RSU's job.
|
||||
*
|
||||
* ## Field widths
|
||||
* Every width is taken from the ETSI ASN.1 modules in the `C-ITS-Parser` checkout
|
||||
* (`dsrc_2_2_1.asn`, `cdd_2_2_1.asn`):
|
||||
* Every width is taken from the ETSI ASN.1 modules in `asn1/` (`dsrc_2_2_1.asn`, `cdd_2_2_1.asn`):
|
||||
*
|
||||
* - `MinuteOfTheYear` (0..527040) = 20 bits
|
||||
* - `DSecond` (0..65535) = 16 bits
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.junit.Test
|
||||
*
|
||||
* A round-trip test through this codebase's own decoder cannot catch that - it shares the
|
||||
* mistake. Only an independent implementation can. So the expected bytes below were produced by
|
||||
* `asn1tools` compiled from the real ETSI modules in the `C-ITS-Parser` checkout: it decoded this
|
||||
* `asn1tools` compiled from the real ETSI modules in `asn1/`: it decoded this
|
||||
* encoder's output and re-encoded it, and the result was byte-identical to what is asserted here.
|
||||
* That is stronger than "it parses" - it means this encoder emits exactly what the reference
|
||||
* encoder emits.
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.junit.Test
|
||||
*
|
||||
* ## Why the expected values can be trusted
|
||||
* Every asserted field was cross-checked against `asn1tools` decoding the same bytes with the real
|
||||
* ETSI modules from the `C-ITS-Parser` checkout (`denm_1_3_1.asn` + `cdd_1_3_1_1.asn`) — an
|
||||
* ETSI modules in `asn1/` (`denm_1_3_1.asn` + `cdd_1_3_1_1.asn`) — an
|
||||
* independent implementation, not this codebase's own arithmetic. Across the full capture set that
|
||||
* cross-check agreed on all 1885 decodable DENMs, on every field below including `detectionTime`.
|
||||
*
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.junit.Test
|
||||
*
|
||||
* The fixture is a real 26-byte RSU CAM taken live from the OBU's `v2x/rx/cam` topic; the
|
||||
* expected values are asn1tools' decoding of those same bytes using the ETSI modules in the
|
||||
* `C-ITS-Parser` checkout.
|
||||
* `asn1/`.
|
||||
*/
|
||||
class RsuCamDecodeTest {
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.junit.Test
|
||||
* ## Why the expected values can be trusted
|
||||
* The bit layout was validated by replaying **79,042 real SPATEMs** - the whole drive across 7+
|
||||
* RSUs plus the live trigger - through a port of this decoder and comparing every field against
|
||||
* `asn1tools` decoding the same bytes with the ETSI modules from the `C-ITS-Parser` checkout.
|
||||
* `asn1tools` decoding the same bytes with the ETSI modules in `asn1/`.
|
||||
* All 79,042 matched exactly, and none hit an unsupported branch. The values asserted below are
|
||||
* that independent decoder's output, not this codebase's own arithmetic.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user