aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--schema/changelog-3.3.xml3
-rw-r--r--schema/changelog-3.5.xml9
-rw-r--r--schema/changelog-3.6.xml9
-rw-r--r--src/org/traccar/database/GroupTree.java8
-rw-r--r--src/org/traccar/model/Command.java1
-rw-r--r--src/org/traccar/protocol/Gt06ProtocolDecoder.java165
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/Pt502Protocol.java8
-rw-r--r--src/org/traccar/protocol/Pt502ProtocolEncoder.java38
-rw-r--r--src/org/traccar/protocol/UlbotechProtocolDecoder.java21
-rw-r--r--src/org/traccar/protocol/V680Protocol.java10
-rw-r--r--test/org/traccar/protocol/CalAmpProtocolDecoderTest.java3
-rw-r--r--test/org/traccar/protocol/Gps103ProtocolDecoderTest.java3
-rw-r--r--test/org/traccar/protocol/Gt06ProtocolDecoderTest.java3
-rw-r--r--test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java7
-rw-r--r--test/org/traccar/protocol/Pt502ProtocolEncoderTest.java25
-rw-r--r--test/org/traccar/protocol/SuntechProtocolDecoderTest.java5
-rw-r--r--test/org/traccar/protocol/UlbotechProtocolDecoderTest.java3
18 files changed, 245 insertions, 82 deletions
diff --git a/schema/changelog-3.3.xml b/schema/changelog-3.3.xml
index 1893a0200..6ed8cecaa 100644
--- a/schema/changelog-3.3.xml
+++ b/schema/changelog-3.3.xml
@@ -3,7 +3,8 @@
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
- http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd"
+ logicalFilePath="changelog-3.3">
<changeSet author="author" id="changelog-3.3">
diff --git a/schema/changelog-3.5.xml b/schema/changelog-3.5.xml
index 63a3a3a92..934f389b2 100644
--- a/schema/changelog-3.5.xml
+++ b/schema/changelog-3.5.xml
@@ -3,10 +3,17 @@
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
- http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd"
+ logicalFilePath="changelog-3.5">
<changeSet author="author" id="changelog-3.5">
+ <preConditions onFail="MARK_RAN">
+ <not>
+ <tableExists tableName="groups" />
+ </not>
+ </preConditions>
+
<createTable tableName="groups">
<column name="id" type="INT" autoIncrement="true">
<constraints primaryKey="true" />
diff --git a/schema/changelog-3.6.xml b/schema/changelog-3.6.xml
index 3de7e2c0f..13d4cae60 100644
--- a/schema/changelog-3.6.xml
+++ b/schema/changelog-3.6.xml
@@ -3,10 +3,17 @@
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
- http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
+ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd"
+ logicalFilePath="changelog-3.6">
<changeSet author="author" id="changelog-3.6">
+ <preConditions onFail="MARK_RAN">
+ <not>
+ <tableExists tableName="events" />
+ </not>
+ </preConditions>
+
<createTable tableName="events">
<column name="id" type="INT" autoIncrement="true">
<constraints primaryKey="true" />
diff --git a/src/org/traccar/database/GroupTree.java b/src/org/traccar/database/GroupTree.java
index 4a2321f58..9062e7aa8 100644
--- a/src/org/traccar/database/GroupTree.java
+++ b/src/org/traccar/database/GroupTree.java
@@ -140,9 +140,11 @@ public class GroupTree {
}
private void getNodes(Set<TreeNode> results, TreeNode node) {
- for (TreeNode child : node.getChildren()) {
- results.add(child);
- getNodes(results, child);
+ if (node != null) {
+ for (TreeNode child : node.getChildren()) {
+ results.add(child);
+ getNodes(results, child);
+ }
}
}
diff --git a/src/org/traccar/model/Command.java b/src/org/traccar/model/Command.java
index 69172ecee..0a1a62216 100644
--- a/src/org/traccar/model/Command.java
+++ b/src/org/traccar/model/Command.java
@@ -36,6 +36,7 @@ public class Command extends Message {
public static final String TYPE_SILENCE_TIME = "silenceTime";
public static final String TYPE_SET_PHONEBOOK = "setPhonebook";
public static final String TYPE_VOICE_MESSAGE = "voiceMessage";
+ public static final String TYPE_OUTPUT_CONTROL = "outputControl";
public static final String TYPE_ALARM_GEOFENCE = "movementAlarm";
public static final String TYPE_ALARM_BATTERY = "alarmBattery";
diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java
index e9799c1b0..00444b61b 100644
--- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2015 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2012 - 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.
@@ -63,6 +63,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_COMMAND_0 = 0x80;
public static final int MSG_COMMAND_1 = 0x81;
public static final int MSG_COMMAND_2 = 0x82;
+ public static final int MSG_INFO = 0x94;
private static boolean isSupported(int type) {
return hasGps(type) || hasLbs(type) || hasStatus(type);
@@ -168,102 +169,132 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
ChannelBuffer buf = (ChannelBuffer) msg;
- if (buf.readByte() != 0x78 || buf.readByte() != 0x78) {
- return null;
- }
+ int header = buf.readShort();
+
+ if (header == 0x7878) {
- int length = buf.readUnsignedByte(); // size
- int dataLength = length - 5;
+ int length = buf.readUnsignedByte();
+ int dataLength = length - 5;
- int type = buf.readUnsignedByte();
+ int type = buf.readUnsignedByte();
- if (type == MSG_LOGIN) {
+ if (type == MSG_LOGIN) {
- String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1);
- buf.readUnsignedShort(); // type
+ String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1);
+ buf.readUnsignedShort(); // type
- // Timezone offset
- if (dataLength > 10) {
- int extensionBits = buf.readUnsignedShort();
- int hours = (extensionBits >> 4) / 100;
- int minutes = (extensionBits >> 4) % 100;
- int offset = (hours * 60 + minutes) * 60;
- if ((extensionBits & 0x8) != 0) {
- offset = -offset;
+ // Timezone offset
+ if (dataLength > 10) {
+ int extensionBits = buf.readUnsignedShort();
+ int hours = (extensionBits >> 4) / 100;
+ int minutes = (extensionBits >> 4) % 100;
+ int offset = (hours * 60 + minutes) * 60;
+ if ((extensionBits & 0x8) != 0) {
+ offset = -offset;
+ }
+ if (!forceTimeZone) {
+ timeZone.setRawOffset(offset * 1000);
+ }
}
- if (!forceTimeZone) {
- timeZone.setRawOffset(offset * 1000);
+
+ if (identify(imei, channel, remoteAddress)) {
+ buf.skipBytes(buf.readableBytes() - 6);
+ sendResponse(channel, type, buf.readUnsignedShort());
}
- }
- if (identify(imei, channel, remoteAddress)) {
- buf.skipBytes(buf.readableBytes() - 6);
- sendResponse(channel, type, buf.readUnsignedShort());
- }
+ } else if (hasDeviceId()) {
+
+ if (type == MSG_STRING) {
- } else if (hasDeviceId()) {
+ Position position = new Position();
+ position.setDeviceId(getDeviceId());
+ position.setProtocol(getProtocolName());
- if (type == MSG_STRING) {
+ getLastLocation(position, null);
- Position position = new Position();
- position.setDeviceId(getDeviceId());
- position.setProtocol(getProtocolName());
+ int commandLength = buf.readUnsignedByte();
- getLastLocation(position, null);
+ if (commandLength > 0) {
+ buf.readUnsignedByte(); // server flag (reserved)
+ position.set("command", buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII));
+ }
- int commandLength = buf.readUnsignedByte();
+ buf.readUnsignedShort(); // language
- if (commandLength > 0) {
- buf.readUnsignedByte(); // server flag (reserved)
- position.set("command", buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII));
- }
+ sendResponse(channel, type, buf.readUnsignedShort());
+
+ return position;
- buf.readUnsignedShort(); // language
+ } else if (isSupported(type)) {
- sendResponse(channel, type, buf.readUnsignedShort());
+ Position position = new Position();
+ position.setDeviceId(getDeviceId());
+ position.setProtocol(getProtocolName());
- return position;
+ if (hasGps(type)) {
+ decodeGps(position, buf);
+ } else {
+ getLastLocation(position, null);
+ }
- } else if (isSupported(type)) {
+ if (hasLbs(type)) {
+ decodeLbs(position, buf, hasStatus(type));
+ }
- Position position = new Position();
- position.setDeviceId(getDeviceId());
- position.setProtocol(getProtocolName());
+ if (hasStatus(type)) {
+ decodeStatus(position, buf);
+ }
+
+ if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) {
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedInt());
+ }
+
+ if (buf.readableBytes() > 6) {
+ buf.skipBytes(buf.readableBytes() - 6);
+ }
+ int index = buf.readUnsignedShort();
+ position.set(Position.KEY_INDEX, index);
+ sendResponse(channel, type, index);
+
+ return position;
- if (hasGps(type)) {
- decodeGps(position, buf);
} else {
- getLastLocation(position, null);
- }
- if (hasLbs(type)) {
- decodeLbs(position, buf, hasStatus(type));
- }
+ buf.skipBytes(dataLength);
+ if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) {
+ sendResponse(channel, type, buf.readUnsignedShort());
+ }
- if (hasStatus(type)) {
- decodeStatus(position, buf);
}
- if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) {
- position.set(Position.KEY_ODOMETER, buf.readUnsignedInt());
- }
+ }
- if (buf.readableBytes() > 6) {
- buf.skipBytes(buf.readableBytes() - 6);
- }
- int index = buf.readUnsignedShort();
- position.set(Position.KEY_INDEX, index);
- sendResponse(channel, type, index);
+ } else if (header == 0x7979) {
- return position;
+ int length = buf.readUnsignedShort();
+ int dataLength = length - 6;
- } else {
+ int type = buf.readUnsignedByte();
- buf.skipBytes(dataLength);
- if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) {
- sendResponse(channel, type, buf.readUnsignedShort());
- }
+ if (type == MSG_INFO) {
+ int subType = buf.readUnsignedByte();
+ if (subType == 0x05) {
+
+ Position position = new Position();
+ position.setDeviceId(getDeviceId());
+ position.setProtocol(getProtocolName());
+
+ getLastLocation(position, null);
+
+ int flags = buf.readUnsignedByte();
+
+ position.set("door", BitUtil.check(flags, 0));
+ position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2));
+
+ return position;
+
+ }
}
}
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index 48ee95c13..cdbf3850a 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2015 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2012 - 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.
@@ -284,10 +284,10 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextInt(16));
+ position.set(Position.KEY_ODOMETER, parser.nextLong(16));
}
if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextInt(16));
+ position.set(Position.KEY_ODOMETER, parser.nextLong(16));
}
if (parser.hasNext()) {
diff --git a/src/org/traccar/protocol/Pt502Protocol.java b/src/org/traccar/protocol/Pt502Protocol.java
index 165d53c2d..04c758b22 100644
--- a/src/org/traccar/protocol/Pt502Protocol.java
+++ b/src/org/traccar/protocol/Pt502Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2015 - 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.
@@ -18,8 +18,10 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
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 org.traccar.model.Command;
import java.nio.ByteOrder;
import java.util.List;
@@ -28,6 +30,8 @@ public class Pt502Protocol extends BaseProtocol {
public Pt502Protocol() {
super("pt502");
+ setSupportedCommands(
+ Command.TYPE_OUTPUT_CONTROL);
}
@Override
@@ -36,7 +40,9 @@ public class Pt502Protocol extends BaseProtocol {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new Pt502FrameDecoder());
+ pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("objectEncoder", new Pt502ProtocolEncoder());
pipeline.addLast("objectDecoder", new Pt502ProtocolDecoder(Pt502Protocol.this));
}
};
diff --git a/src/org/traccar/protocol/Pt502ProtocolEncoder.java b/src/org/traccar/protocol/Pt502ProtocolEncoder.java
new file mode 100644
index 000000000..86c6703d4
--- /dev/null
+++ b/src/org/traccar/protocol/Pt502ProtocolEncoder.java
@@ -0,0 +1,38 @@
+/*
+ * 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.traccar.StringProtocolEncoder;
+import org.traccar.helper.Log;
+import org.traccar.model.Command;
+
+public class Pt502ProtocolEncoder extends StringProtocolEncoder {
+
+ @Override
+ protected Object encodeCommand(Command command) {
+
+ switch (command.getType()) {
+ case Command.TYPE_OUTPUT_CONTROL:
+ return formatCommand(command, "000000OPC{%s},{%s}", Command.KEY_INDEX, Command.KEY_DATA);
+ default:
+ Log.warning(new UnsupportedOperationException(command.getType()));
+ break;
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/org/traccar/protocol/UlbotechProtocolDecoder.java
index 9cbaadfb4..2fd7d8f74 100644
--- a/src/org/traccar/protocol/UlbotechProtocolDecoder.java
+++ b/src/org/traccar/protocol/UlbotechProtocolDecoder.java
@@ -65,6 +65,25 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder {
}
}
+ private void decodeJ1708(Position position, ChannelBuffer buf, short length) {
+
+ int end = buf.readerIndex() + length;
+
+ while (buf.readerIndex() < end) {
+ int mark = buf.readUnsignedByte();
+ int len = BitUtil.between(mark, 0, 6);
+ int type = BitUtil.between(mark, 6, 8);
+ int id = buf.readUnsignedByte();
+ if (type == 3) {
+ id += 256;
+ }
+ String value = ChannelBuffers.hexDump(buf.readBytes(len - 1));
+ if (type == 2 || type == 3) {
+ position.set("pid" + id, value);
+ }
+ }
+ }
+
private void decodeDriverBehavior(Position position, ChannelBuffer buf) {
int value = buf.readUnsignedByte();
@@ -200,7 +219,7 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder {
break;
case DATA_J1708:
- position.set("j1708", ChannelBuffers.hexDump(buf.readBytes(length)));
+ decodeJ1708(position, buf, length);
break;
case DATA_VIN:
diff --git a/src/org/traccar/protocol/V680Protocol.java b/src/org/traccar/protocol/V680Protocol.java
index a89f77edd..d2ceb207b 100644
--- a/src/org/traccar/protocol/V680Protocol.java
+++ b/src/org/traccar/protocol/V680Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2015 - 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.
@@ -15,6 +15,7 @@
*/
package org.traccar.protocol;
+import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.string.StringDecoder;
@@ -40,6 +41,13 @@ public class V680Protocol extends BaseProtocol {
pipeline.addLast("objectDecoder", new V680ProtocolDecoder(V680Protocol.this));
}
});
+ serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("objectDecoder", new V680ProtocolDecoder(V680Protocol.this));
+ }
+ });
}
}
diff --git a/test/org/traccar/protocol/CalAmpProtocolDecoderTest.java b/test/org/traccar/protocol/CalAmpProtocolDecoderTest.java
index 247454de3..238e6df3f 100644
--- a/test/org/traccar/protocol/CalAmpProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/CalAmpProtocolDecoderTest.java
@@ -9,6 +9,9 @@ public class CalAmpProtocolDecoderTest extends ProtocolTest {
public void testDecode() throws Exception {
CalAmpProtocolDecoder decoder = new CalAmpProtocolDecoder(new CalAmpProtocol());
+
+ verifyPosition(decoder, binary(
+ "83052132052924010101020001575c590300000000000000000000000000000000000000000000002c0000ff8f0000030801010000"));
verifyPosition(decoder, binary(
"830543321494860101010a0080560b5a5e0eadd0291becf3c500f005090f1f3305000003010040c0a600000000000000008b12a102"));
diff --git a/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java b/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java
index aecbe2ef1..eb71b3034 100644
--- a/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/Gps103ProtocolDecoderTest.java
@@ -11,6 +11,9 @@ public class Gps103ProtocolDecoderTest extends ProtocolTest {
Gps103ProtocolDecoder decoder = new Gps103ProtocolDecoder(new Gps103Protocol());
verifyAttributes(decoder, text(
+ "imei:359710049042014,001,160615040011,,F,040011.000,A,2833.0957,N,07711.9465,E,0.01,215.33,,0,,,,;"));
+
+ verifyAttributes(decoder, text(
"imei:359710049028435,OBD,160316053657,70430,,,0,49,60.00%,46,19.22%,859,0.00,U1108,,,;"));
verifyPosition(decoder, text(
diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java
index 46ee223ad..81f9f81c3 100644
--- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java
@@ -16,6 +16,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest {
verifyNothing(decoder, binary(
"78780D01086471700328358100093F040D0A"));
+ verifyAttributes(decoder, binary(
+ "7979000794050000c9b63e0d0a"));
+
verifyNotNull(decoder, binary(
"787866150000000000416c726561647920696e20746865207374617465206f66206675656c20737570706c7920746f20726573756d652c74686520636f6d6d616e64206973206e6f742072756e6e696e672100000000000000000000000000000000000001001981e50d0a"));
diff --git a/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java b/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java
index dd497858b..76f62d0f5 100644
--- a/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java
@@ -11,6 +11,9 @@ public class MeiligaoProtocolDecoderTest extends ProtocolTest {
MeiligaoProtocolDecoder decoder = new MeiligaoProtocolDecoder(new MeiligaoProtocol());
verifyPosition(decoder, binary(
+ "242400746251103044ffff99553033353033392e3939392c412c323832332e373632312c4e2c31303635322e303730342c572c3030302e302c3030302e302c3136303631362c2c2c412a37357c302e397c323038332e327c303030307c303030302c303030307c31303034333736333265780d0a"));
+
+ verifyPosition(decoder, binary(
"24240072190820157fffff99553039343335342e3030302c412c313930372e303631392c4e2c30373235312e333235312c452c3031302e312c3138382e352c3234303231362c2c2c412a36427c302e387c36352e327c303830307c303030302c303030307c303336343838373532c73f0d0a"));
verifyPosition(decoder, binary(
@@ -78,8 +81,8 @@ public class MeiligaoProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, binary(
"242400001007ffffffffff99553136323330392e3035342c562c303933312e393136332c4e2c30363931312e383233332c572c2c2c3235313131332c2c2c4e2a36437c7c3135387c303030309cc60d0a"));
- //verifyPosition(decoder, binary(
- // "242400003563070435652099553035323034322e3030302c412c343435382e333536352c4e2c30343130342e343831332c452c302e30302c302e30302c3139303131342c2c2a39437c302e3730303030307c2d3835393131373337367c303130307c307c7c7c4f2a0d0a"));
+ verifyAttributes(decoder, binary(
+ "242400003563070435652099553035323034322e3030302c412c343435382e333536352c4e2c30343130342e343831332c452c302e30302c302e30302c3139303131342c2c2a39437c302e3730303030307c2d3835393131373337367c303130307c307c7c7c4f2a0d0a"));
verifyPosition(decoder, binary(
"2424005035784251ffffff99553030303033362e3938312c562c303933312e333437312c4e2c30363931312e383431322c572c2c2c3238303131342c2c2c4e2a36357c7c3136387c323030305e420d0a"));
diff --git a/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java b/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java
new file mode 100644
index 000000000..889323ae0
--- /dev/null
+++ b/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java
@@ -0,0 +1,25 @@
+package org.traccar.protocol;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+import org.traccar.model.Command;
+
+public class Pt502ProtocolEncoderTest extends ProtocolTest {
+
+ @Test
+ public void testEncode() throws Exception {
+
+ Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder();
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_OUTPUT_CONTROL);
+ command.set(Command.KEY_INDEX, 2);
+ command.set(Command.KEY_DATA, 1);
+
+ Assert.assertEquals("000000OPC2,1", encoder.encodeCommand(command));
+
+ }
+
+}
diff --git a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java
index 41d09bad8..e64041d29 100644
--- a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java
@@ -9,7 +9,10 @@ public class SuntechProtocolDecoderTest extends ProtocolTest {
public void testDecode() throws Exception {
SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol());
-
+
+ verifyPosition(decoder, text(
+ "ST300ALT;205174410;14;712;20110101;00:00:07;00000;+20.593923;-100.336716;000.000;000.00;0;0;0;16.57;000000;81;000000;4.0;0;0.00;0000;0000;0;0"));
+
verifyNothing(decoder, text(
"SA200ALV;317652"));
diff --git a/test/org/traccar/protocol/UlbotechProtocolDecoderTest.java b/test/org/traccar/protocol/UlbotechProtocolDecoderTest.java
index 5036c4a40..cb4e43c38 100644
--- a/test/org/traccar/protocol/UlbotechProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/UlbotechProtocolDecoderTest.java
@@ -10,6 +10,9 @@ public class UlbotechProtocolDecoderTest extends ProtocolTest {
UlbotechProtocolDecoder decoder = new UlbotechProtocolDecoder(new UlbotechProtocol());
+ verifyPosition(decoder, binary(
+ "F8010103596580420045259CFB3329010E015ED91506BDE5A800000000009E030402420000040400492AA405060344197E220D071131058F410C1591310D48312F8F413107C60804027666B00C138254D182607A826EE083BE554385F50019423CAD1DF8"));
+
verifyNotNull(decoder, binary(
"F8010108683230231070781EA3676E020BFFFFFFFFFFFFFFFFFFFF780304000000030404000002C20506032A1790220E100101AC72F8"));