From 89a5e5c75306b9676c1534b853ec9c09c49052ef Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 31 Jan 2019 23:08:47 -0800 Subject: Minor Navis cleanup --- src/org/traccar/protocol/NavisFrameDecoder.java | 40 +++---- src/org/traccar/protocol/NavisProtocol.java | 2 +- src/org/traccar/protocol/NavisProtocolDecoder.java | 133 ++++++++------------- 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("* 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("*