From 4e07ad9afa05e61e884e2c4be83b1cd4f9d051ae Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Oct 2016 14:06:00 +1300 Subject: Rename and format TrakMate protocol --- src/org/traccar/protocol/TkmateProtocol.java | 32 --- .../traccar/protocol/TkmateProtocolDecoder.java | 207 ------------------ src/org/traccar/protocol/TrakMateProtocol.java | 47 ++++ .../traccar/protocol/TrakMateProtocolDecoder.java | 236 +++++++++++++++++++++ .../protocol/TkmateProtocolDecoderTest.java | 28 --- .../protocol/TrakMateProtocolDecoderTest.java | 24 +++ 6 files changed, 307 insertions(+), 267 deletions(-) delete mode 100644 src/org/traccar/protocol/TkmateProtocol.java delete mode 100644 src/org/traccar/protocol/TkmateProtocolDecoder.java create mode 100644 src/org/traccar/protocol/TrakMateProtocol.java create mode 100644 src/org/traccar/protocol/TrakMateProtocolDecoder.java delete mode 100644 test/org/traccar/protocol/TkmateProtocolDecoderTest.java create mode 100644 test/org/traccar/protocol/TrakMateProtocolDecoderTest.java diff --git a/src/org/traccar/protocol/TkmateProtocol.java b/src/org/traccar/protocol/TkmateProtocol.java deleted file mode 100644 index 156718aaa..000000000 --- a/src/org/traccar/protocol/TkmateProtocol.java +++ /dev/null @@ -1,32 +0,0 @@ -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.jboss.netty.handler.codec.string.StringEncoder; -import org.traccar.BaseProtocol; -import org.traccar.CharacterDelimiterFrameDecoder; -import org.traccar.TrackerServer; - -import java.util.List; - - -public class TkmateProtocol extends BaseProtocol { - - public TkmateProtocol() { - super("trakmate"); - } - - @Override - public void initTrackerServers(List serverList) { - serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { - @Override - protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "#")); - pipeline.addLast("stringDecoder", new StringDecoder()); - pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("objectDecoder", new TkmateProtocolDecoder(TkmateProtocol.this)); - } - }); - } -} diff --git a/src/org/traccar/protocol/TkmateProtocolDecoder.java b/src/org/traccar/protocol/TkmateProtocolDecoder.java deleted file mode 100644 index 08f189ece..000000000 --- a/src/org/traccar/protocol/TkmateProtocolDecoder.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.traccar.protocol; - -import org.jboss.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; -import org.traccar.helper.DateBuilder; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.model.Position; - -import java.net.SocketAddress; -import java.util.TimeZone; -import java.util.regex.Pattern; - - -public class TkmateProtocolDecoder extends BaseProtocolDecoder { - - private final TimeZone timeZone = TimeZone.getTimeZone("UTC"); - - public TkmateProtocolDecoder(TkmateProtocol protocol) { - super(protocol); - timeZone.setRawOffset(Context.getConfig().getInteger(getProtocolName() + ".timezone") * 1000); - } - - private static final Pattern PATTERN_SRT = new PatternBuilder() - .text("^TMSRT|") - .expression("([^ ]+)|") // uid - .number("(d+.d+)|") // latitude - .number("(d+.d+)|") // longitude - .number("(dd)(dd)(dd)|") // time - .number("(dd)(dd)(dd)|") // date - .number("(d+.d+)|") // software ver - .number("(d+.d+)|") // Hardware ver - .any() - .compile(); - - - private static final Pattern PATTERN_PER = new PatternBuilder() - .text("^TMPER|") - .expression("([^ ]+)|") // uid - .number("(d+)|") // seq - .number("(d+.d+)|") // latitude - .number("(d+.d+)|") // longitude - .number("(dd)(dd)(dd)|") // time - .number("(dd)(dd)(dd)|") // date - .number("(d+.d+)|") // speed - .number("(d+.d+)|") // heading - .number("(d+)|") // ignition - .number("(d+)|") // dop1 - .number("(d+)|") // dop2 - .number("(d+.d+)|") // analog - .number("(d+.d+)|") // internal battery - .number("(d+.d+)|") // vehicle battery - .number("(d+.d+)|") // gps odometer - .number("(d+.d+)|") // pulse odometer - .number("(d+)|") // main power status - .number("(d+)|") // gps data validity - .number("(d+)|") // live or cache - .any() - .compile(); - - - private static final Pattern PATTERN_ALT = new PatternBuilder() - .text("^TMALT|") - .expression("([^ ]+)|") // uid - .number("(d+)|") // seq - .number("(d+)|") // Alert type - .number("(d+)|") // Alert status - .number("(d+.d+)|") // latitude - .number("(d+.d+)|") // longitude - .number("(dd)(dd)(dd)|") // time - .number("(dd)(dd)(dd)|") // date - .number("(d+.d+)|") // speed - .number("(d+.d+)|") // heading - .any() - .compile(); - - - private String decodeAlarm(int value) { - switch (value) { - case 1: - return Position.ALARM_SOS; - case 3: - return Position.ALARM_GEOFENCE; - case 4: - return Position.ALARM_POWER_CUT; - default: - return null; - } - } - - private Object decodeSrt(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_SRT, sentence); - if (!parser.matches()) { - return null; - } - Position position = new Position(); - position.setProtocol(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - DateBuilder dateBuilder = new DateBuilder(timeZone) - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()) - .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - position.set(Position.KEY_VERSION, parser.next()); - parser.next(); //hardware version - return position; - } - - - private Object decodeAlt(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_ALT, sentence); - if (!parser.matches()) { - return null; - } - Position position = new Position(); - position.setProtocol(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - parser.next(); // seq - int alarm = parser.nextInt(); - position.set(Position.KEY_ALARM, decodeAlarm(alarm)); - parser.next(); //alert status or data - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - DateBuilder dateBuilder = new DateBuilder(timeZone) - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()) - .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - position.setSpeed(parser.nextDouble()); - position.setCourse(parser.nextDouble()); - return position; - } - - - protected Object decodePer(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - Parser parser = new Parser(PATTERN_PER, (String) msg); - if (!parser.matches()) { - return null; - } - Position position = new Position(); - position.setProtocol(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - parser.next(); //seq - position.setLatitude(parser.nextDouble()); - position.setLongitude(parser.nextDouble()); - DateBuilder dateBuilder = new DateBuilder(timeZone) - .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()) - .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); - position.setTime(dateBuilder.getDate()); - position.setSpeed(parser.nextDouble()); - position.setCourse(parser.nextDouble()); - position.set(Position.KEY_IGNITION, parser.nextInt() == 1); - parser.next(); //dop1 - parser.next(); //dop2 - parser.next(); //analog input - position.set(Position.KEY_BATTERY, parser.nextDouble()); //device battery voltage - parser.next(); //vehicle internal voltage - position.set(Position.KEY_ODOMETER, parser.nextDouble()); //GPS odometer - parser.next(); //pulse odometer - position.set(Position.KEY_STATUS, parser.nextInt()); - position.setValid(parser.nextInt() != 0); - position.set(Position.KEY_ARCHIVE, parser.nextInt() == 1); - return position; - } - - @Override - protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - String sentence = (String) msg; - int typeIndex = sentence.indexOf("^TM"); - if (typeIndex < 0) { - return null; - } - - Object result; - String type = sentence.substring(typeIndex + 3, typeIndex + 6); - switch (type) { - case "ALT": - result = decodeAlt(channel, remoteAddress, sentence); - break; - case "SRT": - result = decodeSrt(channel, remoteAddress, sentence); - break; - case "PER": - result = decodePer(channel, remoteAddress, sentence); - break; - default: - return null; - } - return result; - - } -} - diff --git a/src/org/traccar/protocol/TrakMateProtocol.java b/src/org/traccar/protocol/TrakMateProtocol.java new file mode 100644 index 000000000..3126fb80b --- /dev/null +++ b/src/org/traccar/protocol/TrakMateProtocol.java @@ -0,0 +1,47 @@ +/* + * 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.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class TrakMateProtocol extends BaseProtocol { + + public TrakMateProtocol() { + super("trakmate"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '#')); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new TrakMateProtocolDecoder(TrakMateProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/TrakMateProtocolDecoder.java b/src/org/traccar/protocol/TrakMateProtocolDecoder.java new file mode 100644 index 000000000..0ca40e6ab --- /dev/null +++ b/src/org/traccar/protocol/TrakMateProtocolDecoder.java @@ -0,0 +1,236 @@ +/* + * 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.DeviceSession; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.TimeZone; +import java.util.regex.Pattern; + +public class TrakMateProtocolDecoder extends BaseProtocolDecoder { + + private final TimeZone timeZone = TimeZone.getTimeZone("UTC"); + + public TrakMateProtocolDecoder(TrakMateProtocol protocol) { + super(protocol); + timeZone.setRawOffset(Context.getConfig().getInteger(getProtocolName() + ".timezone") * 1000); + } + + private static final Pattern PATTERN_SRT = new PatternBuilder() + .text("^TMSRT|") + .expression("([^ ]+)|") // uid + .number("(d+.d+)|") // latitude + .number("(d+.d+)|") // longitude + .number("(dd)(dd)(dd)|") // time + .number("(dd)(dd)(dd)|") // date + .number("(d+.d+)|") // software ver + .number("(d+.d+)|") // Hardware ver + .any() + .compile(); + + private static final Pattern PATTERN_PER = new PatternBuilder() + .text("^TMPER|") + .expression("([^ ]+)|") // uid + .number("(d+)|") // seq + .number("(d+.d+)|") // latitude + .number("(d+.d+)|") // longitude + .number("(dd)(dd)(dd)|") // time + .number("(dd)(dd)(dd)|") // date + .number("(d+.d+)|") // speed + .number("(d+.d+)|") // heading + .number("(d+)|") // ignition + .number("(d+)|") // dop1 + .number("(d+)|") // dop2 + .number("(d+.d+)|") // analog + .number("(d+.d+)|") // internal battery + .number("(d+.d+)|") // vehicle battery + .number("(d+.d+)|") // gps odometer + .number("(d+.d+)|") // pulse odometer + .number("(d+)|") // main power status + .number("(d+)|") // gps data validity + .number("(d+)|") // live or cache + .any() + .compile(); + + private static final Pattern PATTERN_ALT = new PatternBuilder() + .text("^TMALT|") + .expression("([^ ]+)|") // uid + .number("(d+)|") // seq + .number("(d+)|") // Alert type + .number("(d+)|") // Alert status + .number("(d+.d+)|") // latitude + .number("(d+.d+)|") // longitude + .number("(dd)(dd)(dd)|") // time + .number("(dd)(dd)(dd)|") // date + .number("(d+.d+)|") // speed + .number("(d+.d+)|") // heading + .any() + .compile(); + + private String decodeAlarm(int value) { + switch (value) { + case 1: + return Position.ALARM_SOS; + case 3: + return Position.ALARM_GEOFENCE; + case 4: + return Position.ALARM_POWER_CUT; + default: + return null; + } + } + + private Object decodeSrt(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_SRT, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + + DateBuilder dateBuilder = new DateBuilder(timeZone) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + position.set(Position.KEY_VERSION, parser.next()); + parser.next(); // hardware version + + return position; + } + + private Object decodeAlt(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_ALT, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + parser.next(); // seq + position.set(Position.KEY_ALARM, decodeAlarm(parser.nextInt())); + parser.next(); // alert status or data + + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + + DateBuilder dateBuilder = new DateBuilder(timeZone) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + position.setSpeed(parser.nextDouble()); + position.setCourse(parser.nextDouble()); + + return position; + } + + private Object decodePer(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN_PER, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + parser.next(); // seq + + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + + DateBuilder dateBuilder = new DateBuilder(timeZone) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + position.setSpeed(parser.nextDouble()); + position.setCourse(parser.nextDouble()); + + position.set(Position.KEY_IGNITION, parser.nextInt() == 1); + parser.next(); // dop1 + parser.next(); // dop2 + parser.next(); // analog input + position.set(Position.KEY_BATTERY, parser.nextDouble()); // device battery voltage + parser.next(); // vehicle internal voltage + position.set(Position.KEY_ODOMETER, parser.nextDouble()); // gps odometer + parser.next(); // pulse odometer + position.set(Position.KEY_STATUS, parser.nextInt()); + + position.setValid(parser.nextInt() != 0); + + position.set(Position.KEY_ARCHIVE, parser.nextInt() == 1); + + return position; + } + + @Override + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = (String) msg; + int typeIndex = sentence.indexOf("^TM"); + if (typeIndex < 0) { + return null; + } + + String type = sentence.substring(typeIndex + 3, typeIndex + 6); + switch (type) { + case "ALT": + return decodeAlt(channel, remoteAddress, sentence); + case "SRT": + return decodeSrt(channel, remoteAddress, sentence); + case "PER": + return decodePer(channel, remoteAddress, sentence); + default: + return null; + } + } + +} diff --git a/test/org/traccar/protocol/TkmateProtocolDecoderTest.java b/test/org/traccar/protocol/TkmateProtocolDecoderTest.java deleted file mode 100644 index 61df237d7..000000000 --- a/test/org/traccar/protocol/TkmateProtocolDecoderTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.traccar.protocol; - -import org.junit.Test; -import org.traccar.ProtocolTest; - - -public class TkmateProtocolDecoderTest extends ProtocolTest { - - @Test - public void testDecode() throws Exception { - - - TkmateProtocolDecoder decoder = new TkmateProtocolDecoder(new TkmateProtocol()); - - verifyPosition(decoder, text( - "^TMPER|354678456723764|1|12.59675|77.56789|123456|030414|2.3|34.0|1|0|0|0.015|3.9|12.0|23.4|" + - "23.4|1|1|0|#")); - - verifyPosition(decoder, text( - "^TMALT|354678456723764|3|2|1|12.59675|77.56789|123456|030414|1.2|34.0|#")); - - verifyPosition(decoder, text( - "^TMSRT|354678456723764|12.59675|77.56789|123456|030414|1.03|1.01|#")); - - } - -} - diff --git a/test/org/traccar/protocol/TrakMateProtocolDecoderTest.java b/test/org/traccar/protocol/TrakMateProtocolDecoderTest.java new file mode 100644 index 000000000..b08decc92 --- /dev/null +++ b/test/org/traccar/protocol/TrakMateProtocolDecoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class TrakMateProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + TrakMateProtocolDecoder decoder = new TrakMateProtocolDecoder(new TrakMateProtocol()); + + verifyPosition(decoder, text( + "^TMPER|354678456723764|1|12.59675|77.56789|123456|030414|2.3|34.0|1|0|0|0.015|3.9|12.0|23.4|23.4|1|1|0|#")); + + verifyPosition(decoder, text( + "^TMALT|354678456723764|3|2|1|12.59675|77.56789|123456|030414|1.2|34.0|#")); + + verifyPosition(decoder, text( + "^TMSRT|354678456723764|12.59675|77.56789|123456|030414|1.03|1.01|#")); + + } + +} -- cgit v1.2.3