aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debug.xml1
-rw-r--r--schema/changelog-3.7.xml2
-rw-r--r--src/org/traccar/model/Position.java1
-rw-r--r--src/org/traccar/protocol/AplicomProtocolDecoder.java145
-rw-r--r--src/org/traccar/protocol/CguardProtocol.java47
-rw-r--r--src/org/traccar/protocol/CguardProtocolDecoder.java91
-rw-r--r--src/org/traccar/protocol/OigoProtocolDecoder.java4
-rw-r--r--test/org/traccar/protocol/AplicomProtocolDecoderTest.java17
-rw-r--r--test/org/traccar/protocol/CguardProtocolDecoderTest.java54
-rw-r--r--test/org/traccar/protocol/OigoProtocolDecoderTest.java3
10 files changed, 325 insertions, 40 deletions
diff --git a/debug.xml b/debug.xml
index 44f4f2c7f..5de42c027 100644
--- a/debug.xml
+++ b/debug.xml
@@ -457,5 +457,6 @@
<entry key='autograde.port'>5120</entry>
<entry key='oigo.port'>5121</entry>
<entry key='jpkorjar.port'>5122</entry>
+ <entry key='cguard.port'>5123</entry>
</properties>
diff --git a/schema/changelog-3.7.xml b/schema/changelog-3.7.xml
index d82dbe91b..1bae2aaff 100644
--- a/schema/changelog-3.7.xml
+++ b/schema/changelog-3.7.xml
@@ -17,7 +17,7 @@
<update tableName="groups">
<column name="groupid"/>
- <where>groupid NOT IN (SELECT id FROM (SELECT id FROM groups) AS groups_ids)</where>
+ <where>groupid NOT IN (SELECT id FROM (SELECT DISTINCT id FROM groups) AS groups_ids)</where>
</update>
<addColumn tableName="devices">
diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java
index 710dd1e83..c1058aef9 100644
--- a/src/org/traccar/model/Position.java
+++ b/src/org/traccar/model/Position.java
@@ -57,6 +57,7 @@ public class Position extends Message {
public static final String KEY_THROTTLE = "throttle";
public static final String KEY_MOTION = "motion";
public static final String KEY_ARMED = "armed";
+ public static final String KEY_ACCURACY = "accuracy";
public static final String KEY_OBD_SPEED = "obdSpeed";
public static final String KEY_OBD_ODOMETER = "obdOdometer";
diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java
index 23397b51c..abd30ee45 100644
--- a/src/org/traccar/protocol/AplicomProtocolDecoder.java
+++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2015 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2013 - 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.
@@ -27,6 +27,7 @@ import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
@@ -75,7 +76,8 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
return unitId;
}
- private static final int DEFAULT_SELECTOR = 0x0002FC;
+ private static final int DEFAULT_SELECTOR_D = 0x0002fC;
+ private static final int DEFAULT_SELECTOR_E = 0x007ffc;
private static final int EVENT_DATA = 119;
@@ -191,44 +193,12 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
}
}
- @Override
- protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
-
- ChannelBuffer buf = (ChannelBuffer) msg;
-
- buf.readUnsignedByte(); // marker
- int version = buf.readUnsignedByte();
-
- String imei;
- if ((version & 0x80) != 0) {
- imei = String.valueOf((buf.readUnsignedInt() << (3 * 8)) | buf.readUnsignedMedium());
- } else {
- imei = String.valueOf(imeiFromUnitId(buf.readUnsignedMedium()));
- }
-
- buf.readUnsignedShort(); // length
-
- int selector = DEFAULT_SELECTOR;
- if ((version & 0x40) != 0) {
- selector = buf.readUnsignedMedium();
- }
-
- Position position = new Position();
- position.setProtocol(getProtocolName());
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
- if (deviceSession == null) {
- return null;
- }
- position.setDeviceId(deviceSession.getDeviceId());
-
- int event = buf.readUnsignedByte();
- position.set(Position.KEY_EVENT, event);
- position.set("eventInfo", buf.readUnsignedByte());
+ private void decodeD(Position position, ChannelBuffer buf, int selector, int event) {
if ((selector & 0x0008) != 0) {
position.setValid((buf.readUnsignedByte() & 0x40) != 0);
} else {
- return null; // no location data
+ getLastLocation(position, null);
}
if ((selector & 0x0004) != 0) {
@@ -318,9 +288,110 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
if (Context.getConfig().getBoolean(getProtocolName() + ".can")
&& buf.readable() && (selector & 0x1000) != 0 && event == EVENT_DATA) {
-
decodeCanData(buf, position);
}
+ }
+
+ private void decodeE(Position position, ChannelBuffer buf, int selector) {
+
+ if ((selector & 0x0008) != 0) {
+ position.set("tachographEvent", buf.readUnsignedShort());
+ }
+
+ if ((selector & 0x0004) != 0) {
+ getLastLocation(position, new Date(buf.readUnsignedInt() * 1000));
+ } else {
+ getLastLocation(position, null);
+ }
+
+ if ((selector & 0x0010) != 0) {
+ String time = buf.readUnsignedByte() + "s " + buf.readUnsignedByte() + "m " + buf.readUnsignedByte() + "h "
+ + buf.readUnsignedByte() + "M " + buf.readUnsignedByte() + "D " + buf.readUnsignedByte() + "Y "
+ + buf.readByte() + "m " + buf.readByte() + "h";
+ position.set("tachographTime", time);
+ }
+
+ position.set("workState", buf.readUnsignedByte());
+ position.set("driver1State", buf.readUnsignedByte());
+ position.set("driver2State", buf.readUnsignedByte());
+
+ if ((selector & 0x0020) != 0) {
+ position.set("tachographStatus", buf.readUnsignedByte());
+ }
+
+ if ((selector & 0x0040) != 0) {
+ position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() / 256.0);
+ }
+
+ if ((selector & 0x0080) != 0) {
+ position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 5);
+ }
+
+ if ((selector & 0x0100) != 0) {
+ position.set(Position.KEY_TRIP_ODOMETER, buf.readUnsignedInt() * 5);
+ }
+
+ if ((selector & 0x8000) != 0) {
+ position.set("kFactor", buf.readUnsignedShort() * 0.001 + " pulses/m");
+ }
+
+ if ((selector & 0x0200) != 0) {
+ position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.125);
+ }
+
+ if ((selector & 0x0400) != 0) {
+ position.set("extraInfo", buf.readUnsignedShort());
+ }
+
+ if ((selector & 0x0800) != 0) {
+ position.set(Position.KEY_VIN, buf.readBytes(18).toString(StandardCharsets.US_ASCII).trim());
+ }
+ }
+
+ @Override
+ protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ char protocol = (char) buf.readByte();
+ int version = buf.readUnsignedByte();
+
+ String imei;
+ if ((version & 0x80) != 0) {
+ imei = String.valueOf((buf.readUnsignedInt() << (3 * 8)) | buf.readUnsignedMedium());
+ } else {
+ imei = String.valueOf(imeiFromUnitId(buf.readUnsignedMedium()));
+ }
+
+ buf.readUnsignedShort(); // length
+
+ int selector = DEFAULT_SELECTOR_D;
+ if (protocol == 'E') {
+ selector = DEFAULT_SELECTOR_E;
+ }
+ if ((version & 0x40) != 0) {
+ selector = buf.readUnsignedMedium();
+ }
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
+ if (deviceSession == null) {
+ return null;
+ }
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ int event = buf.readUnsignedByte();
+ position.set(Position.KEY_EVENT, event);
+ position.set("eventInfo", buf.readUnsignedByte());
+
+ if (protocol == 'D') {
+ decodeD(position, buf, selector, event);
+ } else if (protocol == 'E') {
+ decodeE(position, buf, selector);
+ } else {
+ return null;
+ }
return position;
}
diff --git a/src/org/traccar/protocol/CguardProtocol.java b/src/org/traccar/protocol/CguardProtocol.java
new file mode 100644
index 000000000..1e6d212c8
--- /dev/null
+++ b/src/org/traccar/protocol/CguardProtocol.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.frame.LineBasedFrameDecoder;
+import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+
+public class CguardProtocol extends BaseProtocol {
+
+ public CguardProtocol() {
+ super("cguard");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(new ServerBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
+ pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
+ pipeline.addLast("objectDecoder", new CguardProtocolDecoder(CguardProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/CguardProtocolDecoder.java b/src/org/traccar/protocol/CguardProtocolDecoder.java
new file mode 100644
index 000000000..1646363e5
--- /dev/null
+++ b/src/org/traccar/protocol/CguardProtocolDecoder.java
@@ -0,0 +1,91 @@
+/*
+ * 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.DeviceSession;
+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;
+
+import java.net.SocketAddress;
+import java.util.regex.Pattern;
+
+public class CguardProtocolDecoder extends BaseProtocolDecoder {
+
+ public CguardProtocolDecoder(CguardProtocol protocol) {
+ super(protocol);
+ }
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .text("NV:")
+ .number("(dd)(dd)(dd) ") // date
+ .number("(dd)(dd)(dd):") // time
+ .number("(-?d+.d+):") // longitude
+ .number("(-?d+.d+):") // latitude
+ .number("(d+.?d*):") // speed
+ .number("(?:NAN|(d+.?d*)):") // accuracy
+ .number("(?:NAN|(d+.?d*)):") // course
+ .number("(?:NAN|(d+.?d*))") // altitude
+ .compile();
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ String sentence = (String) msg;
+
+ if (sentence.startsWith("ID:") || sentence.startsWith("IDRO:")) {
+ getDeviceSession(channel, remoteAddress, sentence.substring(sentence.indexOf(':') + 1));
+ return null;
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Parser parser = new Parser(PATTERN, (String) msg);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt())
+ .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ position.setTime(dateBuilder.getDate());
+
+ position.setValid(true);
+ position.setLatitude(parser.nextDouble());
+ position.setLongitude(parser.nextDouble());
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble()));
+
+ position.set(Position.KEY_ACCURACY, parser.nextDouble());
+
+ position.setCourse(parser.nextDouble());
+ position.setAltitude(parser.nextDouble());
+
+ return position;
+ }
+
+}
diff --git a/src/org/traccar/protocol/OigoProtocolDecoder.java b/src/org/traccar/protocol/OigoProtocolDecoder.java
index 799f47ea3..bbea38183 100644
--- a/src/org/traccar/protocol/OigoProtocolDecoder.java
+++ b/src/org/traccar/protocol/OigoProtocolDecoder.java
@@ -54,7 +54,7 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder {
DeviceSession deviceSession;
switch (BitUtil.to(tag, 3)) {
case 0:
- String imei = ChannelBuffers.hexDump(buf.readBytes(9)).substring(1, 1 + 15);
+ String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1);
deviceSession = getDeviceSession(channel, remoteAddress, imei);
break;
case 1:
@@ -75,6 +75,8 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder {
position.setProtocol(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
+ position.set(Position.KEY_EVENT, buf.readUnsignedByte());
+
int mask = buf.readInt();
if (BitUtil.check(mask, 0)) {
diff --git a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java
index 26844994e..d6a29c6dd 100644
--- a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java
@@ -10,6 +10,21 @@ public class AplicomProtocolDecoderTest extends ProtocolTest {
AplicomProtocolDecoder decoder = new AplicomProtocolDecoder(new AplicomProtocol());
+ verifyAttributes(decoder, binary(
+ "45c20145931876ffb2007100ffff6d00000057c6dd1970230d087b1f7d7f0000d0c1000000003580000035801f40ffff5001574442393036363035533132333435363700014142432d333435202020202020000000000000000000000000000000000000000000000001123130343632343639373030303030303100000000"));
+
+ verifyAttributes(decoder, binary(
+ "45c20145931876ffb2007100ffff6d00000057c6dd9170250d087b1f7d7f0000d0c1000000003580000035801f40ffff5001574442393036363035533132333435363700014142432d333435202020202020000000000000000000000000000000000000000000000001123130343632343639373030303030303100000000"));
+
+ verifyAttributes(decoder, binary(
+ "45c20145931876ffb2007100ffff6d00000057c6de0970270d087b1f7d7f0000d0c1000000003580000035801f40ffff5001574442393036363035533132333435363700014142432d333435202020202020000000000000000000000000000000000000000000000001123130343632343639373030303030303100000000"));
+
+ verifyNothing(decoder, binary(
+ "48c10144b9de54e6b2008700205f710a57d23ec957d23b8d00000000300d0106ff00000000000000000000000000000000000000000000000000000000000000010a141e28323c46505a646e7801000f020104ff000000000000000000010102000f020104ff000000000000000000010103000f020104ff000000000000000000010105000f020104ff0000000000000000000101"));
+
+ verifyAttributes(decoder, binary(
+ "44c3014645e8ecff3c00ea03ffffbc00f457d68a6557d68a6303bb55fa018843da1100009881000000000000000000000000000000000000000000000000000000000000000000000000000000ff0056007600000000000000014542016d0001010095070e14014645e8ecff3c57d68a6403bb55fa018843dac0010d14ff050102030405060708090a0b0c0d0e0f10112a01010730343f3c1ff5cf01020700007d007d23010103022f2e01060c67452301efcdab8967452301010b10000000007d007d007d7dffffffffffff010a2400000000000000010000000000000000ffffffffffffffff00010001ffff00000000ffff010c02fec6"));
+
verifyPosition(decoder, binary(
"44c3014645e8e91b66002300a21f0b01f056d3e62856d3e626031f845f00c6ee440800000000000000000017bd1cb30000"));
@@ -19,7 +34,7 @@ public class AplicomProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, binary(
"44c3014645e8e91b66001f00221f0b01f456ba1e0d56ba1e0b031f842200c6ef550c000000000017bd1cb30004"));
- verifyNothing(decoder, binary(
+ verifyAttributes(decoder, binary(
"44c3014645e8e9bada003e03fff7070055a4f24200000081000000000000000000000000000000000000000000000000000000000000000000000000000000ff00000001000000000000000044c3014645e8e9bada003e03fff77bff55a4f24300000081000000000000000000000000000000000000000000000000000000000000000000000000000000ff00300002000000000000000044c3014645e8e9bada003e03fff7690655a4f24500000081000000000000000000000000000000000000000000000000000000000000000000000000000000ff003000030000000000000000"));
verifyPosition(decoder, binary(
diff --git a/test/org/traccar/protocol/CguardProtocolDecoderTest.java b/test/org/traccar/protocol/CguardProtocolDecoderTest.java
new file mode 100644
index 000000000..49d037f8f
--- /dev/null
+++ b/test/org/traccar/protocol/CguardProtocolDecoderTest.java
@@ -0,0 +1,54 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class CguardProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ CguardProtocolDecoder decoder = new CguardProtocolDecoder(new CguardProtocol());
+
+ verifyNothing(decoder, text(
+ "IDRO:354868050655283"));
+
+ verifyPosition(decoder, text(
+ "NV:160711 044023:54.342907:48.582590:0:NAN:0:110.1"));
+
+ verifyPosition(decoder, text(
+ "NV:160711 044023:54.342907:-148.582590:0:NAN:0:110.1"));
+
+ verifyNothing(decoder, text(
+ "BC:160711 044023:CSQ1:48:NSQ1:7:NSQ2:1:BAT1:98:PWR1:11.7:CLG1:NAN"));
+
+ verifyNothing(decoder, text(
+ "BC:160711 044524:CSQ1:61:NSQ1:18:BAT1:98:PWR1:11.7:CLG1:NAN"));
+
+ verifyNothing(decoder, text(
+ "VERSION:3.3"));
+
+ verifyPosition(decoder, text(
+ "NV:160420 101902:55.799425:37.674033:0.94:NAN:213.59:156.6"));
+
+ verifyNothing(decoder, text(
+ "BC:160628 081024:CSQ1:32:NSQ1:10:BAT1:100"));
+
+ verifyNothing(decoder, text(
+ "BC:160628 081033:NSQ2:0"));
+
+ verifyPosition(decoder, text(
+ "NV:160630 151537:55.799913:37.674267:0.7:NAN:10.21:174.9"));
+
+ verifyNothing(decoder, text(
+ "BC:160630 153316:BAT1:76"));
+
+ verifyNothing(decoder, text(
+ "BC:160630 153543:NSQ2:0"));
+
+ verifyNothing(decoder, text(
+ "PING"));
+
+ }
+
+}
diff --git a/test/org/traccar/protocol/OigoProtocolDecoderTest.java b/test/org/traccar/protocol/OigoProtocolDecoderTest.java
index b75f3162b..14c34ae7c 100644
--- a/test/org/traccar/protocol/OigoProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/OigoProtocolDecoderTest.java
@@ -16,6 +16,9 @@ public class OigoProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, binary(
"7e004200000014631000258257000000ffff02d1690e00051f690e00051f0696dbd204bdfde31a070000b307100f35c0106305f500000000010908010402200104ffff8001"));
+ verifyPosition(decoder, binary(
+ "7e004200000014631000258257000000ffff0d82691300001669130000160696dbd804bdfdbb1a0800000007101035a2106905f500000000010908010402200104ffff8001"));
+
}
}