aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java283
-rw-r--r--src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java12
3 files changed, 145 insertions, 153 deletions
diff --git a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java
index 53f3e49f9..75f32f1bb 100644
--- a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java
@@ -129,173 +129,162 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder {
List<Position> positions = new LinkedList<>();
- // buf possibly contains multiple packets
- while (buf.readableBytes() >= 11) {
+ 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);
+
+ if (packetType == PT_RESPONSE) {
+ // some retranslator systems do send response on response packets - just skip them
+ return null;
+ }
- 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 frameDataEnd = buf.readerIndex() + frameDataLength;
+ long oid = 0L;
+ while (buf.readerIndex() < frameDataEnd) {
- 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;
+ int length = buf.readUnsignedShortLE();
+ int recordIndex = buf.readUnsignedShortLE();
+ int recordFlags = buf.readUnsignedByte();
+
+ if (BitUtil.check(recordFlags, 0)) {
+ oid = buf.readUnsignedIntLE(); // object id
}
- int frameDataEnd = buf.readerIndex() + frameDataLength;
- long oid = 0L;
- while (buf.readerIndex() < frameDataEnd) {
+ if (BitUtil.check(recordFlags, 1)) {
+ buf.readUnsignedIntLE(); // event id
+ }
+ if (BitUtil.check(recordFlags, 2)) {
+ buf.readUnsignedIntLE(); // time
+ }
- int length = buf.readUnsignedShortLE();
- int recordIndex = buf.readUnsignedShortLE();
- int recordFlags = buf.readUnsignedByte();
+ int serviceType = buf.readUnsignedByte();
+ buf.readUnsignedByte(); // recipient service type
- if (BitUtil.check(recordFlags, 0)) {
- oid = buf.readUnsignedIntLE(); // object id
- }
+ int recordEnd = buf.readerIndex() + length;
- if (BitUtil.check(recordFlags, 1)) {
- buf.readUnsignedIntLE(); // event id
- }
- if (BitUtil.check(recordFlags, 2)) {
- buf.readUnsignedIntLE(); // time
- }
+ Position position = new Position(getProtocolName());
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession != null) {
+ position.setDeviceId(deviceSession.getDeviceId());
+ }
- int serviceType = buf.readUnsignedByte();
- buf.readUnsignedByte(); // recipient service type
+ ByteBuf response = Unpooled.buffer();
+ response.writeShortLE(recordIndex);
+ response.writeByte(0); // success
+ sendResponse(channel, PT_RESPONSE, index, serviceType, MSG_RECORD_RESPONSE, response);
- int recordEnd = buf.readerIndex() + length;
+ while (buf.readerIndex() < recordEnd) {
+ int type = buf.readUnsignedByte();
+ int end = buf.readUnsignedShortLE() + buf.readerIndex();
- Position position = new Position(getProtocolName());
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
- if (deviceSession != null) {
- position.setDeviceId(deviceSession.getDeviceId());
- }
+ if (type == MSG_TERM_IDENTITY) {
+ useOidAsDeviceId = false;
- 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) {
- 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
+ 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);
}
- buf.readerIndex(end);
- }
+ 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);
- 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());
- }
+ int flags = buf.readUnsignedByte();
+ position.setValid(BitUtil.check(flags, 0));
+ if (BitUtil.check(flags, 5)) {
+ position.setLatitude(-position.getLatitude());
}
- if (position.getDeviceId() != 0L) {
- positions.add(position);
+ 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
+
}
+
+ buf.readerIndex(end);
}
- if (frameDataLength > 0) {
- buf.readerIndex(frameDataEnd + 2);
+ 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 (position.getDeviceId() != 0L) {
+ positions.add(position);
+ }
}
}
diff --git a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java
index 237c849c5..523d095f2 100644
--- a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java
@@ -14,6 +14,9 @@ public class EgtsFrameDecoderTest extends ProtocolTest {
binary("0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2"),
decoder.decode(null, null, binary("0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2")));
+ verifyFrame(
+ binary("0100000b000300704300db0500006c27"),
+ decoder.decode(null, null, binary("0100000b000300704300db0500006c270100000b0003007143009d0600003c7e")));
}
}
diff --git a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java
index b6ce0bd67..c6d0900dc 100644
--- a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java
@@ -26,15 +26,15 @@ public class EgtsProtocolDecoderTest extends ProtocolTest {
verifyNotNull(decoder, binary(
"0100000b00ba036b43019014002e0d9579b00000bc23be120202120900000003000000000000150500025a0000000a002f0d9579b00000d723be120202130700030000000000001400300d9579b00000da23be120202120900000003000000000000150500025a0000001800310d9579b000005d4a0efe02021015005d4a0efe00000000000000000a00000000000030000a00320d9579b00000f523be120202130700030000000000001400330d9579b00000f923be120202120900000003000000000000150500025a0000000a00340d9579b000001324be120202130700030000000000001400350d9579b000001724be120202120900000003000000000000150500025a0000001800360d9579b000009a4a0efe02021015009a4a0efe00000000000000000a00000000000030000a00370d9579b000003224be120202130700030000000000001400380d9579b000003524be120202120900000003000000000000150500025a0000000a00390d9579b000005024be1202021307000300000000000014003a0d9579b000005324be120202120900000003000000000000150500025a00000018003b0d9579b00000d74a0efe0202101500d74a0efe00000000000000000a00000000000030000a003c0d9579b000006e24be1202021307000300000000000014003d0d9579b000007224be120202120900000003000000000000150500025a0000000a003e0d9579b000008d24be1202021307000300000000000014003f0d9579b000009024be120202120900000003000000000000150500025a0000001800400d9579b00000144b0efe0202101500144b0efe00000000000000000a00000000000030000a00410d9579b00000ab24be120202130700030000000000001400420d9579b00000ae24be120202120900000003000000000000150500025a0000000a00430d9579b00000c924be120202130700030000000000001400440d9579b00000cc24be120202120900000003000000000000150500025a0000001800450d9579b00000514b0efe0202101500514b0efe00000000000000000a00000000000030000a00460d9579b00000e724be120202130700030000000000001400470d9579b00000eb24be120202120900000003000000000000150500025a0000000a00480d9579b000000625be120202130700030000000000001400490d9579b000000925be120202120900000003000000000000150500025a00000018004a0d9579b000008e4b0efe02021015008e4b0efe00000000000000000a00000000000030000a004b0d9579b000002425be1202021307000300000000000007a1"));
verifyNull(decoder, binary(
- "0100000b0003006c430004010000acfb0100000b0003006d430042020000fca2"));
+ "0100000b0003006c430004010000acfb"));
verifyNull(decoder, binary(
- "0100000b0003006e430088030000cc950100000b0003006f4300ce0400005c10"));
+ "0100000b0003006e430088030000cc95"));
verifyNull(decoder, binary(
- "0100000b000300704300db0500006c270100000b0003007143009d0600003c7e0100000b000300724300570700000c490100000b000300734300110800003d650100000b000300744300f20900000d520100000b000300754300b40a00005d0b0100000b0003007643007e0b00006d3c0100000b000300774300380c0000fdb9"));
+ "0100000b000300704300db0500006c27"));
verifyNull(decoder, binary(
- "0100000b000300784300890d0000cd8e0100000b000300794300cf0e00009dd70100000b0003007a4300050f0000ade0"));
+ "0100000b000300784300890d0000cd8e"));
verifyNull(decoder, binary(
- "0100000b0003007b430043100000ff8f0100000b0003007c4300a0110000cfb80100000b0003007d4300e61200009fe10100000b0003007e43002c130000afd60100000b0003007f43006a1400003f530100000b000300804300211500000f640100000b000300814300671600005f3d0100000b000300824300ad1700006f0a0100000b000300834300eb1800005e260100000b000300844300081900006e110100000b0003008543004e1a00003e480100000b000300864300841b00000e7f0100000b000300874300c21c00009efa0100000b000300884300731d0000aecd"));
+ "0100000b0003007b430043100000ff8f"));
verifyPositions(decoder, binary(
"0100000b0086035ddd016d18004f049579b000001e2fc11002021015001e2fc1107ac3919f59cc5c7a0b0000000000003000180050049579b00000242fc1100202101500242fc1100fb5919f2dbf5c7a0b0000000000003000180051049579b00000312fc1100202101500312fc110b899919f94cf5c7a0b00000000000030001e0052049579b00000ba62a2120202120900000003000000000000150500025c00000013070003000000000000180053049579b000004e2fc11002021015004e2fc11087ba919f8dd45c7a0b0000000000003000180054049579b00000552fc1100202101500552fc1106ecb919f2aec5c7a0b00000000000030001e0055049579b00000d562a2120202120900000003000000000000150500025c00000013070003000000000000180056049579b000005c2fc11002021015005c2fc11059d9919f54fa5c7a0b0000000000003000180057049579b000006e2fc11002021015006e2fc110309f919fc2db5c7a0b0000000000003000180058049579b00000762fc1100202101500762fc1104690919f94cf5c7a0b00000000000030001e0059049579b00000f662a2120202120900000003000000000000150500025c000000130700030000000000001e005a049579b000001463a2120202120900000003000000000000150500025c0000001307000300000000000018005b049579b00000b32fc1100202101500b32fc110c491919fa2c65c7a0b00000000000030001e005c049579b000003363a2120202120900000003000000000000150500025c0000001307000300000000000018005d049579b00000ca2fc1100202101500ca2fc11089b9919fd5f95c7a0b00000000000030001e005e049579b000005163a2120202120900000003000000000000150500025c000000130700030000000000001e005f049579b000006f63a2120202120900000003000000000000150500025c00000013070003000000000000180060049579b00000f42fc1100202101500f42fc11087ba919f43db5c7a0b0000000000003000180061049579b000000730c11002021015000730c110f9c3919fe1c65c7a0b0000000000003000180062049579b000000930c11002021015000930c1106ecb919f3ab65c7a0b00000000000030001e0063049579b000008d63a2120202120900000003000000000000150500025c00000013070003000000000000140064049579b00000ac63a2120202120900000003000000000000150500025c000000ce53"));
@@ -43,7 +43,7 @@ public class EgtsProtocolDecoderTest extends ProtocolTest {
"0100000b00100091030072000100060000000002020003009203000009"));
verifyNull(decoder, binary(
- "0100000b00030095030063100000ff8f0100000b000300960300a9100000ff8f0100000b000300970300ef100000ff8f0100000b0003009803005e100000ff8f0100000b00030099030018100000ff8f"));
+ "0100000b00030095030063100000ff8f"));
verifyNull(decoder, binary(
"0100000b00030060dd005f010000acfb"));