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 --- src/org/traccar/protocol/AstraProtocol.java | 43 ++++++++ src/org/traccar/protocol/AstraProtocolDecoder.java | 119 +++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 src/org/traccar/protocol/AstraProtocol.java create mode 100644 src/org/traccar/protocol/AstraProtocolDecoder.java (limited to 'src/org/traccar') 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; + } + +} -- 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(+) (limited to 'src/org/traccar') 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 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(-) (limited to 'src/org/traccar') 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 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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 (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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 (limited to 'src/org/traccar') 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 (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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 (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(+) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(+) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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(-) (limited to 'src/org/traccar') 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 a284dd6053c17c0decac2c8e30772b0c7107aef3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Mar 2016 13:46:13 +1300 Subject: Put encoders before decoders in pipeline --- src/org/traccar/protocol/BoxProtocol.java | 2 +- src/org/traccar/protocol/CarscopProtocol.java | 2 +- src/org/traccar/protocol/CityeasyProtocol.java | 2 +- src/org/traccar/protocol/FlextrackProtocol.java | 2 +- src/org/traccar/protocol/Gl100Protocol.java | 4 ++-- src/org/traccar/protocol/Gl200Protocol.java | 8 ++++---- src/org/traccar/protocol/GlobalSatProtocol.java | 2 +- src/org/traccar/protocol/GoSafeProtocol.java | 2 +- src/org/traccar/protocol/Gps103Protocol.java | 8 ++++---- src/org/traccar/protocol/GpsGateProtocol.java | 2 +- src/org/traccar/protocol/GpsmtaProtocol.java | 2 +- src/org/traccar/protocol/Gt06Protocol.java | 2 +- src/org/traccar/protocol/IntellitracProtocol.java | 2 +- src/org/traccar/protocol/KhdProtocol.java | 2 +- src/org/traccar/protocol/LaipacProtocol.java | 2 +- src/org/traccar/protocol/ManPowerProtocol.java | 2 +- src/org/traccar/protocol/MegastekProtocol.java | 2 +- src/org/traccar/protocol/MeiligaoProtocol.java | 4 ++-- src/org/traccar/protocol/MeitrackProtocol.java | 4 ++-- src/org/traccar/protocol/Mta6Protocol.java | 2 +- src/org/traccar/protocol/MtxProtocol.java | 2 +- src/org/traccar/protocol/OsmAndProtocol.java | 2 +- src/org/traccar/protocol/PathAwayProtocol.java | 2 +- src/org/traccar/protocol/PiligrimProtocol.java | 2 +- src/org/traccar/protocol/Pt3000Protocol.java | 2 +- src/org/traccar/protocol/SuntechProtocol.java | 4 ++-- src/org/traccar/protocol/T55Protocol.java | 2 +- src/org/traccar/protocol/TaipProtocol.java | 3 ++- src/org/traccar/protocol/Tk102Protocol.java | 2 +- src/org/traccar/protocol/Tk103Protocol.java | 4 ++-- src/org/traccar/protocol/Tlt2hProtocol.java | 2 +- src/org/traccar/protocol/TotemProtocol.java | 4 ++-- src/org/traccar/protocol/Tr20Protocol.java | 2 +- src/org/traccar/protocol/Tr900Protocol.java | 4 ++-- src/org/traccar/protocol/TrackboxProtocol.java | 2 +- src/org/traccar/protocol/TrvProtocol.java | 2 +- src/org/traccar/protocol/WatchProtocol.java | 2 +- src/org/traccar/protocol/WialonProtocol.java | 2 +- src/org/traccar/protocol/XirgoProtocol.java | 2 +- src/org/traccar/protocol/YwtProtocol.java | 2 +- 40 files changed, 54 insertions(+), 53 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/protocol/BoxProtocol.java b/src/org/traccar/protocol/BoxProtocol.java index ae8207002..33cfca282 100644 --- a/src/org/traccar/protocol/BoxProtocol.java +++ b/src/org/traccar/protocol/BoxProtocol.java @@ -37,8 +37,8 @@ public class BoxProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new BoxProtocolDecoder(BoxProtocol.this)); } }); diff --git a/src/org/traccar/protocol/CarscopProtocol.java b/src/org/traccar/protocol/CarscopProtocol.java index 1ac3e5e9f..4432fb87a 100644 --- a/src/org/traccar/protocol/CarscopProtocol.java +++ b/src/org/traccar/protocol/CarscopProtocol.java @@ -37,8 +37,8 @@ public class CarscopProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '^')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new CarscopProtocolDecoder(CarscopProtocol.this)); } }); diff --git a/src/org/traccar/protocol/CityeasyProtocol.java b/src/org/traccar/protocol/CityeasyProtocol.java index 1049e48eb..82302d2d7 100644 --- a/src/org/traccar/protocol/CityeasyProtocol.java +++ b/src/org/traccar/protocol/CityeasyProtocol.java @@ -41,8 +41,8 @@ public class CityeasyProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); - pipeline.addLast("objectDecoder", new CityeasyProtocolDecoder(CityeasyProtocol.this)); pipeline.addLast("objectEncoder", new CityeasyProtocolEncoder()); + pipeline.addLast("objectDecoder", new CityeasyProtocolDecoder(CityeasyProtocol.this)); } }); } diff --git a/src/org/traccar/protocol/FlextrackProtocol.java b/src/org/traccar/protocol/FlextrackProtocol.java index 0d1b13d8a..3b1aaa3d8 100644 --- a/src/org/traccar/protocol/FlextrackProtocol.java +++ b/src/org/traccar/protocol/FlextrackProtocol.java @@ -36,8 +36,8 @@ public class FlextrackProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "\r")); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new FlextrackProtocolDecoder(FlextrackProtocol.this)); } }); diff --git a/src/org/traccar/protocol/Gl100Protocol.java b/src/org/traccar/protocol/Gl100Protocol.java index cc2c826ab..f51834ea2 100644 --- a/src/org/traccar/protocol/Gl100Protocol.java +++ b/src/org/traccar/protocol/Gl100Protocol.java @@ -38,16 +38,16 @@ public class Gl100Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\0')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Gl100ProtocolDecoder(Gl100Protocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Gl100ProtocolDecoder(Gl100Protocol.this)); } }); diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java index 3aa69567d..701652e12 100644 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ b/src/org/traccar/protocol/Gl200Protocol.java @@ -44,19 +44,19 @@ public class Gl200Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "$", "\0")); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); + pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); + pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); } diff --git a/src/org/traccar/protocol/GlobalSatProtocol.java b/src/org/traccar/protocol/GlobalSatProtocol.java index 10db8e313..592ba152e 100644 --- a/src/org/traccar/protocol/GlobalSatProtocol.java +++ b/src/org/traccar/protocol/GlobalSatProtocol.java @@ -37,8 +37,8 @@ public class GlobalSatProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '!')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new GlobalSatProtocolDecoder(GlobalSatProtocol.this)); } }); diff --git a/src/org/traccar/protocol/GoSafeProtocol.java b/src/org/traccar/protocol/GoSafeProtocol.java index af2c2858d..bc1ed14de 100644 --- a/src/org/traccar/protocol/GoSafeProtocol.java +++ b/src/org/traccar/protocol/GoSafeProtocol.java @@ -36,8 +36,8 @@ public class GoSafeProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new GoSafeProtocolDecoder(GoSafeProtocol.this)); } }); diff --git a/src/org/traccar/protocol/Gps103Protocol.java b/src/org/traccar/protocol/Gps103Protocol.java index 6ddc2dea1..d8ad0a8b7 100644 --- a/src/org/traccar/protocol/Gps103Protocol.java +++ b/src/org/traccar/protocol/Gps103Protocol.java @@ -47,19 +47,19 @@ public class Gps103Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "\r\n", "\n", ";")); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("objectDecoder", new Gps103ProtocolDecoder(Gps103Protocol.this)); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gps103ProtocolEncoder()); + pipeline.addLast("objectDecoder", new Gps103ProtocolDecoder(Gps103Protocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("objectDecoder", new Gps103ProtocolDecoder(Gps103Protocol.this)); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gps103ProtocolEncoder()); + pipeline.addLast("objectDecoder", new Gps103ProtocolDecoder(Gps103Protocol.this)); } }); } diff --git a/src/org/traccar/protocol/GpsGateProtocol.java b/src/org/traccar/protocol/GpsGateProtocol.java index 9f07550e4..c654810b1 100644 --- a/src/org/traccar/protocol/GpsGateProtocol.java +++ b/src/org/traccar/protocol/GpsGateProtocol.java @@ -37,8 +37,8 @@ public class GpsGateProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new GpsGateProtocolDecoder(GpsGateProtocol.this)); } }); diff --git a/src/org/traccar/protocol/GpsmtaProtocol.java b/src/org/traccar/protocol/GpsmtaProtocol.java index fe586644a..d1eaa2fd3 100644 --- a/src/org/traccar/protocol/GpsmtaProtocol.java +++ b/src/org/traccar/protocol/GpsmtaProtocol.java @@ -35,8 +35,8 @@ public class GpsmtaProtocol extends BaseProtocol { serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new GpsmtaProtocolDecoder(GpsmtaProtocol.this)); } }); diff --git a/src/org/traccar/protocol/Gt06Protocol.java b/src/org/traccar/protocol/Gt06Protocol.java index eac9ad71a..4630342a5 100644 --- a/src/org/traccar/protocol/Gt06Protocol.java +++ b/src/org/traccar/protocol/Gt06Protocol.java @@ -37,8 +37,8 @@ public class Gt06Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new Gt06FrameDecoder()); - pipeline.addLast("objectDecoder", new Gt06ProtocolDecoder(Gt06Protocol.this)); pipeline.addLast("objectEncoder", new Gt06ProtocolEncoder()); + pipeline.addLast("objectDecoder", new Gt06ProtocolDecoder(Gt06Protocol.this)); } }); } diff --git a/src/org/traccar/protocol/IntellitracProtocol.java b/src/org/traccar/protocol/IntellitracProtocol.java index c06585547..a6caf770f 100644 --- a/src/org/traccar/protocol/IntellitracProtocol.java +++ b/src/org/traccar/protocol/IntellitracProtocol.java @@ -36,8 +36,8 @@ public class IntellitracProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new IntellitracFrameDecoder(1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new IntellitracProtocolDecoder(IntellitracProtocol.this)); } }); diff --git a/src/org/traccar/protocol/KhdProtocol.java b/src/org/traccar/protocol/KhdProtocol.java index a2edbfd5e..93edb0415 100644 --- a/src/org/traccar/protocol/KhdProtocol.java +++ b/src/org/traccar/protocol/KhdProtocol.java @@ -39,8 +39,8 @@ public class KhdProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(512, 3, 2)); - pipeline.addLast("objectDecoder", new KhdProtocolDecoder(KhdProtocol.this)); pipeline.addLast("objectEncoder", new KhdProtocolEncoder()); + pipeline.addLast("objectDecoder", new KhdProtocolDecoder(KhdProtocol.this)); } }); } diff --git a/src/org/traccar/protocol/LaipacProtocol.java b/src/org/traccar/protocol/LaipacProtocol.java index fff7b1c32..c2e5c585e 100644 --- a/src/org/traccar/protocol/LaipacProtocol.java +++ b/src/org/traccar/protocol/LaipacProtocol.java @@ -37,8 +37,8 @@ public class LaipacProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new LaipacProtocolDecoder(LaipacProtocol.this)); } }); diff --git a/src/org/traccar/protocol/ManPowerProtocol.java b/src/org/traccar/protocol/ManPowerProtocol.java index 4fc194963..647a1bea7 100644 --- a/src/org/traccar/protocol/ManPowerProtocol.java +++ b/src/org/traccar/protocol/ManPowerProtocol.java @@ -37,8 +37,8 @@ public class ManPowerProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ';')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new ManPowerProtocolDecoder(ManPowerProtocol.this)); } }); diff --git a/src/org/traccar/protocol/MegastekProtocol.java b/src/org/traccar/protocol/MegastekProtocol.java index cdf891afe..f61a4443c 100644 --- a/src/org/traccar/protocol/MegastekProtocol.java +++ b/src/org/traccar/protocol/MegastekProtocol.java @@ -36,8 +36,8 @@ public class MegastekProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new MegastekFrameDecoder()); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new MegastekProtocolDecoder(MegastekProtocol.this)); } }); diff --git a/src/org/traccar/protocol/MeiligaoProtocol.java b/src/org/traccar/protocol/MeiligaoProtocol.java index 05dd8834b..2e4226e19 100644 --- a/src/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/org/traccar/protocol/MeiligaoProtocol.java @@ -43,15 +43,15 @@ public class MeiligaoProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new MeiligaoFrameDecoder()); - pipeline.addLast("objectDecoder", new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); pipeline.addLast("objectEncoder", new MeiligaoProtocolEncoder()); + pipeline.addLast("objectDecoder", new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("objectDecoder", new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); pipeline.addLast("objectEncoder", new MeiligaoProtocolEncoder()); + pipeline.addLast("objectDecoder", new MeiligaoProtocolDecoder(MeiligaoProtocol.this)); } }); } diff --git a/src/org/traccar/protocol/MeitrackProtocol.java b/src/org/traccar/protocol/MeitrackProtocol.java index 266d9bcd5..e758e5f41 100644 --- a/src/org/traccar/protocol/MeitrackProtocol.java +++ b/src/org/traccar/protocol/MeitrackProtocol.java @@ -45,8 +45,8 @@ public class MeitrackProtocol extends BaseProtocol { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new MeitrackFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("objectDecoder", new MeitrackProtocolDecoder(MeitrackProtocol.this)); pipeline.addLast("objectEncoder", new MeitrackProtocolEncoder()); + pipeline.addLast("objectDecoder", new MeitrackProtocolDecoder(MeitrackProtocol.this)); } }; server.setEndianness(ByteOrder.LITTLE_ENDIAN); @@ -55,8 +55,8 @@ public class MeitrackProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("objectDecoder", new MeitrackProtocolDecoder(MeitrackProtocol.this)); pipeline.addLast("objectEncoder", new MeitrackProtocolEncoder()); + pipeline.addLast("objectDecoder", new MeitrackProtocolDecoder(MeitrackProtocol.this)); } }; server.setEndianness(ByteOrder.LITTLE_ENDIAN); diff --git a/src/org/traccar/protocol/Mta6Protocol.java b/src/org/traccar/protocol/Mta6Protocol.java index 8232b850c..607bf8118 100644 --- a/src/org/traccar/protocol/Mta6Protocol.java +++ b/src/org/traccar/protocol/Mta6Protocol.java @@ -35,8 +35,8 @@ public class Mta6Protocol extends BaseProtocol { serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("httpDecoder", new HttpRequestDecoder()); pipeline.addLast("httpEncoder", new HttpResponseEncoder()); + pipeline.addLast("httpDecoder", new HttpRequestDecoder()); pipeline.addLast("objectDecoder", new Mta6ProtocolDecoder( Mta6Protocol.this, !Context.getConfig().getBoolean(getName() + ".can"))); } diff --git a/src/org/traccar/protocol/MtxProtocol.java b/src/org/traccar/protocol/MtxProtocol.java index 4fba981a5..e0bef8350 100644 --- a/src/org/traccar/protocol/MtxProtocol.java +++ b/src/org/traccar/protocol/MtxProtocol.java @@ -37,8 +37,8 @@ public class MtxProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new MtxProtocolDecoder(MtxProtocol.this)); } }); diff --git a/src/org/traccar/protocol/OsmAndProtocol.java b/src/org/traccar/protocol/OsmAndProtocol.java index 1e60ae807..3b473c435 100644 --- a/src/org/traccar/protocol/OsmAndProtocol.java +++ b/src/org/traccar/protocol/OsmAndProtocol.java @@ -35,8 +35,8 @@ public class OsmAndProtocol extends BaseProtocol { serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("httpDecoder", new HttpRequestDecoder()); pipeline.addLast("httpEncoder", new HttpResponseEncoder()); + pipeline.addLast("httpDecoder", new HttpRequestDecoder()); pipeline.addLast("objectDecoder", new OsmAndProtocolDecoder(OsmAndProtocol.this)); } }); diff --git a/src/org/traccar/protocol/PathAwayProtocol.java b/src/org/traccar/protocol/PathAwayProtocol.java index dfa34abd5..d7efdfaf6 100644 --- a/src/org/traccar/protocol/PathAwayProtocol.java +++ b/src/org/traccar/protocol/PathAwayProtocol.java @@ -35,8 +35,8 @@ public class PathAwayProtocol extends BaseProtocol { serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("httpDecoder", new HttpRequestDecoder()); pipeline.addLast("httpEncoder", new HttpResponseEncoder()); + pipeline.addLast("httpDecoder", new HttpRequestDecoder()); pipeline.addLast("objectDecoder", new PathAwayProtocolDecoder(PathAwayProtocol.this)); } }); diff --git a/src/org/traccar/protocol/PiligrimProtocol.java b/src/org/traccar/protocol/PiligrimProtocol.java index 0478835d9..11aafa412 100644 --- a/src/org/traccar/protocol/PiligrimProtocol.java +++ b/src/org/traccar/protocol/PiligrimProtocol.java @@ -36,9 +36,9 @@ public class PiligrimProtocol extends BaseProtocol { serverList.add(new TrackerServer(new ServerBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("httpDecoder", new HttpRequestDecoder()); pipeline.addLast("httpAggregator", new HttpChunkAggregator(16384)); - pipeline.addLast("httpEncoder", new HttpResponseEncoder()); pipeline.addLast("objectDecoder", new PiligrimProtocolDecoder(PiligrimProtocol.this)); } }); diff --git a/src/org/traccar/protocol/Pt3000Protocol.java b/src/org/traccar/protocol/Pt3000Protocol.java index bde8e7709..3a22be214 100644 --- a/src/org/traccar/protocol/Pt3000Protocol.java +++ b/src/org/traccar/protocol/Pt3000Protocol.java @@ -37,8 +37,8 @@ public class Pt3000Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, 'd')); // probably wrong - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Pt3000ProtocolDecoder(Pt3000Protocol.this)); } }); diff --git a/src/org/traccar/protocol/SuntechProtocol.java b/src/org/traccar/protocol/SuntechProtocol.java index d3f5d6009..e06ed2aac 100644 --- a/src/org/traccar/protocol/SuntechProtocol.java +++ b/src/org/traccar/protocol/SuntechProtocol.java @@ -41,10 +41,10 @@ public class SuntechProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("objectDecoder", new SuntechProtocolDecoder(SuntechProtocol.this)); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new SuntechProtocolEncoder()); + pipeline.addLast("objectDecoder", new SuntechProtocolDecoder(SuntechProtocol.this)); } }); } diff --git a/src/org/traccar/protocol/T55Protocol.java b/src/org/traccar/protocol/T55Protocol.java index 21f1d3e6c..041413a65 100644 --- a/src/org/traccar/protocol/T55Protocol.java +++ b/src/org/traccar/protocol/T55Protocol.java @@ -37,8 +37,8 @@ public class T55Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new T55ProtocolDecoder(T55Protocol.this)); } }); diff --git a/src/org/traccar/protocol/TaipProtocol.java b/src/org/traccar/protocol/TaipProtocol.java index 439fe7696..a3b744e70 100644 --- a/src/org/traccar/protocol/TaipProtocol.java +++ b/src/org/traccar/protocol/TaipProtocol.java @@ -38,14 +38,15 @@ public class TaipProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '<')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new TaipProtocolDecoder(TaipProtocol.this, true)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new TaipProtocolDecoder(TaipProtocol.this, false)); } diff --git a/src/org/traccar/protocol/Tk102Protocol.java b/src/org/traccar/protocol/Tk102Protocol.java index 4e1d067f9..1f4eda730 100644 --- a/src/org/traccar/protocol/Tk102Protocol.java +++ b/src/org/traccar/protocol/Tk102Protocol.java @@ -37,8 +37,8 @@ public class Tk102Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ']')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Tk102ProtocolDecoder(Tk102Protocol.this)); } }); diff --git a/src/org/traccar/protocol/Tk103Protocol.java b/src/org/traccar/protocol/Tk103Protocol.java index b14264091..324c01a31 100644 --- a/src/org/traccar/protocol/Tk103Protocol.java +++ b/src/org/traccar/protocol/Tk103Protocol.java @@ -38,16 +38,16 @@ public class Tk103Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ')')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Tk103ProtocolDecoder(Tk103Protocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Tk103ProtocolDecoder(Tk103Protocol.this)); } }); diff --git a/src/org/traccar/protocol/Tlt2hProtocol.java b/src/org/traccar/protocol/Tlt2hProtocol.java index 3a1bf99ff..14787537d 100644 --- a/src/org/traccar/protocol/Tlt2hProtocol.java +++ b/src/org/traccar/protocol/Tlt2hProtocol.java @@ -37,8 +37,8 @@ public class Tlt2hProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(32 * 1024, "##\r\n")); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Tlt2hProtocolDecoder(Tlt2hProtocol.this)); } }); diff --git a/src/org/traccar/protocol/TotemProtocol.java b/src/org/traccar/protocol/TotemProtocol.java index 097f6a593..4d7f0a135 100644 --- a/src/org/traccar/protocol/TotemProtocol.java +++ b/src/org/traccar/protocol/TotemProtocol.java @@ -41,10 +41,10 @@ public class TotemProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new TotemFrameDecoder()); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("objectDecoder", new TotemProtocolDecoder(TotemProtocol.this)); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new TotemProtocolEncoder()); + pipeline.addLast("objectDecoder", new TotemProtocolDecoder(TotemProtocol.this)); } }); } diff --git a/src/org/traccar/protocol/Tr20Protocol.java b/src/org/traccar/protocol/Tr20Protocol.java index 8c5a27ae2..4e55d5f98 100644 --- a/src/org/traccar/protocol/Tr20Protocol.java +++ b/src/org/traccar/protocol/Tr20Protocol.java @@ -37,8 +37,8 @@ public class Tr20Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Tr20ProtocolDecoder(Tr20Protocol.this)); } }); diff --git a/src/org/traccar/protocol/Tr900Protocol.java b/src/org/traccar/protocol/Tr900Protocol.java index 4db0a2239..d54e4cb3c 100644 --- a/src/org/traccar/protocol/Tr900Protocol.java +++ b/src/org/traccar/protocol/Tr900Protocol.java @@ -38,16 +38,16 @@ public class Tr900Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Tr900ProtocolDecoder(Tr900Protocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new Tr900ProtocolDecoder(Tr900Protocol.this)); } }); diff --git a/src/org/traccar/protocol/TrackboxProtocol.java b/src/org/traccar/protocol/TrackboxProtocol.java index 68554394e..5477de852 100644 --- a/src/org/traccar/protocol/TrackboxProtocol.java +++ b/src/org/traccar/protocol/TrackboxProtocol.java @@ -37,8 +37,8 @@ public class TrackboxProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new TrackboxProtocolDecoder(TrackboxProtocol.this)); } }); diff --git a/src/org/traccar/protocol/TrvProtocol.java b/src/org/traccar/protocol/TrvProtocol.java index 916b7d612..af598ea02 100644 --- a/src/org/traccar/protocol/TrvProtocol.java +++ b/src/org/traccar/protocol/TrvProtocol.java @@ -37,8 +37,8 @@ public class TrvProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new TrvProtocolDecoder(TrvProtocol.this)); } }); diff --git a/src/org/traccar/protocol/WatchProtocol.java b/src/org/traccar/protocol/WatchProtocol.java index 3a10f9c59..1198f689e 100644 --- a/src/org/traccar/protocol/WatchProtocol.java +++ b/src/org/traccar/protocol/WatchProtocol.java @@ -37,8 +37,8 @@ public class WatchProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ']')); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new WatchProtocolDecoder(WatchProtocol.this)); } }); diff --git a/src/org/traccar/protocol/WialonProtocol.java b/src/org/traccar/protocol/WialonProtocol.java index 6fe924c2d..d0d3aa446 100644 --- a/src/org/traccar/protocol/WialonProtocol.java +++ b/src/org/traccar/protocol/WialonProtocol.java @@ -37,8 +37,8 @@ public class WialonProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(4 * 1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new WialonProtocolDecoder(WialonProtocol.this)); } }); diff --git a/src/org/traccar/protocol/XirgoProtocol.java b/src/org/traccar/protocol/XirgoProtocol.java index 83c373175..f186c731f 100644 --- a/src/org/traccar/protocol/XirgoProtocol.java +++ b/src/org/traccar/protocol/XirgoProtocol.java @@ -37,8 +37,8 @@ public class XirgoProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "##")); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new XirgoProtocolDecoder(XirgoProtocol.this)); } }); diff --git a/src/org/traccar/protocol/YwtProtocol.java b/src/org/traccar/protocol/YwtProtocol.java index e9cdb1615..3fa154ec0 100644 --- a/src/org/traccar/protocol/YwtProtocol.java +++ b/src/org/traccar/protocol/YwtProtocol.java @@ -37,8 +37,8 @@ public class YwtProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new YwtProtocolDecoder(YwtProtocol.this)); } }); -- cgit v1.2.3 From 507cc9154d8a40d96fd52447380120c9c3a5b98c Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 5 Mar 2016 11:02:28 +1300 Subject: Further improve GL200 decoder class --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 4 ++-- test/org/traccar/protocol/Gl200ProtocolDecoderTest.java | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 8605d8295..605add0d5 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -144,11 +144,11 @@ 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 - .number("(d{6})?,,,,") // device status + .number("(x{6})?,,,,") // device status .groupEnd() .number("(dddd)(dd)(dd)") // date .number("(dd)(dd)(dd)").optional(2) // time diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java index 6b6e763ad..b0e094c9d 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()); + verifyPositions(decoder, text( + "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); + 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$")); @@ -22,7 +25,7 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { 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( + verifyPositions(decoder, text( "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); verifyPosition(decoder, text( @@ -34,7 +37,7 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, false, text( "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,0F0106,862193020451183,,,10,1,1,0.0,163,,-57.513617,-25.368191,20150918182145,,,,,,21235.0,,,,0,210100,,,,20150918182149,00B8$")); verifyPosition(decoder, text( @@ -58,7 +61,7 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { verifyNothing(decoder, text( "+RESP:GTINF,359464030073766,8938003990320469804f,18,99,100,1,0,+2.00,0,20131018084015,00EE,0103090402")); - verifyPosition(decoder, text( + verifyPositions(decoder, text( "+RESP:GTFRI,04040C,359231038939904,,,10,1,2,0.0,117,346.0,8.924243,50.798077,20130618122040,0262,0002,0299,109C,00,0.0,,,,,,,,,20130618122045,00F6")); verifyPosition(decoder, text( @@ -97,7 +100,7 @@ public class Gl200ProtocolDecoderTest extends ProtocolTest { 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( + verifyPositions(decoder, text( "+BUFF:GTFRI,210101,863286020016706,,,10,1,1,,,,49.903915,40.391669,20140818105815,,,,,,,,,,,210100,,,,,000C$")); verifyPositions(decoder, text( -- cgit v1.2.3 From 10fff38e197140d9966ca81185dc5e8f25983ffb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 5 Mar 2016 11:15:24 +1300 Subject: Handle some async socket exceptions --- src/org/traccar/api/AsyncSocket.java | 4 ++-- src/org/traccar/api/AsyncSocketServlet.java | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/api/AsyncSocket.java b/src/org/traccar/api/AsyncSocket.java index 7de182d7e..96ad2c450 100644 --- a/src/org/traccar/api/AsyncSocket.java +++ b/src/org/traccar/api/AsyncSocket.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. @@ -66,7 +66,7 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U } private void sendData(String key, Collection data) { - if (!data.isEmpty()) { + if (!data.isEmpty() && isConnected()) { JsonObjectBuilder json = Json.createObjectBuilder(); json.add(key, JsonConverter.arrayToJson(data)); getRemote().sendString(json.build().toString(), null); diff --git a/src/org/traccar/api/AsyncSocketServlet.java b/src/org/traccar/api/AsyncSocketServlet.java index edfa8939b..ef6cef732 100644 --- a/src/org/traccar/api/AsyncSocketServlet.java +++ b/src/org/traccar/api/AsyncSocketServlet.java @@ -33,8 +33,12 @@ public class AsyncSocketServlet extends WebSocketServlet { factory.setCreator(new WebSocketCreator() { @Override public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) { - long userId = (Long) req.getSession().getAttribute(SessionResource.USER_ID_KEY); - return new AsyncSocket(userId); + if (req.getSession() != null) { + long userId = (Long) req.getSession().getAttribute(SessionResource.USER_ID_KEY); + return new AsyncSocket(userId); + } else { + return null; + } } }); } -- cgit v1.2.3 From 62ddfb226a55384fdfd1e0dd5a0436d55bb53d49 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 7 Mar 2016 11:15:12 +1300 Subject: Properly compare Java strings --- src/org/traccar/api/SecurityRequestFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/api/SecurityRequestFilter.java b/src/org/traccar/api/SecurityRequestFilter.java index d4fb15059..4c6137ede 100644 --- a/src/org/traccar/api/SecurityRequestFilter.java +++ b/src/org/traccar/api/SecurityRequestFilter.java @@ -56,8 +56,8 @@ 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()); + if (requestContext.getMethod().equals("OPTIONS")) { + throw new WebApplicationException(Response.status(Response.Status.OK).build()); } SecurityContext securityContext = null; -- cgit v1.2.3 From 77158ade988919ce63c905f8328dc6af2ac097c3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 7 Mar 2016 23:53:46 +1300 Subject: Change Meitrack encoder implementation --- src/org/traccar/helper/Checksum.java | 13 +++++++++--- src/org/traccar/protocol/MeitrackProtocol.java | 1 + .../traccar/protocol/MeitrackProtocolEncoder.java | 21 +++++++++++++++----- .../protocol/MeitrackProtocolEncoderTest.java | 23 ++++++++++++++++++++++ 4 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 test/org/traccar/protocol/MeitrackProtocolEncoderTest.java (limited to 'src/org/traccar') diff --git a/src/org/traccar/helper/Checksum.java b/src/org/traccar/helper/Checksum.java index e6b6cd2c8..c156e53f7 100644 --- a/src/org/traccar/helper/Checksum.java +++ b/src/org/traccar/helper/Checksum.java @@ -158,13 +158,20 @@ public final class Checksum { public static String nmea(String msg) { int checksum = 0; - byte[] bytes = msg.getBytes(Charset.defaultCharset()); - for (int i = 1; i < msg.length(); i++) { - checksum ^= bytes[i]; + for (byte b : msg.getBytes(Charset.defaultCharset())) { + checksum ^= b; } return String.format("*%02x", checksum).toUpperCase(); } + public static String sum(String msg) { + byte checksum = 0; + for (byte b : msg.getBytes(Charset.defaultCharset())) { + checksum += b; + } + return String.format("%02X", checksum).toUpperCase(); + } + public static long luhn(long imei) { long checksum = 0; long remain = imei; diff --git a/src/org/traccar/protocol/MeitrackProtocol.java b/src/org/traccar/protocol/MeitrackProtocol.java index e758e5f41..e5b5ddf2b 100644 --- a/src/org/traccar/protocol/MeitrackProtocol.java +++ b/src/org/traccar/protocol/MeitrackProtocol.java @@ -31,6 +31,7 @@ public class MeitrackProtocol extends BaseProtocol { public MeitrackProtocol() { super("meitrack"); setSupportedCommands( + Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, Command.TYPE_ALARM_ARM, diff --git a/src/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/org/traccar/protocol/MeitrackProtocolEncoder.java index 90fa5b624..381935c58 100644 --- a/src/org/traccar/protocol/MeitrackProtocolEncoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -16,25 +16,36 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.helper.Checksum; import org.traccar.helper.Log; import org.traccar.model.Command; public class MeitrackProtocolEncoder extends StringProtocolEncoder { + private Object formatCommand(Command command, char dataId, String content) { + String uniqueId = getUniqueId(command.getDeviceId()); + int length = 1 + uniqueId.length() + 1 + content.length() + 5; + String result = String.format("@@%c%02d,%s,%s*", dataId, length, uniqueId, content); + result += Checksum.sum(result) + "\r\n"; + return result; + } + @Override protected Object encodeCommand(Command command) { switch (command.getType()) { + case Command.TYPE_POSITION_SINGLE: + return formatCommand(command, 'Q', "A10"); case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "@@M33,{%s},C01,0,12222*00\r\n", Command.KEY_UNIQUE_ID); + return formatCommand(command, 'M', "C01,0,12222"); case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "@@M33,{%s},C01,0,02222*00\r\n", Command.KEY_UNIQUE_ID); + return formatCommand(command, 'M', "C01,0,02222"); case Command.TYPE_ALARM_ARM: - return formatCommand(command, "@@M33,{%s},C01,0,22122*00\r\n", Command.KEY_UNIQUE_ID); + return formatCommand(command, 'M', "C01,0,22122"); case Command.TYPE_ALARM_DISARM: - return formatCommand(command, "@@M33,{%s},C01,0,22022*00\r\n", Command.KEY_UNIQUE_ID); + return formatCommand(command, 'M', "C01,0,22022"); case Command.TYPE_REQUEST_PHOTO: - return formatCommand(command, "@@D46,{%s},D03,1,camera_picture.jpg*00\r\n", Command.KEY_UNIQUE_ID); + return formatCommand(command, 'D', "D03,1,camera_picture.jpg"); default: Log.warning(new UnsupportedOperationException(command.getType())); break; diff --git a/test/org/traccar/protocol/MeitrackProtocolEncoderTest.java b/test/org/traccar/protocol/MeitrackProtocolEncoderTest.java new file mode 100644 index 000000000..64812c1da --- /dev/null +++ b/test/org/traccar/protocol/MeitrackProtocolEncoderTest.java @@ -0,0 +1,23 @@ +package org.traccar.protocol; + +import org.junit.Assert; +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; + +public class MeitrackProtocolEncoderTest extends ProtocolTest { + + @Test + public void testEncode() throws Exception { + + MeitrackProtocolEncoder encoder = new MeitrackProtocolEncoder(); + + Command command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_POSITION_SINGLE); + + Assert.assertEquals("@@Q25,123456789012345,A10*68\r\n", encoder.encodeCommand(command)); + + } + +} -- cgit v1.2.3 From b89c936b9ffb0bb3eda36830dba7a6870bbc86c5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 8 Mar 2016 09:49:06 +1300 Subject: Decode GL200 status field --- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 605add0d5..574f9a8c3 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -22,6 +22,7 @@ import java.util.regex.Pattern; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; +import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -148,7 +149,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { .number("(x+)?,") // adc 1 .number("(x+)?,") // adc 2 .number("(d{1,3})?,") // battery - .number("(x{6})?,,,,") // device status + .number("(?:(xx)(xx)(xx))?,,,,") // device status .groupEnd() .number("(dddd)(dd)(dd)") // date .number("(dd)(dd)(dd)").optional(2) // time @@ -350,7 +351,17 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { 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()); + + if (parser.hasNext(3)) { + int ignition = parser.nextInt(16); + if (BitUtil.check(ignition, 4)) { + position.set(Event.KEY_IGNITION, false); + } else if (BitUtil.check(ignition, 5)) { + position.set(Event.KEY_IGNITION, true); + } + position.set(Event.KEY_INPUT, parser.nextInt(16)); + position.set(Event.KEY_OUTPUT, parser.nextInt(16)); + } // workaround for wrong location time if (parser.hasNext(6)) { -- cgit v1.2.3 From 1f2328bd8f4e341dda897fcd52418beb6cf1b83a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 8 Mar 2016 22:05:40 +1300 Subject: Add new and update old data models --- .../traccar/api/resource/PermissionResource.java | 6 +-- src/org/traccar/database/DataManager.java | 6 +-- src/org/traccar/database/PermissionsManager.java | 4 +- src/org/traccar/model/Device.java | 12 ++++- src/org/traccar/model/DevicePermission.java | 40 +++++++++++++++++ src/org/traccar/model/Group.java | 52 ++++++++++++++++++++++ src/org/traccar/model/GroupPermission.java | 40 +++++++++++++++++ src/org/traccar/model/Permission.java | 40 ----------------- 8 files changed, 151 insertions(+), 49 deletions(-) create mode 100644 src/org/traccar/model/DevicePermission.java create mode 100644 src/org/traccar/model/Group.java create mode 100644 src/org/traccar/model/GroupPermission.java delete mode 100644 src/org/traccar/model/Permission.java (limited to 'src/org/traccar') diff --git a/src/org/traccar/api/resource/PermissionResource.java b/src/org/traccar/api/resource/PermissionResource.java index 50deb77c2..7cf2b4ed9 100644 --- a/src/org/traccar/api/resource/PermissionResource.java +++ b/src/org/traccar/api/resource/PermissionResource.java @@ -17,7 +17,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; -import org.traccar.model.Permission; +import org.traccar.model.DevicePermission; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -34,7 +34,7 @@ import java.sql.SQLException; public class PermissionResource extends BaseResource { @POST - public Response add(Permission entity) throws SQLException { + public Response add(DevicePermission entity) throws SQLException { Context.getPermissionsManager().checkAdmin(getUserId()); Context.getDataManager().linkDevice(entity.getUserId(), entity.getDeviceId()); Context.getPermissionsManager().refresh(); @@ -42,7 +42,7 @@ public class PermissionResource extends BaseResource { } @DELETE - public Response remove(Permission entity) throws SQLException { + public Response remove(DevicePermission entity) throws SQLException { Context.getPermissionsManager().checkAdmin(getUserId()); Context.getDataManager().unlinkDevice(entity.getUserId(), entity.getDeviceId()); Context.getPermissionsManager().refresh(); diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index 73984952e..f040ecd20 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -39,7 +39,7 @@ import org.traccar.Config; import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.MiscFormatter; -import org.traccar.model.Permission; +import org.traccar.model.DevicePermission; import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.User; @@ -221,9 +221,9 @@ public class DataManager implements IdentityManager { .executeUpdate(); } - public Collection getPermissions() throws SQLException { + public Collection getPermissions() throws SQLException { return QueryBuilder.create(dataSource, getQuery("database.getPermissionsAll")) - .executeQuery(Permission.class); + .executeQuery(DevicePermission.class); } public Collection getAllDevices() throws SQLException { diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index c676dea23..29228ceeb 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -22,7 +22,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import org.traccar.helper.Log; -import org.traccar.model.Permission; +import org.traccar.model.DevicePermission; import org.traccar.model.Server; import org.traccar.model.User; @@ -56,7 +56,7 @@ public class PermissionsManager { for (User user : dataManager.getUsers()) { users.put(user.getId(), user); } - for (Permission permission : dataManager.getPermissions()) { + for (DevicePermission permission : dataManager.getPermissions()) { getPermissions(permission.getUserId()).add(permission.getDeviceId()); } } catch (SQLException error) { diff --git a/src/org/traccar/model/Device.java b/src/org/traccar/model/Device.java index 7ca9fc843..934e753b1 100644 --- a/src/org/traccar/model/Device.java +++ b/src/org/traccar/model/Device.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. @@ -91,4 +91,14 @@ public class Device { this.positionId = positionId; } + private long groupId; + + public long getGroupId() { + return groupId; + } + + public void setGroupId(long groupId) { + this.groupId = groupId; + } + } diff --git a/src/org/traccar/model/DevicePermission.java b/src/org/traccar/model/DevicePermission.java new file mode 100644 index 000000000..b3bc0cae0 --- /dev/null +++ b/src/org/traccar/model/DevicePermission.java @@ -0,0 +1,40 @@ +/* + * 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. + * 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.model; + +public class DevicePermission { + + private long userId; + + public long getUserId() { + return userId; + } + + public void setUserId(long userId) { + this.userId = userId; + } + + private long deviceId; + + public long getDeviceId() { + return deviceId; + } + + public void setDeviceId(long deviceId) { + this.deviceId = deviceId; + } + +} diff --git a/src/org/traccar/model/Group.java b/src/org/traccar/model/Group.java new file mode 100644 index 000000000..24f7973c8 --- /dev/null +++ b/src/org/traccar/model/Group.java @@ -0,0 +1,52 @@ +/* + * 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.model; + +import java.util.Date; + +public class Group { + + private long id; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + private long groupId; + + public long getGroupId() { + return groupId; + } + + public void setGroupId(long groupId) { + this.groupId = groupId; + } + +} diff --git a/src/org/traccar/model/GroupPermission.java b/src/org/traccar/model/GroupPermission.java new file mode 100644 index 000000000..9b0011575 --- /dev/null +++ b/src/org/traccar/model/GroupPermission.java @@ -0,0 +1,40 @@ +/* + * 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.model; + +public class GroupPermission { + + private long userId; + + public long getUserId() { + return userId; + } + + public void setUserId(long userId) { + this.userId = userId; + } + + private long groupId; + + public long getGroupId() { + return groupId; + } + + public void setGroupId(long groupId) { + this.groupId = groupId; + } + +} diff --git a/src/org/traccar/model/Permission.java b/src/org/traccar/model/Permission.java deleted file mode 100644 index 393de2359..000000000 --- a/src/org/traccar/model/Permission.java +++ /dev/null @@ -1,40 +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.model; - -public class Permission { - - private long userId; - - public long getUserId() { - return userId; - } - - public void setUserId(long userId) { - this.userId = userId; - } - - private long deviceId; - - public long getDeviceId() { - return deviceId; - } - - public void setDeviceId(long deviceId) { - this.deviceId = deviceId; - } - -} -- cgit v1.2.3 From 8cd4f224572e55cd3c87119db24b8adcf1f0351a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 8 Mar 2016 22:41:32 +1300 Subject: Start refactoring permissions manager --- src/org/traccar/database/PermissionsManager.java | 32 ++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 29228ceeb..854732fa2 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.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,13 +34,21 @@ public class PermissionsManager { private final Map users = new HashMap<>(); - private final Map> permissions = new HashMap<>(); + private final Map> groupPermissions = new HashMap<>(); + private final Map> devicePermissions = new HashMap<>(); - private Set getPermissions(long userId) { - if (!permissions.containsKey(userId)) { - permissions.put(userId, new HashSet()); + private Set getGroupPermissions(long userId) { + if (!groupPermissions.containsKey(userId)) { + groupPermissions.put(userId, new HashSet()); } - return permissions.get(userId); + return groupPermissions.get(userId); + } + + private Set getDevicePermissions(long userId) { + if (!devicePermissions.containsKey(userId)) { + devicePermissions.put(userId, new HashSet()); + } + return devicePermissions.get(userId); } public PermissionsManager(DataManager dataManager) { @@ -50,14 +58,14 @@ public class PermissionsManager { public final void refresh() { users.clear(); - permissions.clear(); + devicePermissions.clear(); try { server = dataManager.getServer(); for (User user : dataManager.getUsers()) { users.put(user.getId(), user); } for (DevicePermission permission : dataManager.getPermissions()) { - getPermissions(permission.getUserId()).add(permission.getDeviceId()); + getDevicePermissions(permission.getUserId()).add(permission.getDeviceId()); } } catch (SQLException error) { Log.warning(error); @@ -80,12 +88,16 @@ public class PermissionsManager { } } + public Collection allowedGroups(long userId) { + return getGroupPermissions(userId); + } + public Collection allowedDevices(long userId) { - return getPermissions(userId); + return getDevicePermissions(userId); } public void checkDevice(long userId, long deviceId) throws SecurityException { - if (!getPermissions(userId).contains(deviceId)) { + if (!getDevicePermissions(userId).contains(deviceId)) { throw new SecurityException("Device access denied"); } } -- cgit v1.2.3 From e2da4f276230e3687e42b11b4d94889fb3889436 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 8 Mar 2016 23:02:40 +1300 Subject: Extend GpsGate protocol support --- .../traccar/protocol/GpsGateProtocolDecoder.java | 60 ++++++++++++++++++++-- .../protocol/GpsGateProtocolDecoderTest.java | 6 +++ 2 files changed, 61 insertions(+), 5 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/protocol/GpsGateProtocolDecoder.java b/src/org/traccar/protocol/GpsGateProtocolDecoder.java index 421dc5304..b48fa6266 100644 --- a/src/org/traccar/protocol/GpsGateProtocolDecoder.java +++ b/src/org/traccar/protocol/GpsGateProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2013 - 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,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.helper.Checksum; @@ -31,7 +32,7 @@ public class GpsGateProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Pattern PATTERN = new PatternBuilder() + private static final Pattern PATTERN_GPRMC = new PatternBuilder() .text("$GPRMC,") .number("(dd)(dd)(dd).?(d+)?,") // time .expression("([AV]),") // validity @@ -45,6 +46,24 @@ public class GpsGateProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private static final Pattern PATTERN_FRCMD = new PatternBuilder() + .text("$FRCMD,") + .number("(d+),") // imei + .expression("[^,]*,") // command + .expression("[^,]*,") + .number("(dd)(dd.d+),") // latitude + .expression("([NS]),") + .number("(ddd)(dd.d+),") // longitude + .expression("([EW]),") + .number("(d+.?d*),") // altitude + .number("(d+.?d*),") // speed + .number("(d+.?d*),") // course + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd).?(d+)?,") // time + .expression("([01]),") // validity + .any() + .compile(); + private void send(Channel channel, String message) { if (channel != null) { channel.write(message + Checksum.nmea(message) + "\r\n"); @@ -85,10 +104,10 @@ public class GpsGateProtocolDecoder extends BaseProtocolDecoder { // Version check send(channel, "$FRVER,1,0,GpsGate Server 1.0"); - } else if (sentence.startsWith("$GPRMC,") && hasDeviceId()) { + } else if (sentence.startsWith("$GPRMC,")) { - Parser parser = new Parser(PATTERN, sentence); - if (!parser.matches()) { + Parser parser = new Parser(PATTERN_GPRMC, sentence); + if (!parser.matches() || !hasDeviceId()) { return null; } @@ -109,6 +128,37 @@ public class GpsGateProtocolDecoder extends BaseProtocolDecoder { position.setTime(dateBuilder.getDate()); return position; + + } else if (sentence.startsWith("$FRCMD,")) { + + Parser parser = new Parser(PATTERN_FRCMD, 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.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setAltitude(parser.nextDouble()); + position.setSpeed(parser.nextDouble()); + position.setCourse(parser.nextDouble()); + + DateBuilder dateBuilder = new DateBuilder() + .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + position.setValid(parser.next().equals("1")); + + return position; + } return null; diff --git a/test/org/traccar/protocol/GpsGateProtocolDecoderTest.java b/test/org/traccar/protocol/GpsGateProtocolDecoderTest.java index c4ed38656..788830e52 100644 --- a/test/org/traccar/protocol/GpsGateProtocolDecoderTest.java +++ b/test/org/traccar/protocol/GpsGateProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class GpsGateProtocolDecoderTest extends ProtocolTest { GpsGateProtocolDecoder decoder = new GpsGateProtocolDecoder(new GpsGateProtocol()); + verifyNothing(decoder, text( + "$FRCMD,862950025974620,_Ping,voltage=4*4F")); + + verifyPosition(decoder, text( + "$FRCMD,862950025974620,_SendMessage, ,2721.5781,S,15259.145,E,61,0.00,61,080316,092612,1,SosButton=0,voltage=4*60")); + verifyNothing(decoder, text( "$FRLIN,,user1,8IVHF*7A")); -- cgit v1.2.3 From c0d07811425497f10e41519e090f02cfdffb3c9a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 8 Mar 2016 23:19:30 +1300 Subject: Refactor device permissions resource --- .../api/resource/DevicePermissionResource.java | 52 ++++++++++++++++++++++ .../traccar/api/resource/PermissionResource.java | 52 ---------------------- src/org/traccar/web/WebServer.java | 4 +- web/app/view/UserDevicesController.js | 4 +- 4 files changed, 56 insertions(+), 56 deletions(-) create mode 100644 src/org/traccar/api/resource/DevicePermissionResource.java delete mode 100644 src/org/traccar/api/resource/PermissionResource.java (limited to 'src/org/traccar') diff --git a/src/org/traccar/api/resource/DevicePermissionResource.java b/src/org/traccar/api/resource/DevicePermissionResource.java new file mode 100644 index 000000000..f77375cba --- /dev/null +++ b/src/org/traccar/api/resource/DevicePermissionResource.java @@ -0,0 +1,52 @@ +/* + * 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. + * 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.api.resource; + +import org.traccar.Context; +import org.traccar.api.BaseResource; +import org.traccar.model.DevicePermission; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.sql.SQLException; + +@Path("permissions/devices") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class DevicePermissionResource extends BaseResource { + + @POST + public Response add(DevicePermission entity) throws SQLException { + Context.getPermissionsManager().checkAdmin(getUserId()); + Context.getDataManager().linkDevice(entity.getUserId(), entity.getDeviceId()); + Context.getPermissionsManager().refresh(); + return Response.ok(entity).build(); + } + + @DELETE + public Response remove(DevicePermission entity) throws SQLException { + Context.getPermissionsManager().checkAdmin(getUserId()); + Context.getDataManager().unlinkDevice(entity.getUserId(), entity.getDeviceId()); + Context.getPermissionsManager().refresh(); + return Response.noContent().build(); + } + +} diff --git a/src/org/traccar/api/resource/PermissionResource.java b/src/org/traccar/api/resource/PermissionResource.java deleted file mode 100644 index 7cf2b4ed9..000000000 --- a/src/org/traccar/api/resource/PermissionResource.java +++ /dev/null @@ -1,52 +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.api.resource; - -import org.traccar.Context; -import org.traccar.api.BaseResource; -import org.traccar.model.DevicePermission; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.sql.SQLException; - -@Path("permissions") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class PermissionResource extends BaseResource { - - @POST - public Response add(DevicePermission entity) throws SQLException { - Context.getPermissionsManager().checkAdmin(getUserId()); - Context.getDataManager().linkDevice(entity.getUserId(), entity.getDeviceId()); - Context.getPermissionsManager().refresh(); - return Response.ok(entity).build(); - } - - @DELETE - public Response remove(DevicePermission entity) throws SQLException { - Context.getPermissionsManager().checkAdmin(getUserId()); - Context.getDataManager().unlinkDevice(entity.getUserId(), entity.getDeviceId()); - Context.getPermissionsManager().refresh(); - return Response.noContent().build(); - } - -} diff --git a/src/org/traccar/web/WebServer.java b/src/org/traccar/web/WebServer.java index d6cd19d87..ed006f8cb 100644 --- a/src/org/traccar/web/WebServer.java +++ b/src/org/traccar/web/WebServer.java @@ -42,7 +42,7 @@ import org.traccar.api.ResourceErrorHandler; import org.traccar.api.SecurityRequestFilter; import org.traccar.api.resource.CommandResource; import org.traccar.api.resource.DeviceResource; -import org.traccar.api.resource.PermissionResource; +import org.traccar.api.resource.DevicePermissionResource; import org.traccar.api.resource.PositionResource; import org.traccar.api.resource.ServerResource; import org.traccar.api.resource.SessionResource; @@ -140,7 +140,7 @@ public class WebServer { resourceConfig.register(SecurityRequestFilter.class); resourceConfig.register(CorsResponseFilter.class); resourceConfig.registerClasses(ServerResource.class, SessionResource.class, CommandResource.class, - PermissionResource.class, DeviceResource.class, UserResource.class, PositionResource.class); + DevicePermissionResource.class, DeviceResource.class, UserResource.class, PositionResource.class); servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/*"); handlers.addHandler(servletHandler); diff --git a/web/app/view/UserDevicesController.js b/web/app/view/UserDevicesController.js index 4f013fd64..e5dbbdbb8 100644 --- a/web/app/view/UserDevicesController.js +++ b/web/app/view/UserDevicesController.js @@ -47,7 +47,7 @@ Ext.define('Traccar.view.UserDevicesController', { onBeforeSelect: function (object, record, index) { Ext.Ajax.request({ scope: this, - url: '/api/permissions', + url: '/api/permissions/devices', jsonData: { userId: this.userId, deviceId: record.getData().id @@ -64,7 +64,7 @@ Ext.define('Traccar.view.UserDevicesController', { Ext.Ajax.request({ scope: this, method: 'DELETE', - url: '/api/permissions', + url: '/api/permissions/devices', jsonData: { userId: this.userId, deviceId: record.getData().id -- cgit v1.2.3 From 3e76be5531f89fb906598435096e3eff54f86944 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 8 Mar 2016 23:31:06 +1300 Subject: Add group queries and recourse --- debug.xml | 20 +++++++++ .../api/resource/GroupPermissionResource.java | 52 ++++++++++++++++++++++ src/org/traccar/database/DataManager.java | 35 ++++++++++++++- 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/org/traccar/api/resource/GroupPermissionResource.java (limited to 'src/org/traccar') diff --git a/debug.xml b/debug.xml index eb2038cd5..102272cb3 100644 --- a/debug.xml +++ b/debug.xml @@ -149,6 +149,26 @@ DELETE FROM user_device WHERE userId = :userId AND deviceId = :deviceId; + + INSERT INTO groups (name) VALUES (:name); + + + + UPDATE groups SET name = :name WHERE id = :id; + + + + DELETE FROM groups WHERE id = :id; + + + + INSERT INTO user_group (userId, groupId) VALUES (:userId, :groupId); + + + + DELETE FROM user_group WHERE userId = :userId AND groupId = :groupId; + + SELECT * FROM positions WHERE deviceId = :deviceId AND fixTime BETWEEN :from AND :to ORDER BY fixTime; diff --git a/src/org/traccar/api/resource/GroupPermissionResource.java b/src/org/traccar/api/resource/GroupPermissionResource.java new file mode 100644 index 000000000..b8ec4ae3c --- /dev/null +++ b/src/org/traccar/api/resource/GroupPermissionResource.java @@ -0,0 +1,52 @@ +/* + * 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.api.resource; + +import org.traccar.Context; +import org.traccar.api.BaseResource; +import org.traccar.model.GroupPermission; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.sql.SQLException; + +@Path("permissions/groups") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class GroupPermissionResource extends BaseResource { + + @POST + public Response add(GroupPermission entity) throws SQLException { + Context.getPermissionsManager().checkAdmin(getUserId()); + Context.getDataManager().linkGroup(entity.getUserId(), entity.getGroupId()); + Context.getPermissionsManager().refresh(); + return Response.ok(entity).build(); + } + + @DELETE + public Response remove(GroupPermission entity) throws SQLException { + Context.getPermissionsManager().checkAdmin(getUserId()); + Context.getDataManager().unlinkGroup(entity.getUserId(), entity.getGroupId()); + Context.getPermissionsManager().refresh(); + return Response.noContent().build(); + } + +} diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index f040ecd20..5b4524f2e 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.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,6 +38,7 @@ import liquibase.resource.ResourceAccessor; import org.traccar.Config; import org.traccar.helper.Log; import org.traccar.model.Device; +import org.traccar.model.Group; import org.traccar.model.MiscFormatter; import org.traccar.model.DevicePermission; import org.traccar.model.Position; @@ -286,6 +287,38 @@ public class DataManager implements IdentityManager { AsyncServlet.sessionRefreshUser(userId); } + public void addGroup(Group group) throws SQLException { + group.setId(QueryBuilder.create(dataSource, getQuery("database.insertGroup"), true) + .setObject(group) + .executeUpdate()); + } + + public void updateGroup(Group group) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.updateGroup")) + .setObject(group) + .executeUpdate(); + } + + public void removeGroup(long groupId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.deleteGroup")) + .setLong("id", groupId) + .executeUpdate(); + } + + public void linkGroup(long userId, long groupId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.linkGroup")) + .setLong("userId", userId) + .setLong("groupId", groupId) + .executeUpdate(); + } + + public void unlinkGroup(long userId, long groupId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.unlinkGroup")) + .setLong("userId", userId) + .setLong("groupId", groupId) + .executeUpdate(); + } + public Collection getPositions(long deviceId, Date from, Date to) throws SQLException { return QueryBuilder.create(dataSource, getQuery("database.selectPositions")) .setLong("deviceId", deviceId) -- cgit v1.2.3 From 2879646bc58467939349c367a7763cd1eb11fde2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 8 Mar 2016 23:38:48 +1300 Subject: Add select group permissions query --- debug.xml | 6 +++++- src/org/traccar/database/DataManager.java | 10 ++++++++-- src/org/traccar/database/PermissionsManager.java | 6 +++++- 3 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src/org/traccar') diff --git a/debug.xml b/debug.xml index 102272cb3..413c020eb 100644 --- a/debug.xml +++ b/debug.xml @@ -113,10 +113,14 @@ DELETE FROM users WHERE id = :id; - + SELECT userId, deviceId FROM user_device; + + SELECT userId, groupId FROM user_group; + + SELECT * FROM devices; diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index 5b4524f2e..9a8a14615 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -39,6 +39,7 @@ import org.traccar.Config; import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.Group; +import org.traccar.model.GroupPermission; import org.traccar.model.MiscFormatter; import org.traccar.model.DevicePermission; import org.traccar.model.Position; @@ -222,11 +223,16 @@ public class DataManager implements IdentityManager { .executeUpdate(); } - public Collection getPermissions() throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.getPermissionsAll")) + public Collection getDevicePermissions() throws SQLException { + return QueryBuilder.create(dataSource, getQuery("database.selectDevicePermissions")) .executeQuery(DevicePermission.class); } + public Collection getGroupPermissions() throws SQLException { + return QueryBuilder.create(dataSource, getQuery("database.selectGroupPermissions")) + .executeQuery(GroupPermission.class); + } + public Collection getAllDevices() throws SQLException { return QueryBuilder.create(dataSource, getQuery("database.selectDevicesAll")) .executeQuery(Device.class); diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 854732fa2..0ed8227b4 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Set; import org.traccar.helper.Log; import org.traccar.model.DevicePermission; +import org.traccar.model.GroupPermission; import org.traccar.model.Server; import org.traccar.model.User; @@ -64,9 +65,12 @@ public class PermissionsManager { for (User user : dataManager.getUsers()) { users.put(user.getId(), user); } - for (DevicePermission permission : dataManager.getPermissions()) { + for (DevicePermission permission : dataManager.getDevicePermissions()) { getDevicePermissions(permission.getUserId()).add(permission.getDeviceId()); } + for (GroupPermission permission : dataManager.getGroupPermissions()) { + getGroupPermissions(permission.getUserId()).add(permission.getGroupId()); + } } catch (SQLException error) { Log.warning(error); } -- cgit v1.2.3 From d4825d57fc27384288d9f3e1c1dd9e4bd7e29160 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 9 Mar 2016 16:09:00 +1300 Subject: Implement API resource for groups --- debug.xml | 8 +- src/org/traccar/api/AsyncSocket.java | 2 +- src/org/traccar/api/resource/GroupResource.java | 85 ++++++++++++++++++++++ src/org/traccar/api/resource/PositionResource.java | 2 +- src/org/traccar/database/DataManager.java | 52 +++++++++++-- src/org/traccar/database/PermissionsManager.java | 14 ++-- src/org/traccar/web/AsyncServlet.java | 2 +- 7 files changed, 144 insertions(+), 21 deletions(-) create mode 100644 src/org/traccar/api/resource/GroupResource.java (limited to 'src/org/traccar') diff --git a/debug.xml b/debug.xml index 413c020eb..2266a1eea 100644 --- a/debug.xml +++ b/debug.xml @@ -125,10 +125,6 @@ SELECT * FROM devices; - - SELECT * FROM devices d INNER JOIN user_device ud ON d.id = ud.deviceId WHERE ud.userId = :userId; - - INSERT INTO devices (name, uniqueId) VALUES (:name, :uniqueId); @@ -153,6 +149,10 @@ DELETE FROM user_device WHERE userId = :userId AND deviceId = :deviceId; + + SELECT * FROM groups; + + INSERT INTO groups (name) VALUES (:name); diff --git a/src/org/traccar/api/AsyncSocket.java b/src/org/traccar/api/AsyncSocket.java index 96ad2c450..c289367ea 100644 --- a/src/org/traccar/api/AsyncSocket.java +++ b/src/org/traccar/api/AsyncSocket.java @@ -36,7 +36,7 @@ public class AsyncSocket extends WebSocketAdapter implements ConnectionManager.U private Collection devices; public AsyncSocket(long userId) { - devices = Context.getPermissionsManager().allowedDevices(userId); + devices = Context.getPermissionsManager().getDevicePermissions(userId); } @Override diff --git a/src/org/traccar/api/resource/GroupResource.java b/src/org/traccar/api/resource/GroupResource.java new file mode 100644 index 000000000..49f839499 --- /dev/null +++ b/src/org/traccar/api/resource/GroupResource.java @@ -0,0 +1,85 @@ +/* + * 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.api.resource; + +import org.traccar.Context; +import org.traccar.api.BaseResource; +import org.traccar.model.Device; +import org.traccar.model.Group; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.sql.SQLException; +import java.util.Collection; + +@Path("groups") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class GroupResource extends BaseResource { + + @GET + public Collection get( + @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException { + if (all) { + Context.getPermissionsManager().checkAdmin(getUserId()); + return Context.getDataManager().getAllGroups(); + } else { + if (userId == 0) { + userId = getUserId(); + } + Context.getPermissionsManager().checkUser(getUserId(), userId); + return Context.getDataManager().getGroups(userId); + } + } + + @POST + public Response add(Group entity) throws SQLException { + Context.getPermissionsManager().checkReadonly(getUserId()); + Context.getDataManager().addGroup(entity); + Context.getDataManager().linkGroup(getUserId(), entity.getId()); + Context.getPermissionsManager().refresh(); + return Response.ok(entity).build(); + } + + @Path("{id}") + @PUT + public Response update(@PathParam("id") long id, Group entity) throws SQLException { + Context.getPermissionsManager().checkReadonly(getUserId()); + Context.getPermissionsManager().checkGroup(getUserId(), id); + Context.getDataManager().updateGroup(entity); + return Response.ok(entity).build(); + } + + @Path("{id}") + @DELETE + public Response remove(@PathParam("id") long id) throws SQLException { + Context.getPermissionsManager().checkReadonly(getUserId()); + Context.getPermissionsManager().checkGroup(getUserId(), id); + Context.getDataManager().removeGroup(id); + Context.getPermissionsManager().refresh(); + return Response.noContent().build(); + } + +} diff --git a/src/org/traccar/api/resource/PositionResource.java b/src/org/traccar/api/resource/PositionResource.java index b9e8e877e..9c174625c 100644 --- a/src/org/traccar/api/resource/PositionResource.java +++ b/src/org/traccar/api/resource/PositionResource.java @@ -40,7 +40,7 @@ public class PositionResource extends BaseResource { throws SQLException { if (deviceId == 0) { return Context.getConnectionManager().getInitialState( - Context.getPermissionsManager().allowedDevices(getUserId())); + Context.getPermissionsManager().getDevicePermissions(getUserId())); } else { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); return Context.getDataManager().getPositions( diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index 9a8a14615..d2da4e701 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -21,6 +21,7 @@ import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; @@ -36,6 +37,7 @@ import liquibase.exception.LiquibaseException; import liquibase.resource.FileSystemResourceAccessor; import liquibase.resource.ResourceAccessor; import org.traccar.Config; +import org.traccar.Context; import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.Group; @@ -55,10 +57,14 @@ public class DataManager implements IdentityManager { private DataSource dataSource; + private final long dataRefreshDelay; + private final Map devicesById = new HashMap<>(); private final Map devicesByUniqueId = new HashMap<>(); private long devicesLastUpdate; - private final long devicesRefreshDelay; + + private final Map groupsById = new HashMap<>(); + private long groupsLastUpdate; public DataManager(Config config) throws Exception { this.config = config; @@ -66,7 +72,7 @@ public class DataManager implements IdentityManager { initDatabase(); initDatabaseSchema(); - devicesRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000; + dataRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000; } public DataSource getDataSource() { @@ -114,7 +120,7 @@ public class DataManager implements IdentityManager { } private void updateDeviceCache(boolean force) throws SQLException { - if (System.currentTimeMillis() - devicesLastUpdate > devicesRefreshDelay || force) { + if (System.currentTimeMillis() - devicesLastUpdate > dataRefreshDelay || force) { devicesById.clear(); devicesByUniqueId.clear(); for (Device device : getAllDevices()) { @@ -142,6 +148,25 @@ public class DataManager implements IdentityManager { return devicesByUniqueId.get(uniqueId); } + private void updateGroupCache(boolean force) throws SQLException { + if (System.currentTimeMillis() - groupsLastUpdate > dataRefreshDelay || force) { + groupsById.clear(); + for (Group group : getAllGroups()) { + groupsById.put(group.getId(), group); + } + groupsLastUpdate = System.currentTimeMillis(); + } + } + + public Group getGroupById(long id) { + try { + updateGroupCache(!groupsById.containsKey(id)); + } catch (SQLException e) { + Log.warning(e); + } + return groupsById.get(id); + } + private String getQuery(String key) { String query = config.getString(key); if (query == null) { @@ -239,9 +264,11 @@ public class DataManager implements IdentityManager { } public Collection getDevices(long userId) throws SQLException { - return QueryBuilder.create(dataSource, getQuery("database.selectDevices")) - .setLong("userId", userId) - .executeQuery(Device.class); + Collection devices = new ArrayList<>(); + for (long id : Context.getPermissionsManager().getDevicePermissions(userId)) { + devices.add(getDeviceById(id)); + } + return devices; } public void addDevice(Device device) throws SQLException { @@ -293,6 +320,19 @@ public class DataManager implements IdentityManager { AsyncServlet.sessionRefreshUser(userId); } + public Collection getAllGroups() throws SQLException { + return QueryBuilder.create(dataSource, getQuery("database.selectGroupsAll")) + .executeQuery(Group.class); + } + + public Collection getGroups(long userId) throws SQLException { + Collection groups = new ArrayList<>(); + for (long id : Context.getPermissionsManager().getGroupPermissions(userId)) { + groups.add(getGroupById(id)); + } + return groups; + } + public void addGroup(Group group) throws SQLException { group.setId(QueryBuilder.create(dataSource, getQuery("database.insertGroup"), true) .setObject(group) diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 0ed8227b4..5d6430764 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -38,14 +38,14 @@ public class PermissionsManager { private final Map> groupPermissions = new HashMap<>(); private final Map> devicePermissions = new HashMap<>(); - private Set getGroupPermissions(long userId) { + public Set getGroupPermissions(long userId) { if (!groupPermissions.containsKey(userId)) { groupPermissions.put(userId, new HashSet()); } return groupPermissions.get(userId); } - private Set getDevicePermissions(long userId) { + public Set getDevicePermissions(long userId) { if (!devicePermissions.containsKey(userId)) { devicePermissions.put(userId, new HashSet()); } @@ -92,12 +92,10 @@ public class PermissionsManager { } } - public Collection allowedGroups(long userId) { - return getGroupPermissions(userId); - } - - public Collection allowedDevices(long userId) { - return getDevicePermissions(userId); + public void checkGroup(long userId, long groupId) throws SecurityException { + if (!getGroupPermissions(userId).contains(groupId)) { + throw new SecurityException("Group access denied"); + } } public void checkDevice(long userId, long deviceId) throws SecurityException { diff --git a/src/org/traccar/web/AsyncServlet.java b/src/org/traccar/web/AsyncServlet.java index b10df5408..e4cb64c57 100644 --- a/src/org/traccar/web/AsyncServlet.java +++ b/src/org/traccar/web/AsyncServlet.java @@ -226,7 +226,7 @@ public class AsyncServlet extends BaseServlet { synchronized (ASYNC_SESSIONS) { if (Boolean.parseBoolean(req.getParameter("first")) || !ASYNC_SESSIONS.containsKey(userId)) { - Collection devices = Context.getPermissionsManager().allowedDevices(userId); + Collection devices = Context.getPermissionsManager().getDevicePermissions(userId); ASYNC_SESSIONS.put(userId, new AsyncSession(userId, devices)); } -- cgit v1.2.3 From 1750a8b5353a69f3b1805757f3b31150260d45f8 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 9 Mar 2016 20:34:11 +1300 Subject: Add groups list window component --- src/org/traccar/web/WebServer.java | 5 ++- web/app/view/DeviceDialog.js | 2 +- web/app/view/Devices.js | 2 +- web/app/view/Groups.js | 44 ++++++++++++++++++++++ web/app/view/GroupsController.js | 67 ++++++++++++++++++++++++++++++++++ web/app/view/Register.js | 2 +- web/app/view/SettingsMenu.js | 3 ++ web/app/view/SettingsMenuController.js | 11 ++++++ web/app/view/UserDevices.js | 2 +- web/app/view/UserDialog.js | 2 +- web/app/view/Users.js | 2 +- web/l10n/en.json | 4 +- 12 files changed, 137 insertions(+), 9 deletions(-) create mode 100644 web/app/view/Groups.js create mode 100644 web/app/view/GroupsController.js (limited to 'src/org/traccar') diff --git a/src/org/traccar/web/WebServer.java b/src/org/traccar/web/WebServer.java index ed006f8cb..4e764d5d6 100644 --- a/src/org/traccar/web/WebServer.java +++ b/src/org/traccar/web/WebServer.java @@ -43,6 +43,8 @@ import org.traccar.api.SecurityRequestFilter; import org.traccar.api.resource.CommandResource; import org.traccar.api.resource.DeviceResource; import org.traccar.api.resource.DevicePermissionResource; +import org.traccar.api.resource.GroupPermissionResource; +import org.traccar.api.resource.GroupResource; import org.traccar.api.resource.PositionResource; import org.traccar.api.resource.ServerResource; import org.traccar.api.resource.SessionResource; @@ -140,7 +142,8 @@ public class WebServer { resourceConfig.register(SecurityRequestFilter.class); resourceConfig.register(CorsResponseFilter.class); resourceConfig.registerClasses(ServerResource.class, SessionResource.class, CommandResource.class, - DevicePermissionResource.class, DeviceResource.class, UserResource.class, PositionResource.class); + GroupPermissionResource.class, DevicePermissionResource.class, UserResource.class, + GroupResource.class, DeviceResource.class, PositionResource.class); servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/*"); handlers.addHandler(servletHandler); diff --git a/web/app/view/DeviceDialog.js b/web/app/view/DeviceDialog.js index c42af95d0..318ac4ffe 100644 --- a/web/app/view/DeviceDialog.js +++ b/web/app/view/DeviceDialog.js @@ -29,7 +29,7 @@ Ext.define('Traccar.view.DeviceDialog', { items: [{ xtype: 'textfield', name: 'name', - fieldLabel: Strings.deviceName, + fieldLabel: Strings.sharedName, allowBlank: false }, { xtype: 'textfield', diff --git a/web/app/view/Devices.js b/web/app/view/Devices.js index 66c4e813b..5712feb81 100644 --- a/web/app/view/Devices.js +++ b/web/app/view/Devices.js @@ -57,7 +57,7 @@ Ext.define('Traccar.view.Devices', { }, columns: [{ - text: Strings.deviceName, + text: Strings.sharedName, dataIndex: 'name', flex: 1 }, { diff --git a/web/app/view/Groups.js b/web/app/view/Groups.js new file mode 100644 index 000000000..8404c59a9 --- /dev/null +++ b/web/app/view/Groups.js @@ -0,0 +1,44 @@ +/* + * 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. + */ + +Ext.define('Traccar.view.Groups', { + extend: 'Ext.grid.Panel', + xtype: 'groupsView', + + requires: [ + 'Traccar.view.GroupsController', + 'Traccar.view.EditToolbar' + ], + + controller: 'groups', + store: 'Groups', + + selType: 'rowmodel', + + tbar: { + xtype: 'editToolbar' + }, + + listeners: { + selectionchange: 'onSelectionChange' + }, + + columns: [{ + text: Strings.sharedName, + dataIndex: 'name', + flex: 1 + }] +}); diff --git a/web/app/view/GroupsController.js b/web/app/view/GroupsController.js new file mode 100644 index 000000000..619e0c50e --- /dev/null +++ b/web/app/view/GroupsController.js @@ -0,0 +1,67 @@ +/* + * 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. + */ + +Ext.define('Traccar.view.GroupsController', { + extend: 'Ext.app.ViewController', + alias: 'controller.groups', + + init: function () { + Ext.getStore('Groups').load(); + }, + + onAddClick: function () { + /*var user, dialog; + user = Ext.create('Traccar.model.User'); + dialog = Ext.create('Traccar.view.UserDialog'); + dialog.down('form').loadRecord(user); + dialog.show();*/ + }, + + onEditClick: function () { + /*var user, dialog; + user = this.getView().getSelectionModel().getSelection()[0]; + dialog = Ext.create('Traccar.view.UserDialog'); + dialog.down('form').loadRecord(user); + dialog.show();*/ + }, + + onRemoveClick: function () { + /*var user = this.getView().getSelectionModel().getSelection()[0]; + Ext.Msg.show({ + title: Strings.settingsUser, + message: Strings.sharedRemoveConfirm, + buttons: Ext.Msg.YESNO, + buttonText: { + yes: Strings.sharedRemove, + no: Strings.sharedCancel + }, + fn: function (btn) { + var store = Ext.getStore('Users'); + if (btn === 'yes') { + store.remove(user); + store.sync(); + } + } + });*/ + }, + + onSelectionChange: function (selected) { + var disabled = selected.length > 0; + this.lookupReference('toolbarEditButton').setDisabled(disabled); + this.lookupReference('toolbarRemoveButton').setDisabled(disabled); + this.lookupReference('userDevicesButton').setDisabled(disabled); + } +}); diff --git a/web/app/view/Register.js b/web/app/view/Register.js index 7c2881d62..198e10b8f 100644 --- a/web/app/view/Register.js +++ b/web/app/view/Register.js @@ -33,7 +33,7 @@ Ext.define('Traccar.view.Register', { items: [{ xtype: 'textfield', name: 'name', - fieldLabel: Strings.userName, + fieldLabel: Strings.sharedName, allowBlank: false }, { xtype: 'textfield', diff --git a/web/app/view/SettingsMenu.js b/web/app/view/SettingsMenu.js index c828b37af..1ada94359 100644 --- a/web/app/view/SettingsMenu.js +++ b/web/app/view/SettingsMenu.js @@ -31,6 +31,9 @@ Ext.define('Traccar.view.SettingsMenu', { items: [{ text: Strings.settingsUser, handler: 'onUserClick' + }, { + text: Strings.settingsGroups, + handler: 'onGroupsClick' }, { text: Strings.settingsServer, hidden: true, diff --git a/web/app/view/SettingsMenuController.js b/web/app/view/SettingsMenuController.js index c52f0a75e..6d767e3a9 100644 --- a/web/app/view/SettingsMenuController.js +++ b/web/app/view/SettingsMenuController.js @@ -23,6 +23,7 @@ Ext.define('Traccar.view.SettingsMenuController', { 'Traccar.view.UserDialog', 'Traccar.view.ServerDialog', 'Traccar.view.Users', + 'Traccar.view.Groups', 'Traccar.view.BaseWindow' ], @@ -39,6 +40,16 @@ Ext.define('Traccar.view.SettingsMenuController', { dialog.show(); }, + onGroupsClick: function () { + Ext.create('Traccar.view.BaseWindow', { + title: Strings.settingsGroups, + modal: false, + items: { + xtype: 'groupsView' + } + }).show(); + }, + onServerClick: function () { var dialog = Ext.create('Traccar.view.ServerDialog'); dialog.down('form').loadRecord(Traccar.app.getServer()); diff --git a/web/app/view/UserDevices.js b/web/app/view/UserDevices.js index f9ab48266..f42f7c1bb 100644 --- a/web/app/view/UserDevices.js +++ b/web/app/view/UserDevices.js @@ -37,7 +37,7 @@ Ext.define('Traccar.view.UserDevices', { }, columns: [{ - text: Strings.deviceName, + text: Strings.sharedName, dataIndex: 'name', flex: 1 }, { text: Strings.deviceIdentifier, diff --git a/web/app/view/UserDialog.js b/web/app/view/UserDialog.js index 783ddd159..c1ed2fece 100644 --- a/web/app/view/UserDialog.js +++ b/web/app/view/UserDialog.js @@ -30,7 +30,7 @@ Ext.define('Traccar.view.UserDialog', { items: [{ xtype: 'textfield', name: 'name', - fieldLabel: Strings.userName + fieldLabel: Strings.sharedName }, { xtype: 'textfield', name: 'email', diff --git a/web/app/view/Users.js b/web/app/view/Users.js index f4ef332b4..684931559 100644 --- a/web/app/view/Users.js +++ b/web/app/view/Users.js @@ -43,7 +43,7 @@ Ext.define('Traccar.view.Users', { }, columns: [{ - text: Strings.userName, + text: Strings.sharedName, dataIndex: 'name', flex: 1 }, { diff --git a/web/l10n/en.json b/web/l10n/en.json index ec8018863..259d54b1a 100644 --- a/web/l10n/en.json +++ b/web/l10n/en.json @@ -13,10 +13,10 @@ "sharedHour": "Hour", "sharedMinute": "Minute", "sharedSecond": "Second", + "sharedName": "Name", "errorTitle": "Error", "errorUnknown": "Unknown error", "errorConnection": "Connection error", - "userName": "Name", "userEmail": "Email", "userPassword": "Password", "userAdmin": "Admin", @@ -30,13 +30,13 @@ "devicesAndState": "Devices and State", "deviceDialog": "Device", "deviceTitle": "Devices", - "deviceName": "Name", "deviceIdentifier": "Identifier", "deviceLastUpdate": "Last Update", "deviceCommand": "Command", "deviceFollow": "Follow", "settingsTitle": "Settings", "settingsUser": "Account", + "settingsGroups": "Groups", "settingsServer": "Server", "settingsUsers": "Users", "settingsDistanceUnit": "Distance", -- cgit v1.2.3 From c22cc6982a18eb3601fdc8fb8447b5a2ba73690a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 9 Mar 2016 21:48:59 +1300 Subject: Implement group editing dialog --- debug.xml | 2 +- src/org/traccar/database/PermissionsManager.java | 1 + web/app/view/GroupDialog.js | 36 ++++++++++++++++++++++++ web/app/view/GroupsController.js | 32 ++++++++++----------- web/l10n/en.json | 1 + 5 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 web/app/view/GroupDialog.js (limited to 'src/org/traccar') diff --git a/debug.xml b/debug.xml index 2266a1eea..ce7c3190a 100644 --- a/debug.xml +++ b/debug.xml @@ -14,7 +14,7 @@ web true true - 10000 + 30000 true nominatim diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 5d6430764..022691b1b 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -59,6 +59,7 @@ public class PermissionsManager { public final void refresh() { users.clear(); + groupPermissions.clear(); devicePermissions.clear(); try { server = dataManager.getServer(); diff --git a/web/app/view/GroupDialog.js b/web/app/view/GroupDialog.js new file mode 100644 index 000000000..a34e33aa0 --- /dev/null +++ b/web/app/view/GroupDialog.js @@ -0,0 +1,36 @@ +/* + * 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. + */ + +Ext.define('Traccar.view.GroupDialog', { + extend: 'Traccar.view.BaseEditDialog', + + requires: [ + 'Traccar.view.BaseEditDialogController' + ], + + controller: 'baseEditDialog', + title: Strings.groupDialog, + + items: { + xtype: 'form', + items: [{ + xtype: 'textfield', + name: 'name', + fieldLabel: Strings.sharedName, + allowBlank: false + }] + } +}); diff --git a/web/app/view/GroupsController.js b/web/app/view/GroupsController.js index 619e0c50e..34b259658 100644 --- a/web/app/view/GroupsController.js +++ b/web/app/view/GroupsController.js @@ -23,25 +23,26 @@ Ext.define('Traccar.view.GroupsController', { }, onAddClick: function () { - /*var user, dialog; - user = Ext.create('Traccar.model.User'); - dialog = Ext.create('Traccar.view.UserDialog'); - dialog.down('form').loadRecord(user); - dialog.show();*/ + var group, dialog; + group = Ext.create('Traccar.model.Group'); + group.store = this.getView().getStore(); + dialog = Ext.create('Traccar.view.GroupDialog'); + dialog.down('form').loadRecord(group); + dialog.show(); }, onEditClick: function () { - /*var user, dialog; - user = this.getView().getSelectionModel().getSelection()[0]; - dialog = Ext.create('Traccar.view.UserDialog'); - dialog.down('form').loadRecord(user); - dialog.show();*/ + var group, dialog; + group = this.getView().getSelectionModel().getSelection()[0]; + dialog = Ext.create('Traccar.view.GroupDialog'); + dialog.down('form').loadRecord(group); + dialog.show(); }, onRemoveClick: function () { - /*var user = this.getView().getSelectionModel().getSelection()[0]; + var group = this.getView().getSelectionModel().getSelection()[0]; Ext.Msg.show({ - title: Strings.settingsUser, + title: Strings.groupDialog, message: Strings.sharedRemoveConfirm, buttons: Ext.Msg.YESNO, buttonText: { @@ -49,19 +50,18 @@ Ext.define('Traccar.view.GroupsController', { no: Strings.sharedCancel }, fn: function (btn) { - var store = Ext.getStore('Users'); + var store = Ext.getStore('Groups'); if (btn === 'yes') { - store.remove(user); + store.remove(group); store.sync(); } } - });*/ + }); }, onSelectionChange: function (selected) { var disabled = selected.length > 0; this.lookupReference('toolbarEditButton').setDisabled(disabled); this.lookupReference('toolbarRemoveButton').setDisabled(disabled); - this.lookupReference('userDevicesButton').setDisabled(disabled); } }); diff --git a/web/l10n/en.json b/web/l10n/en.json index 259d54b1a..715dce3a7 100644 --- a/web/l10n/en.json +++ b/web/l10n/en.json @@ -34,6 +34,7 @@ "deviceLastUpdate": "Last Update", "deviceCommand": "Command", "deviceFollow": "Follow", + "groupDialog": "Group", "settingsTitle": "Settings", "settingsUser": "Account", "settingsGroups": "Groups", -- cgit v1.2.3 From 5634860cbe5c43007df354acba79d5051c1eb987 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 9 Mar 2016 23:13:06 +1300 Subject: Add parent field for device and group --- debug.xml | 4 ++-- src/org/traccar/model/Group.java | 2 -- web/app/controller/Root.js | 1 + web/app/model/Device.js | 3 +++ web/app/model/Group.js | 3 +++ web/app/view/DeviceDialog.js | 7 +++++++ web/app/view/GroupDialog.js | 7 +++++++ web/app/view/GroupsController.js | 4 ---- web/l10n/en.json | 1 + 9 files changed, 24 insertions(+), 8 deletions(-) (limited to 'src/org/traccar') diff --git a/debug.xml b/debug.xml index ce7c3190a..45c475a91 100644 --- a/debug.xml +++ b/debug.xml @@ -130,7 +130,7 @@ - UPDATE devices SET name = :name, uniqueId = :uniqueId WHERE id = :id; + UPDATE devices SET name = :name, uniqueId = :uniqueId, groupId = :groupId WHERE id = :id; @@ -158,7 +158,7 @@ - UPDATE groups SET name = :name WHERE id = :id; + UPDATE groups SET name = :name, groupId = :groupId WHERE id = :id; diff --git a/src/org/traccar/model/Group.java b/src/org/traccar/model/Group.java index 24f7973c8..00f2b2cfc 100644 --- a/src/org/traccar/model/Group.java +++ b/src/org/traccar/model/Group.java @@ -15,8 +15,6 @@ */ package org.traccar.model; -import java.util.Date; - public class Group { private long id; diff --git a/web/app/controller/Root.js b/web/app/controller/Root.js index a1026d3c5..5bd567619 100644 --- a/web/app/controller/Root.js +++ b/web/app/controller/Root.js @@ -73,6 +73,7 @@ Ext.define('Traccar.controller.Root', { }, loadApp: function () { + Ext.getStore('Groups').load(); Ext.getStore('Devices').load(); Ext.get('attribution').remove(); if (this.isPhone) { diff --git a/web/app/model/Device.js b/web/app/model/Device.js index 709d51953..588d53c1f 100644 --- a/web/app/model/Device.js +++ b/web/app/model/Device.js @@ -34,5 +34,8 @@ Ext.define('Traccar.model.Device', { name: 'lastUpdate', type: 'date', dateFormat: 'c' + }, { + name: 'groupId', + type: 'int' }] }); diff --git a/web/app/model/Group.js b/web/app/model/Group.js index 22e160315..a28897feb 100644 --- a/web/app/model/Group.js +++ b/web/app/model/Group.js @@ -24,5 +24,8 @@ Ext.define('Traccar.model.Group', { }, { name: 'name', type: 'string' + }, { + name: 'groupId', + type: 'int' }] }); diff --git a/web/app/view/DeviceDialog.js b/web/app/view/DeviceDialog.js index 318ac4ffe..4a22ca008 100644 --- a/web/app/view/DeviceDialog.js +++ b/web/app/view/DeviceDialog.js @@ -36,6 +36,13 @@ Ext.define('Traccar.view.DeviceDialog', { name: 'uniqueId', fieldLabel: Strings.deviceIdentifier, allowBlank: false + }, { + xtype: 'combobox', + name: 'groupId', + fieldLabel: Strings.groupParent, + store: 'Groups', + displayField: 'name', + valueField: 'id' }] } }); diff --git a/web/app/view/GroupDialog.js b/web/app/view/GroupDialog.js index a34e33aa0..2cca61ef5 100644 --- a/web/app/view/GroupDialog.js +++ b/web/app/view/GroupDialog.js @@ -31,6 +31,13 @@ Ext.define('Traccar.view.GroupDialog', { name: 'name', fieldLabel: Strings.sharedName, allowBlank: false + }, { + xtype: 'combobox', + name: 'groupId', + fieldLabel: Strings.groupParent, + store: 'Groups', + displayField: 'name', + valueField: 'id' }] } }); diff --git a/web/app/view/GroupsController.js b/web/app/view/GroupsController.js index 34b259658..6cc568ea2 100644 --- a/web/app/view/GroupsController.js +++ b/web/app/view/GroupsController.js @@ -18,10 +18,6 @@ Ext.define('Traccar.view.GroupsController', { extend: 'Ext.app.ViewController', alias: 'controller.groups', - init: function () { - Ext.getStore('Groups').load(); - }, - onAddClick: function () { var group, dialog; group = Ext.create('Traccar.model.Group'); diff --git a/web/l10n/en.json b/web/l10n/en.json index 715dce3a7..cabd76362 100644 --- a/web/l10n/en.json +++ b/web/l10n/en.json @@ -35,6 +35,7 @@ "deviceCommand": "Command", "deviceFollow": "Follow", "groupDialog": "Group", + "groupParent": "Group", "settingsTitle": "Settings", "settingsUser": "Account", "settingsGroups": "Groups", -- cgit v1.2.3 From acfd6b43fc457cf98d5d1669f89438240bb871c2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 10 Mar 2016 14:10:00 +1300 Subject: Support extended RMC message format --- src/org/traccar/protocol/T55ProtocolDecoder.java | 20 +++++++++++++++++--- .../org/traccar/protocol/T55ProtocolDecoderTest.java | 3 +++ 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java index c6b2a670e..71f493318 100644 --- a/src/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/org/traccar/protocol/T55ProtocolDecoder.java @@ -42,7 +42,13 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { .expression("([EW]),") .number("(d+.?d*)?,") // speed .number("(d+.?d*)?,") // course - .number("(dd)(dd)(dd)") // date + .number("(dd)(dd)(dd),") // date + .expression("[^*]+") + .text("*") + .expression("[^,]+") + .number(",(d+)") // satellites + .number(",(d+)") // imei + .number(",(d+)").optional(3) .any() .compile(); @@ -84,7 +90,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { private Position position = null; - private Position decodeGprmc(String sentence, Channel channel) { + private Position decodeGprmc(String sentence, SocketAddress remoteAddress, Channel channel) { if (channel != null) { channel.write("OK1\r\n"); @@ -114,6 +120,14 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setTime(dateBuilder.getDate()); + if (parser.hasNext(3)) { + position.set(Event.KEY_SATELLITES, parser.next()); + if (!identify(parser.next(), channel, remoteAddress)) { + return null; + } + position.setDeviceId(getDeviceId()); + } + if (hasDeviceId()) { return position; } else { @@ -226,7 +240,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { } else if (Character.isDigit(sentence.charAt(0)) && sentence.length() == 15) { identify(sentence, channel, remoteAddress); } else if (sentence.startsWith("$GPRMC")) { - return decodeGprmc(sentence, channel); + return decodeGprmc(sentence, remoteAddress, channel); } else if (sentence.startsWith("$GPGGA") && hasDeviceId()) { return decodeGpgga(sentence); } else if (sentence.startsWith("$GPRMA") && hasDeviceId()) { diff --git a/test/org/traccar/protocol/T55ProtocolDecoderTest.java b/test/org/traccar/protocol/T55ProtocolDecoderTest.java index 20d30ce73..4160758fc 100644 --- a/test/org/traccar/protocol/T55ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/T55ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class T55ProtocolDecoderTest extends ProtocolTest { T55ProtocolDecoder decoder = new T55ProtocolDecoder(new T55Protocol()); + verifyPosition(decoder, text( + "$GPRMC,073501.000,A,1255.5125,N,07738.2948,E,0.00,0.53,080316,,,D*73,12,865733027593268,10011")); + verifyNothing(decoder, text( "$GPFID,ID123456ABC")); -- cgit v1.2.3 From 222265e0c884d06158426e7d0ca033127cecb22f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 10 Mar 2016 15:29:26 +1300 Subject: Implement group tree structure --- src/org/traccar/database/GroupTree.java | 106 +++++++++++++++++++++++++++ test/org/traccar/database/GroupTreeTest.java | 37 ++++++++++ 2 files changed, 143 insertions(+) create mode 100644 src/org/traccar/database/GroupTree.java create mode 100644 test/org/traccar/database/GroupTreeTest.java (limited to 'src/org/traccar') diff --git a/src/org/traccar/database/GroupTree.java b/src/org/traccar/database/GroupTree.java new file mode 100644 index 000000000..7263a6331 --- /dev/null +++ b/src/org/traccar/database/GroupTree.java @@ -0,0 +1,106 @@ +/* + * 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.database; + +import org.traccar.model.Group; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class GroupTree { + + private static class GroupNode { + + private Group group; + private GroupNode parent; + private Collection children = new HashSet<>(); + + public GroupNode(Group group) { + this.group = group; + } + + @Override + public int hashCode() { + return (int) group.getId(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof GroupNode)) { + return false; + } + return obj == this || group.getId() == ((GroupNode) obj).group.getId(); + } + + public Group getGroup() { + return group; + } + + public void setParent(GroupNode parent) { + this.parent = parent; + if (parent != null) { + parent.children.add(this); + } + } + + public GroupNode getParent() { + return parent; + } + + public Collection getChildren() { + return children; + } + + } + + private final Map groupMap = new HashMap<>(); + + public GroupTree(Collection groups) { + + for (Group group : groups) { + groupMap.put(group.getId(), new GroupNode(group)); + } + + for (GroupNode node : groupMap.values()) { + if (node.getGroup().getGroupId() != 0) { + node.setParent(groupMap.get(node.getGroup().getGroupId())); + } + } + + } + + public Collection getDescendants(long groupId) { + Set results = new HashSet<>(); + getDescendants(results, groupMap.get(groupId)); + Collection groups = new ArrayList<>(); + for (GroupNode node : results) { + groups.add(node.getGroup()); + } + return groups; + } + + private void getDescendants(Set results, GroupNode node) { + for (GroupNode child : node.getChildren()) { + results.add(child); + getDescendants(results, child); + } + } + +} diff --git a/test/org/traccar/database/GroupTreeTest.java b/test/org/traccar/database/GroupTreeTest.java new file mode 100644 index 000000000..26ac595f8 --- /dev/null +++ b/test/org/traccar/database/GroupTreeTest.java @@ -0,0 +1,37 @@ +package org.traccar.database; + +import org.junit.Assert; +import org.junit.Test; +import org.traccar.model.Group; + +import java.util.ArrayList; +import java.util.Collection; + +public class GroupTreeTest { + + private static Group createGroup(long id, String name, long parent) { + Group group = new Group(); + group.setId(id); + group.setName(name); + group.setGroupId(parent); + return group; + } + + @Test + public void testGetDescendants() { + Collection groups = new ArrayList<>(); + groups.add(createGroup(1, "First", 0)); + groups.add(createGroup(2, "Second", 1)); + groups.add(createGroup(3, "Third", 2)); + groups.add(createGroup(4, "Fourth", 2)); + groups.add(createGroup(5, "Fifth", 4)); + + GroupTree groupTree = new GroupTree(groups); + + Assert.assertEquals(4, groupTree.getDescendants(1).size()); + Assert.assertEquals(3, groupTree.getDescendants(2).size()); + Assert.assertEquals(0, groupTree.getDescendants(3).size()); + Assert.assertEquals(1, groupTree.getDescendants(4).size()); + } + +} -- cgit v1.2.3 From d940a84da87bcf4c164344fa7018cbf96ca1a920 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 10 Mar 2016 17:03:37 +1300 Subject: Expand group permissions in manager --- src/org/traccar/database/PermissionsManager.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 022691b1b..0aefb9605 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -22,7 +22,9 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import org.traccar.helper.Log; +import org.traccar.model.Device; import org.traccar.model.DevicePermission; +import org.traccar.model.Group; import org.traccar.model.GroupPermission; import org.traccar.model.Server; import org.traccar.model.User; @@ -66,12 +68,24 @@ public class PermissionsManager { for (User user : dataManager.getUsers()) { users.put(user.getId(), user); } + + GroupTree groupTree = new GroupTree(dataManager.getAllGroups()); + for (GroupPermission permission : dataManager.getGroupPermissions()) { + Set userGroupPermissions = getGroupPermissions(permission.getUserId()); + userGroupPermissions.add(permission.getGroupId()); + for (Group group : groupTree.getDescendants(permission.getGroupId())) { + userGroupPermissions.add(group.getId()); + } + } + for (DevicePermission permission : dataManager.getDevicePermissions()) { getDevicePermissions(permission.getUserId()).add(permission.getDeviceId()); } - for (GroupPermission permission : dataManager.getGroupPermissions()) { - getGroupPermissions(permission.getUserId()).add(permission.getGroupId()); + + for (Device device : dataManager.getAllDevices()) { + // TODO } + } catch (SQLException error) { Log.warning(error); } -- cgit v1.2.3 From 5e2ad583f62db56fe81ec4c41756fb3fc28747a5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 11 Mar 2016 16:22:40 +1300 Subject: Add devices to group tree --- src/org/traccar/database/GroupTree.java | 99 +++++++++++++++++------- src/org/traccar/database/PermissionsManager.java | 13 ++-- test/org/traccar/database/GroupTreeTest.java | 30 +++++-- 3 files changed, 103 insertions(+), 39 deletions(-) (limited to 'src/org/traccar') diff --git a/src/org/traccar/database/GroupTree.java b/src/org/traccar/database/GroupTree.java index 7263a6331..b383b1501 100644 --- a/src/org/traccar/database/GroupTree.java +++ b/src/org/traccar/database/GroupTree.java @@ -15,6 +15,7 @@ */ package org.traccar.database; +import org.traccar.model.Device; import org.traccar.model.Group; import java.util.ArrayList; @@ -26,80 +27,126 @@ import java.util.Set; public class GroupTree { - private static class GroupNode { + private static class TreeNode { private Group group; - private GroupNode parent; - private Collection children = new HashSet<>(); + private Device device; + private Collection children = new HashSet<>(); - public GroupNode(Group group) { + public TreeNode(Group group) { this.group = group; } + public TreeNode(Device device) { + this.device = device; + } + @Override public int hashCode() { - return (int) group.getId(); + if (group != null) { + return (int) group.getId(); + } else { + return (int) device.getId(); + } } @Override public boolean equals(Object obj) { - if (!(obj instanceof GroupNode)) { + if (!(obj instanceof TreeNode)) { return false; } - return obj == this || group.getId() == ((GroupNode) obj).group.getId(); + TreeNode other = (TreeNode) obj; + if (other == this) { + return true; + } + if (group != null) { + if (other.group != null) { + return group.getId() == other.group.getId(); + } + } else if (device != null) { + if (other.device != null) { + return device.getId() == other.device.getId(); + } + } + return false; } public Group getGroup() { return group; } - public void setParent(GroupNode parent) { - this.parent = parent; + public Device getDevice() { + return device; + } + + public void setParent(TreeNode parent) { if (parent != null) { parent.children.add(this); } } - public GroupNode getParent() { - return parent; - } - - public Collection getChildren() { + public Collection getChildren() { return children; } } - private final Map groupMap = new HashMap<>(); + private final Map groupMap = new HashMap<>(); - public GroupTree(Collection groups) { + public GroupTree(Collection groups, Collection devices) { for (Group group : groups) { - groupMap.put(group.getId(), new GroupNode(group)); + groupMap.put(group.getId(), new TreeNode(group)); } - for (GroupNode node : groupMap.values()) { + for (TreeNode node : groupMap.values()) { if (node.getGroup().getGroupId() != 0) { node.setParent(groupMap.get(node.getGroup().getGroupId())); } } + Map deviceMap = new HashMap<>(); + + for (Device device : devices) { + deviceMap.put(device.getId(), new TreeNode(device)); + } + + for (TreeNode node : deviceMap.values()) { + if (node.getDevice().getGroupId() != 0) { + node.setParent(groupMap.get(node.getDevice().getGroupId())); + } + } + } - public Collection getDescendants(long groupId) { - Set results = new HashSet<>(); - getDescendants(results, groupMap.get(groupId)); + public Collection getGroups(long groupId) { + Set results = new HashSet<>(); + getNodes(results, groupMap.get(groupId)); Collection groups = new ArrayList<>(); - for (GroupNode node : results) { - groups.add(node.getGroup()); + for (TreeNode node : results) { + if (node.getGroup() != null) { + groups.add(node.getGroup()); + } } return groups; } - private void getDescendants(Set results, GroupNode node) { - for (GroupNode child : node.getChildren()) { + public Collection getDevices(long groupId) { + Set results = new HashSet<>(); + getNodes(results, groupMap.get(groupId)); + Collection devices = new ArrayList<>(); + for (TreeNode node : results) { + if (node.getDevice() != null) { + devices.add(node.getDevice()); + } + } + return devices; + } + + private void getNodes(Set results, TreeNode node) { + for (TreeNode child : node.getChildren()) { results.add(child); - getDescendants(results, child); + getNodes(results, child); } } diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 0aefb9605..dc37bbc84 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -16,7 +16,6 @@ package org.traccar.database; import java.sql.SQLException; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -69,23 +68,23 @@ public class PermissionsManager { users.put(user.getId(), user); } - GroupTree groupTree = new GroupTree(dataManager.getAllGroups()); + GroupTree groupTree = new GroupTree(dataManager.getAllGroups(), dataManager.getAllDevices()); for (GroupPermission permission : dataManager.getGroupPermissions()) { Set userGroupPermissions = getGroupPermissions(permission.getUserId()); + Set userDevicePermissions = getDevicePermissions(permission.getUserId()); userGroupPermissions.add(permission.getGroupId()); - for (Group group : groupTree.getDescendants(permission.getGroupId())) { + for (Group group : groupTree.getGroups(permission.getGroupId())) { userGroupPermissions.add(group.getId()); } + for (Device device : groupTree.getDevices(permission.getGroupId())) { + userDevicePermissions.add(device.getId()); + } } for (DevicePermission permission : dataManager.getDevicePermissions()) { getDevicePermissions(permission.getUserId()).add(permission.getDeviceId()); } - for (Device device : dataManager.getAllDevices()) { - // TODO - } - } catch (SQLException error) { Log.warning(error); } diff --git a/test/org/traccar/database/GroupTreeTest.java b/test/org/traccar/database/GroupTreeTest.java index 26ac595f8..f73cb75b6 100644 --- a/test/org/traccar/database/GroupTreeTest.java +++ b/test/org/traccar/database/GroupTreeTest.java @@ -2,6 +2,7 @@ package org.traccar.database; import org.junit.Assert; import org.junit.Test; +import org.traccar.model.Device; import org.traccar.model.Group; import java.util.ArrayList; @@ -16,7 +17,15 @@ public class GroupTreeTest { group.setGroupId(parent); return group; } - + + private static Device createDevice(long id, String name, long parent) { + Device device = new Device(); + device.setId(id); + device.setName(name); + device.setGroupId(parent); + return device; + } + @Test public void testGetDescendants() { Collection groups = new ArrayList<>(); @@ -26,12 +35,21 @@ public class GroupTreeTest { groups.add(createGroup(4, "Fourth", 2)); groups.add(createGroup(5, "Fifth", 4)); - GroupTree groupTree = new GroupTree(groups); + Collection devices = new ArrayList<>(); + devices.add(createDevice(1, "One", 3)); + devices.add(createDevice(2, "Two", 5)); + devices.add(createDevice(3, "One", 5)); + + GroupTree groupTree = new GroupTree(groups, devices); + + Assert.assertEquals(4, groupTree.getGroups(1).size()); + Assert.assertEquals(3, groupTree.getGroups(2).size()); + Assert.assertEquals(0, groupTree.getGroups(3).size()); + Assert.assertEquals(1, groupTree.getGroups(4).size()); - Assert.assertEquals(4, groupTree.getDescendants(1).size()); - Assert.assertEquals(3, groupTree.getDescendants(2).size()); - Assert.assertEquals(0, groupTree.getDescendants(3).size()); - Assert.assertEquals(1, groupTree.getDescendants(4).size()); + Assert.assertEquals(3, groupTree.getDevices(1).size()); + Assert.assertEquals(1, groupTree.getDevices(3).size()); + Assert.assertEquals(2, groupTree.getDevices(4).size()); } } -- cgit v1.2.3