From 5757c40f845b6470ba0e1288ce9ee1db58cf32bd Mon Sep 17 00:00:00 2001 From: Sergey Kostin <7er@inbox.ru> Date: Thu, 1 Aug 2019 12:40:00 +0300 Subject: egts with oid authentication (auto-detect) --- .../org/traccar/protocol/EgtsProtocolDecoder.java | 277 ++++++++++++--------- 1 file changed, 164 insertions(+), 113 deletions(-) (limited to 'src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java') diff --git a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java index b9fcb2f44..34e4aa137 100644 --- a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java @@ -18,6 +18,8 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; @@ -35,10 +37,14 @@ import java.util.List; public class EgtsProtocolDecoder extends BaseProtocolDecoder { + private static final Logger LOGGER = LoggerFactory.getLogger(EgtsProtocolDecoder.class); + public EgtsProtocolDecoder(Protocol protocol) { super(protocol); } + private boolean useOidAsDeviceId = true; + public static final int PT_RESPONSE = 0; public static final int PT_APPDATA = 1; public static final int PT_SIGNED_APPDATA = 2; @@ -68,7 +74,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_ABS_CNTR_DATA = 25; public static final int MSG_ABS_LOOPIN_DATA = 26; public static final int MSG_LIQUID_LEVEL_SENSOR = 27; - public static final int MSG_PASSENGERS_COUNTERS = 28; + public static final int MSG_PASSENGERS_COUNTERS = 28; private int packetId; @@ -121,141 +127,186 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; - int index = buf.getUnsignedShort(buf.readerIndex() + 5 + 2); - buf.skipBytes(buf.getUnsignedByte(buf.readerIndex() + 3)); - List positions = new LinkedList<>(); - while (buf.readableBytes() > 2) { - - int length = buf.readUnsignedShortLE(); - int recordIndex = buf.readUnsignedShortLE(); - int recordFlags = buf.readUnsignedByte(); - - if (BitUtil.check(recordFlags, 0)) { - buf.readUnsignedIntLE(); // object id - } + // buf possibly contains multiple packets + while (buf.readableBytes() >= 11) { - if (BitUtil.check(recordFlags, 1)) { - buf.readUnsignedIntLE(); // event id - } - if (BitUtil.check(recordFlags, 2)) { - buf.readUnsignedIntLE(); // time - } +// short packetFlags = buf.getUnsignedByte(buf.readerIndex() + 2); +// if (BitUtil.check(packetFlags, 5)) { +// int pra = buf.getUnsignedShortLE(10); +// int rca = buf.getUnsignedShortLE(12); +// short ttl = buf.getUnsignedByte(14); +// LOGGER.trace("PRA:{} RCA:{} TTL: {}", pra, rca, ttl); +// } - int serviceType = buf.readUnsignedByte(); - buf.readUnsignedByte(); // recipient service type + short headerLength = buf.getUnsignedByte(buf.readerIndex() + 3); + int frameDataLength = buf.getUnsignedShortLE(buf.readerIndex() + 5); + int index = buf.getUnsignedShort(buf.readerIndex() + 5 + 2); + short packetType = buf.getUnsignedByte(buf.readerIndex() + 5 + 2 + 2); + buf.skipBytes(headerLength); - int recordEnd = buf.readerIndex() + length; - - Position position = new Position(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession != null) { - position.setDeviceId(deviceSession.getDeviceId()); + if (packetType == PT_RESPONSE) { + // some retranslator systems do send response on response packets + if (frameDataLength > 0) { + buf.skipBytes(frameDataLength + 2); // 2-byte CRC is present only if frameData exists + } + continue; } - 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.readUnsignedShortLE() + buf.readerIndex(); - - if (type == MSG_TERM_IDENTITY) { - - buf.readUnsignedIntLE(); // object id - int flags = buf.readUnsignedByte(); + int frameDataEnd = buf.readerIndex() + frameDataLength; + long oid = 0L; + while (buf.readerIndex() < frameDataEnd) { - 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()); - } + int length = buf.readUnsignedShortLE(); + int recordIndex = buf.readUnsignedShortLE(); + int recordFlags = buf.readUnsignedByte(); - response = Unpooled.buffer(); - response.writeByte(0); // success - sendResponse(channel, PT_APPDATA, 0, serviceType, MSG_RESULT_CODE, response); + if (BitUtil.check(recordFlags, 0)) { + oid = buf.readUnsignedIntLE(); // object id + } - } else if (type == MSG_POS_DATA) { + if (BitUtil.check(recordFlags, 1)) { + buf.readUnsignedIntLE(); // event id + } + if (BitUtil.check(recordFlags, 2)) { + buf.readUnsignedIntLE(); // time + } - 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 serviceType = buf.readUnsignedByte(); + buf.readUnsignedByte(); // recipient service type - int flags = buf.readUnsignedByte(); - position.setValid(BitUtil.check(flags, 0)); - if (BitUtil.check(flags, 5)) { - position.setLatitude(-position.getLatitude()); - } - if (BitUtil.check(flags, 6)) { - position.setLongitude(-position.getLongitude()); - } + int recordEnd = buf.readerIndex() + length; - 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 position = new Position(getProtocolName()); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + } - position.set(Position.KEY_ODOMETER, buf.readUnsignedMediumLE() * 100); - position.set(Position.KEY_INPUT, buf.readUnsignedByte()); - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + 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.readUnsignedShortLE() + buf.readerIndex(); +// LOGGER.trace("{} {} {}", buf.readerIndex(), end, type); + + if (type == MSG_TERM_IDENTITY) { + useOidAsDeviceId = false; + + buf.readUnsignedIntLE(); // object id + int flags = buf.readUnsignedByte(); + + if (BitUtil.check(flags, 0)) { + buf.readUnsignedShortLE(); // home dispatcher identifier + } + if (BitUtil.check(flags, 1)) { + String imei = buf.readSlice(15).toString(StandardCharsets.US_ASCII).trim(); + LOGGER.trace("[{}] Using IMEI1 as deviceId: {}", channel == null ? "" : channel.id(), imei); + getDeviceSession(channel, remoteAddress, imei); + } + if (BitUtil.check(flags, 2)) { + String imei = buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim(); + LOGGER.trace("[{}] Using IMEI2 as deviceId: {}", channel == null ? "" : channel.id(), imei); + getDeviceSession(channel, remoteAddress, imei); + } + 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)) { + String imei = buf.readSlice(15).toString(StandardCharsets.US_ASCII).trim(); + LOGGER.trace("[{}] Using IMEI7 as deviceId: {}", channel == null ? "" : channel.id(), imei); + getDeviceSession(channel, remoteAddress, imei); + } + + response = Unpooled.buffer(); + response.writeByte(0); // success + sendResponse(channel, PT_APPDATA, 0, serviceType, MSG_RESULT_CODE, response); + + } 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)); + if (BitUtil.check(flags, 5)) { + position.setLatitude(-position.getLatitude()); + } + if (BitUtil.check(flags, 6)) { + position.setLongitude(-position.getLongitude()); + } + + 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.readUnsignedMediumLE() * 100); + position.set(Position.KEY_INPUT, buf.readUnsignedByte()); + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + + if (BitUtil.check(flags, 7)) { + position.setAltitude(buf.readMediumLE()); + } + + } else if (type == MSG_EXT_POS_DATA) { + + int flags = buf.readUnsignedByte(); + + if (BitUtil.check(flags, 0)) { + position.set(Position.KEY_VDOP, buf.readUnsignedShortLE()); + } + if (BitUtil.check(flags, 1)) { + position.set(Position.KEY_HDOP, buf.readUnsignedShortLE()); + } + if (BitUtil.check(flags, 2)) { + position.set(Position.KEY_PDOP, buf.readUnsignedShortLE()); + } + if (BitUtil.check(flags, 3)) { + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + } + + } else if (type == MSG_AD_SENSORS_DATA) { + + buf.readUnsignedByte(); // inputs flags + + position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); + + buf.readUnsignedByte(); // adc flags - if (BitUtil.check(flags, 7)) { - position.setAltitude(buf.readMediumLE()); } - } else if (type == MSG_EXT_POS_DATA) { - - int flags = buf.readUnsignedByte(); + buf.readerIndex(end); + } - if (BitUtil.check(flags, 0)) { - position.set(Position.KEY_VDOP, buf.readUnsignedShortLE()); - } - if (BitUtil.check(flags, 1)) { - position.set(Position.KEY_HDOP, buf.readUnsignedShortLE()); - } - if (BitUtil.check(flags, 2)) { - position.set(Position.KEY_PDOP, buf.readUnsignedShortLE()); + if (serviceType == SERVICE_TELEDATA && position.getFixTime() != null) { + if (useOidAsDeviceId && oid != 0L) { + LOGGER.debug("[{}] Using OID as deviceId: {}", channel == null ? "" : channel.id(), oid); + deviceSession = getDeviceSession(channel, remoteAddress, true, String.valueOf(oid)); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + } } - if (BitUtil.check(flags, 3)) { - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + if (position.getDeviceId() != 0L) { + positions.add(position); +// } else { +// LOGGER.debug("[{}] EGTS not authorized, OID: {}", channel.id(), oid); } - - } else if (type == MSG_AD_SENSORS_DATA) { - - buf.readUnsignedByte(); // inputs flags - - position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); - - buf.readUnsignedByte(); // adc flags - } - - buf.readerIndex(end); } - if (serviceType == SERVICE_TELEDATA && deviceSession != null) { - positions.add(position); + if (frameDataLength > 0) { + buf.readerIndex(frameDataEnd + 2); } } -- cgit v1.2.3