aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2016-07-14 16:42:27 +1200
committerAnton Tananaev <anton.tananaev@gmail.com>2016-07-14 16:42:27 +1200
commit6dfd599ef69fac9ea0851e3c07873c6368231610 (patch)
tree70e6b64e9b97e4f1082e9fa3bbcbdd0fb284c910
parent82fd4d09aa7ac37bf2eb1857b12efbd3bc773a94 (diff)
downloadtraccar-server-6dfd599ef69fac9ea0851e3c07873c6368231610.tar.gz
traccar-server-6dfd599ef69fac9ea0851e3c07873c6368231610.tar.bz2
traccar-server-6dfd599ef69fac9ea0851e3c07873c6368231610.zip
Support new eelink protocol messages
-rw-r--r--src/org/traccar/protocol/EelinkProtocolDecoder.java129
-rw-r--r--test/org/traccar/protocol/EelinkProtocolDecoderTest.java9
2 files changed, 108 insertions, 30 deletions
diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java
index 09cf1808f..e9de73dd5 100644
--- a/src/org/traccar/protocol/EelinkProtocolDecoder.java
+++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2014 - 2016 Anton Tananaev (anton.tananaev@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
+import org.traccar.helper.BitUtil;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
@@ -41,6 +42,16 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_INTERACTIVE = 0x80;
public static final int MSG_DATA = 0x81;
+ public static final int MSG_NORMAL = 0x12;
+ public static final int MSG_WARNING = 0x14;
+ public static final int MSG_REPORT = 0x15;
+ public static final int MSG_COMMAND = 0x16;
+ public static final int MSG_OBD_DATA = 0x17;
+ public static final int MSG_OBD_BODY = 0x18;
+ public static final int MSG_OBD_CODE = 0x19;
+ public static final int MSG_CAMERA_INFO = 0x1E;
+ public static final int MSG_CAMERA_DATA = 0x1F;
+
private void sendResponse(Channel channel, int type, int index) {
if (channel != null) {
ChannelBuffer response = ChannelBuffers.buffer(7);
@@ -52,57 +63,115 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder {
}
}
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ private Position decodeOld(ChannelBuffer buf, int type, int index) {
- ChannelBuffer buf = (ChannelBuffer) msg;
+ Position position = new Position();
+ position.setDeviceId(getDeviceId());
+ position.setProtocol(getProtocolName());
- buf.skipBytes(2); // header
- int type = buf.readUnsignedByte();
- buf.readShort(); // length
- int index = buf.readUnsignedShort();
+ position.set(Position.KEY_INDEX, index);
- if (type != MSG_GPS && type != MSG_DATA) {
- sendResponse(channel, type, index);
+ position.setTime(new Date(buf.readUnsignedInt() * 1000));
+ position.setLatitude(buf.readInt() / 1800000.0);
+ position.setLongitude(buf.readInt() / 1800000.0);
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
+ position.setCourse(buf.readUnsignedShort());
+
+ position.set(Position.KEY_MCC, buf.readUnsignedShort());
+ position.set(Position.KEY_MNC, buf.readUnsignedShort());
+ position.set(Position.KEY_LAC, buf.readUnsignedShort());
+ position.set(Position.KEY_CID, buf.readUnsignedMedium());
+
+ position.setValid((buf.readUnsignedByte() & 0x01) != 0);
+
+ if (type == MSG_ALARM) {
+ position.set(Position.KEY_ALARM, buf.readUnsignedByte());
}
- if (type == MSG_LOGIN) {
+ if (type == MSG_STATE) {
+ position.set(Position.KEY_STATUS, buf.readUnsignedByte());
+ }
- identify(ChannelBuffers.hexDump(buf.readBytes(8)).substring(1), channel, remoteAddress);
+ return position;
+ }
+
+ private Position decodeNew(ChannelBuffer buf, int type, int index) {
+
+ Position position = new Position();
+ position.setDeviceId(getDeviceId());
+ position.setProtocol(getProtocolName());
- } else if (hasDeviceId()
- && (type == MSG_GPS || type == MSG_ALARM || type == MSG_STATE || type == MSG_SMS)) {
+ position.set(Position.KEY_INDEX, index);
- Position position = new Position();
- position.setDeviceId(getDeviceId());
+ position.setTime(new Date(buf.readUnsignedInt() * 1000));
- position.setProtocol(getProtocolName());
- position.set(Position.KEY_INDEX, index);
+ int flags = buf.readUnsignedByte();
- position.setTime(new Date(buf.readUnsignedInt() * 1000));
+ if (BitUtil.check(flags, 0)) {
position.setLatitude(buf.readInt() / 1800000.0);
position.setLongitude(buf.readInt() / 1800000.0);
- position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
+ position.setAltitude(buf.readShort());
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort()));
position.setCourse(buf.readUnsignedShort());
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+ }
+ if (BitUtil.check(flags, 1)) {
position.set(Position.KEY_MCC, buf.readUnsignedShort());
position.set(Position.KEY_MNC, buf.readUnsignedShort());
position.set(Position.KEY_LAC, buf.readUnsignedShort());
- position.set(Position.KEY_CID, buf.readUnsignedMedium());
+ position.set(Position.KEY_CID, buf.readUnsignedInt());
+ position.set(Position.KEY_GSM, buf.readUnsignedByte());
+ }
- position.setValid((buf.readUnsignedByte() & 0x01) != 0);
+ if (BitUtil.check(flags, 2)) {
+ buf.skipBytes(7); // bsid1
+ }
- if (type == MSG_ALARM) {
- position.set(Position.KEY_ALARM, buf.readUnsignedByte());
- }
+ if (BitUtil.check(flags, 3)) {
+ buf.skipBytes(7); // bsid2
+ }
- if (type == MSG_STATE) {
- position.set(Position.KEY_STATUS, buf.readUnsignedByte());
- }
+ if (BitUtil.check(flags, 4)) {
+ buf.skipBytes(7); // bss0
+ }
+
+ if (BitUtil.check(flags, 5)) {
+ buf.skipBytes(7); // bss1
+ }
+
+ if (BitUtil.check(flags, 6)) {
+ buf.skipBytes(7); // bss2
+ }
+
+ return position;
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
- return position;
+ buf.skipBytes(2); // header
+ int type = buf.readUnsignedByte();
+ buf.readShort(); // length
+ int index = buf.readUnsignedShort();
+ if (type != MSG_GPS && type != MSG_DATA) {
+ sendResponse(channel, type, index);
+ }
+
+ if (type == MSG_LOGIN) {
+
+ identify(ChannelBuffers.hexDump(buf.readBytes(8)).substring(1), channel, remoteAddress);
+
+ } else if (hasDeviceId()) {
+ if (type == MSG_GPS || type == MSG_ALARM || type == MSG_STATE || type == MSG_SMS) {
+ return decodeOld(buf, type, index);
+ } else if (type >= MSG_NORMAL && type <= MSG_OBD_CODE) {
+ return decodeNew(buf, type, index);
+ }
}
return null;
diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java
index d7a6c5e86..925e90dd6 100644
--- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java
@@ -11,6 +11,15 @@ public class EelinkProtocolDecoderTest extends ProtocolTest {
EelinkProtocolDecoder decoder = new EelinkProtocolDecoder(new EelinkProtocol());
verifyNothing(decoder, binary(
+ "676701000c007b03525440717505180104"));
+
+ verifyPosition(decoder, binary(
+ "676712003400505784cc0b130246479b07d05a06001800000000070195039f046100002cc52e6466b391604a4900890e7c00000000000006ca"));
+
+ verifyPosition(decoder, binary(
+ "676714002b00515784cc24130246479b07d05a06001800010000060195039f046100002cc52f6466b391604a49020089"));
+
+ verifyNothing(decoder, binary(
"676701000c002603541880486128290120"));
verifyPosition(decoder, binary(