From 79147b8a6fc8a3bfe863c2e8d3c47db06af90bc8 Mon Sep 17 00:00:00 2001 From: Ivan Muratov Date: Mon, 17 Jul 2017 10:58:49 +0300 Subject: Rewrite the code of frame decoder. Added tests with invalid packets. --- src/org/traccar/protocol/Arnavi4FrameDecoder.java | 39 +++++++++++++---------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'src/org') diff --git a/src/org/traccar/protocol/Arnavi4FrameDecoder.java b/src/org/traccar/protocol/Arnavi4FrameDecoder.java index bb130e6bb..ee4aee32a 100644 --- a/src/org/traccar/protocol/Arnavi4FrameDecoder.java +++ b/src/org/traccar/protocol/Arnavi4FrameDecoder.java @@ -22,17 +22,18 @@ import org.jboss.netty.handler.codec.frame.FrameDecoder; public class Arnavi4FrameDecoder extends FrameDecoder { - static final int PACKET_MIN_LENGTH = 4; + private static final int PACKET_MINIMUM_LENGTH = 4; + private static final int RECORD_MINIMUM_LENGTH = 8; - static final byte HEADER_START_SIGN = (byte) 0xFF; + static final byte HEADER_START_SIGN = (byte) 0xff; static final byte HEADER_VERSION_1 = 0x22; static final byte HEADER_VERSION_2 = 0x23; - static final int HEADER_LENGTH = 10; + private static final int HEADER_LENGTH = 10; - static final byte PACKAGE_START_SIGN = 0x5B; - static final byte PACKAGE_END_SIGN = 0x5D; - static final int PACKAGE_MIN_PARCEL_NUMBER = 0x01; - static final int PACKAGE_MAX_PARCEL_NUMBER = 0xFB; + private static final byte PACKAGE_START_SIGN = 0x5b; + private static final byte PACKAGE_END_SIGN = 0x5d; + private static final int PACKAGE_MIN_PARCEL_NUMBER = 0x01; + private static final int PACKAGE_MAX_PARCEL_NUMBER = 0xfb; @Override protected Object decode( @@ -40,31 +41,37 @@ public class Arnavi4FrameDecoder extends FrameDecoder { Channel channel, ChannelBuffer buf) throws Exception { - if (buf.readableBytes() < PACKET_MIN_LENGTH) { + if (buf.readableBytes() < PACKET_MINIMUM_LENGTH) { return null; } if (buf.getByte(0) == HEADER_START_SIGN && buf.readableBytes() == HEADER_LENGTH && (buf.getByte(1) == HEADER_VERSION_1 || buf.getByte(1) == HEADER_VERSION_2)) { + return buf.readBytes(HEADER_LENGTH); } - int index = buf.getByte(1) & 0xFF; // parcel number + int index = buf.getUnsignedByte(1); // 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; + int bufferPosition = 2; // start sign + parcel number + while (bufferPosition + RECORD_MINIMUM_LENGTH < buf.readableBytes() + && buf.getByte(bufferPosition) != PACKAGE_END_SIGN) { + + int dataLength = buf.getUnsignedShort(bufferPosition + 1); + bufferPosition += RECORD_MINIMUM_LENGTH + dataLength; // type + data length + unixtime + data + crc } - return buf.readBytes(packetStartIndex + 1); + if (bufferPosition < buf.readableBytes() + && buf.getByte(bufferPosition) == PACKAGE_END_SIGN) { + + return buf.readBytes(bufferPosition + 1); // end sign + } } return null; } -} +} \ No newline at end of file -- cgit v1.2.3 From 31e972e169acf4a517ff10f8a64f0e0cf0b8df0e Mon Sep 17 00:00:00 2001 From: Ivan Muratov Date: Mon, 17 Jul 2017 14:00:46 +0300 Subject: Refactoring of the ARNAVI4 protocol decoder. --- .../traccar/protocol/Arnavi4ProtocolDecoder.java | 35 ++++++++++------------ 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'src/org') diff --git a/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java b/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java index a1a9d2ea1..4ab929cf7 100644 --- a/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java +++ b/src/org/traccar/protocol/Arnavi4ProtocolDecoder.java @@ -50,34 +50,31 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private void sendHeaderResponse(Channel channel, byte version) { + private void sendResponse(Channel channel, byte version, int index) { 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}); + response.writeByte(0x7b); + response.writeByte(0x00); + response.writeByte((byte) index); + response.writeByte(0x7d); } else if (version == HEADER_VERSION_2) { response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 9); - response.writeBytes(new byte[]{0x7B, 0x04, 0x00}); + response.writeByte(0x7b); + response.writeByte(0x04); + response.writeByte(0x00); byte[] timeBytes = ByteBuffer.allocate(4).putInt((int) (System.currentTimeMillis() / 1000)).array(); response.writeByte(Checksum.modulo256(timeBytes)); response.writeBytes(timeBytes); - response.writeByte(0x7D); + response.writeByte(0x7d); } else { - return; // Ignore unsupported versions of header + return; // Ignore unsupported header's versions } 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(); @@ -135,7 +132,7 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession != null) { - sendHeaderResponse(channel, version); + sendResponse(channel, version, 0); } return null; @@ -164,20 +161,20 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder { if (recordType == RECORD_DATA) { positions.add(decodePosition(deviceSession, buf, length, time)); } else { - buf.readBytes(length); // Skip other records + buf.readBytes(length); // Skip other types of record } buf.readUnsignedByte(); // crc break; default: - return null; // Ignore unsupported types of package + return null; // Ignore unsupported types of record } - recordType = buf.readByte(); // The last byte in package is end sign + recordType = buf.readByte(); } - sendPackageResponse(channel, index); + sendResponse(channel, HEADER_VERSION_1, index); return positions; } -- cgit v1.2.3