From 032d02b584553f4374c4bc6ae9f7c8e819595c42 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 06:50:59 +0000 Subject: Xexun2 Encoder - Initial Code --- .../java/org/traccar/protocol/Xexun2Protocol.java | 7 ++ .../traccar/protocol/Xexun2ProtocolEncoder.java | 121 +++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java (limited to 'src/main') diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 4630a69e0..1d5038a22 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -19,6 +19,7 @@ import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; import org.traccar.config.Config; +import org.traccar.model.Command; import javax.inject.Inject; @@ -26,11 +27,17 @@ public class Xexun2Protocol extends BaseProtocol { @Inject public Xexun2Protocol(Config config) { + setSupportedDataCommands( + Command.TYPE_CUSTOM, + Command.TYPE_POSITION_PERIODIC, + Command.TYPE_POWER_OFF, + Command.TYPE_REBOOT_DEVICE); addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { pipeline.addLast(new Xexun2FrameDecoder()); pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); + pipeline.addLast(new Xexun2ProtocolEncoder(Xexun2Protocol.this)); } }); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java new file mode 100644 index 000000000..d85c6734b --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -0,0 +1,121 @@ +/* + * Copyright 2016 - 2022 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.DataConverter; +import org.traccar.model.Command; +import org.traccar.Protocol; + +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { + + public Xexun2ProtocolEncoder(Protocol protocol) { + super(protocol); + } + + private static ByteBuf encodeFrame(ByteBuf buf) { + buf.clear(); + if (buf.readableBytes() < 5) { + return null; + } + + ByteBuf result = Unpooled.buffer(); + + result.writeBytes(buf.readBytes(2)); + + while (buf.readerIndex() < buf.capacity() - 2) { + int b = buf.readUnsignedByte(); + if (b == 0xfa && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xaf) { + buf.readUnsignedByte(); + result.writeByte(0xfb); + result.writeByte(0xbf); + result.writeByte(0x01); + } else if (b == 0xfb && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { + buf.readUnsignedByte(); + result.writeByte(0xfb); + result.writeByte(0xbf); + result.writeByte(0x02); + } else { + result.writeByte(b); + } + } + result.writeBytes(buf.readBytes(2)); + + return result; + } + + private static int checksum(byte[] data) + { + int sum = 0; + int len = data.length; + for (int j = 0; len > 1; len--) { + sum += data[j++] & 0xff; + if ((sum & 0x80000000) > 0) { + sum = (sum & 0xffff) + (sum >> 16); + } + } + if (len == 1) { + sum += data[data.length - 1] & 0xff; + } + while ((sum >> 16) > 0) { + sum = (sum & 0xffff) + sum >> 16; + } + sum = (sum == 0xffff) ? sum & 0xffff : (~sum) & 0xffff; + return sum; + } + + + private static ByteBuf encodeContent(String uniqueId, String content) { + ByteBuf buf = Unpooled.buffer(); + + byte[] message = content.getBytes(); + + buf.writeShort(0xFAAF); + buf.writeShort(0x0007); + buf.writeShort(0x0001); + buf.writeBytes(DataConverter.parseHex(uniqueId + "0"),0,8); + buf.writeShort(message.length); + buf.writeShort(checksum(message)); + buf.writeBytes(message); + buf.writeShort(0xFAAF); + + return encodeFrame(buf); + } + + @Override + protected Object encodeCommand(Command command) { + String uniqueId = getUniqueId(command.getDeviceId()); + + switch (command.getType()) { + case Command.TYPE_CUSTOM: + return encodeContent(uniqueId, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_PERIODIC: + return encodeContent(uniqueId, String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); + case Command.TYPE_POWER_OFF: + return encodeContent(uniqueId, "of=1"); + case Command.TYPE_REBOOT_DEVICE: + return encodeContent(uniqueId, "reset"); + default: + return null; + } + } + +} -- cgit v1.2.3 From 8b63ce5c51fca9462e0e561b8ce07ae49afce6f8 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 13:34:02 +0000 Subject: Update Xexun2 Encoder --- src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java | 6 +++--- src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index d85c6734b..287364cf2 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -32,8 +32,8 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { } private static ByteBuf encodeFrame(ByteBuf buf) { - buf.clear(); - if (buf.readableBytes() < 5) { + int bufLength = buf.readableBytes(); + if (bufLength < 5) { return null; } @@ -41,7 +41,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { result.writeBytes(buf.readBytes(2)); - while (buf.readerIndex() < buf.capacity() - 2) { + while (buf.readerIndex() < bufLength - 2) { int b = buf.readUnsignedByte(); if (b == 0xfa && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xaf) { buf.readUnsignedByte(); diff --git a/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java index 6d3b3e065..483bc85fa 100644 --- a/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2ProtocolEncoderTest.java @@ -14,15 +14,15 @@ public class Xexun2ProtocolEncoderTest extends ProtocolTest { Command command; command = new Command(); - command.setDeviceId(604080829351806311L); + command.setDeviceId(1); command.setType(Command.TYPE_POWER_OFF); - verifyCommand(encoder, command, binary("FAAF0007000186220505123456700004FEBC6F663D31FAAF")); + verifyCommand(encoder, command, binary("FAAF0007000112345678901234500004FEBC6F663D31FAAF")); command = new Command(); - command.setDeviceId(604080829351806311L); + command.setDeviceId(1); command.setType(Command.TYPE_POSITION_PERIODIC); command.set(Command.KEY_FREQUENCY, 150); - verifyCommand(encoder, command, binary("FAAF0007000186220505123456700015F90E747261636B696E675F73656E643D3135302C313530FAAF")); + verifyCommand(encoder, command, binary("FAAF0007000112345678901234500015F90E747261636B696E675F73656E643D3135302C313530FAAF")); } -- cgit v1.2.3 From 1f0965d02081d0257a969927ba58de5b39e051bd Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 13:52:06 +0000 Subject: Update Xexun2 Decoder - do not ACK a command ACK --- src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 28e7fbda3..bdeb0fa78 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -42,6 +42,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { } public static final int MSG_POSITION = 0x14; + public static final int MSG_COMMAND = 0x07; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { @@ -99,12 +100,12 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } - sendResponse(channel, type, index, imei); - buf.readUnsignedShort(); // attributes buf.readUnsignedShort(); // checksum if (type == MSG_POSITION) { + sendResponse(channel, type, index, imei); + List lengths = new ArrayList<>(); List positions = new ArrayList<>(); -- cgit v1.2.3 From e91402cddad8763658572eb8e383fa8a16d69190 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Mon, 25 Jul 2022 19:49:37 +0000 Subject: Update Xexun2 Encoder --- .../traccar/protocol/Xexun2ProtocolDecoder.java | 6 ++++-- .../traccar/protocol/Xexun2ProtocolEncoder.java | 24 +++++++++++----------- 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index bdeb0fa78..3c81ec27f 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -100,12 +100,14 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } + if (type != MSG_COMMAND) { + sendResponse(channel, type, index, imei); + } + buf.readUnsignedShort(); // attributes buf.readUnsignedShort(); // checksum if (type == MSG_POSITION) { - sendResponse(channel, type, index, imei); - List lengths = new ArrayList<>(); List positions = new ArrayList<>(); diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index 287364cf2..c31d6e747 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 Stefan Clark (stefan@stefanclark.co.uk) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,15 +22,15 @@ import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.Protocol; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { public Xexun2ProtocolEncoder(Protocol protocol) { super(protocol); } + public static final int FLAG = 0xfaaf; + public static final int MSG_COMMAND = 0x07; + private static ByteBuf encodeFrame(ByteBuf buf) { int bufLength = buf.readableBytes(); if (bufLength < 5) { @@ -62,8 +62,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { return result; } - private static int checksum(byte[] data) - { + private static int checksum(byte[] data) { int sum = 0; int len = data.length; for (int j = 0; len > 1; len--) { @@ -88,14 +87,14 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { byte[] message = content.getBytes(); - buf.writeShort(0xFAAF); - buf.writeShort(0x0007); - buf.writeShort(0x0001); - buf.writeBytes(DataConverter.parseHex(uniqueId + "0"),0,8); + buf.writeShort(FLAG); + buf.writeShort(MSG_COMMAND); + buf.writeShort(1); // index + buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); buf.writeShort(message.length); buf.writeShort(checksum(message)); buf.writeBytes(message); - buf.writeShort(0xFAAF); + buf.writeShort(FLAG); return encodeFrame(buf); } @@ -108,7 +107,8 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { case Command.TYPE_CUSTOM: return encodeContent(uniqueId, command.getString(Command.KEY_DATA)); case Command.TYPE_POSITION_PERIODIC: - return encodeContent(uniqueId, String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); + return encodeContent(uniqueId, + String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); case Command.TYPE_POWER_OFF: return encodeContent(uniqueId, "of=1"); case Command.TYPE_REBOOT_DEVICE: -- cgit v1.2.3 From de2219565e4a61aa0d64b03650ec36ef6d17de93 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Wed, 27 Jul 2022 15:47:18 +0100 Subject: Update Xexun2 Encoder --- .../java/org/traccar/protocol/Xexun2ProtocolDecoder.java | 9 +++------ .../java/org/traccar/protocol/Xexun2ProtocolEncoder.java | 15 ++++++++------- 2 files changed, 11 insertions(+), 13 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 3c81ec27f..8deb2328b 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -42,13 +42,11 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { } public static final int MSG_POSITION = 0x14; - public static final int MSG_COMMAND = 0x07; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { ByteBuf response = Unpooled.buffer(); - response.writeByte(0xfa); - response.writeByte(0xaf); + response.writeShort(Xexun2ProtocolEncoder.FLAG); response.writeShort(type); response.writeShort(index); @@ -57,8 +55,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { response.writeShort(0xfffe); // checksum response.writeByte(1); // response - response.writeByte(0xfa); - response.writeByte(0xaf); + response.writeShort(Xexun2ProtocolEncoder.FLAG); channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } @@ -100,7 +97,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } - if (type != MSG_COMMAND) { + if (type != Xexun2ProtocolEncoder.MSG_COMMAND) { sendResponse(channel, type, index, imei); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index c31d6e747..f876853bf 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -62,17 +62,17 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { return result; } - private static int checksum(byte[] data) { + private static int udpchecksum(ByteBuf data) { int sum = 0; - int len = data.length; + int len = data.capacity(); for (int j = 0; len > 1; len--) { - sum += data[j++] & 0xff; + sum += data.readByte() & 0xff; if ((sum & 0x80000000) > 0) { sum = (sum & 0xffff) + (sum >> 16); } } if (len == 1) { - sum += data[data.length - 1] & 0xff; + sum += data.readByte() & 0xff; } while ((sum >> 16) > 0) { sum = (sum & 0xffff) + sum >> 16; @@ -85,14 +85,15 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { private static ByteBuf encodeContent(String uniqueId, String content) { ByteBuf buf = Unpooled.buffer(); - byte[] message = content.getBytes(); + ByteBuf message = Unpooled.copiedBuffer(content.getBytes()); buf.writeShort(FLAG); buf.writeShort(MSG_COMMAND); buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); - buf.writeShort(message.length); - buf.writeShort(checksum(message)); + buf.writeShort(message.capacity()); + buf.writeShort(udpchecksum(message)); + message.resetReaderIndex(); buf.writeBytes(message); buf.writeShort(FLAG); -- cgit v1.2.3 From 42e88c2bf95962f1274a8bbb6e8fc09af95f627f Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Thu, 28 Jul 2022 22:37:15 +0100 Subject: Added udp() to Checksum helper and Updated Xexun2 procotol --- src/main/java/org/traccar/helper/Checksum.java | 19 +++++++++++++++++ .../traccar/protocol/Xexun2ProtocolDecoder.java | 11 +++++++--- .../traccar/protocol/Xexun2ProtocolEncoder.java | 24 ++-------------------- 3 files changed, 29 insertions(+), 25 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/traccar/helper/Checksum.java b/src/main/java/org/traccar/helper/Checksum.java index 8c3d0063a..e660790ef 100644 --- a/src/main/java/org/traccar/helper/Checksum.java +++ b/src/main/java/org/traccar/helper/Checksum.java @@ -200,4 +200,23 @@ public final class Checksum { return (10 - (checksum % 10)) % 10; } + public static int udp(ByteBuffer data) { + int sum = 0; + int len = data.capacity(); + for (int j = 0; len > 1; len--) { + sum += data.get() & 0xff; + if ((sum & 0x80000000) > 0) { + sum = (sum & 0xffff) + (sum >> 16); + } + } + if (len == 1) { + sum += data.get() & 0xff; + } + while ((sum >> 16) > 0) { + sum = (sum & 0xffff) + sum >> 16; + } + sum = (sum == 0xffff) ? sum & 0xffff : (~sum) & 0xffff; + return sum; + } + } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index 8deb2328b..f0158e6ce 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -24,6 +24,7 @@ import org.traccar.session.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -97,13 +98,17 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { return null; } + int payloadSize = buf.readUnsignedShort() & 0x03ff; + int checksum = buf.readUnsignedShort(); // checksum + + if (checksum != Checksum.udp(buf.nioBuffer(buf.readerIndex(), payloadSize))) { + return null; + } + if (type != Xexun2ProtocolEncoder.MSG_COMMAND) { sendResponse(channel, type, index, imei); } - buf.readUnsignedShort(); // attributes - buf.readUnsignedShort(); // checksum - if (type == MSG_POSITION) { List lengths = new ArrayList<>(); List positions = new ArrayList<>(); diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index f876853bf..6e1e1d68d 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.Checksum; import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.Protocol; @@ -62,26 +63,6 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { return result; } - private static int udpchecksum(ByteBuf data) { - int sum = 0; - int len = data.capacity(); - for (int j = 0; len > 1; len--) { - sum += data.readByte() & 0xff; - if ((sum & 0x80000000) > 0) { - sum = (sum & 0xffff) + (sum >> 16); - } - } - if (len == 1) { - sum += data.readByte() & 0xff; - } - while ((sum >> 16) > 0) { - sum = (sum & 0xffff) + sum >> 16; - } - sum = (sum == 0xffff) ? sum & 0xffff : (~sum) & 0xffff; - return sum; - } - - private static ByteBuf encodeContent(String uniqueId, String content) { ByteBuf buf = Unpooled.buffer(); @@ -92,8 +73,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); buf.writeShort(message.capacity()); - buf.writeShort(udpchecksum(message)); - message.resetReaderIndex(); + buf.writeShort(Checksum.udp(message.nioBuffer())); buf.writeBytes(message); buf.writeShort(FLAG); -- cgit v1.2.3 From dbc5fc5dcf697dcc00d357bbca5fe4669325148b Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Sat, 6 Aug 2022 17:42:22 +0100 Subject: Updated Xexun2 Protocol --- src/main/java/org/traccar/helper/Checksum.java | 8 +--- .../org/traccar/protocol/Xexun2FrameEncoder.java | 48 ++++++++++++++++++++++ .../java/org/traccar/protocol/Xexun2Protocol.java | 1 + .../traccar/protocol/Xexun2ProtocolDecoder.java | 12 +++--- .../traccar/protocol/Xexun2ProtocolEncoder.java | 48 ++++------------------ .../traccar/protocol/Xexun2FrameDecoderTest.java | 4 ++ .../traccar/protocol/Xexun2FrameEncoderTest.java | 20 +++++++++ 7 files changed, 90 insertions(+), 51 deletions(-) create mode 100644 src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java create mode 100644 src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java (limited to 'src/main') diff --git a/src/main/java/org/traccar/helper/Checksum.java b/src/main/java/org/traccar/helper/Checksum.java index e660790ef..db5817275 100644 --- a/src/main/java/org/traccar/helper/Checksum.java +++ b/src/main/java/org/traccar/helper/Checksum.java @@ -200,18 +200,14 @@ public final class Checksum { return (10 - (checksum % 10)) % 10; } - public static int udp(ByteBuffer data) { + public static int ip(ByteBuffer data) { int sum = 0; - int len = data.capacity(); - for (int j = 0; len > 1; len--) { + while (data.remaining() > 0) { sum += data.get() & 0xff; if ((sum & 0x80000000) > 0) { sum = (sum & 0xffff) + (sum >> 16); } } - if (len == 1) { - sum += data.get() & 0xff; - } while ((sum >> 16) > 0) { sum = (sum & 0xffff) + sum >> 16; } diff --git a/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java b/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java new file mode 100644 index 000000000..52d43c36c --- /dev/null +++ b/src/main/java/org/traccar/protocol/Xexun2FrameEncoder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2022 Stefan Clark (stefan@stefanclark.co.uk) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +public class Xexun2FrameEncoder extends MessageToByteEncoder { + + @Override + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) { + out.writeBytes(msg.readBytes(2)); + + while (msg.readableBytes() > 2) { + int b = msg.readUnsignedByte(); + if (b == 0xfa && msg.isReadable() && msg.getUnsignedByte(msg.readerIndex()) == 0xaf) { + msg.readUnsignedByte(); + out.writeByte(0xfb); + out.writeByte(0xbf); + out.writeByte(0x01); + } else if (b == 0xfb && msg.isReadable() && msg.getUnsignedByte(msg.readerIndex()) == 0xbf) { + msg.readUnsignedByte(); + out.writeByte(0xfb); + out.writeByte(0xbf); + out.writeByte(0x02); + } else { + out.writeByte(b); + } + } + + out.writeBytes(msg.readBytes(2)); + + } +} diff --git a/src/main/java/org/traccar/protocol/Xexun2Protocol.java b/src/main/java/org/traccar/protocol/Xexun2Protocol.java index 1d5038a22..52cf731f0 100644 --- a/src/main/java/org/traccar/protocol/Xexun2Protocol.java +++ b/src/main/java/org/traccar/protocol/Xexun2Protocol.java @@ -35,6 +35,7 @@ public class Xexun2Protocol extends BaseProtocol { addServer(new TrackerServer(config, getName(), false) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new Xexun2FrameEncoder()); pipeline.addLast(new Xexun2FrameDecoder()); pipeline.addLast(new Xexun2ProtocolDecoder(Xexun2Protocol.this)); pipeline.addLast(new Xexun2ProtocolEncoder(Xexun2Protocol.this)); diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java index f0158e6ce..913dfaf28 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolDecoder.java @@ -42,12 +42,14 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public static final int FLAG = 0xfaaf; + public static final int MSG_COMMAND = 0x07; public static final int MSG_POSITION = 0x14; private void sendResponse(Channel channel, int type, int index, ByteBuf imei) { if (channel != null) { ByteBuf response = Unpooled.buffer(); - response.writeShort(Xexun2ProtocolEncoder.FLAG); + response.writeShort(FLAG); response.writeShort(type); response.writeShort(index); @@ -56,7 +58,7 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { response.writeShort(0xfffe); // checksum response.writeByte(1); // response - response.writeShort(Xexun2ProtocolEncoder.FLAG); + response.writeShort(FLAG); channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress())); } @@ -99,13 +101,13 @@ public class Xexun2ProtocolDecoder extends BaseProtocolDecoder { } int payloadSize = buf.readUnsignedShort() & 0x03ff; - int checksum = buf.readUnsignedShort(); // checksum + int checksum = buf.readUnsignedShort(); - if (checksum != Checksum.udp(buf.nioBuffer(buf.readerIndex(), payloadSize))) { + if (checksum != Checksum.ip(buf.nioBuffer(buf.readerIndex(), payloadSize))) { return null; } - if (type != Xexun2ProtocolEncoder.MSG_COMMAND) { + if (type != MSG_COMMAND) { sendResponse(channel, type, index, imei); } diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index 6e1e1d68d..c315cab30 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -23,61 +23,29 @@ import org.traccar.helper.DataConverter; import org.traccar.model.Command; import org.traccar.Protocol; +import java.nio.charset.StandardCharsets; + public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { public Xexun2ProtocolEncoder(Protocol protocol) { super(protocol); } - public static final int FLAG = 0xfaaf; - public static final int MSG_COMMAND = 0x07; - - private static ByteBuf encodeFrame(ByteBuf buf) { - int bufLength = buf.readableBytes(); - if (bufLength < 5) { - return null; - } - - ByteBuf result = Unpooled.buffer(); - - result.writeBytes(buf.readBytes(2)); - - while (buf.readerIndex() < bufLength - 2) { - int b = buf.readUnsignedByte(); - if (b == 0xfa && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xaf) { - buf.readUnsignedByte(); - result.writeByte(0xfb); - result.writeByte(0xbf); - result.writeByte(0x01); - } else if (b == 0xfb && buf.isReadable() && buf.getUnsignedByte(buf.readerIndex()) == 0xbf) { - buf.readUnsignedByte(); - result.writeByte(0xfb); - result.writeByte(0xbf); - result.writeByte(0x02); - } else { - result.writeByte(b); - } - } - result.writeBytes(buf.readBytes(2)); - - return result; - } - private static ByteBuf encodeContent(String uniqueId, String content) { ByteBuf buf = Unpooled.buffer(); - ByteBuf message = Unpooled.copiedBuffer(content.getBytes()); + ByteBuf message = Unpooled.copiedBuffer(content.getBytes(StandardCharsets.US_ASCII)); - buf.writeShort(FLAG); - buf.writeShort(MSG_COMMAND); + buf.writeShort(Xexun2ProtocolDecoder.FLAG); + buf.writeShort(Xexun2ProtocolDecoder.MSG_COMMAND); buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); buf.writeShort(message.capacity()); - buf.writeShort(Checksum.udp(message.nioBuffer())); + buf.writeShort(Checksum.ip(message.nioBuffer())); buf.writeBytes(message); - buf.writeShort(FLAG); + buf.writeShort(Xexun2ProtocolDecoder.FLAG); - return encodeFrame(buf); + return buf; } @Override diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java index 7209a423b..34437862c 100644 --- a/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Xexun2FrameDecoderTest.java @@ -14,6 +14,10 @@ public class Xexun2FrameDecoderTest extends ProtocolTest { binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"), decoder.decode(null, null, binary("faaf0014000286147503139003400032f2b001002f4260b0d6a0008019104a3378323130333135317c323130333132303100704020308715758089502023015648643670faaf"))); + verifyFrame( + binary("FAAF123456FAAF123456FBBF123456FAAF"), + decoder.decode(null, null, binary("FAAF123456FBBF01123456FBBF02123456FAAF"))); + } } diff --git a/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java b/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java new file mode 100644 index 000000000..54a8aaa14 --- /dev/null +++ b/src/test/java/org/traccar/protocol/Xexun2FrameEncoderTest.java @@ -0,0 +1,20 @@ +package org.traccar.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Xexun2FrameEncoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Xexun2FrameEncoder encoder = new Xexun2FrameEncoder(); + + ByteBuf result = Unpooled.buffer(); + encoder.encode(null, binary("FAAF123456FAAF123456FBBF123456FAAF"), result); + verifyFrame(binary("FAAF123456FBBF01123456FBBF02123456FAAF"), result); + } + +} -- cgit v1.2.3 From 7aa230b9ddcd5540e7ff9c9b3d9bcf5119175c46 Mon Sep 17 00:00:00 2001 From: Stefan Clark Date: Sat, 17 Sep 2022 20:46:40 +0100 Subject: Xexun2 Encoder update --- src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main') diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index c315cab30..8f3fa5672 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -40,7 +40,7 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { buf.writeShort(Xexun2ProtocolDecoder.MSG_COMMAND); buf.writeShort(1); // index buf.writeBytes(DataConverter.parseHex(uniqueId + "0")); - buf.writeShort(message.capacity()); + buf.writeShort(message.readableBytes()); buf.writeShort(Checksum.ip(message.nioBuffer())); buf.writeBytes(message); buf.writeShort(Xexun2ProtocolDecoder.FLAG); -- cgit v1.2.3