From 818fff6daf87a9e90a225122d04dc8b93694a8c6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Nov 2017 20:01:45 +1300 Subject: Fix eelink checksum and decode result --- .../traccar/protocol/EelinkProtocolDecoder.java | 74 +++++++++++++++++++++- .../traccar/protocol/EelinkProtocolEncoder.java | 11 +++- .../protocol/EelinkProtocolDecoderTest.java | 6 +- .../protocol/EelinkProtocolEncoderTest.java | 6 +- 4 files changed, 89 insertions(+), 8 deletions(-) diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 91ae16289..f2b4f0765 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -21,13 +21,17 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.regex.Pattern; public class EelinkProtocolDecoder extends BaseProtocolDecoder { @@ -259,13 +263,73 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return position; } + /* + gg€^WˆLuLuLat:N23.111743 +Lon:E114.409238 +Course:0.00 +Speed:0.17KM/H +Date Time:2015-09-13 20:21:20 + */ + + private static final Pattern PATTERN = new PatternBuilder() + .text("Lat:") + .number("([NS])(d+.d+)") // latitude + .any() + .text("Lon:") + .number("([EW])(d+.d+)") // longitude + .any() + .text("Course:") + .number("(d+.d+)") // course + .any() + .text("Speed:") + .number("(d+.d+)KM/H") // speed + .any() + .text("Date Time:") + .number("(dddd)-(dd)-(dd) ") // date + .number("(dd):(dd):(dd)") // time + .compile(); + + private Position decodeResult(DeviceSession deviceSession, ChannelBuffer buf, int index) { + + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); + + position.set(Position.KEY_INDEX, index); + + buf.readUnsignedByte(); // type + buf.readUnsignedInt(); // uid + + String sentence = buf.toString(StandardCharsets.UTF_8); + + Parser parser = new Parser(PATTERN, sentence); + if (parser.matches()) { + + position.setValid(true); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG)); + position.setCourse(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setTime(parser.nextDateTime()); + + } else { + + getLastLocation(position, null); + + position.set(Position.KEY_RESULT, sentence); + + } + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; - DeviceSession deviceSession = null; + DeviceSession deviceSession; if (buf.getByte(0) == 'E' && buf.getByte(1) == 'L') { buf.skipBytes(2 + 2 + 2); // udp header @@ -297,9 +361,13 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { } if (type == MSG_GPS || type == MSG_ALARM || type == MSG_STATE || type == MSG_SMS) { + return decodeOld(deviceSession, buf, type, index); + } else if (type >= MSG_NORMAL && type <= MSG_OBD_CODE) { + return decodeNew(deviceSession, buf, index); + } else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2) { Position position = new Position(); @@ -312,6 +380,10 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_DOWNLINK) { + + return decodeResult(deviceSession, buf, index); + } } diff --git a/src/org/traccar/protocol/EelinkProtocolEncoder.java b/src/org/traccar/protocol/EelinkProtocolEncoder.java index b9be684a3..917f964fe 100644 --- a/src/org/traccar/protocol/EelinkProtocolEncoder.java +++ b/src/org/traccar/protocol/EelinkProtocolEncoder.java @@ -22,6 +22,7 @@ import org.traccar.helper.Log; import org.traccar.model.Command; import javax.xml.bind.DatatypeConverter; +import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; public class EelinkProtocolEncoder extends BaseProtocolEncoder { @@ -32,6 +33,14 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder { this.connectionless = connectionless; } + public static int checksum(ByteBuffer buf) { + int sum = 0; + while (buf.hasRemaining()) { + sum = (((sum << 1) | (sum >> 15)) + (buf.get() & 0xFF)) & 0xFFFF; + } + return sum; + } + private ChannelBuffer encodeContent(long deviceId, String content) { ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); @@ -56,7 +65,7 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder { result.writeByte('E'); result.writeByte('L'); result.writeShort(2 + 2 + 2 + buf.readableBytes()); // length - result.writeShort(0); // checksum + result.writeShort(checksum(buf.toByteBuffer())); } result.writeBytes(buf); diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java index b029795e0..a7477c823 100644 --- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -14,11 +14,11 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { "454C0027E753035254407167747167670100180002035254407167747100200205020500010432000086BD")); verifyPosition(decoder, binary( - "454C0050EAE2035254407167747167671200410021590BD93803026B940D0C3952AD0021000000000501CC0001A53F0170F0AB1305890F11000000000000C2D0001C001600000000000000000000000000000000")); - - verifyNull(decoder, binary( "676780005E5788014C754C754C61743A4E32332E3131313734330A4C6F6E3A453131342E3430393233380A436F757273653A302E30300A53706565643A302E31374B4D2F480A446174652054696D653A323031352D30392D31332032303A32313A3230")); + verifyPosition(decoder, binary( + "454C0050EAE2035254407167747167671200410021590BD93803026B940D0C3952AD0021000000000501CC0001A53F0170F0AB1305890F11000000000000C2D0001C001600000000000000000000000000000000")); + verifyNull(decoder, binary( "676701000c007b03525440717505180104")); diff --git a/test/org/traccar/protocol/EelinkProtocolEncoderTest.java b/test/org/traccar/protocol/EelinkProtocolEncoderTest.java index e0843b36d..96be348d1 100644 --- a/test/org/traccar/protocol/EelinkProtocolEncoderTest.java +++ b/test/org/traccar/protocol/EelinkProtocolEncoderTest.java @@ -9,13 +9,13 @@ public class EelinkProtocolEncoderTest extends ProtocolTest { @Test public void testEncode() throws Exception { - EelinkProtocolEncoder encoder = new EelinkProtocolEncoder(false); - Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); - verifyCommand(encoder, command, binary("676780000f0000010000000052454c41592c3123")); + verifyCommand(new EelinkProtocolEncoder(false), command, binary("676780000f0000010000000052454c41592c3123")); + + verifyCommand(new EelinkProtocolEncoder(true), command, binary("454c0022b41a0123456789012345676780000f0000010000000052454c41592c3123")); } -- cgit v1.2.3