aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java')
-rw-r--r--src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java115
1 files changed, 86 insertions, 29 deletions
diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java
index a9cc1de3a..0f0d22021 100644
--- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2023 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.
@@ -19,8 +19,8 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
-import org.traccar.Context;
-import org.traccar.DeviceSession;
+import org.traccar.model.Device;
+import org.traccar.session.DeviceSession;
import org.traccar.NetworkMessage;
import org.traccar.Protocol;
import org.traccar.helper.Checksum;
@@ -204,18 +204,18 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_ADC + i, parser.nextHexInt());
}
- String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel();
- if (deviceModel == null) {
- deviceModel = "";
+ String model = getCacheManager().getObject(Device.class, deviceSession.getDeviceId()).getModel();
+ if (model == null) {
+ model = "";
}
- switch (deviceModel.toUpperCase()) {
+ switch (model.toUpperCase()) {
case "MVT340":
case "MVT380":
- position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.0 * 2.0 / 1024.0);
+ position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.0 * 2.0 / 1024.0);
position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.0 * 16.0 / 1024.0);
break;
case "MT90":
- position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0);
+ position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0);
position.set(Position.KEY_POWER, parser.nextHexInt(0));
break;
case "T1":
@@ -225,19 +225,18 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
case "MVT800":
case "TC68":
case "TC68S":
- position.set(Position.KEY_BATTERY, parser.nextHexInt(0) * 3.3 * 2.0 / 4096.0);
+ position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0);
position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.3 * 16.0 / 4096.0);
break;
case "T311":
case "T322X":
case "T333":
case "T355":
- position.set(Position.KEY_BATTERY, parser.nextHexInt(0) / 100.0);
- position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0);
- break;
+ case "T366":
+ case "T366G":
default:
- position.set(Position.KEY_BATTERY, parser.nextHexInt(0));
- position.set(Position.KEY_POWER, parser.nextHexInt(0));
+ position.set(Position.KEY_BATTERY, parser.nextHexInt() / 100.0);
+ position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0);
break;
}
@@ -368,13 +367,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
StringBuilder command = new StringBuilder("@@");
command.append(flag).append(27 + positions.size() / 10).append(",");
command.append(imei).append(",CCC,").append(positions.size()).append("*");
- int checksum = 0;
- for (int i = 0; i < command.length(); i += 1) {
- checksum += command.charAt(i);
- }
- command.append(String.format("%02x", checksum & 0xff).toUpperCase());
+ command.append(Checksum.sum(command.toString()));
command.append("\r\n");
- channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress)); // delete processed data
+ channel.writeAndFlush(new NetworkMessage(command.toString(), remoteAddress));
}
return positions;
@@ -404,7 +399,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
int paramCount = buf.readUnsignedByte();
for (int j = 0; j < paramCount; j++) {
- int id = buf.readUnsignedByte();
+ boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE;
+ int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte();
switch (id) {
case 0x01:
position.set(Position.KEY_EVENT, buf.readUnsignedByte());
@@ -424,12 +420,21 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
case 0x15:
position.set(Position.KEY_INPUT, buf.readUnsignedByte());
break;
+ case 0x47:
+ int lockState = buf.readUnsignedByte();
+ if (lockState > 0) {
+ position.set(Position.KEY_LOCK, lockState == 2);
+ }
+ break;
case 0x97:
position.set(Position.KEY_THROTTLE, buf.readUnsignedByte());
break;
case 0x9D:
position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte());
break;
+ case 0xFE69:
+ position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte());
+ break;
default:
buf.readUnsignedByte();
break;
@@ -438,7 +443,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
paramCount = buf.readUnsignedByte();
for (int j = 0; j < paramCount; j++) {
- int id = buf.readUnsignedByte();
+ boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE;
+ int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte();
switch (id) {
case 0x08:
position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE()));
@@ -491,7 +497,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
paramCount = buf.readUnsignedByte();
for (int j = 0; j < paramCount; j++) {
- int id = buf.readUnsignedByte();
+ boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE;
+ int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte();
switch (id) {
case 0x02:
position.setLatitude(buf.readIntLE() * 0.000001);
@@ -509,6 +516,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
case 0x0D:
position.set("runtime", buf.readUnsignedIntLE());
break;
+ case 0x25:
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedIntLE()));
+ break;
case 0xA0:
position.set(Position.KEY_FUEL_USED, buf.readUnsignedIntLE() * 0.001);
break;
@@ -523,8 +533,41 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
paramCount = buf.readUnsignedByte();
for (int j = 0; j < paramCount; j++) {
- buf.readUnsignedByte(); // id
- buf.skipBytes(buf.readUnsignedByte()); // value
+ boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE;
+ int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte();
+ int length = buf.readUnsignedByte();
+ switch (id) {
+ case 0x2A:
+ case 0x2B:
+ case 0x2C:
+ case 0x2D:
+ case 0x2E:
+ case 0x2F:
+ case 0x30:
+ case 0x31:
+ buf.readUnsignedByte(); // label
+ position.set(Position.PREFIX_TEMP + (id - 0x2A), buf.readShortLE() * 0.01);
+ break;
+ case 0xFE31:
+ buf.readUnsignedByte(); // alarm protocol
+ buf.readUnsignedByte(); // alarm type
+ buf.skipBytes(length - 2);
+ break;
+ case 0xFEA8:
+ for (int k = 1; k <= 3; k++) {
+ if (buf.readUnsignedByte() > 0) {
+ String key = k == 1 ? Position.KEY_BATTERY_LEVEL : "battery" + k + "Level";
+ position.set(key, buf.readUnsignedByte());
+ } else {
+ buf.readUnsignedByte();
+ }
+ }
+ buf.readUnsignedByte(); // battery alert
+ break;
+ default:
+ buf.skipBytes(length);
+ break;
+ }
}
positions.add(position);
@@ -533,13 +576,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
return positions;
}
- private void requestPhotoPacket(Channel channel, SocketAddress socketAddress, String imei, String file, int index) {
+ private void requestPhotoPacket(Channel channel, SocketAddress remoteAddress, String imei, String file, int index) {
if (channel != null) {
String content = "D00," + file + "," + index;
int length = 1 + imei.length() + 1 + content.length() + 5;
String response = String.format("@@O%02d,%s,%s*", length, imei, content);
response += Checksum.sum(response) + "\r\n";
- channel.writeAndFlush(new NetworkMessage(response, socketAddress));
+ channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
}
}
@@ -555,6 +598,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
String type = buf.toString(index + 1, 3, StandardCharsets.US_ASCII);
switch (type) {
+ case "AAC":
+ if (channel != null) {
+ String response = String.format("@@z27,%s,AAC,1*", imei);
+ response += Checksum.sum(response) + "\r\n";
+ channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
+ }
+ return null;
case "D00":
if (photo == null) {
photo = Unpooled.buffer();
@@ -579,7 +629,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
getLastLocation(position, null);
- position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg"));
+ position.set(Position.KEY_IMAGE, writeMediaFile(imei, photo, "jpg"));
photo.release();
photo = null;
@@ -594,6 +644,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
photo = Unpooled.buffer();
requestPhotoPacket(channel, remoteAddress, imei, "camera_picture.jpg", 0);
return null;
+ case "D82":
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(getDeviceSession(channel, remoteAddress, imei).getDeviceId());
+ getLastLocation(position, null);
+ String result = buf.toString(index + 1, buf.writerIndex() - index - 4, StandardCharsets.US_ASCII);
+ position.set(Position.KEY_RESULT, result);
+ return position;
case "CCC":
return decodeBinaryC(channel, remoteAddress, buf);
case "CCE":