diff options
-rw-r--r-- | build.gradle | 2 | ||||
-rw-r--r-- | setup/default.xml | 1 | ||||
-rw-r--r-- | setup/traccar.iss | 2 | ||||
-rw-r--r-- | src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java | 19 | ||||
-rw-r--r-- | src/main/java/org/traccar/protocol/FleetGuideProtocol.java | 36 | ||||
-rw-r--r-- | src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java | 98 | ||||
-rw-r--r-- | src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java | 2 | ||||
-rw-r--r-- | src/test/java/org/traccar/protocol/FleetGuideProtocolDecoderTest.java | 20 | ||||
-rw-r--r-- | src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java | 4 | ||||
-rw-r--r-- | swagger.json | 2 | ||||
m--------- | traccar-web | 0 |
11 files changed, 179 insertions, 7 deletions
diff --git a/build.gradle b/build.gradle index 41baa7f89..3677f8f94 100644 --- a/build.gradle +++ b/build.gradle @@ -109,7 +109,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "5.11", + "Implementation-Version": "5.12", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } diff --git a/setup/default.xml b/setup/default.xml index fbe63c873..b89e3ebef 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -296,5 +296,6 @@ <entry key='ramac.port'>5251</entry> <entry key='positrex.port'>5252</entry> <entry key='dragino.port'>5253</entry> + <entry key='fleetguide.port'>5254</entry> </properties> diff --git a/setup/traccar.iss b/setup/traccar.iss index 68258dcb5..2ccee1c3e 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=5.11 +AppVersion=5.12 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 6c4271ce2..2fa2e8869 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2024 Anton Tananaev (anton@traccar.org) * Copyright 2016 - 2018 Andrey Kunitsyn (andrey@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,8 +49,8 @@ public class MaintenanceEventHandler extends BaseEventHandler { Map<Event, Position> events = new HashMap<>(); for (Maintenance maintenance : cacheManager.getDeviceObjects(position.getDeviceId(), Maintenance.class)) { if (maintenance.getPeriod() != 0) { - double oldValue = lastPosition.getDouble(maintenance.getType()); - double newValue = position.getDouble(maintenance.getType()); + double oldValue = getValue(lastPosition, maintenance.getType()); + double newValue = getValue(position, maintenance.getType()); if (oldValue != 0.0 && newValue != 0.0 && newValue >= maintenance.getStart()) { if (oldValue < maintenance.getStart() || (long) ((oldValue - maintenance.getStart()) / maintenance.getPeriod()) @@ -67,4 +67,17 @@ public class MaintenanceEventHandler extends BaseEventHandler { return events; } + private double getValue(Position position, String type) { + switch (type) { + case "serverTime": + return position.getServerTime().getTime(); + case "deviceTime": + return position.getDeviceTime().getTime(); + case "fixTime": + return position.getFixTime().getTime(); + default: + return position.getDouble(type); + } + } + } diff --git a/src/main/java/org/traccar/protocol/FleetGuideProtocol.java b/src/main/java/org/traccar/protocol/FleetGuideProtocol.java new file mode 100644 index 000000000..46611c25c --- /dev/null +++ b/src/main/java/org/traccar/protocol/FleetGuideProtocol.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import jakarta.inject.Inject; +import org.traccar.BaseProtocol; +import org.traccar.PipelineBuilder; +import org.traccar.TrackerServer; +import org.traccar.config.Config; + +public class FleetGuideProtocol extends BaseProtocol { + + @Inject + public FleetGuideProtocol(Config config) { + addServer(new TrackerServer(config, getName(), true) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new FleetGuideProtocolDecoder(FleetGuideProtocol.this)); + } + }); + } + +} diff --git a/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java b/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java new file mode 100644 index 000000000..d63187921 --- /dev/null +++ b/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java @@ -0,0 +1,98 @@ +/* + * Copyright 2024 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Protocol; +import org.traccar.helper.BitUtil; +import org.traccar.session.DeviceSession; + +import java.lang.reflect.Method; +import java.net.SocketAddress; + +public class FleetGuideProtocolDecoder extends BaseProtocolDecoder { + + public FleetGuideProtocolDecoder(Protocol protocol) { + super(protocol); + } + + public static final int MSG_DATA = 0x10; + public static final int MSG_HEARTBEAT = 0x1A; + public static final int MSG_RESPONSE = 0x1C; + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + buf.readUnsignedByte(); // signature + int options = buf.readUnsignedShort(); + int length = BitUtil.to(options, 11); + + DeviceSession deviceSession; + if (BitUtil.check(options, 11)) { + deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(buf.readUnsignedInt())); + } else { + deviceSession = getDeviceSession(channel, remoteAddress); + } + if (deviceSession == null) { + return null; + } + + int type; + if (BitUtil.check(options, 12)) { + type = BitUtil.to(buf.readUnsignedByte(), 4); + } else { + type = 0; + } + + if (BitUtil.check(options, 13)) { + buf.readUnsignedShort(); // acknowledgement + } + + ByteBuf data; + if (BitUtil.check(options, 14)) { + data = decompress(buf.readSlice(length)); + } else { + data = buf.readRetainedSlice(length); + } + + data.release(); + + return null; + } + + private ByteBuf decompress(ByteBuf input) throws ReflectiveOperationException { + + Class<?> clazz = Class.forName("io.netty.handler.codec.compression.FastLz"); + Method method = clazz.getDeclaredMethod( + "decompress", ByteBuf.class, int.class, int.class, ByteBuf.class, int.class, int.class); + + ByteBuf output = Unpooled.buffer(); + int result = (Integer) method.invoke( + null, input, input.readerIndex(), input.readableBytes(), output, 0, Integer.MAX_VALUE); + if (result <= 0) { + throw new IllegalArgumentException("FastLz decompression failed"); + } + + return output; + } + +} diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index 55b3c900f..402262348 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -163,7 +163,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_OBD_SPEED, readValue(buf, length, true)); break; case 98: - position.set("fuelRate", readValue(buf, length, true) * 100 / 255.0); + position.set(Position.KEY_FUEL_LEVEL, readValue(buf, length, true) * 100 / 255.0); break; case 100: position.set(Position.KEY_FUEL_CONSUMPTION, readValue(buf, length, true) / 20.0); diff --git a/src/test/java/org/traccar/protocol/FleetGuideProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FleetGuideProtocolDecoderTest.java new file mode 100644 index 000000000..010f0d649 --- /dev/null +++ b/src/test/java/org/traccar/protocol/FleetGuideProtocolDecoderTest.java @@ -0,0 +1,20 @@ +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 + public void testDecode() throws Exception { + + var decoder = inject(new FleetGuideProtocolDecoder(null)); + + verifyPosition(decoder, binary( + "539e598f8a020003020700e378351ac39f040c04ffa92e806a28a13b1f00b638030c000067052c06ffffffff033006808001180003200100000700e478351ac40204303dab2e80cb27a13b1c00ac40021b30e778351ac502043082a72e8054020530bf30021b30e978351ac69f0d0c0433a72e80c123a13b2000df3807002579351ac79f06020a170000df28021b476179351ac8020f30021c81279d79351ac9020f30021c8207d979351aca020f30021c8157157a351acb022b8140517a351acc022b608d7a351acd022b60c97a351ace022b30057b351acf022b30417b351ad0022b307d7b351ad1020f3048021b30b97b351ad2020f3070030c004066021630f57b351ad30213841080021730317c351ad4021330c00217306d7c351ad5020f3050021b30a97c351ad602138170021830e57c351ad7020f3058021b30217d351ad8021385500218305d7d351ad9022b8110997d351ada022b8170d57d351adb022b30117e351adc020f3068030ce184680216304d7e351add020f3060030ce34469021630897e351ade021260e4021830c57e351adf021230e5021830017f351ae002293022f2")); + + } + +} diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java index 24dc9d18e..74a180b11 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -12,6 +12,10 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeitrackProtocolDecoder(null)); verifyAttribute(decoder, binary( + "24246D3230312C3836393430393036323730323834332C4343452C000000000100A7002A000D05010626070914001502930194009500960097629D209E63A1640E0824000956000A07000B2A001606001704001901001A0E0B91280092280099EF049C52009F1B004023000C0215B9F2FF035855F506041E0F142D0C01708C010D748AC2001C012000009A000000009BD0623E02A0889FF201A2D61A0000A542020000FEF4A3D50900030E0CFE010A007F466FFC0000000049090401000000000000004B0501010232472A44360D0A"), + Position.KEY_HOURS, 644515 * 60000L); + + verifyAttribute(decoder, binary( "2424593136312c3836323039303035303031363139332c4343452c0000000001007f0017000705010607071714001500fe69601b00070800000971000a13000b19001605001acc0440230006029779570103eb5bcc06041ff0e8290c430100000d780400001c01000000030e0ccc010000922781abb90ca4fffe731e0109746e6873656e736f72ac233f6e219064051b753b00000000000000004b060101034c54452a42380d0a"), "tagName", "tnhsensor"); diff --git a/swagger.json b/swagger.json index 9268e1a0d..b2209a20e 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "5.11", + "version": "5.12", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", diff --git a/traccar-web b/traccar-web -Subproject d1a9c08571683184ce10b7db5890e2a75bf6179 +Subproject 42db1a41cbf733ea4f82c86e5d45a6fbccc8b8f |