From 7d82b0f88197f8ebfcef949abec4ddca07d9ed87 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 1 Feb 2024 07:49:28 -0800 Subject: Decode FleetGuide locations --- .../protocol/FleetGuideProtocolDecoder.java | 77 +++++++++++++++++++++- .../protocol/FleetGuideProtocolDecoderTest.java | 4 +- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java b/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java index 94d837145..9fddec922 100644 --- a/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java @@ -21,9 +21,16 @@ import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; import org.traccar.session.DeviceSession; import java.net.SocketAddress; +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; public class FleetGuideProtocolDecoder extends BaseProtocolDecoder { @@ -73,9 +80,77 @@ public class FleetGuideProtocolDecoder extends BaseProtocolDecoder { data = buf.readRetainedSlice(length); } + List positions = new LinkedList<>(); + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + Set recordTypes = new HashSet<>(); + + while (data.isReadable()) { + + int recordHeader = data.readUnsignedShortLE(); + int recordLength = BitUtil.to(recordHeader, 10); + int recordType = BitUtil.from(recordHeader, 10); + int recordEndIndex = data.readerIndex() + recordLength; + + if (recordTypes.contains(recordType)) { + positions.add(processPosition(position)); + position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + recordTypes.clear(); + } + recordTypes.add(recordType); + + switch (recordType) { + case 0: + position.setTime(new Date((data.readUnsignedIntLE() + 1262304000) * 1000)); // since 2010-01-01 + break; + case 1: + position.setLatitude(data.readUnsignedIntLE() * 90.0 / 0xFFFFFFFFL); + position.setLongitude(data.readUnsignedIntLE() * 180.0 / 0xFFFFFFFFL); + int speed = data.readUnsignedShortLE(); + position.setSpeed(UnitsConverter.knotsFromKph(BitUtil.to(speed, 14) * 0.1)); + if (BitUtil.check(speed, 14)) { + position.setLatitude(-position.getLatitude()); + } + if (BitUtil.check(speed, 15)) { + position.setLongitude(-position.getLongitude()); + } + int course = data.readUnsignedShortLE(); + position.setSpeed(BitUtil.to(course, 9)); + int motion = BitUtil.between(course, 9, 11); + if (motion > 0) { + position.set(Position.KEY_MOTION, motion == 1); + } + position.set(Position.KEY_SATELLITES, BitUtil.from(course, 11)); + int altitude = data.readUnsignedShortLE(); + position.setAltitude(BitUtil.to(altitude, 14)); + if (BitUtil.check(altitude, 14)) { + position.setAltitude(-position.getAltitude()); + } + break; + default: + break; + } + + data.readerIndex(recordEndIndex); + + } + data.release(); - return null; + return positions.isEmpty() ? null : positions; + } + + private Position processPosition(Position position) { + if (position.getFixTime() == null) { + position.setTime(new Date()); + } + if (!position.getAttributes().containsKey(Position.KEY_SATELLITES)) { + getLastLocation(position, null); + } + return position; } private int readVarSize(ByteBuf buf) { diff --git a/src/test/java/org/traccar/protocol/FleetGuideProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FleetGuideProtocolDecoderTest.java index 010f0d649..34b15d14b 100644 --- a/src/test/java/org/traccar/protocol/FleetGuideProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/FleetGuideProtocolDecoderTest.java @@ -1,10 +1,8 @@ package org.traccar.protocol; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.traccar.ProtocolTest; -@Disabled public class FleetGuideProtocolDecoderTest extends ProtocolTest { @Test @@ -12,7 +10,7 @@ public class FleetGuideProtocolDecoderTest extends ProtocolTest { var decoder = inject(new FleetGuideProtocolDecoder(null)); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "539e598f8a020003020700e378351ac39f040c04ffa92e806a28a13b1f00b638030c000067052c06ffffffff033006808001180003200100000700e478351ac40204303dab2e80cb27a13b1c00ac40021b30e778351ac502043082a72e8054020530bf30021b30e978351ac69f0d0c0433a72e80c123a13b2000df3807002579351ac79f06020a170000df28021b476179351ac8020f30021c81279d79351ac9020f30021c8207d979351aca020f30021c8157157a351acb022b8140517a351acc022b608d7a351acd022b60c97a351ace022b30057b351acf022b30417b351ad0022b307d7b351ad1020f3048021b30b97b351ad2020f3070030c004066021630f57b351ad30213841080021730317c351ad4021330c00217306d7c351ad5020f3050021b30a97c351ad602138170021830e57c351ad7020f3058021b30217d351ad8021385500218305d7d351ad9022b8110997d351ada022b8170d57d351adb022b30117e351adc020f3068030ce184680216304d7e351add020f3060030ce34469021630897e351ade021260e4021830c57e351adf021230e5021830017f351ae002293022f2")); } -- cgit v1.2.3