From c88ee305e5f023477381e81b1729479ddb593706 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 27 Mar 2017 04:00:00 +1300 Subject: Refactor GT06 protocol decoder --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 240 ++++++++++++---------- 1 file changed, 128 insertions(+), 112 deletions(-) diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 07c95dc30..20b2c8eab 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -218,158 +218,174 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + protected Object decodeBasic(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { - ChannelBuffer buf = (ChannelBuffer) msg; + int length = buf.readUnsignedByte(); + int dataLength = length - 5; + int type = buf.readUnsignedByte(); + + if (type == MSG_LOGIN) { + + String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + buf.readUnsignedShort(); // type + + // Timezone offset + if (dataLength > 10) { + int extensionBits = buf.readUnsignedShort(); + int hours = (extensionBits >> 4) / 100; + int minutes = (extensionBits >> 4) % 100; + int offset = (hours * 60 + minutes) * 60; + if ((extensionBits & 0x8) != 0) { + offset = -offset; + } + if (!forceTimeZone) { + timeZone.setRawOffset(offset * 1000); + } + } - int header = buf.readShort(); + if (getDeviceSession(channel, remoteAddress, imei) != null) { + buf.skipBytes(buf.readableBytes() - 6); + sendResponse(channel, type, buf.readUnsignedShort()); + } - if (header == 0x7878) { + } else { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); - int length = buf.readUnsignedByte(); - int dataLength = length - 5; - int type = buf.readUnsignedByte(); - - if (type == MSG_LOGIN) { - - String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); - buf.readUnsignedShort(); // type - - // Timezone offset - if (dataLength > 10) { - int extensionBits = buf.readUnsignedShort(); - int hours = (extensionBits >> 4) / 100; - int minutes = (extensionBits >> 4) % 100; - int offset = (hours * 60 + minutes) * 60; - if ((extensionBits & 0x8) != 0) { - offset = -offset; - } - if (!forceTimeZone) { - timeZone.setRawOffset(offset * 1000); - } + if (type == MSG_LBS_EXTEND) { + + DateBuilder dateBuilder = new DateBuilder(timeZone) + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + + getLastLocation(position, dateBuilder.getDate()); + + int mcc = buf.readUnsignedShort(); + int mnc = buf.readUnsignedByte(); + + Network network = new Network(); + for (int i = 0; i < 7; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); } + position.setNetwork(network); - if (getDeviceSession(channel, remoteAddress, imei) != null) { - buf.skipBytes(buf.readableBytes() - 6); - sendResponse(channel, type, buf.readUnsignedShort()); + } else if (type == MSG_STRING) { + + getLastLocation(position, null); + + int commandLength = buf.readUnsignedByte(); + + if (commandLength > 0) { + buf.readUnsignedByte(); // server flag (reserved) + position.set(Position.KEY_COMMAND, + buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); } - } else { + } else if (isSupported(type)) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; + if (hasGps(type)) { + decodeGps(position, buf); + } else { + getLastLocation(position, null); } - Position position = new Position(); - position.setDeviceId(deviceSession.getDeviceId()); - position.setProtocol(getProtocolName()); + if (hasLbs(type)) { + decodeLbs(position, buf, hasStatus(type)); + } - if (type == MSG_LBS_EXTEND) { + if (hasStatus(type)) { + decodeStatus(position, buf); + } - DateBuilder dateBuilder = new DateBuilder(timeZone) - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } - getLastLocation(position, dateBuilder.getDate()); + } else { - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedByte(); + buf.skipBytes(dataLength); + if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { + sendResponse(channel, type, buf.readUnsignedShort()); + } + return null; - Network network = new Network(); - for (int i = 0; i < 7; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); - } - position.setNetwork(network); + } - } else if (type == MSG_STRING) { + if (buf.readableBytes() > 6) { + buf.skipBytes(buf.readableBytes() - 6); + } + sendResponse(channel, type, buf.readUnsignedShort()); - getLastLocation(position, null); + return position; - int commandLength = buf.readUnsignedByte(); + } - if (commandLength > 0) { - buf.readUnsignedByte(); // server flag (reserved) - position.set(Position.KEY_COMMAND, - buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); - } + return null; + } - } else if (isSupported(type)) { + protected Object decodeExtended(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { - if (hasGps(type)) { - decodeGps(position, buf); - } else { - getLastLocation(position, null); - } + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } - if (hasLbs(type)) { - decodeLbs(position, buf, hasStatus(type)); - } + buf.readUnsignedShort(); // length + int type = buf.readUnsignedByte(); - if (hasStatus(type)) { - decodeStatus(position, buf); - } + if (type == MSG_INFO) { + int subType = buf.readUnsignedByte(); - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); - } else { + getLastLocation(position, null); - buf.skipBytes(dataLength); - if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { - sendResponse(channel, type, buf.readUnsignedShort()); - } - return null; + if (subType == 0x00) { - } + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + return position; - if (buf.readableBytes() > 6) { - buf.skipBytes(buf.readableBytes() - 6); - } - sendResponse(channel, type, buf.readUnsignedShort()); + } else if (subType == 0x05) { + int flags = buf.readUnsignedByte(); + position.set("door", BitUtil.check(flags, 0)); + position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); return position; - } + } else if (subType == 0x0d) { - } else if (header == 0x7979) { + buf.skipBytes(6); + return decodeFuelData(position, buf.toString( + buf.readerIndex(), buf.readableBytes() - 4 - 2, StandardCharsets.US_ASCII)); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; } + } - buf.readUnsignedShort(); // length - int type = buf.readUnsignedByte(); - - if (type == MSG_INFO) { - int subType = buf.readUnsignedByte(); + return null; + } - Position position = new Position(); - position.setDeviceId(deviceSession.getDeviceId()); - position.setProtocol(getProtocolName()); + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - getLastLocation(position, null); + ChannelBuffer buf = (ChannelBuffer) msg; - if (subType == 0x00) { - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - return position; - } else if (subType == 0x05) { - int flags = buf.readUnsignedByte(); - position.set("door", BitUtil.check(flags, 0)); - position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); - return position; - } else if (subType == 0x0d) { - buf.skipBytes(6); - return decodeFuelData(position, buf.toString( - buf.readerIndex(), buf.readableBytes() - 4 - 2, StandardCharsets.US_ASCII)); - } - } + int header = buf.readShort(); + if (header == 0x7878) { + return decodeBasic(channel, remoteAddress, buf); + } else if (header == 0x7979) { + return decodeExtended(channel, remoteAddress, buf); } return null; -- cgit v1.2.3