aboutsummaryrefslogtreecommitdiff
path: root/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/org')
-rw-r--r--src/org/traccar/protocol/NavisFrameDecoder.java40
-rw-r--r--src/org/traccar/protocol/NavisProtocol.java2
-rw-r--r--src/org/traccar/protocol/NavisProtocolDecoder.java133
3 files changed, 66 insertions, 109 deletions
diff --git a/src/org/traccar/protocol/NavisFrameDecoder.java b/src/org/traccar/protocol/NavisFrameDecoder.java
index 0146243cd..8a0bb0b9a 100644
--- a/src/org/traccar/protocol/NavisFrameDecoder.java
+++ b/src/org/traccar/protocol/NavisFrameDecoder.java
@@ -18,39 +18,31 @@ package org.traccar.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.TooLongFrameException;
import java.nio.charset.StandardCharsets;
import org.traccar.BaseFrameDecoder;
import org.traccar.BasePipelineFactory;
public class NavisFrameDecoder extends BaseFrameDecoder {
- private int flexDataSize; // bytes
-
private static final int NTCB_HEADER_LENGTH = 16;
private static final int NTCB_LENGTH_OFFSET = 12;
private static final int FLEX_HEADER_LENGTH = 2;
- private static final int MAX_FRAME_LENGTH = 65551;
+
+ private int flexDataSize;
+
+ public void setFlexDataSize(int flexDataSize) {
+ this.flexDataSize = flexDataSize;
+ }
@Override
protected Object decode(
ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {
- // Check minimum length
- if (buf.readableBytes() < 1) {
- return null;
- }
-
- if (buf.readableBytes() > MAX_FRAME_LENGTH) {
- throw new TooLongFrameException();
- }
-
if (buf.getByte(buf.readerIndex()) == 0x7F) {
- // FLEX keep alive frame
- return buf.readRetainedSlice(1);
+ return buf.readRetainedSlice(1); // keep alive
}
- if (ctx != null) {
+ if (ctx != null && flexDataSize == 0) {
NavisProtocolDecoder protocolDecoder =
BasePipelineFactory.getHandler(ctx.pipeline(), NavisProtocolDecoder.class);
if (protocolDecoder != null) {
@@ -59,7 +51,7 @@ public class NavisFrameDecoder extends BaseFrameDecoder {
}
if (flexDataSize > 0) {
- // FLEX frame
+
if (buf.readableBytes() > FLEX_HEADER_LENGTH) {
int length = 0;
String type = buf.toString(buf.readerIndex(), 2, StandardCharsets.US_ASCII);
@@ -97,23 +89,21 @@ public class NavisFrameDecoder extends BaseFrameDecoder {
return buf.readRetainedSlice(buf.readableBytes());
}
}
+
} else {
- // NTCB frame
+
if (buf.readableBytes() < NTCB_HEADER_LENGTH) {
return null;
}
- int length = buf.getUnsignedShortLE(buf.readerIndex() + NTCB_LENGTH_OFFSET);
- if (buf.readableBytes() >= NTCB_HEADER_LENGTH + length) {
- return buf.readRetainedSlice(NTCB_HEADER_LENGTH + length);
+ int length = NTCB_HEADER_LENGTH + buf.getUnsignedShortLE(buf.readerIndex() + NTCB_LENGTH_OFFSET);
+ if (buf.readableBytes() >= length) {
+ return buf.readRetainedSlice(length);
}
+
}
return null;
}
- public void setFlexDataSize(int flexDataSize) {
- this.flexDataSize = flexDataSize;
- }
-
}
diff --git a/src/org/traccar/protocol/NavisProtocol.java b/src/org/traccar/protocol/NavisProtocol.java
index db0eba8c1..d5af6838d 100644
--- a/src/org/traccar/protocol/NavisProtocol.java
+++ b/src/org/traccar/protocol/NavisProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/org/traccar/protocol/NavisProtocolDecoder.java b/src/org/traccar/protocol/NavisProtocolDecoder.java
index ad20ea61f..7ba474ae0 100644
--- a/src/org/traccar/protocol/NavisProtocolDecoder.java
+++ b/src/org/traccar/protocol/NavisProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,20 +37,22 @@ import java.util.Date;
public class NavisProtocolDecoder extends BaseProtocolDecoder {
+ private static final int[] FLEX_FIELDS_SIZES = {
+ 4, 2, 4, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 4, 4, 2, 2,
+ 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1, 4, 2, 2, 2, 2, 2, 1, 1, 1, 2, 4, 2, 1,
+ /* FLEX 2.0 */
+ 8, 2, 1, 16, 4, 2, 4, 37, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 12, 24, 48, 1, 1, 1, 1, 4, 4,
+ 1, 4, 2, 6, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1
+ };
+
private String prefix;
private long deviceUniqueId, serverId;
- private int flexDataSize; // bytes
- private int flexBitfieldDataSize; // bits
- private final byte[] flexBitfield;
- private static final int[] FLEX_FIELDS_SIZES = {4, 2, 4, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 4, 4, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 4, 2, 1, 4, 2, 2, 2, 2, 2, 1, 1, 1, 2, 4, 2, 1, /* FLEX 2.0 */ 8, 2, 1, 16, 4, 2, 4, 37, 1,
- 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 12, 24, 48, 1, 1, 1, 1, 4, 4, 1, 4, 2, 6, 2, 6, 2,
- 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1}; // bytes
+ private int flexDataSize;
+ private int flexBitFieldSize;
+ private final byte[] flexBitField = new byte[16];
public NavisProtocolDecoder(Protocol protocol) {
super(protocol);
- this.flexBitfield = new byte[16];
}
public static final int F10 = 0x01;
@@ -62,6 +64,10 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
public static final int F52 = 0x25;
public static final int F60 = 0x06;
+ public int getFlexDataSize() {
+ return flexDataSize;
+ }
+
private static boolean isFormat(int type, int... types) {
for (int i : types) {
if (type == i) {
@@ -71,25 +77,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
return false;
}
- private static final class ParseResult {
- private final long id;
- private final Position position;
-
- private ParseResult(long id, Position position) {
- this.id = id;
- this.position = position;
- }
-
- public long getId() {
- return id;
- }
-
- public Position getPosition() {
- return position;
- }
- }
-
- private ParseResult parseNtcbPosition(DeviceSession deviceSession, ByteBuf buf) {
+ private Position parseNtcbPosition(DeviceSession deviceSession, ByteBuf buf) {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
@@ -102,9 +90,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
}
position.set("format", format);
- long index = buf.readUnsignedIntLE();
- position.set(Position.KEY_INDEX, index);
-
+ position.set(Position.KEY_INDEX, buf.readUnsignedIntLE());
position.set(Position.KEY_EVENT, buf.readUnsignedShortLE());
buf.skipBytes(6); // event time
@@ -273,22 +259,18 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_TEMP + 4, buf.readByte());
}
- return new ParseResult(index, position);
+ return position;
}
private Object processNtcbSingle(DeviceSession deviceSession, Channel channel, ByteBuf buf) {
- ParseResult result = parseNtcbPosition(deviceSession, buf);
+ Position position = parseNtcbPosition(deviceSession, buf);
ByteBuf response = Unpooled.buffer(7);
response.writeCharSequence("*<T", StandardCharsets.US_ASCII);
- response.writeIntLE((int) result.getId());
+ response.writeIntLE((int) position.getLong(Position.KEY_INDEX));
sendNtcbReply(channel, response);
- if (result.getPosition().getFixTime() == null) {
- return null;
- }
-
- return result.getPosition();
+ return position.getFixTime() != null ? position : null;
}
private Object processNtcbArray(DeviceSession deviceSession, Channel channel, ByteBuf buf) {
@@ -296,7 +278,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
int count = buf.readUnsignedByte();
for (int i = 0; i < count; i++) {
- Position position = parseNtcbPosition(deviceSession, buf).getPosition();
+ Position position = parseNtcbPosition(deviceSession, buf);
if (position.getFixTime() != null) {
positions.add(position);
}
@@ -317,29 +299,27 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
private boolean checkFlexBitfield(int index) {
int byteIndex = Math.floorDiv(index, 8);
int bitIndex = Math.floorMod(index, 8);
- return BitUtil.check(flexBitfield[byteIndex], 7 - bitIndex);
+ return BitUtil.check(flexBitField[byteIndex], 7 - bitIndex);
}
- private ParseResult parseFlexPosition(DeviceSession deviceSession, ByteBuf buf) {
+ private Position parseFlexPosition(DeviceSession deviceSession, ByteBuf buf) {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- long index = 0;
int status = 0;
short input = 0;
short output = 0;
- for (int i = 0; i < flexBitfieldDataSize; i++) {
+ for (int i = 0; i < flexBitFieldSize; i++) {
if (!checkFlexBitfield(i)) {
continue;
}
switch (i) {
case 0:
- index = buf.readUnsignedIntLE();
- position.set(Position.KEY_INDEX, index);
+ position.set(Position.KEY_INDEX, buf.readUnsignedIntLE());
break;
case 1:
position.set(Position.KEY_EVENT, buf.readUnsignedShortLE());
@@ -471,22 +451,20 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
}
}
- return new ParseResult(index, position);
+ return position;
}
- private ParseResult parseFlex20Position(DeviceSession deviceSession, ByteBuf buf) {
- Position position = new Position(getProtocolName());
+ private Position parseFlex20Position(DeviceSession deviceSession, ByteBuf buf) {
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- long index = 0;
int length = buf.readUnsignedShort();
-
if (length <= buf.readableBytes() && buf.readUnsignedByte() == 0x0A) {
+
buf.readUnsignedByte(); // length of static part
- index = buf.readUnsignedIntLE();
- position.set(Position.KEY_INDEX, index);
+ position.set(Position.KEY_INDEX, buf.readUnsignedIntLE());
position.set(Position.KEY_EVENT, buf.readUnsignedShortLE());
buf.readUnsignedInt(); // event time
@@ -506,55 +484,49 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
buf.skipBytes(length - buf.readerIndex() - 1); // skip unused part
}
- return new ParseResult(index, position);
+ return position;
}
private interface FlexPositionParser {
- ParseResult parsePosition(DeviceSession deviceSession, ByteBuf buf);
+ Position parsePosition(DeviceSession deviceSession, ByteBuf buf);
}
private Object processFlexSingle(
FlexPositionParser parser, String flexHeader, DeviceSession deviceSession, Channel channel, ByteBuf buf) {
+
if (!flexHeader.equals("~C")) {
buf.readUnsignedInt(); // event index
}
- ParseResult result = parser.parsePosition(deviceSession, buf);
+ Position position = parser.parsePosition(deviceSession, buf);
- ByteBuf response = Unpooled.buffer(6);
+ ByteBuf response = Unpooled.buffer();
response.writeCharSequence(flexHeader, StandardCharsets.US_ASCII);
- response.writeIntLE((int) result.getId());
+ response.writeIntLE((int) position.getLong(Position.KEY_INDEX));
sendFlexReply(channel, response);
- if (result.getPosition().getFixTime() == null) {
- return null;
- }
-
- return result.getPosition();
+ return position.getFixTime() != null ? position : null;
}
private Object processFlexArray(
FlexPositionParser parser, String flexHeader, DeviceSession deviceSession, Channel channel, ByteBuf buf) {
+
List<Position> positions = new LinkedList<>();
int count = buf.readUnsignedByte();
for (int i = 0; i < count; i++) {
- Position position = parser.parsePosition(deviceSession, buf).getPosition();
+ Position position = parser.parsePosition(deviceSession, buf);
if (position.getFixTime() != null) {
positions.add(position);
}
}
- ByteBuf response = Unpooled.buffer(6);
+ ByteBuf response = Unpooled.buffer();
response.writeCharSequence(flexHeader, StandardCharsets.US_ASCII);
response.writeByte(count);
sendFlexReply(channel, response);
- if (positions.isEmpty()) {
- return null;
- }
-
- return positions;
+ return !positions.isEmpty() ? positions : null;
}
private Object processFlexNegotiation(Channel channel, ByteBuf buf) {
@@ -567,21 +539,20 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
if ((flexProtocolVersion == 0x0A || flexProtocolVersion == 0x14)
&& (flexStructVersion == 0x0A || flexStructVersion == 0x14)) {
- flexBitfieldDataSize = buf.readUnsignedByte();
- if (flexBitfieldDataSize > 122) {
+ flexBitFieldSize = buf.readUnsignedByte();
+ if (flexBitFieldSize > 122) {
return null;
}
- buf.readBytes(flexBitfield, 0, (int) Math.ceil((double) flexBitfieldDataSize / 8));
+ buf.readBytes(flexBitField, 0, (int) Math.ceil((double) flexBitFieldSize / 8));
flexDataSize = 0;
- for (int i = 0; i < flexBitfieldDataSize; i++) {
+ for (int i = 0; i < flexBitFieldSize; i++) {
if (checkFlexBitfield(i)) {
flexDataSize += FLEX_FIELDS_SIZES[i];
}
}
} else {
- // Preparing request to downgrade protocol version to FLEX 2.0
flexProtocolVersion = 0x14;
flexStructVersion = 0x14;
}
@@ -597,7 +568,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
}
private Object processHandshake(Channel channel, SocketAddress remoteAddress, ByteBuf buf) {
- buf.readByte(); // colon symbol
+ buf.readByte(); // colon
if (getDeviceSession(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII)) != null) {
sendNtcbReply(channel, Unpooled.copiedBuffer("*<S", StandardCharsets.US_ASCII));
}
@@ -668,8 +639,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
private Object decodeFlex(Channel channel, SocketAddress remoteAddress, ByteBuf buf) {
if (buf.getByte(buf.readerIndex()) == 0x7F) {
- // keep alive message
- return null;
+ return null; // keep alive
}
String type = buf.toString(buf.readerIndex(), 2, StandardCharsets.US_ASCII);
@@ -684,7 +654,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
case "~T":
case "~C":
return processFlexSingle(this::parseFlexPosition, type, deviceSession, channel, buf);
- // FLEX 2.0 (Extra packages)
+ // FLEX 2.0 (extra packages)
case "~E":
return processFlexArray(this::parseFlex20Position, type, deviceSession, channel, buf);
case "~X":
@@ -710,7 +680,4 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
}
}
- public int getFlexDataSize() {
- return flexDataSize;
- }
}