From e4e4bad2d525b9a575fd8332441b7463267ee7c1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 15 Feb 2016 09:17:57 +1100 Subject: Implement Astra communication protocol --- debug.xml | 1 + src/org/traccar/protocol/AstraProtocol.java | 43 ++++++++ src/org/traccar/protocol/AstraProtocolDecoder.java | 119 +++++++++++++++++++++ .../traccar/protocol/AstraProtocolDecoderTest.java | 18 ++++ 4 files changed, 181 insertions(+) create mode 100644 src/org/traccar/protocol/AstraProtocol.java create mode 100644 src/org/traccar/protocol/AstraProtocolDecoder.java create mode 100644 test/org/traccar/protocol/AstraProtocolDecoderTest.java diff --git a/debug.xml b/debug.xml index e641bda56..6d519d64c 100644 --- a/debug.xml +++ b/debug.xml @@ -270,5 +270,6 @@ 5100 5101 5102 + 5103 diff --git a/src/org/traccar/protocol/AstraProtocol.java b/src/org/traccar/protocol/AstraProtocol.java new file mode 100644 index 000000000..d0b1d47a5 --- /dev/null +++ b/src/org/traccar/protocol/AstraProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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 org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class AstraProtocol extends BaseProtocol { + + public AstraProtocol() { + super("astra"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 1, 2, -3, 0)); + pipeline.addLast("objectDecoder", new AstraProtocolDecoder(AstraProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/AstraProtocolDecoder.java b/src/org/traccar/protocol/AstraProtocolDecoder.java new file mode 100644 index 000000000..e57533eaf --- /dev/null +++ b/src/org/traccar/protocol/AstraProtocolDecoder.java @@ -0,0 +1,119 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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 org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BitUtil; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Event; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.charset.Charset; +import java.util.LinkedList; +import java.util.List; + +public class AstraProtocolDecoder extends BaseProtocolDecoder { + + public AstraProtocolDecoder(AstraProtocol protocol) { + super(protocol); + } + + public static final int MSG_HEARTBEAT = 0x1A; + public static final int MSG_DATA = 0x10; + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + buf.readUnsignedByte(); // protocol + buf.readUnsignedShort(); // length + + String imei = String.format("%08d", buf.readUnsignedInt()) + String.format("%07d", buf.readUnsignedMedium()); + if (!identify(imei, channel, remoteAddress)) { + return null; + } + + List positions = new LinkedList<>(); + + while (buf.readableBytes() > 2) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(getDeviceId()); + + buf.readUnsignedByte(); // index + + position.setLatitude(buf.readInt() * 0.000001); + position.setLongitude(buf.readInt() * 0.000001); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(1980, 1, 6).addMillis(buf.readUnsignedInt() * 1000L); + position.setTime(dateBuilder.getDate()); + + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte() * 2)); + position.setCourse(buf.readUnsignedByte() * 2); + + int reason = buf.readUnsignedMedium(); + int status = buf.readUnsignedShort(); + + position.set(Event.PREFIX_IO + 1, buf.readUnsignedByte()); + position.set(Event.PREFIX_ADC + 1, buf.readUnsignedByte()); + position.set(Event.KEY_BATTERY, buf.readUnsignedByte()); + position.set(Event.KEY_POWER, buf.readUnsignedByte()); + + buf.readUnsignedByte(); // max journey speed + buf.skipBytes(6); // accelerometer + buf.readUnsignedShort(); // journey distance + buf.readUnsignedShort(); // journey idle time + + position.setAltitude(buf.readUnsignedByte() * 20); + + int quality = buf.readUnsignedByte(); + position.set(Event.KEY_SATELLITES, quality & 0xf); + position.set(Event.KEY_GSM, quality >> 4); + + buf.readUnsignedByte(); // geofence events + + if (BitUtil.check(reason, 6) || BitUtil.check(reason, 7)) { + + position.set(Event.KEY_RFID, buf.readBytes(7).toString(Charset.defaultCharset())); + position.set(Event.KEY_ODOMETER, buf.readUnsignedMedium()); + + buf.readUnsignedShort(); // engine time + + } + + if (BitUtil.check(status, 6)) { + + // extra data + + } + + positions.add(position); + + } + + return positions; + } + +} diff --git a/test/org/traccar/protocol/AstraProtocolDecoderTest.java b/test/org/traccar/protocol/AstraProtocolDecoderTest.java new file mode 100644 index 000000000..93a939879 --- /dev/null +++ b/test/org/traccar/protocol/AstraProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class AstraProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + AstraProtocolDecoder decoder = new AstraProtocolDecoder(new AstraProtocol()); + + verifyPositions(decoder, binary( + "4b013c02213aec35c501ad031368b8ffcd1ad043e5c4500c79000100003101005c490c001c0009020200020015069600ae03136801ffcd1af143e5c452125e000100003101005c491200090011010000020015068500af0313629effcd1f4b43e5c45d1e46000100003101005c491e00080409040500040015068700b0031359d5ffcd35ad43e5c47b2a3b000001003101005c492a1b1a0d0b0f0b00080015068700b103134984ffcd4b1e43e5c4913354000100003101005c49340b0103090606000f0015067700b203132e1affcd5a5a43e5c4af3348000001003101005c4935070a08000a070017001505f700b30313192cffcd7af143e5c4cd3733000001003101005c4937091206050a0800200015058600b403130debffcda88743e5c4eb2c3e000001003101005c493707030601080600290015058600b377")); + + } + +} -- cgit v1.2.3 From 513de76c622f743b7ed257d1a956666d575dd6f3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 17 Feb 2016 07:50:08 +1100 Subject: Add new Totem unit test case --- test/org/traccar/ProtocolTest.java | 2 +- test/org/traccar/protocol/TotemProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index 75c12b171..d7104edba 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -194,7 +194,7 @@ public class ProtocolTest { if (attributes.containsKey(Event.KEY_LAC) || attributes.containsKey(Event.KEY_CID)) { checkInteger(attributes.get(Event.KEY_LAC), 1, 65535); - checkInteger(attributes.get(Event.KEY_CID), 1, 268435455); + checkInteger(attributes.get(Event.KEY_CID), 0, 268435455); } if (attributes.containsKey(Event.KEY_MCC) || attributes.containsKey(Event.KEY_MNC)) { diff --git a/test/org/traccar/protocol/TotemProtocolDecoderTest.java b/test/org/traccar/protocol/TotemProtocolDecoderTest.java index de554b7bc..237e77612 100644 --- a/test/org/traccar/protocol/TotemProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TotemProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TotemProtocolDecoderTest extends ProtocolTest { TotemProtocolDecoder decoder = new TotemProtocolDecoder(new TotemProtocol()); + verifyPosition(decoder, text( + "$$0108AA863835024426319|18004000160216160756411100007DCD0000111000000000.800000000316.3519N10228.5086E126522")); + // $$0128AA867521029231005|1880100015101802314842140000000000000000000000001AB48366093127600000.900000000806.1947N09818.4795E080355 verifyPosition(decoder, text( -- cgit v1.2.3 From 2ce5a32a8cbcbb7d2e22f2912fa47f03b2d6b2fd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 17 Feb 2016 08:39:29 +1100 Subject: Implement Astra protocol ack messages --- src/org/traccar/protocol/AstraProtocolDecoder.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/org/traccar/protocol/AstraProtocolDecoder.java b/src/org/traccar/protocol/AstraProtocolDecoder.java index e57533eaf..03053ca2d 100644 --- a/src/org/traccar/protocol/AstraProtocolDecoder.java +++ b/src/org/traccar/protocol/AstraProtocolDecoder.java @@ -45,6 +45,10 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; + if (channel != null) { + channel.write(ChannelBuffers.wrappedBuffer(new byte[] {0x06}), remoteAddress); + } + buf.readUnsignedByte(); // protocol buf.readUnsignedShort(); // length -- cgit v1.2.3 From 6ea8778be3d7426fa9281f9260081e1863fae4bd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 17 Feb 2016 22:10:52 +1100 Subject: Add GT06 frame decoder tests --- test/org/traccar/protocol/Gt06FrameDecoderTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/org/traccar/protocol/Gt06FrameDecoderTest.java b/test/org/traccar/protocol/Gt06FrameDecoderTest.java index 9a4c709e8..9ecd44e59 100644 --- a/test/org/traccar/protocol/Gt06FrameDecoderTest.java +++ b/test/org/traccar/protocol/Gt06FrameDecoderTest.java @@ -11,6 +11,18 @@ public class Gt06FrameDecoderTest extends ProtocolTest { Gt06FrameDecoder decoder = new Gt06FrameDecoder(); + Assert.assertEquals( + binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"), + decoder.decode(null, null, binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"))); + + Assert.assertNotEquals( + binary("787808134606020002044dc5050d0a"), + decoder.decode(null, null, binary("787808134606020002044dc5050d0a"))); + + Assert.assertEquals( + binary("78781f1210020e14061dcc0476fcd0003e3faf3e14b20000000000000000044ef6740d0a"), + decoder.decode(null, null, binary("78781f1210020e14061dcc0476fcd0003e3faf3e14b20000000000000000044ef6740d0a"))); + Assert.assertEquals( binary("78780d010352887071911998000479d00d0a"), decoder.decode(null, null, binary("78780d010352887071911998000479d00d0a"))); -- cgit v1.2.3 From c9403e503e269f36b93d97777c98352946e1da2f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 19 Feb 2016 10:51:16 +1300 Subject: Handle IMEI without delimiter (fix #1733) --- src/org/traccar/protocol/Gps103ProtocolDecoder.java | 9 +++++++-- test/org/traccar/protocol/Gps103ProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java index a45e20ba2..e2aed6309 100644 --- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -118,11 +118,16 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { } // Send response #2 - if (sentence.length() == 15 && Character.isDigit(sentence.charAt(0))) { + if (Character.isDigit(sentence.charAt(0))) { if (channel != null) { channel.write("ON", remoteAddress); } - return null; + int start = sentence.indexOf("imei:"); + if (start >= 0) { + sentence = sentence.substring(start); + } else { + return null; + } } Position position = new Position(); diff --git a/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java b/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java index ae3d2fa55..6e7f19e18 100644 --- a/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gps103ProtocolDecoderTest extends ProtocolTest { Gps103ProtocolDecoder decoder = new Gps103ProtocolDecoder(new Gps103Protocol()); + verifyNothing(decoder, text( + "359769031878322imei:359769031878322,tracker,1602160718,2,F,221811.000,A,1655.2193,S,14546.6722,E,0.00,,")); + verifyNothing(decoder, text( "imei:865328021049167,OBD,141118115036,,,0.0,,000,0.0%,+,0.0%,00000,,,,,")); -- cgit v1.2.3 From 1f4a8c8af7b67f0b48f30a442c74fbfcf7ccbe97 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 19 Feb 2016 10:56:55 +1300 Subject: Fix GPS103 unit test issue --- test/org/traccar/protocol/Gps103ProtocolDecoderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java b/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java index 6e7f19e18..ab59ba331 100644 --- a/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class Gps103ProtocolDecoderTest extends ProtocolTest { Gps103ProtocolDecoder decoder = new Gps103ProtocolDecoder(new Gps103Protocol()); - verifyNothing(decoder, text( + verifyPosition(decoder, text( "359769031878322imei:359769031878322,tracker,1602160718,2,F,221811.000,A,1655.2193,S,14546.6722,E,0.00,,")); verifyNothing(decoder, text( -- cgit v1.2.3 From b178acdc21483cc7bd9588453a4d8afc476ca294 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 19 Feb 2016 11:16:42 +1300 Subject: Fix check style and pmd issues --- src/org/traccar/protocol/AstraProtocolDecoder.java | 8 ++--- .../traccar/protocol/CastelProtocolDecoder.java | 40 +++++++++++++--------- src/org/traccar/protocol/KenjiProtocolDecoder.java | 2 +- src/org/traccar/protocol/TrvProtocolDecoder.java | 2 +- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/org/traccar/protocol/AstraProtocolDecoder.java b/src/org/traccar/protocol/AstraProtocolDecoder.java index 03053ca2d..8cfec95fe 100644 --- a/src/org/traccar/protocol/AstraProtocolDecoder.java +++ b/src/org/traccar/protocol/AstraProtocolDecoder.java @@ -78,7 +78,7 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { position.setCourse(buf.readUnsignedByte() * 2); int reason = buf.readUnsignedMedium(); - int status = buf.readUnsignedShort(); + buf.readUnsignedShort(); // status position.set(Event.PREFIX_IO + 1, buf.readUnsignedByte()); position.set(Event.PREFIX_ADC + 1, buf.readUnsignedByte()); @@ -107,11 +107,7 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { } - if (BitUtil.check(status, 6)) { - - // extra data - - } + // extra data positions.add(position); diff --git a/src/org/traccar/protocol/CastelProtocolDecoder.java b/src/org/traccar/protocol/CastelProtocolDecoder.java index 3179cbd78..9f332dd04 100644 --- a/src/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/org/traccar/protocol/CastelProtocolDecoder.java @@ -109,6 +109,28 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } } + private void sendResponse( + Channel channel, SocketAddress remoteAddress, ChannelBuffer id, short type) { + + if (channel != null) { + int length = 2 + 2 + id.readableBytes() + 2 + 4 + 8 + 2 + 2; + + ChannelBuffer response = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, length); + response.writeByte('@'); response.writeByte('@'); + response.writeShort(length); + response.writeBytes(id); + response.writeShort(ChannelBuffers.swapShort(type)); + response.writeInt(0); + for (int i = 0; i < 8; i++) { + response.writeByte(0xff); + } + response.writeShort( + Checksum.crc16(Checksum.CRC16_X25, response.toByteBuffer(0, response.writerIndex()))); + response.writeByte(0x0D); response.writeByte(0x0A); + channel.write(response, remoteAddress); + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -134,23 +156,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { if (type == 0x2001) { - if (channel != null) { - int length = 2 + 2 + id.readableBytes() + 2 + 4 + 8 + 2 + 2; - - ChannelBuffer response = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, length); - response.writeByte('@'); response.writeByte('@'); - response.writeShort(length); - response.writeBytes(id); - response.writeShort(ChannelBuffers.swapShort((short) 0x1001)); - response.writeInt(0); - for (int i = 0; i < 8; i++) { - response.writeByte(0xff); - } - response.writeShort( - Checksum.crc16(Checksum.CRC16_X25, response.toByteBuffer(0, response.writerIndex()))); - response.writeByte(0x0D); response.writeByte(0x0A); - channel.write(response, remoteAddress); - } + sendResponse(channel, remoteAddress, id, (short) 0x1001); buf.readUnsignedInt(); // index buf.readUnsignedInt(); // unix time diff --git a/src/org/traccar/protocol/KenjiProtocolDecoder.java b/src/org/traccar/protocol/KenjiProtocolDecoder.java index e1f8130fa..e190af948 100755 --- a/src/org/traccar/protocol/KenjiProtocolDecoder.java +++ b/src/org/traccar/protocol/KenjiProtocolDecoder.java @@ -47,7 +47,7 @@ public class KenjiProtocolDecoder extends BaseProtocolDecoder { .number("G(d+)") // satellites .any() .compile(); - + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { diff --git a/src/org/traccar/protocol/TrvProtocolDecoder.java b/src/org/traccar/protocol/TrvProtocolDecoder.java index 94796fa5e..8075515c2 100644 --- a/src/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/org/traccar/protocol/TrvProtocolDecoder.java @@ -105,7 +105,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { position.set(Event.KEY_GSM, parser.nextInt()); position.set(Event.KEY_SATELLITES, parser.nextInt()); - position.set(Event.KEY_BATTERY , parser.nextInt()); + position.set(Event.KEY_BATTERY, parser.nextInt()); position.set(Event.KEY_IGNITION, parser.nextInt() != 0); position.set("arm", parser.nextInt()); -- cgit v1.2.3 From dac5c6923044572b0714e29dfae650888332c920 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 19 Feb 2016 11:24:29 +1300 Subject: Workaround for GT06 length issue (fix #1727) --- src/org/traccar/protocol/Gt06FrameDecoder.java | 6 ++++++ test/org/traccar/protocol/Gt06FrameDecoderTest.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/Gt06FrameDecoder.java b/src/org/traccar/protocol/Gt06FrameDecoder.java index ed0d8d548..21f5c8b52 100644 --- a/src/org/traccar/protocol/Gt06FrameDecoder.java +++ b/src/org/traccar/protocol/Gt06FrameDecoder.java @@ -37,6 +37,12 @@ public class Gt06FrameDecoder extends FrameDecoder { if (buf.getByte(buf.readerIndex()) == 0x78) { length += 1 + buf.getUnsignedByte(buf.readerIndex() + 2); + + int type = buf.getUnsignedByte(buf.readerIndex() + 3); + if (type == Gt06ProtocolDecoder.MSG_STATUS && length == 13) { + length += 2; // workaround for #1727 + } + } else { length += 2 + buf.getUnsignedShort(buf.readerIndex() + 2); } diff --git a/test/org/traccar/protocol/Gt06FrameDecoderTest.java b/test/org/traccar/protocol/Gt06FrameDecoderTest.java index 9ecd44e59..12ee6bb60 100644 --- a/test/org/traccar/protocol/Gt06FrameDecoderTest.java +++ b/test/org/traccar/protocol/Gt06FrameDecoderTest.java @@ -15,7 +15,7 @@ public class Gt06FrameDecoderTest extends ProtocolTest { binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"), decoder.decode(null, null, binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"))); - Assert.assertNotEquals( + Assert.assertEquals( binary("787808134606020002044dc5050d0a"), decoder.decode(null, null, binary("787808134606020002044dc5050d0a"))); -- cgit v1.2.3 From 591c6b74e8449f7d35c6c464e96b58f6d621bd6c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 19 Feb 2016 12:55:17 +1300 Subject: Implement Homtecs communication protocol --- debug.xml | 1 + src/org/traccar/protocol/HomtecsProtocol.java | 43 +++++++++++ .../traccar/protocol/HomtecsProtocolDecoder.java | 83 ++++++++++++++++++++++ .../protocol/HomtecsProtocolDecoderTest.java | 18 +++++ 4 files changed, 145 insertions(+) create mode 100644 src/org/traccar/protocol/HomtecsProtocol.java create mode 100644 src/org/traccar/protocol/HomtecsProtocolDecoder.java create mode 100644 test/org/traccar/protocol/HomtecsProtocolDecoderTest.java diff --git a/debug.xml b/debug.xml index 6d519d64c..b5c89a90c 100644 --- a/debug.xml +++ b/debug.xml @@ -271,5 +271,6 @@ 5101 5102 5103 + 5104 diff --git a/src/org/traccar/protocol/HomtecsProtocol.java b/src/org/traccar/protocol/HomtecsProtocol.java new file mode 100644 index 000000000..1a2e98565 --- /dev/null +++ b/src/org/traccar/protocol/HomtecsProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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 org.jboss.netty.bootstrap.ConnectionlessBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class HomtecsProtocol extends BaseProtocol { + + public HomtecsProtocol() { + super("homtecs"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new HomtecsProtocolDecoder(HomtecsProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/HomtecsProtocolDecoder.java b/src/org/traccar/protocol/HomtecsProtocolDecoder.java new file mode 100644 index 000000000..0b1cd99e9 --- /dev/null +++ b/src/org/traccar/protocol/HomtecsProtocolDecoder.java @@ -0,0 +1,83 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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 org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.Event; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class HomtecsProtocolDecoder extends BaseProtocolDecoder { + + public HomtecsProtocolDecoder(HomtecsProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .expression("([^,]+),") // id + .number("(dd)(dd)(dd),") // date + .number("(dd)(dd)(dd).(d+),") // time + .number("(d+),") // satellites + .number("(dd)(dd.d+),") // latitude + .expression("([NS]),") + .number("(ddd)(dd.d+),") // longitude + .expression("([EW]),") + .number("(d+.?d*)?,") // speed + .number("(d+.?d*)?,") // course + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + if (!identify(parser.next(), channel, remoteAddress)) { + return null; + } + position.setDeviceId(getDeviceId()); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt()); + + position.setTime(dateBuilder.getDate()); + + position.setValid(true); + position.set(Event.KEY_SATELLITES, parser.nextInt()); + + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setSpeed(parser.nextDouble()); + position.setCourse(parser.nextDouble()); + + return position; + } + +} diff --git a/test/org/traccar/protocol/HomtecsProtocolDecoderTest.java b/test/org/traccar/protocol/HomtecsProtocolDecoderTest.java new file mode 100644 index 000000000..5b70453e0 --- /dev/null +++ b/test/org/traccar/protocol/HomtecsProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class HomtecsProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + HomtecsProtocolDecoder decoder = new HomtecsProtocolDecoder(new HomtecsProtocol()); + + verifyPosition(decoder, text( + "strommabus939_R01272028,160217,191003.00,06,5540.12292,N,01237.49814,E,0.391,,1,1.27,1.2")); + + } + +} -- cgit v1.2.3 From b71bea3e0503dc9008fa8cc1f4981686fc0ee540 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 20 Feb 2016 10:22:32 +1300 Subject: Calculate distance for valid positions (fix #1738) --- src/org/traccar/DistanceHandler.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/org/traccar/DistanceHandler.java b/src/org/traccar/DistanceHandler.java index 1586d116b..c737457f6 100644 --- a/src/org/traccar/DistanceHandler.java +++ b/src/org/traccar/DistanceHandler.java @@ -1,5 +1,6 @@ /* * Copyright 2015 Amila Silva + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,11 +41,13 @@ public class DistanceHandler extends BaseDataHandler { distance = ((Number) last.getAttributes().get(Event.KEY_DISTANCE)).doubleValue(); } - distance += DistanceCalculator.distance( - position.getLatitude(), position.getLongitude(), - last.getLatitude(), last.getLongitude()); + if (position.getValid()) { + distance += DistanceCalculator.distance( + position.getLatitude(), position.getLongitude(), + last.getLatitude(), last.getLongitude()); - distance = BigDecimal.valueOf(distance).setScale(2, RoundingMode.HALF_EVEN).doubleValue(); + distance = BigDecimal.valueOf(distance).setScale(2, RoundingMode.HALF_EVEN).doubleValue(); + } } position.set(Event.KEY_DISTANCE, distance); -- cgit v1.2.3 From 7eaf8d55da9b71d697c9307cbf79220df7a1535d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 21 Feb 2016 10:27:08 +1300 Subject: Split TT8850 into separate protocol --- debug.xml | 1 + src/org/traccar/protocol/Gl200ProtocolDecoder.java | 6 -- src/org/traccar/protocol/Tt8850Protocol.java | 45 +++++++++ .../traccar/protocol/Tt8850ProtocolDecoder.java | 105 +++++++++++++++++++++ .../traccar/protocol/Gl200ProtocolDecoderTest.java | 18 ---- .../protocol/Tt8850ProtocolDecoderTest.java | 33 +++++++ 6 files changed, 184 insertions(+), 24 deletions(-) create mode 100644 src/org/traccar/protocol/Tt8850Protocol.java create mode 100644 src/org/traccar/protocol/Tt8850ProtocolDecoder.java create mode 100644 test/org/traccar/protocol/Tt8850ProtocolDecoderTest.java diff --git a/debug.xml b/debug.xml index b5c89a90c..51d668066 100644 --- a/debug.xml +++ b/debug.xml @@ -247,6 +247,7 @@ 5076 5077 5078 + 5079 5080 5081 5082 diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index e4bf43979..fb018dc19 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -69,13 +69,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .compile(); private static final Pattern PATTERN = new PatternBuilder() - .groupBegin() .text("+").expression("(?:RESP|BUFF)").text(":") - .or() - .binary("00?04,") - .number("xxxx,") - .expression("[01],") - .groupEnd() .expression("GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version .expression("([^,]+),") // imei diff --git a/src/org/traccar/protocol/Tt8850Protocol.java b/src/org/traccar/protocol/Tt8850Protocol.java new file mode 100644 index 000000000..a409205c7 --- /dev/null +++ b/src/org/traccar/protocol/Tt8850Protocol.java @@ -0,0 +1,45 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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 org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class Tt8850Protocol extends BaseProtocol { + + public Tt8850Protocol() { + super("tt8850"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "$")); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new Tt8850ProtocolDecoder(Tt8850Protocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java new file mode 100644 index 000000000..c270d3364 --- /dev/null +++ b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java @@ -0,0 +1,105 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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 org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.PatternUtil; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Event; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class Tt8850ProtocolDecoder extends BaseProtocolDecoder { + + public Tt8850ProtocolDecoder(Tt8850Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .binary("0004,") + .number("xxxx,") + .expression("[01],") + .expression("GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .expression("([^,]+),") // imei + .any() + .number("(d{1,2})?,") // gps accuracy + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6}),") // longitude + .number("(-?d{1,2}.d{6}),") // latitude + .number("(dddd)(dd)(dd)") // date + .number("(dd)(dd)(dd),") // time + .number("(0ddd)?,") // mcc + .number("(0ddd)?,") // mnc + .number("(xxxx)?,") // lac + .number("(xxxx)?,") // cell + .any() + .number("(dddd)(dd)(dd)") // date + .number("(dd)(dd)(dd),") // time + .number("(xxxx)") + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String x = PatternUtil.checkPattern(PATTERN.pattern(), (String) msg); + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + if (!identify(parser.next(), channel, remoteAddress)) { + return null; + } + position.setDeviceId(getDeviceId()); + + position.setValid(parser.nextInt() < 20); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + position.setAltitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + if (parser.hasNext(4)) { + position.set(Event.KEY_MCC, parser.nextInt()); + position.set(Event.KEY_MNC, parser.nextInt()); + position.set(Event.KEY_LAC, parser.nextInt(16)); + position.set(Event.KEY_CID, parser.nextInt(16)); + } + + return position; + } + +} diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java index b06715e29..0977b7fc1 100644 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java @@ -127,24 +127,6 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "+RESP:GTFRI,240100,135790246811220,,,10,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,,,,,,20090214093254,11F0$")); - verifyPosition(decoder, text( - "\u0000\u0004,005F,0,GTFRI,020100,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,90,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "\u0000\u0004,005F,0,GTGEO,020100,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,90,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "\u0000\u0004,005F,0,GTNMR,020100,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,90,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "\u0000\u0004,0017,0,GTNMR,,867844000400914,,0,41,1,2,0.0,0,1504.2,-75.569202,6.242850,20150404162835,,,,,97,20150404162836,05EF$")); - - verifyNothing(decoder, text( - "\u0000\u0004,0017,0,GTPNA,,867844000400914,,0,0,1,0,,,,0,0,,,,,,99,20150404190153,0601$")); - - verifyPosition(decoder, text( - "\u0000\u0004,0017,0,GTEPN,,867844000400914,,0,0,1,0,0.0,0,1717.4,-75.598445,6.278578,20150405003116,,,,,95,20150405003358,0607$")); - verifyPosition(decoder, text( "+RESP:GTSTT,280100,A1000043D20139,,42,0,0.1,321,228.6,-76.660884,39.832552,20150615120628,0310,0484,00600019,0A52,,20150615085741,0320$")); diff --git a/test/org/traccar/protocol/Tt8850ProtocolDecoderTest.java b/test/org/traccar/protocol/Tt8850ProtocolDecoderTest.java new file mode 100644 index 000000000..b2b7c4fe5 --- /dev/null +++ b/test/org/traccar/protocol/Tt8850ProtocolDecoderTest.java @@ -0,0 +1,33 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Tt8850ProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Tt8850ProtocolDecoder decoder = new Tt8850ProtocolDecoder(new Tt8850Protocol()); + + verifyPosition(decoder, text( + "\u0000\u0004,005F,0,GTFRI,020100,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,90,20090214093254,11F0")); + + verifyPosition(decoder, text( + "\u0000\u0004,005F,0,GTGEO,020100,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,90,20090214093254,11F0")); + + verifyPosition(decoder, text( + "\u0000\u0004,005F,0,GTNMR,020100,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,90,20090214093254,11F0")); + + verifyPosition(decoder, text( + "\u0000\u0004,0017,0,GTNMR,,867844000400914,,0,41,1,2,0.0,0,1504.2,-75.569202,6.242850,20150404162835,,,,,97,20150404162836,05EF")); + + verifyNothing(decoder, text( + "\u0000\u0004,0017,0,GTPNA,,867844000400914,,0,0,1,0,,,,0,0,,,,,,99,20150404190153,0601")); + + verifyPosition(decoder, text( + "\u0000\u0004,0017,0,GTEPN,,867844000400914,,0,0,1,0,0.0,0,1717.4,-75.598445,6.278578,20150405003116,,,,,95,20150405003358,0607")); + + } + +} -- cgit v1.2.3 From 63d3e629fd0b4d02b1885160e4289596cfd958c0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 21 Feb 2016 11:04:48 +1300 Subject: Rename telik protocol to telic --- debug.xml | 2 +- src/org/traccar/protocol/TelicProtocol.java | 45 +++++++++++ src/org/traccar/protocol/TelicProtocolDecoder.java | 86 ++++++++++++++++++++++ src/org/traccar/protocol/TelikProtocol.java | 45 ----------- src/org/traccar/protocol/TelikProtocolDecoder.java | 86 ---------------------- .../traccar/protocol/TelicProtocolDecoderTest.java | 25 +++++++ .../traccar/protocol/TelikProtocolDecoderTest.java | 25 ------- 7 files changed, 157 insertions(+), 157 deletions(-) create mode 100644 src/org/traccar/protocol/TelicProtocol.java create mode 100644 src/org/traccar/protocol/TelicProtocolDecoder.java delete mode 100644 src/org/traccar/protocol/TelikProtocol.java delete mode 100644 src/org/traccar/protocol/TelikProtocolDecoder.java create mode 100644 test/org/traccar/protocol/TelicProtocolDecoderTest.java delete mode 100644 test/org/traccar/protocol/TelikProtocolDecoderTest.java diff --git a/debug.xml b/debug.xml index 51d668066..992f586d9 100644 --- a/debug.xml +++ b/debug.xml @@ -235,7 +235,7 @@ 5064 5065 5066 - 5067 + 5067 5068 5069 5070 diff --git a/src/org/traccar/protocol/TelicProtocol.java b/src/org/traccar/protocol/TelicProtocol.java new file mode 100644 index 000000000..c2a7287dd --- /dev/null +++ b/src/org/traccar/protocol/TelicProtocol.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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 org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class TelicProtocol extends BaseProtocol { + + public TelicProtocol() { + super("telic"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\0')); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new TelicProtocolDecoder(TelicProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java new file mode 100644 index 000000000..466b40aa4 --- /dev/null +++ b/src/org/traccar/protocol/TelicProtocolDecoder.java @@ -0,0 +1,86 @@ +/* + * Copyright 2014 - 2015 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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 java.net.SocketAddress; +import java.util.regex.Pattern; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.Event; +import org.traccar.model.Position; + +public class TelicProtocolDecoder extends BaseProtocolDecoder { + + public TelicProtocolDecoder(TelicProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .number("dddd") + .number("(d{6})") // device id + .number("(d+),") // type + .number("d{12},") // event time + .number("d+,") + .number("(dd)(dd)(dd)") // date + .number("(dd)(dd)(dd),") // time + .number("(-?d+),") // longitude + .number("(-?d+),") // latitude + .number("(d),") // validity + .number("(d+),") // speed + .number("(d+),") // course + .number("(d+),") // satellites + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + if (!identify(parser.next(), channel, remoteAddress)) { + return null; + } + position.setDeviceId(getDeviceId()); + + position.set(Event.KEY_TYPE, parser.next()); + + DateBuilder dateBuilder = new DateBuilder() + .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + position.setLongitude(parser.nextDouble() / 10000); + position.setLatitude(parser.nextDouble() / 10000); + position.setValid(parser.nextInt() != 1); + position.setSpeed(parser.nextDouble()); + position.setCourse(parser.nextDouble()); + + position.set(Event.KEY_SATELLITES, parser.next()); + + return position; + } + +} diff --git a/src/org/traccar/protocol/TelikProtocol.java b/src/org/traccar/protocol/TelikProtocol.java deleted file mode 100644 index b6b5ba14d..000000000 --- a/src/org/traccar/protocol/TelikProtocol.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) - * - * 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 org.jboss.netty.bootstrap.ServerBootstrap; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.traccar.BaseProtocol; -import org.traccar.CharacterDelimiterFrameDecoder; -import org.traccar.TrackerServer; - -import java.util.List; - -public class TelikProtocol extends BaseProtocol { - - public TelikProtocol() { - super("telik"); - } - - @Override - public void initTrackerServers(List serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { - @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\0')); - pipeline.addLast("stringDecoder", new StringDecoder()); - pipeline.addLast("objectDecoder", new TelikProtocolDecoder(TelikProtocol.this)); - } - }); - } - -} diff --git a/src/org/traccar/protocol/TelikProtocolDecoder.java b/src/org/traccar/protocol/TelikProtocolDecoder.java deleted file mode 100644 index 4171750d6..000000000 --- a/src/org/traccar/protocol/TelikProtocolDecoder.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2014 - 2015 Anton Tananaev (anton.tananaev@gmail.com) - * - * 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 java.net.SocketAddress; -import java.util.regex.Pattern; -import org.jboss.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Event; -import org.traccar.model.Position; - -public class TelikProtocolDecoder extends BaseProtocolDecoder { - - public TelikProtocolDecoder(TelikProtocol protocol) { - super(protocol); - } - - private static final Pattern PATTERN = new PatternBuilder() - .number("dddd") - .number("(d{6})") // device id - .number("(d+),") // type - .number("d{12},") // event time - .number("d+,") - .number("(dd)(dd)(dd)") // date - .number("(dd)(dd)(dd),") // time - .number("(-?d+),") // longitude - .number("(-?d+),") // latitude - .number("(d),") // validity - .number("(d+),") // speed - .number("(d+),") // course - .number("(d+),") // satellites - .any() - .compile(); - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - Parser parser = new Parser(PATTERN, (String) msg); - if (!parser.matches()) { - return null; - } - - Position position = new Position(); - position.setProtocol(getProtocolName()); - - if (!identify(parser.next(), channel, remoteAddress)) { - return null; - } - position.setDeviceId(getDeviceId()); - - position.set(Event.KEY_TYPE, parser.next()); - - DateBuilder dateBuilder = new DateBuilder() - .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()) - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - - position.setLongitude(parser.nextDouble() / 10000); - position.setLatitude(parser.nextDouble() / 10000); - position.setValid(parser.nextInt() != 1); - position.setSpeed(parser.nextDouble()); - position.setCourse(parser.nextDouble()); - - position.set(Event.KEY_SATELLITES, parser.next()); - - return position; - } - -} diff --git a/test/org/traccar/protocol/TelicProtocolDecoderTest.java b/test/org/traccar/protocol/TelicProtocolDecoderTest.java new file mode 100644 index 000000000..536875a2f --- /dev/null +++ b/test/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -0,0 +1,25 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class TelicProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + TelicProtocolDecoder decoder = new TelicProtocolDecoder(new TelicProtocol()); + + verifyNothing(decoder, text( + "0026436729|232|01|003002030")); + + verifyPosition(decoder, text( + "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7"), + position("2013-06-27 04:16:52.000", true, 47.53410, 16.66530)); + + verifyPosition(decoder, text( + "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7")); + + } + +} diff --git a/test/org/traccar/protocol/TelikProtocolDecoderTest.java b/test/org/traccar/protocol/TelikProtocolDecoderTest.java deleted file mode 100644 index 180ab1b3d..000000000 --- a/test/org/traccar/protocol/TelikProtocolDecoderTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.traccar.protocol; - -import org.junit.Test; -import org.traccar.ProtocolTest; - -public class TelikProtocolDecoderTest extends ProtocolTest { - - @Test - public void testDecode() throws Exception { - - TelikProtocolDecoder decoder = new TelikProtocolDecoder(new TelikProtocol()); - - verifyNothing(decoder, text( - "0026436729|232|01|003002030")); - - verifyPosition(decoder, text( - "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7"), - position("2013-06-27 04:16:52.000", true, 47.53410, 16.66530)); - - verifyPosition(decoder, text( - "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7")); - - } - -} -- cgit v1.2.3 From 2c8223bed1ae6ed809a50a4e459e3cc50068bd86 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 21 Feb 2016 11:48:00 +1300 Subject: Support another Telic protocol format --- src/org/traccar/protocol/TelicProtocol.java | 13 ++++++++----- src/org/traccar/protocol/TelicProtocolDecoder.java | 19 ++++++++++++++++--- .../traccar/protocol/TelicProtocolDecoderTest.java | 8 ++++---- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/org/traccar/protocol/TelicProtocol.java b/src/org/traccar/protocol/TelicProtocol.java index c2a7287dd..b2139c54c 100644 --- a/src/org/traccar/protocol/TelicProtocol.java +++ b/src/org/traccar/protocol/TelicProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,12 @@ package org.traccar.protocol; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; import org.jboss.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; -import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.TrackerServer; +import java.nio.ByteOrder; import java.util.List; public class TelicProtocol extends BaseProtocol { @@ -32,14 +33,16 @@ public class TelicProtocol extends BaseProtocol { @Override public void initTrackerServers(List serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { + TrackerServer server = new TrackerServer(new ServerBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\0')); + pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 0, 4, 1, 4)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new TelicProtocolDecoder(TelicProtocol.this)); } - }); + }; + server.setEndianness(ByteOrder.LITTLE_ENDIAN); + serverList.add(server); } } diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java index 466b40aa4..3ba81de6e 100644 --- a/src/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/org/traccar/protocol/TelicProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2014 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,8 +39,13 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { .number("d+,") .number("(dd)(dd)(dd)") // date .number("(dd)(dd)(dd),") // time + .groupBegin() + .number("(ddd)(dd)(dddd),") // longitude + .number("(dd)(dd)(dddd),") // latitude + .or() .number("(-?d+),") // longitude .number("(-?d+),") // latitude + .groupEnd() .number("(d),") // validity .number("(d+),") // speed .number("(d+),") // course @@ -72,8 +77,16 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setTime(dateBuilder.getDate()); - position.setLongitude(parser.nextDouble() / 10000); - position.setLatitude(parser.nextDouble() / 10000); + if (parser.hasNext(6)) { + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); + } + + if (parser.hasNext(2)) { + position.setLongitude(parser.nextDouble() / 10000); + position.setLatitude(parser.nextDouble() / 10000); + } + position.setValid(parser.nextInt() != 1); position.setSpeed(parser.nextDouble()); position.setCourse(parser.nextDouble()); diff --git a/test/org/traccar/protocol/TelicProtocolDecoderTest.java b/test/org/traccar/protocol/TelicProtocolDecoderTest.java index 536875a2f..62a80c94f 100644 --- a/test/org/traccar/protocol/TelicProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -10,15 +10,15 @@ public class TelicProtocolDecoderTest extends ProtocolTest { TelicProtocolDecoder decoder = new TelicProtocolDecoder(new TelicProtocol()); - verifyNothing(decoder, text( - "0026436729|232|01|003002030")); + verifyPosition(decoder, text( + "002017297899,190216202500,0,190216202459,014221890,46492170,3,0,0,6,,,1034,43841,,0000,00,0,209,0,0407\u0000")); verifyPosition(decoder, text( - "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7"), + "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7\u0000"), position("2013-06-27 04:16:52.000", true, 47.53410, 16.66530)); verifyPosition(decoder, text( - "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7")); + "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7\u0000")); } -- cgit v1.2.3 From 547246a76bfe48d21b89164b0dd674e06bf3d6ab Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Feb 2016 10:39:02 +1300 Subject: Add Telic custom frame decoder --- src/org/traccar/protocol/Gt06FrameDecoder.java | 6 +-- src/org/traccar/protocol/TelicFrameDecoder.java | 54 ++++++++++++++++++++++ src/org/traccar/protocol/TelicProtocol.java | 2 +- .../traccar/protocol/TelicFrameDecoderTest.java | 30 ++++++++++++ 4 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 src/org/traccar/protocol/TelicFrameDecoder.java create mode 100644 test/org/traccar/protocol/TelicFrameDecoderTest.java diff --git a/src/org/traccar/protocol/Gt06FrameDecoder.java b/src/org/traccar/protocol/Gt06FrameDecoder.java index 21f5c8b52..67f42efb4 100644 --- a/src/org/traccar/protocol/Gt06FrameDecoder.java +++ b/src/org/traccar/protocol/Gt06FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2014 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,7 @@ public class Gt06FrameDecoder extends FrameDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, - Channel channel, - ChannelBuffer buf) throws Exception { + ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { // Check minimum length if (buf.readableBytes() < 5) { diff --git a/src/org/traccar/protocol/TelicFrameDecoder.java b/src/org/traccar/protocol/TelicFrameDecoder.java new file mode 100644 index 000000000..2a6e121cf --- /dev/null +++ b/src/org/traccar/protocol/TelicFrameDecoder.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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 org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; + +public class TelicFrameDecoder extends FrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + + if (buf.readableBytes() < 4) { + return null; + } + + long length = buf.getUnsignedInt(buf.readerIndex()); + + if (length < 1024) { + if (buf.readableBytes() >= length + 4) { + buf.readUnsignedInt(); + return buf.readBytes((int) length); + } + } else { + int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); + if (endIndex >= 0) { + ChannelBuffer frame = buf.readBytes(endIndex - buf.readerIndex()); + buf.readByte(); + if (frame.readableBytes() > 0) { + return frame; + } + } + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/TelicProtocol.java b/src/org/traccar/protocol/TelicProtocol.java index b2139c54c..6b8abcaeb 100644 --- a/src/org/traccar/protocol/TelicProtocol.java +++ b/src/org/traccar/protocol/TelicProtocol.java @@ -36,7 +36,7 @@ public class TelicProtocol extends BaseProtocol { TrackerServer server = new TrackerServer(new ServerBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 0, 4, 1, 4)); + pipeline.addLast("frameDecoder", new TelicFrameDecoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new TelicProtocolDecoder(TelicProtocol.this)); } diff --git a/test/org/traccar/protocol/TelicFrameDecoderTest.java b/test/org/traccar/protocol/TelicFrameDecoderTest.java new file mode 100644 index 000000000..64f8b55e6 --- /dev/null +++ b/test/org/traccar/protocol/TelicFrameDecoderTest.java @@ -0,0 +1,30 @@ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.junit.Assert; +import org.junit.Test; +import org.traccar.ProtocolTest; + +import java.nio.ByteOrder; + +public class TelicFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + TelicFrameDecoder decoder = new TelicFrameDecoder(); + + Assert.assertNull( + decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "00303032363937393238317c3233327c30337c30303230303430313000"))); + + Assert.assertEquals( + binary(ByteOrder.LITTLE_ENDIAN, "303032363937393238317c3233327c30337c303032303034303130"), + decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "303032363937393238317c3233327c30337c30303230303430313000"))); + + Assert.assertEquals( + binary(ByteOrder.LITTLE_ENDIAN, "3030323039373932383139392c3231303231363038313930302c302c3231303231363038313835392c3031333839333338352c34363635383639352c332c302c302c382c2c2c3534312c36313239382c2c303030302c30302c302c3139362c302c30343037"), + decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "650000003030323039373932383139392c3231303231363038313930302c302c3231303231363038313835392c3031333839333338352c34363635383639352c332c302c302c382c2c2c3534312c36313239382c2c303030302c30302c302c3139362c302c3034303700"))); + + } + +} -- cgit v1.2.3 From 4d9481d8c3c0d61bf533f7cbd365840b7f7c6402 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Feb 2016 14:32:22 +1300 Subject: Start GL200 decoder refactoring --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 169 +++++++++++++++++---- .../traccar/protocol/Gl200ProtocolDecoderTest.java | 33 +--- 2 files changed, 139 insertions(+), 63 deletions(-) diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index fb018dc19..bb6acb1ef 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -23,6 +23,7 @@ import org.traccar.Context; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; +import org.traccar.helper.PatternUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Event; import org.traccar.model.Position; @@ -33,7 +34,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Pattern PATTERN_HEARTBEAT = new PatternBuilder() + private static final Pattern PATTERN_HBD = new PatternBuilder() .text("+ACK:GTHBD,") .number("([0-9A-Z]{2}xxxx),") .any().text(",") @@ -68,7 +69,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); - private static final Pattern PATTERN = new PatternBuilder() + /*private static final Pattern PATTERN = new PatternBuilder() .text("+").expression("(?:RESP|BUFF)").text(":") .expression("GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version @@ -127,50 +128,154 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .groupEnd() .number(",(xxxx)") .text("$").optional() + .compile();*/ + + private static final Pattern PATTERN_BACKUP = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF)").text(":") + .expression("GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .any() + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6}),") // longitude + .number("(-?d{1,2}.d{6}),") // latitude + .number("(dddd)(dd)(dd)") // date + .number("(dd)(dd)(dd)").optional(2) // time + .text(",") + .any() + .number("(xxxx)") // count number + .text("$").optional() .compile(); - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + /*private static final Pattern PATTERN = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF)").text(":") + .expression("GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}),") // imei + .expression("[^,]*,") // device name + .number("d,") // report id + .number("d,") // report type + .number("d{1,2},") // report number - String sentence = (String) msg; + .number("(d{1,2})?,") // gps accuracy + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6})?,") // longitude + .number("(-?d{1,2}.d{6})?,") // latitude + .number("(dddd)(dd)(dd)") // date + .number("(dd)(dd)(dd)").optional(2) // time + .text(",") - Parser parser = new Parser(PATTERN_HEARTBEAT, sentence); - if (parser.matches()) { - if (channel != null) { - channel.write("+SACK:GTHBD," + parser.next() + "," + parser.next() + "$", remoteAddress); - } + .number("(0ddd)?,") // mcc + .number("(0ddd)?,") // mnc + .number("(xxxx)?,") // lac + .number("(xxxx)?,") // cell + .number("d*,") // reserved + + .number("(d{1,3})?,") // battery + .number("(dddd)(dd)(dd)") // date + .number("(dd)(dd)(dd)").optional(2) // time + .text(",") + .number("(xxxx)") // count number + + .text("$").optional() + .compile();*/ + + private Position decodeHbd(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_HBD, sentence); + if (parser.matches() && channel != null) { + channel.write("+SACK:GTHBD," + parser.next() + "," + parser.next() + "$", remoteAddress); + } + return null; + } + + private Position decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_INF, sentence); + if (!parser.matches()) { return null; } - parser = new Parser(PATTERN_INF, sentence); - if (parser.matches()) { + Position position = new Position(); + position.setProtocol(getProtocolName()); + + if (!identify(parser.next(), channel, remoteAddress)) { + return null; + } + position.setDeviceId(getDeviceId()); - Position position = new Position(); - position.setProtocol(getProtocolName()); + position.set(Event.KEY_STATUS, parser.next()); + position.set(Event.KEY_POWER, parser.next()); + position.set(Event.KEY_BATTERY, parser.next()); + position.set(Event.KEY_CHARGE, parser.next()); - if (!identify(parser.next(), channel, remoteAddress)) { - return null; - } - position.setDeviceId(getDeviceId()); + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.set(Event.KEY_STATUS, parser.next()); - position.set(Event.KEY_POWER, parser.next()); - position.set(Event.KEY_BATTERY, parser.next()); - position.set(Event.KEY_CHARGE, parser.next()); + getLastLocation(position, dateBuilder.getDate()); - DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.set(Event.KEY_INDEX, parser.next()); + + return position; + } + + private Position decodeOther(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_BACKUP, sentence); + if (!parser.matches()) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + if (!identify(parser.next(), channel, remoteAddress)) { + return null; + } + position.setDeviceId(getDeviceId()); - getLastLocation(position, dateBuilder.getDate()); + position.setValid(true); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + position.setAltitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); - position.set(Event.KEY_INDEX, parser.next()); + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); - return position; + if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { + channel.write("+SACK:" + parser.next() + "$", remoteAddress); } - parser = new Parser(PATTERN, sentence); + return position; + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + + int typeIndex = sentence.indexOf(":GT"); + if (typeIndex < 0) { + return null; + } + + switch (sentence.substring(typeIndex + 3, typeIndex + 6)) { + case "HBD": + return decodeHbd(channel, remoteAddress, sentence); + case "INF": + return decodeInf(channel, remoteAddress, sentence); + default: + return decodeOther(channel, remoteAddress, sentence); + } + + /*parser = new Parser(PATTERN, sentence); if (!parser.matches()) { return null; } @@ -238,9 +343,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { channel.write("+SACK:" + parser.next() + "$", remoteAddress); - } - - return position; + }*/ } } diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java index 0977b7fc1..58b166707 100644 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java @@ -13,7 +13,7 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "+RESP:GTFRI,110100,A5868800000015,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214013254,000C")); - verifyNothing(decoder, text( + verifyPosition(decoder, text( "+RESP:GTFRI,210102,A10000458356CE,,0,1,1,15,1.4,0,190.6,-85.765763,42.894896,20160208164505,4126,210,0,18673,00,92,20160208164507,00A6")); verifyPosition(decoder, text( @@ -25,7 +25,7 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, text( "+RESP:GTINF,1F0101,135790246811220,1G1JC5444R7252367,,16,898600810906F8048812,16,0,1,12000,,4.2,0,0,,,20090214013254,,,,,,+0800,0,20090214093254,11F0$")); - verifyAttributes(decoder, text( + verifyNothing(decoder, text( "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$")); verifyPosition(decoder, text( @@ -78,40 +78,13 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "+RESP:GTFRI,07000D,868487001005941,,0,0,1,1,0.0,0,46.3,-77.039627,38.907573,20120731175232,0310,0260,B44B,EBC9,0015e96913a7,-58,,100,20120731175244,0114")); - - verifyPosition(decoder, text( - "+RESP:GTTOW,0F0100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTDIS,0F0100,135790246811220,,,20,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTIOB,0F0100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTGEO,0F0100,135790246811220,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTSPD,0F0100,135790246811220,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTSOS,0F0100,135790246811220,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTRTL,0F0100,135790246811220,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTDOG,0F0100,135790246811220,,,01,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTIGL,0F0100,135790246811220,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); verifyPosition(decoder, text( "+RESP:GTHBM,0F0100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); verifyPosition(decoder, text( "+RESP:GTHBM,0F0100,135790246811220,,,11,1,1,24.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - + verifyPosition(decoder, text( "+RESP:GTFRI,02010C,867844001274144,,0,0,1,1,18.0,233,118.1,7.615551,51.515600,20140106130516,0262,0007,79E6,B956,,72,20140106140524,09CE$")); -- cgit v1.2.3 From 94c5e012a9d0f9c3079cf5c012367722841f5415 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Feb 2016 16:16:25 +1300 Subject: Implement specific GL200 messages --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 263 +++++++++++---------- .../traccar/protocol/Gl200ProtocolDecoderTest.java | 2 +- 2 files changed, 138 insertions(+), 127 deletions(-) diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index bb6acb1ef..6731ef00d 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -69,38 +69,32 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); - /*private static final Pattern PATTERN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF)").text(":") - .expression("GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .expression("([^,]+),") // imei - - .groupBegin() - .expression("[0-9A-Z]{17},") // vin + private static final Pattern PATTERN_OBD = new PatternBuilder() + .text("+RESP:GTOBD,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}),") // imei + .expression("(?:[0-9A-Z]{17})?,") // vin .expression("[^,]{0,20},") // device name .expression("[01],") // report type .number("x{1,8},") // report mask - .expression("[0-9A-Z]{17},") // vin + .expression("(?:[0-9A-Z]{17})?,") // vin .number("[01],") // obd connect - .number("d{1,5},") // obd voltage - .number("x{8},") // support pids - .number("(d{1,5}),") // engine rpm - .number("(d{1,3}),") // speed - .number("(-?d{1,3}),") // coolant temp + .number("(?:d{1,5})?,") // obd voltage + .number("(?:x{8})?,") // support pids + .number("(d{1,5})?,") // engine rpm + .number("(d{1,3})?,") // speed + .number("(-?d{1,3})?,") // coolant temp .number("(d+.?d*|Inf|NaN)?,") // fuel consumption - .number("(d{1,5}),") // dtcs cleared distance - .number("d{1,5},") - .expression("([01]),") // obd connect - .number("(d{1,3}),") // number of dtcs + .number("(d{1,5})?,") // dtcs cleared distance + .number("(?:d{1,5})?,") + .expression("([01])?,") // obd connect + .number("(d{1,3})?,") // number of dtcs .number("(x*),") // dtcs - .number("(d{1,3}),") // throttle - .number("d{1,3},") // engine load + .number("(d{1,3})?,") // throttle + .number("(?:d{1,3})?,") // engine load .number("(d{1,3})?,") // fuel level - .number("(d+)") // odometer - .or().any() - .groupEnd().text(",") - - .number("(d{1,2})?,") // gps accuracy + .number("(d+),") // odometer + .number("(?:d{1,2})?,") // gps accuracy .number("(d{1,3}.d)?,") // speed .number("(d{1,3})?,") // course .number("(-?d{1,5}.d)?,") // altitude @@ -111,45 +105,18 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .text(",") .number("(0ddd)?,") // mcc .number("(0ddd)?,") // mnc - .number("(?:xxxx)?") - .number("(xxxx)").optional(2) // lac - .text(",") + .number("(xxxx)?,") // lac .number("(xxxx)?,") // cell - .groupBegin() - .number("(d+.d)?,") // odometer - .number("(d{1,3})?,") // battery - .groupEnd("?") - .groupBegin() - .any() - .number("(dddd)(dd)(dd)") // date - .number("(dd)(dd)(dd)") // time - .or() - .any() - .groupEnd() - .number(",(xxxx)") - .text("$").optional() - .compile();*/ - - private static final Pattern PATTERN_BACKUP = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF)").text(":") - .expression("GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .any() - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6}),") // longitude - .number("(-?d{1,2}.d{6}),") // latitude + .number("d*,") // reserved + .number("(d{1,7}.d)?,") // odometer .number("(dddd)(dd)(dd)") // date .number("(dd)(dd)(dd)").optional(2) // time .text(",") - .any() .number("(xxxx)") // count number .text("$").optional() .compile(); - /*private static final Pattern PATTERN = new PatternBuilder() + private static final Pattern PATTERN = new PatternBuilder() .text("+").expression("(?:RESP|BUFF)").text(":") .expression("GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version @@ -158,8 +125,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("d,") // report id .number("d,") // report type .number("d{1,2},") // report number - - .number("(d{1,2})?,") // gps accuracy + .number("(?:d{1,2})?,") // gps accuracy .number("(d{1,3}.d)?,") // speed .number("(d{1,3})?,") // course .number("(-?d{1,5}.d)?,") // altitude @@ -168,21 +134,37 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("(dddd)(dd)(dd)") // date .number("(dd)(dd)(dd)").optional(2) // time .text(",") - .number("(0ddd)?,") // mcc .number("(0ddd)?,") // mnc .number("(xxxx)?,") // lac .number("(xxxx)?,") // cell .number("d*,") // reserved - .number("(d{1,3})?,") // battery .number("(dddd)(dd)(dd)") // date .number("(dd)(dd)(dd)").optional(2) // time .text(",") .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private static final Pattern PATTERN_BACKUP = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF)").text(":") + .expression("GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .any() + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6}),") // longitude + .number("(-?d{1,2}.d{6}),") // latitude + .number("(dddd)(dd)(dd)") // date + .number("(dd)(dd)(dd)") // time + .text(",") + .any() + .number("(xxxx)") // count number .text("$").optional() - .compile();*/ + .compile(); private Position decodeHbd(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_HBD, sentence); @@ -222,60 +204,11 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return position; } - private Position decodeOther(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_BACKUP, sentence); - if (!parser.matches()) { - return null; - } - - Position position = new Position(); - position.setProtocol(getProtocolName()); - - if (!identify(parser.next(), channel, remoteAddress)) { - return null; - } - position.setDeviceId(getDeviceId()); - - position.setValid(true); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - position.setAltitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - position.setLatitude(parser.nextDouble()); + private Position decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { - DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); + String x = PatternUtil.checkPattern(PATTERN_OBD.pattern(), sentence); - if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { - channel.write("+SACK:" + parser.next() + "$", remoteAddress); - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - int typeIndex = sentence.indexOf(":GT"); - if (typeIndex < 0) { - return null; - } - - switch (sentence.substring(typeIndex + 3, typeIndex + 6)) { - case "HBD": - return decodeHbd(channel, remoteAddress, sentence); - case "INF": - return decodeInf(channel, remoteAddress, sentence); - default: - return decodeOther(channel, remoteAddress, sentence); - } - - /*parser = new Parser(PATTERN, sentence); + Parser parser = new Parser(PATTERN_OBD, sentence); if (!parser.matches()) { return null; } @@ -288,12 +221,6 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { } position.setDeviceId(getDeviceId()); - // RFID - if (sentence.startsWith("+RESP:GTIDA")) { - position.set(Event.KEY_RFID, sentence.split(",")[5]); - } - - // OBD position.set(Event.KEY_RPM, parser.next()); position.set(Event.KEY_OBD_SPEED, parser.next()); position.set(Event.PREFIX_TEMP + 1, parser.next()); @@ -306,11 +233,12 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { position.set(Event.KEY_FUEL, parser.next()); position.set(Event.KEY_OBD_ODOMETER, parser.next()); - if (parser.hasNext(12)) { - position.setValid(parser.nextInt() < 20); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - position.setAltitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + position.setAltitude(parser.nextDouble()); + + if (parser.hasNext(8)) { + position.setValid(true); position.setLongitude(parser.nextDouble()); position.setLatitude(parser.nextDouble()); @@ -330,7 +258,6 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { } position.set(Event.KEY_ODOMETER, parser.next()); - position.set(Event.KEY_BATTERY, parser.next()); if (parser.hasNext(6)) { DateBuilder dateBuilder = new DateBuilder() @@ -341,9 +268,93 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { } } + return position; + } + + private Position decodeOther(Channel channel, SocketAddress remoteAddress, String sentence) { + Pattern pattern = PATTERN; + Parser parser = new Parser(pattern, sentence); + if (!parser.matches()) { + pattern = PATTERN_BACKUP; + parser = new Parser(pattern, sentence); + if (!parser.matches()) { + return null; + } + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + if (!identify(parser.next(), channel, remoteAddress)) { + return null; + } + position.setDeviceId(getDeviceId()); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + position.setAltitude(parser.nextDouble()); + + if (parser.hasNext(8)) { + position.setValid(true); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + } else { + getLastLocation(position, null); + } + + if (pattern == PATTERN) { + if (parser.hasNext(4)) { + position.set(Event.KEY_MCC, parser.nextInt()); + position.set(Event.KEY_MNC, parser.nextInt()); + position.set(Event.KEY_LAC, parser.nextInt(16)); + position.set(Event.KEY_CID, parser.nextInt(16)); + } + + position.set(Event.KEY_BATTERY, parser.next()); + + if (parser.hasNext(6)) { + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + if (!position.getOutdated() && position.getFixTime().after(dateBuilder.getDate())) { + position.setTime(dateBuilder.getDate()); + } + } + } + if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { channel.write("+SACK:" + parser.next() + "$", remoteAddress); - }*/ + } + + return position; + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + + int typeIndex = sentence.indexOf(":GT"); + if (typeIndex < 0) { + return null; + } + + switch (sentence.substring(typeIndex + 3, typeIndex + 6)) { + case "HBD": + return decodeHbd(channel, remoteAddress, sentence); + case "INF": + return decodeInf(channel, remoteAddress, sentence); + case "OBD": + return decodeObd(channel, remoteAddress, sentence); + default: + return decodeOther(channel, remoteAddress, sentence); + } } } diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java index 58b166707..7a88ff5f5 100644 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java @@ -25,7 +25,7 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, text( "+RESP:GTINF,1F0101,135790246811220,1G1JC5444R7252367,,16,898600810906F8048812,16,0,1,12000,,4.2,0,0,,,20090214013254,,,,,,+0800,0,20090214093254,11F0$")); - verifyNothing(decoder, text( + verifyAttributes(decoder, text( "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$")); verifyPosition(decoder, text( -- cgit v1.2.3 From ea63ff71484f23d4246476cfae6705db551529d6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Feb 2016 16:27:21 +1300 Subject: Remove pattern debugging code --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 6731ef00d..fd0961665 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -23,7 +23,6 @@ import org.traccar.Context; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; -import org.traccar.helper.PatternUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Event; import org.traccar.model.Position; @@ -206,8 +205,6 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { private Position decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { - String x = PatternUtil.checkPattern(PATTERN_OBD.pattern(), sentence); - Parser parser = new Parser(PATTERN_OBD, sentence); if (!parser.matches()) { return null; -- cgit v1.2.3 From 8436dd58c37545973803dd292d36aaad3c2fdc70 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Feb 2016 17:00:41 +1300 Subject: Share GL200 location decoding code --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 197 +++++++++++---------- 1 file changed, 102 insertions(+), 95 deletions(-) diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index fd0961665..ef8cf34e4 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -17,6 +17,7 @@ package org.traccar.protocol; import java.net.SocketAddress; import java.util.regex.Pattern; + import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; @@ -68,6 +69,23 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); + private static final Pattern PATTERN_LOCATION = new PatternBuilder() + .number("(?:d{1,2})?,") // gps accuracy + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6})?,") // longitude + .number("(-?d{1,2}.d{6})?,") // latitude + .number("(dddd)(dd)(dd)") // date + .number("(dd)(dd)(dd)").optional(2) // time + .text(",") + .number("(0ddd)?,") // mcc + .number("(0ddd)?,") // mnc + .number("(xxxx)?,") // lac + .number("(xxxx)?,") // cell + .number("d*,") // reserved + .compile(); + private static final Pattern PATTERN_OBD = new PatternBuilder() .text("+RESP:GTOBD,") .number("[0-9A-Z]{2}xxxx,") // protocol version @@ -93,20 +111,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("(?:d{1,3})?,") // engine load .number("(d{1,3})?,") // fuel level .number("(d+),") // odometer - .number("(?:d{1,2})?,") // gps accuracy - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date - .number("(dd)(dd)(dd)").optional(2) // time - .text(",") - .number("(0ddd)?,") // mcc - .number("(0ddd)?,") // mnc - .number("(xxxx)?,") // lac - .number("(xxxx)?,") // cell - .number("d*,") // reserved + .expression(PATTERN_LOCATION.pattern()) .number("(d{1,7}.d)?,") // odometer .number("(dddd)(dd)(dd)") // date .number("(dd)(dd)(dd)").optional(2) // time @@ -123,21 +128,8 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .expression("[^,]*,") // device name .number("d,") // report id .number("d,") // report type - .number("d{1,2},") // report number - .number("(?:d{1,2})?,") // gps accuracy - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date - .number("(dd)(dd)(dd)").optional(2) // time - .text(",") - .number("(0ddd)?,") // mcc - .number("(0ddd)?,") // mnc - .number("(xxxx)?,") // lac - .number("(xxxx)?,") // cell - .number("d*,") // reserved + .number("d{1,2},") // count + .expression(PATTERN_LOCATION.pattern()) .number("(d{1,3})?,") // battery .number("(dddd)(dd)(dd)") // date .number("(dd)(dd)(dd)").optional(2) // time @@ -165,7 +157,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); - private Position decodeHbd(Channel channel, SocketAddress remoteAddress, String sentence) { + private Object decodeHbd(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_HBD, sentence); if (parser.matches() && channel != null) { channel.write("+SACK:GTHBD," + parser.next() + "," + parser.next() + "$", remoteAddress); @@ -173,7 +165,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return null; } - private Position decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { + private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_INF, sentence); if (!parser.matches()) { return null; @@ -203,8 +195,33 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return position; } - private Position decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { + private void decodeLocation(Position position, Parser parser) { + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + position.setAltitude(parser.nextDouble()); + + if (parser.hasNext(8)) { + position.setValid(true); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + } else { + getLastLocation(position, null); + } + + if (parser.hasNext(4)) { + position.set(Event.KEY_MCC, parser.nextInt()); + position.set(Event.KEY_MNC, parser.nextInt()); + position.set(Event.KEY_LAC, parser.nextInt(16)); + position.set(Event.KEY_CID, parser.nextInt(16)); + } + } + private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN_OBD, sentence); if (!parser.matches()) { return null; @@ -230,29 +247,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { position.set(Event.KEY_FUEL, parser.next()); position.set(Event.KEY_OBD_ODOMETER, parser.next()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - position.setAltitude(parser.nextDouble()); - - if (parser.hasNext(8)) { - position.setValid(true); - position.setLongitude(parser.nextDouble()); - position.setLatitude(parser.nextDouble()); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - } else { - getLastLocation(position, null); - } - - if (parser.hasNext(4)) { - position.set(Event.KEY_MCC, parser.nextInt()); - position.set(Event.KEY_MNC, parser.nextInt()); - position.set(Event.KEY_LAC, parser.nextInt(16)); - position.set(Event.KEY_CID, parser.nextInt(16)); - } + decodeLocation(position, parser); position.set(Event.KEY_ODOMETER, parser.next()); @@ -268,15 +263,10 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return position; } - private Position decodeOther(Channel channel, SocketAddress remoteAddress, String sentence) { - Pattern pattern = PATTERN; - Parser parser = new Parser(pattern, sentence); + private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { - pattern = PATTERN_BACKUP; - parser = new Parser(pattern, sentence); - if (!parser.matches()) { - return null; - } + return null; } Position position = new Position(); @@ -287,46 +277,52 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { } position.setDeviceId(getDeviceId()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - position.setCourse(parser.nextDouble()); - position.setAltitude(parser.nextDouble()); + decodeLocation(position, parser); - if (parser.hasNext(8)) { - position.setValid(true); - position.setLongitude(parser.nextDouble()); - position.setLatitude(parser.nextDouble()); + position.set(Event.KEY_BATTERY, parser.next()); + if (parser.hasNext(6)) { DateBuilder dateBuilder = new DateBuilder() .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - } else { - getLastLocation(position, null); + if (!position.getOutdated() && position.getFixTime().after(dateBuilder.getDate())) { + position.setTime(dateBuilder.getDate()); + } } - if (pattern == PATTERN) { - if (parser.hasNext(4)) { - position.set(Event.KEY_MCC, parser.nextInt()); - position.set(Event.KEY_MNC, parser.nextInt()); - position.set(Event.KEY_LAC, parser.nextInt(16)); - position.set(Event.KEY_CID, parser.nextInt(16)); - } + if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { + channel.write("+SACK:" + parser.next() + "$", remoteAddress); + } - position.set(Event.KEY_BATTERY, parser.next()); + return position; + } - if (parser.hasNext(6)) { - DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); - if (!position.getOutdated() && position.getFixTime().after(dateBuilder.getDate())) { - position.setTime(dateBuilder.getDate()); - } - } + private Object decodeBackup(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_BACKUP, sentence); + if (!parser.matches()) { + return null; } - if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { - channel.write("+SACK:" + parser.next() + "$", remoteAddress); + Position position = new Position(); + position.setProtocol(getProtocolName()); + + if (!identify(parser.next(), channel, remoteAddress)) { + return null; } + position.setDeviceId(getDeviceId()); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + position.setAltitude(parser.nextDouble()); + + position.setValid(true); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); return position; } @@ -342,16 +338,27 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return null; } + Object result; switch (sentence.substring(typeIndex + 3, typeIndex + 6)) { case "HBD": - return decodeHbd(channel, remoteAddress, sentence); + result = decodeHbd(channel, remoteAddress, sentence); + break; case "INF": - return decodeInf(channel, remoteAddress, sentence); + result = decodeInf(channel, remoteAddress, sentence); + break; case "OBD": - return decodeObd(channel, remoteAddress, sentence); + result = decodeObd(channel, remoteAddress, sentence); + break; default: - return decodeOther(channel, remoteAddress, sentence); + result = decodeOther(channel, remoteAddress, sentence); + break; + } + + if (result == null) { + result = decodeBackup(channel, remoteAddress, sentence); } + + return result; } } -- cgit v1.2.3 From 7118504798b62b4f0c0186a19e8417463d653383 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Feb 2016 23:08:29 +1300 Subject: Decode battery for Telic (fix #1735) --- src/org/traccar/protocol/TelicProtocolDecoder.java | 3 +++ test/org/traccar/protocol/TelicProtocolDecoderTest.java | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java index 3ba81de6e..6e6e94325 100644 --- a/src/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/org/traccar/protocol/TelicProtocolDecoder.java @@ -50,6 +50,8 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // speed .number("(d+),") // course .number("(d+),") // satellites + .expression("(?:[^,]*,){7}") + .number("(d+),") .any() .compile(); @@ -92,6 +94,7 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { position.setCourse(parser.nextDouble()); position.set(Event.KEY_SATELLITES, parser.next()); + position.set(Event.KEY_BATTERY, parser.nextInt()); return position; } diff --git a/test/org/traccar/protocol/TelicProtocolDecoderTest.java b/test/org/traccar/protocol/TelicProtocolDecoderTest.java index 62a80c94f..a0d9febad 100644 --- a/test/org/traccar/protocol/TelicProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -11,14 +11,23 @@ public class TelicProtocolDecoderTest extends ProtocolTest { TelicProtocolDecoder decoder = new TelicProtocolDecoder(new TelicProtocol()); verifyPosition(decoder, text( - "002017297899,190216202500,0,190216202459,014221890,46492170,3,0,0,6,,,1034,43841,,0000,00,0,209,0,0407\u0000")); + "003097061325,210216112630,0,210216001405,246985,594078,3,0,283,12,,,23,4418669,,0010,00,117,0,0,0108")); + + verifyNothing(decoder, text( + "0026970613|248|01|004006011")); + + verifyPosition(decoder, text( + "032097061399,210216112800,0,210216112759,246912,594076,3,47,291,10,,,46,4419290,,0010,00,100,0,0,0108")); + + verifyPosition(decoder, text( + "002017297899,190216202500,0,190216202459,014221890,46492170,3,0,0,6,,,1034,43841,,0000,00,0,209,0,0407")); verifyPosition(decoder, text( - "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7\u0000"), + "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7"), position("2013-06-27 04:16:52.000", true, 47.53410, 16.66530)); verifyPosition(decoder, text( - "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7\u0000")); + "182043672999,010100001301,0,270613041652,166653,475341,3,0,355,6,2,1,231,8112432,23201,01,00,217,0,0,0,0,7")); } -- cgit v1.2.3 From 993ac257133211953eb8c8d862c133f2d12de274 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 23 Feb 2016 10:37:33 +1300 Subject: Fix Telic problem with latitude value --- src/org/traccar/protocol/TelicProtocolDecoder.java | 2 +- test/org/traccar/protocol/TelicProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java index 6e6e94325..ba6d9c47e 100644 --- a/src/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/org/traccar/protocol/TelicProtocolDecoder.java @@ -81,7 +81,7 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext(6)) { position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN)); } if (parser.hasNext(2)) { diff --git a/test/org/traccar/protocol/TelicProtocolDecoderTest.java b/test/org/traccar/protocol/TelicProtocolDecoderTest.java index a0d9febad..a922c390d 100644 --- a/test/org/traccar/protocol/TelicProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TelicProtocolDecoderTest extends ProtocolTest { TelicProtocolDecoder decoder = new TelicProtocolDecoder(new TelicProtocol()); + verifyPosition(decoder, text( + "002017297899,220216111100,0,220216111059,014306446,46626713,3,7,137,7,,,448,266643,,0000,00,0,206,0,0407")); + verifyPosition(decoder, text( "003097061325,210216112630,0,210216001405,246985,594078,3,0,283,12,,,23,4418669,,0010,00,117,0,0,0108")); -- cgit v1.2.3 From 3daa5ad1e59a9da74dfb8efce698c754e141f6bf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 23 Feb 2016 15:37:46 +1300 Subject: Support another GL200 message type --- src/org/traccar/helper/Parser.java | 4 ++ src/org/traccar/protocol/Gl200ProtocolDecoder.java | 79 ++++++++++++++++++++-- .../traccar/protocol/Gl200ProtocolDecoderTest.java | 20 +++--- 3 files changed, 87 insertions(+), 16 deletions(-) diff --git a/src/org/traccar/helper/Parser.java b/src/org/traccar/helper/Parser.java index a3f118df0..73713c51c 100644 --- a/src/org/traccar/helper/Parser.java +++ b/src/org/traccar/helper/Parser.java @@ -37,6 +37,10 @@ public class Parser { return matcher.find(); } + public void skip(int number) { + position += number; + } + public boolean hasNext() { return hasNext(1); } diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index ef8cf34e4..c6881d035 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -16,6 +16,8 @@ package org.traccar.protocol; import java.net.SocketAddress; +import java.util.LinkedList; +import java.util.List; import java.util.regex.Pattern; import org.jboss.netty.channel.Channel; @@ -24,6 +26,7 @@ import org.traccar.Context; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; +import org.traccar.helper.PatternUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Event; import org.traccar.model.Position; @@ -120,17 +123,49 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); + private static final Pattern PATTERN_FRI = new PatternBuilder() + .text("+RESP:GTFRI,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}),") // imei + .expression("[^,]*,") // device name + .number("d?,") + .number("d{1,2},") // report type + .number("d{1,2},") // count + .expression("(") + .expression(PATTERN_LOCATION.pattern()) + .expression(")+") + .groupBegin() + .number("(d{1,3})?,") // battery + .or() + .number("(d{1,7}.d)?,") // odometer + .number("d{5}:dd:dd,") // hour meter + .number("(x+)?,") // adc 1 + .number("(x+)?,") // adc 2 + .number("(d{1,3})?,") // battery + .number("(d{6})?,,,,") // device status + .groupEnd() + .number("(dddd)(dd)(dd)") // date + .number("(dd)(dd)(dd)").optional(2) // time + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + private static final Pattern PATTERN = new PatternBuilder() .text("+").expression("(?:RESP|BUFF)").text(":") .expression("GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version .number("(d{15}),") // imei .expression("[^,]*,") // device name - .number("d,") // report id - .number("d,") // report type + .number("d?,") + .number("d{1,2},") // report type .number("d{1,2},") // count .expression(PATTERN_LOCATION.pattern()) + .groupBegin() .number("(d{1,3})?,") // battery + .or() + .number("(d{1,7}.d)?,") // odometer + .groupEnd() .number("(dddd)(dd)(dd)") // date .number("(dd)(dd)(dd)").optional(2) // time .text(",") @@ -138,7 +173,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); - private static final Pattern PATTERN_BACKUP = new PatternBuilder() + private static final Pattern PATTERN_BASIC = new PatternBuilder() .text("+").expression("(?:RESP|BUFF)").text(":") .expression("GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version @@ -263,6 +298,34 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodeFri(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_FRI, sentence); + if (!parser.matches()) { + return null; + } + + List positions = new LinkedList<>(); + + if (!identify(parser.next(), channel, remoteAddress)) { + return null; + } + + Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); + while (itemParser.find()) { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(getDeviceId()); + + decodeLocation(position, itemParser); + + positions.add(position); + } + + parser.skip(15); + + return positions; + } + private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence) { Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { @@ -280,6 +343,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); position.set(Event.KEY_BATTERY, parser.next()); + position.set(Event.KEY_ODOMETER, parser.next()); if (parser.hasNext(6)) { DateBuilder dateBuilder = new DateBuilder() @@ -297,8 +361,8 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return position; } - private Object decodeBackup(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_BACKUP, sentence); + private Object decodeBasic(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_BASIC, sentence); if (!parser.matches()) { return null; } @@ -349,13 +413,16 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { case "OBD": result = decodeObd(channel, remoteAddress, sentence); break; + case "FRI": + result = decodeFri(channel, remoteAddress, sentence); + break; default: result = decodeOther(channel, remoteAddress, sentence); break; } if (result == null) { - result = decodeBackup(channel, remoteAddress, sentence); + result = decodeBasic(channel, remoteAddress, sentence); } return result; diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java index 7a88ff5f5..f906217fe 100644 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java @@ -25,8 +25,8 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, text( "+RESP:GTINF,1F0101,135790246811220,1G1JC5444R7252367,,16,898600810906F8048812,16,0,1,12000,,4.2,0,0,,,20090214013254,,,,,,+0800,0,20090214093254,11F0$")); - verifyAttributes(decoder, text( - "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$")); + /*verifyAttributes(decoder, text( + "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$"));*/ verifyPosition(decoder, text( "+RESP:GTFRI,0F0106,862193020451183,,,10,1,1,0.0,163,,-57.513617,-25.368191,20150918182145,,,,,,21235.0,,,,0,210100,,,,20150918182149,00B8$")); @@ -40,13 +40,13 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "+RESP:GTSTT,1A0401,860599000508846,,41,0,0.0,84,107.5,-76.657998,39.497203,20150623160622,0310,0260,B435,3B81,,20150623160622,0F54$")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,1A0401,860599000508846,,0,0,1,1,134.8,154,278.7,-76.671089,39.778885,20150623154301,0310,0260,043F,7761,,99,20150623154314,0F24$")); verifyPosition(decoder, text( "+RESP:GTFRI,1A0200,860599000165464,CRI001,0,0,1,2,,41,,-71.153137,42.301634,20150328020301,,,,,280.3,55,20150327220351,320C")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,02010D,867844001675407,,0,0,1,2,0.0,0,28.9,8.591011,56.476397,20140915213209,0238,0001,03CB,2871,,97,20140915213459,009A")); verifyNothing(decoder, text( @@ -58,13 +58,13 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "+RESP:GTSTT,04040C,359231038939904,,42,0,0.0,117,346.0,8.924243,50.798077,20130618125152,0262,0002,0299,109C,00,20130618125154,017A")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,020102,000035988863964,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,020102,135790246811220,,0,0,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,,20090214093254,11F0")); verifyPosition(decoder, text( @@ -85,16 +85,16 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "+RESP:GTHBM,0F0100,135790246811220,,,11,1,1,24.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,02010C,867844001274144,,0,0,1,1,18.0,233,118.1,7.615551,51.515600,20140106130516,0262,0007,79E6,B956,,72,20140106140524,09CE$")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,02010C,867844001274649,,0,0,1,1,0.0,0,122.5,7.684216,51.524512,20140106233722,0262,0007,79EE,1D22,,93,20140107003805,03C4$")); verifyPosition(decoder, text( "+BUFF:GTFRI,210101,863286020016706,,,10,1,1,,,,49.903915,40.391669,20140818105815,,,,,,,,,,,210100,,,,,000C$")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,240100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,80,,,,,,20090214093254,11F0$")); verifyPosition(decoder, text( -- cgit v1.2.3 From 5741cd0fdbddb623f1807463d9a8d26cf5cc8f4d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Feb 2016 00:22:20 +1300 Subject: Finish new GL200 decoder implementation --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 33 +++++++++++++++++----- .../traccar/protocol/Gl200ProtocolDecoderTest.java | 15 ++++++---- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index c6881d035..9098cbd8c 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -82,10 +82,17 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("(dddd)(dd)(dd)") // date .number("(dd)(dd)(dd)").optional(2) // time .text(",") + .groupBegin() .number("(0ddd)?,") // mcc .number("(0ddd)?,") // mnc .number("(xxxx)?,") // lac .number("(xxxx)?,") // cell + .or() + .number("(d+)?,") // mcc + .number("(d+)?,") // mnc + .number("(d+)?,") // lac + .number("(d+)?,") // cell + .groupEnd() .number("d*,") // reserved .compile(); @@ -126,14 +133,14 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN_FRI = new PatternBuilder() .text("+RESP:GTFRI,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}),") // imei + .number("(d{15}|x{14}),") // imei .expression("[^,]*,") // device name - .number("d?,") + .number("d*,") .number("d{1,2},") // report type .number("d{1,2},") // count - .expression("(") + .expression("((?:") .expression(PATTERN_LOCATION.pattern()) - .expression(")+") + .expression(")+)") .groupBegin() .number("(d{1,3})?,") // battery .or() @@ -157,7 +164,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version .number("(d{15}),") // imei .expression("[^,]*,") // device name - .number("d?,") + .number("d*,") .number("d{1,2},") // report type .number("d{1,2},") // count .expression(PATTERN_LOCATION.pattern()) @@ -254,6 +261,8 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { position.set(Event.KEY_LAC, parser.nextInt(16)); position.set(Event.KEY_CID, parser.nextInt(16)); } + + parser.skip(4); // alternative networks } private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { @@ -304,7 +313,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return null; } - List positions = new LinkedList<>(); + LinkedList positions = new LinkedList<>(); if (!identify(parser.next(), channel, remoteAddress)) { return null; @@ -321,7 +330,17 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } - parser.skip(15); + Position position = positions.getLast(); + + decodeLocation(position, parser); + + position.set(Event.KEY_BATTERY, parser.next()); + + position.set(Event.KEY_ODOMETER, parser.next()); + position.set(Event.PREFIX_ADC + 1, parser.next()); + position.set(Event.PREFIX_ADC + 2, parser.next()); + position.set(Event.KEY_BATTERY, parser.next()); + position.set(Event.KEY_STATUS, parser.next()); return positions; } diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java index f906217fe..4e7686da7 100644 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java @@ -10,10 +10,13 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { Gl200ProtocolDecoder decoder = new Gl200ProtocolDecoder(new Gl200Protocol()); - verifyPosition(decoder, text( + verifyPositions(decoder, text( + "+RESP:GTFRI,060228,862894020178276,,15153,10,1,1,0.0,0,431.7,-63.169571,-17.776235,20160210153458,0736,0003,6AD4,80EF,00,34.9,00117:31:26,13442,15163,0,210101,,,,20160210113503,38EE$")); + + verifyPositions(decoder, text( "+RESP:GTFRI,110100,A5868800000015,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214013254,000C")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,210102,A10000458356CE,,0,1,1,15,1.4,0,190.6,-85.765763,42.894896,20160208164505,4126,210,0,18673,00,92,20160208164507,00A6")); verifyPosition(decoder, text( @@ -25,8 +28,8 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, text( "+RESP:GTINF,1F0101,135790246811220,1G1JC5444R7252367,,16,898600810906F8048812,16,0,1,12000,,4.2,0,0,,,20090214013254,,,,,,+0800,0,20090214093254,11F0$")); - /*verifyAttributes(decoder, text( - "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$"));*/ + verifyPositions(decoder, false, text( + "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$")); verifyPosition(decoder, text( "+RESP:GTFRI,0F0106,862193020451183,,,10,1,1,0.0,163,,-57.513617,-25.368191,20150918182145,,,,,,21235.0,,,,0,210100,,,,20150918182149,00B8$")); @@ -97,8 +100,8 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, text( "+RESP:GTFRI,240100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,80,,,,,,20090214093254,11F0$")); - verifyPosition(decoder, text( - "+RESP:GTFRI,240100,135790246811220,,,10,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,,,,,,20090214093254,11F0$")); + verifyPositions(decoder, text( + "+RESP:GTFRI,240100,135790246811220,,,10,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,,,,,20090214093254,11F0$")); verifyPosition(decoder, text( "+RESP:GTSTT,280100,A1000043D20139,,42,0,0.1,321,228.6,-76.660884,39.832552,20150615120628,0310,0484,00600019,0A52,,20150615085741,0320$")); -- cgit v1.2.3 From debe7092f6d48abc51852b808f45144863baebde Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Feb 2016 00:33:02 +1300 Subject: Add another GL200 decoder test case --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 5 +++++ test/org/traccar/protocol/Gl200ProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 9098cbd8c..62d93ce13 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -142,6 +142,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .expression(PATTERN_LOCATION.pattern()) .expression(")+)") .groupBegin() + .number("(d{1,7}.d)?,").optional() // odometer .number("(d{1,3})?,") // battery .or() .number("(d{1,7}.d)?,") // odometer @@ -169,6 +170,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("d{1,2},") // count .expression(PATTERN_LOCATION.pattern()) .groupBegin() + .number("(d{1,7}.d)?,").optional() // odometer .number("(d{1,3})?,") // battery .or() .number("(d{1,7}.d)?,") // odometer @@ -334,6 +336,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); + position.set(Event.KEY_ODOMETER, parser.next()); position.set(Event.KEY_BATTERY, parser.next()); position.set(Event.KEY_ODOMETER, parser.next()); @@ -361,7 +364,9 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); + position.set(Event.KEY_ODOMETER, parser.next()); position.set(Event.KEY_BATTERY, parser.next()); + position.set(Event.KEY_ODOMETER, parser.next()); if (parser.hasNext(6)) { diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java index 4e7686da7..11c069adb 100644 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { Gl200ProtocolDecoder decoder = new Gl200ProtocolDecoder(new Gl200Protocol()); + verifyPosition(decoder, text( + "+RESP:GTFRI,2C0204,867162020003125,GL300W,0,0,2,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210433,0740,0000,7596,5891C,0.0,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210503,0740,0000,7596,5891C,0.0,88,20160215210506,1E78$")); + verifyPositions(decoder, text( "+RESP:GTFRI,060228,862894020178276,,15153,10,1,1,0.0,0,431.7,-63.169571,-17.776235,20160210153458,0736,0003,6AD4,80EF,00,34.9,00117:31:26,13442,15163,0,210101,,,,20160210113503,38EE$")); -- cgit v1.2.3 From b6b565858154dd8293829ee7f4d982178d97a0a3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Feb 2016 16:59:45 +1300 Subject: Save OBD cleared distance value --- src/org/traccar/helper/ObdDecoder.java | 2 +- test/org/traccar/protocol/UlbotechProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/traccar/helper/ObdDecoder.java b/src/org/traccar/helper/ObdDecoder.java index 35fa4dc07..f52216cae 100644 --- a/src/org/traccar/helper/ObdDecoder.java +++ b/src/org/traccar/helper/ObdDecoder.java @@ -69,7 +69,7 @@ public final class ObdDecoder { case PID_FUEL_LEVEL: return createEntry(Event.KEY_FUEL, intValue * 100 / 255); case PID_DISTANCE_CLEARED: - return createEntry(Event.KEY_FUEL, intValue); + return createEntry("cleared-distance", intValue); default: return null; } diff --git a/test/org/traccar/protocol/UlbotechProtocolDecoderTest.java b/test/org/traccar/protocol/UlbotechProtocolDecoderTest.java index e87e95efe..edee9930d 100644 --- a/test/org/traccar/protocol/UlbotechProtocolDecoderTest.java +++ b/test/org/traccar/protocol/UlbotechProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class UlbotechProtocolDecoderTest extends ProtocolTest { UlbotechProtocolDecoder decoder = new UlbotechProtocolDecoder(new UlbotechProtocol()); + verifyPosition(decoder, binary( + "f8010103515790566431569e5fbb9d010e015ee2b906bde4a000000000009f03040a4000000404000115fe05060340173f22030711310583410c0000310d00312f834131000008040000b78c09077320290082c021100101120af8")); + verifyNothing(decoder, binary( "2a545330312c33353430343330353133383934363023")); -- cgit v1.2.3 From fcd74ee0e418a82fe118920d67c824bbfbe984a2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Feb 2016 21:57:11 +1300 Subject: Check time before updating current location --- src/org/traccar/MainEventHandler.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java index f0ef36e5b..f99765de4 100644 --- a/src/org/traccar/MainEventHandler.java +++ b/src/org/traccar/MainEventHandler.java @@ -48,7 +48,10 @@ public class MainEventHandler extends IdleStateAwareChannelHandler { s.append("course: ").append(String.format("%.1f", position.getCourse())); Log.info(s.toString()); - Context.getConnectionManager().updatePosition(position); + Position lastPosition = Context.getConnectionManager().getLastPosition(position.getDeviceId()); + if (lastPosition == null || position.getFixTime().compareTo(lastPosition.getFixTime()) > 0) { + Context.getConnectionManager().updatePosition(position); + } } } -- cgit v1.2.3 From 2bcaeff435d1e1fa10ab253241e3d722ad29b153 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Feb 2016 22:46:32 +1300 Subject: Decode additional GL200 protocol data --- src/org/traccar/model/Event.java | 1 + src/org/traccar/protocol/Gl200ProtocolDecoder.java | 11 +++++++++-- src/org/traccar/protocol/MxtProtocolDecoder.java | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/org/traccar/model/Event.java b/src/org/traccar/model/Event.java index a9f6f9204..221536530 100644 --- a/src/org/traccar/model/Event.java +++ b/src/org/traccar/model/Event.java @@ -29,6 +29,7 @@ public abstract class Event extends Extensible { public static final String KEY_ALARM = "alarm"; public static final String KEY_STATUS = "status"; public static final String KEY_ODOMETER = "odometer"; + public static final String KEY_HOURS = "hours"; public static final String KEY_INPUT = "input"; public static final String KEY_OUTPUT = "output"; public static final String KEY_POWER = "power"; diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 62d93ce13..91e8d86bc 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -135,7 +135,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version .number("(d{15}|x{14}),") // imei .expression("[^,]*,") // device name - .number("d*,") + .number("(d+)?,") // power .number("d{1,2},") // report type .number("d{1,2},") // count .expression("((?:") @@ -146,7 +146,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("(d{1,3})?,") // battery .or() .number("(d{1,7}.d)?,") // odometer - .number("d{5}:dd:dd,") // hour meter + .number("(d{5}:dd:dd),") // hour meter .number("(x+)?,") // adc 1 .number("(x+)?,") // adc 2 .number("(d{1,3})?,") // battery @@ -321,6 +321,8 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return null; } + int power = parser.nextInt(); + Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); while (itemParser.find()) { Position position = new Position(); @@ -336,10 +338,15 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); + if (power > 10) { + position.set(Event.KEY_POWER, power); + } + position.set(Event.KEY_ODOMETER, parser.next()); position.set(Event.KEY_BATTERY, parser.next()); position.set(Event.KEY_ODOMETER, parser.next()); + position.set(Event.KEY_HOURS, parser.next()); position.set(Event.PREFIX_ADC + 1, parser.next()); position.set(Event.PREFIX_ADC + 2, parser.next()); position.set(Event.KEY_BATTERY, parser.next()); diff --git a/src/org/traccar/protocol/MxtProtocolDecoder.java b/src/org/traccar/protocol/MxtProtocolDecoder.java index fedb7c715..53d5b8b09 100644 --- a/src/org/traccar/protocol/MxtProtocolDecoder.java +++ b/src/org/traccar/protocol/MxtProtocolDecoder.java @@ -114,7 +114,7 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(infoGroups, 4)) { - position.set("hours", buf.readUnsignedInt()); + position.set(Event.KEY_HOURS, buf.readUnsignedInt()); } if (BitUtil.check(infoGroups, 5)) { -- cgit v1.2.3 From b395bb276c73a9278ed2dad1168b8c0e8309e7c2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Feb 2016 22:48:41 +1300 Subject: Workaround for wrong location time --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 91e8d86bc..6902e61dd 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -338,6 +338,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); + // power value only on some devices if (power > 10) { position.set(Event.KEY_POWER, power); } @@ -352,6 +353,16 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { position.set(Event.KEY_BATTERY, parser.next()); position.set(Event.KEY_STATUS, parser.next()); + // workaround for wrong location time + if (parser.hasNext(6)) { + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + if (!position.getOutdated() && position.getFixTime().after(dateBuilder.getDate())) { + position.setTime(dateBuilder.getDate()); + } + } + return positions; } @@ -376,6 +387,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { position.set(Event.KEY_ODOMETER, parser.next()); + // workaround for wrong location time if (parser.hasNext(6)) { DateBuilder dateBuilder = new DateBuilder() .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) -- cgit v1.2.3 From c2248f7d46c992f24205f28622ccc72f7fc20b9c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 24 Feb 2016 23:06:07 +1300 Subject: Implement iButton support for Aplicom --- src/org/traccar/protocol/AplicomProtocolDecoder.java | 2 +- test/org/traccar/protocol/AplicomProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index 6ae6aa09f..a3d34cf3c 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -288,7 +288,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } if ((selector & 0x0200) != 0) { - buf.skipBytes(6); // button + position.set(Event.KEY_RFID, (((long) buf.readUnsignedShort()) << 32) + buf.readUnsignedInt()); } if ((selector & 0x0400) != 0) { diff --git a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java index 103718941..035163fc8 100644 --- a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class AplicomProtocolDecoderTest extends ProtocolTest { AplicomProtocolDecoder decoder = new AplicomProtocolDecoder(new AplicomProtocol()); + verifyPosition(decoder, binary( + "44c3014645e8e91b66001f00221f0b01f456ba1e0d56ba1e0b031f842200c6ef550c000000000017bd1cb30004")); + verifyNothing(decoder, binary( "44c3014645e8e9bada003e03fff7070055a4f24200000081000000000000000000000000000000000000000000000000000000000000000000000000000000ff00000001000000000000000044c3014645e8e9bada003e03fff77bff55a4f24300000081000000000000000000000000000000000000000000000000000000000000000000000000000000ff00300002000000000000000044c3014645e8e9bada003e03fff7690655a4f24500000081000000000000000000000000000000000000000000000000000000000000000000000000000000ff003000030000000000000000")); -- cgit v1.2.3 From fddcc3fd41423720ab5034ec527af8086e301e0a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Feb 2016 16:23:13 +1300 Subject: Implement Meiligao odometer decoding --- src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 19 +++++++------------ .../traccar/protocol/MeiligaoProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index cb2139a00..5c17aab61 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -54,23 +54,19 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { .number("|(xxxx)?") // state .groupBegin() .number("|(xxxx),(xxxx)") // adc + .number("(?:,(xxxx),(xxxx),(xxxx),(xxxx),(xxxx),(xxxx))?") .groupBegin() - .number(",(xxxx),(xxxx),(xxxx),(xxxx),(xxxx),(xxxx)") - .groupEnd("?") - .groupBegin() - .text("|") - .groupBegin() - .number("(x{16})") // cell + .number("|x{16}") // cell .number("|(xx)") // gsm - .number("|(x{8})|") // odometer - .number("(x{9})") // odometer + .number("|(x{8})") // odometer + .or() + .number("|(x{9})") // odometer .groupBegin() .number("|(x{5,})") // rfid .groupEnd("?") .groupEnd("?") .groupEnd("?") .groupEnd("?") - .groupEnd("?") .any() .compile(); @@ -283,15 +279,14 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } } - position.set(Event.KEY_CID, parser.next()); - if (parser.hasNext()) { position.set(Event.KEY_GSM, parser.nextInt(16)); } if (parser.hasNext()) { position.set(Event.KEY_ODOMETER, parser.nextInt(16)); - } else if (parser.hasNext()) { + } + if (parser.hasNext()) { position.set(Event.KEY_ODOMETER, parser.nextInt(16)); } diff --git a/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java b/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java index 2dbb24d9e..dd497858b 100644 --- a/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class MeiligaoProtocolDecoderTest extends ProtocolTest { MeiligaoProtocolDecoder decoder = new MeiligaoProtocolDecoder(new MeiligaoProtocol()); + verifyPosition(decoder, binary( + "24240072190820157fffff99553039343335342e3030302c412c313930372e303631392c4e2c30373235312e333235312c452c3031302e312c3138382e352c3234303231362c2c2c412a36427c302e387c36352e327c303830307c303030302c303030307c303336343838373532c73f0d0a")); + verifyPosition(decoder, binary( "242400680790209818ffff99553038333235382e3030302c412c303131352e393338302c532c30333634382e313430392c452c302e30302c3331352e35352c3132303131367c302e37347c313930322e337c303430307c303030302c303030307c302e30f41b0d0a")); -- cgit v1.2.3 From 4e1c651633ba76f388e856cc025416a5d5c7ec9f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Feb 2016 16:26:32 +1300 Subject: Enable UDP protocol for Teltonika --- src/org/traccar/protocol/TeltonikaProtocol.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/TeltonikaProtocol.java b/src/org/traccar/protocol/TeltonikaProtocol.java index 859b2a08c..f944c3003 100644 --- a/src/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/org/traccar/protocol/TeltonikaProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package org.traccar.protocol; +import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.traccar.BaseProtocol; @@ -37,6 +38,12 @@ public class TeltonikaProtocol extends BaseProtocol { pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this)); } }); + serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this)); + } + }); } } -- cgit v1.2.3 From 967b513318d4778b7ae5023e48cb544e2e9579a3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 25 Feb 2016 23:03:37 +1300 Subject: Implement DTC codes for Ulbotech --- src/org/traccar/helper/ObdDecoder.java | 37 +++++++++++++++++++--- .../traccar/protocol/UlbotechProtocolDecoder.java | 4 +-- test/org/traccar/helper/ObdDecoderTest.java | 10 +++--- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/org/traccar/helper/ObdDecoder.java b/src/org/traccar/helper/ObdDecoder.java index f52216cae..d847fb7c4 100644 --- a/src/org/traccar/helper/ObdDecoder.java +++ b/src/org/traccar/helper/ObdDecoder.java @@ -18,6 +18,8 @@ package org.traccar.helper; import org.traccar.model.Event; import java.util.AbstractMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; public final class ObdDecoder { @@ -25,8 +27,9 @@ public final class ObdDecoder { private ObdDecoder() { } - private static final int MODE_CURRENT = 0x01; - private static final int MODE_FREEZE_FRAME = 0x02; + public static final int MODE_CURRENT = 0x01; + public static final int MODE_FREEZE_FRAME = 0x02; + public static final int MODE_CODES = 0x03; private static final int PID_ENGINE_LOAD = 0x04; private static final int PID_COOLANT_TEMPERATURE = 0x05; @@ -37,11 +40,13 @@ public final class ObdDecoder { private static final int PID_FUEL_LEVEL = 0x2F; private static final int PID_DISTANCE_CLEARED = 0x31; - public static Map.Entry decode(int mode, int pid, String value) { + public static Map.Entry decode(int mode, String value) { switch (mode) { case MODE_CURRENT: case MODE_FREEZE_FRAME: - return decodeData(pid, value); + return decodeData(Integer.parseInt(value.substring(0, 2), 16), value.substring(2)); + case MODE_CODES: + return decodeCodes(value); default: return null; } @@ -51,6 +56,30 @@ public final class ObdDecoder { return new AbstractMap.SimpleEntry<>(key, value); } + private static Map.Entry decodeCodes(String value) { + StringBuilder codes = new StringBuilder(); + for (int i = 0; i < value.length() / 4; i++) { + int numValue = Integer.parseInt(value.substring(i * 4, (i + 1) * 4), 16); + codes.append(','); + switch (numValue >> 14) { + case 0: + codes.append('P'); + break; + case 1: + codes.append('C'); + break; + case 2: + codes.append('B'); + break; + case 3: + codes.append('U'); + break; + } + codes.append(String.format("%04X", numValue & 0x3FFF)); + } + return createEntry("dtcs", codes.toString().replaceFirst(",", "")); + } + private static Map.Entry decodeData(int pid, String value) { int intValue = Integer.parseInt(value, 16); switch (pid) { diff --git a/src/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/org/traccar/protocol/UlbotechProtocolDecoder.java index bf0a9cc76..a5c608dd3 100644 --- a/src/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -60,8 +60,8 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { while (buf.readerIndex() < end) { int parameterLength = buf.getUnsignedByte(buf.readerIndex()) >> 4; - position.add(ObdDecoder.decode(buf.readUnsignedByte() & 0x0F, buf.readUnsignedByte(), - ChannelBuffers.hexDump(buf.readBytes(parameterLength - 2)))); + int mode = buf.readUnsignedByte() & 0x0F; + position.add(ObdDecoder.decode(mode, ChannelBuffers.hexDump(buf.readBytes(parameterLength - 1)))); } } diff --git a/test/org/traccar/helper/ObdDecoderTest.java b/test/org/traccar/helper/ObdDecoderTest.java index 238f3e0a6..62881b66c 100644 --- a/test/org/traccar/helper/ObdDecoderTest.java +++ b/test/org/traccar/helper/ObdDecoderTest.java @@ -8,11 +8,11 @@ public class ObdDecoderTest { @Test public void testDecode() { - Assert.assertEquals(83, ObdDecoder.decode(0x01, 0x05, "7b").getValue()); - Assert.assertEquals(1225, ObdDecoder.decode(0x01, 0x0C, "1324").getValue()); - Assert.assertEquals(20, ObdDecoder.decode(0x01, 0x0D, "14").getValue()); - Assert.assertEquals(64050, ObdDecoder.decode(0x01, 0x31, "fa32").getValue()); - Assert.assertEquals(25, ObdDecoder.decode(0x01, 0x2F, "41").getValue()); + Assert.assertEquals(83, ObdDecoder.decode(0x01, "057b").getValue()); + Assert.assertEquals(1225, ObdDecoder.decode(0x01, "0C1324").getValue()); + Assert.assertEquals(20, ObdDecoder.decode(0x01, "0D14").getValue()); + Assert.assertEquals(64050, ObdDecoder.decode(0x01, "31fa32").getValue()); + Assert.assertEquals(25, ObdDecoder.decode(0x01, "2F41").getValue()); } -- cgit v1.2.3 From de5c65eb3854776840690a80cf8b3cf8aaf2c7b9 Mon Sep 17 00:00:00 2001 From: Alexander <4nonym0us@xakep.ru> Date: Thu, 25 Feb 2016 13:16:43 +0200 Subject: #1751 Bugfix in old API --- src/org/traccar/web/BaseServlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/traccar/web/BaseServlet.java b/src/org/traccar/web/BaseServlet.java index 8b022d556..17f4f19cd 100644 --- a/src/org/traccar/web/BaseServlet.java +++ b/src/org/traccar/web/BaseServlet.java @@ -53,7 +53,7 @@ public abstract class BaseServlet extends HttpServlet { String origin = req.getHeader(HttpHeaders.Names.ORIGIN); String allowed = Context.getConfig().getString("web.origin"); - if (allowed == null) { + if (allowed == null || origin == null) { resp.setHeader(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, ALLOW_ORIGIN_VALUE); } else if (allowed.contains(origin)) { String originSafe = URLEncoder.encode(origin, StandardCharsets.UTF_8.name()); -- cgit v1.2.3 From 8b17694d807799c1311fd32e38925f9f5fd0c5a1 Mon Sep 17 00:00:00 2001 From: Alexander <4nonym0us@xakep.ru> Date: Thu, 25 Feb 2016 13:18:24 +0200 Subject: #1751 Bugfix in new API --- src/org/traccar/api/CorsResponseFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/traccar/api/CorsResponseFilter.java b/src/org/traccar/api/CorsResponseFilter.java index 001f6ab4c..5e1ff0852 100644 --- a/src/org/traccar/api/CorsResponseFilter.java +++ b/src/org/traccar/api/CorsResponseFilter.java @@ -54,7 +54,7 @@ public class CorsResponseFilter implements ContainerResponseFilter { if (!response.getHeaders().containsKey(ACCESS_CONTROL_ALLOW_ORIGIN_KEY)) { String origin = request.getHeaderString(HttpHeaders.Names.ORIGIN); String allowed = Context.getConfig().getString("web.origin"); - if (allowed == null) { + if (allowed == null || origin == null) { response.getHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN_KEY, ACCESS_CONTROL_ALLOW_ORIGIN_VALUE); } else if (allowed.contains(origin)) { String originSafe = URLEncoder.encode(origin, StandardCharsets.UTF_8.name()); -- cgit v1.2.3 From b82431f69fff7ea7c602aa41d8eddc6dc1fc6e68 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 26 Feb 2016 11:41:31 +1300 Subject: Add new Xexun unit test case --- test/org/traccar/protocol/XexunProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/org/traccar/protocol/XexunProtocolDecoderTest.java b/test/org/traccar/protocol/XexunProtocolDecoderTest.java index 76c516caf..d2d921916 100644 --- a/test/org/traccar/protocol/XexunProtocolDecoderTest.java +++ b/test/org/traccar/protocol/XexunProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class XexunProtocolDecoderTest extends ProtocolTest { XexunProtocolDecoder decoder = new XexunProtocolDecoder(new XexunProtocol(), false); + verifyNothing(decoder, text( + "GPRMC,215853.000,A,5304.9600,N,6.7907,E,1.43,80.67,250216,00,0000.0,A*47,F,,imei:351525018007873,")); + verifyPosition(decoder, text( "GPRMC,121535.000,A,5417.2666,N,04822.1264,E,1.452,30.42,031014,0.0,A*4D\r\n,L,imei:355227042011730,")); -- cgit v1.2.3 From d05bee19a973798554bf9b9f5563c5a8e5ba4d5e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 26 Feb 2016 15:23:08 +1300 Subject: Flexible coordinates format for Xexun --- src/org/traccar/protocol/XexunProtocolDecoder.java | 4 ++-- test/org/traccar/protocol/XexunProtocolDecoderTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/org/traccar/protocol/XexunProtocolDecoder.java b/src/org/traccar/protocol/XexunProtocolDecoder.java index 0929ee99b..bbf4d9453 100644 --- a/src/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/org/traccar/protocol/XexunProtocolDecoder.java @@ -38,8 +38,8 @@ public class XexunProtocolDecoder extends BaseProtocolDecoder { .expression("G[PN]RMC,") .number("(dd)(dd)(dd).(d+),") // time .expression("([AV]),") // validity - .number("(d+)(dd.d+),([NS]),") // latitude - .number("(d+)(dd.d+),([EW])?,") // longitude + .number("(d+?)?(d?d.d+),([NS]),") // latitude + .number("(d+?)?(d?d.d+),([EW])?,") // longitude .number("(d+.?d*),") // speed .number("(d+.?d*)?,") // course .number("(dd)(dd)(dd),") // date diff --git a/test/org/traccar/protocol/XexunProtocolDecoderTest.java b/test/org/traccar/protocol/XexunProtocolDecoderTest.java index d2d921916..96560fd03 100644 --- a/test/org/traccar/protocol/XexunProtocolDecoderTest.java +++ b/test/org/traccar/protocol/XexunProtocolDecoderTest.java @@ -11,7 +11,7 @@ public class XexunProtocolDecoderTest extends ProtocolTest { XexunProtocolDecoder decoder = new XexunProtocolDecoder(new XexunProtocol(), false); - verifyNothing(decoder, text( + verifyPosition(decoder, text( "GPRMC,215853.000,A,5304.9600,N,6.7907,E,1.43,80.67,250216,00,0000.0,A*47,F,,imei:351525018007873,")); verifyPosition(decoder, text( -- cgit v1.2.3 From e586ffd374f7a66d1077d5a9cd1d6380655a23dc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 27 Feb 2016 09:29:58 +1300 Subject: Support new GL200 message format --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 4 +++- test/org/traccar/protocol/Gl200ProtocolDecoderTest.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 6902e61dd..71ccbd026 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -93,7 +93,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("(d+)?,") // lac .number("(d+)?,") // cell .groupEnd() - .number("d*,") // reserved + .number("(?:d+|(d+.d))?,") // odometer .compile(); private static final Pattern PATTERN_OBD = new PatternBuilder() @@ -265,6 +265,8 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { } parser.skip(4); // alternative networks + + position.set(Event.KEY_ODOMETER, parser.next()); } private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java index 11c069adb..6b6e763ad 100644 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java @@ -49,7 +49,7 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, text( "+RESP:GTFRI,1A0401,860599000508846,,0,0,1,1,134.8,154,278.7,-76.671089,39.778885,20150623154301,0310,0260,043F,7761,,99,20150623154314,0F24$")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,1A0200,860599000165464,CRI001,0,0,1,2,,41,,-71.153137,42.301634,20150328020301,,,,,280.3,55,20150327220351,320C")); verifyPositions(decoder, text( -- cgit v1.2.3 From 6710bc0d1f0667ea2a3e9e3c038d9412dd6195f1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 27 Feb 2016 09:52:19 +1300 Subject: Update Xexun decoder regex pattern --- src/org/traccar/protocol/XexunProtocolDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/org/traccar/protocol/XexunProtocolDecoder.java b/src/org/traccar/protocol/XexunProtocolDecoder.java index bbf4d9453..4d4831a20 100644 --- a/src/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/org/traccar/protocol/XexunProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2012 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,8 +38,8 @@ public class XexunProtocolDecoder extends BaseProtocolDecoder { .expression("G[PN]RMC,") .number("(dd)(dd)(dd).(d+),") // time .expression("([AV]),") // validity - .number("(d+?)?(d?d.d+),([NS]),") // latitude - .number("(d+?)?(d?d.d+),([EW])?,") // longitude + .number("(d*?)(d?d.d+),([NS]),") // latitude + .number("(d*?)(d?d.d+),([EW])?,") // longitude .number("(d+.?d*),") // speed .number("(d+.?d*)?,") // course .number("(dd)(dd)(dd),") // date -- cgit v1.2.3 From 70642da680096f52fe1478690cd7816f41e18c74 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 27 Feb 2016 09:57:37 +1300 Subject: Update file to fix IDE issue --- src/org/traccar/api/CorsResponseFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/traccar/api/CorsResponseFilter.java b/src/org/traccar/api/CorsResponseFilter.java index 5e1ff0852..ed6e482ae 100644 --- a/src/org/traccar/api/CorsResponseFilter.java +++ b/src/org/traccar/api/CorsResponseFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. -- cgit v1.2.3 From 04dd07ab82e8af604fe66df7bc92e59d45c0c916 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 27 Feb 2016 10:03:45 +1300 Subject: Handle empty values in parser --- src/org/traccar/helper/Parser.java | 3 ++- test/org/traccar/protocol/XexunProtocolDecoderTest.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/org/traccar/helper/Parser.java b/src/org/traccar/helper/Parser.java index 73713c51c..dcea1c8f7 100644 --- a/src/org/traccar/helper/Parser.java +++ b/src/org/traccar/helper/Parser.java @@ -46,7 +46,8 @@ public class Parser { } public boolean hasNext(int number) { - if (matcher.group(position) != null) { + String value = matcher.group(position); + if (value != null && !value.isEmpty()) { return true; } else { position += number; diff --git a/test/org/traccar/protocol/XexunProtocolDecoderTest.java b/test/org/traccar/protocol/XexunProtocolDecoderTest.java index 96560fd03..770c4071d 100644 --- a/test/org/traccar/protocol/XexunProtocolDecoderTest.java +++ b/test/org/traccar/protocol/XexunProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class XexunProtocolDecoderTest extends ProtocolTest { XexunProtocolDecoder decoder = new XexunProtocolDecoder(new XexunProtocol(), false); + verifyPosition(decoder, text( + "GPRMC,215853.000,A,5304.9600,N,10.7907,E,1.43,80.67,250216,00,0000.0,A*47,F,,imei:351525018007873,")); + verifyPosition(decoder, text( "GPRMC,215853.000,A,5304.9600,N,6.7907,E,1.43,80.67,250216,00,0000.0,A*47,F,,imei:351525018007873,")); -- cgit v1.2.3 From d428a5b62531cfc02c8f20d35879b4ec1e383869 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 27 Feb 2016 10:06:27 +1300 Subject: Replace fake sample with real one --- test/org/traccar/protocol/XexunProtocolDecoderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/org/traccar/protocol/XexunProtocolDecoderTest.java b/test/org/traccar/protocol/XexunProtocolDecoderTest.java index 770c4071d..ac90daec5 100644 --- a/test/org/traccar/protocol/XexunProtocolDecoderTest.java +++ b/test/org/traccar/protocol/XexunProtocolDecoderTest.java @@ -12,7 +12,7 @@ public class XexunProtocolDecoderTest extends ProtocolTest { XexunProtocolDecoder decoder = new XexunProtocolDecoder(new XexunProtocol(), false); verifyPosition(decoder, text( - "GPRMC,215853.000,A,5304.9600,N,10.7907,E,1.43,80.67,250216,00,0000.0,A*47,F,,imei:351525018007873,")); + "GPRMC,113518.000,A,5303.4150,N,10.2368,E,60.73,207.42,260216,00,0000.0,A*74,F,,imei:351525018007873,")); verifyPosition(decoder, text( "GPRMC,215853.000,A,5304.9600,N,6.7907,E,1.43,80.67,250216,00,0000.0,A*47,F,,imei:351525018007873,")); -- cgit v1.2.3 From 53fa46d769168f4f97745412e3ff241843d0851b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 27 Feb 2016 10:18:07 +1300 Subject: Correctly decode GPFID T55 messages --- src/org/traccar/protocol/T55ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java index 9c47d1ab0..c6b2a670e 100644 --- a/src/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/org/traccar/protocol/T55ProtocolDecoder.java @@ -217,7 +217,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { } else if (sentence.startsWith("IMEI")) { identify(sentence.substring(5, sentence.length()), channel, remoteAddress); } else if (sentence.startsWith("$GPFID")) { - if (identify(sentence.substring(6, sentence.length()), channel, remoteAddress) && position != null) { + if (identify(sentence.substring(7, sentence.length()), channel, remoteAddress) && position != null) { Position position = this.position; position.setDeviceId(getDeviceId()); this.position = null; -- cgit v1.2.3 From 002443ba33bbf9883d54505119c5361897d30f66 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 27 Feb 2016 10:31:22 +1300 Subject: Merge changes from RS-CORS-Origin --- src/org/traccar/api/CorsResponseFilter.java | 8 ++++---- src/org/traccar/api/SecurityRequestFilter.java | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/org/traccar/api/CorsResponseFilter.java b/src/org/traccar/api/CorsResponseFilter.java index ed6e482ae..01d100d0a 100644 --- a/src/org/traccar/api/CorsResponseFilter.java +++ b/src/org/traccar/api/CorsResponseFilter.java @@ -37,7 +37,7 @@ public class CorsResponseFilter implements ContainerResponseFilter { public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS_VALUE = "true"; public static final String ACCESS_CONTROL_ALLOW_METHODS_KEY = "Access-Control-Allow-Methods"; - public static final String ACCESS_CONTROL_ALLOW_METHODS_VALUE = "GET, POST, PUT, DELETE"; + public static final String ACCESS_CONTROL_ALLOW_METHODS_VALUE = "GET, POST, PUT, DELETE, OPTIONS"; @Override public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException { @@ -54,11 +54,11 @@ public class CorsResponseFilter implements ContainerResponseFilter { if (!response.getHeaders().containsKey(ACCESS_CONTROL_ALLOW_ORIGIN_KEY)) { String origin = request.getHeaderString(HttpHeaders.Names.ORIGIN); String allowed = Context.getConfig().getString("web.origin"); + if (allowed == null || origin == null) { response.getHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN_KEY, ACCESS_CONTROL_ALLOW_ORIGIN_VALUE); - } else if (allowed.contains(origin)) { - String originSafe = URLEncoder.encode(origin, StandardCharsets.UTF_8.name()); - response.getHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN_KEY, originSafe); + } else if (allowed.equals(ACCESS_CONTROL_ALLOW_ORIGIN_VALUE) || allowed.contains(origin)) { + response.getHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN_KEY, origin); } } } diff --git a/src/org/traccar/api/SecurityRequestFilter.java b/src/org/traccar/api/SecurityRequestFilter.java index 20186b0cb..d4fb15059 100644 --- a/src/org/traccar/api/SecurityRequestFilter.java +++ b/src/org/traccar/api/SecurityRequestFilter.java @@ -55,6 +55,11 @@ public class SecurityRequestFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) { + + if (requestContext.getMethod() == "OPTIONS") { + throw new WebApplicationException(Response.status(Response.Status.OK).entity("").build()); + } + SecurityContext securityContext = null; String authHeader = requestContext.getHeaderString(AUTHORIZATION_HEADER); -- cgit v1.2.3 From f3c7e3e6dc28a39f23197beecb2bdac79d6628a3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 27 Feb 2016 12:49:44 +1300 Subject: Make WebSocket timeout configurable --- debug.xml | 1 + src/org/traccar/api/AsyncSocketServlet.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/debug.xml b/debug.xml index 992f586d9..82600a3eb 100644 --- a/debug.xml +++ b/debug.xml @@ -14,6 +14,7 @@ web true true + 10000 true nominatim diff --git a/src/org/traccar/api/AsyncSocketServlet.java b/src/org/traccar/api/AsyncSocketServlet.java index fbfe248e5..edfa8939b 100644 --- a/src/org/traccar/api/AsyncSocketServlet.java +++ b/src/org/traccar/api/AsyncSocketServlet.java @@ -20,6 +20,7 @@ import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; import org.eclipse.jetty.websocket.servlet.WebSocketCreator; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; +import org.traccar.Context; import org.traccar.api.resource.SessionResource; public class AsyncSocketServlet extends WebSocketServlet { @@ -28,7 +29,7 @@ public class AsyncSocketServlet extends WebSocketServlet { @Override public void configure(WebSocketServletFactory factory) { - factory.getPolicy().setIdleTimeout(ASYNC_TIMEOUT); + factory.getPolicy().setIdleTimeout(Context.getConfig().getLong("web.timeout", ASYNC_TIMEOUT)); factory.setCreator(new WebSocketCreator() { @Override public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) { -- cgit v1.2.3 From ed60fc9e4385284445252a2372711c3f402d3823 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 28 Feb 2016 00:27:11 +1300 Subject: Remove _dc parameter from web files --- web/debug.html | 3 +++ web/locale.js | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web/debug.html b/web/debug.html index 3608930c0..792cfa5d9 100644 --- a/web/debug.html +++ b/web/debug.html @@ -16,6 +16,9 @@ + diff --git a/web/locale.js b/web/locale.js index 7dc94ec45..30749f0f7 100644 --- a/web/locale.js +++ b/web/locale.js @@ -16,9 +16,6 @@ var Locale = {}; -Ext.Ajax.disableCaching = false; -Ext.Loader.disableCaching = false; - Locale.languages = { 'ar': { name: 'العربية', code: 'en' }, 'bg': { name: 'Български', code: 'bg' }, -- cgit v1.2.3 From ff905789b95be8e9b8901317c04ab0c32fbf627d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 29 Feb 2016 23:30:43 +1300 Subject: Add starline M17 unit test case --- test/org/traccar/protocol/AutoFonProtocolDecoderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java b/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java index 4a0a42a7b..e971216a5 100644 --- a/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class AutoFonProtocolDecoderTest extends ProtocolTest { AutoFonProtocolDecoder decoder = new AutoFonProtocolDecoder(new AutoFonProtocol()); + verifyNothing(decoder, binary( + "02080000251848470afa010262daa690013aa4046da83745f8812560df010001126a")); + verifyNothing(decoder, binary( "10556103592310314825728F")); -- cgit v1.2.3 From 7a90bd82cd8a90d1ddbb7341cae89a1f6b01d50a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Mar 2016 00:00:08 +1300 Subject: Fix the AutoFon unit test cases --- test/org/traccar/protocol/AutoFonProtocolDecoderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java b/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java index e971216a5..f84873c6e 100644 --- a/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java @@ -11,7 +11,7 @@ public class AutoFonProtocolDecoderTest extends ProtocolTest { AutoFonProtocolDecoder decoder = new AutoFonProtocolDecoder(new AutoFonProtocol()); - verifyNothing(decoder, binary( + verifyPosition(decoder, binary( "02080000251848470afa010262daa690013aa4046da83745f8812560df010001126a")); verifyNothing(decoder, binary( -- cgit v1.2.3 From a8192b921e0f0b89654440075e4045d9002f1b73 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Mar 2016 10:40:32 +1300 Subject: Add iButton Aplicom test cases --- test/org/traccar/protocol/AplicomProtocolDecoderTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java index 035163fc8..26844994e 100644 --- a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class AplicomProtocolDecoderTest extends ProtocolTest { AplicomProtocolDecoder decoder = new AplicomProtocolDecoder(new AplicomProtocol()); + verifyPosition(decoder, binary( + "44c3014645e8e91b66002300a21f0b01f056d3e62856d3e626031f845f00c6ee440800000000000000000017bd1cb30000")); + + verifyPosition(decoder, binary( + "44c3014645e8e91b66002300a21f0b00f056d3e64756d3e646031f845f00c6ee440800000000000000000017bd1cb30001")); + verifyPosition(decoder, binary( "44c3014645e8e91b66001f00221f0b01f456ba1e0d56ba1e0b031f842200c6ef550c000000000017bd1cb30004")); -- cgit v1.2.3 From 8e0740ac9465b431ccc298b665b0750ed06a6b72 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Mar 2016 13:48:16 +1300 Subject: Remove unused Java class imports --- src/org/traccar/api/CorsResponseFilter.java | 2 -- src/org/traccar/helper/ObdDecoder.java | 10 ++++------ src/org/traccar/protocol/Gl200ProtocolDecoder.java | 2 -- src/org/traccar/protocol/TelicProtocol.java | 1 - src/org/traccar/protocol/Tt8850ProtocolDecoder.java | 1 - 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/org/traccar/api/CorsResponseFilter.java b/src/org/traccar/api/CorsResponseFilter.java index 01d100d0a..178d08812 100644 --- a/src/org/traccar/api/CorsResponseFilter.java +++ b/src/org/traccar/api/CorsResponseFilter.java @@ -19,8 +19,6 @@ import org.jboss.netty.handler.codec.http.HttpHeaders; import org.traccar.Context; import java.io.IOException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; diff --git a/src/org/traccar/helper/ObdDecoder.java b/src/org/traccar/helper/ObdDecoder.java index d847fb7c4..c2d9b1841 100644 --- a/src/org/traccar/helper/ObdDecoder.java +++ b/src/org/traccar/helper/ObdDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,6 @@ package org.traccar.helper; import org.traccar.model.Event; import java.util.AbstractMap; -import java.util.LinkedList; -import java.util.List; import java.util.Map; public final class ObdDecoder { @@ -62,9 +60,6 @@ public final class ObdDecoder { int numValue = Integer.parseInt(value.substring(i * 4, (i + 1) * 4), 16); codes.append(','); switch (numValue >> 14) { - case 0: - codes.append('P'); - break; case 1: codes.append('C'); break; @@ -74,6 +69,9 @@ public final class ObdDecoder { case 3: codes.append('U'); break; + default: + codes.append('P'); + break; } codes.append(String.format("%04X", numValue & 0x3FFF)); } diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 71ccbd026..7dd60f44f 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import java.net.SocketAddress; import java.util.LinkedList; -import java.util.List; import java.util.regex.Pattern; import org.jboss.netty.channel.Channel; @@ -26,7 +25,6 @@ import org.traccar.Context; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; -import org.traccar.helper.PatternUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Event; import org.traccar.model.Position; diff --git a/src/org/traccar/protocol/TelicProtocol.java b/src/org/traccar/protocol/TelicProtocol.java index 6b8abcaeb..464892431 100644 --- a/src/org/traccar/protocol/TelicProtocol.java +++ b/src/org/traccar/protocol/TelicProtocol.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; import org.jboss.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; diff --git a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java index c270d3364..526946eac 100644 --- a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java @@ -17,7 +17,6 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; -- cgit v1.2.3 From c922091c83d02760fcd2c15cbbcb1eb91fbf548f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 1 Mar 2016 13:49:11 +1300 Subject: Fix other source code issues --- src/org/traccar/protocol/Tt8850ProtocolDecoder.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java index 526946eac..9979fd61d 100644 --- a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java @@ -20,7 +20,6 @@ import org.traccar.BaseProtocolDecoder; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; -import org.traccar.helper.PatternUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Event; import org.traccar.model.Position; @@ -64,8 +63,6 @@ public class Tt8850ProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - String x = PatternUtil.checkPattern(PATTERN.pattern(), (String) msg); - Parser parser = new Parser(PATTERN, (String) msg); if (!parser.matches()) { return null; -- cgit v1.2.3 From ea5d08507fc82073bf198b2c3fffd90870d291d3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 2 Mar 2016 10:17:34 +1300 Subject: Another update for GL200 decoder --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 7dd60f44f..8605d8295 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -129,7 +129,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .compile(); private static final Pattern PATTERN_FRI = new PatternBuilder() - .text("+RESP:GTFRI,") + .text("+").expression("(?:RESP|BUFF):GTFRI,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version .number("(d{15}|x{14}),") // imei .expression("[^,]*,") // device name @@ -158,8 +158,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .compile(); private static final Pattern PATTERN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF)").text(":") - .expression("GT...,") + .text("+").expression("(?:RESP|BUFF):GT...,") .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version .number("(d{15}),") // imei .expression("[^,]*,") // device name -- cgit v1.2.3 From f5d687b7adb86e259f7b1f3b04a48d625cf1ca5e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 2 Mar 2016 10:47:36 +1300 Subject: Implement Meitrack photo request --- src/org/traccar/protocol/MeitrackProtocol.java | 7 +++++-- src/org/traccar/protocol/MeitrackProtocolDecoder.java | 16 ++++++++++++---- src/org/traccar/protocol/MeitrackProtocolEncoder.java | 12 +++++++----- .../traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/org/traccar/protocol/MeitrackProtocol.java b/src/org/traccar/protocol/MeitrackProtocol.java index c957d4ea1..266d9bcd5 100644 --- a/src/org/traccar/protocol/MeitrackProtocol.java +++ b/src/org/traccar/protocol/MeitrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,8 @@ public class MeitrackProtocol extends BaseProtocol { Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_ARM, - Command.TYPE_ALARM_DISARM); + Command.TYPE_ALARM_DISARM, + Command.TYPE_REQUEST_PHOTO); } @Override @@ -45,6 +46,7 @@ public class MeitrackProtocol extends BaseProtocol { pipeline.addLast("frameDecoder", new MeitrackFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new MeitrackProtocolDecoder(MeitrackProtocol.this)); + pipeline.addLast("objectEncoder", new MeitrackProtocolEncoder()); } }; server.setEndianness(ByteOrder.LITTLE_ENDIAN); @@ -54,6 +56,7 @@ public class MeitrackProtocol extends BaseProtocol { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectDecoder", new MeitrackProtocolDecoder(MeitrackProtocol.this)); + pipeline.addLast("objectEncoder", new MeitrackProtocolEncoder()); } }; server.setEndianness(ByteOrder.LITTLE_ENDIAN); diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index e0ca01412..a920c6e76 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -24,6 +24,7 @@ import java.util.regex.Pattern; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -237,10 +238,17 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { index = buf.indexOf(index + 1, buf.writerIndex(), (byte) ','); String type = buf.toString(index + 1, 3, Charset.defaultCharset()); - if (type.equals("CCC")) { - return decodeBinaryMessage(channel, remoteAddress, buf); - } else { - return decodeRegularMessage(channel, remoteAddress, buf); + switch (type) { + case "D03": + if (channel != null) { + String imei = Context.getIdentityManager().getDeviceById(getDeviceId()).getUniqueId(); + channel.write("@@O46," + imei + ",D00,camera_picture.jpg,0*00\r\n"); + } + return null; + case "CCC": + return decodeBinaryMessage(channel, remoteAddress, buf); + default: + return decodeRegularMessage(channel, remoteAddress, buf); } } diff --git a/src/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/org/traccar/protocol/MeitrackProtocolEncoder.java index bfda2b7d2..90fa5b624 100644 --- a/src/org/traccar/protocol/MeitrackProtocolEncoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,13 +26,15 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder { switch (command.getType()) { case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "@@M33,{%s},C01,0,12222*18\r\n", Command.KEY_UNIQUE_ID); + return formatCommand(command, "@@M33,{%s},C01,0,12222*00\r\n", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "@@M33,{%s},C01,0,02222*18\r\n", Command.KEY_UNIQUE_ID); + return formatCommand(command, "@@M33,{%s},C01,0,02222*00\r\n", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_ARM: - return formatCommand(command, "@@M33,{%s},C01,0,22122*18\r\n", Command.KEY_UNIQUE_ID); + return formatCommand(command, "@@M33,{%s},C01,0,22122*00\r\n", Command.KEY_UNIQUE_ID); case Command.TYPE_ALARM_DISARM: - return formatCommand(command, "@@M33,{%s},C01,0,22022*18\r\n", Command.KEY_UNIQUE_ID); + return formatCommand(command, "@@M33,{%s},C01,0,22022*00\r\n", Command.KEY_UNIQUE_ID); + case Command.TYPE_REQUEST_PHOTO: + return formatCommand(command, "@@D46,{%s},D03,1,camera_picture.jpg*00\r\n", Command.KEY_UNIQUE_ID); default: Log.warning(new UnsupportedOperationException(command.getType())); break; diff --git a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java index dcefb1637..f74914461 100644 --- a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { MeitrackProtocolDecoder decoder = new MeitrackProtocolDecoder(new MeitrackProtocol()); + verifyNothing(decoder, buffer( + "$$D28,353358017784062,D03,OK*F3")); + verifyPosition(decoder, buffer( "$$A158,79007001520234,AAA,35,40.996370,-8.575065,150730184834,A,8,24,0,1,1.3,173,32573389,31405012,268|3|2BC0|250B,2000,|||0A2D|0000,00000001,,50,,,,,,,,,,,,,*4A"), position("2015-07-30 18:48:34.000", true, 40.99637, -8.57507)); -- cgit v1.2.3 From a05541ee221b261a4554e27487d4ecf8f466a1e4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Mar 2016 09:55:49 +1300 Subject: Add API to get current positions --- src/org/traccar/api/resource/PositionResource.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/org/traccar/api/resource/PositionResource.java b/src/org/traccar/api/resource/PositionResource.java index ec6925b3a..b9e8e877e 100644 --- a/src/org/traccar/api/resource/PositionResource.java +++ b/src/org/traccar/api/resource/PositionResource.java @@ -38,9 +38,14 @@ public class PositionResource extends BaseResource { public Collection get( @QueryParam("deviceId") long deviceId, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - return Context.getDataManager().getPositions( - deviceId, JsonConverter.parseDate(from), JsonConverter.parseDate(to)); + if (deviceId == 0) { + return Context.getConnectionManager().getInitialState( + Context.getPermissionsManager().allowedDevices(getUserId())); + } else { + Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + return Context.getDataManager().getPositions( + deviceId, JsonConverter.parseDate(from), JsonConverter.parseDate(to)); + } } } -- cgit v1.2.3 From 07412baa3500a8ff4086adb0edf03c9bd2a69310 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Mar 2016 10:52:10 +1300 Subject: Start db changelogs from scratch --- database/changelog-3.3.xml | 187 ++++++++++++++++++++++++++++++++ database/changelog-master.xml | 9 ++ database/db.changelog-3.0.xml | 207 ------------------------------------ database/db.changelog-3.1.xml | 131 ----------------------- database/db.changelog-3.2.xml | 63 ----------- database/db.changelog-3.3.xml | 32 ------ database/db.changelog-master.xml | 13 --- database/db.changelog-normalize.xml | 114 -------------------- debug.xml | 2 +- 9 files changed, 197 insertions(+), 561 deletions(-) create mode 100644 database/changelog-3.3.xml create mode 100644 database/changelog-master.xml delete mode 100644 database/db.changelog-3.0.xml delete mode 100644 database/db.changelog-3.1.xml delete mode 100644 database/db.changelog-3.2.xml delete mode 100644 database/db.changelog-3.3.xml delete mode 100644 database/db.changelog-master.xml delete mode 100644 database/db.changelog-normalize.xml diff --git a/database/changelog-3.3.xml b/database/changelog-3.3.xml new file mode 100644 index 000000000..25b359401 --- /dev/null +++ b/database/changelog-3.3.xml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/database/changelog-master.xml b/database/changelog-master.xml new file mode 100644 index 000000000..595643dce --- /dev/null +++ b/database/changelog-master.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/database/db.changelog-3.0.xml b/database/db.changelog-3.0.xml deleted file mode 100644 index 453f6f00b..000000000 --- a/database/db.changelog-3.0.xml +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/database/db.changelog-3.1.xml b/database/db.changelog-3.1.xml deleted file mode 100644 index 740da4e2f..000000000 --- a/database/db.changelog-3.1.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/database/db.changelog-3.2.xml b/database/db.changelog-3.2.xml deleted file mode 100644 index fdeabfb68..000000000 --- a/database/db.changelog-3.2.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/database/db.changelog-3.3.xml b/database/db.changelog-3.3.xml deleted file mode 100644 index 22fcd6f5c..000000000 --- a/database/db.changelog-3.3.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/database/db.changelog-master.xml b/database/db.changelog-master.xml deleted file mode 100644 index 06fc7a695..000000000 --- a/database/db.changelog-master.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/database/db.changelog-normalize.xml b/database/db.changelog-normalize.xml deleted file mode 100644 index 7621846ca..000000000 --- a/database/db.changelog-normalize.xml +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CREATE ALIAS IF NOT EXISTS EXECUTE AS $$ void executeSql(Connection conn, String sql) throws SQLException { try { conn.createStatement().executeUpdate(sql); } catch (Exception e) {} } $$; - - CALL EXECUTE('ALTER TABLE POSITION DROP CONSTRAINT ' || (SELECT DISTINCT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE CONSTRAINT_TYPE = 'REFERENTIAL' AND TABLE_NAME = 'POSITION' AND COLUMN_LIST = 'DEVICEID')); - CALL EXECUTE('ALTER TABLE DEVICE DROP CONSTRAINT ' || (SELECT DISTINCT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE CONSTRAINT_TYPE = 'REFERENTIAL' AND TABLE_NAME = 'DEVICE' AND COLUMN_LIST = 'POSITIONID')); - CALL EXECUTE('ALTER TABLE DEVICE DROP CONSTRAINT ' || (SELECT DISTINCT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE CONSTRAINT_TYPE = 'REFERENTIAL' AND TABLE_NAME = 'DEVICE' AND COLUMN_LIST = 'DATAID')); - CALL EXECUTE('ALTER TABLE USER_DEVICE DROP CONSTRAINT ' || (SELECT DISTINCT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE CONSTRAINT_TYPE = 'REFERENTIAL' AND TABLE_NAME = 'USER_DEVICE' AND COLUMN_LIST = 'USERID')); - CALL EXECUTE('ALTER TABLE USER_DEVICE DROP CONSTRAINT ' || (SELECT DISTINCT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE CONSTRAINT_TYPE = 'REFERENTIAL' AND TABLE_NAME = 'USER_DEVICE' AND COLUMN_LIST = 'DEVICEID')); - CALL EXECUTE('ALTER TABLE DATA DROP CONSTRAINT ' || (SELECT DISTINCT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE CONSTRAINT_TYPE = 'REFERENTIAL' AND TABLE_NAME = 'DATA' AND COLUMN_LIST = 'DEVICEID')); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/debug.xml b/debug.xml index 82600a3eb..eb2038cd5 100644 --- a/debug.xml +++ b/debug.xml @@ -49,7 +49,7 @@ sa false - ./database/db.changelog-master.xml + ./database/changelog-master.xml SELECT * FROM server; -- cgit v1.2.3 From dbe7c3ff97d127bdff4aae21a65ed1e5106c4d76 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Mar 2016 11:10:25 +1300 Subject: Make column names lowercase (fix #1674) --- database/changelog-3.3.xml | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/database/changelog-3.3.xml b/database/changelog-3.3.xml index 25b359401..1893a0200 100644 --- a/database/changelog-3.3.xml +++ b/database/changelog-3.3.xml @@ -23,7 +23,7 @@ - + @@ -41,10 +41,10 @@ - + - + @@ -67,30 +67,30 @@ - + - - + + - + - + - + - - + + - + @@ -98,16 +98,16 @@ - + - + - + - + @@ -134,11 +134,11 @@ - + - - - + + + @@ -159,10 +159,10 @@ - - - - + + + + @@ -178,7 +178,7 @@ - + -- cgit v1.2.3 From 2f9c09c52a96ee44b966b2a82d7c5f05cd663609 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Mar 2016 13:58:46 +1300 Subject: Update Java third party libraries --- pom.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index bfe2a886b..3f2cd802a 100644 --- a/pom.xml +++ b/pom.xml @@ -11,8 +11,8 @@ UTF-8 - 9.2.14.v20151106 - 2.22.1 + 9.2.15.v20160210 + 2.22.2 @@ -30,12 +30,12 @@ joda-time joda-time - 2.9.1 + 2.9.2 com.h2database h2 - 1.4.190 + 1.4.191 mysql @@ -45,7 +45,7 @@ org.postgresql postgresql - 9.4-1206-jdbc41 + 9.4.1208.jre7 com.mchange @@ -60,12 +60,12 @@ com.ning async-http-client - 1.9.31 + 1.9.33 org.slf4j slf4j-simple - 1.7.13 + 1.7.18 org.glassfish @@ -164,7 +164,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.3 + 3.5.1 1.7 1.7 -- cgit v1.2.3 From e312cf7059c4657f01c3e9fafb9c9a39e50bc2bb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 3 Mar 2016 14:13:05 +1300 Subject: Update JavaScript libraries --- web/debug.html | 4 ++-- web/release.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/debug.html b/web/debug.html index 792cfa5d9..351bb9f9f 100644 --- a/web/debug.html +++ b/web/debug.html @@ -5,7 +5,7 @@ Traccar - + @@ -14,7 +14,7 @@ - + - +