aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/protocol')
-rw-r--r--src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java179
-rw-r--r--src/main/java/org/traccar/protocol/ArnaviFrameDecoder.java82
-rw-r--r--src/main/java/org/traccar/protocol/ArnaviProtocol.java9
-rw-r--r--src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java80
-rw-r--r--src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java108
-rw-r--r--src/main/java/org/traccar/protocol/BceProtocolDecoder.java16
-rw-r--r--src/main/java/org/traccar/protocol/BlueProtocol.java2
-rw-r--r--src/main/java/org/traccar/protocol/BlueProtocolDecoder.java63
-rw-r--r--src/main/java/org/traccar/protocol/EskyProtocol.java10
-rw-r--r--src/main/java/org/traccar/protocol/EskyProtocolDecoder.java20
-rw-r--r--src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java28
-rw-r--r--src/main/java/org/traccar/protocol/GatorProtocolDecoder.java21
-rw-r--r--src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java13
-rw-r--r--src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java8
-rw-r--r--src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java29
-rw-r--r--src/main/java/org/traccar/protocol/ItsProtocolDecoder.java2
-rw-r--r--src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java13
-rw-r--r--src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java4
-rw-r--r--src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java28
-rw-r--r--src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java9
-rw-r--r--src/main/java/org/traccar/protocol/OkoProtocolDecoder.java23
-rw-r--r--src/main/java/org/traccar/protocol/OmnicommFrameDecoder.java4
-rw-r--r--src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java31
-rw-r--r--src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java23
-rw-r--r--src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java54
-rw-r--r--src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java17
-rw-r--r--src/main/java/org/traccar/protocol/RstProtocolDecoder.java2
-rw-r--r--src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java72
-rw-r--r--src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java18
-rw-r--r--src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java17
-rw-r--r--src/main/java/org/traccar/protocol/T800xProtocolDecoder.java11
-rw-r--r--src/main/java/org/traccar/protocol/TelicProtocolDecoder.java6
-rw-r--r--src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java2
-rw-r--r--src/main/java/org/traccar/protocol/TopinProtocolDecoder.java28
-rw-r--r--src/main/java/org/traccar/protocol/WondexProtocol.java11
36 files changed, 838 insertions, 212 deletions
diff --git a/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java
new file mode 100644
index 000000000..e957a6911
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2020 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Ivan Muratov (binakot@gmail.com)
+ *
+ * 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.DeviceSession;
+import org.traccar.NetworkMessage;
+import org.traccar.Protocol;
+import org.traccar.helper.Checksum;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ArnaviBinaryProtocolDecoder extends BaseProtocolDecoder {
+
+ private static final byte HEADER_START_SIGN = (byte) 0xff;
+ private static final byte HEADER_VERSION_1 = 0x22;
+ private static final byte HEADER_VERSION_2 = 0x23;
+
+ private static final byte RECORD_PING = 0x00;
+ private static final byte RECORD_DATA = 0x01;
+ private static final byte RECORD_TEXT = 0x03;
+ private static final byte RECORD_FILE = 0x04;
+ private static final byte RECORD_BINARY = 0x06;
+
+ private static final byte TAG_LATITUDE = 3;
+ private static final byte TAG_LONGITUDE = 4;
+ private static final byte TAG_COORD_PARAMS = 5;
+
+ public ArnaviBinaryProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ private void sendResponse(Channel channel, byte version, int index) {
+ if (channel != null) {
+ ByteBuf response = Unpooled.buffer();
+ response.writeByte(0x7b);
+ if (version == HEADER_VERSION_1) {
+ response.writeByte(0x00);
+ response.writeByte((byte) index);
+ } else if (version == HEADER_VERSION_2) {
+ response.writeByte(0x04);
+ response.writeByte(0x00);
+ ByteBuffer time = ByteBuffer.allocate(4).putInt((int) (System.currentTimeMillis() / 1000));
+ ((Buffer) time).position(0);
+ response.writeByte(Checksum.modulo256(time.slice()));
+ response.writeBytes(time);
+ }
+ response.writeByte(0x7d);
+ channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress()));
+ }
+ }
+
+ private Position decodePosition(DeviceSession deviceSession, ByteBuf buf, int length, Date time) {
+
+ final Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setTime(time);
+
+ int readBytes = 0;
+ while (readBytes < length) {
+ short tag = buf.readUnsignedByte();
+ switch (tag) {
+ case TAG_LATITUDE:
+ position.setLatitude(buf.readFloatLE());
+ position.setValid(true);
+ break;
+
+ case TAG_LONGITUDE:
+ position.setLongitude(buf.readFloatLE());
+ position.setValid(true);
+ break;
+
+ case TAG_COORD_PARAMS:
+ position.setCourse(buf.readUnsignedByte() * 2);
+ position.setAltitude(buf.readUnsignedByte() * 10);
+ byte satellites = buf.readByte();
+ position.set(Position.KEY_SATELLITES, satellites & 0x0F + (satellites >> 4) & 0x0F);
+ position.setSpeed(buf.readUnsignedByte());
+ break;
+
+ default:
+ buf.skipBytes(4);
+ break;
+ }
+
+ readBytes += 1 + 4;
+ }
+
+ return position;
+ }
+
+ @Override
+ protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ByteBuf buf = (ByteBuf) msg;
+
+ byte startSign = buf.readByte();
+
+ if (startSign == HEADER_START_SIGN) {
+
+ byte version = buf.readByte();
+
+ String imei = String.valueOf(buf.readLongLE());
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
+
+ if (deviceSession != null) {
+ sendResponse(channel, version, 0);
+ }
+
+ return null;
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ List<Position> positions = new LinkedList<>();
+
+ int index = buf.readUnsignedByte();
+
+ byte recordType = buf.readByte();
+ while (buf.readableBytes() > 0) {
+ switch (recordType) {
+ case RECORD_PING:
+ case RECORD_DATA:
+ case RECORD_TEXT:
+ case RECORD_FILE:
+ case RECORD_BINARY:
+ int length = buf.readUnsignedShortLE();
+ Date time = new Date(buf.readUnsignedIntLE() * 1000);
+
+ if (recordType == RECORD_DATA) {
+ positions.add(decodePosition(deviceSession, buf, length, time));
+ } else {
+ buf.readBytes(length);
+ }
+
+ buf.readUnsignedByte(); // checksum
+ break;
+
+ default:
+ return null;
+ }
+
+ recordType = buf.readByte();
+ }
+
+ sendResponse(channel, HEADER_VERSION_1, index);
+
+ return positions;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/ArnaviFrameDecoder.java b/src/main/java/org/traccar/protocol/ArnaviFrameDecoder.java
new file mode 100644
index 000000000..473e8b2c7
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/ArnaviFrameDecoder.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2020 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Ivan Muratov (binakot@gmail.com)
+ *
+ * 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.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import org.traccar.BaseFrameDecoder;
+import org.traccar.helper.BufferUtil;
+
+public class ArnaviFrameDecoder extends BaseFrameDecoder {
+
+ private static final int HEADER_LENGTH = 10;
+ private static final int PACKET_WRAPPER_LENGTH = 8;
+ private static final int RESULT_TYPE = 0xfd;
+ private static final byte PACKAGE_END_SIGN = 0x5d;
+
+ private boolean firstPacket = true;
+
+ @Override
+ protected Object decode(ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {
+
+ if (buf.readableBytes() < 4) {
+ return null;
+ }
+
+ if (buf.getByte(buf.readerIndex()) == '$') {
+
+ int index = BufferUtil.indexOf("\r\n", buf);
+ if (index > 0) {
+ ByteBuf frame = buf.readRetainedSlice(index - buf.readerIndex());
+ buf.skipBytes(2);
+ return frame;
+ }
+
+ } else {
+
+ int length;
+ if (firstPacket) {
+ firstPacket = false;
+ length = HEADER_LENGTH;
+ } else {
+ int type = buf.getUnsignedByte(1);
+ if (type == RESULT_TYPE) {
+ length = 4;
+ } else {
+ int index = 2;
+ while (index + PACKET_WRAPPER_LENGTH < buf.readableBytes()
+ && buf.getByte(index) != PACKAGE_END_SIGN) {
+ index += PACKET_WRAPPER_LENGTH + buf.getUnsignedShortLE(index + 1);
+ }
+ if (buf.getByte(index) != PACKAGE_END_SIGN) {
+ return null;
+ }
+ length = index + 1;
+ }
+ }
+
+ if (buf.readableBytes() >= length) {
+ return buf.readRetainedSlice(length);
+ }
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocol.java b/src/main/java/org/traccar/protocol/ArnaviProtocol.java
index afe491865..aecb42c8c 100644
--- a/src/main/java/org/traccar/protocol/ArnaviProtocol.java
+++ b/src/main/java/org/traccar/protocol/ArnaviProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2020 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.
@@ -15,9 +15,6 @@
*/
package org.traccar.protocol;
-import io.netty.handler.codec.LineBasedFrameDecoder;
-import io.netty.handler.codec.string.StringDecoder;
-import io.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.PipelineBuilder;
import org.traccar.TrackerServer;
@@ -28,9 +25,7 @@ public class ArnaviProtocol extends BaseProtocol {
addServer(new TrackerServer(false, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new LineBasedFrameDecoder(1024));
- pipeline.addLast(new StringDecoder());
- pipeline.addLast(new StringEncoder());
+ pipeline.addLast(new ArnaviFrameDecoder());
pipeline.addLast(new ArnaviProtocolDecoder(ArnaviProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java
index 7996cf429..68a70c944 100644
--- a/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/ArnaviProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2020 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.
@@ -15,91 +15,35 @@
*/
package org.traccar.protocol;
+import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
-import org.traccar.DeviceSession;
import org.traccar.Protocol;
-import org.traccar.helper.DateBuilder;
-import org.traccar.helper.Parser;
-import org.traccar.helper.PatternBuilder;
-import org.traccar.model.Position;
import java.net.SocketAddress;
-import java.util.regex.Pattern;
public class ArnaviProtocolDecoder extends BaseProtocolDecoder {
+ private final ArnaviTextProtocolDecoder textProtocolDecoder;
+ private final ArnaviBinaryProtocolDecoder binaryProtocolDecoder;
+
public ArnaviProtocolDecoder(Protocol protocol) {
super(protocol);
+ textProtocolDecoder = new ArnaviTextProtocolDecoder(protocol);
+ binaryProtocolDecoder = new ArnaviBinaryProtocolDecoder(protocol);
}
- private static final Pattern PATTERN = new PatternBuilder()
- .text("$AV,")
- .number("Vd,") // type
- .number("(d+),") // device id
- .number("(d+),") // index
- .number("(d+),") // power
- .number("(d+),") // battery
- .number("-?d+,")
- .expression("[01],") // movement
- .expression("([01]),") // ignition
- .number("(d+),") // input
- .number("d+,d+,") // input 1
- .number("d+,d+,").optional() // input 2
- .expression("[01],") // fix type
- .number("(d+),") // satellites
- .groupBegin()
- .number("(d+.d+)?,") // altitude
- .number("(?:d+.d+)?,") // geoid height
- .groupEnd("?")
- .number("(dd)(dd)(dd),") // time (hhmmss)
- .number("(dd)(dd.d+)([NS]),") // latitude
- .number("(ddd)(dd.d+)([EW]),") // longitude
- .number("(d+.d+),") // speed
- .number("(d+.d+),") // course
- .number("(dd)(dd)(dd)") // date (ddmmyy)
- .any()
- .compile();
-
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
- Parser parser = new Parser(PATTERN, (String) msg);
- if (!parser.matches()) {
- return null;
- }
+ ByteBuf buf = (ByteBuf) msg;
- Position position = new Position(getProtocolName());
-
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession == null) {
- return null;
+ if (buf.getByte(buf.readerIndex()) == '$') {
+ return textProtocolDecoder.decode(channel, remoteAddress, msg);
+ } else {
+ return binaryProtocolDecoder.decode(channel, remoteAddress, msg);
}
- position.setDeviceId(deviceSession.getDeviceId());
-
- position.set(Position.KEY_INDEX, parser.nextInt());
- position.set(Position.KEY_POWER, parser.nextInt() * 0.01);
- position.set(Position.KEY_BATTERY, parser.nextInt() * 0.01);
- position.set(Position.KEY_IGNITION, parser.nextInt() == 1);
- position.set(Position.KEY_INPUT, parser.nextInt());
- position.set(Position.KEY_SATELLITES, parser.nextInt());
-
- position.setAltitude(parser.nextDouble(0));
-
- DateBuilder dateBuilder = new DateBuilder()
- .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
-
- position.setValid(true);
- position.setLatitude(parser.nextCoordinate());
- position.setLongitude(parser.nextCoordinate());
- position.setSpeed(parser.nextDouble());
- position.setCourse(parser.nextDouble());
-
- dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
- position.setTime(dateBuilder.getDate());
-
- return position;
}
}
diff --git a/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java
new file mode 100644
index 000000000..b99869e6e
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/ArnaviTextProtocolDecoder.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2015 - 2020 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.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.Protocol;
+import org.traccar.helper.DateBuilder;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.regex.Pattern;
+
+public class ArnaviTextProtocolDecoder extends BaseProtocolDecoder {
+
+ public ArnaviTextProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .text("$AV,")
+ .number("Vd,") // type
+ .number("(d+),") // device id
+ .number("(d+),") // index
+ .number("(d+),") // power
+ .number("(d+),") // battery
+ .number("-?d+,")
+ .expression("[01],") // movement
+ .expression("([01]),") // ignition
+ .number("(d+),") // input
+ .number("d+,d+,") // input 1
+ .number("d+,d+,").optional() // input 2
+ .expression("[01],") // fix type
+ .number("(d+),") // satellites
+ .groupBegin()
+ .number("(d+.d+)?,") // altitude
+ .number("(?:d+.d+)?,") // geoid height
+ .groupEnd("?")
+ .number("(dd)(dd)(dd),") // time (hhmmss)
+ .number("(dd)(dd.d+)([NS]),") // latitude
+ .number("(ddd)(dd.d+)([EW]),") // longitude
+ .number("(d+.d+),") // speed
+ .number("(d+.d+),") // course
+ .number("(dd)(dd)(dd)") // date (ddmmyy)
+ .any()
+ .compile();
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ByteBuf buf = (ByteBuf) msg;
+ Parser parser = new Parser(PATTERN, buf.toString(StandardCharsets.US_ASCII));
+ if (!parser.matches()) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ if (deviceSession == null) {
+ return null;
+ }
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.set(Position.KEY_INDEX, parser.nextInt());
+ position.set(Position.KEY_POWER, parser.nextInt() * 0.01);
+ position.set(Position.KEY_BATTERY, parser.nextInt() * 0.01);
+ position.set(Position.KEY_IGNITION, parser.nextInt() == 1);
+ position.set(Position.KEY_INPUT, parser.nextInt());
+ position.set(Position.KEY_SATELLITES, parser.nextInt());
+
+ position.setAltitude(parser.nextDouble(0));
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
+
+ position.setValid(true);
+ position.setLatitude(parser.nextCoordinate());
+ position.setLongitude(parser.nextCoordinate());
+ position.setSpeed(parser.nextDouble());
+ position.setCourse(parser.nextDouble());
+
+ dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ position.setTime(dateBuilder.getDate());
+
+ return position;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java
index 30f9bb1f3..a259e027a 100644
--- a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2020 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.
@@ -83,10 +83,10 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
buf.skipBytes(4);
}
if (BitUtil.check(mask, 12)) {
- buf.skipBytes(2);
+ position.set("fuel1", buf.readUnsignedShort());
}
if (BitUtil.check(mask, 13)) {
- buf.skipBytes(2);
+ position.set("fuel2", buf.readUnsignedShort());
}
if (BitUtil.check(mask, 14)) {
@@ -113,7 +113,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte());
}
if (BitUtil.check(mask, 4)) {
- position.set(Position.KEY_RPM, buf.readUnsignedShortLE());
+ position.set(Position.KEY_RPM, buf.readUnsignedShortLE() * 0.125);
}
if (BitUtil.check(mask, 5)) {
position.set(Position.KEY_HOURS, buf.readUnsignedIntLE());
@@ -122,7 +122,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE());
}
if (BitUtil.check(mask, 7)) {
- position.set(Position.KEY_COOLANT_TEMP, (int) buf.readByte());
+ position.set(Position.KEY_COOLANT_TEMP, buf.readByte() - 40);
}
if (BitUtil.check(mask, 8)) {
position.set("fuel2", buf.readUnsignedByte());
@@ -217,9 +217,9 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedShortLE();
}
if (BitUtil.check(mask, 6)) {
- buf.readUnsignedByte(); // maximum acceleration
- buf.readUnsignedByte(); // maximum deceleration
- buf.readUnsignedByte(); // maximum cornering
+ position.set("maxAcceleration", buf.readUnsignedByte() * 0.02);
+ position.set("maxBraking", buf.readUnsignedByte() * 0.02);
+ position.set("maxCornering", buf.readUnsignedByte() * 0.02);
}
if (BitUtil.check(mask, 7)) {
buf.skipBytes(16);
diff --git a/src/main/java/org/traccar/protocol/BlueProtocol.java b/src/main/java/org/traccar/protocol/BlueProtocol.java
index 79f0714ec..d5dc5c421 100644
--- a/src/main/java/org/traccar/protocol/BlueProtocol.java
+++ b/src/main/java/org/traccar/protocol/BlueProtocol.java
@@ -26,7 +26,7 @@ public class BlueProtocol extends BaseProtocol {
addServer(new TrackerServer(false, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, 3, 0));
+ pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 1, 2, -2, 0));
pipeline.addLast(new BlueProtocolDecoder(BlueProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java
index 98a8ae565..f35ac6fbe 100644
--- a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2020 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.
@@ -16,11 +16,14 @@
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.DeviceSession;
+import org.traccar.NetworkMessage;
import org.traccar.Protocol;
import org.traccar.helper.BitUtil;
+import org.traccar.helper.Checksum;
import org.traccar.helper.DateBuilder;
import org.traccar.model.Position;
@@ -41,6 +44,41 @@ public class BlueProtocolDecoder extends BaseProtocolDecoder {
return negative ? -coordinate : coordinate;
}
+ private void sendResponse(Channel channel, int deviceIndex) {
+ if (channel != null) {
+
+ ByteBuf response = Unpooled.buffer();
+ response.writeByte(0xaa);
+ response.writeShort(2 + 1 + 1 + 6 + 1);
+ response.writeByte(0x86); // version
+ response.writeByte(0);
+
+ response.writeByte(6); // data length
+ response.writeByte(0xa4); // type
+ response.writeByte(0); // server index
+ response.writeByte(deviceIndex);
+ response.writeByte(0);
+ response.writeByte(0);
+
+ response.writeByte(Checksum.xor(response.nioBuffer(1, response.writerIndex() - 1)));
+
+ channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress()));
+ }
+ }
+
+ private String decodeAlarm(int value) {
+ switch (value) {
+ case 1:
+ return Position.ALARM_SOS;
+ case 8:
+ return Position.ALARM_OVERSPEED;
+ case 19:
+ return Position.ALARM_LOW_POWER;
+ default:
+ return null;
+ }
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -66,7 +104,7 @@ public class BlueProtocolDecoder extends BaseProtocolDecoder {
int frameEnd = buf.readerIndex() + buf.readUnsignedByte();
int type = buf.readUnsignedByte();
- buf.readUnsignedByte(); // reference id
+ int index = buf.readUnsignedByte();
buf.readUnsignedByte();
buf.readUnsignedByte(); // flags
@@ -98,10 +136,29 @@ public class BlueProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte(); // status 2
buf.readUnsignedByte(); // status 3
- buf.readUnsignedByte(); // status 4
+
+ status = buf.readUnsignedByte(); // status 4
+ int ignition = BitUtil.between(status, 2, 4);
+ if (ignition == 0b01) {
+ position.set(Position.KEY_IGNITION, false);
+ }
+ if (ignition == 0b10) {
+ position.set(Position.KEY_IGNITION, true);
+ }
+
buf.readUnsignedByte(); // status 5
buf.readUnsignedByte(); // status 6
+ position.set(Position.KEY_STATUS, buf.readUnsignedShort());
+
+ } else if (type == 0x81) {
+
+ position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte()));
+
+ } else if (type == 0x84) {
+
+ sendResponse(channel, index);
+
}
buf.readerIndex(frameEnd);
diff --git a/src/main/java/org/traccar/protocol/EskyProtocol.java b/src/main/java/org/traccar/protocol/EskyProtocol.java
index aaa92da58..fb047c207 100644
--- a/src/main/java/org/traccar/protocol/EskyProtocol.java
+++ b/src/main/java/org/traccar/protocol/EskyProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2020 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.
@@ -33,6 +33,14 @@ public class EskyProtocol extends BaseProtocol {
pipeline.addLast(new EskyProtocolDecoder(EskyProtocol.this));
}
});
+ addServer(new TrackerServer(true, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new StringEncoder());
+ pipeline.addLast(new StringDecoder());
+ pipeline.addLast(new EskyProtocolDecoder(EskyProtocol.this));
+ }
+ });
}
}
diff --git a/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java b/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java
index 641b2e28f..1a4f9b906 100644
--- a/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/EskyProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2020 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.
@@ -16,9 +16,12 @@
package org.traccar.protocol;
import io.netty.channel.Channel;
+import io.netty.channel.socket.DatagramChannel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
+import org.traccar.NetworkMessage;
import org.traccar.Protocol;
+import org.traccar.helper.BitUtil;
import org.traccar.helper.Parser;
import org.traccar.helper.PatternBuilder;
import org.traccar.helper.UnitsConverter;
@@ -35,7 +38,7 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder {
private static final Pattern PATTERN = new PatternBuilder()
.expression("..;") // header
- .number("d+;") // index
+ .number("d+;")
.number("(d+);") // imei
.text("R;") // data type
.number("(d+)[+;]") // satellites
@@ -58,7 +61,8 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder {
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
- Parser parser = new Parser(PATTERN, (String) msg);
+ String sentence = (String) msg;
+ Parser parser = new Parser(PATTERN, sentence);
if (!parser.matches()) {
return null;
}
@@ -81,13 +85,21 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder {
position.setCourse(parser.nextDouble());
if (parser.hasNext(3)) {
- position.set(Position.KEY_INPUT, parser.nextHexInt());
+ int input = parser.nextHexInt();
+ position.set(Position.KEY_IGNITION, !BitUtil.check(input, 0));
+ position.set(Position.PREFIX_IN + 1, !BitUtil.check(input, 1));
+ position.set(Position.PREFIX_IN + 2, !BitUtil.check(input, 2));
position.set(Position.KEY_EVENT, parser.nextInt());
position.set(Position.KEY_ODOMETER, parser.nextInt());
}
position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001);
+ int index = sentence.lastIndexOf('+');
+ if (index > 0 && channel instanceof DatagramChannel) {
+ channel.writeAndFlush(new NetworkMessage("ACK," + sentence.substring(index + 1) + "#", remoteAddress));
+ }
+
return position;
}
diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java
index 40e146e0b..9bc7cb504 100644
--- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2020 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.
@@ -116,6 +116,32 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder {
return Position.ALARM_POWER_CUT;
case 16:
return Position.ALARM_POWER_RESTORED;
+ case 17:
+ return Position.ALARM_LOW_BATTERY;
+ case 18:
+ return Position.ALARM_OVERSPEED;
+ case 20:
+ return Position.ALARM_GPS_ANTENNA_CUT;
+ case 21:
+ return Position.ALARM_VIBRATION;
+ case 23:
+ return Position.ALARM_ACCELERATION;
+ case 24:
+ return Position.ALARM_BRAKING;
+ case 27:
+ return Position.ALARM_FATIGUE_DRIVING;
+ case 30:
+ case 32:
+ return Position.ALARM_JAMMING;
+ case 33:
+ return Position.ALARM_GEOFENCE_EXIT;
+ case 34:
+ return Position.ALARM_GEOFENCE_ENTER;
+ case 35:
+ return Position.ALARM_IDLE;
+ case 40:
+ case 41:
+ return Position.ALARM_TEMPERATURE;
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java
index 043839be9..087861635 100644
--- a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2020 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.
@@ -23,6 +23,7 @@ import org.traccar.DeviceSession;
import org.traccar.NetworkMessage;
import org.traccar.Protocol;
import org.traccar.helper.BcdUtil;
+import org.traccar.helper.Checksum;
import org.traccar.helper.DateBuilder;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
@@ -58,16 +59,16 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder {
return String.format("%02d%02d%02d%02d%02d", d1, d2, d3, d4, d5);
}
- private void sendResponse(Channel channel, SocketAddress remoteAddress, byte calibration) {
+ private void sendResponse(Channel channel, SocketAddress remoteAddress, int type, int checksum) {
if (channel != null) {
ByteBuf response = Unpooled.buffer();
- response.writeByte(0x24); response.writeByte(0x24); // header
- response.writeByte(MSG_HEARTBEAT); // size
- response.writeShort(5);
- response.writeByte(calibration);
- response.writeByte(0); // main order
- response.writeByte(0); // slave order
- response.writeByte(1); // calibration
+ response.writeShort(0x2424); // header
+ response.writeByte(MSG_HEARTBEAT);
+ response.writeShort(5); // length
+ response.writeByte(checksum);
+ response.writeByte(type);
+ response.writeByte(0); // subtype
+ response.writeByte(Checksum.xor(response.nioBuffer(2, response.writerIndex())));
response.writeByte(0x0D);
channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
}
@@ -87,7 +88,7 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte(), buf.readUnsignedByte(),
buf.readUnsignedByte(), buf.readUnsignedByte());
- sendResponse(channel, remoteAddress, buf.getByte(buf.writerIndex() - 2));
+ sendResponse(channel, remoteAddress, type, buf.getByte(buf.writerIndex() - 2));
if (type == MSG_POSITION_DATA || type == MSG_ROLLCALL_RESPONSE
|| type == MSG_ALARM_DATA || type == MSG_BLIND_AREA) {
diff --git a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java
index 26af8d5af..ab89f10c8 100644
--- a/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/GlobalstarProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2020 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.
@@ -23,6 +23,7 @@ import io.netty.channel.Channel;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
+import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import org.traccar.BaseHttpProtocolDecoder;
@@ -96,21 +97,23 @@ public class GlobalstarProtocolDecoder extends BaseHttpProtocolDecoder {
rootElement.appendChild(state);
Element stateMessage = document.createElement("stateMessage");
- stateMessage.appendChild(document.createTextNode("Messages received and stored successfully"));
+ stateMessage.appendChild(document.createTextNode("Store OK"));
rootElement.appendChild(stateMessage);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
ByteBuf content = Unpooled.buffer();
transformer.transform(new DOMSource(document), new StreamResult(new ByteBufOutputStream(content)));
- FullHttpResponse response = new DefaultFullHttpResponse(
- HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
if (channel != null) {
+ FullHttpResponse response = new DefaultFullHttpResponse(
+ HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
+ response.headers()
+ .add(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes())
+ .add(HttpHeaderNames.CONTENT_TYPE, "text/xml");
channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress()));
}
}
-
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java
index c435b6cec..946652b03 100644
--- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java
@@ -730,6 +730,14 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
decodeStatus(position, buf);
}
+ if (type == MSG_GPS_LBS_1 && buf.readableBytes() > 75 + 6) {
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedInt());
+ String data = buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString();
+ buf.readUnsignedByte(); // alarm
+ buf.readUnsignedByte(); // swiped
+ position.set("driverLicense", data.trim());
+ }
+
if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 2 + 6) {
int mask = buf.readUnsignedShort();
position.set(Position.KEY_IGNITION, BitUtil.check(mask, 8 + 7));
diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
index 9449e2d5c..eac06bbfe 100644
--- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2020 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.
@@ -25,7 +25,10 @@ import org.traccar.Protocol;
import org.traccar.helper.BitUtil;
import org.traccar.helper.DateBuilder;
import org.traccar.helper.UnitsConverter;
+import org.traccar.model.CellTower;
+import org.traccar.model.Network;
import org.traccar.model.Position;
+import org.traccar.model.WifiAccessPoint;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
@@ -137,6 +140,8 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_ODOMETER, buf.readUnsignedShort() * 1000);
+ Network network = new Network();
+
while (buf.readableBytes() > 4) {
int subtype = buf.readUnsignedShort();
int length = buf.readUnsignedShort() - 4;
@@ -161,12 +166,34 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
position.set(
Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString());
break;
+ case 0x0020:
+ String[] cells = buf.readCharSequence(
+ length, StandardCharsets.US_ASCII).toString().split("\\+");
+ for (String cell : cells) {
+ String[] values = cell.split("@");
+ network.addCellTower(CellTower.from(
+ Integer.parseInt(values[0]), Integer.parseInt(values[1]),
+ Integer.parseInt(values[2], 16), Integer.parseInt(values[3], 16)));
+ }
+ break;
+ case 0x0021:
+ String[] points = buf.readCharSequence(
+ length, StandardCharsets.US_ASCII).toString().split("\\+");
+ for (String point : points) {
+ String[] values = point.split("@");
+ network.addWifiAccessPoint(WifiAccessPoint.from(values[0], Integer.parseInt(values[1])));
+ }
+ break;
default:
buf.skipBytes(length);
break;
}
}
+ if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) {
+ position.setNetwork(network);
+ }
+
sendResponse(channel, MSG_POSITION_RSP, index, null);
return position;
diff --git a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java
index e8d77f1a8..6a107d67d 100644
--- a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java
@@ -51,7 +51,7 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder {
.groupEnd()
.number("(d{15}),") // imei
.groupBegin()
- .expression("(..),") // status
+ .expression("([^,]{2}),") // status
.or()
.expression("[^,]*,") // vehicle registration
.number("([01]),").optional() // valid
diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java
index 5b352a961..ad0c9bd32 100644
--- a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2020 Anton Tananaev (anton@traccar.org)
* Copyright 2019 Jesse Hills (jesserockz@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,16 +19,12 @@ package org.traccar.protocol;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpRequest;
-import io.netty.handler.codec.http.DefaultFullHttpResponse;
-import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
-import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import org.traccar.BaseHttpProtocolDecoder;
import org.traccar.DeviceSession;
import org.traccar.Protocol;
import org.traccar.model.Position;
-import org.traccar.NetworkMessage;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
@@ -122,13 +118,8 @@ public class LeafSpyProtocolDecoder extends BaseHttpProtocolDecoder {
}
if (position.getDeviceId() != 0) {
- if (channel != null) {
- HttpResponse response = new DefaultFullHttpResponse(
- HttpVersion.HTTP_1_1,
- HttpResponseStatus.OK,
+ sendResponse(channel, HttpResponseStatus.OK,
Unpooled.copiedBuffer("\"status\":\"0\"", StandardCharsets.US_ASCII));
- channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress()));
- }
return position;
} else {
sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java
index cbfc3660a..bd66cdc4b 100644
--- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2020 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.
@@ -47,7 +47,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
private static final Pattern PATTERN = new PatternBuilder()
- .number("(dd)(dd)(dd).?d*,") // time (hhmmss)
+ .number("(d+)(dd)(dd).?d*,") // time (hhmmss)
.expression("([AV]),") // validity
.number("(d+)(dd.d+),") // latitude
.expression("([NS]),")
diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java
index 55260ef0c..529496928 100644
--- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java
@@ -70,7 +70,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
.number("(d+)|") // mnc
.number("(x+)|") // lac
.number("(x+),") // cid
- .number("(x+),") // state
+ .number("(xx)") // input
+ .number("(xx),") // output
.number("(x+)?|") // adc1
.number("(x+)?|") // adc2
.number("(x+)?|") // adc3
@@ -149,39 +150,38 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
}
position.setDeviceId(deviceSession.getDeviceId());
- int event = parser.nextInt(0);
+ int event = parser.nextInt();
position.set(Position.KEY_EVENT, event);
position.set(Position.KEY_ALARM, decodeAlarm(event));
- position.setLatitude(parser.nextDouble(0));
- position.setLongitude(parser.nextDouble(0));
+ position.setLatitude(parser.nextDouble());
+ position.setLongitude(parser.nextDouble());
position.setTime(parser.nextDateTime());
position.setValid(parser.next().equals("A"));
position.set(Position.KEY_SATELLITES, parser.nextInt());
- int rssi = parser.nextInt(0);
+ int rssi = parser.nextInt();
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
- position.setCourse(parser.nextDouble(0));
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble()));
+ position.setCourse(parser.nextDouble());
position.set(Position.KEY_HDOP, parser.nextDouble());
- position.setAltitude(parser.nextDouble(0));
+ position.setAltitude(parser.nextDouble());
- position.set(Position.KEY_ODOMETER, parser.nextInt(0));
+ position.set(Position.KEY_ODOMETER, parser.nextInt());
position.set("runtime", parser.next());
position.setNetwork(new Network(CellTower.from(
- parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0), rssi)));
+ parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt(), rssi)));
- position.set(Position.KEY_STATUS, parser.next());
+ position.set(Position.KEY_OUTPUT, parser.nextHexInt());
+ position.set(Position.KEY_INPUT, parser.nextHexInt());
for (int i = 1; i <= 3; i++) {
- if (parser.hasNext()) {
- position.set(Position.PREFIX_ADC + i, parser.nextHexInt(0));
- }
+ position.set(Position.PREFIX_ADC + i, parser.nextHexInt());
}
String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel();
diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java
index b6f257d2c..b8ab134c5 100644
--- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java
@@ -154,6 +154,15 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder {
mac.substring(0, mac.length() - 1), rssi));
}
break;
+ case 0x23:
+ if (endIndex > buf.readerIndex()) {
+ buf.skipBytes(6); // mac
+ }
+ if (endIndex > buf.readerIndex()) {
+ position.setLatitude(buf.readIntLE() * 0.0000001);
+ position.setLongitude(buf.readIntLE() * 0.0000001);
+ }
+ break;
case 0x24:
position.setTime(new Date(buf.readUnsignedIntLE() * 1000));
long status = buf.readUnsignedIntLE();
diff --git a/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java b/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java
index 5adf61494..4d9c9afc4 100644
--- a/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/OkoProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2020 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.
@@ -36,7 +36,7 @@ public class OkoProtocolDecoder extends BaseProtocolDecoder {
private static final Pattern PATTERN = new PatternBuilder()
.text("{")
.number("(d{15}),").optional() // imei
- .number("(dd)(dd)(dd).d+,") // time
+ .number("(dd)(dd)(dd)(?:.d+)?,") // time
.expression("([AV]),") // validity
.number("(dd)(dd.d+),") // latitude
.expression("([NS]),")
@@ -46,14 +46,23 @@ public class OkoProtocolDecoder extends BaseProtocolDecoder {
.number("(d+.?d*)?,") // course
.number("(dd)(dd)(dd),") // date (ddmmyy)
.number("(d+),") // satellites
- .number("(d+.d+),") // adc
+ .number("(d+.d+|xx),") // adc
.number("(xx),") // event
- .number("(d+.d+),") // power
+ .number("(d+.d+|xx),") // power
.number("d,") // memory status
- .number("(xx)") // io
+ .number("(xx)?") // io
.any()
.compile();
+ private double decodeVoltage(Parser parser) {
+ String value = parser.next();
+ if (value.contains(".")) {
+ return Double.parseDouble(value);
+ } else {
+ return Integer.parseInt(value, 16) * 0.1;
+ }
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -89,9 +98,9 @@ public class OkoProtocolDecoder extends BaseProtocolDecoder {
position.setTime(dateBuilder.getDate());
position.set(Position.KEY_SATELLITES, parser.nextInt());
- position.set(Position.PREFIX_ADC + 1, parser.nextDouble());
+ position.set(Position.PREFIX_ADC + 1, decodeVoltage(parser));
position.set(Position.KEY_EVENT, parser.next());
- position.set(Position.KEY_POWER, parser.nextDouble());
+ position.set(Position.KEY_POWER, decodeVoltage(parser));
position.set(Position.KEY_INPUT, parser.nextHexInt());
return position;
diff --git a/src/main/java/org/traccar/protocol/OmnicommFrameDecoder.java b/src/main/java/org/traccar/protocol/OmnicommFrameDecoder.java
index 1caf6ceb9..314f19757 100644
--- a/src/main/java/org/traccar/protocol/OmnicommFrameDecoder.java
+++ b/src/main/java/org/traccar/protocol/OmnicommFrameDecoder.java
@@ -27,11 +27,11 @@ public class OmnicommFrameDecoder extends BaseFrameDecoder {
protected Object decode(
ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {
- if (buf.readableBytes() < 10) {
+ if (buf.readableBytes() < 6) {
return null;
}
- int endIndex = buf.getUnsignedShortLE(2) + buf.readerIndex() + 6;
+ int endIndex = buf.getUnsignedShortLE(buf.readerIndex() + 2) + buf.readerIndex() + 6;
if (buf.writerIndex() < endIndex) {
return null;
}
diff --git a/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java
index cd8b74c9a..6e9cf52a5 100644
--- a/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/OmnicommProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2020 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.
@@ -111,16 +111,29 @@ public class OmnicommProtocolDecoder extends BaseProtocolDecoder {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
+ if (message.hasGeneral()) {
+ OmnicommMessageOuterClass.OmnicommMessage.General data = message.getGeneral();
+ position.set(Position.KEY_POWER, data.getUboard() * 0.1);
+ position.set(Position.KEY_BATTERY_LEVEL, data.getBatLife());
+ }
+
if (message.hasNAV()) {
- OmnicommMessageOuterClass.OmnicommMessage.NAV nav = message.getNAV();
+ OmnicommMessageOuterClass.OmnicommMessage.NAV data = message.getNAV();
position.setValid(true);
- position.setTime(new Date((nav.getGPSTime() + 1230768000) * 1000L)); // from 2009-01-01 12:00
- position.setLatitude(nav.getLAT() * 0.0000001);
- position.setLongitude(nav.getLON() * 0.0000001);
- position.setSpeed(UnitsConverter.knotsFromKph(nav.getGPSVel() * 0.1));
- position.setCourse(nav.getGPSDir());
- position.setAltitude(nav.getGPSAlt() * 0.1);
- position.set(Position.KEY_SATELLITES, nav.getGPSNSat());
+ position.setTime(new Date((data.getGPSTime() + 1230768000) * 1000L)); // from 2009-01-01 12:00
+ position.setLatitude(data.getLAT() * 0.0000001);
+ position.setLongitude(data.getLON() * 0.0000001);
+ position.setSpeed(UnitsConverter.knotsFromKph(data.getGPSVel() * 0.1));
+ position.setCourse(data.getGPSDir());
+ position.setAltitude(data.getGPSAlt() * 0.1);
+ position.set(Position.KEY_SATELLITES, data.getGPSNSat());
+ }
+
+ if (message.hasLLSDt()) {
+ OmnicommMessageOuterClass.OmnicommMessage.LLSDt data = message.getLLSDt();
+ position.set("fuel1Temp", data.getTLLS1());
+ position.set("fuel1", data.getCLLS1());
+ position.set("fuel1State", data.getFLLS1());
}
if (position.getFixTime() != null) {
diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java
index 3bc71de81..ec9bbc240 100644
--- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2020 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.
@@ -15,15 +15,19 @@
*/
package org.traccar.protocol;
+import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.QueryStringDecoder;
import org.traccar.BaseHttpProtocolDecoder;
+import org.traccar.Context;
import org.traccar.DeviceSession;
import org.traccar.Protocol;
+import org.traccar.database.CommandsManager;
import org.traccar.helper.DateUtil;
import org.traccar.model.CellTower;
+import org.traccar.model.Command;
import org.traccar.model.Network;
import org.traccar.model.Position;
import org.traccar.model.WifiAccessPoint;
@@ -173,7 +177,18 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder {
}
if (position.getDeviceId() != 0) {
- sendResponse(channel, HttpResponseStatus.OK);
+ String response = null;
+ CommandsManager commandsManager = Context.getCommandsManager();
+ if (commandsManager != null) {
+ for (Command command : commandsManager.readQueuedCommands(position.getDeviceId(), 1)) {
+ response = command.getString(Command.KEY_DATA);
+ }
+ }
+ if (response != null) {
+ sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer(response, StandardCharsets.UTF_8));
+ } else {
+ sendResponse(channel, HttpResponseStatus.OK);
+ }
return position;
} else {
sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
@@ -181,4 +196,8 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder {
}
}
+ @Override
+ protected void sendQueuedCommands(Channel channel, SocketAddress remoteAddress, long deviceId) {
+ }
+
}
diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java
index 15e08d7b1..d49a73a86 100644
--- a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2020 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.
@@ -63,7 +63,7 @@ public class PacificTrackProtocolDecoder extends BaseProtocolDecoder {
while (buf.isReadable()) {
int segmentId = readBitExt(buf);
- int segmentLength = readBitExt(buf);
+ int segmentEnd = readBitExt(buf) + buf.readerIndex();
switch (segmentId) {
case 0x01:
@@ -83,12 +83,60 @@ public class PacificTrackProtocolDecoder extends BaseProtocolDecoder {
position.setSpeed(UnitsConverter.knotsFromKph(BitUtil.to(speedAndCourse, 12) * 0.1));
position.set(Position.KEY_INDEX, buf.readUnsignedShort());
break;
+ case 0x92:
+ while (buf.readerIndex() < segmentEnd) {
+ int field = buf.readUnsignedByte();
+ int fieldPrefix = BitUtil.from(field, 5);
+ if (fieldPrefix < 0b100) {
+ switch (BitUtil.between(field, 2, 5)) {
+ case 0b000:
+ position.set("bus", BitUtil.to(field, 2));
+ case 0b001:
+ position.set("currentGear", BitUtil.to(field, 2));
+ break;
+ default:
+ break;
+ }
+ } else if (fieldPrefix < 0b101) {
+ switch (BitUtil.to(field, 5)) {
+ case 0b00000:
+ position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte());
+ break;
+ case 0b00001:
+ position.set(Position.KEY_RPM, buf.readUnsignedByte() * 32);
+ break;
+ default:
+ buf.readUnsignedByte();
+ break;
+ }
+ } else if (fieldPrefix < 0b110) {
+ buf.readUnsignedShort();
+ } else if (fieldPrefix < 0b111) {
+ switch (BitUtil.to(field, 5)) {
+ case 0b00000:
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100);
+ break;
+ case 0b00001:
+ position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 180);
+ break;
+ case 0b00010:
+ position.set("idleHours", buf.readUnsignedInt() * 180);
+ break;
+ default:
+ buf.readUnsignedInt();
+ break;
+ }
+ } else {
+ buf.skipBytes(buf.readUnsignedByte());
+ }
+ }
+ break;
case 0x100:
String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(0, 15);
deviceSession = getDeviceSession(channel, remoteAddress, imei);
break;
default:
- buf.skipBytes(segmentLength);
+ buf.readerIndex(segmentEnd);
break;
}
}
diff --git a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java
index 47aa86da7..26ce2fe53 100644
--- a/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/PiligrimProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2014 - 2020 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.
@@ -18,15 +18,11 @@ package org.traccar.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
-import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
-import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
-import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
-import org.traccar.BaseProtocolDecoder;
+import org.traccar.BaseHttpProtocolDecoder;
import org.traccar.DeviceSession;
-import org.traccar.NetworkMessage;
import org.traccar.Protocol;
import org.traccar.helper.BitUtil;
import org.traccar.helper.DateBuilder;
@@ -37,19 +33,14 @@ import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.List;
-public class PiligrimProtocolDecoder extends BaseProtocolDecoder {
+public class PiligrimProtocolDecoder extends BaseHttpProtocolDecoder {
public PiligrimProtocolDecoder(Protocol protocol) {
super(protocol);
}
private void sendResponse(Channel channel, String message) {
- if (channel != null) {
- FullHttpResponse response = new DefaultFullHttpResponse(
- HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
- Unpooled.copiedBuffer(message, StandardCharsets.US_ASCII));
- channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress()));
- }
+ sendResponse(channel, HttpResponseStatus.OK, Unpooled.copiedBuffer(message, StandardCharsets.US_ASCII));
}
public static final int MSG_GPS = 0xF1;
diff --git a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java
index 8981c117b..05601ed51 100644
--- a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2020 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.
diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java
index 304f61836..5fc81085b 100644
--- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2020 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.
@@ -48,6 +48,31 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder {
super(protocol);
}
+ private boolean jsonContains(JsonObject json, String key) {
+ if (json.containsKey(key)) {
+ JsonValue value = json.get(key);
+ if (value.getValueType() == JsonValue.ValueType.STRING) {
+ return !((JsonString) value).getString().equals("null");
+
+ } else {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean getJsonBoolean(JsonObject json, String key) {
+ JsonValue value = json.get(key);
+ if (value != null) {
+ if (value.getValueType() == JsonValue.ValueType.STRING) {
+ return Boolean.parseBoolean(((JsonString) value).getString());
+ } else {
+ return value.getValueType() == JsonValue.ValueType.TRUE;
+ }
+ }
+ return false;
+ }
+
private int getJsonInt(JsonObject json, String key) {
JsonValue value = json.get(key);
if (value != null) {
@@ -83,7 +108,14 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder {
}
JsonObject json = Json.createReader(new StringReader(content)).readObject();
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("device"));
+ String deviceId;
+ if (json.containsKey("device")) {
+ deviceId = json.getString("device");
+ } else {
+ deviceId = json.getString("deviceId");
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, deviceId);
if (deviceSession == null) {
sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
return null;
@@ -92,29 +124,36 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- if (json.containsKey("time")) {
+ if (jsonContains(json, "time")) {
position.setTime(new Date(getJsonInt(json, "time") * 1000L));
+ } else if (jsonContains(json, "positionTime")) {
+ position.setTime(new Date(getJsonInt(json, "positionTime") * 1000L));
} else {
position.setTime(new Date());
}
- if (json.containsKey("location")
- || json.containsKey("lat") && json.containsKey("lng") && !json.containsKey("data")) {
+ if (jsonContains(json, "lastSeen")) {
+ position.setDeviceTime(new Date(getJsonInt(json, "lastSeen") * 1000L));
+ }
+
+ if (jsonContains(json, "location")
+ || jsonContains(json, "lat") && jsonContains(json, "lng") && !jsonContains(json, "data")
+ || jsonContains(json, "latitude") && jsonContains(json, "longitude") && !jsonContains(json, "data")) {
JsonObject location;
- if (json.containsKey("location")) {
+ if (jsonContains(json, "location")) {
location = json.getJsonObject("location");
} else {
location = json;
}
position.setValid(true);
- position.setLatitude(getJsonDouble(location, "lat"));
- position.setLongitude(getJsonDouble(location, "lng"));
+ position.setLatitude(getJsonDouble(location, jsonContains(location, "lat") ? "lat" : "latitude"));
+ position.setLongitude(getJsonDouble(location, jsonContains(location, "lng") ? "lng" : "longitude"));
- } else {
+ } else if (jsonContains(json, "data") || jsonContains(json, "payload")) {
- String data = json.getString(json.containsKey("data") ? "data" : "payload");
+ String data = json.getString(jsonContains(json, "data") ? "data" : "payload");
ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(data));
try {
int event = buf.readUnsignedByte();
@@ -205,10 +244,19 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder {
getLastLocation(position, position.getDeviceTime());
}
- if (json.containsKey("rssi")) {
+ if (jsonContains(json, "moving")) {
+ position.set(Position.KEY_MOTION, getJsonBoolean(json, "moving"));
+ }
+ if (jsonContains(json, "magStatus")) {
+ position.set(Position.KEY_BLOCKED, getJsonBoolean(json, "magStatus"));
+ }
+ if (jsonContains(json, "temperature")) {
+ position.set(Position.KEY_DEVICE_TEMP, getJsonDouble(json, "temperature"));
+ }
+ if (jsonContains(json, "rssi")) {
position.set(Position.KEY_RSSI, getJsonDouble(json, "rssi"));
}
- if (json.containsKey("seqNumber")) {
+ if (jsonContains(json, "seqNumber")) {
position.set(Position.KEY_INDEX, getJsonInt(json, "seqNumber"));
}
diff --git a/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java b/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java
index eae37386a..6fe54b0b0 100644
--- a/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/SolarPoweredProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2020 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.
@@ -77,10 +77,24 @@ public class SolarPoweredProtocolDecoder extends BaseProtocolDecoder {
position.setLongitude(-position.getLongitude());
}
position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
- position.set(Position.KEY_DEVICE_TEMP, (int) buf.readByte());
+ int temperature = buf.readUnsignedByte();
+ if (BitUtil.check(temperature, 7)) {
+ position.set(Position.KEY_DEVICE_TEMP, -BitUtil.to(temperature, 7));
+ } else {
+ position.set(Position.KEY_DEVICE_TEMP, BitUtil.to(temperature, 7));
+ }
position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.02);
position.setCourse(buf.readUnsignedByte());
break;
+ case 0x83:
+ buf.readUnsignedInt(); // uptime
+ buf.readUnsignedInt(); // gps count
+ buf.readUnsignedInt(); // gsm count
+ buf.readUnsignedByte(); // positioning time
+ buf.readUnsignedByte(); // registration time
+ buf.readUnsignedByte(); // connection time
+ position.set(Position.KEY_RSSI, buf.readUnsignedByte());
+ break;
default:
buf.skipBytes(length);
break;
diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java
index bad6f03a9..2d1613e03 100644
--- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2020 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.
@@ -140,6 +140,11 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder {
event = Integer.parseInt(data[i]);
position.set(Position.KEY_ALARM, decodeAlarm(event));
position.set(Position.KEY_EVENT, event);
+ if (event == 24) {
+ position.set(Position.KEY_IGNITION, true);
+ } else if (event == 25) {
+ position.set(Position.KEY_IGNITION, false);
+ }
break;
case "#PDT#":
position.setFixTime(dateFormat.parse(data[i]));
diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java
index 915f764e1..978d768be 100644
--- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java
@@ -397,7 +397,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
if (isIncludeAdc(deviceSession.getDeviceId())) {
for (int i = 1; i <= 3; i++) {
- if (!values[index++].isEmpty()) {
+ if (index < values.length && !values[index++].isEmpty()) {
position.set(Position.PREFIX_ADC + i, Double.parseDouble(values[index - 1]));
}
}
@@ -614,10 +614,21 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_OUTPUT, buf.readUnsignedByte());
}
+ int alertId = 0;
if (BitUtil.check(mask, 19)) {
- int value = buf.readUnsignedByte();
+ alertId = buf.readUnsignedByte();
if (type == 0x82) {
- position.set(Position.KEY_ALARM, decodeAlert(value));
+ position.set(Position.KEY_ALARM, decodeAlert(alertId));
+ }
+ }
+
+ if (BitUtil.check(mask, 20)) {
+ buf.readUnsignedShort(); // alert mod
+ }
+
+ if (BitUtil.check(mask, 21)) {
+ if (alertId == 59) {
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(8)));
}
}
diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
index 9b146ec90..3331ebb71 100644
--- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2020 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.
@@ -177,8 +177,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder {
}
private Position decodePosition(
- Channel channel, DeviceSession deviceSession,
- ByteBuf buf, int type, int index, ByteBuf imei) {
+ Channel channel, DeviceSession deviceSession, ByteBuf buf, int type, int index, ByteBuf imei) {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
@@ -214,8 +213,10 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(io, 7 + i));
}
- position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort());
- position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort());
+ if (header != 0x2626) {
+ position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort());
+ position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort());
+ }
}
diff --git a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java
index 457687b2e..a4f9e2989 100644
--- a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2014 - 2020 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.
@@ -42,8 +42,8 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder {
.number("(dd)(dd)(dd)") // date (ddmmyy)
.number("(dd)(dd)(dd),") // time (hhmmss)
.groupBegin()
- .number("(-?d{9}),") // longitude
- .number("(-?d{8}),") // latitude
+ .number("(-?d{8,}),") // longitude
+ .number("(-?d{7,}),") // latitude
.or()
.number("(-?d+),") // longitude
.number("(-?d+),") // latitude
diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java
index 7ad99b37e..3ce6438f8 100644
--- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java
@@ -38,7 +38,7 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder {
private static final Pattern PATTERN_HEADER = new PatternBuilder()
.number("#(d+)") // imei
.expression("#[^#]*") // user
- .number("#d+") // password
+ .number("#d*") // password
.groupBegin()
.number("#([01])") // door
.number("#(d+)") // fuel voltage
diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java
index ea72b7cb8..eee0e9ae8 100644
--- a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 - 2020 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.
@@ -23,6 +23,8 @@ import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
import org.traccar.NetworkMessage;
import org.traccar.Protocol;
+import org.traccar.helper.BcdUtil;
+import org.traccar.helper.DateBuilder;
import org.traccar.model.CellTower;
import org.traccar.model.Network;
import org.traccar.model.Position;
@@ -44,11 +46,11 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_WIFI_OFFLINE = 0x17;
public static final int MSG_WIFI = 0x69;
- private void sendResponse(Channel channel, int type, ByteBuf content) {
+ private void sendResponse(Channel channel, int length, int type, ByteBuf content) {
if (channel != null) {
ByteBuf response = Unpooled.buffer();
response.writeShort(0x7878);
- response.writeByte(1 + content.readableBytes());
+ response.writeByte(length);
response.writeByte(type);
response.writeBytes(content);
response.writeByte('\r');
@@ -75,7 +77,7 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder {
deviceSession = getDeviceSession(channel, remoteAddress, imei);
ByteBuf content = Unpooled.buffer();
content.writeByte(deviceSession != null ? 0x01 : 0x44);
- sendResponse(channel, type, content);
+ sendResponse(channel, length, type, content);
return null;
} else {
deviceSession = getDeviceSession(channel, remoteAddress);
@@ -95,7 +97,7 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder {
ByteBuf content = Unpooled.buffer();
content.writeBytes(time);
- sendResponse(channel, type, content);
+ sendResponse(channel, length, type, content);
return position;
@@ -127,7 +129,7 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder {
if (length >= 7) {
content.writeByte(signal);
}
- sendResponse(channel, type, content);
+ sendResponse(channel, length, type, content);
return position;
@@ -136,9 +138,17 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- getLastLocation(position, null);
-
ByteBuf time = buf.readSlice(6);
+ DateBuilder dateBuilder = new DateBuilder()
+ .setYear(BcdUtil.readInteger(time, 2))
+ .setMonth(BcdUtil.readInteger(time, 2))
+ .setDay(BcdUtil.readInteger(time, 2))
+ .setHour(BcdUtil.readInteger(time, 2))
+ .setMinute(BcdUtil.readInteger(time, 2))
+ .setSecond(BcdUtil.readInteger(time, 2));
+ time.resetReaderIndex();
+
+ getLastLocation(position, dateBuilder.getDate());
Network network = new Network();
for (int i = 0; i < length; i++) {
@@ -160,7 +170,7 @@ public class TopinProtocolDecoder extends BaseProtocolDecoder {
ByteBuf content = Unpooled.buffer();
content.writeBytes(time);
- sendResponse(channel, type, content);
+ sendResponse(channel, length, type, content);
return position;
diff --git a/src/main/java/org/traccar/protocol/WondexProtocol.java b/src/main/java/org/traccar/protocol/WondexProtocol.java
index 035dd9160..6401fde85 100644
--- a/src/main/java/org/traccar/protocol/WondexProtocol.java
+++ b/src/main/java/org/traccar/protocol/WondexProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2020 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.
@@ -25,7 +25,7 @@ import io.netty.handler.codec.string.StringEncoder;
public class WondexProtocol extends BaseProtocol {
public WondexProtocol() {
- setSupportedCommands(
+ setSupportedDataCommands(
Command.TYPE_GET_DEVICE_STATUS,
Command.TYPE_GET_MODEM_STATUS,
Command.TYPE_REBOOT_DEVICE,
@@ -33,6 +33,13 @@ public class WondexProtocol extends BaseProtocol {
Command.TYPE_GET_VERSION,
Command.TYPE_IDENTIFICATION);
setTextCommandEncoder(new WondexProtocolEncoder(this));
+ setSupportedTextCommands(
+ Command.TYPE_GET_DEVICE_STATUS,
+ Command.TYPE_GET_MODEM_STATUS,
+ Command.TYPE_REBOOT_DEVICE,
+ Command.TYPE_POSITION_SINGLE,
+ Command.TYPE_GET_VERSION,
+ Command.TYPE_IDENTIFICATION);
addServer(new TrackerServer(false, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {