aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol/AplicomProtocolDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/protocol/AplicomProtocolDecoder.java')
-rw-r--r--src/org/traccar/protocol/AplicomProtocolDecoder.java298
1 files changed, 259 insertions, 39 deletions
diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java
index 23397b51c..d1f92ea0a 100644
--- a/src/org/traccar/protocol/AplicomProtocolDecoder.java
+++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2015 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2013 - 2016 Anton Tananaev (anton.tananaev@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
@@ -75,11 +76,12 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
return unitId;
}
- private static final int DEFAULT_SELECTOR = 0x0002FC;
+ private static final int DEFAULT_SELECTOR_D = 0x0002fC;
+ private static final int DEFAULT_SELECTOR_E = 0x007ffc;
private static final int EVENT_DATA = 119;
- private void decodeEventData(int event, ChannelBuffer buf) {
+ private void decodeEventData(Position position, ChannelBuffer buf, int event) {
switch (event) {
case 2:
case 40:
@@ -106,6 +108,9 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
case 130:
buf.readUnsignedInt(); // incorrect
break;
+ case 188:
+ decodeEB(position, buf);
+ break;
default:
break;
}
@@ -191,44 +196,12 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
}
}
- @Override
- protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
-
- ChannelBuffer buf = (ChannelBuffer) msg;
-
- buf.readUnsignedByte(); // marker
- int version = buf.readUnsignedByte();
-
- String imei;
- if ((version & 0x80) != 0) {
- imei = String.valueOf((buf.readUnsignedInt() << (3 * 8)) | buf.readUnsignedMedium());
- } else {
- imei = String.valueOf(imeiFromUnitId(buf.readUnsignedMedium()));
- }
-
- buf.readUnsignedShort(); // length
-
- int selector = DEFAULT_SELECTOR;
- if ((version & 0x40) != 0) {
- selector = buf.readUnsignedMedium();
- }
-
- Position position = new Position();
- position.setProtocol(getProtocolName());
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
- if (deviceSession == null) {
- return null;
- }
- position.setDeviceId(deviceSession.getDeviceId());
-
- int event = buf.readUnsignedByte();
- position.set(Position.KEY_EVENT, event);
- position.set("eventInfo", buf.readUnsignedByte());
+ private void decodeD(Position position, ChannelBuffer buf, int selector, int event) {
if ((selector & 0x0008) != 0) {
position.setValid((buf.readUnsignedByte() & 0x40) != 0);
} else {
- return null; // no location data
+ getLastLocation(position, null);
}
if ((selector & 0x0004) != 0) {
@@ -313,14 +286,261 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
}
if ((selector & 0x1000) != 0) {
- decodeEventData(event, buf);
+ decodeEventData(position, buf, event);
}
if (Context.getConfig().getBoolean(getProtocolName() + ".can")
&& buf.readable() && (selector & 0x1000) != 0 && event == EVENT_DATA) {
-
decodeCanData(buf, position);
}
+ }
+
+ private void decodeE(Position position, ChannelBuffer buf, int selector) {
+
+ if ((selector & 0x0008) != 0) {
+ position.set("tachographEvent", buf.readUnsignedShort());
+ }
+
+ if ((selector & 0x0004) != 0) {
+ getLastLocation(position, new Date(buf.readUnsignedInt() * 1000));
+ } else {
+ getLastLocation(position, null);
+ }
+
+ if ((selector & 0x0010) != 0) {
+ String time = buf.readUnsignedByte() + "s " + buf.readUnsignedByte() + "m " + buf.readUnsignedByte() + "h "
+ + buf.readUnsignedByte() + "M " + buf.readUnsignedByte() + "D " + buf.readUnsignedByte() + "Y "
+ + buf.readByte() + "m " + buf.readByte() + "h";
+ position.set("tachographTime", time);
+ }
+
+ position.set("workState", buf.readUnsignedByte());
+ position.set("driver1State", buf.readUnsignedByte());
+ position.set("driver2State", buf.readUnsignedByte());
+
+ if ((selector & 0x0020) != 0) {
+ position.set("tachographStatus", buf.readUnsignedByte());
+ }
+
+ if ((selector & 0x0040) != 0) {
+ position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() / 256.0);
+ }
+
+ if ((selector & 0x0080) != 0) {
+ position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 5);
+ }
+
+ if ((selector & 0x0100) != 0) {
+ position.set(Position.KEY_TRIP_ODOMETER, buf.readUnsignedInt() * 5);
+ }
+
+ if ((selector & 0x8000) != 0) {
+ position.set("kFactor", buf.readUnsignedShort() * 0.001 + " pulses/m");
+ }
+
+ if ((selector & 0x0200) != 0) {
+ position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.125);
+ }
+
+ if ((selector & 0x0400) != 0) {
+ position.set("extraInfo", buf.readUnsignedShort());
+ }
+
+ if ((selector & 0x0800) != 0) {
+ position.set(Position.KEY_VIN, buf.readBytes(18).toString(StandardCharsets.US_ASCII).trim());
+ }
+ }
+
+ private void decodeH(Position position, ChannelBuffer buf, int selector) {
+
+ if ((selector & 0x0004) != 0) {
+ getLastLocation(position, new Date(buf.readUnsignedInt() * 1000));
+ } else {
+ getLastLocation(position, null);
+ }
+
+ if ((selector & 0x0040) != 0) {
+ buf.readUnsignedInt(); // reset time
+ }
+
+ if ((selector & 0x2000) != 0) {
+ buf.readUnsignedShort(); // snapshot counter
+ }
+
+ int index = 1;
+ while (buf.readableBytes() > 0) {
+
+ position.set("h" + index + "Index", buf.readUnsignedByte());
+
+ buf.readUnsignedShort(); // length
+
+ int n = buf.readUnsignedByte();
+ int m = buf.readUnsignedByte();
+
+ position.set("h" + index + "XLength", n);
+ position.set("h" + index + "YLength", m);
+
+ if ((selector & 0x0008) != 0) {
+ position.set("h" + index + "XType", buf.readUnsignedByte());
+ position.set("h" + index + "YType", buf.readUnsignedByte());
+ position.set("h" + index + "Parameters", buf.readUnsignedByte());
+ }
+
+ boolean percentageFormat = (selector & 0x0020) != 0;
+
+ StringBuilder data = new StringBuilder();
+ for (int i = 0; i < n * m; i++) {
+ if (percentageFormat) {
+ data.append(buf.readUnsignedByte() * 0.5).append("%").append(" ");
+ } else {
+ data.append(buf.readUnsignedShort()).append(" ");
+ }
+ }
+
+ position.set("h" + index + "Data", data.toString().trim());
+
+ position.set("h" + index + "Total", buf.readUnsignedInt());
+
+ if ((selector & 0x0010) != 0) {
+ int k = buf.readUnsignedByte();
+
+ data = new StringBuilder();
+ for (int i = 1; i < n; i++) {
+ if (k == 1) {
+ data.append(buf.readByte()).append(" ");
+ } else if (k == 2) {
+ data.append(buf.readShort()).append(" ");
+ }
+ }
+ position.set("h" + index + "XLimits", data.toString().trim());
+
+ data = new StringBuilder();
+ for (int i = 1; i < m; i++) {
+ if (k == 1) {
+ data.append(buf.readByte()).append(" ");
+ } else if (k == 2) {
+ data.append(buf.readShort()).append(" ");
+ }
+ }
+ position.set("h" + index + "YLimits", data.toString().trim());
+ }
+
+ index += 1;
+ }
+ }
+
+ private void decodeEB(Position position, ChannelBuffer buf) {
+
+ if (buf.readByte() != (byte) 'E' || buf.readByte() != (byte) 'B') {
+ return;
+ }
+
+ buf.readUnsignedByte(); // version
+ buf.readUnsignedShort(); // event
+ buf.readUnsignedByte(); // data validity
+ buf.readUnsignedByte(); // towed
+ buf.readUnsignedShort(); // length
+
+ while (buf.readableBytes() > 0) {
+ buf.readUnsignedByte(); // towed position
+ int type = buf.readUnsignedByte();
+ int length = buf.readUnsignedByte();
+
+ if (type == 0x01) {
+ position.set("brakeFlags", ChannelBuffers.hexDump(buf.readBytes(length)));
+ } else if (type == 0x02) {
+ position.set("wheelSpeed", buf.readUnsignedShort() / 256.0);
+ position.set("wheelSpeedDifference", buf.readUnsignedShort() / 256.0 - 125.0);
+ position.set("lateralAcceleration", buf.readUnsignedByte() / 10.0 - 12.5);
+ position.set("vehicleSpeed", buf.readUnsignedShort() / 256.0);
+ } else if (type == 0x03) {
+ position.set("axleLoadSum", buf.readUnsignedShort() * 2);
+ } else if (type == 0x04) {
+ position.set("tyrePressure", buf.readUnsignedByte() * 10);
+ position.set("pneumaticPressure", buf.readUnsignedByte() * 5);
+ } else if (type == 0x05) {
+ position.set("brakeLining", buf.readUnsignedByte() * 0.4);
+ position.set("brakeTemperature", buf.readUnsignedByte() * 10);
+ } else if (type == 0x06) {
+ position.set("totalDistance", buf.readUnsignedInt() * 5);
+ position.set("tripDistance", buf.readUnsignedInt() * 5);
+ position.set("serviceDistance", (buf.readUnsignedInt() - 2105540607) * 5);
+ } else if (type == 0x0A) {
+ position.set("brakeData", ChannelBuffers.hexDump(buf.readBytes(length)));
+ } else if (type == 0x0B) {
+ position.set("brakeMinMaxData", ChannelBuffers.hexDump(buf.readBytes(length)));
+ } else if (type == 0x0C) {
+ position.set("missingPgn", ChannelBuffers.hexDump(buf.readBytes(length)));
+ } else if (type == 0x0D) {
+ switch (buf.readUnsignedByte()) {
+ case 1:
+ position.set("brakeManufacturer", "Wabco");
+ break;
+ case 2:
+ position.set("brakeManufacturer", "Knorr");
+ break;
+ case 3:
+ position.set("brakeManufacturer", "Haldex");
+ break;
+ default:
+ position.set("brakeManufacturer", "Unknown");
+ break;
+ }
+ buf.readUnsignedByte();
+ buf.readBytes(17); // vin
+ position.set("towedDetectionStatus", buf.readUnsignedByte());
+ } else if (type == 0x0E) {
+ buf.skipBytes(length);
+ }
+ }
+ }
+
+ @Override
+ protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ char protocol = (char) buf.readByte();
+ int version = buf.readUnsignedByte();
+
+ String imei;
+ if ((version & 0x80) != 0) {
+ imei = String.valueOf((buf.readUnsignedInt() << (3 * 8)) | buf.readUnsignedMedium());
+ } else {
+ imei = String.valueOf(imeiFromUnitId(buf.readUnsignedMedium()));
+ }
+
+ buf.readUnsignedShort(); // length
+
+ int selector = DEFAULT_SELECTOR_D;
+ if (protocol == 'E') {
+ selector = DEFAULT_SELECTOR_E;
+ }
+ if ((version & 0x40) != 0) {
+ selector = buf.readUnsignedMedium();
+ }
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
+ if (deviceSession == null) {
+ return null;
+ }
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ int event = buf.readUnsignedByte();
+ position.set(Position.KEY_EVENT, event);
+ position.set("eventInfo", buf.readUnsignedByte());
+
+ if (protocol == 'D') {
+ decodeD(position, buf, selector, event);
+ } else if (protocol == 'E') {
+ decodeE(position, buf, selector);
+ } else if (protocol == 'H') {
+ decodeH(position, buf, selector);
+ } else {
+ return null;
+ }
return position;
}