aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java')
-rw-r--r--src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java231
1 files changed, 145 insertions, 86 deletions
diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
index f1d146bda..7b0eed943 100644
--- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
@@ -16,6 +16,7 @@
package org.traccar.protocol;
import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
@@ -43,6 +44,8 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_POSITION_RSP = 0xFF01;
public static final int MSG_LOGIN = 0xAA02;
public static final int MSG_LOGIN_RSP = 0xFF03;
+ public static final int MSG_UPFAULT = 0xAA12;
+ public static final int MSG_UPFAULT_RSP = 0xFF13;
public static final int MSG_HSO_REQ = 0x0002;
public static final int MSG_HSO_RSP = 0x0003;
@@ -123,111 +126,167 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
sendResponse(channel, MSG_HSO_RSP, index, null);
- } else if (type == MSG_POSITION) {
+ } else if (type == MSG_UPFAULT) {
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
- if (deviceSession == null) {
- return null;
- }
+ return decodeFaultCodes(channel, remoteAddress, buf, index);
- Position position = new Position(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
+ } else if (type == MSG_POSITION) {
- int status = buf.readUnsignedShort();
+ return decodePosition(channel, remoteAddress, buf, index);
- position.setValid(BitUtil.check(status, 15));
+ }
- position.set(Position.KEY_STATUS, status);
- position.set(Position.KEY_IGNITION, BitUtil.check(status, 14));
+ return null;
+ }
- int event = buf.readUnsignedShort();
- position.set(Position.KEY_ALARM, decodeAlarm(event));
- position.set(Position.KEY_EVENT, event);
+ private Position decodeFaultCodes(
+ Channel channel, SocketAddress remoteAddress, ByteBuf buf, int index) {
- String time = buf.readCharSequence(12, StandardCharsets.US_ASCII).toString();
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
- DateBuilder dateBuilder = new DateBuilder()
- .setYear(Integer.parseInt(time.substring(0, 2)))
- .setMonth(Integer.parseInt(time.substring(2, 4)))
- .setDay(Integer.parseInt(time.substring(4, 6)))
- .setHour(Integer.parseInt(time.substring(6, 8)))
- .setMinute(Integer.parseInt(time.substring(8, 10)))
- .setSecond(Integer.parseInt(time.substring(10, 12)));
- position.setTime(dateBuilder.getDate());
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
- position.setLongitude(buf.readInt() * 0.00001);
- position.setLatitude(buf.readInt() * 0.00001);
+ getLastLocation(position, null);
- position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort()));
- position.setCourse(buf.readUnsignedShort());
- position.setAltitude(buf.readUnsignedShort());
+ buf.readUnsignedShort(); // type
+ buf.readUnsignedShort(); // length
- position.set(Position.KEY_ODOMETER, buf.readUnsignedShort() * 1000);
+ StringBuilder codes = new StringBuilder();
+ while (buf.readableBytes() > 2) {
+ String value = ByteBufUtil.hexDump(buf.readSlice(2));
+ int digit = Integer.parseInt(value.substring(0, 1), 16);
+ char prefix;
+ switch (digit >> 2) {
+ default:
+ prefix = 'P';
+ break;
+ case 1:
+ prefix = 'C';
+ break;
+ case 2:
+ prefix = 'B';
+ break;
+ case 3:
+ prefix = 'U';
+ break;
+ }
+ codes.append(prefix).append(digit % 4).append(value.substring(1));
+ if (buf.readableBytes() > 2) {
+ codes.append(' ');
+ }
+ }
- Network network = new Network();
+ position.set(Position.KEY_DTCS, codes.toString());
- while (buf.readableBytes() > 4) {
- int subtype = buf.readUnsignedShort();
- int length = buf.readUnsignedShort() - 4;
- switch (subtype) {
- case 0x0001:
- position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40);
- position.set(Position.KEY_RPM, buf.readUnsignedShort());
- position.set("averageSpeed", buf.readUnsignedByte());
- buf.readUnsignedShort(); // interval fuel consumption
- position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01);
- position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort());
- position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01);
- position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4);
- buf.readUnsignedInt(); // trip id
- break;
- case 0x0005:
- position.set(Position.KEY_RSSI, buf.readUnsignedByte());
- position.set(Position.KEY_HDOP, buf.readUnsignedByte());
- buf.readUnsignedInt(); // run time
- break;
- case 0x0009:
- position.set(
- Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString());
- break;
- case 0x0011:
- position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 0.05);
- break;
- case 0x0020:
- String[] cells = buf.readCharSequence(
- length, StandardCharsets.US_ASCII).toString().split("\\+");
- for (String cell : cells) {
- String[] values = cell.split("@");
- network.addCellTower(CellTower.from(
- Integer.parseInt(values[0]), Integer.parseInt(values[1]),
- Integer.parseInt(values[2], 16), Integer.parseInt(values[3], 16)));
- }
- break;
- case 0x0021:
- String[] points = buf.readCharSequence(
- length, StandardCharsets.US_ASCII).toString().split("\\+");
- for (String point : points) {
- String[] values = point.split("@");
- network.addWifiAccessPoint(WifiAccessPoint.from(values[0], Integer.parseInt(values[1])));
- }
- break;
- default:
- buf.skipBytes(length);
- break;
- }
- }
+ return position;
+ }
- if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) {
- position.setNetwork(network);
- }
+ private Position decodePosition(
+ Channel channel, SocketAddress remoteAddress, ByteBuf buf, int index) {
- sendResponse(channel, MSG_POSITION_RSP, index, null);
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
- return position;
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ int status = buf.readUnsignedShort();
+
+ position.setValid(BitUtil.check(status, 15));
+
+ position.set(Position.KEY_STATUS, status);
+ position.set(Position.KEY_IGNITION, BitUtil.check(status, 14));
+
+ int event = buf.readUnsignedShort();
+ position.set(Position.KEY_ALARM, decodeAlarm(event));
+ position.set(Position.KEY_EVENT, event);
+
+ String time = buf.readCharSequence(12, StandardCharsets.US_ASCII).toString();
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setYear(Integer.parseInt(time.substring(0, 2)))
+ .setMonth(Integer.parseInt(time.substring(2, 4)))
+ .setDay(Integer.parseInt(time.substring(4, 6)))
+ .setHour(Integer.parseInt(time.substring(6, 8)))
+ .setMinute(Integer.parseInt(time.substring(8, 10)))
+ .setSecond(Integer.parseInt(time.substring(10, 12)));
+ position.setTime(dateBuilder.getDate());
+
+ position.setLongitude(buf.readInt() * 0.00001);
+ position.setLatitude(buf.readInt() * 0.00001);
+
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort()));
+ position.setCourse(buf.readUnsignedShort());
+ position.setAltitude(buf.readUnsignedShort());
+
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedShort() * 1000);
+
+ Network network = new Network();
+
+ while (buf.readableBytes() > 4) {
+ int subtype = buf.readUnsignedShort();
+ int length = buf.readUnsignedShort() - 4;
+ switch (subtype) {
+ case 0x0001:
+ position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40);
+ position.set(Position.KEY_RPM, buf.readUnsignedShort());
+ position.set("averageSpeed", buf.readUnsignedByte());
+ buf.readUnsignedShort(); // interval fuel consumption
+ position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01);
+ position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort());
+ position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01);
+ position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4);
+ buf.readUnsignedInt(); // trip id
+ break;
+ case 0x0005:
+ position.set(Position.KEY_RSSI, buf.readUnsignedByte());
+ position.set(Position.KEY_HDOP, buf.readUnsignedByte());
+ buf.readUnsignedInt(); // run time
+ break;
+ case 0x0009:
+ position.set(
+ Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString());
+ break;
+ case 0x0011:
+ position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 0.05);
+ break;
+ case 0x0020:
+ String[] cells = buf.readCharSequence(
+ length, StandardCharsets.US_ASCII).toString().split("\\+");
+ for (String cell : cells) {
+ String[] values = cell.split("@");
+ network.addCellTower(CellTower.from(
+ Integer.parseInt(values[0]), Integer.parseInt(values[1]),
+ Integer.parseInt(values[2], 16), Integer.parseInt(values[3], 16)));
+ }
+ break;
+ case 0x0021:
+ String[] points = buf.readCharSequence(
+ length, StandardCharsets.US_ASCII).toString().split("\\+");
+ for (String point : points) {
+ String[] values = point.split("@");
+ network.addWifiAccessPoint(WifiAccessPoint.from(values[0], Integer.parseInt(values[1])));
+ }
+ break;
+ default:
+ buf.skipBytes(length);
+ break;
+ }
+ }
+ if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) {
+ position.setNetwork(network);
}
- return null;
+ sendResponse(channel, MSG_POSITION_RSP, index, null);
+
+ return position;
}
}