aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java67
-rw-r--r--src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java37
-rw-r--r--src/main/java/org/traccar/protocol/T800xProtocolDecoder.java30
-rw-r--r--src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java20
-rw-r--r--src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java5
5 files changed, 119 insertions, 40 deletions
diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java
index 14d14f4b6..ea4975d3e 100644
--- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java
@@ -43,29 +43,52 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_SERVER_ACKNOWLEDGE = 4;
- private byte commandCount;
+ public static ByteBuf encodeContent(int type, int uniqueId, int packetNumber, ByteBuf content) {
+
+ ByteBuf buf = Unpooled.buffer();
+ buf.writeByte('M');
+ buf.writeByte('C');
+ buf.writeByte('G');
+ buf.writeByte('P');
+ buf.writeByte(type);
+ buf.writeIntLE(uniqueId);
+ buf.writeByte(packetNumber);
+ buf.writeIntLE(0); // authentication code
+ buf.writeBytes(content);
+
+ byte checksum = 0;
+ for (int i = 4; i < buf.writerIndex(); i++) {
+ checksum += buf.getByte(i);
+ }
+ buf.writeByte(checksum);
+
+ return buf;
+ }
private void sendResponse(Channel channel, SocketAddress remoteAddress, long deviceId, byte packetNumber) {
if (channel != null) {
- ByteBuf reply = Unpooled.buffer(28);
- reply.writeByte('M');
- reply.writeByte('C');
- reply.writeByte('G');
- reply.writeByte('P');
- reply.writeByte(MSG_SERVER_ACKNOWLEDGE);
- reply.writeIntLE((int) deviceId);
- reply.writeByte(commandCount++);
- reply.writeIntLE(0); // authentication code
- reply.writeByte(0);
- reply.writeByte(packetNumber);
- reply.writeZero(11);
-
- byte checksum = 0;
- for (int i = 4; i < 27; i++) {
- checksum += reply.getByte(i);
- }
- reply.writeByte(checksum);
+ ByteBuf content = Unpooled.buffer();
+ content.writeByte(0);
+ content.writeByte(packetNumber);
+ content.writeZero(11);
+ ByteBuf reply = encodeContent(MSG_SERVER_ACKNOWLEDGE, (int) deviceId, packetNumber, content);
+ channel.writeAndFlush(new NetworkMessage(reply, remoteAddress));
+ }
+ }
+
+ private void sendModuleResponse(Channel channel, SocketAddress remoteAddress, long deviceId, byte packetNumber) {
+ if (channel != null) {
+ ByteBuf content = Unpooled.buffer();
+ content.writeByte(0x80);
+ content.writeShortLE(10); // modules length
+ content.writeIntLE(0); // reserved
+ content.writeByte(9); // ack module type
+ content.writeShortLE(3); // module length
+ content.writeByte(0); // ack
+ content.writeShortLE(0); // reserved
+
+ ByteBuf reply = encodeContent(MSG_SERVER_ACKNOWLEDGE, (int) deviceId, packetNumber, content);
channel.writeAndFlush(new NetworkMessage(reply, remoteAddress));
}
}
@@ -225,7 +248,11 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder {
}
byte packetNumber = buf.readByte();
- sendResponse(channel, remoteAddress, deviceUniqueId, packetNumber);
+ if (type == MSG_CLIENT_MODULAR_EXT) {
+ sendModuleResponse(channel, remoteAddress, deviceUniqueId, packetNumber);
+ } else {
+ sendResponse(channel, remoteAddress, deviceUniqueId, packetNumber);
+ }
if (type == MSG_CLIENT_STATUS) {
return decodeStatus(buf, deviceSession, alternative);
diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java
index 52de4593c..76fa67686 100644
--- a/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java
@@ -27,24 +27,18 @@ public class CellocatorProtocolEncoder extends BaseProtocolEncoder {
super(protocol);
}
- private ByteBuf encodeContent(long deviceId, int command, int data1, int data2) {
+ public static ByteBuf encodeContent(int type, int uniqueId, int packetNumber, ByteBuf content) {
- ByteBuf buf = Unpooled.buffer(0);
+ ByteBuf buf = Unpooled.buffer();
buf.writeByte('M');
buf.writeByte('C');
buf.writeByte('G');
buf.writeByte('P');
- buf.writeByte(0);
- buf.writeIntLE(Integer.parseInt(getUniqueId(deviceId)));
- buf.writeByte(0); // command numerator
+ buf.writeByte(type);
+ buf.writeIntLE(uniqueId);
+ buf.writeByte(packetNumber);
buf.writeIntLE(0); // authentication code
- buf.writeByte(command);
- buf.writeByte(command);
- buf.writeByte(data1);
- buf.writeByte(data1);
- buf.writeByte(data2);
- buf.writeByte(data2);
- buf.writeIntLE(0); // command specific data
+ buf.writeBytes(content);
byte checksum = 0;
for (int i = 4; i < buf.writerIndex(); i++) {
@@ -55,6 +49,23 @@ public class CellocatorProtocolEncoder extends BaseProtocolEncoder {
return buf;
}
+ private ByteBuf encodeCommand(long deviceId, int command, int data1, int data2) {
+
+ ByteBuf content = Unpooled.buffer();
+ content.writeByte(command);
+ content.writeByte(command);
+ content.writeByte(data1);
+ content.writeByte(data1);
+ content.writeByte(data2);
+ content.writeByte(data2);
+ content.writeIntLE(0); // command specific data
+
+ ByteBuf buf = encodeContent(0, Integer.parseInt(getUniqueId(deviceId)), 0, content);
+ content.release();
+
+ return buf;
+ }
+
@Override
protected Object encodeCommand(Command command) {
@@ -62,7 +73,7 @@ public class CellocatorProtocolEncoder extends BaseProtocolEncoder {
case Command.TYPE_OUTPUT_CONTROL:
int data = Integer.parseInt(command.getString(Command.KEY_DATA)) << 4
+ command.getInteger(Command.KEY_INDEX);
- return encodeContent(command.getDeviceId(), 0x03, data, 0);
+ return encodeCommand(command.getDeviceId(), 0x03, data, 0);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
index 4351a14bf..9b146ec90 100644
--- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
@@ -31,6 +31,7 @@ import org.traccar.model.CellTower;
import org.traccar.model.Network;
import org.traccar.model.Position;
+import java.math.BigInteger;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Date;
@@ -265,14 +266,39 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder {
if (header == 0x2727) {
- buf.skipBytes(5); // acceleration
+ byte[] accelerationBytes = new byte[5];
+ buf.readBytes(accelerationBytes);
+ long acceleration = new BigInteger(accelerationBytes).longValue();
+ double accelerationZ = BitUtil.between(acceleration, 8, 15) + BitUtil.between(acceleration, 4, 8) * 0.1;
+ if (!BitUtil.check(acceleration, 15)) {
+ accelerationZ = -accelerationZ;
+ }
+ double accelerationY = BitUtil.between(acceleration, 20, 27) + BitUtil.between(acceleration, 16, 20) * 0.1;
+ if (!BitUtil.check(acceleration, 27)) {
+ accelerationY = -accelerationY;
+ }
+ double accelerationX = BitUtil.between(acceleration, 28, 32) + BitUtil.between(acceleration, 32, 39) * 0.1;
+ if (!BitUtil.check(acceleration, 39)) {
+ accelerationX = -accelerationX;
+ }
+ position.set(Position.KEY_G_SENSOR, "[" + accelerationX + "," + accelerationY + "," + accelerationZ + "]");
+
position.set(Position.KEY_BATTERY_LEVEL, BcdUtil.readInteger(buf, 2));
position.set(Position.KEY_DEVICE_TEMP, (int) buf.readByte());
position.set("lightSensor", BcdUtil.readInteger(buf, 2) * 0.1);
position.set(Position.KEY_BATTERY, BcdUtil.readInteger(buf, 2) * 0.1);
position.set("solarPanel", BcdUtil.readInteger(buf, 2) * 0.1);
position.set(Position.KEY_ODOMETER, buf.readUnsignedInt());
- position.set(Position.KEY_IGNITION, BitUtil.check(buf.readUnsignedShort(), 2));
+
+ int inputStatus = buf.readUnsignedShort();
+ position.set(Position.KEY_IGNITION, BitUtil.check(inputStatus, 2));
+ position.set(Position.KEY_RSSI, BitUtil.between(inputStatus, 4, 11));
+
+ buf.readUnsignedShort(); // ignition on upload interval
+ buf.readUnsignedInt(); // ignition off upload interval
+ buf.readUnsignedByte(); // angle upload interval
+ buf.readUnsignedShort(); // distance upload interval
+ buf.readUnsignedByte(); // heartbeat
} else if (buf.readableBytes() >= 2) {
diff --git a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java
index 819011a50..c132f194b 100644
--- a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 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.
@@ -59,7 +59,7 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
0x26, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x57, 0x58, 0x59, 0x5a, 0x6b, 0x6f, 0x7A,
0x7B, 0x7C, 0x7d, 0x7E, 0x7F, 0x80, 0x81, 0x82,
- 0x83, 0x84, 0x85, 0x86
+ 0x83, 0x84, 0x85, 0x86, 0xc8
};
int[] l4 = {
0x03, 0x06, 0x07, 0x08, 0x0e, 0x0f, 0x10, 0x11,
@@ -80,12 +80,13 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
TAG_LENGTH_MAP.put(i, 4);
}
TAG_LENGTH_MAP.put(0x95, 24);
+ TAG_LENGTH_MAP.put(0xD0, 21);
}
private static int getTagLength(int tag) {
Integer length = TAG_LENGTH_MAP.get(tag);
if (length == null) {
- throw new IllegalArgumentException("Unknown tag: " + tag);
+ throw new IllegalArgumentException(String.format("Unknown tag: 0x%02X", tag));
}
return length;
}
@@ -93,7 +94,7 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
private Map<Short, byte[]> formats = new HashMap<>();
public void setConfig(String configString) {
- Pattern pattern = Pattern.compile(":wycfg pcr\\[\\d+\\] ([0-9a-fA-F]{2})[0-9a-fA-F]{2}([0-9a-fA-F]+)");
+ Pattern pattern = Pattern.compile(":wycfg pcr\\[\\d+] ([0-9a-fA-F]{2})[0-9a-fA-F]{2}([0-9a-fA-F]+)");
Matcher matcher = pattern.matcher(configString);
while (matcher.find()) {
formats.put(Short.parseShort(matcher.group(1), 16), DataConverter.parseHex(matcher.group(2)));
@@ -119,7 +120,8 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
Position position = new Position(getProtocolName());
- for (byte tag : format) {
+ for (byte b : format) {
+ int tag = b & 0xFF;
switch (tag) {
case 0x03:
DeviceSession deviceSession = getDeviceSession(
@@ -177,6 +179,14 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
case 0x65:
position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII));
break;
+ case 0x6C:
+ buf.readUnsignedByte(); // mil
+ int ecuCount = buf.readUnsignedByte();
+ for (int i = 0; i < ecuCount; i++) {
+ buf.readUnsignedByte(); // ecu id
+ buf.skipBytes(buf.readUnsignedByte() * 6);
+ }
+ break;
case 0x73:
position.set(Position.KEY_VERSION_FW, buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim());
break;
diff --git a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java
index f4a78b5bd..6d49f2516 100644
--- a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java
@@ -10,6 +10,11 @@ public class Xt2400ProtocolDecoderTest extends ProtocolTest {
Xt2400ProtocolDecoder decoder = new Xt2400ProtocolDecoder(null);
+ decoder.setConfig("\n::wycfg pcr[1] 012801030405060708090a1213c8545657585a656e7d2cd055595d5e71797a7b7c7e7f80818285866b\n");
+
+ verifyPosition(decoder, binary(
+ "010ae85be10801a05d52d590030b12d1f9330be9290a0000ff10008b00000000000000000000000000000000000000000000000000000000000000000000000000003839333032363930323031303036363039373733000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000"));
+
decoder.setConfig("\n:wycfg pcr[0] 001001030406070809570a13121714100565\n");
verifyPosition(decoder, binary(