From 1baae2c5f6e3a70f055146f5f037fa83f380d143 Mon Sep 17 00:00:00 2001 From: Ashin Walpola Date: Fri, 11 Sep 2026 20:19:40 +0200 Subject: [PATCH] Encode yawRateConfidence in 4 bits in the firmware CAM encoders YawRateConfidence has nine enumerands, degSec-000-01(0) to unavailable(8) (cdd_1_3_1_1.asn), so UPER needs 4 bits and "unavailable" is 8. Both firmware copies of cam.c wrote 3 bits with value 7, which is also the wrong symbol (outOfRange), and every field after it shifted by one bit. The app's CamUperCodec fixed the same line on 2026-08-20; these two copies were missed. obu-cam-transmistter compiles its cam.c, so a board running that bench beacon sent CAMs no standards-compliant station could decode. obu-firmware's copy is reference only - it is not in SRCS, since the phone encodes the CAM - and is kept in step because the app's encoder was ported from it. The production OBU runs obu-firmware and was never affected. Every other field width was compared against CamUperCodec.kt and matches. Checked with asn1tools against asn1/cam_1_4_1.asn and cdd_1_3_1_1.asn: the CAM both fixed copies emit decodes with every expected value and re-encodes byte-identically, while the version before this change fails on yawRateConfidence. obu-cam-transmistter builds on IDF 5.5.4. --- obu-cam-transmistter/main/cam.c | 8 ++++++-- obu-firmware/main/cam.c | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/obu-cam-transmistter/main/cam.c b/obu-cam-transmistter/main/cam.c index 8f4a148..8d800e7 100644 --- a/obu-cam-transmistter/main/cam.c +++ b/obu-cam-transmistter/main/cam.c @@ -117,9 +117,13 @@ int cam_encode(const cam_fields_t *f, uint8_t *buf, size_t buf_len) bw_put_bits(&bw, 0, 1); // extension bit: value is in the root list bw_put_bits(&bw, 2, 2); // unavailable(2) // YawRate: YawRateValue(-32766..32767)->16 (offset from -32766), - // YawRateConfidence ENUM 8 values -> 3 bits + // YawRateConfidence ENUM with NINE values, degSec-000-01(0) .. unavailable(8) + // (cdd_1_3_1_1.asn) -> 4 bits. This wrote 3 bits with value 7, one bit short and the + // wrong symbol (7 is outOfRange), so every field after it shifted for any + // standards-compliant receiver. The app's CamUperCodec.kt fixed the same line on + // 2026-08-20; this copy was missed until 2026-09-11. bw_put_bits(&bw, 32767 - (uint32_t)(-32766), 16); // yawRateValue: unavailable(32767) - bw_put_bits(&bw, 7, 3); // yawRateConfidence: unavailable(7) + bw_put_bits(&bw, 8, 4); // yawRateConfidence: unavailable(8) // ---- LowFrequencyContainer ---- CHOICE { basicVehicleContainerLowFrequency, // ... } - EXTENSIBLE, 1 root alternative (index needs 0 bits). diff --git a/obu-firmware/main/cam.c b/obu-firmware/main/cam.c index 14cb8a3..14c17b7 100644 --- a/obu-firmware/main/cam.c +++ b/obu-firmware/main/cam.c @@ -122,9 +122,13 @@ int cam_encode(const cam_fields_t *f, uint8_t *buf, size_t buf_len) bw_put_bits(&bw, 0, 1); // extension bit: value is in the root list bw_put_bits(&bw, 2, 2); // unavailable(2) // YawRate: YawRateValue(-32766..32767)->16 (offset from -32766), - // YawRateConfidence ENUM 8 values -> 3 bits + // YawRateConfidence ENUM with NINE values, degSec-000-01(0) .. unavailable(8) + // (cdd_1_3_1_1.asn) -> 4 bits. This wrote 3 bits with value 7, one bit short and the + // wrong symbol (7 is outOfRange), so every field after it shifted for any + // standards-compliant receiver. The app's CamUperCodec.kt fixed the same line on + // 2026-08-20; this reference copy was missed until 2026-09-11. bw_put_bits(&bw, 32767 - (uint32_t)(-32766), 16); // yawRateValue: unavailable(32767) - bw_put_bits(&bw, 7, 3); // yawRateConfidence: unavailable(7) + bw_put_bits(&bw, 8, 4); // yawRateConfidence: unavailable(8) // ---- LowFrequencyContainer ---- CHOICE { basicVehicleContainerLowFrequency, // ... } - EXTENSIBLE, 1 root alternative (index needs 0 bits).