diff options
Diffstat (limited to 'src/org/traccar/protocol/EgtsProtocolDecoder.java')
-rw-r--r-- | src/org/traccar/protocol/EgtsProtocolDecoder.java | 155 |
1 files changed, 122 insertions, 33 deletions
diff --git a/src/org/traccar/protocol/EgtsProtocolDecoder.java b/src/org/traccar/protocol/EgtsProtocolDecoder.java index d05504d81..45e191d1e 100644 --- a/src/org/traccar/protocol/EgtsProtocolDecoder.java +++ b/src/org/traccar/protocol/EgtsProtocolDecoder.java @@ -15,14 +15,19 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; +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.helper.BitUtil; +import org.traccar.helper.Checksum; +import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -33,6 +38,10 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public static final int PT_RESPONSE = 0; + public static final int PT_APPDATA = 1; + public static final int PT_SIGNED_APPDATA = 2; + public static final int SERVICE_AUTH = 1; public static final int SERVICE_TELEDATA = 2; public static final int SERVICE_COMMANDS = 4; @@ -60,60 +69,138 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LIQUID_LEVEL_SENSOR = 27; public static final int MSG_PASSENGERS_COUNTERS = 28; + private int packetId; + + private void sendResponse( + Channel channel, int packetType, int index, int serviceType, int type, ByteBuf content) { + if (channel != null) { + + ByteBuf data = Unpooled.buffer(); + data.writeByte(type); + data.writeShortLE(content.readableBytes()); + data.writeBytes(content); + content.release(); + + ByteBuf record = Unpooled.buffer(); + if (packetType == PT_RESPONSE) { + record.writeShortLE(index); + record.writeByte(0); // success + } + record.writeShortLE(data.readableBytes()); + record.writeShortLE(0); + record.writeByte(0); // flags (possibly 1 << 6) + record.writeByte(serviceType); + record.writeByte(serviceType); + record.writeBytes(data); + data.release(); + int recordChecksum = Checksum.crc16(Checksum.CRC16_CCITT_FALSE, record.nioBuffer()); + + ByteBuf response = Unpooled.buffer(); + response.writeByte(1); // protocol version + response.writeByte(0); // security key id + response.writeByte(0); // flags + response.writeByte(5 + 2 + 2 + 2); // header length + response.writeByte(0); // encoding + response.writeShortLE(record.readableBytes()); + response.writeShortLE(packetId++); + response.writeByte(packetType); + response.writeByte(Checksum.crc8(Checksum.CRC8_EGTS, response.nioBuffer())); + response.writeBytes(record); + record.release(); + response.writeShortLE(recordChecksum); + + channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); + + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + ByteBuf buf = (ByteBuf) msg; + int index = buf.getUnsignedShort(buf.readerIndex() + 5 + 2); buf.skipBytes(buf.getUnsignedByte(buf.readerIndex() + 3)); - DeviceSession deviceSession = null; List<Position> positions = new LinkedList<>(); while (buf.readableBytes() > 2) { - int length = buf.readUnsignedShort(); - - buf.readUnsignedShort(); // index - + int length = buf.readUnsignedShortLE(); + int recordIndex = buf.readUnsignedShortLE(); int recordFlags = buf.readUnsignedByte(); if (BitUtil.check(recordFlags, 0)) { - String deviceId = String.valueOf(buf.readUnsignedInt()); - if (deviceSession == null) { - deviceSession = getDeviceSession(channel, remoteAddress, deviceId); - } - } - - if (deviceSession == null) { - deviceSession = getDeviceSession(channel, remoteAddress); + buf.readUnsignedIntLE(); // object id } if (BitUtil.check(recordFlags, 1)) { - buf.readUnsignedInt(); // event id + buf.readUnsignedIntLE(); // event id } if (BitUtil.check(recordFlags, 2)) { - buf.readUnsignedInt(); // time + buf.readUnsignedIntLE(); // time } - buf.readUnsignedByte(); // source service type + int serviceType = buf.readUnsignedByte(); buf.readUnsignedByte(); // recipient service type int recordEnd = buf.readerIndex() + length; Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + } + + ByteBuf response = Unpooled.buffer(); + response.writeShortLE(recordIndex); + response.writeByte(0); // success + sendResponse(channel, PT_RESPONSE, index, serviceType, MSG_RECORD_RESPONSE, response); while (buf.readerIndex() < recordEnd) { int type = buf.readUnsignedByte(); - int end = buf.readUnsignedShort() + buf.readerIndex(); + int end = buf.readUnsignedShortLE() + buf.readerIndex(); + + if (type == MSG_TERM_IDENTITY) { + + buf.readUnsignedIntLE(); // object id + int flags = buf.readUnsignedByte(); + + if (BitUtil.check(flags, 0)) { + buf.readUnsignedShortLE(); // home dispatcher identifier + } + if (BitUtil.check(flags, 1)) { + getDeviceSession( + channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII).trim()); + } + if (BitUtil.check(flags, 2)) { + getDeviceSession( + channel, remoteAddress, buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim()); + } + if (BitUtil.check(flags, 3)) { + buf.skipBytes(3); // language identifier + } + if (BitUtil.check(flags, 5)) { + buf.skipBytes(3); // network identifier + } + if (BitUtil.check(flags, 6)) { + buf.readUnsignedShortLE(); // buffer size + } + if (BitUtil.check(flags, 7)) { + getDeviceSession( + channel, remoteAddress, buf.readSlice(15).toString(StandardCharsets.US_ASCII).trim()); + } - if (type == MSG_POS_DATA) { + response = Unpooled.buffer(); + response.writeByte(0); // success + sendResponse(channel, PT_APPDATA, 0, serviceType, MSG_RESULT_CODE, response); - position.setTime(new Date((buf.readUnsignedInt() + 1262304000) * 1000)); // since 2010-01-01 - position.setLatitude(buf.readUnsignedInt() * 90.0 / 0xFFFFFFFFL); - position.setLongitude(buf.readUnsignedInt() * 180.0 / 0xFFFFFFFFL); + } else if (type == MSG_POS_DATA) { + + position.setTime(new Date((buf.readUnsignedIntLE() + 1262304000) * 1000)); // since 2010-01-01 + position.setLatitude(buf.readUnsignedIntLE() * 90.0 / 0xFFFFFFFFL); + position.setLongitude(buf.readUnsignedIntLE() * 180.0 / 0xFFFFFFFFL); int flags = buf.readUnsignedByte(); position.setValid(BitUtil.check(flags, 0)); @@ -124,16 +211,16 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(-position.getLongitude()); } - int speed = buf.readUnsignedShort(); - position.setSpeed(BitUtil.to(speed, 14)); + int speed = buf.readUnsignedShortLE(); + position.setSpeed(UnitsConverter.knotsFromKph(BitUtil.to(speed, 14) * 0.1)); position.setCourse(buf.readUnsignedByte() + (BitUtil.check(speed, 15) ? 0x100 : 0)); - position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 100); + position.set(Position.KEY_ODOMETER, buf.readUnsignedMediumLE() * 100); position.set(Position.KEY_INPUT, buf.readUnsignedByte()); position.set(Position.KEY_EVENT, buf.readUnsignedByte()); if (BitUtil.check(flags, 7)) { - position.setAltitude(buf.readMedium()); + position.setAltitude(buf.readMediumLE()); } } else if (type == MSG_EXT_POS_DATA) { @@ -141,13 +228,13 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { int flags = buf.readUnsignedByte(); if (BitUtil.check(flags, 0)) { - position.set(Position.KEY_VDOP, buf.readUnsignedShort()); + position.set(Position.KEY_VDOP, buf.readUnsignedShortLE()); } if (BitUtil.check(flags, 1)) { - position.set(Position.KEY_HDOP, buf.readUnsignedShort()); + position.set(Position.KEY_HDOP, buf.readUnsignedShortLE()); } if (BitUtil.check(flags, 2)) { - position.set(Position.KEY_PDOP, buf.readUnsignedShort()); + position.set(Position.KEY_PDOP, buf.readUnsignedShortLE()); } if (BitUtil.check(flags, 3)) { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); @@ -166,7 +253,9 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { buf.readerIndex(end); } - positions.add(position); + if (serviceType == SERVICE_TELEDATA && deviceSession != null) { + positions.add(position); + } } return positions.isEmpty() ? null : positions; |