aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/org/traccar/protocol/Arnavi4FrameDecoder.java16
-rw-r--r--src/org/traccar/protocol/Arnavi4ProtocolDecoder.java116
-rw-r--r--test/org/traccar/protocol/Arnavi4FrameDecoderTest.java16
3 files changed, 85 insertions, 63 deletions
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 539f6d35c..ed11e1559 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.readByte() * 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,47 +148,40 @@ public class Arnavi4ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- if (startSign == PACKAGE_START_SIGN) {
-
- List<Position> 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<Position> positions = new LinkedList<>();
- if (recordType == RECORD_DATA) {
- positions.add(decodePosition(deviceSession, buf, length, time));
- }
+ int index = buf.readUnsignedByte();
- buf.readUnsignedByte(); // crc
- break;
+ byte recordType = buf.readByte();
+ while (buf.readableBytes() > 0) {
+ 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(); // The last byte in package is end sign
}
- return null;
+ sendPackageResponse(channel, index);
+
+ return positions;
}
}
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