diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2016-07-14 16:42:27 +1200 |
---|---|---|
committer | Anton Tananaev <anton.tananaev@gmail.com> | 2016-07-14 16:42:27 +1200 |
commit | 6dfd599ef69fac9ea0851e3c07873c6368231610 (patch) | |
tree | 70e6b64e9b97e4f1082e9fa3bbcbdd0fb284c910 | |
parent | 82fd4d09aa7ac37bf2eb1857b12efbd3bc773a94 (diff) | |
download | traccar-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.java | 129 | ||||
-rw-r--r-- | test/org/traccar/protocol/EelinkProtocolDecoderTest.java | 9 |
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( |