aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2017-12-07 15:01:12 +1300
committerGitHub <noreply@github.com>2017-12-07 15:01:12 +1300
commit4d903ef0ef21cd6575ed9a55426b18f6b94e63ef (patch)
treed3467073a73fec96cccae3b1c864a6adcf23e669
parente3f7a20c29a38dae64ffe0ab7724cc9df29a03f1 (diff)
parentb9c78ab2c6ac9f2e7598743114864aae04404ac1 (diff)
downloadtraccar-server-4d903ef0ef21cd6575ed9a55426b18f6b94e63ef.tar.gz
traccar-server-4d903ef0ef21cd6575ed9a55426b18f6b94e63ef.tar.bz2
traccar-server-4d903ef0ef21cd6575ed9a55426b18f6b94e63ef.zip
Merge pull request #3643 from ValeraVi/t580w
T580w protocol implementation
-rw-r--r--src/org/traccar/protocol/Tk103FrameDecoder.java79
-rw-r--r--src/org/traccar/protocol/Tk103Protocol.java11
-rw-r--r--src/org/traccar/protocol/Tk103ProtocolDecoder.java178
-rw-r--r--src/org/traccar/protocol/Tk103ProtocolEncoder.java52
-rw-r--r--test/org/traccar/BaseTest.java60
-rw-r--r--test/org/traccar/FilterHandlerTest.java56
-rw-r--r--test/org/traccar/TestIdentityManager.java61
-rw-r--r--test/org/traccar/protocol/Tk103FrameDecoderTest.java42
-rw-r--r--test/org/traccar/protocol/Tk103ProtocolDecoderTest.java81
-rw-r--r--test/org/traccar/protocol/Tk103ProtocolEncoderTest.java153
10 files changed, 619 insertions, 154 deletions
diff --git a/src/org/traccar/protocol/Tk103FrameDecoder.java b/src/org/traccar/protocol/Tk103FrameDecoder.java
new file mode 100644
index 000000000..e8e0325da
--- /dev/null
+++ b/src/org/traccar/protocol/Tk103FrameDecoder.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017 Valerii Vyshniak (val@val.one)
+ * Copyright 2017 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.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
+
+public class Tk103FrameDecoder extends FrameDecoder {
+
+ @Override
+ protected Object decode(
+ ChannelHandlerContext ctx,
+ Channel channel,
+ ChannelBuffer buf) throws Exception {
+
+ if (buf.readableBytes() < 2) {
+ return null;
+ }
+
+ int frameStartIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '(');
+ if (frameStartIndex == -1) {
+ buf.clear();
+ return null;
+ }
+
+ int frameEndIndex, freeTextSymbolCounter;
+ for (frameEndIndex = frameStartIndex, freeTextSymbolCounter = 0;; frameEndIndex++) {
+ int freeTextIndex = frameEndIndex;
+ frameEndIndex = buf.indexOf(frameEndIndex, buf.writerIndex(), (byte) ')');
+ if (frameEndIndex == -1) {
+ break;
+ }
+ for (;; freeTextIndex++, freeTextSymbolCounter++) {
+ freeTextIndex = buf.indexOf(freeTextIndex, frameEndIndex, (byte) '$');
+ if (freeTextIndex == -1 || freeTextIndex >= frameEndIndex) {
+ break;
+ }
+ }
+ if (freeTextSymbolCounter % 2 == 0) {
+ break;
+ }
+ }
+
+ if (frameEndIndex == -1) {
+ while (buf.readableBytes() > 1024) {
+ int discardUntilIndex = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) '(');
+ if (discardUntilIndex == -1) {
+ buf.clear();
+ } else {
+ buf.readerIndex(discardUntilIndex);
+ }
+ }
+ return null;
+ }
+
+ buf.readerIndex(frameStartIndex);
+ ChannelBuffer result = buf.readBytes(frameEndIndex + 1 - frameStartIndex);
+
+ return result;
+
+ }
+
+}
diff --git a/src/org/traccar/protocol/Tk103Protocol.java b/src/org/traccar/protocol/Tk103Protocol.java
index 07a68e2d8..6ef9c0a56 100644
--- a/src/org/traccar/protocol/Tk103Protocol.java
+++ b/src/org/traccar/protocol/Tk103Protocol.java
@@ -22,7 +22,6 @@ 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.CharacterDelimiterFrameDecoder;
import org.traccar.TrackerServer;
import org.traccar.model.Command;
@@ -33,6 +32,14 @@ public class Tk103Protocol extends BaseProtocol {
public Tk103Protocol() {
super("tk103");
setSupportedDataCommands(
+ Command.TYPE_CUSTOM,
+ Command.TYPE_GET_DEVICE_STATUS,
+ Command.TYPE_IDENTIFICATION,
+ Command.TYPE_MODE_DEEP_SLEEP,
+ Command.TYPE_MODE_POWER_SAVING,
+ Command.TYPE_ALARM_SOS,
+ Command.TYPE_SET_CONNECTION,
+ Command.TYPE_SOS_NUMBER,
Command.TYPE_POSITION_SINGLE,
Command.TYPE_POSITION_PERIODIC,
Command.TYPE_POSITION_STOP,
@@ -48,7 +55,7 @@ public class Tk103Protocol extends BaseProtocol {
serverList.add(new TrackerServer(new ServerBootstrap(), getName()) {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
- pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ')'));
+ pipeline.addLast("frameDecoder", new Tk103FrameDecoder());
pipeline.addLast("stringDecoder", new StringDecoder());
pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectEncoder", new Tk103ProtocolEncoder());
diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java
index be3def453..7e2cb06cb 100644
--- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java
@@ -26,6 +26,7 @@ import org.traccar.helper.PatternBuilder;
import org.traccar.model.CellTower;
import org.traccar.model.Network;
import org.traccar.model.Position;
+import org.traccar.model.WifiAccessPoint;
import java.net.SocketAddress;
import java.util.regex.Pattern;
@@ -40,6 +41,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
}
private static final Pattern PATTERN = new PatternBuilder()
+ .text("(").optional()
.number("(d+)(,)?") // device id
.expression("(.{4}),?") // command
.number("(d*)")
@@ -63,21 +65,28 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
.number("(?:L(x+))?") // odometer
.any()
.number("([+-]ddd.d)?") // temperature
+ .groupBegin()
+ .number("([+-]?d+.d{1,2}),") // altitude
+ .number("(d+)$") // number of visible satellites
+ .groupEnd("?")
.text(")").optional()
.compile();
private static final Pattern PATTERN_BATTERY = new PatternBuilder()
+ .text("(").optional()
.number("(d+),") // device id
.text("ZC20,")
.number("(dd)(dd)(dd),") // date (ddmmyy)
.number("(dd)(dd)(dd),") // time (hhmmss)
- .number("d+,") // battery level
+ .number("(d+),") // battery level
.number("(d+),") // battery voltage
.number("(d+),") // power voltage
.number("d+") // installed
+ .any()
.compile();
private static final Pattern PATTERN_NETWORK = new PatternBuilder()
+ .text("(").optional()
.number("(d{12})") // device id
.text("BZ00,")
.number("(d+),") // mcc
@@ -87,6 +96,31 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
.any()
.compile();
+ private static final Pattern PATTERN_LBSWIFI = new PatternBuilder()
+ .text("(").optional()
+ .number("(d+),") // device id
+ .expression("(.{4}),") // command
+ .number("(d+),") // mcc
+ .number("(d+),") // mnc
+ .number("(d+),") // lac
+ .number("(d+),") // cid
+ .number("(d+),") // number of wifi macs
+ .number("((?:(?:xx:){5}(?:xx)\\*[-+]?d+\\*d+,)*)")
+ .number("(dd)(dd)(dd),") // date (ddmmyy)
+ .number("(dd)(dd)(dd)") // time (hhmmss)
+ .any()
+ .compile();
+
+ private static final Pattern PATTERN_COMMAND_RESULT = new PatternBuilder()
+ .text("(").optional()
+ .number("(d+),") // device id
+ .expression(".{4},") // command
+ .number("(dd)(dd)(dd),") // date (ddmmyy)
+ .number("(dd)(dd)(dd),") // time (hhmmss)
+ .expression("\\$([\\s\\S]*?)(?:\\$|$)") // message
+ .any()
+ .compile();
+
private String decodeAlarm(int value) {
switch (value) {
case 1:
@@ -112,37 +146,82 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_ALARM, decodeAlarm(data.charAt(0) - '0'));
break;
case "ZC11":
+ case "DW31":
+ case "DW51":
position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT);
break;
case "ZC12":
+ case "DW32":
+ case "DW52":
position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY);
break;
case "ZC13":
+ case "DW33":
+ case "DW53":
position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT);
break;
case "ZC15":
+ case "DW35":
+ case "DW55":
position.set(Position.KEY_IGNITION, true);
break;
case "ZC16":
+ case "DW36":
+ case "DW56":
position.set(Position.KEY_IGNITION, false);
break;
+ case "ZC29":
+ case "DW42":
+ case "DW62":
+ position.set(Position.KEY_IGNITION, true);
+ break;
case "ZC17":
+ case "DW37":
+ case "DW57":
position.set(Position.KEY_ALARM, Position.ALARM_REMOVING);
break;
case "ZC25":
+ case "DW3E":
+ case "DW5E":
position.set(Position.KEY_ALARM, Position.ALARM_SOS);
break;
case "ZC26":
+ case "DW3F":
+ case "DW5F":
position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING);
break;
case "ZC27":
+ case "DW40":
+ case "DW60":
position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER);
break;
+ case "ZC28":
+ case "DW41":
+ case "DW61":
+ position.set(Position.KEY_ALARM, "badBattery");
+ break;
default:
break;
}
}
+ private Integer decodeBattery(int value) {
+ switch (value) {
+ case 6:
+ return 100;
+ case 5:
+ return 80;
+ case 4:
+ return 50;
+ case 3:
+ return 20;
+ case 2:
+ return 10;
+ default:
+ return null;
+ }
+ }
+
private Position decodeBattery(Channel channel, SocketAddress remoteAddress, String sentence) {
Parser parser = new Parser(PATTERN_BATTERY, sentence);
if (!parser.matches()) {
@@ -160,6 +239,11 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
+ int batterylevel = parser.nextInt(0);
+ if (batterylevel != 255) {
+ position.set(Position.KEY_BATTERY_LEVEL, decodeBattery(batterylevel));
+ }
+
int battery = parser.nextInt(0);
if (battery != 65535) {
position.set(Position.KEY_BATTERY, battery * 0.01);
@@ -195,20 +279,84 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
return position;
}
- @Override
+
+ private Position decodeLbsWifi(Channel channel, SocketAddress remoteAddress, String sentence) {
+ Parser parser = new Parser(PATTERN_LBSWIFI, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ decodeType(position, parser.next(), "0");
+
+ getLastLocation(position, null);
+
+ Network network = new Network();
+
+ network.addCellTower(CellTower.from(
+ parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt()));
+
+ int wifiCount = parser.nextInt();
+ if (parser.hasNext()) {
+ String[] wifimacs = parser.next().split(",");
+ if (wifimacs.length == wifiCount) {
+ for (int i = 0; i < wifiCount; i++) {
+ String[] wifiinfo = wifimacs[i].split("\\*");
+ network.addWifiAccessPoint(WifiAccessPoint.from(
+ wifiinfo[0], Integer.parseInt(wifiinfo[1]), Integer.parseInt(wifiinfo[2])));
+ }
+ }
+ }
+
+ if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) {
+ position.setNetwork(network);
+ }
+
+ position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
+
+ return position;
+ }
+
+ private Position decodeCommandResult(Channel channel, SocketAddress remoteAddress, String sentence) {
+ Parser parser = new Parser(PATTERN_COMMAND_RESULT, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
+
+ position.set(Position.KEY_RESULT, parser.next());
+
+ return position;
+
+ }
+
+@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
String sentence = (String) msg;
- int beginIndex = sentence.indexOf('(');
- if (beginIndex != -1) {
- sentence = sentence.substring(beginIndex + 1);
- }
-
if (channel != null) {
- String id = sentence.substring(0, 12);
- String type = sentence.substring(12, 16);
+ String id = sentence.substring(1, 13);
+ String type = sentence.substring(13, 17);
if (type.equals("BP00")) {
channel.write("(" + id + "AP01HSO)");
return null;
@@ -221,6 +369,10 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
return decodeBattery(channel, remoteAddress, sentence);
} else if (sentence.contains("BZ00")) {
return decodeNetwork(channel, remoteAddress, sentence);
+ } else if (sentence.contains("ZC03")) {
+ return decodeCommandResult(channel, remoteAddress, sentence);
+ } else if (sentence.contains("DW5")) {
+ return decodeLbsWifi(channel, remoteAddress, sentence);
}
Parser parser = new Parser(PATTERN, sentence);
@@ -299,6 +451,14 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_TEMP + 1, parser.nextDouble(0));
}
+ if (parser.hasNext()) {
+ position.setAltitude(parser.nextDouble(0));
+ }
+
+ if (parser.hasNext()) {
+ position.set(Position.KEY_SATELLITES_VISIBLE, parser.nextInt(0));
+ }
+
return position;
}
diff --git a/src/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/org/traccar/protocol/Tk103ProtocolEncoder.java
index 9e49b6ff1..d7b17eeb7 100644
--- a/src/org/traccar/protocol/Tk103ProtocolEncoder.java
+++ b/src/org/traccar/protocol/Tk103ProtocolEncoder.java
@@ -16,33 +16,75 @@
*/
package org.traccar.protocol;
+import org.traccar.Context;
import org.traccar.StringProtocolEncoder;
import org.traccar.helper.Log;
import org.traccar.model.Command;
public class Tk103ProtocolEncoder extends StringProtocolEncoder {
+ private final boolean forceAlternative;
+
+ public Tk103ProtocolEncoder() {
+ this.forceAlternative = false;
+ }
+
+ public Tk103ProtocolEncoder(boolean forceAlternative) {
+ this.forceAlternative = forceAlternative;
+ }
+
@Override
protected Object encodeCommand(Command command) {
+ boolean alternative = forceAlternative || Context.getIdentityManager().lookupAttributeBoolean(
+ command.getDeviceId(), "tk103.alternative", false, true);
+
+ initDevicePassword(command, "123456");
+
switch (command.getType()) {
case Command.TYPE_GET_VERSION:
- return formatCommand(command, "({%s}AP07)", Command.KEY_UNIQUE_ID);
+ return alternative ? formatCommand(command, "[begin]sms2,*about*,[end]")
+ : formatCommand(command, "({%s}AP07)", Command.KEY_UNIQUE_ID);
case Command.TYPE_REBOOT_DEVICE:
- return formatCommand(command, "({%s}AT00)", Command.KEY_UNIQUE_ID);
+ return alternative ? formatCommand(command, "[begin]sms2,88888888,[end]")
+ : formatCommand(command, "({%s}AT00)", Command.KEY_UNIQUE_ID);
case Command.TYPE_SET_ODOMETER:
return formatCommand(command, "({%s}AX01)", Command.KEY_UNIQUE_ID);
case Command.TYPE_POSITION_SINGLE:
- return formatCommand(command, "({%s}AP00)", Command.KEY_UNIQUE_ID);
+ return alternative ? formatCommand(command, "[begin]sms2,*getposl*,[end]")
+ : formatCommand(command, "({%s}AP00)", Command.KEY_UNIQUE_ID);
case Command.TYPE_POSITION_PERIODIC:
- return formatCommand(command, "({%s}AR00%s0000)", Command.KEY_UNIQUE_ID,
+ return alternative ? formatCommand(command, "[begin]sms2,*routetrack*99*,[end]")
+ : formatCommand(command, "({%s}AR00%s0000)", Command.KEY_UNIQUE_ID,
String.format("%04X", command.getInteger(Command.KEY_FREQUENCY)));
case Command.TYPE_POSITION_STOP:
- return formatCommand(command, "({%s}AR0000000000)", Command.KEY_UNIQUE_ID);
+ return alternative ? formatCommand(command, "[begin]sms2,*routetrackoff*,[end]")
+ : formatCommand(command, "({%s}AR0000000000)", Command.KEY_UNIQUE_ID);
case Command.TYPE_ENGINE_STOP:
return formatCommand(command, "({%s}AV011)", Command.KEY_UNIQUE_ID);
case Command.TYPE_ENGINE_RESUME:
return formatCommand(command, "({%s}AV010)", Command.KEY_UNIQUE_ID);
+ case Command.TYPE_CUSTOM:
+ return formatCommand(command, "[begin]sms2,{%s},[end]", Command.KEY_DATA);
+ case Command.TYPE_GET_DEVICE_STATUS:
+ return formatCommand(command, "[begin]sms2,*status*,[end]");
+ case Command.TYPE_IDENTIFICATION:
+ return formatCommand(command, "[begin]sms2,999999,[end]");
+ case Command.TYPE_MODE_DEEP_SLEEP:
+ return formatCommand(command, command.getBoolean(Command.KEY_ENABLE)
+ ? "[begin]sms2,*sleep*2*,[end]" : "[begin]sms2,*sleepoff*,[end]");
+ case Command.TYPE_MODE_POWER_SAVING:
+ return formatCommand(command, command.getBoolean(Command.KEY_ENABLE)
+ ? "[begin]sms2,*sleepv*,[end]" : "[begin]sms2,*sleepoff*,[end]");
+ case Command.TYPE_ALARM_SOS:
+ return formatCommand(command, command.getBoolean(Command.KEY_ENABLE)
+ ? "[begin]sms2,*soson*,[end]" : "[begin]sms2,*sosoff*,[end]");
+ case Command.TYPE_SET_CONNECTION:
+ return formatCommand(command, "[begin]sms2,*setip*%s*{%s}*,[end]",
+ command.getString(Command.KEY_SERVER).replace(".", "*"), Command.KEY_PORT);
+ case Command.TYPE_SOS_NUMBER:
+ return formatCommand(command, "[begin]sms2,*master*{%s}*{%s}*,[end]",
+ Command.KEY_DEVICE_PASSWORD, Command.KEY_PHONE);
default:
Log.warning(new UnsupportedOperationException(command.getType()));
break;
diff --git a/test/org/traccar/BaseTest.java b/test/org/traccar/BaseTest.java
index 4b9ee5451..fb1b5de8f 100644
--- a/test/org/traccar/BaseTest.java
+++ b/test/org/traccar/BaseTest.java
@@ -1,67 +1,9 @@
package org.traccar;
-import org.traccar.database.IdentityManager;
-import org.traccar.model.Device;
-import org.traccar.model.Position;
-
public class BaseTest {
static {
- Context.init(new IdentityManager() {
-
- private Device createDevice() {
- Device device = new Device();
- device.setId(1);
- device.setName("test");
- device.setUniqueId("123456789012345");
- return device;
- }
-
- @Override
- public Device getById(long id) {
- return createDevice();
- }
-
- @Override
- public Device getByUniqueId(String uniqueId) {
- return createDevice();
- }
-
- @Override
- public Position getLastPosition(long deviceId) {
- return null;
- }
-
- @Override
- public boolean isLatestPosition(Position position) {
- return true;
- }
-
- @Override
- public boolean lookupAttributeBoolean(
- long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) {
- return defaultValue;
- }
-
- @Override
- public String lookupAttributeString(
- long deviceId, String attributeName, String defaultValue, boolean lookupConfig) {
- return defaultValue;
- }
-
- @Override
- public int lookupAttributeInteger(
- long deviceId, String attributeName, int defaultValue, boolean lookupConfig) {
- return defaultValue;
- }
-
- @Override
- public long lookupAttributeLong(
- long deviceId, String attributeName, long defaultValue, boolean lookupConfig) {
- return defaultValue;
- }
-
- });
+ Context.init(new TestIdentityManager());
}
}
diff --git a/test/org/traccar/FilterHandlerTest.java b/test/org/traccar/FilterHandlerTest.java
index 7ebab3af5..0d488a7fb 100644
--- a/test/org/traccar/FilterHandlerTest.java
+++ b/test/org/traccar/FilterHandlerTest.java
@@ -15,61 +15,7 @@ import static org.junit.Assert.assertNull;
public class FilterHandlerTest {
static {
- Context.init(new IdentityManager() {
-
- private Device createDevice() {
- Device device = new Device();
- device.setId(1);
- device.setName("test");
- device.setUniqueId("123456789012345");
- return device;
- }
-
- @Override
- public Device getById(long id) {
- return createDevice();
- }
-
- @Override
- public Device getByUniqueId(String uniqueId) {
- return createDevice();
- }
-
- @Override
- public Position getLastPosition(long deviceId) {
- return null;
- }
-
- @Override
- public boolean isLatestPosition(Position position) {
- return true;
- }
-
- @Override
- public boolean lookupAttributeBoolean(
- long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) {
- return defaultValue;
- }
-
- @Override
- public String lookupAttributeString(
- long deviceId, String attributeName, String defaultValue, boolean lookupConfig) {
- return "alarm,result";
- }
-
- @Override
- public int lookupAttributeInteger(
- long deviceId, String attributeName, int defaultValue, boolean lookupConfig) {
- return defaultValue;
- }
-
- @Override
- public long lookupAttributeLong(
- long deviceId, String attributeName, long defaultValue, boolean lookupConfig) {
- return defaultValue;
- }
-
- });
+ Context.init(new TestIdentityManager());
}
private FilterHandler filtingHandler;
diff --git a/test/org/traccar/TestIdentityManager.java b/test/org/traccar/TestIdentityManager.java
new file mode 100644
index 000000000..f9d95927d
--- /dev/null
+++ b/test/org/traccar/TestIdentityManager.java
@@ -0,0 +1,61 @@
+package org.traccar;
+
+import org.traccar.database.IdentityManager;
+import org.traccar.model.Device;
+import org.traccar.model.Position;
+
+public final class TestIdentityManager implements IdentityManager {
+
+ private static Device createDevice() {
+ Device device = new Device();
+ device.setId(1);
+ device.setName("test");
+ device.setUniqueId("123456789012345");
+ return device;
+ }
+
+ @Override
+ public Device getById(long id) {
+ return createDevice();
+ }
+
+ @Override
+ public Device getByUniqueId(String uniqueId) {
+ return createDevice();
+ }
+
+ @Override
+ public Position getLastPosition(long deviceId) {
+ return null;
+ }
+
+ @Override
+ public boolean isLatestPosition(Position position) {
+ return true;
+ }
+
+ @Override
+ public boolean lookupAttributeBoolean(
+ long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) {
+ return defaultValue;
+ }
+
+ @Override
+ public String lookupAttributeString(
+ long deviceId, String attributeName, String defaultValue, boolean lookupConfig) {
+ return "alarm,result";
+ }
+
+ @Override
+ public int lookupAttributeInteger(
+ long deviceId, String attributeName, int defaultValue, boolean lookupConfig) {
+ return defaultValue;
+ }
+
+ @Override
+ public long lookupAttributeLong(
+ long deviceId, String attributeName, long defaultValue, boolean lookupConfig) {
+ return defaultValue;
+ }
+
+}
diff --git a/test/org/traccar/protocol/Tk103FrameDecoderTest.java b/test/org/traccar/protocol/Tk103FrameDecoderTest.java
new file mode 100644
index 000000000..33f7182e0
--- /dev/null
+++ b/test/org/traccar/protocol/Tk103FrameDecoderTest.java
@@ -0,0 +1,42 @@
+package org.traccar.protocol;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class Tk103FrameDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ Tk103FrameDecoder decoder = new Tk103FrameDecoder();
+
+ verifyFrame(
+ binary("283836343735353535353535353535352C445733422C3133313131372C412C353536322E30323837304E2C30313334382E3038313934452C312E3539372C3232333730372C3239312E36352C2D302E31302C3429"),
+ decoder.decode(null, null, binary("283836343735353535353535353535352C445733422C3133313131372C412C353536322E30323837304E2C30313334382E3038313934452C312E3539372C3232333730372C3239312E36352C2D302E31302C3429283836343735353535353535353535352C5A4332302C3133313131372C3232333730362C362C3339342C36353533352C32353529")));
+
+ ChannelBuffer buf = binary("283836343535353535353535353535352C445735422C3231302C362C353939352C34373730312C352C33303A45453A43433A45373A38363A44442A2D35392A31312C34433A36303A43433A45413A42423A45452A2D36382A312C34323A41413A44453A45413A42423A30302A2D36392A312C33323A43443A42423A43333A34463A43432A2D38362A332C31303A30303A34333A42413A32323A31352A2D38382A312C3135313131372C31363337323229283836343735353535353535353535352C5A4332302C3133313131372C3232333730362C362C3339342C36353533352C32353529");
+ verifyFrame(
+ binary("283836343535353535353535353535352C445735422C3231302C362C353939352C34373730312C352C33303A45453A43433A45373A38363A44442A2D35392A31312C34433A36303A43433A45413A42423A45452A2D36382A312C34323A41413A44453A45413A42423A30302A2D36392A312C33323A43443A42423A43333A34463A43432A2D38362A332C31303A30303A34333A42413A32323A31352A2D38382A312C3135313131372C31363337323229"),
+ decoder.decode(null, null, buf));
+ verifyFrame(
+ binary("283836343735353535353535353535352C5A4332302C3133313131372C3232333730362C362C3339342C36353533352C32353529"),
+ decoder.decode(null, null, buf));
+
+ verifyFrame(
+ binary("283836343735353535353535353535352C445733422C3133313131372C412C353536322E30323837304E2C30313334382E3038313934452C312E3539372C3232333730372C3239312E36352C2D302E31302C3429"),
+ decoder.decode(null, null, binary("676172626167652540232A5E242D2B3C3E3F2429292924242D2D283836343735353535353535353535352C445733422C3133313131372C412C353536322E30323837304E2C30313334382E3038313934452C312E3539372C3232333730372C3239312E36352C2D302E31302C3429283836343735353535353535353535352C5A4332302C3133313131372C3232333730362C362C3339342C36353533352C32353529")));
+
+ verifyNull(decoder.decode(null, null, binary("67")));
+
+ verifyNull(decoder.decode(null, null, binary("676172626167652540232a5e242d2b3c3e3f24")));
+
+ verifyFrame(
+ binary("2838363437353535353535352C5A4330332C3139313131372C3233343432312C24294E6F746963653A0D0A446576696365732073657269616C206E756D6265723A200D0A3538303535353535353535292E0D0A536F6674776172652076657273696F6E3A0D0A56322E3030302C323031362F30382F32332031313A3137292429"),
+ decoder.decode(null, null, binary("610D0A676172626167652540232A5E242D2B3C3E3F2429292924242D2D2838363437353535353535352C5A4330332C3139313131372C3233343432312C24294E6F746963653A0D0A446576696365732073657269616C206E756D6265723A200D0A3538303535353535353535292E0D0A536F6674776172652076657273696F6E3A0D0A56322E3030302C323031362F30382F32332031313A3137292429283836343735353535353535353535352C5A4332302C3133313131372C3232333730362C362C3339342C36353533352C32353529")));
+
+ verifyNull(decoder.decode(null, null, binary("610D0A676172626167652540232A5E242D2B3C3E3F2429292924242D2D2838363437353535353535352C5A4330332C3139313131372C3233343432312C24294E6F746963653A0D0A446576696365732073657269616C206E756D6265723A200D0A3538303535353535353535292E0D0A536F6674776172652076657273696F6E3A0D0A56322E3030302C323031362F30382F32332031313A31372929283836343735353535353535353535352C5A4332302C3133313131372C3232333730362C362C3339342C36353533352C32353529")));
+
+ }
+
+}
diff --git a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java
index a69ff8856..8b185c104 100644
--- a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java
@@ -38,7 +38,7 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest {
"(087073104337BZ00,740,000,3bf7,0425,3bf7,0bf5,3bf7,09e7,3bf7,cbad,3bf7,0dcf,3bf7,c7b2,01000000)"));
verifyNull(decoder, text(
- "(087073005534BP00HSO"));
+ "(087073005534BP00HSO)"));
verifyNull(decoder, text(
"(027028258309BQ86,0,05550c21b10d1d0f431008bd114c0ea5078400010007a100423932,161117005322,01000001)"));
@@ -56,22 +56,22 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest {
"(088046338039BP05000088046338039160727A3354.7768N03540.7258E000.0140309065.1000000000L00BEB0D4+017.3)"));
verifyAttributes(decoder, text(
- "(013632651491,ZC20,180716,144222,6,392,65535,255"));
+ "(013632651491,ZC20,180716,144222,6,392,65535,255)"));
verifyAttributes(decoder, text(
- "(087072009461BR00000007V0000.0000N00000.0000E000.00014039900000000L00000000"));
+ "(087072009461BR00000007V0000.0000N00000.0000E000.00014039900000000L00000000)"));
verifyPosition(decoder, text(
- "(013612345678BO012061830A2934.0133N10627.2544E040.0080331309.6200000000L000770AD"));
+ "(013612345678BO012061830A2934.0133N10627.2544E040.0080331309.6200000000L000770AD)"));
verifyNotNull(decoder, text(
- "(088047194605BZ00,510,010,36e6,932c,43,36e6,766b,36,36e6,7668,32"));
+ "(088047194605BZ00,510,010,36e6,932c,43,36e6,766b,36,36e6,7668,32)"));
verifyAttributes(decoder, text(
- "(013632651491,ZC20,040613,040137,6,421,112,0"));
+ "(013632651491,ZC20,040613,040137,6,421,112,0)"));
verifyAttributes(decoder, text(
- "(864768010159785,ZC20,291015,030413,3,362,65535,255"));
+ "(864768010159785,ZC20,291015,030413,3,362,65535,255)"));
verifyPosition(decoder, text(
"(088047365460BR00151024A2555.3531S02855.3329E004.7055148276.1701000000L00009AA3)"),
@@ -90,50 +90,50 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest {
"(088048003342BR00150807A1352.9871N10030.9084E000.0110718000.0001010000L00000000)"));
verifyNull(decoder, text(
- "(090411121854BP0000001234567890HSO"));
+ "(090411121854BP0000001234567890HSO)"));
verifyPosition(decoder, text(
"(01029131573BR00150428A3801.6382N02351.0159E000.0080729278.7800000000LEF9ECB9C)"));
verifyPosition(decoder, text(
- "(035988863964BP05000035988863964110524A4241.7977N02318.7561E000.0123536356.5100000000L000946BB"));
+ "(035988863964BP05000035988863964110524A4241.7977N02318.7561E000.0123536356.5100000000L000946BB)"));
verifyPosition(decoder, text(
- "(013632782450BP05000013632782450120803V0000.0000N00000.0000E000.0174654000.0000000000L00000000"));
+ "(013632782450BP05000013632782450120803V0000.0000N00000.0000E000.0174654000.0000000000L00000000)"));
verifyPosition(decoder, text(
- "(013666666666BP05000013666666666110925A1234.5678N01234.5678W000.002033490.00000000000L000024DE"));
+ "(013666666666BP05000013666666666110925A1234.5678N01234.5678W000.002033490.00000000000L000024DE)"));
verifyPosition(decoder, text(
- "(013666666666BO012110925A1234.5678N01234.5678W000.0025948118.7200000000L000024DE"));
+ "(013666666666BO012110925A1234.5678N01234.5678W000.0025948118.7200000000L000024DE)"));
verifyPosition(decoder, text(
- "\n\n\n(088045133878BR00130228A5124.5526N00117.7152W000.0233614352.2200000000L01B0CF1C"));
+ "(088045133878BR00130228A5124.5526N00117.7152W000.0233614352.2200000000L01B0CF1C)"));
verifyPosition(decoder, text(
- "(008600410203BP05000008600410203130721A4152.5790N01239.2770E000.0145238173.870100000AL0000000"));
+ "(008600410203BP05000008600410203130721A4152.5790N01239.2770E000.0145238173.870100000AL0000000)"));
verifyPosition(decoder, text(
- "(013012345678BR00130515A4843.9703N01907.6211E000.019232800000000000000L00009239"));
+ "(013012345678BR00130515A4843.9703N01907.6211E000.019232800000000000000L00009239)"));
verifyPosition(decoder, text(
- "(012345678901BP05000012345678901130520A3439.9629S05826.3504W000.1175622323.8700000000L000450AC"));
+ "(012345678901BP05000012345678901130520A3439.9629S05826.3504W000.1175622323.8700000000L000450AC)"));
verifyPosition(decoder, text(
- "(012345678901BR00130520A3439.9629S05826.3504W000.1175622323.8700000000L000450AC"));
+ "(012345678901BR00130520A3439.9629S05826.3504W000.1175622323.8700000000L000450AC)"));
verifyPosition(decoder, text(
- "(352606090042050,BP05,240414,V,0000.0000N,00000.0000E,000.0,193133,000.0"));
+ "(352606090042050,BP05,240414,V,0000.0000N,00000.0000E,000.0,193133,000.0)"));
verifyPosition(decoder, text(
- "(352606090042050,BP05,240414,A,4527.3513N,00909.9758E,4.80,112825,155.49"),
+ "(352606090042050,BP05,240414,A,4527.3513N,00909.9758E,4.80,112825,155.49)"),
position("2014-04-24 11:28:25.000", true, 45.45586, 9.16626));
verifyPosition(decoder, text(
- "(013632782450,BP05,101201,A,2234.0297N,11405.9101E,000.0,040137,178.48,00000000,L00000000"));
+ "(013632782450,BP05,101201,A,2234.0297N,11405.9101E,000.0,040137,178.48,00000000,L00000000)"));
verifyPosition(decoder, text(
- "(864768010009188,BP05,271114,V,4012.19376N,00824.05638E,000.0,154436,000.0"));
+ "(864768010009188,BP05,271114,V,4012.19376N,00824.05638E,000.0,154436,000.0)"));
verifyPosition(decoder, text(
"(013632651491,BP05,040613,A,2234.0297N,11405.9101E,000.0,040137,178.48)"));
@@ -153,12 +153,45 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, text(
"(013632651491,ZC17,040613,A,2234.0297N,11405.9101E,000.0,040137,178.48)"));
- verifyNull(decoder, text(
- "(013632651491,ZC20,040613,040137,6,42,112,0)"));
-
verifyPosition(decoder, text(
"(094050000111BP05000094050000111150808A3804.2418N04616.7468E000.0201447133.3501000011L0028019DT000)"));
+ verifyPosition(decoder, text(
+ "(864555555555555,DW3B,131117,A,5544.02870N,01315.08194E,1.597,223707,291.65,-0.10,4)"));
+
+ verifyPosition(decoder, text(
+ "(864555555555555,DW3B,131117,A,5544.02870N,01315.08194E,1.597,223707,291.65,0.10,8)"));
+
+ verifyPosition(decoder, text(
+ "(013632651491,ZC07,040613,A,2234.0297N,11405.9101E,000.0,040137,178.48)"));
+
+ verifyAttributes(decoder, text(
+ "(013632651491,ZC20,040613,040137,6,42,112,0)"));
+
+ verifyNotNull(decoder, text(
+ "(864555555555555,DW51,200,1,3215,43370,2,58:F3:BB:3B:AA:82*-65*1,1C:6A:BB:AA:81:95*-78*1,151117,154419)"));
+
+ verifyNotNull(decoder, text(
+ "(864555555555555,DW5B,210,6,5995,47701,5,30:EE:CC:E7:86:DD*-59*11,4C:60:CC:EA:BB:EE*-68*1,42:AA:DE:EA:BB:00*-69*1,32:CD:BB:C3:4F:CC*-86*3,10:00:43:BA:22:15*-88*1,151117,163722)"));
+
+ verifyNotNull(decoder, text(
+ "(013632651491,DW50,460,0,0,6,2,aa:bb:cc:dd:ee:ff*-8*0,aa:bb:cc:dd:ee:ff*-8*0,040613,040137)"));
+
+ verifyNotNull(decoder, text(
+ "(013632651491,DW50,460,0,0,6,0,040613,040137)"));
+
+ verifyNotNull(decoder, text(
+ "(864555555555555,ZC03,191117,234207,$Notice: Device version: 1.0$)"));
+
+ verifyNotNull(decoder, text(
+ "(864555555555555,ZC03,191117,234207,$1 .Sensor sensitivity: 1\r\n" +
+ "2 .Alert status: Off\r\n" +
+ "3 .Check interval is set to 240 minute(s).\r\n" +
+ "4 .Checkgsm interval is set to 60 minute(s).\r\n" +
+ "5 .SOS SMS Alert: On\r\n" +
+ "6 .SOS Call Alert: On\r\n" +
+ "7 . Power: 95%$)"));
+
}
}
diff --git a/test/org/traccar/protocol/Tk103ProtocolEncoderTest.java b/test/org/traccar/protocol/Tk103ProtocolEncoderTest.java
index afc3b2387..a99889e3b 100644
--- a/test/org/traccar/protocol/Tk103ProtocolEncoderTest.java
+++ b/test/org/traccar/protocol/Tk103ProtocolEncoderTest.java
@@ -3,7 +3,9 @@ package org.traccar.protocol;
import org.junit.Assert;
import org.junit.Test;
import org.traccar.ProtocolTest;
+import org.traccar.TestIdentityManager;
import org.traccar.model.Command;
+import org.traccar.model.Device;
public class Tk103ProtocolEncoderTest extends ProtocolTest {
@@ -99,4 +101,155 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
}
+ @Test
+ public void testEncodePositionSingleAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_POSITION_SINGLE);
+
+ Assert.assertEquals("[begin]sms2,*getposl*,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodePositionPeriodicAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_POSITION_PERIODIC);
+
+ Assert.assertEquals("[begin]sms2,*routetrack*99*,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodePositionStopAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_POSITION_STOP);
+
+ Assert.assertEquals("[begin]sms2,*routetrackoff*,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodeGetVersionAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_GET_VERSION);
+
+ Assert.assertEquals("[begin]sms2,*about*,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodeRebootDeviceAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_REBOOT_DEVICE);
+
+ Assert.assertEquals("[begin]sms2,88888888,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodeIdentificationAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_IDENTIFICATION);
+
+ Assert.assertEquals("[begin]sms2,999999,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodeSosOnAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_ALARM_SOS);
+ command.set(Command.KEY_ENABLE, true);
+
+ Assert.assertEquals("[begin]sms2,*soson*,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodeSosOffAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_ALARM_SOS);
+ command.set(Command.KEY_ENABLE, false);
+
+ Assert.assertEquals("[begin]sms2,*sosoff*,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodeCustomAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_CUSTOM);
+ command.set(Command.KEY_DATA, "any text is ok");
+
+ Assert.assertEquals("[begin]sms2,any text is ok,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodeSetConnectionAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_SET_CONNECTION);
+ command.set(Command.KEY_SERVER, "1.2.3.4");
+ command.set(Command.KEY_PORT, "5555");
+
+ Assert.assertEquals("[begin]sms2,*setip*1*2*3*4*5555*,[end]", encoder.encodeCommand(command));
+
+ }
+
+ @Test
+ public void testEncodeSosNumberAlternative() throws Exception {
+
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_SOS_NUMBER);
+ command.set(Command.KEY_INDEX, "0");
+ command.set(Command.KEY_PHONE, "+55555555555");
+ command.set(Command.KEY_DEVICE_PASSWORD, "232323");
+
+ Assert.assertEquals("[begin]sms2,*master*232323*+55555555555*,[end]", encoder.encodeCommand(command));
+
+ }
+
}