From 6a17134942cea511b4e0aaa61c38df678e8c7079 Mon Sep 17 00:00:00 2001 From: lingniu Date: Mon, 29 Jun 2026 22:27:10 +0800 Subject: [PATCH] fix: query gb32960 tdengine frames without vin --- .../Gb32960DecodedFrameService.java | 6 +- .../Gb32960DecodedFrameServiceTest.java | 79 +++++++++++++++++++ 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/Gb32960DecodedFrameService.java b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/Gb32960DecodedFrameService.java index aeea25b0..227ec8a7 100644 --- a/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/Gb32960DecodedFrameService.java +++ b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/Gb32960DecodedFrameService.java @@ -201,12 +201,10 @@ public final class Gb32960DecodedFrameService { int frameLimit, String vin, String platformAccount) throws IOException { - if (vin == null || vin.isBlank()) { - return List.of(); - } + String vehicleKey = vin == null ? "" : vin.trim(); TdenginePage page = tdengineReader.queryRawFrames(new TdengineRawFrameQuery( "GB32960", - vin.trim(), + vehicleKey, fromInstant(dateFrom, eventTimeFrom), toExclusiveInstant(dateTo, eventTimeTo), tdengineOrder(order), diff --git a/modules/services/event-history-service/src/test/java/com/lingniu/ingest/eventhistory/Gb32960DecodedFrameServiceTest.java b/modules/services/event-history-service/src/test/java/com/lingniu/ingest/eventhistory/Gb32960DecodedFrameServiceTest.java index 8c3440a5..4abd12e4 100644 --- a/modules/services/event-history-service/src/test/java/com/lingniu/ingest/eventhistory/Gb32960DecodedFrameServiceTest.java +++ b/modules/services/event-history-service/src/test/java/com/lingniu/ingest/eventhistory/Gb32960DecodedFrameServiceTest.java @@ -341,6 +341,52 @@ class Gb32960DecodedFrameServiceTest { .containsExactly("VEHICLE", "GD_FC_DCDC"); } + @Test + void queryCanUseTdengineRawFramesWithoutVinForPlatformLoginFrames() throws Exception { + String key = "2026/06/22/GB32960/unknown-vin/platform-login.bin"; + String uri = "archive://" + key; + writeArchive(key, platformLoginFrame()); + CapturingTdengineReader reader = new CapturingTdengineReader(List.of(new TdengineRawFrameRow( + Instant.parse("2026-06-22T10:00:00Z"), + "tdengine-platform-login", + Instant.parse("2026-06-22T10:00:01Z"), + 0x05, + 0, + Instant.parse("2026-06-22T10:00:00Z"), + uri, + "sha256:test", + platformLoginFrame().length, + "SUCCEEDED", + "", + "8.134.95.166:37302", + "{\"platformAccount\":\"Hyundai\"}", + "GB32960", + "unknown:GB32960:platform-login", + "", + ""))); + + Gb32960DecodedFrameService service = new Gb32960DecodedFrameService( + reader, + decoder(), + archiveRoot, + null); + + List frames = service.query( + LocalDate.parse("2026-06-22"), + LocalDate.parse("2026-06-22"), + EventFileQuery.Order.DESC, + 10, + null, + "Hyundai"); + + assertThat(reader.lastQuery.protocol()).isEqualTo("GB32960"); + assertThat(reader.lastQuery.vehicleKey()).isBlank(); + assertThat(reader.lastQuery.vin()).isBlank(); + assertThat(frames).hasSize(1); + assertThat(frames.getFirst().command()).isEqualTo("PLATFORM_LOGIN"); + assertThat(frames.getFirst().rawArchiveUri()).isEqualTo(uri); + } + @Test void framePageUsesTdengineCursorAndReturnsNextCursor() throws Exception { String vin = "LNVFC000000000001"; @@ -584,6 +630,39 @@ class Gb32960DecodedFrameServiceTest { return out.toByteArray(); } + private static byte[] platformLoginFrame() { + ByteArrayOutputStream body = new ByteArrayOutputStream(); + body.write(26); body.write(6); body.write(22); body.write(18); body.write(0); body.write(0); + writeU16(body, 1); + writeAsciiPadded(body, "Hyundai", 12); + writeAsciiPadded(body, "f2e3445d7cda409fb4f", 20); + body.write(0x01); + + byte[] bodyBytes = body.toByteArray(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + out.write(0x23); out.write(0x23); + out.write(0x05); + out.write(0xFE); + for (int i = 0; i < 17; i++) { + out.write(0); + } + out.write(0x01); + writeU16(out, bodyBytes.length); + out.write(bodyBytes, 0, bodyBytes.length); + byte[] almost = out.toByteArray(); + out.write(BccChecksum.compute(almost, 2, almost.length - 2) & 0xFF); + return out.toByteArray(); + } + + private static void writeAsciiPadded(ByteArrayOutputStream out, String value, int length) { + byte[] bytes = value.getBytes(StandardCharsets.US_ASCII); + int count = Math.min(bytes.length, length); + out.write(bytes, 0, count); + for (int i = count; i < length; i++) { + out.write(0); + } + } + private void writeArchive(String key, byte[] frame) throws Exception { Path rawFile = archiveRoot.resolve(key); Files.createDirectories(rawFile.getParent());