aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2015-10-25 12:02:40 +1300
committerAnton Tananaev <anton.tananaev@gmail.com>2015-10-25 12:02:40 +1300
commit943ed449bb3862c8e3c380d51675d20ac4806cf3 (patch)
tree085fe228a9fc19842a339563e8acd1e7879814c8
parente273bf603317165d4ef43f302a7a9066b050bc8f (diff)
downloadtraccar-server-943ed449bb3862c8e3c380d51675d20ac4806cf3.tar.gz
traccar-server-943ed449bb3862c8e3c380d51675d20ac4806cf3.tar.bz2
traccar-server-943ed449bb3862c8e3c380d51675d20ac4806cf3.zip
Refactor H02 protocol decoder
-rw-r--r--src/org/traccar/helper/Parser.java6
-rw-r--r--src/org/traccar/protocol/H02ProtocolDecoder.java141
-rw-r--r--test/org/traccar/protocol/H02ProtocolDecoderTest.java9
3 files changed, 71 insertions, 85 deletions
diff --git a/src/org/traccar/helper/Parser.java b/src/org/traccar/helper/Parser.java
index 7c15c0323..9f24cacd0 100644
--- a/src/org/traccar/helper/Parser.java
+++ b/src/org/traccar/helper/Parser.java
@@ -67,8 +67,12 @@ public class Parser {
}
public long nextLong() {
+ return nextLong(10);
+ }
+
+ public long nextLong(int radix) {
if (hasNext()) {
- return Long.parseLong(next());
+ return Long.parseLong(next(), radix);
} else {
return 0;
}
diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java
index d8cf762f4..3d4dc0e9d 100644
--- a/src/org/traccar/protocol/H02ProtocolDecoder.java
+++ b/src/org/traccar/protocol/H02ProtocolDecoder.java
@@ -24,8 +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.helper.BitUtil;
-import org.traccar.helper.ChannelBufferTools;
+import org.traccar.helper.*;
import org.traccar.model.Event;
import org.traccar.model.Position;
@@ -46,7 +45,13 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
if (lon) {
result = buf.readUnsignedByte() & 0x0f;
}
- result = result * 10 + ChannelBufferTools.readHexInteger(buf, lon ? 5 : 6) * 0.0001;
+
+ int length = 6;
+ if (lon) {
+ length = 5;
+ }
+
+ result = result * 10 + ChannelBufferTools.readHexInteger(buf, length) * 0.0001;
result /= 60;
result += degrees;
@@ -55,7 +60,8 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
}
private void processStatus(Position position, long status) {
- if (!BitUtil.check(status, 0) || !BitUtil.check(status, 1) || !BitUtil.check(status, 3) || !BitUtil.check(status, 4)) {
+ if (!BitUtil.check(status, 0) || !BitUtil.check(status, 1)
+ || !BitUtil.check(status, 3) || !BitUtil.check(status, 4)) {
position.set(Event.KEY_ALARM, true);
}
position.set(Event.KEY_IGNITION, !BitUtil.check(status, 10));
@@ -64,41 +70,41 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
private Position decodeBinary(ChannelBuffer buf, Channel channel) {
- // Create new position
Position position = new Position();
position.setProtocol(getProtocolName());
buf.readByte(); // marker
- // Identification
if (!identify(ChannelBufferTools.readHexString(buf, 10), channel)) {
return null;
}
position.setDeviceId(getDeviceId());
- // Time
- Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- time.clear();
- time.set(Calendar.HOUR_OF_DAY, ChannelBufferTools.readHexInteger(buf, 2));
- time.set(Calendar.MINUTE, ChannelBufferTools.readHexInteger(buf, 2));
- time.set(Calendar.SECOND, ChannelBufferTools.readHexInteger(buf, 2));
- time.set(Calendar.DAY_OF_MONTH, ChannelBufferTools.readHexInteger(buf, 2));
- time.set(Calendar.MONTH, ChannelBufferTools.readHexInteger(buf, 2) - 1);
- time.set(Calendar.YEAR, 2000 + ChannelBufferTools.readHexInteger(buf, 2));
- position.setTime(time.getTime());
-
- // Location
+ DateBuilder dateBuilder = new DateBuilder()
+ .setHour(ChannelBufferTools.readHexInteger(buf, 2))
+ .setMinute(ChannelBufferTools.readHexInteger(buf, 2))
+ .setSecond(ChannelBufferTools.readHexInteger(buf, 2))
+ .setDay(ChannelBufferTools.readHexInteger(buf, 2))
+ .setMonth(ChannelBufferTools.readHexInteger(buf, 2))
+ .setYear(ChannelBufferTools.readHexInteger(buf, 2));
+ position.setTime(dateBuilder.getDate());
+
double latitude = readCoordinate(buf, false);
position.set(Event.KEY_POWER, buf.readByte());
double longitude = readCoordinate(buf, true);
+
int flags = buf.readUnsignedByte() & 0x0f;
position.setValid((flags & 0x02) != 0);
- if ((flags & 0x04) == 0) latitude = -latitude;
- if ((flags & 0x08) == 0) longitude = -longitude;
+ if ((flags & 0x04) == 0) {
+ latitude = -latitude;
+ }
+ if ((flags & 0x08) == 0) {
+ longitude = -longitude;
+ }
+
position.setLatitude(latitude);
position.setLongitude(longitude);
- // Speed and course
position.setSpeed(ChannelBufferTools.readHexInteger(buf, 3));
position.setCourse((buf.readUnsignedByte() & 0x0f) * 100.0 + ChannelBufferTools.readHexInteger(buf, 2));
@@ -106,84 +112,57 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
return position;
}
- private static final Pattern PATTERN = Pattern.compile(
- "\\*..," + // Manufacturer
- "(\\d+)," + // IMEI
- "V\\d," + // Version?
- ".*" +
- "(\\d{2})(\\d{2})(\\d{2})," + // Time (HHMMSS)
- "([AV])?," + // Validity
- "-?(\\d+)-?(\\d{2}.\\d+)," + // Latitude (DDMM.MMMM)
- "([NS])," +
- "-?(\\d+)-?(\\d{2}.\\d+)," + // Longitude (DDMM.MMMM)
- "([EW])," +
- "(\\d+.?\\d*)," + // Speed
- "(\\d+.?\\d*)?," + // Course
- "(\\d{2})(\\d{2})(\\d{2})," + // Date (DDMMYY)
- "(\\p{XDigit}{8})" + // Status
- ".*");
+ private static final Pattern PATTERN = new PatternBuilder()
+ .text("*")
+ .expression("..,") // manufacturer
+ .number("(d+),") // imei
+ .number("Vd,") // version?
+ .any()
+ .number("(dd)(dd)(dd),") // time
+ .expression("([AV])?,") // validity
+ .number("-?(d+)-?(dd.d+),") // latitude
+ .expression("([NS]),")
+ .number("-?(d+)-?(dd.d+),") // longitude
+ .expression("([EW]),")
+ .number("(d+.?d*),") // speed
+ .number("(d+.?d*)?,") // course
+ .number("(dd)(dd)(dd),") // date (ddmmyy)
+ .number("(x{8})") // status
+ .any()
+ .compile();
private Position decodeText(String sentence, Channel channel) {
- // Parse message
- Matcher parser = PATTERN.matcher(sentence);
+ Parser parser = new Parser(PATTERN, sentence);
if (!parser.matches()) {
return null;
}
- // Create new position
Position position = new Position();
position.setProtocol(getProtocolName());
- Integer index = 1;
-
- // Get device by IMEI
- if (!identify(parser.group(index++), channel)) {
+ if (!identify(parser.next(), channel)) {
return null;
}
position.setDeviceId(getDeviceId());
- // Time
- Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- time.clear();
- 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++)));
-
- // Validity
- String valid = parser.group(index++);
- if (valid != null) {
- position.setValid(valid.compareTo("A") == 0);
- }
-
- // Latitude
- Double latitude = Double.parseDouble(parser.group(index++));
- latitude += Double.parseDouble(parser.group(index++)) / 60;
- if (parser.group(index++).compareTo("S") == 0) latitude = -latitude;
- position.setLatitude(latitude);
+ DateBuilder dateBuilder = new DateBuilder()
+ .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
- // Longitude
- Double longitude = Double.parseDouble(parser.group(index++));
- longitude += Double.parseDouble(parser.group(index++)) / 60;
- if (parser.group(index++).compareTo("W") == 0) longitude = -longitude;
- position.setLongitude(longitude);
+ if (parser.hasNext()) {
+ position.setValid(parser.next().equals("A"));
+ }
- // Speed
- position.setSpeed(Double.parseDouble(parser.group(index++)));
+ position.setLatitude(parser.nextCoordinate());
+ position.setLongitude(parser.nextCoordinate());
+ position.setSpeed(parser.nextDouble());
+ position.setCourse(parser.nextDouble());
- // Course
- String course = parser.group(index++);
- if (course != null) {
- position.setCourse(Double.parseDouble(course));
- }
+ dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ position.setTime(dateBuilder.getDate());
- // Date
- time.set(Calendar.DAY_OF_MONTH, Integer.parseInt(parser.group(index++)));
- time.set(Calendar.MONTH, Integer.parseInt(parser.group(index++)) - 1);
- time.set(Calendar.YEAR, 2000 + Integer.parseInt(parser.group(index++)));
- position.setTime(time.getTime());
+ processStatus(position, parser.nextLong(16));
- processStatus(position, Long.parseLong(parser.group(index++), 16));
return position;
}
@@ -195,7 +174,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
ChannelBuffer buf = (ChannelBuffer) msg;
String marker = buf.toString(0, 1, Charset.defaultCharset());
- // TODO X mode?
+ // handle X mode?
if (marker.equals("*")) {
return decodeText(buf.toString(Charset.defaultCharset()), channel);
diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java
index 787b1596e..b7d2b07b0 100644
--- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java
@@ -12,10 +12,12 @@ public class H02ProtocolDecoderTest extends ProtocolDecoderTest {
H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol());
verifyPosition(decoder, buffer(
- "*HQ,355488020119695,V1,050418,,2827.61232,N,07703.84822,E,0.00,0,031015,FFFEFBFF#"));
+ "*HQ,355488020119695,V1,050418,,2827.61232,N,07703.84822,E,0.00,0,031015,FFFEFBFF#"),
+ position("2015-10-03 05:04:18.000", false, 28.46021, 77.06414));
verifyPosition(decoder, buffer(
- "*HQ,1451316409,V1,030149,A,-23-29.0095,S,-46-51.5852,W,2.4,065,070315,FFFFFFFF#"));
+ "*HQ,1451316409,V1,030149,A,-23-29.0095,S,-46-51.5852,W,2.4,065,070315,FFFFFFFF#"),
+ position("2015-03-07 03:01:49.000", true, -23.48349, -46.85975));
verifyNothing(decoder, buffer(
"*HQ,353588020068342,V1,000000,V,0.0000,0,0.0000,0,0.00,0.00,000000,ffffffff,000106,000002,000203,004c87,16#"));
@@ -81,7 +83,8 @@ public class H02ProtocolDecoderTest extends ProtocolDecoderTest {
"*HQ,8401016597,BASE,152609,0,0,0,0,211014,FFFFFFFF#"));
verifyPosition(decoder, binary(
- "24410600082621532131081504419390060740418306000000fffffbfdff0015060000002c02dc0c000000001f"));
+ "24410600082621532131081504419390060740418306000000fffffbfdff0015060000002c02dc0c000000001f"),
+ position("2015-08-31 21:53:21.000", true, 4.69898, -74.06971));
verifyPosition(decoder, binary(
"2427051711092133391406135002584900014337822e000000ffffffffff0000"));