From 1def68657a59e56d2b46a0dfab77a39beed36824 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 1 Nov 2015 17:45:51 +1300 Subject: Refactor TR20 protocol decoder --- src/org/traccar/protocol/Tr20ProtocolDecoder.java | 131 ++++++++-------------- 1 file changed, 49 insertions(+), 82 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Tr20ProtocolDecoder.java b/src/org/traccar/protocol/Tr20ProtocolDecoder.java index 069757820..fac0f8ee9 100644 --- a/src/org/traccar/protocol/Tr20ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tr20ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2012 - 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. @@ -16,12 +16,12 @@ package org.traccar.protocol; import java.net.SocketAddress; -import java.util.Calendar; -import java.util.TimeZone; -import java.util.regex.Matcher; 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.helper.UnitsConverter; import org.traccar.model.Position; @@ -31,98 +31,65 @@ public class Tr20ProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Pattern PATTERN_PING = Pattern.compile( - "%%[^,]+,(\\d+)"); - - private static final Pattern PATTERN_DATA = Pattern.compile( - "%%" + - "([^,]+)," + // Id - "([AL])," + // Validity - "(\\d{2})(\\d{2})(\\d{2})" + // Date (YYMMDD) - "(\\d{2})(\\d{2})(\\d{2})," + // Time (HHMMSS) - "([NS])" + - "(\\d{2})(\\d{2}\\.\\d+)" + // Latitude (DDMM.MMMM) - "([EW])" + - "(\\d{3})(\\d{2}\\.\\d+)," + // Longitude (DDDMM.MMMM) - "(\\d+)," + // Speed - "(\\d+)," + // Course - ".*"); + private static final Pattern PATTERN_PING = new PatternBuilder() + .text("%%") + .expression("[^,]+,") + .number("(d+)") + .compile(); + + private static final Pattern PATTERN_DATA = new PatternBuilder() + .text("%%") + .expression("([^,]+),") // id + .expression("([AL]),") // validity + .number("(dd)(dd)(dd)") // date (yymmdd) + .number("(dd)(dd)(dd),") // time + .expression("([NS])") + .number("(dd)(dd.d+)") // latitude + .expression("([EW])") + .number("(ddd)(dd.d+),") // longitude + .number("(d+),") // speed + .number("(d+),") // course + .any() + .compile(); @Override protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) - throws Exception { - - String sentence = (String) msg; + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - // Keep alive message - Matcher parser = PATTERN_PING.matcher(sentence); + Parser parser = new Parser(PATTERN_PING, (String) msg); if (parser.matches()) { - - // Send response if (channel != null) { - channel.write("&&" + parser.group(1) + "\r\n"); - } - } else { - - // Data message parse - parser = PATTERN_DATA.matcher(sentence); - - // Unknown message - if (!parser.matches()) { - return null; + channel.write("&&" + parser.next() + "\r\n"); // keep-alive response } + return null; + } - // Create new position - Position position = new Position(); - position.setProtocol(getProtocolName()); - - Integer index = 1; - - // Get device by id - if (!identify(parser.group(index++), channel)) { - return null; - } - position.setDeviceId(getDeviceId()); - - // Validity - position.setValid(parser.group(index++).compareTo("A") == 0); - - // Time - Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - time.clear(); - time.set(Calendar.YEAR, 2000 + Integer.parseInt(parser.group(index++))); - time.set(Calendar.MONTH, Integer.parseInt(parser.group(index++)) - 1); - time.set(Calendar.DAY_OF_MONTH, Integer.parseInt(parser.group(index++))); - time.set(Calendar.HOUR_OF_DAY, Integer.parseInt(parser.group(index++))); - time.set(Calendar.MINUTE, Integer.parseInt(parser.group(index++))); - time.set(Calendar.SECOND, Integer.parseInt(parser.group(index++))); - position.setTime(time.getTime()); + parser = new Parser(PATTERN_DATA, (String) msg); + if (!parser.matches()) { + return null; + } - // Latitude - int hemisphere = 1; - if (parser.group(index++).compareTo("S") == 0) hemisphere = -1; - Double latitude = Double.parseDouble(parser.group(index++)); - latitude += Double.parseDouble(parser.group(index++)) / 60; - position.setLatitude(latitude * hemisphere); + Position position = new Position(); + position.setProtocol(getProtocolName()); - // Longitude - hemisphere = 1; - if (parser.group(index++).compareTo("W") == 0) hemisphere = -1; - Double longitude = Double.parseDouble(parser.group(index++)); - longitude += Double.parseDouble(parser.group(index++)) / 60; - position.setLongitude(longitude * hemisphere); + if (!identify(parser.next(), channel)) { + return null; + } + position.setDeviceId(getDeviceId()); - // Speed - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(parser.group(index++)))); + position.setValid(parser.next().equals("A")); - // Course - position.setCourse(Double.parseDouble(parser.group(index++))); + DateBuilder dateBuilder = new DateBuilder() + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()) + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); - return position; - } + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN)); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); + position.setCourse(parser.nextDouble()); - return null; + return position; } } -- cgit v1.2.3