From 5ab6ae8d6217f3d7565a9d1073e50c1d479c5625 Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sat, 9 Sep 2017 22:48:02 +0300 Subject: Improve AdmProtocolDecoder --- src/org/traccar/protocol/AdmProtocolDecoder.java | 105 ++++++++++++++++------- 1 file changed, 73 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java index f4a21cad0..4b6a5d3fc 100644 --- a/src/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/org/traccar/protocol/AdmProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2017 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. @@ -33,76 +33,80 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public static final int CMD_RESPONSE_SIZE = 0x84; public static final int MSG_IMEI = 0x03; public static final int MSG_PHOTO = 0x0A; public static final int MSG_ADM5 = 0x01; - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ChannelBuffer buf = (ChannelBuffer) msg; - - buf.readUnsignedShort(); // device id - buf.readUnsignedByte(); // length - - int type = buf.readUnsignedByte(); - - DeviceSession deviceSession; - if (type == MSG_IMEI) { - deviceSession = getDeviceSession( - channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); - } else { - deviceSession = getDeviceSession(channel, remoteAddress); - } + private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + String imei = buf.readBytes(15).toString(StandardCharsets.UTF_8); + return getDeviceSession(channel, remoteAddress, imei); + } + private Position parseData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int type) { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } if (BitUtil.to(type, 2) == 0) { - Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - buf.readUnsignedShort(); // index + position.set(Position.KEY_INDEX, buf.readUnsignedShort()); + + int status = buf.readUnsignedShort(); + position.set(Position.KEY_STATUS, status); - position.set(Position.KEY_STATUS, buf.readUnsignedShort()); + boolean isValid = !BitUtil.check(status, 5); + position.setValid(isValid); - position.setValid(true); position.setLatitude(buf.readFloat()); position.setLongitude(buf.readFloat()); position.setCourse(buf.readUnsignedShort() * 0.1); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); - position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte()); - + position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte() * 0.1); position.setAltitude(buf.readUnsignedShort()); - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte() & 0x0f); position.setTime(new Date(buf.readUnsignedInt() * 1000)); - position.set(Position.KEY_POWER, buf.readUnsignedShort()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); if (BitUtil.check(type, 2)) { - buf.skipBytes(4); + buf.skipBytes(2); // vib, vib_count + + int out = buf.readUnsignedByte(); + for (int i = 0; i <= 3; ++i) { + position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(out, i) ? 1 : 0); + } + + buf.skipBytes(1); // in_alarm } if (BitUtil.check(type, 3)) { - buf.skipBytes(12); + for (int i = 1; i <= 6; ++i) { + position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort() * 0.001); + } } if (BitUtil.check(type, 4)) { - buf.skipBytes(8); + for (int i = 1; i <= 2; ++i) { + position.set(Position.PREFIX_COUNT + i, buf.readUnsignedInt()); + } } if (BitUtil.check(type, 5)) { - buf.skipBytes(9); + buf.skipBytes(6); // fuel level 0..2 + + for (int i = 1; i <= 3; ++i) { + position.set(Position.PREFIX_TEMP + i, buf.readUnsignedByte()); + } } if (BitUtil.check(type, 6)) { @@ -119,4 +123,41 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { return null; } + private Position parseCommandResponse(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + position.set(Position.KEY_RESULT, buf.readBytes(129).toString(StandardCharsets.UTF_8)); + + return position; + } + + @Override + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + ChannelBuffer buf = (ChannelBuffer) msg; + + buf.readUnsignedShort(); // device id + + int size = buf.readUnsignedByte(); + if (size != CMD_RESPONSE_SIZE) { + int type = buf.readUnsignedByte(); + if (type == MSG_IMEI) { + parseIdentification(channel, remoteAddress, buf); + } else { + return parseData(channel, remoteAddress, buf, type); + } + } else { + return parseCommandResponse(channel, remoteAddress, buf); + } + + return null; + } } -- cgit v1.2.3