aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavriel Fleischer <flocsy@gmail.com>2019-11-11 00:20:13 +0200
committerGavriel Fleischer <flocsy@gmail.com>2019-11-11 00:20:13 +0200
commit8a696af4d92821ccf741c21dcbe118861008743a (patch)
tree74cd5697a87603c4b17ca84206cea9fc34d91f9f
parent47a1af1554b0216eae8248227407486c0eba8ef3 (diff)
parent81a7195b2efe148d47e3cf0cead0de415529bbab (diff)
downloadtraccar-server-8a696af4d92821ccf741c21dcbe118861008743a.tar.gz
traccar-server-8a696af4d92821ccf741c21dcbe118861008743a.tar.bz2
traccar-server-8a696af4d92821ccf741c21dcbe118861008743a.zip
Merge branch 'master' into set-language
# Conflicts: # src/main/java/org/traccar/StringProtocolEncoder.java # src/main/java/org/traccar/protocol/WatchProtocolEncoder.java
-rw-r--r--setup/default.xml2
-rw-r--r--src/main/java/org/traccar/StringProtocolEncoder.java38
-rw-r--r--src/main/java/org/traccar/protocol/AdmProtocolEncoder.java2
-rw-r--r--src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java4
-rw-r--r--src/main/java/org/traccar/protocol/EsealProtocolEncoder.java6
-rw-r--r--src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java10
-rw-r--r--src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java18
-rw-r--r--src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java2
-rw-r--r--src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java2
-rw-r--r--src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java6
-rw-r--r--src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java22
-rw-r--r--src/main/java/org/traccar/protocol/OutsafeProtocol.java39
-rw-r--r--src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java69
-rw-r--r--src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java8
-rw-r--r--src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java16
-rw-r--r--src/main/java/org/traccar/protocol/SviasProtocolEncoder.java4
-rw-r--r--src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java30
-rw-r--r--src/main/java/org/traccar/protocol/TopinProtocol.java33
-rw-r--r--src/main/java/org/traccar/protocol/TopinProtocolDecoder.java136
-rw-r--r--src/main/java/org/traccar/protocol/TotemProtocolEncoder.java4
-rw-r--r--src/main/java/org/traccar/protocol/WatchProtocolEncoder.java24
-rw-r--r--src/main/java/org/traccar/protocol/WialonProtocolEncoder.java4
-rw-r--r--src/main/java/org/traccar/protocol/WondexProtocolEncoder.java12
-rw-r--r--src/main/java/org/traccar/protocol/XexunProtocolEncoder.java4
-rw-r--r--src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java19
-rw-r--r--src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java38
-rw-r--r--src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java24
27 files changed, 446 insertions, 130 deletions
diff --git a/setup/default.xml b/setup/default.xml
index 1452137c3..f1f3ab517 100644
--- a/setup/default.xml
+++ b/setup/default.xml
@@ -275,5 +275,7 @@
<entry key='rst.port'>5196</entry>
<entry key='pt215.port'>5197</entry>
<entry key='pacifictrack.port'>5198</entry>
+ <entry key='topin.port'>5199</entry>
+ <entry key='outsafe.port'>5200</entry>
</properties>
diff --git a/src/main/java/org/traccar/StringProtocolEncoder.java b/src/main/java/org/traccar/StringProtocolEncoder.java
index 7041a31ab..40dfb25b6 100644
--- a/src/main/java/org/traccar/StringProtocolEncoder.java
+++ b/src/main/java/org/traccar/StringProtocolEncoder.java
@@ -17,11 +17,6 @@ package org.traccar;
import org.traccar.model.Command;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
public abstract class StringProtocolEncoder extends BaseProtocolEncoder {
public StringProtocolEncoder(Protocol protocol) {
@@ -34,26 +29,27 @@ public abstract class StringProtocolEncoder extends BaseProtocolEncoder {
protected String formatCommand(Command command, String format, ValueFormatter valueFormatter, String... keys) {
- String result = String.format(format, (Object[]) keys);
-
- Set<String> missingKeys = new HashSet<>(Arrays.asList(keys));
- result = result.replaceAll("\\{" + Command.KEY_UNIQUE_ID + "}", getUniqueId(command.getDeviceId()));
- for (Map.Entry<String, Object> entry : command.getAttributes().entrySet()) {
+ Object[] values = new String[keys.length];
+ for (int i = 0; i < keys.length; i++) {
String value = null;
- if (valueFormatter != null) {
- value = valueFormatter.formatValue(entry.getKey(), entry.getValue());
+ if (keys[i].equals(Command.KEY_UNIQUE_ID)) {
+ value = getUniqueId(command.getDeviceId());
+ } else {
+ Object object = command.getAttributes().get(keys[i]);
+ if (valueFormatter != null) {
+ value = valueFormatter.formatValue(keys[i], object);
+ }
+ if (value == null) {
+ value = object.toString();
+ }
+ if (value == null) {
+ value = "";
+ }
}
- if (value == null) {
- value = entry.getValue().toString();
- }
- result = result.replaceAll("\\{" + entry.getKey() + "}", value);
- missingKeys.remove(entry.getKey());
- }
- for (String key : missingKeys) {
- result = result.replaceAll("\\{" + key + "}", "");
+ values[i] = value;
}
- return result;
+ return String.format(format, values);
}
protected String formatCommand(Command command, String format, String... keys) {
diff --git a/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java b/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java
index 1c3dfc156..c02fa4112 100644
--- a/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java
@@ -34,7 +34,7 @@ public class AdmProtocolEncoder extends StringProtocolEncoder {
return formatCommand(command, "STATUS\r\n");
case Command.TYPE_CUSTOM:
- return formatCommand(command, "{%s}\r\n", Command.KEY_DATA);
+ return formatCommand(command, "%s\r\n", Command.KEY_DATA);
default:
return null;
diff --git a/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java b/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java
index 083fe9a9e..78dbe7e91 100644
--- a/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java
@@ -30,9 +30,9 @@ public class CarcellProtocolEncoder extends StringProtocolEncoder {
switch (command.getType()) {
case Command.TYPE_ENGINE_STOP:
- return formatCommand(command, "$SRVCMD,{%s},BA#\r\n", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "$SRVCMD,%s,BA#\r\n", Command.KEY_UNIQUE_ID);
case Command.TYPE_ENGINE_RESUME:
- return formatCommand(command, "$SRVCMD,{%s},BD#\r\n", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "$SRVCMD,%s,BD#\r\n", Command.KEY_UNIQUE_ID);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java b/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java
index 6ee305ed8..74f9e22ab 100644
--- a/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java
@@ -31,13 +31,13 @@ public class EsealProtocolEncoder extends StringProtocolEncoder {
switch (command.getType()) {
case Command.TYPE_CUSTOM:
return formatCommand(
- command, "##S,eSeal,{%s},256,3.0.8,{%s},E##", Command.KEY_UNIQUE_ID, Command.KEY_DATA);
+ command, "##S,eSeal,%s,256,3.0.8,%s,E##", Command.KEY_UNIQUE_ID, Command.KEY_DATA);
case Command.TYPE_ALARM_ARM:
return formatCommand(
- command, "##S,eSeal,{%s},256,3.0.8,RC-Power Control,Power OFF,E##", Command.KEY_UNIQUE_ID);
+ command, "##S,eSeal,%s,256,3.0.8,RC-Power Control,Power OFF,E##", Command.KEY_UNIQUE_ID);
case Command.TYPE_ALARM_DISARM:
return formatCommand(
- command, "##S,eSeal,{%s},256,3.0.8,RC-Unlock,E##", Command.KEY_UNIQUE_ID);
+ command, "##S,eSeal,%s,256,3.0.8,RC-Unlock,E##", Command.KEY_UNIQUE_ID);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java
index 32307446b..dd0672c23 100644
--- a/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java
@@ -32,17 +32,17 @@ public class Gl200ProtocolEncoder extends StringProtocolEncoder {
switch (command.getType()) {
case Command.TYPE_POSITION_SINGLE:
- return formatCommand(command, "AT+GTRTO={%s},1,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "AT+GTRTO=%s,1,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_ENGINE_STOP:
- return formatCommand(command, "AT+GTOUT={%s},1,,,0,0,0,0,0,0,0,,,,,,,FFFF$",
+ return formatCommand(command, "AT+GTOUT=%s,1,,,0,0,0,0,0,0,0,,,,,,,FFFF$",
Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_ENGINE_RESUME:
- return formatCommand(command, "AT+GTOUT={%s},0,,,0,0,0,0,0,0,0,,,,,,,FFFF$",
+ return formatCommand(command, "AT+GTOUT=%s,0,,,0,0,0,0,0,0,0,,,,,,,FFFF$",
Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_IDENTIFICATION:
- return formatCommand(command, "AT+GTRTO={%s},8,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "AT+GTRTO=%s,8,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_REBOOT_DEVICE:
- return formatCommand(command, "AT+GTRTO={%s},3,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "AT+GTRTO=%s,3,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java
index 7128823ed..e662e9b04 100644
--- a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java
@@ -47,24 +47,24 @@ public class Gps103ProtocolEncoder extends StringProtocolEncoder implements Stri
switch (command.getType()) {
case Command.TYPE_CUSTOM:
- return formatCommand(command, "**,imei:{%s},{%s}", Command.KEY_UNIQUE_ID, Command.KEY_DATA);
+ return formatCommand(command, "**,imei:%s,%s", Command.KEY_UNIQUE_ID, Command.KEY_DATA);
case Command.TYPE_POSITION_STOP:
- return formatCommand(command, "**,imei:{%s},A", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "**,imei:%s,A", Command.KEY_UNIQUE_ID);
case Command.TYPE_POSITION_SINGLE:
- return formatCommand(command, "**,imei:{%s},B", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "**,imei:%s,B", Command.KEY_UNIQUE_ID);
case Command.TYPE_POSITION_PERIODIC:
return formatCommand(
- command, "**,imei:{%s},C,{%s}", this, Command.KEY_UNIQUE_ID, Command.KEY_FREQUENCY);
+ command, "**,imei:%s,C,%s", this, Command.KEY_UNIQUE_ID, Command.KEY_FREQUENCY);
case Command.TYPE_ENGINE_STOP:
- return formatCommand(command, "**,imei:{%s},J", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "**,imei:%s,J", Command.KEY_UNIQUE_ID);
case Command.TYPE_ENGINE_RESUME:
- return formatCommand(command, "**,imei:{%s},K", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "**,imei:%s,K", Command.KEY_UNIQUE_ID);
case Command.TYPE_ALARM_ARM:
- return formatCommand(command, "**,imei:{%s},L", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "**,imei:%s,L", Command.KEY_UNIQUE_ID);
case Command.TYPE_ALARM_DISARM:
- return formatCommand(command, "**,imei:{%s},M", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "**,imei:%s,M", Command.KEY_UNIQUE_ID);
case Command.TYPE_REQUEST_PHOTO:
- return formatCommand(command, "**,imei:{%s},160", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "**,imei:%s,160", Command.KEY_UNIQUE_ID);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java b/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java
index 7dd4b2d77..be0ab5130 100644
--- a/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java
+++ b/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java
@@ -32,7 +32,7 @@ public class GranitProtocolSmsEncoder extends StringProtocolEncoder {
case Command.TYPE_REBOOT_DEVICE:
return "BB+RESET";
case Command.TYPE_POSITION_PERIODIC:
- return formatCommand(command, "BB+BBMD={%s}", Command.KEY_FREQUENCY);
+ return formatCommand(command, "BB+BBMD=%s", Command.KEY_FREQUENCY);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java
index 07da70bf7..6711fe0fd 100644
--- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java
@@ -209,7 +209,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
sendResponse(channel, false, MSG_X1_PHOTO_DATA, 0, content);
}
- private boolean decodeGps(Position position, ByteBuf buf, boolean hasLength, TimeZone timezone) {
+ public static boolean decodeGps(Position position, ByteBuf buf, boolean hasLength, TimeZone timezone) {
DateBuilder dateBuilder = new DateBuilder(timezone)
.setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java
index 343ac9431..0c9f8ebb8 100644
--- a/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java
@@ -40,13 +40,13 @@ public class LaipacProtocolEncoder extends StringProtocolEncoder {
switch (command.getType()) {
case Command.TYPE_CUSTOM:
- return formatCommand(command, "{%s}",
+ return formatCommand(command, "%s",
Command.KEY_DATA);
case Command.TYPE_POSITION_SINGLE:
- return formatCommand(command, "AVREQ,{%s},1",
+ return formatCommand(command, "AVREQ,%s,1",
Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_REBOOT_DEVICE:
- return formatCommand(command, "AVRESET,{%s},{%s}",
+ return formatCommand(command, "AVRESET,%s,%s",
Command.KEY_UNIQUE_ID, Command.KEY_DEVICE_PASSWORD);
default:
return null;
diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java
index 36fb9fc2f..059f688f7 100644
--- a/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java
@@ -57,28 +57,28 @@ public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements
switch (command.getType()) {
case Command.TYPE_SET_TIMEZONE:
- return formatCommand(command, "{%s}L{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_TIMEZONE);
+ return formatCommand(command, "%sL%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_TIMEZONE);
case Command.TYPE_VOICE_MONITORING:
- return formatCommand(command, "{%s}P{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
+ return formatCommand(command, "%sP%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
case Command.TYPE_ALARM_SPEED:
- return formatCommand(command, "{%s}J1{%s}", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA);
+ return formatCommand(command, "%sJ1%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA);
case Command.TYPE_ALARM_GEOFENCE:
- return formatCommand(command, "{%s}R1{%s}", Command.KEY_DEVICE_PASSWORD, Command.KEY_RADIUS);
+ return formatCommand(command, "%sR1%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_RADIUS);
case Command.TYPE_ALARM_VIBRATION:
- return formatCommand(command, "{%s}W1,{%s}", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA);
+ return formatCommand(command, "%sW1,%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA);
case Command.TYPE_SET_AGPS:
- return formatCommand(command, "{%s}AGPS{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
+ return formatCommand(command, "%sAGPS%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
case Command.TYPE_ALARM_FALL:
- return formatCommand(command, "{%s}F{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
+ return formatCommand(command, "%sF%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
case Command.TYPE_MODE_POWER_SAVING:
- return formatCommand(command, "{%s}SP{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
+ return formatCommand(command, "%sSP%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
case Command.TYPE_MODE_DEEP_SLEEP:
- return formatCommand(command, "{%s}DS{%s}", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
+ return formatCommand(command, "%sDS%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE);
case Command.TYPE_SOS_NUMBER:
- return formatCommand(command, "{%s}{%s}1,{%s}", this,
+ return formatCommand(command, "%s%s1,%s", this,
Command.KEY_DEVICE_PASSWORD, Command.KEY_INDEX, Command.KEY_PHONE);
case Command.TYPE_SET_INDICATOR:
- return formatCommand(command, "{%s}LED{%s}", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA);
+ return formatCommand(command, "%sLED%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocol.java b/src/main/java/org/traccar/protocol/OutsafeProtocol.java
new file mode 100644
index 000000000..ece433e3f
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/OutsafeProtocol.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * 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 io.netty.handler.codec.http.HttpObjectAggregator;
+import io.netty.handler.codec.http.HttpRequestDecoder;
+import io.netty.handler.codec.http.HttpResponseEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class OutsafeProtocol extends BaseProtocol {
+
+ public OutsafeProtocol() {
+ addServer(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new HttpResponseEncoder());
+ pipeline.addLast(new HttpRequestDecoder());
+ pipeline.addLast(new HttpObjectAggregator(65535));
+ pipeline.addLast(new SigfoxProtocolDecoder(OutsafeProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java
new file mode 100644
index 000000000..5e95270e8
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * 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 io.netty.channel.Channel;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.HttpResponseStatus;
+import org.traccar.BaseHttpProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.Protocol;
+import org.traccar.model.Position;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import java.io.StringReader;
+import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+
+public class OutsafeProtocolDecoder extends BaseHttpProtocolDecoder {
+
+ public OutsafeProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ FullHttpRequest request = (FullHttpRequest) msg;
+ String content = request.content().toString(StandardCharsets.UTF_8);
+ JsonObject json = Json.createReader(new StringReader(content)).readObject();
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("device"));
+ if (deviceSession == null) {
+ sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setTime(new Date());
+ position.setValid(true);
+ position.setLatitude(json.getJsonNumber("latitude").doubleValue());
+ position.setLongitude(json.getJsonNumber("longitude").doubleValue());
+ position.setAltitude(json.getJsonNumber("altitude").doubleValue());
+ position.setCourse(json.getJsonNumber("heading").intValue());
+
+ position.set(Position.KEY_RSSI, json.getJsonNumber("rssi").intValue());
+
+ sendResponse(channel, HttpResponseStatus.OK);
+ return position;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java
index ba08b16ae..364ecae86 100644
--- a/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java
@@ -46,13 +46,13 @@ public class Pt502ProtocolEncoder extends StringProtocolEncoder implements Strin
switch (command.getType()) {
case Command.TYPE_CUSTOM:
- return formatCommand(command, "{%s}\r\n", Command.KEY_DATA);
+ return formatCommand(command, "%s\r\n", Command.KEY_DATA);
case Command.TYPE_OUTPUT_CONTROL:
- return formatCommand(command, "#OPC{%s},{%s}\r\n", Command.KEY_INDEX, Command.KEY_DATA);
+ return formatCommand(command, "#OPC%s,%s\r\n", Command.KEY_INDEX, Command.KEY_DATA);
case Command.TYPE_SET_TIMEZONE:
- return formatCommand(command, "#TMZ{%s}\r\n", Command.KEY_TIMEZONE);
+ return formatCommand(command, "#TMZ%s\r\n", Command.KEY_TIMEZONE);
case Command.TYPE_ALARM_SPEED:
- return formatCommand(command, "#SPD{%s}\r\n", Command.KEY_DATA);
+ return formatCommand(command, "#SPD%s\r\n", Command.KEY_DATA);
case Command.TYPE_REQUEST_PHOTO:
return formatCommand(command, "#PHO\r\n");
default:
diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java
index 6dae42ad5..55f2c73dd 100644
--- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java
@@ -30,27 +30,27 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder {
switch (command.getType()) {
case Command.TYPE_REBOOT_DEVICE:
- return formatCommand(command, "SA200CMD;{%s};02;Reboot\r", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "SA200CMD;%s;02;Reboot\r", Command.KEY_UNIQUE_ID);
case Command.TYPE_POSITION_SINGLE:
- return formatCommand(command, "SA200GTR;{%s};02;\r", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "SA200GTR;%s;02;\r", Command.KEY_UNIQUE_ID);
case Command.TYPE_OUTPUT_CONTROL:
if (command.getAttributes().containsKey(Command.KEY_DATA)) {
if (command.getAttributes().get(Command.KEY_DATA).equals("1")) {
- return formatCommand(command, "SA200CMD;{%s};02;Enable{%s}\r",
+ return formatCommand(command, "SA200CMD;%s;02;Enable%s\r",
Command.KEY_UNIQUE_ID, Command.KEY_INDEX);
} else {
- return formatCommand(command, "SA200CMD;{%s};02;Disable{%s}\r",
+ return formatCommand(command, "SA200CMD;%s;02;Disable%s\r",
Command.KEY_UNIQUE_ID, Command.KEY_INDEX);
}
}
case Command.TYPE_ENGINE_STOP:
- return formatCommand(command, "SA200CMD;{%s};02;Enable1\r", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "SA200CMD;%s;02;Enable1\r", Command.KEY_UNIQUE_ID);
case Command.TYPE_ENGINE_RESUME:
- return formatCommand(command, "SA200CMD;{%s};02;Disable1\r", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "SA200CMD;%s;02;Disable1\r", Command.KEY_UNIQUE_ID);
case Command.TYPE_ALARM_ARM:
- return formatCommand(command, "SA200CMD;{%s};02;Enable2\r", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "SA200CMD;%s;02;Enable2\r", Command.KEY_UNIQUE_ID);
case Command.TYPE_ALARM_DISARM:
- return formatCommand(command, "SA200CMD;{%s};02;Disable2\r", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "SA200CMD;%s;02;Disable2\r", Command.KEY_UNIQUE_ID);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java b/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java
index 2607d7bd1..d218f63ce 100644
--- a/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java
@@ -30,11 +30,11 @@ public class SviasProtocolEncoder extends StringProtocolEncoder {
protected Object encodeCommand(Command command) {
switch (command.getType()) {
case Command.TYPE_CUSTOM:
- return formatCommand(command, "{%s}", Command.KEY_DATA);
+ return formatCommand(command, "%s", Command.KEY_DATA);
case Command.TYPE_POSITION_SINGLE:
return formatCommand(command, "AT+STR=1*");
case Command.TYPE_SET_ODOMETER:
- return formatCommand(command, "AT+ODT={%s}*", Command.KEY_DATA);
+ return formatCommand(command, "AT+ODT=%s*", Command.KEY_DATA);
case Command.TYPE_ENGINE_STOP:
return formatCommand(command, "AT+OUT=1,1*");
case Command.TYPE_ENGINE_RESUME:
diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java
index a8aa84105..5d7e63920 100644
--- a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java
@@ -50,7 +50,7 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder {
if (alternative) {
switch (command.getType()) {
case Command.TYPE_CUSTOM:
- return formatAlt(command, "{%s}", Command.KEY_DATA);
+ return formatAlt(command, "%s", Command.KEY_DATA);
case Command.TYPE_GET_VERSION:
return formatAlt(command, "*about*");
case Command.TYPE_POWER_OFF:
@@ -74,36 +74,36 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder {
case Command.TYPE_ALARM_SOS:
return formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*soson*" : "*sosoff*");
case Command.TYPE_SET_CONNECTION:
- return formatAlt(command, "*setip*%s*{%s}*",
- command.getString(Command.KEY_SERVER).replace(".", "*"), Command.KEY_PORT);
+ String server = command.getString(Command.KEY_SERVER).replace(".", "*");
+ return formatAlt(command, "*setip*" + server + "*%s*", Command.KEY_PORT);
case Command.TYPE_SOS_NUMBER:
- return formatAlt(command, "*master*{%s}*{%s}*", Command.KEY_DEVICE_PASSWORD, Command.KEY_PHONE);
+ return formatAlt(command, "*master*%s*%s*", Command.KEY_DEVICE_PASSWORD, Command.KEY_PHONE);
default:
return null;
}
} else {
switch (command.getType()) {
case Command.TYPE_CUSTOM:
- return formatCommand(command, "({%s}{%s})", Command.KEY_UNIQUE_ID, Command.KEY_DATA);
+ return formatCommand(command, "(%s%s)", Command.KEY_UNIQUE_ID, Command.KEY_DATA);
case Command.TYPE_GET_VERSION:
- return formatCommand(command, "({%s}AP07)", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "(%sAP07)", Command.KEY_UNIQUE_ID);
case Command.TYPE_REBOOT_DEVICE:
- return formatCommand(command, "({%s}AT00)", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "(%sAT00)", Command.KEY_UNIQUE_ID);
case Command.TYPE_SET_ODOMETER:
- return formatCommand(command, "({%s}AX01)", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "(%sAX01)", Command.KEY_UNIQUE_ID);
case Command.TYPE_POSITION_SINGLE:
- return formatCommand(command, "({%s}AP00)", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "(%sAP00)", Command.KEY_UNIQUE_ID);
case Command.TYPE_POSITION_PERIODIC:
- return formatCommand(command, "({%s}AR00%s0000)", Command.KEY_UNIQUE_ID,
- String.format("%04X", command.getInteger(Command.KEY_FREQUENCY)));
+ String frequency = String.format("%04X", command.getInteger(Command.KEY_FREQUENCY));
+ return formatCommand(command, "(%sAR00" + frequency + "0000)", Command.KEY_UNIQUE_ID);
case Command.TYPE_POSITION_STOP:
- return formatCommand(command, "({%s}AR0000000000)", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "(%sAR0000000000)", Command.KEY_UNIQUE_ID);
case Command.TYPE_ENGINE_STOP:
- return formatCommand(command, "({%s}AV010)", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "(%sAV010)", Command.KEY_UNIQUE_ID);
case Command.TYPE_ENGINE_RESUME:
- return formatCommand(command, "({%s}AV011)", Command.KEY_UNIQUE_ID);
+ return formatCommand(command, "(%sAV011)", Command.KEY_UNIQUE_ID);
case Command.TYPE_OUTPUT_CONTROL:
- return formatCommand(command, "({%s}AV00{%s})", Command.KEY_UNIQUE_ID, Command.KEY_DATA);
+ return formatCommand(command, "(%sAV00%s)", Command.KEY_UNIQUE_ID, Command.KEY_DATA);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/TopinProtocol.java b/src/main/java/org/traccar/protocol/TopinProtocol.java
new file mode 100644
index 000000000..844dd7518
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/TopinProtocol.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * 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.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class TopinProtocol extends BaseProtocol {
+
+ public TopinProtocol() {
+ addServer(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new TopinProtocolDecoder(TopinProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java
new file mode 100644
index 000000000..9393fbca9
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/TopinProtocolDecoder.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * 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 io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.NetworkMessage;
+import org.traccar.Protocol;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.util.TimeZone;
+
+public class TopinProtocolDecoder extends BaseProtocolDecoder {
+
+ public TopinProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ public static final int MSG_LOGIN = 0x01;
+ public static final int MSG_GPS = 0x10;
+ public static final int MSG_GPS_OFFLINE = 0x11;
+ public static final int MSG_STATUS = 0x13;
+
+ private void sendResponse(Channel channel, ByteBuf content) {
+ if (channel != null) {
+ ByteBuf response = Unpooled.buffer();
+ response.writeShort(0x7878);
+ response.writeBytes(content);
+ response.writeByte('\r');
+ response.writeByte('\n');
+ channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress()));
+ }
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ByteBuf buf = (ByteBuf) msg;
+
+ buf.skipBytes(2); // header
+ int length = buf.readUnsignedByte();
+
+ int type = buf.readUnsignedByte();
+
+ DeviceSession deviceSession;
+ if (type == MSG_LOGIN) {
+ String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1);
+ deviceSession = getDeviceSession(channel, remoteAddress, imei);
+ ByteBuf content = Unpooled.buffer();
+ content.writeByte(type);
+ content.writeByte(deviceSession != null ? 0x01 : 0x44);
+ sendResponse(channel, content);
+ return null;
+ } else {
+ deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
+ }
+
+ if (type == MSG_GPS || type == MSG_GPS_OFFLINE) {
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ ByteBuf time = buf.slice(buf.readerIndex(), 6);
+
+ Gt06ProtocolDecoder.decodeGps(position, buf, false, TimeZone.getTimeZone("UTC"));
+
+ ByteBuf content = Unpooled.buffer();
+ content.writeByte(0);
+ content.writeByte(type);
+ content.writeBytes(time);
+ sendResponse(channel, content);
+
+ return position;
+
+ } else if (type == MSG_STATUS) {
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ getLastLocation(position, null);
+
+ int battery = buf.readUnsignedByte();
+ int firmware = buf.readUnsignedByte();
+ int timezone = buf.readUnsignedByte();
+ int interval = buf.readUnsignedByte();
+ int signal = 0;
+ if (length >= 7) {
+ signal = buf.readUnsignedByte();
+ position.set(Position.KEY_RSSI, signal);
+ }
+
+ position.set(Position.KEY_BATTERY_LEVEL, battery);
+ position.set(Position.KEY_VERSION_FW, firmware);
+
+ ByteBuf content = Unpooled.buffer();
+ content.writeByte(length);
+ content.writeByte(type);
+ content.writeByte(battery);
+ content.writeByte(firmware);
+ content.writeByte(timezone);
+ content.writeByte(interval);
+ if (length >= 7) {
+ content.writeByte(signal);
+ }
+ sendResponse(channel, content);
+
+ return position;
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java
index 3bbb92031..a96dd1ee3 100644
--- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java
@@ -34,9 +34,9 @@ public class TotemProtocolEncoder extends StringProtocolEncoder {
switch (command.getType()) {
// Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8
case Command.TYPE_ENGINE_STOP:
- return formatCommand(command, "*{%s},025,C,1#", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "*%s,025,C,1#", Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_ENGINE_RESUME:
- return formatCommand(command, "*{%s},025,C,0#", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "*%s,025,C,0#", Command.KEY_DEVICE_PASSWORD);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java
index 1c535e9de..f285267ba 100644
--- a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java
@@ -47,8 +47,6 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin
return DataConverter.printHex(value.toString().getBytes(StandardCharsets.UTF_16BE));
} else if (key.equals(Command.KEY_ENABLE)) {
return (boolean) value ? "1" : "0";
- } else if (key.equals(Command.KEY_LANGUAGE)) {
- return String.valueOf(value);
}
return null;
@@ -139,33 +137,33 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin
case Command.TYPE_POSITION_SINGLE:
return formatTextCommand(channel, command, "RG");
case Command.TYPE_SOS_NUMBER:
- return formatTextCommand(channel, command, "SOS{%s},{%s}", Command.KEY_INDEX, Command.KEY_PHONE);
+ return formatTextCommand(channel, command, "SOS%s,%s", Command.KEY_INDEX, Command.KEY_PHONE);
case Command.TYPE_ALARM_SOS:
- return formatTextCommand(channel, command, "SOSSMS,{%s}", Command.KEY_ENABLE);
+ return formatTextCommand(channel, command, "SOSSMS,%s", Command.KEY_ENABLE);
case Command.TYPE_ALARM_BATTERY:
- return formatTextCommand(channel, command, "LOWBAT,{%s}", Command.KEY_ENABLE);
+ return formatTextCommand(channel, command, "LOWBAT,%s", Command.KEY_ENABLE);
case Command.TYPE_REBOOT_DEVICE:
return formatTextCommand(channel, command, "RESET");
case Command.TYPE_POWER_OFF:
return formatTextCommand(channel, command, "POWEROFF");
case Command.TYPE_ALARM_REMOVE:
- return formatTextCommand(channel, command, "REMOVE,{%s}", Command.KEY_ENABLE);
+ return formatTextCommand(channel, command, "REMOVE,%s", Command.KEY_ENABLE);
case Command.TYPE_SILENCE_TIME:
- return formatTextCommand(channel, command, "SILENCETIME,{%s}", Command.KEY_DATA);
+ return formatTextCommand(channel, command, "SILENCETIME,%s", Command.KEY_DATA);
case Command.TYPE_ALARM_CLOCK:
- return formatTextCommand(channel, command, "REMIND,{%s}", Command.KEY_DATA);
+ return formatTextCommand(channel, command, "REMIND,%s", Command.KEY_DATA);
case Command.TYPE_SET_PHONEBOOK:
- return formatTextCommand(channel, command, "PHB,{%s}", Command.KEY_DATA);
+ return formatTextCommand(channel, command, "PHB,%s", Command.KEY_DATA);
case Command.TYPE_MESSAGE:
- return formatTextCommand(channel, command, "MESSAGE,{%s}", Command.KEY_MESSAGE);
+ return formatTextCommand(channel, command, "MESSAGE,%s", Command.KEY_MESSAGE);
case Command.TYPE_VOICE_MESSAGE:
return formatBinaryCommand(channel, command, "TK,", getBinaryData(command));
case Command.TYPE_POSITION_PERIODIC:
- return formatTextCommand(channel, command, "UPLOAD,{%s}", Command.KEY_FREQUENCY);
+ return formatTextCommand(channel, command, "UPLOAD,%s", Command.KEY_FREQUENCY);
case Command.TYPE_SET_TIMEZONE:
- return formatTextCommand(channel, command, "LZ,{%s},{%s}", Command.KEY_LANGUAGE, Command.KEY_TIMEZONE);
+ return formatTextCommand(channel, command, "LZ,%s,%s", Command.KEY_LANGUAGE, Command.KEY_TIMEZONE);
case Command.TYPE_SET_INDICATOR:
- return formatTextCommand(channel, command, "FLOWER,{%s}", Command.KEY_DATA);
+ return formatTextCommand(channel, command, "FLOWER,%s", Command.KEY_DATA);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java b/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java
index c45edf00d..93086bf8a 100644
--- a/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java
@@ -32,11 +32,11 @@ public class WialonProtocolEncoder extends StringProtocolEncoder {
case Command.TYPE_REBOOT_DEVICE:
return formatCommand(command, "reboot\r\n");
case Command.TYPE_SEND_USSD:
- return formatCommand(command, "USSD:{%s}\r\n", Command.KEY_PHONE);
+ return formatCommand(command, "USSD:%s\r\n", Command.KEY_PHONE);
case Command.TYPE_IDENTIFICATION:
return formatCommand(command, "VER?\r\n");
case Command.TYPE_OUTPUT_CONTROL:
- return formatCommand(command, "L{%s}={%s}\r\n", Command.KEY_INDEX, Command.KEY_DATA);
+ return formatCommand(command, "L%s=%s\r\n", Command.KEY_INDEX, Command.KEY_DATA);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java
index e9bb23d15..21f1ee321 100644
--- a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java
@@ -32,17 +32,17 @@ public class WondexProtocolEncoder extends StringProtocolEncoder {
switch (command.getType()) {
case Command.TYPE_REBOOT_DEVICE:
- return formatCommand(command, "$WP+REBOOT={%s}", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "$WP+REBOOT=%s", Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_GET_DEVICE_STATUS:
- return formatCommand(command, "$WP+TEST={%s}", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "$WP+TEST=%s", Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_GET_MODEM_STATUS:
- return formatCommand(command, "$WP+GSMINFO={%s}", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "$WP+GSMINFO=%s", Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_IDENTIFICATION:
- return formatCommand(command, "$WP+IMEI={%s}", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "$WP+IMEI=%s", Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_POSITION_SINGLE:
- return formatCommand(command, "$WP+GETLOCATION={%s}", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "$WP+GETLOCATION=%s", Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_GET_VERSION:
- return formatCommand(command, "$WP+VER={%s}", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "$WP+VER=%s", Command.KEY_DEVICE_PASSWORD);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java b/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java
index fc849fe15..4f2707c2a 100644
--- a/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java
@@ -32,9 +32,9 @@ public class XexunProtocolEncoder extends StringProtocolEncoder {
switch (command.getType()) {
case Command.TYPE_ENGINE_STOP:
- return formatCommand(command, "powercar{%s} 11", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "powercar%s 11", Command.KEY_DEVICE_PASSWORD);
case Command.TYPE_ENGINE_RESUME:
- return formatCommand(command, "powercar{%s} 00", Command.KEY_DEVICE_PASSWORD);
+ return formatCommand(command, "powercar%s 00", Command.KEY_DEVICE_PASSWORD);
default:
return null;
}
diff --git a/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java
new file mode 100644
index 000000000..82bc7dec7
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/OutsafeProtocolDecoderTest.java
@@ -0,0 +1,19 @@
+package org.traccar.protocol;
+
+import io.netty.handler.codec.http.HttpMethod;
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class OutsafeProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ OutsafeProtocolDecoder decoder = new OutsafeProtocolDecoder(null);
+
+ verifyPosition(decoder, request(HttpMethod.POST, "/",
+ buffer("{\"device\":\"1e09d88a-fe8e-4dee-90b9-6297088ff3de\",\"owner\":\"\",\"data\":{\"cmd\":\"GEO\",\"ms1\":82,\"ms2\":80,\"ms3\":5266,\"ms4\":-68,\"observation\":\"$NMEA 323455\",\"content\":null},\"time\":null,\"origin\":\"TCP\",\"latitude\":19.334734,\"longitude\":-99.307236,\"altitude\":2000,\"heading\":0,\"rssi\":123}")));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java
index d1dad8c92..82e0e0d88 100644
--- a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java
@@ -23,7 +23,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeEngineStop() throws Exception {
+ public void testEncodeEngineStop() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
@@ -36,7 +36,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodePositionSingle() throws Exception {
+ public void testEncodePositionSingle() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
@@ -49,7 +49,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodePositionPeriodic() throws Exception {
+ public void testEncodePositionPeriodic() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
@@ -63,7 +63,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodePositionStop() throws Exception {
+ public void testEncodePositionStop() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
@@ -76,7 +76,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeGetVersion() throws Exception {
+ public void testEncodeGetVersion() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
@@ -89,7 +89,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeRebootDevice() throws Exception {
+ public void testEncodeRebootDevice() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
@@ -102,7 +102,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeSetOdometer() throws Exception {
+ public void testEncodeSetOdometer() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
@@ -115,7 +115,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodePositionSingleAlternative() throws Exception {
+ public void testEncodePositionSingleAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -128,7 +128,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodePositionPeriodicAlternative() throws Exception {
+ public void testEncodePositionPeriodicAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -141,7 +141,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodePositionStopAlternative() throws Exception {
+ public void testEncodePositionStopAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -154,7 +154,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeGetVersionAlternative() throws Exception {
+ public void testEncodeGetVersionAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -167,7 +167,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeRebootDeviceAlternative() throws Exception {
+ public void testEncodeRebootDeviceAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -180,7 +180,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeIdentificationAlternative() throws Exception {
+ public void testEncodeIdentificationAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -193,7 +193,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeSosOnAlternative() throws Exception {
+ public void testEncodeSosOnAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -207,7 +207,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeSosOffAlternative() throws Exception {
+ public void testEncodeSosOffAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -221,7 +221,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeCustom() throws Exception {
+ public void testEncodeCustom() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
@@ -235,7 +235,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeCustomAlternative() throws Exception {
+ public void testEncodeCustomAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -249,7 +249,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeSetConnectionAlternative() throws Exception {
+ public void testEncodeSetConnectionAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
@@ -264,7 +264,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
@Test
- public void testEncodeSosNumberAlternative() throws Exception {
+ public void testEncodeSosNumberAlternative() {
Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
diff --git a/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java
new file mode 100644
index 000000000..2fb734462
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/TopinProtocolDecoderTest.java
@@ -0,0 +1,24 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class TopinProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ TopinProtocolDecoder decoder = new TopinProtocolDecoder(null);
+
+ verifyNull(decoder, binary(
+ "78780d0103593390754169634d0d0a"));
+
+ verifyPosition(decoder, binary(
+ "787812100a03170f32179c026b3f3e0c22ad651f34600d0a"));
+
+ verifyAttributes(decoder, binary(
+ "78780713514d0819640d0a"));
+
+ }
+
+}