first working parser for SwissTiming GPS packets with test case

This commit is contained in:
Axel Uhl committed 2011-08-25 18:31:49 +02:00
1 parent ac8508e5f8
commit 66c031ccf4
12 files changed
+205 -11

No files matched your search

@@ -6,3 +6,4 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: com.sap.sailing.domain
Export-Package: com.sap.sailing.domain.swisstimingadapter
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.domain.swisstimingadapter</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
@@ -0,0 +1,16 @@
package com.sap.sailing.domain.swisstimingadapter;
public class SwissTimingFormatException extends Exception {
private static final long serialVersionUID = -1210353206288437237L;
private final byte[] swissTimingMessage;
public SwissTimingFormatException(String errorMessage, byte[] swissTimingMessage) {
super(errorMessage);
this.swissTimingMessage = swissTimingMessage;
}
public byte[] getSwissTimingMessage() {
return swissTimingMessage;
}
}
@@ -0,0 +1,23 @@
package com.sap.sailing.domain.swisstimingadapter;
import com.sap.sailing.domain.base.Position;
import com.sap.sailing.domain.base.Speed;
import com.sap.sailing.domain.base.TimePoint;
public interface SwissTimingMessage {
String getRaceID();
int getPacketID();
TimePoint getTimestamp();
int getGpsID();
Position getPosition();
Speed getSpeed();
int getNumberOfSatellites();
int getBatteryPercent();
}
@@ -0,0 +1,9 @@
package com.sap.sailing.domain.swisstimingadapter;
import com.sap.sailing.domain.swisstimingadapter.impl.SwissTimingMessageParserImpl;
public interface SwissTimingMessageParser {
SwissTimingMessageParser INSTANCE = new SwissTimingMessageParserImpl();
SwissTimingMessage parse(byte[] message) throws SwissTimingFormatException;
}
@@ -1,21 +1,22 @@
package com.sap.sailing.domain.swisstimingadapter;
package com.sap.sailing.domain.swisstimingadapter.impl;
import com.sap.sailing.domain.base.Position;
import com.sap.sailing.domain.base.Speed;
import com.sap.sailing.domain.base.TimePoint;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessage;
public class GPSFix {
public class SwissTimingMessageImpl implements SwissTimingMessage {
private final String raceID;
private final int packetID;
private final TimePoint timestamp;
private final short gpsID;
private final int gpsID;
private final Position position;
private final Speed speed;
private final byte numberOfSatellites;
private final byte batteryPercent;
private final int numberOfSatellites;
private final int batteryPercent;
public GPSFix(String raceID, int packetID, TimePoint timestamp, short gpsID, Position position, Speed speed,
byte numberOfSatellites, byte batteryPercent) {
public SwissTimingMessageImpl(String raceID, int packetID, TimePoint timestamp, int gpsID, Position position, Speed speed,
int numberOfSatellites, int batteryPercent) {
super();
this.raceID = raceID;
this.packetID = packetID;
@@ -39,7 +40,7 @@ public class GPSFix {
return timestamp;
}
public short getGpsID() {
public int getGpsID() {
return gpsID;
}
@@ -51,11 +52,11 @@ public class GPSFix {
return speed;
}
public byte getNumberOfSatellites() {
public int getNumberOfSatellites() {
return numberOfSatellites;
}
public byte getBatteryPercent() {
public int getBatteryPercent() {
return batteryPercent;
}
@@ -0,0 +1,81 @@
package com.sap.sailing.domain.swisstimingadapter.impl;
import com.sap.sailing.domain.base.impl.DegreeBearingImpl;
import com.sap.sailing.domain.base.impl.DegreePosition;
import com.sap.sailing.domain.base.impl.KilometersPerHourSpeedWithBearingImpl;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingFormatException;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessage;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessageParser;
public class SwissTimingMessageParserImpl implements SwissTimingMessageParser {
@Override
public SwissTimingMessage parse(byte[] message) throws SwissTimingFormatException {
int i=0;
if (message[i] != 0x10 || message[i+1] != 0x00) {
throw new SwissTimingFormatException("Didn't find start marker 0x1000", message);
}
i+=2;
String raceID = new String(message, i, 9);
i+=9;
int packetID = parseInt(message, i);
i+=4;
long timestamp = parseLong(message, i);
i+=8;
byte packetType = message[i];
if (packetType != 0x02) {
throw new SwissTimingFormatException("Expected to find package type 0x02", message);
}
i+=1;
short gpsID = parseShort(message, i);
i+=2;
int longitude = parseInt(message, i);
i+=4;
int latitude = parseInt(message, i);
i+=4;
int speedInDecimetersPerSecond = 0xFF & message[i];
i+=1;
int course = parseShort(message, i);
i+=2;
int numberOfSatellites = (message[i] & 0xF0) >> 4;
int batteryPercent = 10 * (message[i] & 0x0F);
i+=1;
if (message[i] != 0x10 || message[i+1] != 0x30) {
throw new SwissTimingFormatException("Didn't find end marker 0x1030", message);
}
i+=2;
return new SwissTimingMessageImpl(raceID, packetID, new MillisecondsTimePoint(timestamp), gpsID,
new DegreePosition((double) latitude / 10000000., (double) longitude / 10000000.),
new KilometersPerHourSpeedWithBearingImpl(0.36*speedInDecimetersPerSecond, new DegreeBearingImpl(course)),
numberOfSatellites, batteryPercent);
}
private short parseShort(byte[] message, int offset) {
short result = 0;
for (int b=0; b<2; b++) {
result <<= 8;
result += (0xFF & message[offset+b]);
}
return result;
}
private long parseLong(byte[] message, int offset) {
long result = 0l;
for (int b=0; b<8; b++) {
result <<= 8;
result += (0xFF & message[offset+b]);
}
return result;
}
private int parseInt(byte[] message, int offset) {
int result = 0;
for (int b=0; b<4; b++) {
result <<= 8;
result += (0xFF & message[offset+b]);
}
return result;
}
}