From 36eeb5c4fa86f6516585819bb76ca7b73fa4d28a Mon Sep 17 00:00:00 2001 From: Ivan Muratov Date: Fri, 14 Jul 2017 12:28:41 +0300 Subject: Split responses to separate methods. Optimize math operations with course and altitude. Remove unnecessary check for package first byte. Remove exception throwing. Store speed in knots, but not in km/h. --- .../traccar/protocol/Arnavi4ProtocolDecoder.java | 118 ++++++++++----------- 1 file changed, 59 insertions(+), 59 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java b/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java index 682fc1577..07e4d855c 100644 --- a/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java +++ b/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java @@ -52,6 +52,34 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private void sendHeaderResponse(Channel channel, byte version) { + if (channel != null) { + final ChannelBuffer response; + if (version == HEADER_VERSION_1) { + response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 4); + response.writeBytes(new byte[]{0x7B, 0x00, 0x00, 0x7D}); + } else if (version == HEADER_VERSION_2) { + response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 9); + response.writeBytes(new byte[]{0x7B, 0x04, 0x00}); + byte[] timeBytes = ByteBuffer.allocate(4).putInt((int) (System.currentTimeMillis() / 1000)).array(); + response.writeByte(Checksum.modulo256(timeBytes)); + response.writeBytes(timeBytes); + response.writeByte(0x7D); + } else { + return; // Ignore unsupported versions of header + } + channel.write(response); + } + } + + private void sendPackageResponse(Channel channel, int index) { + if (channel != null) { + final ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 4); + response.writeBytes(new byte[]{0x7B, 0x00, (byte) index, 0x7D}); + channel.write(response); + } + } + private Position decodePosition(DeviceSession deviceSession, ChannelBuffer buf, int length, Date time) { final Position position = new Position(); @@ -75,15 +103,15 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder { break; case TAG_COORD_PARAMS: - position.setCourse(buf.readUnsignedByte() * 2.0); - position.setAltitude(buf.readUnsignedByte() * 10.0); + position.setCourse(buf.readUnsignedByte() * 2); + position.setAltitude(buf.readUnsignedByte() * 10); byte satellites = buf.readByte(); position.set(Position.KEY_SATELLITES, satellites & 0x0F + (satellites >> 4) & 0x0F); // gps+glonass - position.setSpeed(buf.readUnsignedByte() * 1.852); + position.setSpeed(buf.readUnsignedByte()); break; default: - buf.readBytes(4); // Skip other tags + buf.readBytes(4); // Skip unsupported tags break; } @@ -108,27 +136,8 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder { String imei = String.valueOf(buf.readLong()); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - if (deviceSession != null && channel != null) { - - final ChannelBuffer response; - - if (version == HEADER_VERSION_1) { - response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 4); - response.writeBytes(new byte[]{0x7B, 0x00, 0x00, 0x7D}); - - } else if (version == HEADER_VERSION_2) { - response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 9); - response.writeBytes(new byte[]{0x7B, 0x04, 0x00}); - byte[] timeBytes = ByteBuffer.allocate(4).putInt((int) (System.currentTimeMillis() / 1000)).array(); - response.writeByte(Checksum.modulo256(timeBytes)); - response.writeBytes(timeBytes); - response.writeByte(0x7D); - - } else { - throw new IllegalArgumentException("unsupported header version"); - } - - channel.write(response); + if (deviceSession != null) { + sendHeaderResponse(channel, version); } return null; @@ -139,49 +148,40 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder { return null; } - if (startSign == PACKAGE_START_SIGN) { - - List positions = new LinkedList<>(); - - int index = buf.readUnsignedByte(); - - byte recordType = buf.readByte(); - while (recordType != PACKAGE_END_SIGN) { - switch (recordType) { - case RECORD_PING: - case RECORD_DATA: - case RECORD_TEXT: - case RECORD_FILE: - case RECORD_BINARY: - int length = buf.readUnsignedShort(); - Date time = new Date(buf.readUnsignedInt() * 1000); + List positions = new LinkedList<>(); - if (recordType == RECORD_DATA) { - positions.add(decodePosition(deviceSession, buf, length, time)); - } else { - buf.readBytes(length); // Skip other records - } + int index = buf.readUnsignedByte(); - buf.readUnsignedByte(); // crc - break; + byte recordType = buf.readByte(); + while (recordType != PACKAGE_END_SIGN && buf.readableBytes() != 1) { // The last end sign byte + switch (recordType) { + case RECORD_PING: + case RECORD_DATA: + case RECORD_TEXT: + case RECORD_FILE: + case RECORD_BINARY: + int length = buf.readUnsignedShort(); + Date time = new Date(buf.readUnsignedInt() * 1000); - default: - return null; // Unsupported types of package - } + if (recordType == RECORD_DATA) { + positions.add(decodePosition(deviceSession, buf, length, time)); + } else { + buf.readBytes(length); // Skip other records + } - recordType = buf.readByte(); - } + buf.readUnsignedByte(); // crc + break; - if (channel != null) { - final ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 4); - response.writeBytes(new byte[]{0x7B, 0x00, (byte) index, 0x7D}); - channel.write(response); + default: + return null; // Ignore unsupported types of package } - return positions; + recordType = buf.readByte(); } - return null; + sendPackageResponse(channel, index); + + return positions; } } -- cgit v1.2.3 From c8f648e0261ad46e9301db35f161140aabad880a Mon Sep 17 00:00:00 2001 From: Ivan Muratov Date: Fri, 14 Jul 2017 13:29:52 +0300 Subject: Upgrade the frame decoder and remove unnecessary check for the last end sign byte in protocol decoder. Protocol decoder read the buffer until its over, because frame decoder garantee the correct package length. Added additional tests for frame decoding. --- src/org/traccar/protocol/Arnavi4FrameDecoder.java | 16 ++++++++++++---- src/org/traccar/protocol/Arnavi4ProtocolDecoder.java | 4 ++-- test/org/traccar/protocol/Arnavi4FrameDecoderTest.java | 16 ++++++++++++++-- 3 files changed, 28 insertions(+), 8 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/protocol/Arnavi4FrameDecoder.java b/src/org/traccar/protocol/Arnavi4FrameDecoder.java index a50ece641..bb130e6bb 100644 --- a/src/org/traccar/protocol/Arnavi4FrameDecoder.java +++ b/src/org/traccar/protocol/Arnavi4FrameDecoder.java @@ -50,10 +50,18 @@ public class Arnavi4FrameDecoder extends FrameDecoder { return buf.readBytes(HEADER_LENGTH); } - int parcelNumber = buf.getByte(1) & 0xFF; - if (buf.getByte(0) == PACKAGE_START_SIGN && buf.getByte(buf.readableBytes() - 1) == PACKAGE_END_SIGN - && parcelNumber >= PACKAGE_MIN_PARCEL_NUMBER && parcelNumber <= PACKAGE_MAX_PARCEL_NUMBER) { - return buf; + int index = buf.getByte(1) & 0xFF; // parcel number + if (buf.getByte(0) == PACKAGE_START_SIGN + && index >= PACKAGE_MIN_PARCEL_NUMBER && index <= PACKAGE_MAX_PARCEL_NUMBER) { + + // package: 1 byte start sign, 1 byte parcel number, packets, 1 byte end sign + int packetStartIndex = 2; + while (packetStartIndex + 8 < buf.readableBytes() && buf.getByte(packetStartIndex) != PACKAGE_END_SIGN) { + // packet: 1 byte type, 2 bytes length, 4 bytes unixtime, length-bytes data, 1 byte crc + packetStartIndex += buf.getUnsignedShort(packetStartIndex + 1) + 8; + } + + return buf.readBytes(packetStartIndex + 1); } return null; diff --git a/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java b/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java index 07e4d855c..ed11e1559 100644 --- a/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java +++ b/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java @@ -153,7 +153,7 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder { int index = buf.readUnsignedByte(); byte recordType = buf.readByte(); - while (recordType != PACKAGE_END_SIGN && buf.readableBytes() != 1) { // The last end sign byte + while (buf.readableBytes() > 0) { switch (recordType) { case RECORD_PING: case RECORD_DATA: @@ -176,7 +176,7 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder { return null; // Ignore unsupported types of package } - recordType = buf.readByte(); + recordType = buf.readByte(); // The last byte in package is end sign } sendPackageResponse(channel, index); diff --git a/test/org/traccar/protocol/Arnavi4FrameDecoderTest.java b/test/org/traccar/protocol/Arnavi4FrameDecoderTest.java index 0b502bc36..93d818f56 100644 --- a/test/org/traccar/protocol/Arnavi4FrameDecoderTest.java +++ b/test/org/traccar/protocol/Arnavi4FrameDecoderTest.java @@ -21,14 +21,26 @@ public class Arnavi4FrameDecoderTest extends ProtocolTest { binary(ByteOrder.LITTLE_ENDIAN, "ff23f30c45f5c90f0300"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "ff23f30c45f5c90f0300"))); - Assert.assertEquals( // Valid PACKAGE packet with one DATA packet + Assert.assertEquals( // Valid PACKAGE with answer to server on file transfer. + null, + decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "5bfd005d"))); + + Assert.assertEquals( // Valid PACKAGE with one DATA packet binary(ByteOrder.LITTLE_ENDIAN, "5b01012800a3175f5903513934420447221c42055402781E0900f0c5215b4e0084005c00007c005d0000a300fa37010000295d"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "5b01012800a3175f5903513934420447221c42055402781E0900f0c5215b4e0084005c00007c005d0000a300fa37010000295d"))); - Assert.assertEquals( // Valid PACKAGE packet with two DATA packet + Assert.assertEquals( // Valid PACKAGE with two DATA packet binary(ByteOrder.LITTLE_ENDIAN, "5b01012800a3175f5903513934420447221c42055402781E0900f0c5215b4e0084005c00007c005d0000a300fa3701000029012800a3175f5903513934420447221c42055402781E0900f0c5215b4e0084005c00007c005d0000a300fa37010000295d"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "5b01012800a3175f5903513934420447221c42055402781E0900f0c5215b4e0084005c00007c005d0000a300fa3701000029012800a3175f5903513934420447221c42055402781E0900f0c5215b4e0084005c00007c005d0000a300fa37010000295d"))); + Assert.assertEquals( // Valid PACKAGE with one TEXT packet. + null, + decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "030700e3f16b50747261636361721b"))); + + Assert.assertEquals( // Valid PACKAGE with one BINARY packet. + null, + decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "062000e3f16b5003298b5e4204cbd514420500191000080400ff021b"))); + } } \ No newline at end of file -- cgit v1.2.3