diff options
Diffstat (limited to 'src/org/traccar/protocol/EelinkProtocolDecoder.java')
-rw-r--r-- | src/org/traccar/protocol/EelinkProtocolDecoder.java | 95 |
1 files changed, 85 insertions, 10 deletions
diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 8d0f8016a..98a9f7d6d 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -18,16 +18,21 @@ package org.traccar.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.socket.DatagramChannel; 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 { @@ -55,14 +60,10 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { 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) { + private void sendResponse(Channel channel, SocketAddress remoteAddress, String uniqueId, int type, int index) { if (channel != null) { - ChannelBuffer response = ChannelBuffers.buffer(7); - response.writeByte(0x67); response.writeByte(0x67); // header - response.writeByte(type); - response.writeShort(2); // length - response.writeShort(index); - channel.write(response); + channel.write(EelinkProtocolEncoder.encodeContent( + channel instanceof DatagramChannel, uniqueId, type, index, null), remoteAddress); } } @@ -189,6 +190,8 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); position.setCourse(buf.readUnsignedShort()); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + } else { + getLastLocation(position, position.getDeviceTime()); } if (BitUtil.check(flags, 1)) { @@ -259,36 +262,104 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return position; } + 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+)") // speed + .any() + .expression("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; + String uniqueId = null; + DeviceSession deviceSession; + + if (buf.getByte(0) == 'E' && buf.getByte(1) == 'L') { + buf.skipBytes(2 + 2 + 2); // udp header + uniqueId = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + deviceSession = getDeviceSession(channel, remoteAddress, uniqueId); + } else { + deviceSession = getDeviceSession(channel, remoteAddress); + } + 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); + sendResponse(channel, remoteAddress, uniqueId, type, index); } if (type == MSG_LOGIN) { - getDeviceSession(channel, remoteAddress, ChannelBuffers.hexDump(buf.readBytes(8)).substring(1)); + if (deviceSession == null) { + getDeviceSession(channel, remoteAddress, ChannelBuffers.hexDump(buf.readBytes(8)).substring(1)); + } } else { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } 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(); @@ -301,6 +372,10 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == MSG_DOWNLINK) { + + return decodeResult(deviceSession, buf, index); + } } |