diff options
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( |