aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol/MeitrackProtocolDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/protocol/MeitrackProtocolDecoder.java')
-rw-r--r--src/org/traccar/protocol/MeitrackProtocolDecoder.java165
1 files changed, 147 insertions, 18 deletions
diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
index efc9c24db..5b67aebe3 100644
--- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
@@ -16,6 +16,7 @@
package org.traccar.protocol;
import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.Context;
@@ -37,6 +38,8 @@ import java.util.regex.Pattern;
public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
+ private ChannelBuffer photo;
+
public MeitrackProtocolDecoder(MeitrackProtocol protocol) {
super(protocol);
}
@@ -109,7 +112,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
}
}
- private Position decodeRegularMessage(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
+ private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
Parser parser = new Parser(PATTERN, buf.toString(StandardCharsets.US_ASCII));
if (!parser.matches()) {
@@ -219,13 +222,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
if (parser.hasNext()) {
for (String temp : parser.next().split("\\|")) {
- int index = Integer.valueOf(temp.substring(0, 2), 16);
+ int index = Integer.parseInt(temp.substring(0, 2), 16);
if (protocol >= 3) {
- double value = Short.valueOf(temp.substring(2), 16);
+ double value = (short) Integer.parseInt(temp.substring(2), 16);
position.set(Position.PREFIX_TEMP + index, value * 0.01);
} else {
- double value = Byte.valueOf(temp.substring(2, 4), 16);
- value += (value < 0 ? -0.01 : 0.01) * Integer.valueOf(temp.substring(4), 16);
+ double value = Byte.parseByte(temp.substring(2, 4), 16);
+ value += (value < 0 ? -0.01 : 0.01) * Integer.parseInt(temp.substring(4), 16);
position.set(Position.PREFIX_TEMP + index, value);
}
}
@@ -234,7 +237,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
return position;
}
- private List<Position> decodeBinaryMessage(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
+ private List<Position> decodeBinaryC(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
List<Position> positions = new LinkedList<>();
String flag = buf.toString(2, 1, StandardCharsets.US_ASCII);
@@ -308,6 +311,108 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
return positions;
}
+ private List<Position> decodeBinaryE(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
+ List<Position> positions = new LinkedList<>();
+
+ buf.readerIndex(buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ',') + 1);
+ String imei = buf.readBytes(15).toString(StandardCharsets.US_ASCII);
+ buf.skipBytes(1 + 3 + 1);
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ buf.readUnsignedInt(); // remaining cache
+ int count = buf.readUnsignedShort();
+
+ for (int i = 0; i < count; i++) {
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ buf.readUnsignedShort(); // length
+ buf.readUnsignedShort(); // index
+
+ int paramCount = buf.readUnsignedByte();
+ for (int j = 0; j < paramCount; j++) {
+ int id = buf.readUnsignedByte();
+ switch (id) {
+ case 0x01:
+ position.set(Position.KEY_EVENT, buf.readUnsignedByte());
+ break;
+ case 0x05:
+ position.setValid(buf.readUnsignedByte() > 0);
+ break;
+ case 0x06:
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+ break;
+ default:
+ buf.readUnsignedByte();
+ break;
+ }
+ }
+
+ paramCount = buf.readUnsignedByte();
+ for (int j = 0; j < paramCount; j++) {
+ int id = buf.readUnsignedByte();
+ switch (id) {
+ case 0x08:
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort()));
+ break;
+ case 0x09:
+ position.setCourse(buf.readUnsignedShort() * 0.1);
+ break;
+ case 0x0B:
+ position.setAltitude(buf.readShort());
+ break;
+ default:
+ buf.readUnsignedShort();
+ break;
+ }
+ }
+
+ paramCount = buf.readUnsignedByte();
+ for (int j = 0; j < paramCount; j++) {
+ int id = buf.readUnsignedByte();
+ switch (id) {
+ case 0x02:
+ position.setLatitude(buf.readInt() * 0.000001);
+ break;
+ case 0x03:
+ position.setLongitude(buf.readInt() * 0.000001);
+ break;
+ case 0x04:
+ position.setTime(new Date((946684800 + buf.readUnsignedInt()) * 1000)); // 2000-01-01
+ break;
+ default:
+ buf.readUnsignedInt();
+ break;
+ }
+ }
+
+ paramCount = buf.readUnsignedByte();
+ for (int j = 0; j < paramCount; j++) {
+ buf.readUnsignedByte(); // id
+ buf.skipBytes(buf.readUnsignedByte()); // value
+ }
+
+ positions.add(position);
+ }
+
+ return positions;
+ }
+
+ private void requestPhotoPacket(Channel channel, String imei, int index) {
+ if (channel != null) {
+ String content = "D00,camera_picture.jpg," + 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.write(response);
+ }
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -315,25 +420,49 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
ChannelBuffer buf = (ChannelBuffer) msg;
int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ',');
+ String imei = buf.toString(index + 1, 15, StandardCharsets.US_ASCII);
index = buf.indexOf(index + 1, buf.writerIndex(), (byte) ',');
-
String type = buf.toString(index + 1, 3, StandardCharsets.US_ASCII);
+
switch (type) {
- case "D03":
- if (channel != null) {
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
- String imei = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId();
- String content = "D00,camera_picture.jpg,0";
- 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.write(response);
+ case "D00":
+ index = buf.indexOf(index + 1 + type.length() + 1, buf.writerIndex(), (byte) ',') + 1;
+ int endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ',');
+ int total = Integer.parseInt(buf.toString(index, endIndex - index, StandardCharsets.US_ASCII));
+ index = endIndex + 1;
+ endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ',');
+ int current = Integer.parseInt(buf.toString(index, endIndex - index, StandardCharsets.US_ASCII));
+
+ buf.readerIndex(endIndex + 1);
+ photo.writeBytes(buf.readBytes(buf.readableBytes() - 1 - 2 - 2));
+
+ if (current == total - 1) {
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(getDeviceSession(channel, remoteAddress, imei).getDeviceId());
+
+ getLastLocation(position, null);
+
+ position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(imei, photo, "jpg"));
+ photo = null;
+
+ return position;
+ } else {
+ if ((current + 1) % 8 == 0) {
+ requestPhotoPacket(channel, imei, current + 1);
+ }
+ return null;
}
+ case "D03":
+ photo = ChannelBuffers.dynamicBuffer();
+ requestPhotoPacket(channel, imei, 0);
return null;
case "CCC":
- return decodeBinaryMessage(channel, remoteAddress, buf);
+ return decodeBinaryC(channel, remoteAddress, buf);
+ case "CCE":
+ return decodeBinaryE(channel, remoteAddress, buf);
default:
- return decodeRegularMessage(channel, remoteAddress, buf);
+ return decodeRegular(channel, remoteAddress, buf);
}
}