aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/org/traccar/api/resource/CommandResource.java10
-rw-r--r--src/org/traccar/database/CommandsManager.java65
-rw-r--r--src/org/traccar/database/ConnectionManager.java5
-rw-r--r--src/org/traccar/model/Command.java7
-rw-r--r--src/org/traccar/protocol/CradlepointProtocolDecoder.java26
-rw-r--r--src/org/traccar/protocol/MegastekProtocolDecoder.java8
-rw-r--r--src/org/traccar/protocol/MeitrackProtocolDecoder.java16
-rw-r--r--src/org/traccar/protocol/T55ProtocolDecoder.java10
-rw-r--r--src/org/traccar/protocol/TaipProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TzoneProtocolDecoder.java11
-rw-r--r--swagger.json14
-rw-r--r--test/org/traccar/protocol/CradlepointProtocolDecoderTest.java12
-rw-r--r--test/org/traccar/protocol/MegastekFrameDecoderTest.java6
-rw-r--r--test/org/traccar/protocol/MegastekProtocolDecoderTest.java6
-rw-r--r--test/org/traccar/protocol/MeitrackProtocolDecoderTest.java3
-rw-r--r--test/org/traccar/protocol/TaipProtocolDecoderTest.java6
-rw-r--r--test/org/traccar/protocol/TzoneProtocolDecoderTest.java3
-rw-r--r--test/org/traccar/protocol/WatchFrameDecoderTest.java5
18 files changed, 147 insertions, 69 deletions
diff --git a/src/org/traccar/api/resource/CommandResource.java b/src/org/traccar/api/resource/CommandResource.java
index 8da9f8447..703638701 100644
--- a/src/org/traccar/api/resource/CommandResource.java
+++ b/src/org/traccar/api/resource/CommandResource.java
@@ -62,15 +62,15 @@ public class CommandResource extends ExtendedObjectResource<Command> {
Context.getPermissionsManager().checkReadonly(getUserId());
long deviceId = entity.getDeviceId();
long id = entity.getId();
- if (deviceId != 0 && id != 0) {
+ Context.getPermissionsManager().checkDevice(getUserId(), deviceId);
+ if (id != 0) {
Context.getPermissionsManager().checkPermission(Command.class, getUserId(), id);
- Context.getPermissionsManager().checkDevice(getUserId(), deviceId);
Context.getPermissionsManager().checkUserDeviceCommand(getUserId(), deviceId, id);
- Context.getCommandsManager().sendCommand(id, deviceId);
} else {
Context.getPermissionsManager().checkLimitCommands(getUserId());
- Context.getPermissionsManager().checkDevice(getUserId(), deviceId);
- Context.getCommandsManager().sendCommand(entity);
+ }
+ if (!Context.getCommandsManager().sendCommand(entity)) {
+ return Response.accepted(entity).build();
}
return Response.ok(entity).build();
}
diff --git a/src/org/traccar/database/CommandsManager.java b/src/org/traccar/database/CommandsManager.java
index 521a2e1d1..9ceb995ef 100644
--- a/src/org/traccar/database/CommandsManager.java
+++ b/src/org/traccar/database/CommandsManager.java
@@ -21,6 +21,10 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
import org.traccar.BaseProtocol;
import org.traccar.Context;
@@ -31,26 +35,22 @@ import org.traccar.model.Position;
public class CommandsManager extends ExtendedObjectManager<Command> {
- private boolean fallbackToText;
+ private final Map<Long, Queue<Command>> deviceQueues = new ConcurrentHashMap<>();
public CommandsManager(DataManager dataManager) {
super(dataManager, Command.class);
- fallbackToText = Context.getConfig().getBoolean("command.fallbackToSms");
}
public boolean checkDeviceCommand(long deviceId, long commandId) {
return !getAllDeviceItems(deviceId).contains(commandId);
}
- public void sendCommand(Command command) throws Exception {
- sendCommand(command, command.getDeviceId(), fallbackToText);
- }
-
- public void sendCommand(long commandId, long deviceId) throws Exception {
- sendCommand(getById(commandId), deviceId, false);
- }
-
- public void sendCommand(Command command, long deviceId, boolean fallbackToText) throws Exception {
+ public boolean sendCommand(Command command) throws Exception {
+ long deviceId = command.getDeviceId();
+ if (command.getId() != 0) {
+ command = getById(command.getId()).clone();
+ command.setDeviceId(deviceId);
+ }
if (command.getTextChannel()) {
Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId);
String phone = Context.getIdentityManager().getById(deviceId).getPhone();
@@ -71,32 +71,27 @@ public class CommandsManager extends ExtendedObjectManager<Command> {
if (activeDevice != null) {
activeDevice.sendCommand(command);
} else {
- if (fallbackToText) {
- command.setTextChannel(true);
- sendCommand(command, deviceId, false);
- } else {
- throw new RuntimeException("Device is not online");
- }
+ getDeviceQueue(deviceId).add(command);
+ return false;
}
}
+ return true;
}
public Collection<Long> getSupportedCommands(long deviceId) {
List<Long> result = new ArrayList<>();
Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId);
- boolean online = Context.getConnectionManager().getActiveDevice(deviceId) != null;
for (long commandId : getAllDeviceItems(deviceId)) {
Command command = getById(commandId);
- if (command.getTextChannel() || online) {
- if (lastPosition != null) {
- BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol());
- if (protocol.getSupportedTextCommands().contains(command.getType())
- || online && protocol.getSupportedDataCommands().contains(command.getType())) {
- result.add(commandId);
- }
- } else if (command.getType().equals(Command.TYPE_CUSTOM)) {
+ if (lastPosition != null) {
+ BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol());
+ if (command.getTextChannel() && protocol.getSupportedTextCommands().contains(command.getType())
+ || !command.getTextChannel()
+ && protocol.getSupportedDataCommands().contains(command.getType())) {
result.add(commandId);
}
+ } else if (command.getType().equals(Command.TYPE_CUSTOM)) {
+ result.add(commandId);
}
}
return result;
@@ -133,4 +128,22 @@ public class CommandsManager extends ExtendedObjectManager<Command> {
return result;
}
+ private Queue<Command> getDeviceQueue(long deviceId) {
+ if (!deviceQueues.containsKey(deviceId)) {
+ deviceQueues.put(deviceId, new ConcurrentLinkedQueue<Command>());
+ }
+ return deviceQueues.get(deviceId);
+ }
+
+ public void sendQueuedCommands(ActiveDevice activeDevice) {
+ Queue<Command> deviceQueue = deviceQueues.get(activeDevice.getDeviceId());
+ if (deviceQueue != null) {
+ Command command = deviceQueue.poll();
+ while (command != null) {
+ activeDevice.sendCommand(command);
+ command = deviceQueue.poll();
+ }
+ }
+ }
+
}
diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java
index de11db21b..e5a7a272f 100644
--- a/src/org/traccar/database/ConnectionManager.java
+++ b/src/org/traccar/database/ConnectionManager.java
@@ -57,7 +57,9 @@ public class ConnectionManager {
}
public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) {
- activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress));
+ ActiveDevice activeDevice = new ActiveDevice(deviceId, protocol, channel, remoteAddress);
+ activeDevices.put(deviceId, activeDevice);
+ Context.getCommandsManager().sendQueuedCommands(activeDevice);
}
public void removeActiveDevice(Channel channel) {
@@ -122,6 +124,7 @@ public class ConnectionManager {
public void run(Timeout timeout) throws Exception {
if (!timeout.isCancelled()) {
updateDevice(deviceId, Device.STATUS_UNKNOWN, null);
+ activeDevices.remove(deviceId);
}
}
}, deviceTimeout, TimeUnit.MILLISECONDS));
diff --git a/src/org/traccar/model/Command.java b/src/org/traccar/model/Command.java
index 67134dc7d..16205ede1 100644
--- a/src/org/traccar/model/Command.java
+++ b/src/org/traccar/model/Command.java
@@ -20,7 +20,7 @@ import org.traccar.database.QueryIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
-public class Command extends Message {
+public class Command extends Message implements Cloneable {
public static final String TYPE_CUSTOM = "custom";
public static final String TYPE_IDENTIFICATION = "deviceIdentification";
@@ -77,6 +77,11 @@ public class Command extends Message {
public static final String KEY_SERVER = "server";
public static final String KEY_PORT = "port";
+ @Override
+ public Command clone() throws CloneNotSupportedException {
+ return (Command) super.clone();
+ }
+
private boolean textChannel;
public boolean getTextChannel() {
diff --git a/src/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/org/traccar/protocol/CradlepointProtocolDecoder.java
index 67a140cf7..e8f95a60c 100644
--- a/src/org/traccar/protocol/CradlepointProtocolDecoder.java
+++ b/src/org/traccar/protocol/CradlepointProtocolDecoder.java
@@ -18,11 +18,13 @@ 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.model.Position;
import java.net.SocketAddress;
+import java.util.Date;
import java.util.regex.Pattern;
public class CradlepointProtocolDecoder extends BaseProtocolDecoder {
@@ -33,7 +35,7 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder {
private static final Pattern PATTERN = new PatternBuilder()
.expression("([^,]+),") // id
- .number("(dd)(dd)(dd),") // time (hhmmss)
+ .number("(d{1,6}),") // time (hhmmss)
.number("(d+)(dd.d+),") // latitude
.expression("([NS]),")
.number("(d+)(dd.d+),") // longitude
@@ -58,16 +60,21 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
-
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
return null;
}
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS));
+ int time = parser.nextInt();
+ DateBuilder dateBuilder = new DateBuilder(new Date());
+ dateBuilder.setHour(time / 100 / 100);
+ dateBuilder.setMinute(time / 100 % 100);
+ dateBuilder.setSecond(time % 100);
+ position.setTime(dateBuilder.getDate());
position.setValid(true);
position.setLatitude(parser.nextCoordinate());
@@ -75,9 +82,12 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder {
position.setSpeed(parser.nextDouble(0));
position.setCourse(parser.nextDouble(0));
- parser.skip(3);
-
- position.set(Position.KEY_RSSI, parser.nextDouble());
+ position.set("carrid", parser.next());
+ position.set("serdis", parser.next());
+ position.set("rsrp", parser.next());
+ position.set("dbm", parser.next());
+ position.set("rsrq", parser.next());
+ position.set("ecio", parser.next());
return position;
}
diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java
index 994e2d983..3ef52acd1 100644
--- a/src/org/traccar/protocol/MegastekProtocolDecoder.java
+++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java
@@ -267,7 +267,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
.or().text(" ")
.groupEnd("?").text(",")
.number("(d+)?,") // rfid
- .number("d*,")
+ .expression("[^,]*,")
.number("(d+)?,") // battery
.expression("([^,]*);") // alert
.any()
@@ -280,13 +280,13 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
-
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
return null;
}
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (parser.next().equals("S")) {
diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
index 4714e24ea..a74d5ca62 100644
--- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
@@ -20,6 +20,7 @@ import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.Context;
import org.traccar.DeviceSession;
+import org.traccar.helper.Checksum;
import org.traccar.helper.Parser;
import org.traccar.helper.PatternBuilder;
import org.traccar.helper.UnitsConverter;
@@ -218,13 +219,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
if (parser.hasNext()) {
for (String temp : parser.next().split("\\|")) {
- int index = Integer.valueOf(temp.substring(0, 2), 16);
+ int index = Integer.parseInt(temp.substring(0, 2), 16);
if (protocol >= 3) {
- double value = Short.valueOf(temp.substring(2), 16);
+ double value = (short) Integer.parseInt(temp.substring(2), 16);
position.set(Position.PREFIX_TEMP + index, value * 0.01);
} else {
- double value = Byte.valueOf(temp.substring(2, 4), 16);
- value += (value < 0 ? -0.01 : 0.01) * Integer.valueOf(temp.substring(4), 16);
+ double value = Byte.parseByte(temp.substring(2, 4), 16);
+ value += (value < 0 ? -0.01 : 0.01) * Integer.parseInt(temp.substring(4), 16);
position.set(Position.PREFIX_TEMP + index, value);
}
}
@@ -313,7 +314,6 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
ChannelBuffer buf = (ChannelBuffer) msg;
- // Find type
int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ',');
index = buf.indexOf(index + 1, buf.writerIndex(), (byte) ',');
@@ -323,7 +323,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
if (channel != null) {
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
String imei = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId();
- channel.write("@@O46," + imei + ",D00,camera_picture.jpg,0*00\r\n");
+ String content = "D00,camera_picture.jpg,0";
+ int length = 1 + imei.length() + 1 + content.length() + 5;
+ String response = String.format("@@O%02d,%s,%s*", length, imei, content);
+ response += Checksum.sum(response) + "\r\n";
+ channel.write(response);
}
return null;
case "CCC":
diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java
index 43e1a57f7..6b4ee6ebd 100644
--- a/src/org/traccar/protocol/T55ProtocolDecoder.java
+++ b/src/org/traccar/protocol/T55ProtocolDecoder.java
@@ -31,11 +31,8 @@ import java.util.regex.Pattern;
public class T55ProtocolDecoder extends BaseProtocolDecoder {
- private final boolean ack;
-
public T55ProtocolDecoder(T55Protocol protocol) {
super(protocol);
- ack = Context.getConfig().getBoolean(getProtocolName() + ".ack");
}
private static final Pattern PATTERN_GPRMC = new PatternBuilder()
@@ -102,8 +99,11 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
private Position decodeGprmc(
DeviceSession deviceSession, String sentence, SocketAddress remoteAddress, Channel channel) {
- if (ack && channel != null && !(channel instanceof DatagramChannel)) {
- channel.write("OK1\r\n");
+ if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel)) {
+ if (Context.getIdentityManager().lookupAttributeBoolean(
+ deviceSession.getDeviceId(), getProtocolName() + ".ack", false, true)) {
+ channel.write("OK1\r\n");
+ }
}
Parser parser = new Parser(PATTERN_GPRMC, sentence);
diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java
index c6220ab1d..e7117a5c9 100644
--- a/src/org/traccar/protocol/TaipProtocolDecoder.java
+++ b/src/org/traccar/protocol/TaipProtocolDecoder.java
@@ -68,7 +68,6 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder {
.number("(x{8})") // odometer
.number("[01]") // gps power
.groupEnd("?")
- .number("(d)") // fix mode
.any()
.compile();
@@ -162,7 +161,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0));
}
- position.setValid(parser.nextInt(0) != 0);
+ position.setValid(true);
String[] attributes = null;
beginIndex = sentence.indexOf(';');
diff --git a/src/org/traccar/protocol/TzoneProtocolDecoder.java b/src/org/traccar/protocol/TzoneProtocolDecoder.java
index 76903c90c..079ad3126 100644
--- a/src/org/traccar/protocol/TzoneProtocolDecoder.java
+++ b/src/org/traccar/protocol/TzoneProtocolDecoder.java
@@ -203,7 +203,16 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder {
if (blockLength >= 13) {
position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte()));
position.set("terminalInfo", buf.readUnsignedByte());
- position.set(Position.PREFIX_IO + 1, buf.readUnsignedShort());
+
+ int status = buf.readUnsignedByte();
+ position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 0));
+ position.set(Position.PREFIX_OUT + 2, BitUtil.check(status, 1));
+ status = buf.readUnsignedByte();
+ position.set(Position.PREFIX_IN + 1, BitUtil.check(status, 4));
+ if (BitUtil.check(status, 0)) {
+ position.set(Position.KEY_ALARM, Position.ALARM_SOS);
+ }
+
position.set(Position.KEY_RSSI, buf.readUnsignedByte());
position.set("gsmStatus", buf.readUnsignedByte());
position.set(Position.KEY_BATTERY, buf.readUnsignedShort());
diff --git a/swagger.json b/swagger.json
index 120544798..82f34ac1d 100644
--- a/swagger.json
+++ b/swagger.json
@@ -108,11 +108,11 @@
"/commands/send": {
"get": {
"summary": "Fetch a list of Saved Commands supported by Device at the moment",
- "description": "Return a list of saved commands linked to Device and its groups, filtered by current Device state and protocol support",
+ "description": "Return a list of saved commands linked to Device and its groups, filtered by current Device protocol support",
"parameters": [
{
"$ref": "#/parameters/deviceId"
- },
+ }
],
"responses": {
"200": {
@@ -144,13 +144,19 @@
],
"responses": {
"200": {
- "description": "OK",
+ "description": "Command sent",
+ "schema": {
+ "$ref": "#/definitions/Command"
+ }
+ },
+ "202": {
+ "description": "Command queued",
"schema": {
"$ref": "#/definitions/Command"
}
},
"400": {
- "description": "Could happen when dispatching to a device that is offline, the user doesn't have permission or an incorrect command _type_ for the device"
+ "description": "Could happen when the user doesn't have permission or an incorrect command _type_ for the device"
}
}
}
diff --git a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java
index 7eae791d5..757298682 100644
--- a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java
@@ -11,6 +11,18 @@ public class CradlepointProtocolDecoderTest extends ProtocolTest {
CradlepointProtocolDecoder decoder = new CradlepointProtocolDecoder(new CradlepointProtocol());
verifyPosition(decoder, text(
+ "356526070063940,0,4337.19009,N,11612.34705,W,0.0,277.2,AT&T,,,-79,,-14.0,"));
+
+ verifyPosition(decoder, text(
+ "356526070063940,1,4337.19008,N,11612.34705,W,0.0,277.2,AT&T,,,-79,,-14.0,"));
+
+ verifyPosition(decoder, text(
+ "+14063964266,162658,4333.62404,N,11636.23469,W,0.0,,Verizon Wireless,LTE,-107,-74,-16,,100.68.169.178"));
+
+ verifyPosition(decoder, text(
+ "+12084014675,162658,4337.174385,N,11612.338373,W,0.0,,Verizon,,-71,-44,-11,,"));
+
+ verifyPosition(decoder, text(
"353547063544681,170515,3613.25,N,11559.14,W,0.0,,,,,,,,"));
verifyPosition(decoder, text(
diff --git a/test/org/traccar/protocol/MegastekFrameDecoderTest.java b/test/org/traccar/protocol/MegastekFrameDecoderTest.java
index c2a8f4ecd..9a327bb1f 100644
--- a/test/org/traccar/protocol/MegastekFrameDecoderTest.java
+++ b/test/org/traccar/protocol/MegastekFrameDecoderTest.java
@@ -11,15 +11,15 @@ public class MegastekFrameDecoderTest extends ProtocolTest {
MegastekFrameDecoder decoder = new MegastekFrameDecoder();
- Assert.assertEquals(
+ verifyFrame(
binary("30313337244d47563030322c3335343535303035303239323636392c4756543930302c522c3134313231352c3033313830342c412c2c532c2c452c30302c30332c30302c332e36372c302e3030302c302e30302c3131372e312c302e302c3531302c31302c2c2c2c303030302c303030302c32322c31322c302c202c202c2c312d312c39382c5057204f4e3b21"),
decoder.decode(null, null, binary("30313337244d47563030322c3335343535303035303239323636392c4756543930302c522c3134313231352c3033313830342c412c2c532c2c452c30302c30332c30302c332e36372c302e3030302c302e30302c3131372e312c302e302c3531302c31302c2c2c2c303030302c303030302c32322c31322c302c202c202c2c312d312c39382c5057204f4e3b21")));
- Assert.assertEquals(
+ verifyFrame(
binary("244d47563030322c3031333737373030373533363433342c2c522c3031303131342c3030303035372c562c303030302e303030302c4e2c30303030302e303030302c452c30302c30302c30302c39392e392c302e3030302c302e30302c302e302c38302e3236332c3531302c38392c323334322c303330422c2c303030302c303030302c3230302c39362c302c202c202c2c2c2c54696d65723b21"),
decoder.decode(null, null, binary("244d47563030322c3031333737373030373533363433342c2c522c3031303131342c3030303035372c562c303030302e303030302c4e2c30303030302e303030302c452c30302c30302c30302c39392e392c302e3030302c302e30302c302e302c38302e3236332c3531302c38392c323334322c303330422c2c303030302c303030302c3230302c39362c302c202c202c2c2c2c54696d65723b210d0a")));
- Assert.assertEquals(
+ verifyFrame(
binary("53545832363034373520202020202020202020024f244750524d432c3133313131302e30302c562c2c2c2c2c2c2c3036303931332c2c2c4e2a37362c3232322c30312c383135412c443435352c31312c39372c303030302c303030312c302c54696d65723b3735"),
decoder.decode(null, null, binary("53545832363034373520202020202020202020024f244750524d432c3133313131302e30302c562c2c2c2c2c2c2c3036303931332c2c2c4e2a37362c3232322c30312c383135412c443435352c31312c39372c303030302c303030312c302c54696d65723b37350d0a")));
diff --git a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java
index 106baff98..9bb705f17 100644
--- a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java
@@ -11,6 +11,12 @@ public class MegastekProtocolDecoderTest extends ProtocolTest {
MegastekProtocolDecoder decoder = new MegastekProtocolDecoder(new MegastekProtocol());
verifyNull(decoder, text(
+ "0112$MGV002,,GVT900-3,S,010114,000003,,,,,,00,00,00,,0.000,0.00,,0.0,,,,,,0000,0000,14,10,0, , ,,1-0,0,Low Ext Vol;!"));
+
+ verifyPosition(decoder, text(
+ "0170$MGV002,354550056642321,GVT900-3,S,011017,090208,A,1635.8484,N,10446.6095,E,00,09,00,0.91,16.980,257.73,177.6,0.0,457,01,0741,00C0,21,0000,0000,20,10,0, , ,,1-1,54,Dist;!"));
+
+ verifyNull(decoder, text(
"0140$MGV002,354550056642321,GVT900-3,S,300917,071731,V,,,,,00,00,00,99.9,0.000,0.00,,0.0,457,01,0741,00CD,,0000,0000,20,10,0, , ,,1-1,94,PW ON;!"));
verifyPosition(decoder, text(
diff --git a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java
index 07411dbc8..34b2ad579 100644
--- a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java
@@ -12,6 +12,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest {
MeitrackProtocolDecoder decoder = new MeitrackProtocolDecoder(new MeitrackProtocol());
verifyPosition(decoder, buffer(
+ "$$V177,863835026871173,AAA,35,34.516428,10.470160,170915154043,A,9,12,68,74,0.9,9,1988259,525882,605|2|008C|0007B5A6,0200,0003|0000|0000|01A6|0571,00000001,,3,0000,06FB2E,360,511*74"));
+
+ verifyPosition(decoder, buffer(
"$$V177,863835026871173,AAA,35,34.516428,10.470160,170915154043,A,9,12,68,74,0.9,9,1988259,525882,605|2|008C|0007B5A6,0200,0003|0000|0000|01A6|0571,00000001,,3,0000,010A92,360,511*74"));
verifyPosition(decoder, buffer(
diff --git a/test/org/traccar/protocol/TaipProtocolDecoderTest.java b/test/org/traccar/protocol/TaipProtocolDecoderTest.java
index e2de26ec0..beba54d74 100644
--- a/test/org/traccar/protocol/TaipProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/TaipProtocolDecoderTest.java
@@ -11,6 +11,12 @@ public class TaipProtocolDecoderTest extends ProtocolTest {
TaipProtocolDecoder decoder = new TaipProtocolDecoder(new TaipProtocol());
verifyPosition(decoder, text(
+ ">RPV46640+4197412-0752857900015802;ID=5102;*71<"));
+
+ verifyNull(decoder, text(
+ ">RCP46640+419741-075285802;ID=5102;*6C<"));
+
+ verifyPosition(decoder, text(
">REV001958003965+0307178+1016144900031532;IO=300;SV=8;BL=4159;CF=8161,C,13;AD=14145;IX=10233040;FF=0,0,0,0;VO=338578;ID=357042063052352<"));
verifyPosition(decoder, text(
diff --git a/test/org/traccar/protocol/TzoneProtocolDecoderTest.java b/test/org/traccar/protocol/TzoneProtocolDecoderTest.java
index aa8f61772..68c8bbdbc 100644
--- a/test/org/traccar/protocol/TzoneProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/TzoneProtocolDecoderTest.java
@@ -12,6 +12,9 @@ public class TzoneProtocolDecoderTest extends ProtocolTest {
TzoneProtocolDecoder decoder = new TzoneProtocolDecoder(new TzoneProtocol());
verifyPosition(decoder, binary(
+ "545a005624240111010e0000086169303626931411091b151d2600160801de26ec002f633411091b151d2500000000160c0000040d2a34df000eaa4000001b37016000000000319c0000000000000000000000000000003a84240d0a"));
+
+ verifyPosition(decoder, binary(
"545a005024240153011000000863835025559464110103080a22001609011bed79245964a9110103080a22000a0000550c00000604396f04222c000daac000151701a204870000000000000003000959000546190d0a"));
verifyPosition(decoder, binary(
diff --git a/test/org/traccar/protocol/WatchFrameDecoderTest.java b/test/org/traccar/protocol/WatchFrameDecoderTest.java
index c705b24b3..664501a43 100644
--- a/test/org/traccar/protocol/WatchFrameDecoderTest.java
+++ b/test/org/traccar/protocol/WatchFrameDecoderTest.java
@@ -1,6 +1,5 @@
package org.traccar.protocol;
-import org.junit.Assert;
import org.junit.Test;
import org.traccar.ProtocolTest;
@@ -11,11 +10,11 @@ public class WatchFrameDecoderTest extends ProtocolTest {
WatchFrameDecoder decoder = new WatchFrameDecoder();
- Assert.assertEquals(
+ verifyFrame(
binary("5b33472a383330383430363237392a303030382a72636170747572655d"),
decoder.decode(null, null, binary("5b33472a383330383430363237392a303030382a72636170747572655d")));
- Assert.assertEquals(
+ verifyFrame(
binary("5b33472a383330383430363237392a303030392a4c4b2c302c302c38345d"),
decoder.decode(null, null, binary("5b33472a383330383430363237392a303030392a4c4b2c302c302c38345d")));