From cbddcd311a777f0fbe1dcea4105b01ef0ffa4e34 Mon Sep 17 00:00:00 2001 From: Evgeny S Maksimov Date: Mon, 28 Jan 2019 23:44:12 +0300 Subject: Message type parser refactoring --- src/org/traccar/protocol/NavisProtocolDecoder.java | 137 ++++++++++++--------- 1 file changed, 76 insertions(+), 61 deletions(-) (limited to 'src/org/traccar/protocol/NavisProtocolDecoder.java') diff --git a/src/org/traccar/protocol/NavisProtocolDecoder.java b/src/org/traccar/protocol/NavisProtocolDecoder.java index 65c425053..decfae63f 100644 --- a/src/org/traccar/protocol/NavisProtocolDecoder.java +++ b/src/org/traccar/protocol/NavisProtocolDecoder.java @@ -649,82 +649,97 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { } } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private Object decodeNtcb(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { - ByteBuf buf = (ByteBuf) msg; + prefix = buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII); + buf.skipBytes(prefix.length()); // Prefix @NTC by default + serverId = buf.readUnsignedIntLE(); + deviceUniqueId = buf.readUnsignedIntLE(); + int length = buf.readUnsignedShortLE(); + buf.skipBytes(2); // Header and data XOR checksum - if (buf.getByte(buf.readerIndex()) == 0x7F) { - // FLEX keep alive message - return null; - } else if (buf.getByte(buf.readerIndex()) == 0x7E) { // "~" - // FLEX message - try { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession != null) { - switch (buf.readShortLE()) { - // FLEX 1.0 - case 0x417E: // "~A" - return processFlexArray(this::parseFlexPosition, "~A", deviceSession, channel, buf); - case 0x547E: // "~T" - return processFlexSingle(this::parseFlexPosition, "~T", deviceSession, channel, buf); - case 0x437E: // "~C" - return processFlexSingle(this::parseFlexPosition, "~C", deviceSession, channel, buf); - // FLEX 2.0 (Extra packages) - case 0x457E: // "~E" - return processFlexArray(this::parseFlex20Position, "~E", deviceSession, channel, buf); - case 0x587E: // "~X" - return processFlexSingle(this::parseFlex20Position, "~X", deviceSession, channel, buf); + if (length == 0) { + return null; // Keep alive message + } + + String type = buf.toString(buf.readerIndex(), 3, StandardCharsets.US_ASCII); + buf.skipBytes(type.length()); + + if (type.equals("*>S")) { + return processHandshake(channel, remoteAddress, buf); + } else { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession != null) { + try { + switch (type) { + case "*>A": + return processNtcbArray(deviceSession, channel, buf); + case "*>T": + return processNtcbSingle(deviceSession, channel, buf); + case "*>F": // "*>FLEX" + buf.skipBytes(3); + return processFlexNegotiation(channel, buf); default: break; } + } catch (IndexOutOfBoundsException error) { + LOGGER.warn("Navis NTCB message parsing error", error); } - } catch (IndexOutOfBoundsException error) { - LOGGER.warn("Navis FLEX message parsing error", error); - } - } else { - // NTCB message - prefix = buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII); - buf.skipBytes(prefix.length()); // Prefix @NTC by default - serverId = buf.readUnsignedIntLE(); - deviceUniqueId = buf.readUnsignedIntLE(); - int length = buf.readUnsignedShortLE(); - buf.skipBytes(2); // Header and data XOR checksum - - if (length == 0) { - return null; // Keep alive message } + } - int type = buf.getIntLE(buf.readerIndex()); - buf.skipBytes(3); - if ((type & 0xFFFFFF) == 0x533E2AL) { // "*>S" - return processHandshake(channel, remoteAddress, buf); - } else { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession != null) { - try { - switch (type & 0xFFFFFF) { - case 0x413E2A: // "*>A" - return processNtcbArray(deviceSession, channel, buf); - case 0x543E2A: // "*>T" - return processNtcbSingle(deviceSession, channel, buf); - case 0x463E2A: // "*>F" (*>FLEX) - buf.skipBytes(3); - return processFlexNegotiation(channel, buf); - default: - break; - } - } catch (IndexOutOfBoundsException error) { - LOGGER.warn("Navis NTCB message parsing error", error); - } + return null; + } + + private Object decodeFlex(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + + String type = buf.toString(buf.readerIndex(), 2, StandardCharsets.US_ASCII); + buf.skipBytes(type.length()); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession != null) { + try { + switch (type) { + // FLEX 1.0 + case "~A": + return processFlexArray(this::parseFlexPosition, type, deviceSession, channel, buf); + case "~T": + case "~C": + return processFlexSingle(this::parseFlexPosition, type, deviceSession, channel, buf); + // FLEX 2.0 (Extra packages) + case "~E": + return processFlexArray(this::parseFlex20Position, type, deviceSession, channel, buf); + case "~X": + return processFlexSingle(this::parseFlex20Position, type, deviceSession, channel, buf); + default: + break; } + } catch (IndexOutOfBoundsException error) { + LOGGER.warn("Navis FLEX message parsing error", error); } } return null; } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ByteBuf buf = (ByteBuf) msg; + + if (buf.getByte(buf.readerIndex()) == 0x7F) { + // FLEX keep alive message + return null; + } + + if (flexDataSize > 0) { + return decodeFlex(channel, remoteAddress, buf); + } else { + return decodeNtcb(channel, remoteAddress, buf); + } + } + public int getFlexDataSize() { return flexDataSize; } -- cgit v1.2.3