aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2016-12-05 07:55:25 +1300
committerAnton Tananaev <anton.tananaev@gmail.com>2016-12-05 07:55:25 +1300
commit6936e7aa6404419c5a9380c5e62489abcd58ce0d (patch)
treef9938acad173a5c8597b525f68eaca5eb5e46b45
parentc9232000e595b0addd4bf7bbaf7a90e088c94624 (diff)
downloadtrackermap-server-6936e7aa6404419c5a9380c5e62489abcd58ce0d.tar.gz
trackermap-server-6936e7aa6404419c5a9380c5e62489abcd58ce0d.tar.bz2
trackermap-server-6936e7aa6404419c5a9380c5e62489abcd58ce0d.zip
Implement OIGO MG protocol
-rw-r--r--src/org/traccar/helper/UnitsConverter.java9
-rw-r--r--src/org/traccar/protocol/OigoProtocolDecoder.java97
-rw-r--r--test/org/traccar/protocol/OigoProtocolDecoderTest.java15
3 files changed, 113 insertions, 8 deletions
diff --git a/src/org/traccar/helper/UnitsConverter.java b/src/org/traccar/helper/UnitsConverter.java
index 00b00861e..e0d94c6dc 100644
--- a/src/org/traccar/helper/UnitsConverter.java
+++ b/src/org/traccar/helper/UnitsConverter.java
@@ -21,6 +21,7 @@ public final class UnitsConverter {
private static final double KNOTS_TO_MPH_RATIO = 0.868976;
private static final double KNOTS_TO_MPS_RATIO = 1.94384;
private static final double KNOTS_TO_CPS_RATIO = 0.0194384449;
+ private static final double METERS_TO_FEET_RATIO = 0.3048;
private UnitsConverter() {
}
@@ -53,4 +54,12 @@ public final class UnitsConverter {
return value * KNOTS_TO_CPS_RATIO;
}
+ public static double feetFromMeters(double value) {
+ return value / METERS_TO_FEET_RATIO;
+ }
+
+ public static double metersFromFeet(double value) {
+ return value * METERS_TO_FEET_RATIO;
+ }
+
}
diff --git a/src/org/traccar/protocol/OigoProtocolDecoder.java b/src/org/traccar/protocol/OigoProtocolDecoder.java
index 15a215c4f..3a4134eda 100644
--- a/src/org/traccar/protocol/OigoProtocolDecoder.java
+++ b/src/org/traccar/protocol/OigoProtocolDecoder.java
@@ -34,15 +34,12 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
- public static final int MSG_LOCATION = 0x00;
- public static final int MSG_REMOTE_START = 0x10;
- public static final int MSG_ACKNOWLEDGEMENT = 0xE0;
+ public static final int MSG_AR_LOCATION = 0x00;
+ public static final int MSG_AR_REMOTE_START = 0x10;
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ public static final int MSG_ACKNOWLEDGEMENT = 0xE0;
- ChannelBuffer buf = (ChannelBuffer) msg;
+ private Position decodeArMessage(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
buf.skipBytes(1); // header
buf.readUnsignedShort(); // length
@@ -67,7 +64,7 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder {
break;
}
- if (deviceSession == null || type != MSG_LOCATION) {
+ if (deviceSession == null || type != MSG_AR_LOCATION) {
return null;
}
@@ -154,4 +151,88 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder {
return position;
}
+ private double convertCoordinate(long value) {
+ boolean negative = value < 0;
+ value = Math.abs(value);
+ double minutes = (value % 100000) * 0.001;
+ double degrees = value / 100000 + minutes / 60;
+ return negative ? -degrees : degrees;
+ }
+
+ private Position decodeMgMessage(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
+
+ buf.readUnsignedByte(); // tag
+ int flags = buf.getUnsignedByte(buf.readerIndex());
+
+ DeviceSession deviceSession;
+ if (BitUtil.check(flags, 6)) {
+ buf.readUnsignedByte(); // flags
+ deviceSession = getDeviceSession(channel, remoteAddress);
+ } else {
+ String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1);
+ deviceSession = getDeviceSession(channel, remoteAddress, imei);
+ }
+
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ buf.skipBytes(8); // imsi
+
+ int date = buf.readUnsignedShort();
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setDate(2010 + BitUtil.from(date, 12), BitUtil.between(date, 8, 12), BitUtil.to(date, 8))
+ .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), 0);
+
+ position.setValid(true);
+ position.setLatitude(convertCoordinate(buf.readInt()));
+ position.setLongitude(convertCoordinate(buf.readInt()));
+
+ position.setAltitude(UnitsConverter.metersFromFeet(buf.readShort()));
+ position.setCourse(buf.readUnsignedShort());
+ position.setSpeed(UnitsConverter.knotsFromMph(buf.readUnsignedByte()));
+
+ position.set(Position.KEY_POWER, buf.readUnsignedByte() * 100 + "mV");
+ position.set(Position.PREFIX_IO + 1, buf.readUnsignedByte());
+
+ dateBuilder.setSecond(buf.readUnsignedByte());
+ position.setTime(dateBuilder.getDate());
+
+ position.set(Position.KEY_GSM, buf.readUnsignedByte());
+
+ int index = buf.readUnsignedByte();
+
+ position.set(Position.KEY_VERSION, buf.readUnsignedByte());
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+ position.set(Position.KEY_ODOMETER, (long) (buf.readUnsignedInt() * 1609.34));
+
+ if (channel != null && BitUtil.check(flags, 7)) {
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer();
+ response.writeByte(MSG_ACKNOWLEDGEMENT);
+ response.writeByte(index);
+ response.writeByte(0x00);
+ channel.write(response, remoteAddress);
+ }
+
+ return position;
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ if (buf.getUnsignedByte(buf.readerIndex()) == 0x7e) {
+ return decodeArMessage(channel, remoteAddress,buf);
+ } else {
+ return decodeMgMessage(channel, remoteAddress,buf);
+ }
+ }
+
}
diff --git a/test/org/traccar/protocol/OigoProtocolDecoderTest.java b/test/org/traccar/protocol/OigoProtocolDecoderTest.java
index 14c34ae7c..452e40a78 100644
--- a/test/org/traccar/protocol/OigoProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/OigoProtocolDecoderTest.java
@@ -11,6 +11,21 @@ public class OigoProtocolDecoderTest extends ProtocolTest {
OigoProtocolDecoder decoder = new OigoProtocolDecoder(new OigoProtocol());
verifyPosition(decoder, binary(
+ "0103537820628365110310410790660962521813380026EE4EFF8593AA0065003E00794C020600100500000000"));
+
+ verifyPosition(decoder, binary(
+ "0E03537820628344660204043255862749531B100E0026EE3AFF8593A3FFFE00BF00044C20090710C300000000"));
+
+ verifyPosition(decoder, binary(
+ "00035378206638500203340201271426226b190203001ac000ff72eedd00370097238b4c34116a130b000094d9"));
+
+ verifyPosition(decoder, binary(
+ "1d035378206638500203340201271426226b19020c001ab144ff72f74d005f0097298a4c1d066d130b000094de"));
+
+ verifyPosition(decoder, binary(
+ "00035378206638500203340201271426226b191016001c04e5ff760081013d002900814c1a0f5e130b00009576"));
+
+ verifyPosition(decoder, binary(
"7e004200000014631000258257000000ffff02d0690e000220690e0002200696dbd204bdfde31a070000b307101135de106e05f500000000010908010402200104ffff8001"));
verifyPosition(decoder, binary(