From 3ea901e4198c6dbbdde74c6e49805714694c8271 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Nov 2018 16:47:49 +1300 Subject: Extended codec 8 for Teltonika --- .../traccar/protocol/TeltonikaProtocolDecoder.java | 60 ++++++++++++++-------- .../protocol/TeltonikaProtocolDecoderTest.java | 3 ++ 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 5c3af026c..d7c4bca60 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -70,7 +70,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } public static final int CODEC_GH3000 = 0x07; - public static final int CODEC_FM4X00 = 0x08; + public static final int CODEC_8 = 0x08; + public static final int CODEC_8_EXT = 0x8E; public static final int CODEC_12 = 0x0C; public static final int CODEC_16 = 0x10; @@ -271,6 +272,21 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } + private int readExtByte(ByteBuf buf, int codec, int... codecs) { + boolean ext = false; + for (int c : codecs) { + if (codec == c) { + ext = true; + break; + } + } + if (ext) { + return buf.readUnsignedShort(); + } else { + return buf.readUnsignedByte(); + } + } + private void decodeLocation(Position position, ByteBuf buf, int codec) { int globalMask = 0x0f; @@ -354,62 +370,66 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); + position.set(Position.KEY_EVENT, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16)); if (codec == CODEC_16) { - position.set(Position.KEY_EVENT, buf.readUnsignedShort()); buf.readUnsignedByte(); // generation type - } else { - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); } - buf.readUnsignedByte(); // total IO data records + readExtByte(buf, codec, CODEC_8_EXT); // total IO data records } // Read 1 byte data if (BitUtil.check(globalMask, 1)) { - int cnt = buf.readUnsignedByte(); + int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte(); - decodeParameter(position, id, buf, 1, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 1, codec); } } // Read 2 byte data if (BitUtil.check(globalMask, 2)) { - int cnt = buf.readUnsignedByte(); + int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte(); - decodeParameter(position, id, buf, 2, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 2, codec); } } // Read 4 byte data if (BitUtil.check(globalMask, 3)) { - int cnt = buf.readUnsignedByte(); + int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte(); - decodeParameter(position, id, buf, 4, codec); + decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 4, codec); } } // Read 8 byte data - if (codec == CODEC_FM4X00 || codec == CODEC_16) { - int cnt = buf.readUnsignedByte(); + if (codec == CODEC_8 || codec == CODEC_8_EXT || codec == CODEC_16) { + int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte(); - decodeOtherParameter(position, id, buf, 8); + decodeOtherParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8); } } // Read 16 byte data if (extended) { - int cnt = buf.readUnsignedByte(); + int cnt = readExtByte(buf, codec, CODEC_8_EXT); for (int j = 0; j < cnt; j++) { - int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte(); + int id = readExtByte(buf, codec, CODEC_8_EXT, CODEC_16); position.set(Position.PREFIX_IO + id, ByteBufUtil.hexDump(buf.readSlice(16))); } } + // Read X byte data + if (codec == CODEC_8_EXT) { + int cnt = buf.readUnsignedShort(); + for (int j = 0; j < cnt; j++) { + int id = buf.readUnsignedShort(); + int length = buf.readUnsignedShort(); + position.set(Position.PREFIX_IO + id, ByteBufUtil.hexDump(buf.readSlice(length))); + } + } + decodeNetwork(position); } diff --git a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 802cae877..6450a8591 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, false, binary( + "00000000000000818e0100000166e368a510000f0d8b5b20961c35008d010308000000000014000900ef0000f00100500100150400c800004501001e00002500002900000a00b5000800b60007004230dc0018000000430fcb0044005f001103de001200e50013001200240000000000000001010000113141314a433534343452373235323336370100005e99")); + verifyPositions(decoder, false, binary( "000000000000009D10020000013feb55ff74000f0ea850209a690000AE00B90B00000000070A050001000002000003000004000120000200180000004601290200C700000000004C0000000001003E00000000000000000000015B198C7498000F0DBC502095872F00AE00B90B00000000070A050001000002000003000004000120000200180000004601290200C700000000004C0000000001003E000000000000000002000009A5")); -- cgit v1.2.3