From a08a132a3aedea01bf5ddb90fb30c6e43dcdff77 Mon Sep 17 00:00:00 2001 From: lingniu Date: Wed, 1 Jul 2026 08:29:21 +0800 Subject: [PATCH] test: cover jt808 gps mileage extension --- .../jt808/codec/Jt808DecoderTest.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/modules/protocols/protocol-jt808/src/test/java/com/lingniu/ingest/protocol/jt808/codec/Jt808DecoderTest.java b/modules/protocols/protocol-jt808/src/test/java/com/lingniu/ingest/protocol/jt808/codec/Jt808DecoderTest.java index e1cb5a3d..198430f9 100644 --- a/modules/protocols/protocol-jt808/src/test/java/com/lingniu/ingest/protocol/jt808/codec/Jt808DecoderTest.java +++ b/modules/protocols/protocol-jt808/src/test/java/com/lingniu/ingest/protocol/jt808/codec/Jt808DecoderTest.java @@ -14,6 +14,7 @@ import com.lingniu.ingest.protocol.jt808.codec.parser.TerminalParamsReportBodyPa import com.lingniu.ingest.protocol.jt808.codec.parser.UnregisterBodyParser; import com.lingniu.ingest.protocol.jt808.codec.parser.RegisterBodyParser; import com.lingniu.ingest.protocol.jt808.model.Jt808Body; +import com.lingniu.ingest.protocol.jt808.model.Jt808LocationAdditionalInfo; import com.lingniu.ingest.protocol.jt808.model.Jt808Message; import com.lingniu.ingest.protocol.jt808.model.Jt808MessageId; import org.junit.jupiter.api.Test; @@ -77,6 +78,31 @@ class Jt808DecoderTest { assertThat(loc.extensionItems().get(0x30)).containsExactly(88); } + @Test + void decodesForwardedLocationFrameGpsMileageExtension() { + byte[] framed = hex(""" + 7E020000320133077954250001000000000048000301D2C4C707376139000A00E6004F260630162357 + 01040001900C2504000000000202000030011F31010F867E + """); + byte[] unescaped = Jt808Escape.unescape(framed, 1, framed.length - 2); + + Jt808Body.Location loc = (Jt808Body.Location) decoder.decode(ByteBuffer.wrap(unescaped)).body(); + + assertThat(loc.longitude()).isEqualTo(121.069881); + assertThat(loc.latitude()).isEqualTo(30.590151); + assertThat(loc.speedKmh()).isEqualTo(23.0); + assertThat(loc.deviceTime().toString()).isEqualTo("2026-06-30T08:23:57Z"); + assertThat(loc.extensionItems()).containsOnlyKeys(0x01, 0x25, 0x02, 0x30, 0x31); + assertThat(loc.extensionItems().get(0x01)).containsExactly(0x00, 0x01, (byte) 0x90, 0x0C); + assertThat(Jt808LocationAdditionalInfo.mileageKm(loc.extensionItems())).isEqualTo(10241.2); + assertThat(Jt808LocationAdditionalInfo.decode(loc.extensionItems())) + .containsEntry("jt808.extra.mileage_km", "10241.2") + .containsEntry("jt808.extra.vehicle_signal_raw", "0") + .containsEntry("jt808.extra.fuel_l", "0") + .containsEntry("jt808.extra.network_signal_strength", "31") + .containsEntry("jt808.extra.gnss_satellite_count", "15"); + } + @Test void decodesSyntheticHeartbeatFrame() { byte[] frame = buildFrame(Jt808MessageId.TERMINAL_HEARTBEAT, "123456789012", 0x0002, new byte[0]); @@ -225,6 +251,15 @@ class Jt808DecoderTest { return framed.toByteArray(); } + private static byte[] hex(String value) { + String compact = value.replaceAll("\\s+", ""); + byte[] out = new byte[compact.length() / 2]; + for (int i = 0; i < out.length; i++) { + out[i] = (byte) Integer.parseInt(compact.substring(i * 2, i * 2 + 2), 16); + } + return out; + } + private static void writeU16(ByteArrayOutputStream os, int v) { os.write((v >> 8) & 0xFF); os.write(v & 0xFF);