From 69d0cc47d63d9052218a8d87cf436e46165e716c Mon Sep 17 00:00:00 2001 From: Vitaly Litvak Date: Sat, 1 Oct 2016 09:14:33 +0300 Subject: For JT600c - added checksum verification and replying for alarms/positions messages --- src/org/traccar/protocol/Jt600ProtocolDecoder.java | 75 ++++++++++++++++------ .../traccar/protocol/Jt600ProtocolDecoderTest.java | 14 ++-- 2 files changed, 65 insertions(+), 24 deletions(-) diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index fd2448c0d..0c235a4b5 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -201,24 +201,25 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_U01 = new PatternBuilder() .text("(") - .number("(d+),") // id - .number("Udd,") // type - .number("d+,").optional() // alarm - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time - .expression("([TF]),") // validity - .number("(d+.d+),([NS]),") // latitude - .number("(d+.d+),([EW]),") // longitude - .number("(d+.?d*),") // speed - .number("(d+),") // course - .number("(d+),") // satellites - .number("(d+%),") // battery - .expression("([01]+),") // status - .number("(d+),") // cid - .number("(d+),") // lac - .number("(d+),") // gsm signal - .number("(d+),") // odometer - .number("(d+)") // index + .number("(d+),") // id + .number("(Udd),") // type + .number("d+,").optional() // alarm + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time + .expression("([TF]),") // validity + .number("(d+.d+),([NS]),") // latitude + .number("(d+.d+),([EW]),") // longitude + .number("(d+.?d*),") // speed + .number("(d+),") // course + .number("(d+),") // satellites + .number("(d+%),") // battery + .expression("([01]+),") // status + .number("(d+),") // cid + .number("(d+),") // lac + .number("(d+),") // gsm signal + .number("(d+),") // odometer + .number("(d+),") // serial number + .expression("([0-9A-F][0-9A-F])").optional() // checksum .any() .compile(); @@ -234,6 +235,8 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { return null; } + String messageType = parser.next(); + Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -256,11 +259,29 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CID, parser.nextInt()); position.set(Position.KEY_LAC, parser.nextInt()); position.set(Position.KEY_GSM, parser.nextInt()); - position.set(Position.KEY_ODOMETER, parser.nextLong() * 1000); + position.set(Position.KEY_ODOMETER, parser.nextLong() * 100); position.set(Position.KEY_INDEX, parser.nextInt()); - return position; + switch (messageType) { + case "U01": + case "U02": + case "U03": + String checkSum = parser.next(); + int calculatedCheckSum = checkSum(sentence.substring(1, sentence.length() - checkSum.length() - 1)); + if (Integer.parseInt(checkSum, 16) == calculatedCheckSum) { + sendResponse(channel, "(S39)"); + return position; + } else { + return null; + } + case "U06": + sendResponse(channel, "(S20)"); + return position; + default: + return null; + } } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -282,4 +303,18 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { return null; } + private byte checkSum(String sentence) { + byte[] bytes = sentence.getBytes(StandardCharsets.US_ASCII); + byte sum = 0; + for (byte b : bytes) { + sum ^= b; + } + return sum; + } + + private void sendResponse(Channel channel, String response) { + if (channel != null) { + channel.write(ChannelBuffers.copiedBuffer(response, StandardCharsets.US_ASCII)); + } + } } diff --git a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 64db2a124..6899418d9 100644 --- a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -18,13 +18,13 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { "2475605035891613002328091601152806086750106533350c00000000000a000000000000e1ff4f97007f1607")); verifyPosition(decoder, buffer( - "(3301210003,U01,040812,185302,T,22.564025,N,113.242329,E,5.21,152,9,32%,00000000000011,10133,5173,22,100,1)")); + "(3301210003,U01,040812,185302,T,22.564025,N,113.242329,E,5.21,152,9,32%,00000000000011,10133,5173,22,100,1,18)")); verifyPosition(decoder, buffer( - "(3301210003,U02,040812,185302,T,22.564025,N,113.242329,E,5,152,9,32%,00000000000011,10133,5173,22,100,1)")); + "(3301210003,U02,040812,185302,T,22.564025,N,113.242329,E,5,152,9,32%,00000000000011,10133,5173,22,100,1,36)")); verifyPosition(decoder, buffer( - "(3301210003,U03,040812,185302,T,22.564025,N,113.242329,E,5,152,9,32%,00000000000011,10133,5173,22,100,1)")); + "(3301210003,U03,040812,185302,T,22.564025,N,113.242329,E,5,152,9,32%,00000000000011,10133,5173,22,100,1,37)")); verifyNothing(decoder, buffer( "(3301210003,U04)")); @@ -68,11 +68,17 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { "(3120820029,W01,02553.3555,E,2438.0997,S,A,171012,053339,0,8,20,6,31,5,20,20)")); verifyPosition(decoder, buffer( - "(3330104377,U01,010100,010228,F,00.000000,N,000.000000,E,0,0,0,0%,00001000000000,741,14,22,0,206)")); + "(3330104377,U01,010100,010228,F,00.000000,N,000.000000,E,0,0,0,0%,00001000000000,741,14,22,0,206,1E)")); verifyNothing(decoder, buffer( "(6221107674,2,U09,129,2,A,280513113036,E,02711.0500,S,1721.0876,A,030613171243,E,02756.7618,S,2300.0325,3491,538200,14400,1)")); + verifyPosition(decoder, buffer( + "(3301210003,U02,040812,185302,T,00.000000,N,000.000000,E,0,0,0,0%,00000000000011,741,51,22,0,1,05)")); + + verifyPosition(decoder, buffer( + "(3301210003,U06,4,250916,133207,T,7.011013,N,25.060708,W,27.61,102,10,0%,00101011000000,0,1,0,448,0,126,1,30)")); + verifyPosition(decoder, buffer( "(3551001012,U01,010100,000032,F,0.000000,N,0.000000,E,0.00,0,0,10%,00000000010000,15748,7923,23,0,0,3E)")); -- cgit v1.2.3 From 42f870437ca784c63d8018de9848c2ed445fb453 Mon Sep 17 00:00:00 2001 From: Vitaly Litvak Date: Sat, 1 Oct 2016 17:03:52 +0300 Subject: Updated formatting, removed indentation, changed regular expression parameters --- src/org/traccar/protocol/Jt600ProtocolDecoder.java | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index 0c235a4b5..117f2cc33 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -201,25 +201,25 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_U01 = new PatternBuilder() .text("(") - .number("(d+),") // id - .number("(Udd),") // type - .number("d+,").optional() // alarm - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time - .expression("([TF]),") // validity - .number("(d+.d+),([NS]),") // latitude - .number("(d+.d+),([EW]),") // longitude - .number("(d+.?d*),") // speed - .number("(d+),") // course - .number("(d+),") // satellites - .number("(d+%),") // battery - .expression("([01]+),") // status - .number("(d+),") // cid - .number("(d+),") // lac - .number("(d+),") // gsm signal - .number("(d+),") // odometer - .number("(d+),") // serial number - .expression("([0-9A-F][0-9A-F])").optional() // checksum + .number("(d+),") // id + .number("(Udd),") // type + .number("d+,").optional() // alarm + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time + .expression("([TF]),") // validity + .number("(d+.d+),([NS]),") // latitude + .number("(d+.d+),([EW]),") // longitude + .number("(d+.?d*),") // speed + .number("(d+),") // course + .number("(d+),") // satellites + .number("(d+%),") // battery + .expression("([01]+),") // status + .number("(d+),") // cid + .number("(d+),") // lac + .number("(d+),") // gsm signal + .number("(d+),") // odometer + .number("(d+),") // serial number + .number("(xx)").optional() // checksum .any() .compile(); @@ -266,9 +266,9 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { case "U01": case "U02": case "U03": - String checkSum = parser.next(); - int calculatedCheckSum = checkSum(sentence.substring(1, sentence.length() - checkSum.length() - 1)); - if (Integer.parseInt(checkSum, 16) == calculatedCheckSum) { + int checkSum = parser.nextInt(16); + int calculatedCheckSum = checkSum(sentence.substring(1, sentence.length() - 3)); + if (checkSum == calculatedCheckSum) { sendResponse(channel, "(S39)"); return position; } else { -- cgit v1.2.3 From b5a09475b90b044cf0b5b0f64d8709dd7e92c460 Mon Sep 17 00:00:00 2001 From: Vitaly Litvak Date: Sun, 2 Oct 2016 08:15:28 +0300 Subject: Updated formatting --- src/org/traccar/protocol/Jt600ProtocolDecoder.java | 38 +++++++++++----------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index 117f2cc33..827d6fbb5 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -201,25 +201,25 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_U01 = new PatternBuilder() .text("(") - .number("(d+),") // id - .number("(Udd),") // type - .number("d+,").optional() // alarm - .number("(dd)(dd)(dd),") // date (ddmmyy) - .number("(dd)(dd)(dd),") // time - .expression("([TF]),") // validity - .number("(d+.d+),([NS]),") // latitude - .number("(d+.d+),([EW]),") // longitude - .number("(d+.?d*),") // speed - .number("(d+),") // course - .number("(d+),") // satellites - .number("(d+%),") // battery - .expression("([01]+),") // status - .number("(d+),") // cid - .number("(d+),") // lac - .number("(d+),") // gsm signal - .number("(d+),") // odometer - .number("(d+),") // serial number - .number("(xx)").optional() // checksum + .number("(d+),") // id + .number("(Udd),") // type + .number("d+,").optional() // alarm + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time + .expression("([TF]),") // validity + .number("(d+.d+),([NS]),") // latitude + .number("(d+.d+),([EW]),") // longitude + .number("(d+.?d*),") // speed + .number("(d+),") // course + .number("(d+),") // satellites + .number("(d+%),") // battery + .expression("([01]+),") // status + .number("(d+),") // cid + .number("(d+),") // lac + .number("(d+),") // gsm signal + .number("(d+),") // odometer + .number("(d+),") // serial number + .number("(xx)").optional() // checksum .any() .compile(); -- cgit v1.2.3 From 9cc1cbd2b21afcd40091069d2f0a58565db18c15 Mon Sep 17 00:00:00 2001 From: Vitaly Litvak Date: Sun, 2 Oct 2016 08:17:43 +0300 Subject: Moved 'xor' checksum method to the utility class. --- src/org/traccar/helper/Checksum.java | 9 +++++++++ src/org/traccar/protocol/Jt600ProtocolDecoder.java | 12 ++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/org/traccar/helper/Checksum.java b/src/org/traccar/helper/Checksum.java index 2a4b1191d..dde174545 100644 --- a/src/org/traccar/helper/Checksum.java +++ b/src/org/traccar/helper/Checksum.java @@ -194,6 +194,15 @@ public final class Checksum { return checksum; } + public static int xor(String string) { + byte[] bytes = string.getBytes(StandardCharsets.US_ASCII); + byte sum = 0; + for (byte b : bytes) { + sum ^= b; + } + return sum; + } + public static String nmea(String msg) { int checksum = 0; for (byte b : msg.getBytes(StandardCharsets.US_ASCII)) { diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index 827d6fbb5..de4510d17 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -21,6 +21,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BcdUtil; +import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -267,7 +268,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { case "U02": case "U03": int checkSum = parser.nextInt(16); - int calculatedCheckSum = checkSum(sentence.substring(1, sentence.length() - 3)); + int calculatedCheckSum = Checksum.xor(sentence.substring(1, sentence.length() - 3)); if (checkSum == calculatedCheckSum) { sendResponse(channel, "(S39)"); return position; @@ -303,15 +304,6 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { return null; } - private byte checkSum(String sentence) { - byte[] bytes = sentence.getBytes(StandardCharsets.US_ASCII); - byte sum = 0; - for (byte b : bytes) { - sum ^= b; - } - return sum; - } - private void sendResponse(Channel channel, String response) { if (channel != null) { channel.write(ChannelBuffers.copiedBuffer(response, StandardCharsets.US_ASCII)); -- cgit v1.2.3 From 2d145a029bf45d309366b5b6367befd00efb5efc Mon Sep 17 00:00:00 2001 From: Vitaly Litvak Date: Sun, 2 Oct 2016 08:20:42 +0300 Subject: Reverted back odometer to count as thousands of meters. --- src/org/traccar/protocol/Jt600ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index de4510d17..287235fb1 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -260,7 +260,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CID, parser.nextInt()); position.set(Position.KEY_LAC, parser.nextInt()); position.set(Position.KEY_GSM, parser.nextInt()); - position.set(Position.KEY_ODOMETER, parser.nextLong() * 100); + position.set(Position.KEY_ODOMETER, parser.nextLong() * 1000); position.set(Position.KEY_INDEX, parser.nextInt()); switch (messageType) { -- cgit v1.2.3 From bb211eea5f62014c0700138e922cb1adcdc9d9dd Mon Sep 17 00:00:00 2001 From: Vitaly Litvak Date: Sun, 2 Oct 2016 08:28:27 +0300 Subject: Support old protocol versions without checksum --- src/org/traccar/protocol/Jt600ProtocolDecoder.java | 20 +++++++++++++------- .../traccar/protocol/Jt600ProtocolDecoderTest.java | 8 ++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index 287235fb1..6d066299a 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -219,7 +219,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // lac .number("(d+),") // gsm signal .number("(d+),") // odometer - .number("(d+),") // serial number + .number("(d+),?") // serial number .number("(xx)").optional() // checksum .any() .compile(); @@ -267,13 +267,19 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { case "U01": case "U02": case "U03": - int checkSum = parser.nextInt(16); - int calculatedCheckSum = Checksum.xor(sentence.substring(1, sentence.length() - 3)); - if (checkSum == calculatedCheckSum) { - sendResponse(channel, "(S39)"); - return position; + // support protocol with check sum + if (parser.hasNext(2)) { + int checkSum = parser.nextInt(16); + int calculatedCheckSum = Checksum.xor(sentence.substring(1, sentence.length() - 3)); + if (checkSum == calculatedCheckSum) { + sendResponse(channel, "(S39)"); + return position; + } else { + return null; + } + // support protocol without check sum } else { - return null; + return position; } case "U06": sendResponse(channel, "(S20)"); diff --git a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 6899418d9..3fc74081f 100644 --- a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -18,13 +18,13 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { "2475605035891613002328091601152806086750106533350c00000000000a000000000000e1ff4f97007f1607")); verifyPosition(decoder, buffer( - "(3301210003,U01,040812,185302,T,22.564025,N,113.242329,E,5.21,152,9,32%,00000000000011,10133,5173,22,100,1,18)")); + "(3301210003,U01,040812,185302,T,22.564025,N,113.242329,E,5.21,152,9,32%,00000000000011,10133,5173,22,100,1)")); verifyPosition(decoder, buffer( - "(3301210003,U02,040812,185302,T,22.564025,N,113.242329,E,5,152,9,32%,00000000000011,10133,5173,22,100,1,36)")); + "(3301210003,U02,040812,185302,T,22.564025,N,113.242329,E,5,152,9,32%,00000000000011,10133,5173,22,100,1)")); verifyPosition(decoder, buffer( - "(3301210003,U03,040812,185302,T,22.564025,N,113.242329,E,5,152,9,32%,00000000000011,10133,5173,22,100,1,37)")); + "(3301210003,U03,040812,185302,T,22.564025,N,113.242329,E,5,152,9,32%,00000000000011,10133,5173,22,100,1)")); verifyNothing(decoder, buffer( "(3301210003,U04)")); @@ -68,7 +68,7 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { "(3120820029,W01,02553.3555,E,2438.0997,S,A,171012,053339,0,8,20,6,31,5,20,20)")); verifyPosition(decoder, buffer( - "(3330104377,U01,010100,010228,F,00.000000,N,000.000000,E,0,0,0,0%,00001000000000,741,14,22,0,206,1E)")); + "(3330104377,U01,010100,010228,F,00.000000,N,000.000000,E,0,0,0,0%,00001000000000,741,14,22,0,206)")); verifyNothing(decoder, buffer( "(6221107674,2,U09,129,2,A,280513113036,E,02711.0500,S,1721.0876,A,030613171243,E,02756.7618,S,2300.0325,3491,538200,14400,1)")); -- cgit v1.2.3