aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/org/traccar/FilterHandler.java10
-rw-r--r--src/org/traccar/database/PermissionsManager.java4
-rw-r--r--src/org/traccar/model/Position.java2
-rw-r--r--src/org/traccar/protocol/AtrackProtocolDecoder.java52
-rw-r--r--src/org/traccar/protocol/Gt06ProtocolDecoder.java161
-rw-r--r--src/org/traccar/protocol/MeitrackProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Tk103Protocol.java7
-rw-r--r--src/org/traccar/protocol/Tk103ProtocolDecoder.java159
-rw-r--r--src/org/traccar/protocol/Tk103ProtocolEncoder.java14
-rw-r--r--src/org/traccar/protocol/WatchProtocolDecoder.java17
-rw-r--r--src/org/traccar/smpp/EnquireLinkTask.java2
11 files changed, 339 insertions, 92 deletions
diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java
index 973dfc205..9e532347d 100644
--- a/src/org/traccar/FilterHandler.java
+++ b/src/org/traccar/FilterHandler.java
@@ -93,7 +93,15 @@ public class FilterHandler extends BaseDataHandler {
}
private boolean filterDuplicate(Position position, Position last) {
- return filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime());
+ if (filterDuplicate && last != null && position.getFixTime().equals(last.getFixTime())) {
+ for (String key : position.getAttributes().keySet()) {
+ if (!last.getAttributes().containsKey(key)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
}
private boolean filterFuture(Position position) {
diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java
index 11f147c7c..9a82efd48 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -182,14 +182,14 @@ public class PermissionsManager {
public void checkManager(long userId, long managedUserId) throws SecurityException {
checkManager(userId);
- if (!userPermissions.get(userId).contains(managedUserId)) {
+ if (!getUserPermissions(userId).contains(managedUserId)) {
throw new SecurityException("User access denied");
}
}
public void checkUserLimit(long userId) throws SecurityException {
int userLimit = users.get(userId).getUserLimit();
- if (userLimit != -1 && userPermissions.get(userId).size() >= userLimit) {
+ if (userLimit != -1 && getUserPermissions(userId).size() >= userLimit) {
throw new SecurityException("Manager user limit reached");
}
}
diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java
index bf2518c3c..2198d3b24 100644
--- a/src/org/traccar/model/Position.java
+++ b/src/org/traccar/model/Position.java
@@ -39,7 +39,7 @@ public class Position extends Message {
public static final String KEY_OUTPUT = "output";
public static final String KEY_IMAGE = "image";
public static final String KEY_VIDEO = "video";
- public static final String KEY_SOUND = "sound";
+ public static final String KEY_AUDIO = "audio";
// The units for the below four KEYs currently vary.
// The preferred units of measure are specified in the comment for each.
diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java
index 3566631f0..79b3c36cc 100644
--- a/src/org/traccar/protocol/AtrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java
@@ -22,6 +22,8 @@ import org.traccar.BaseProtocolDecoder;
import org.traccar.Context;
import org.traccar.DeviceSession;
import org.traccar.helper.DateBuilder;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.CellTower;
import org.traccar.model.Network;
@@ -34,6 +36,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.regex.Pattern;
public class AtrackProtocolDecoder extends BaseProtocolDecoder {
@@ -195,29 +198,62 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
}
}
- private Position decodeString(Channel channel, SocketAddress remoteAddress, String sentence) {
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
- if (deviceSession == null) {
- return null;
- }
+ private static final Pattern PATTERN_INFO = new PatternBuilder()
+ .text("$INFO=")
+ .number("(d+),") // unit id
+ .expression("([^,]+),") // model
+ .expression("([^,]+),") // firmware version
+ .number("d+,") // imei
+ .number("d+,") // imsi
+ .number("d+,") // sim card id
+ .number("(d+),") // power
+ .number("(d+),") // battery
+ .number("(d+),") // satellites
+ .number("d+,") // gsm status
+ .number("(d+),") // rssi
+ .number("d+,") // connection status
+ .number("d+") // antenna status
+ .any()
+ .compile();
+ private Position decodeString(Channel channel, SocketAddress remoteAddress, String sentence) {
Position position = new Position();
position.setProtocol(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
+ DeviceSession deviceSession;
+
if (sentence.startsWith("$INFO")) {
- return null;
+ Parser parser = new Parser(PATTERN_INFO, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+
+ position.set("model", parser.next());
+ position.set(Position.KEY_VERSION_FW, parser.next());
+ position.set(Position.KEY_POWER, parser.nextInt() * 0.1);
+ position.set(Position.KEY_BATTERY, parser.nextInt() * 0.1);
+ position.set(Position.KEY_SATELLITES, parser.nextInt());
+ position.set(Position.KEY_RSSI, parser.nextInt());
} else {
+ deviceSession = getDeviceSession(channel, remoteAddress);
+
position.set(Position.KEY_RESULT, sentence);
}
- return position;
+ if (deviceSession == null) {
+ return null;
+ } else {
+ position.setDeviceId(deviceSession.getDeviceId());
+ return position;
+ }
}
@Override
diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java
index 261278539..261c86825 100644
--- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java
@@ -28,11 +28,14 @@ import org.traccar.helper.Parser;
import org.traccar.helper.PatternBuilder;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.CellTower;
+import org.traccar.model.Device;
import org.traccar.model.Network;
import org.traccar.model.Position;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Pattern;
@@ -41,6 +44,10 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
private boolean forceTimeZone = false;
private final TimeZone timeZone = TimeZone.getTimeZone("UTC");
+ private int serverIndex;
+
+ private final Map<Integer, ChannelBuffer> photos = new HashMap<>();
+
public Gt06ProtocolDecoder(Gt06Protocol protocol) {
super(protocol);
@@ -66,6 +73,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_LBS_STATUS = 0x19;
public static final int MSG_GPS_PHONE = 0x1A;
public static final int MSG_GPS_LBS_EXTEND = 0x1E;
+ public static final int MSG_AZ735_GPS = 0x32;
+ public static final int MSG_AZ735_ALARM = 0x33;
+ public static final int MSG_X1_GPS = 0x34;
+ public static final int MSG_X1_PHOTO_INFO = 0x35;
+ public static final int MSG_X1_PHOTO_DATA = 0x36;
public static final int MSG_COMMAND_0 = 0x80;
public static final int MSG_COMMAND_1 = 0x81;
public static final int MSG_COMMAND_2 = 0x82;
@@ -92,26 +104,54 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
|| type == MSG_GPS_LBS_STATUS_1 || type == MSG_GPS_LBS_STATUS_2 || type == MSG_GPS_LBS_STATUS_3;
}
- private static void sendResponse(Channel channel, int type, int index) {
+ private void sendResponse(Channel channel, boolean extended, int type) {
if (channel != null) {
ChannelBuffer response = ChannelBuffers.dynamicBuffer();
- response.writeByte(0x78); response.writeByte(0x78); // header
- response.writeByte(5); // size
+ if (extended) {
+ response.writeShort(0x7979);
+ response.writeShort(5);
+ } else {
+ response.writeShort(0x7878);
+ response.writeByte(5);
+ }
response.writeByte(type);
- response.writeShort(index);
- response.writeShort(Checksum.crc16(Checksum.CRC16_X25, response.toByteBuffer(2, 4)));
- response.writeByte(0x0D); response.writeByte(0x0A); // ending
+ response.writeShort(++serverIndex);
+ response.writeShort(Checksum.crc16(Checksum.CRC16_X25,
+ response.toByteBuffer(2, response.writerIndex() - 2)));
+ response.writeByte('\r'); response.writeByte('\n'); // ending
+ channel.write(response);
+ }
+ }
+
+ private void sendPhotoRequest(Channel channel, int pictureId) {
+ if (channel != null) {
+ ChannelBuffer photo = photos.get(pictureId);
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer();
+ response.writeShort(0x7878); // header
+ response.writeByte(15); // size
+ response.writeByte(MSG_X1_PHOTO_DATA);
+ response.writeInt(pictureId);
+ response.writeInt(photo.writerIndex());
+ response.writeShort(Math.min(photo.writableBytes(), 1024));
+ response.writeShort(++serverIndex);
+ response.writeShort(Checksum.crc16(Checksum.CRC16_X25,
+ response.toByteBuffer(2, response.writerIndex() - 2)));
+ response.writeByte('\r'); response.writeByte('\n'); // ending
channel.write(response);
}
}
- private void decodeGps(Position position, ChannelBuffer buf) {
+ private boolean decodeGps(Position position, ChannelBuffer buf, boolean hasLength) {
DateBuilder dateBuilder = new DateBuilder(timeZone)
.setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
.setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte());
position.setTime(dateBuilder.getDate());
+ if (hasLength && buf.readUnsignedByte() == 0) {
+ return false;
+ }
+
int length = buf.readUnsignedByte();
position.set(Position.KEY_SATELLITES, BitUtil.to(length, 4));
length = BitUtil.from(length, 4);
@@ -138,10 +178,14 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_IGNITION, BitUtil.check(flags, 15));
}
- buf.skipBytes(length - 12); // skip reserved
+ if (length > 0) {
+ buf.skipBytes(length - 12); // skip reserved
+ }
+
+ return true;
}
- private void decodeLbs(Position position, ChannelBuffer buf, boolean hasLength) {
+ private boolean decodeLbs(Position position, ChannelBuffer buf, boolean hasLength) {
int lbsLength = 0;
if (hasLength) {
@@ -154,9 +198,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
if (lbsLength > 0) {
buf.skipBytes(lbsLength - 9);
}
+
+ return true;
}
- private void decodeStatus(Position position, ChannelBuffer buf) {
+ private boolean decodeStatus(Position position, ChannelBuffer buf) {
int status = buf.readUnsignedByte();
@@ -185,6 +231,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_BATTERY, buf.readUnsignedByte());
position.set(Position.KEY_RSSI, buf.readUnsignedByte());
position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte()));
+
+ return true;
}
private String decodeAlarm(short value) {
@@ -266,12 +314,20 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
return position;
}
- protected Object decodeBasic(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception {
+ private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception {
int length = buf.readUnsignedByte();
int dataLength = length - 5;
int type = buf.readUnsignedByte();
+ DeviceSession deviceSession = null;
+ if (type != MSG_LOGIN) {
+ deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
+ }
+
if (type == MSG_LOGIN) {
String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1);
@@ -292,16 +348,45 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
}
if (getDeviceSession(channel, remoteAddress, imei) != null) {
- buf.skipBytes(buf.readableBytes() - 6);
- sendResponse(channel, type, buf.readUnsignedShort());
+ sendResponse(channel, false, type);
}
- } else {
+ } else if (type == MSG_X1_GPS) {
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
- if (deviceSession == null) {
- return null;
- }
+ Position position = new Position();
+ position.setDeviceId(deviceSession.getDeviceId());
+ position.setProtocol(getProtocolName());
+
+ buf.readUnsignedInt(); // data and alarm
+
+ decodeGps(position, buf, false);
+
+ buf.readUnsignedShort(); // terminal info
+
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedInt());
+
+ position.setNetwork(new Network(CellTower.from(
+ buf.readUnsignedShort(), buf.readUnsignedByte(),
+ buf.readUnsignedShort(), buf.readUnsignedInt())));
+
+ return position;
+
+ } else if (type == MSG_X1_PHOTO_INFO) {
+
+ buf.skipBytes(6); // time
+ buf.readUnsignedByte(); // fix status
+ buf.readUnsignedInt(); // latitude
+ buf.readUnsignedInt(); // longitude
+ buf.readUnsignedByte(); // camera id
+ buf.readUnsignedByte(); // photo source
+ buf.readUnsignedByte(); // picture format
+
+ ChannelBuffer photo = ChannelBuffers.buffer(buf.readInt());
+ int pictureId = buf.readInt();
+ photos.put(pictureId, photo);
+ sendPhotoRequest(channel, pictureId);
+
+ } else {
Position position = new Position();
position.setDeviceId(deviceSession.getDeviceId());
@@ -340,7 +425,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
} else if (isSupported(type)) {
if (hasGps(type)) {
- decodeGps(position, buf);
+ decodeGps(position, buf, false);
} else {
getLastLocation(position, null);
}
@@ -361,16 +446,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
buf.skipBytes(dataLength);
if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) {
- sendResponse(channel, type, buf.readUnsignedShort());
+ sendResponse(channel, false, type);
}
return null;
}
- if (buf.readableBytes() > 6) {
- buf.skipBytes(buf.readableBytes() - 6);
- }
- sendResponse(channel, type, buf.readUnsignedShort());
+ sendResponse(channel, false, type);
return position;
@@ -379,7 +461,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- protected Object decodeExtended(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception {
+ private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception {
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
if (deviceSession == null) {
@@ -431,6 +513,35 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
}
+ } else if (type == MSG_X1_PHOTO_DATA) {
+
+ int pictureId = buf.readInt();
+
+ ChannelBuffer photo = photos.get(pictureId);
+
+ buf.readUnsignedInt(); // offset
+ buf.readBytes(photo, buf.readUnsignedShort());
+
+ if (photo.writableBytes() > 0) {
+ sendPhotoRequest(channel, pictureId);
+ } else {
+ Device device = Context.getDeviceManager().getDeviceById(deviceSession.getDeviceId());
+ Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg");
+ photos.remove(pictureId);
+ }
+
+ } else if (type == MSG_AZ735_GPS || type == MSG_AZ735_ALARM) {
+
+ if (!decodeGps(position, buf, true)) {
+ getLastLocation(position, position.getDeviceTime());
+ }
+
+ decodeLbs(position, buf, true);
+
+ sendResponse(channel, true, type);
+
+ return position;
+
}
return null;
diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
index 11ecb5d72..38ecde519 100644
--- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
@@ -218,7 +218,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
if (parser.hasNext()) {
for (String temp : parser.next().split("\\|")) {
int index = Integer.valueOf(temp.substring(0, 2), 16);
- int value = Integer.valueOf(temp.substring(2), 16);
+ double value = Byte.valueOf(temp.substring(2, 4), 16);
+ value += (value < 0 ? -0.01 : 0.01) * Integer.valueOf(temp.substring(4), 16);
position.set(Position.PREFIX_TEMP + index, value);
}
}
diff --git a/src/org/traccar/protocol/Tk103Protocol.java b/src/org/traccar/protocol/Tk103Protocol.java
index 6fc00195e..07a68e2d8 100644
--- a/src/org/traccar/protocol/Tk103Protocol.java
+++ b/src/org/traccar/protocol/Tk103Protocol.java
@@ -1,4 +1,5 @@
/*
+ * Copyright 2017 Christoph Krey (c@ckrey.de)
* Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -32,6 +33,12 @@ public class Tk103Protocol extends BaseProtocol {
public Tk103Protocol() {
super("tk103");
setSupportedDataCommands(
+ Command.TYPE_POSITION_SINGLE,
+ Command.TYPE_POSITION_PERIODIC,
+ Command.TYPE_POSITION_STOP,
+ Command.TYPE_GET_VERSION,
+ Command.TYPE_REBOOT_DEVICE,
+ Command.TYPE_SET_ODOMETER,
Command.TYPE_ENGINE_STOP,
Command.TYPE_ENGINE_RESUME);
}
diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java
index baaa6c6fe..4c7da12e0 100644
--- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 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.
@@ -39,8 +39,8 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
private static final Pattern PATTERN = new PatternBuilder()
.number("(d+)(,)?") // device id
- .expression(".{4},?") // command
- .number("d*") // imei?
+ .expression("(.{4}),?") // command
+ .number("(d*)")
.number("(dd)(dd)(dd),?") // date (mmddyy if comma-delimited, otherwise yyddmm)
.expression("([AV]),?") // validity
.number("(d+)(dd.d+)") // latitude
@@ -97,19 +97,106 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
}
}
+ private void decodeType(Position position, String type, String data) {
+ switch (type) {
+ case "BO01":
+ position.set(Position.KEY_ALARM, decodeAlarm(data.charAt(0) - '0'));
+ break;
+ case "ZC11":
+ position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT);
+ break;
+ case "ZC12":
+ position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY);
+ break;
+ case "ZC13":
+ position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT);
+ break;
+ case "ZC15":
+ position.set(Position.KEY_IGNITION, true);
+ break;
+ case "ZC16":
+ position.set(Position.KEY_IGNITION, false);
+ break;
+ case "ZC17":
+ position.set(Position.KEY_ALARM, Position.ALARM_REMOVING);
+ break;
+ case "ZC25":
+ position.set(Position.KEY_ALARM, Position.ALARM_SOS);
+ break;
+ case "ZC26":
+ position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING);
+ break;
+ case "ZC27":
+ position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private Position decodeBattery(Channel channel, SocketAddress remoteAddress, String sentence) {
+ Parser parser = new Parser(PATTERN_BATTERY, 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));
+
+ int battery = parser.nextInt(0);
+ if (battery != 65535) {
+ position.set(Position.KEY_BATTERY, battery * 0.01);
+ }
+
+ int power = parser.nextInt(0);
+ if (power != 65535) {
+ position.set(Position.KEY_POWER, power * 0.1);
+ }
+
+ return position;
+ }
+
+ private Position decodeNetwork(Channel channel, SocketAddress remoteAddress, String sentence) {
+ Parser parser = new Parser(PATTERN_NETWORK, 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, null);
+
+ position.setNetwork(new Network(CellTower.from(
+ parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0))));
+
+ return position;
+ }
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
String sentence = (String) msg;
- // Find message start
int beginIndex = sentence.indexOf('(');
if (beginIndex != -1) {
sentence = sentence.substring(beginIndex + 1);
}
- // Send response
if (channel != null) {
String id = sentence.substring(0, 12);
String type = sentence.substring(12, 16);
@@ -127,49 +214,13 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
}
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
-
- Parser parser = new Parser(PATTERN_BATTERY, sentence);
- if (parser.matches()) {
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession == null) {
- return null;
- }
- position.setDeviceId(deviceSession.getDeviceId());
-
- getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
-
- int battery = parser.nextInt(0);
- if (battery != 65535) {
- position.set(Position.KEY_BATTERY, battery * 0.01);
- }
-
- int power = parser.nextInt(0);
- if (power != 65535) {
- position.set(Position.KEY_POWER, power * 0.1);
- }
-
- return position;
- }
-
- parser = new Parser(PATTERN_NETWORK, sentence);
- if (parser.matches()) {
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession == null) {
- return null;
- }
- position.setDeviceId(deviceSession.getDeviceId());
-
- getLastLocation(position, null);
-
- position.setNetwork(new Network(CellTower.from(
- parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0))));
-
- return position;
+ if (sentence.contains("ZC20")) {
+ return decodeBattery(channel, remoteAddress, sentence);
+ } else if (sentence.contains("BZ00")) {
+ return decodeNetwork(channel, remoteAddress, sentence);
}
- parser = new Parser(PATTERN, sentence);
+ Parser parser = new Parser(PATTERN, sentence);
if (!parser.matches()) {
return null;
}
@@ -178,18 +229,20 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
if (deviceSession == null) {
return null;
}
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- int alarm = sentence.indexOf("BO01");
- if (alarm != -1) {
- position.set(Position.KEY_ALARM, decodeAlarm(Integer.parseInt(sentence.substring(alarm + 4, alarm + 5))));
- }
+ boolean alternative = parser.next() != null;
+
+ decodeType(position, parser.next(), parser.next());
DateBuilder dateBuilder = new DateBuilder();
- if (parser.next() == null) {
- dateBuilder.setDate(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
- } else {
+ if (alternative) {
dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
+ } else {
+ dateBuilder.setDate(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
}
position.setValid(parser.next().equals("A"));
diff --git a/src/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/org/traccar/protocol/Tk103ProtocolEncoder.java
index ce995a65f..9e49b6ff1 100644
--- a/src/org/traccar/protocol/Tk103ProtocolEncoder.java
+++ b/src/org/traccar/protocol/Tk103ProtocolEncoder.java
@@ -1,4 +1,5 @@
/*
+ * Copyright 2017 Christoph Krey (c@ckrey.de)
* Copyright 2017 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,6 +26,19 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder {
protected Object encodeCommand(Command command) {
switch (command.getType()) {
+ case Command.TYPE_GET_VERSION:
+ return formatCommand(command, "({%s}AP07)", Command.KEY_UNIQUE_ID);
+ case Command.TYPE_REBOOT_DEVICE:
+ return 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);
+ case Command.TYPE_POSITION_PERIODIC:
+ return 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);
case Command.TYPE_ENGINE_STOP:
return formatCommand(command, "({%s}AV011)", Command.KEY_UNIQUE_ID);
case Command.TYPE_ENGINE_RESUME:
diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java
index d0c066954..57f5d7e78 100644
--- a/src/org/traccar/protocol/WatchProtocolDecoder.java
+++ b/src/org/traccar/protocol/WatchProtocolDecoder.java
@@ -222,15 +222,20 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
} else if (type.equals("PULSE") || type.equals("heart")) {
if (buf.readable()) {
+
Position position = new Position();
position.setProtocol(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
+
getLastLocation(position, new Date());
+
position.setValid(false);
String pulse = buf.toString(StandardCharsets.US_ASCII);
position.set("pulse", pulse);
position.set(Position.KEY_RESULT, pulse);
+
return position;
+
}
} else if (type.equals("img")) {
@@ -247,6 +252,18 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
return position;
+ } else if (type.equals("TK")) {
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ getLastLocation(position, null);
+
+ position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, buf, "amr"));
+
+ return position;
+
}
return null;
diff --git a/src/org/traccar/smpp/EnquireLinkTask.java b/src/org/traccar/smpp/EnquireLinkTask.java
index 9a3121e24..affb712b3 100644
--- a/src/org/traccar/smpp/EnquireLinkTask.java
+++ b/src/org/traccar/smpp/EnquireLinkTask.java
@@ -44,7 +44,7 @@ public class EnquireLinkTask implements Runnable {
} catch (SmppTimeoutException | SmppChannelException
| RecoverablePduException | UnrecoverablePduException error) {
Log.warning("Enquire link failed, executing reconnect: ", error);
- smppClient.reconnect();
+ smppClient.scheduleReconnect();
} catch (InterruptedException error) {
Log.info("Enquire link interrupted, probably killed by reconnecting");
}