aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol
diff options
context:
space:
mode:
authorChristoph Krey <c@ckrey.de>2018-04-16 10:45:11 +0200
committerGitHub <noreply@github.com>2018-04-16 10:45:11 +0200
commit3a602dd133b533cc69d5986d64a00fb3ed670f75 (patch)
tree97ff753db310a49ae7e53240b1db07fb8475679e /src/org/traccar/protocol
parent232de5f0daef98f31b28d177d991fdbfa191f195 (diff)
parent6d4b8df25c7e942b9ad594db9444fe15bcb16be9 (diff)
downloadtrackermap-server-3a602dd133b533cc69d5986d64a00fb3ed670f75.tar.gz
trackermap-server-3a602dd133b533cc69d5986d64a00fb3ed670f75.tar.bz2
trackermap-server-3a602dd133b533cc69d5986d64a00fb3ed670f75.zip
Merge pull request #4 from traccar/master
upgrade to current master
Diffstat (limited to 'src/org/traccar/protocol')
-rw-r--r--src/org/traccar/protocol/AdmProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/AisProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/AlematicsProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/ApelProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/AplicomProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/AppelloProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/AquilaProtocolDecoder.java152
-rw-r--r--src/org/traccar/protocol/Ardi01ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/ArknavProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/ArknavX8ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/ArnaviProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/AstraProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/At2000ProtocolDecoder.java7
-rw-r--r--src/org/traccar/protocol/AtrackProtocolDecoder.java23
-rw-r--r--src/org/traccar/protocol/AuroProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/AutoFonProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/AutoGradeProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Avl301ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/BceProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/BlackKiteProtocolDecoder.java5
-rw-r--r--src/org/traccar/protocol/BoxProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/CalAmpProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/CarTrackProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/CarcellProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/CarscopProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/CastelProtocol.java8
-rw-r--r--src/org/traccar/protocol/CastelProtocolDecoder.java83
-rw-r--r--src/org/traccar/protocol/CastelProtocolEncoder.java73
-rw-r--r--src/org/traccar/protocol/CautelaProtocol.java47
-rw-r--r--src/org/traccar/protocol/CautelaProtocolDecoder.java77
-rw-r--r--src/org/traccar/protocol/CellocatorProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/CguardProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/CityeasyProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/ContinentalProtocol.java43
-rw-r--r--src/org/traccar/protocol/ContinentalProtocolDecoder.java113
-rw-r--r--src/org/traccar/protocol/CradlepointProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/DishaProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/DmtHttpProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/DmtProtocolDecoder.java288
-rw-r--r--src/org/traccar/protocol/DwayProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/EasyTrackProtocolDecoder.java35
-rw-r--r--src/org/traccar/protocol/EelinkProtocolDecoder.java12
-rw-r--r--src/org/traccar/protocol/EelinkProtocolEncoder.java4
-rw-r--r--src/org/traccar/protocol/EgtsFrameDecoder.java45
-rw-r--r--src/org/traccar/protocol/EgtsProtocol.java45
-rw-r--r--src/org/traccar/protocol/EgtsProtocolDecoder.java256
-rw-r--r--src/org/traccar/protocol/EnforaProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/EskyProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/ExtremTracProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/FifotrackProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/FlespiProtocolDecoder.java5
-rw-r--r--src/org/traccar/protocol/FlexCommProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/FlextrackProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/FoxProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/FreedomProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/GalileoProtocolDecoder.java24
-rw-r--r--src/org/traccar/protocol/GatorProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/GenxProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Gl100ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java12
-rw-r--r--src/org/traccar/protocol/Gl200TextProtocolDecoder.java171
-rw-r--r--src/org/traccar/protocol/GlobalSatProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/GlobeKeeperProtocol.java45
-rw-r--r--src/org/traccar/protocol/GlobeKeeperProtocolDecoder.java69
-rw-r--r--src/org/traccar/protocol/GnxProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/GoSafeProtocolDecoder.java256
-rw-r--r--src/org/traccar/protocol/GotopProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Gps056ProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/Gps103ProtocolDecoder.java234
-rw-r--r--src/org/traccar/protocol/GpsGateProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/GpsMarkerProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/GpsmtaProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/GranitProtocolDecoder.java9
-rw-r--r--src/org/traccar/protocol/Gt02ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Gt06ProtocolDecoder.java85
-rw-r--r--src/org/traccar/protocol/Gt30ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/H02ProtocolDecoder.java17
-rw-r--r--src/org/traccar/protocol/HaicomProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/HomtecsProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/HuaShengProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/HuabaoProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/HuabaoProtocolEncoder.java6
-rw-r--r--src/org/traccar/protocol/HunterProProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/IdplProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/IntellitracProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Ivt401ProtocolDecoder.java103
-rw-r--r--src/org/traccar/protocol/JpKorjarProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Jt600ProtocolDecoder.java9
-rw-r--r--src/org/traccar/protocol/KenjiProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/KhdProtocolDecoder.java16
-rw-r--r--src/org/traccar/protocol/KhdProtocolEncoder.java17
-rw-r--r--src/org/traccar/protocol/L100ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/LaipacProtocolDecoder.java86
-rw-r--r--src/org/traccar/protocol/M2cProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/M2mProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/MaestroProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/ManPowerProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/MegastekProtocolDecoder.java12
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolEncoder.java4
-rw-r--r--src/org/traccar/protocol/MeitrackProtocolDecoder.java41
-rw-r--r--src/org/traccar/protocol/MeitrackProtocolEncoder.java5
-rw-r--r--src/org/traccar/protocol/MiniFinderProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/MiniFinderProtocolEncoder.java36
-rw-r--r--src/org/traccar/protocol/Mta6ProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/MtxProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/MxtProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/NavigilProtocolDecoder.java18
-rw-r--r--src/org/traccar/protocol/NavisProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/NoranProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/NvsProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/ObdDongleProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/OigoProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/OkoProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/OpenGtsProtocol.java45
-rw-r--r--src/org/traccar/protocol/OpenGtsProtocolDecoder.java115
-rw-r--r--src/org/traccar/protocol/OrionProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/OsmAndProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/OwnTracksProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/PathAwayProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/PiligrimProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/PretraceProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/PricolProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/ProgressProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Pt3000ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Pt502FrameDecoder.java47
-rw-r--r--src/org/traccar/protocol/Pt502Protocol.java4
-rw-r--r--src/org/traccar/protocol/Pt502ProtocolDecoder.java94
-rw-r--r--src/org/traccar/protocol/Pt60Protocol.java47
-rw-r--r--src/org/traccar/protocol/Pt60ProtocolDecoder.java83
-rw-r--r--src/org/traccar/protocol/RaveonProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/RecodaProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/RitiProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/RoboTrackFrameDecoder.java57
-rw-r--r--src/org/traccar/protocol/RoboTrackProtocol.java45
-rw-r--r--src/org/traccar/protocol/RoboTrackProtocolDecoder.java130
-rw-r--r--src/org/traccar/protocol/RuptelaProtocolDecoder.java15
-rw-r--r--src/org/traccar/protocol/SanavProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/SigfoxProtocolDecoder.java7
-rw-r--r--src/org/traccar/protocol/SiwiProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/SkypatrolProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/SmokeyProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/SpotProtocolDecoder.java5
-rw-r--r--src/org/traccar/protocol/StarLinkProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Stl060ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/SuntechProtocolDecoder.java24
-rw-r--r--src/org/traccar/protocol/SupermateProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/T55ProtocolDecoder.java20
-rw-r--r--src/org/traccar/protocol/T57ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/T800xProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/T800xProtocolEncoder.java4
-rw-r--r--src/org/traccar/protocol/TaipProtocolDecoder.java93
-rw-r--r--src/org/traccar/protocol/TelicProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TeltonikaProtocolDecoder.java13
-rw-r--r--src/org/traccar/protocol/ThinkRaceProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Tk102ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Tk103Protocol.java3
-rw-r--r--src/org/traccar/protocol/Tk103ProtocolDecoder.java15
-rw-r--r--src/org/traccar/protocol/Tk103ProtocolEncoder.java2
-rw-r--r--src/org/traccar/protocol/Tlt2hProtocolDecoder.java44
-rw-r--r--src/org/traccar/protocol/TlvProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TmgFrameDecoder.java7
-rw-r--r--src/org/traccar/protocol/TmgProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TopflytechProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TotemProtocolDecoder.java74
-rw-r--r--src/org/traccar/protocol/Tr20ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Tr900ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TrackboxProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TrakMateProtocolDecoder.java16
-rw-r--r--src/org/traccar/protocol/TramigoProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TrvProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/Tt8850ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TytanProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TzoneProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/UlbotechProtocolDecoder.java18
-rw-r--r--src/org/traccar/protocol/UproProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/V680ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/VisiontekProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Vt200ProtocolDecoder.java8
-rw-r--r--src/org/traccar/protocol/VtfmsProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/WatchFrameDecoder.java89
-rw-r--r--src/org/traccar/protocol/WatchProtocolDecoder.java155
-rw-r--r--src/org/traccar/protocol/WatchProtocolEncoder.java58
-rw-r--r--src/org/traccar/protocol/WialonProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/WondexProtocolDecoder.java10
-rw-r--r--src/org/traccar/protocol/XexunProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/XirgoProtocolDecoder.java72
-rw-r--r--src/org/traccar/protocol/Xt013ProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/Xt2400ProtocolDecoder.java9
-rw-r--r--src/org/traccar/protocol/YwtProtocolDecoder.java3
190 files changed, 3188 insertions, 1220 deletions
diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java
index f93c55e18..4ae16017a 100644
--- a/src/org/traccar/protocol/AdmProtocolDecoder.java
+++ b/src/org/traccar/protocol/AdmProtocolDecoder.java
@@ -46,8 +46,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder {
}
if (BitUtil.to(type, 2) == 0) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte());
@@ -124,8 +123,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
diff --git a/src/org/traccar/protocol/AisProtocolDecoder.java b/src/org/traccar/protocol/AisProtocolDecoder.java
index 1f7a12595..842260e98 100644
--- a/src/org/traccar/protocol/AisProtocolDecoder.java
+++ b/src/org/traccar/protocol/AisProtocolDecoder.java
@@ -61,8 +61,7 @@ public class AisProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date());
diff --git a/src/org/traccar/protocol/AlematicsProtocolDecoder.java b/src/org/traccar/protocol/AlematicsProtocolDecoder.java
index da0704242..b83081cc1 100644
--- a/src/org/traccar/protocol/AlematicsProtocolDecoder.java
+++ b/src/org/traccar/protocol/AlematicsProtocolDecoder.java
@@ -113,8 +113,7 @@ public class AlematicsProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_TYPE, parser.nextInt());
position.set(Position.KEY_INDEX, parser.nextInt());
diff --git a/src/org/traccar/protocol/ApelProtocolDecoder.java b/src/org/traccar/protocol/ApelProtocolDecoder.java
index 6e16e02be..a107f7d6f 100644
--- a/src/org/traccar/protocol/ApelProtocolDecoder.java
+++ b/src/org/traccar/protocol/ApelProtocolDecoder.java
@@ -136,8 +136,7 @@ public class ApelProtocolDecoder extends BaseProtocolDecoder {
}
for (int j = 0; j < recordCount; j++) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
int subtype = type;
diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java
index c1d7ab087..7ed187937 100644
--- a/src/org/traccar/protocol/AplicomProtocolDecoder.java
+++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java
@@ -608,8 +608,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
selector = buf.readUnsignedMedium();
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
if (deviceSession == null) {
return null;
diff --git a/src/org/traccar/protocol/AppelloProtocolDecoder.java b/src/org/traccar/protocol/AppelloProtocolDecoder.java
index 30dec3941..bf95b4068 100644
--- a/src/org/traccar/protocol/AppelloProtocolDecoder.java
+++ b/src/org/traccar/protocol/AppelloProtocolDecoder.java
@@ -65,8 +65,7 @@ public class AppelloProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (parser.hasNext(6)) {
diff --git a/src/org/traccar/protocol/AquilaProtocolDecoder.java b/src/org/traccar/protocol/AquilaProtocolDecoder.java
index 773210b04..960139b3f 100644
--- a/src/org/traccar/protocol/AquilaProtocolDecoder.java
+++ b/src/org/traccar/protocol/AquilaProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -21,6 +21,8 @@ import org.traccar.DeviceSession;
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;
import org.traccar.model.Position;
import java.net.SocketAddress;
@@ -32,7 +34,7 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
- private static final Pattern PATTERN = new PatternBuilder()
+ private static final Pattern PATTERN_A = new PatternBuilder()
.text("$$")
.expression("[^,]*,") // client
.number("(d+),") // device serial number
@@ -42,6 +44,7 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
.number("(dd)(dd)(dd)") // date (yymmdd)
.number("(dd)(dd)(dd),") // time (hhmmss)
.expression("([AV]),") // validity
+ .groupBegin()
.number("(d+),") // gsm
.number("(d+),") // speed
.number("(d+),") // distance
@@ -120,15 +123,17 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
.number("(d+),") // external voltage
.number("(d+),") // internal voltage
.groupEnd()
+ .or()
+ .number("(d+),") // sensor id
+ .expression("([^,]+),") // sensor data
+ .groupEnd()
.text("*")
.number("xx") // checksum
.compile();
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ private Position decodeA(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN, (String) msg);
+ Parser parser = new Parser(PATTERN_A, sentence);
if (!parser.matches()) {
return null;
}
@@ -138,8 +143,7 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_EVENT, parser.nextInt(0));
@@ -151,11 +155,11 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
position.setValid(parser.next().equals("A"));
- position.set(Position.KEY_RSSI, parser.nextInt(0));
-
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
-
- position.set(Position.KEY_ODOMETER, parser.nextInt(0));
+ if (parser.hasNext(3)) {
+ position.set(Position.KEY_RSSI, parser.nextInt(0));
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
+ position.set(Position.KEY_ODOMETER, parser.nextInt(0));
+ }
if (parser.hasNext(9)) {
@@ -187,7 +191,7 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
String dtcs = parser.next();
position.set(Position.KEY_DTCS, dtcs.substring(1, dtcs.length() - 1).replace('|', ' '));
- } else {
+ } else if (parser.hasNext(10)) {
position.setCourse(parser.nextInt(0));
@@ -201,9 +205,129 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_POWER, parser.nextInt(0));
position.set(Position.KEY_BATTERY, parser.nextInt(0));
+ } else if (parser.hasNext(2)) {
+
+ position.set("sensorId", parser.nextInt());
+ position.set("sensorData", parser.next());
+
+ }
+
+ return position;
+ }
+
+ private static final Pattern PATTERN_B = new PatternBuilder()
+ .text("$Header,")
+ .expression("[^,]+,") // client
+ .expression("[^,]+,") // firmware version
+ .expression(".{2},") // type
+ .number("d+,") // message id
+ .expression("[LH],") // status
+ .number("(d+),") // imei
+ .expression("[^,]+,") // registration number
+ .number("([01]),") // validity
+ .number("(dd)(dd)(dddd),") // date (ddmmyyyy)
+ .number("(dd)(dd)(dd),") // time (hhmmss)
+ .number("(-?d+.d+),") // latitude
+ .expression("([NS]),")
+ .number("(-?d+.d+),") // longitude
+ .expression("([EW]),")
+ .number("(d+.d+),") // speed
+ .number("(d+),") // course
+ .number("(d+),") // satellites
+ .number("(-?d+.d+),") // altitude
+ .number("(d+.d+),") // pdop
+ .number("(d+.d+),") // hdop
+ .expression("[^,]+,") // operator
+ .number("([01]),") // ignition
+ .number("([01]),") // charge
+ .number("(d+.d+),") // power
+ .number("(d+.d+),") // battery
+ .number("[01],") // emergency
+ .expression("[CO],") // tamper
+ .number("(d+),") // rssi
+ .number("(d+),") // mcc
+ .number("(d+),") // mnc
+ .number("(x+),") // lac
+ .number("(x+),") // cid
+ .number("(d+),(x+),(x+),") // cell 1
+ .number("(d+),(x+),(x+),") // cell 2
+ .number("(d+),(x+),(x+),") // cell 3
+ .number("(d+),(x+),(x+),") // cell 4
+ .number("([01])+,") // inputs
+ .number("([01])+,") // outputs
+ .number("d+,") // frame number
+ .number("(d+.d+),") // adc1
+ .number("(d+.d+),") // adc2
+ .number("d+,") // delta distance
+ .any()
+ .compile();
+
+ private Position decodeB(Channel channel, SocketAddress remoteAddress, String sentence) {
+
+ Parser parser = new Parser(PATTERN_B, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setValid(parser.nextInt() == 1);
+ position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
+ position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
+ position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble()));
+ position.setCourse(parser.nextInt());
+
+ position.set(Position.KEY_SATELLITES, parser.nextInt());
+
+ position.setAltitude(parser.nextDouble());
+
+ position.set(Position.KEY_PDOP, parser.nextDouble());
+ position.set(Position.KEY_HDOP, parser.nextDouble());
+ position.set(Position.KEY_IGNITION, parser.nextInt() == 1);
+ position.set(Position.KEY_CHARGE, parser.nextInt() == 1);
+ position.set(Position.KEY_POWER, parser.nextDouble());
+ position.set(Position.KEY_BATTERY, parser.nextDouble());
+
+ Network network = new Network();
+
+ int rssi = parser.nextInt();
+ int mcc = parser.nextInt();
+ int mnc = parser.nextInt();
+
+ network.addCellTower(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt(), rssi));
+ for (int i = 0; i < 4; i++) {
+ rssi = parser.nextInt();
+ network.addCellTower(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt(), rssi));
}
+ position.setNetwork(network);
+
+ position.set(Position.KEY_INPUT, parser.nextBinInt());
+ position.set(Position.KEY_OUTPUT, parser.nextBinInt());
+ position.set(Position.PREFIX_ADC + 1, parser.nextDouble());
+ position.set(Position.PREFIX_ADC + 2, parser.nextDouble());
+
return position;
}
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ String sentence = (String) msg;
+
+ if (sentence.startsWith("$$")) {
+ return decodeA(channel, remoteAddress, sentence);
+ } else {
+ return decodeB(channel, remoteAddress, sentence);
+ }
+ }
+
}
diff --git a/src/org/traccar/protocol/Ardi01ProtocolDecoder.java b/src/org/traccar/protocol/Ardi01ProtocolDecoder.java
index 7a5bd217c..dea9e3483 100644
--- a/src/org/traccar/protocol/Ardi01ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Ardi01ProtocolDecoder.java
@@ -56,8 +56,7 @@ public class Ardi01ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/ArknavProtocolDecoder.java b/src/org/traccar/protocol/ArknavProtocolDecoder.java
index 927c50c29..aeea4a734 100644
--- a/src/org/traccar/protocol/ArknavProtocolDecoder.java
+++ b/src/org/traccar/protocol/ArknavProtocolDecoder.java
@@ -58,8 +58,7 @@ public class ArknavProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java b/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java
index 8a80901b5..47cc267fe 100644
--- a/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java
+++ b/src/org/traccar/protocol/ArknavX8ProtocolDecoder.java
@@ -65,8 +65,7 @@ public class ArknavX8ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_TYPE, parser.next());
diff --git a/src/org/traccar/protocol/ArnaviProtocolDecoder.java b/src/org/traccar/protocol/ArnaviProtocolDecoder.java
index 9c4ab5d05..ec96343fe 100644
--- a/src/org/traccar/protocol/ArnaviProtocolDecoder.java
+++ b/src/org/traccar/protocol/ArnaviProtocolDecoder.java
@@ -65,8 +65,7 @@ public class ArnaviProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/AstraProtocolDecoder.java b/src/org/traccar/protocol/AstraProtocolDecoder.java
index 8d86cd2be..79c7eba3f 100644
--- a/src/org/traccar/protocol/AstraProtocolDecoder.java
+++ b/src/org/traccar/protocol/AstraProtocolDecoder.java
@@ -63,8 +63,7 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder {
while (buf.readableBytes() > 2) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
buf.readUnsignedByte(); // index
diff --git a/src/org/traccar/protocol/At2000ProtocolDecoder.java b/src/org/traccar/protocol/At2000ProtocolDecoder.java
index 70840c37d..e0f2b4278 100644
--- a/src/org/traccar/protocol/At2000ProtocolDecoder.java
+++ b/src/org/traccar/protocol/At2000ProtocolDecoder.java
@@ -20,13 +20,13 @@ import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
+import org.traccar.helper.DataConverter;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
-import javax.xml.bind.DatatypeConverter;
import java.net.SocketAddress;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
@@ -84,7 +84,7 @@ public class At2000ProtocolDecoder extends BaseProtocolDecoder {
IvParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKeySpec keySpec = new SecretKeySpec(
- DatatypeConverter.parseHexBinary("000102030405060708090a0b0c0d0e0f"), "AES");
+ DataConverter.parseHex("000102030405060708090a0b0c0d0e0f"), "AES");
cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
@@ -114,8 +114,7 @@ public class At2000ProtocolDecoder extends BaseProtocolDecoder {
while (buf.readableBytes() >= 63) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
buf.readUnsignedShort(); // index
diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java
index 23cb67e15..8138f0fcb 100644
--- a/src/org/traccar/protocol/AtrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2018 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.
@@ -36,6 +36,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AtrackProtocolDecoder extends BaseProtocolDecoder {
@@ -43,6 +44,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
private static final int MIN_DATA_LENGTH = 40;
private boolean longDate;
+ private boolean decimalFuel;
private boolean custom;
private String form;
@@ -52,6 +54,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
longDate = Context.getConfig().getBoolean(getProtocolName() + ".longDate");
+ decimalFuel = Context.getConfig().getBoolean(getProtocolName() + ".decimalFuel");
custom = Context.getConfig().getBoolean(getProtocolName() + ".custom");
form = Context.getConfig().getString(getProtocolName() + ".form");
@@ -217,8 +220,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
.compile();
private Position decodeString(Channel channel, SocketAddress remoteAddress, String sentence) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
getLastLocation(position, null);
@@ -288,8 +290,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
while (buf.readableBytes() >= MIN_DATA_LENGTH) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (longDate) {
@@ -332,7 +333,17 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_TEMP + 1, buf.readShort() * 0.1);
position.set(Position.PREFIX_TEMP + 2, buf.readShort() * 0.1);
- position.set("message", readString(buf));
+ String message = readString(buf);
+ if (message != null && !message.isEmpty()) {
+ Pattern pattern = Pattern.compile("FULS:F=(\\p{XDigit}+) t=(\\p{XDigit}+) N=(\\p{XDigit}+)");
+ Matcher matcher = pattern.matcher(message);
+ if (matcher.find()) {
+ int value = Integer.parseInt(matcher.group(3), decimalFuel ? 10 : 16);
+ position.set(Position.KEY_FUEL_LEVEL, value * 0.1);
+ } else {
+ position.set("message", message);
+ }
+ }
if (custom) {
String form = this.form;
diff --git a/src/org/traccar/protocol/AuroProtocolDecoder.java b/src/org/traccar/protocol/AuroProtocolDecoder.java
index a45d14709..3cb3a440c 100644
--- a/src/org/traccar/protocol/AuroProtocolDecoder.java
+++ b/src/org/traccar/protocol/AuroProtocolDecoder.java
@@ -62,8 +62,7 @@ public class AuroProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_INDEX, parser.nextInt(0));
diff --git a/src/org/traccar/protocol/AutoFonProtocolDecoder.java b/src/org/traccar/protocol/AutoFonProtocolDecoder.java
index 32b4bfa74..e243b93ea 100644
--- a/src/org/traccar/protocol/AutoFonProtocolDecoder.java
+++ b/src/org/traccar/protocol/AutoFonProtocolDecoder.java
@@ -62,8 +62,7 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder {
private Position decodePosition(DeviceSession deviceSession, ChannelBuffer buf, boolean history) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (!history) {
@@ -167,8 +166,7 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder {
} else if (type == MSG_45_LOCATION) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
short status = buf.readUnsignedByte();
diff --git a/src/org/traccar/protocol/AutoGradeProtocolDecoder.java b/src/org/traccar/protocol/AutoGradeProtocolDecoder.java
index 753509f31..b98c68cbd 100644
--- a/src/org/traccar/protocol/AutoGradeProtocolDecoder.java
+++ b/src/org/traccar/protocol/AutoGradeProtocolDecoder.java
@@ -72,8 +72,7 @@ public class AutoGradeProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
diff --git a/src/org/traccar/protocol/Avl301ProtocolDecoder.java b/src/org/traccar/protocol/Avl301ProtocolDecoder.java
index cc61be91b..056395d35 100644
--- a/src/org/traccar/protocol/Avl301ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Avl301ProtocolDecoder.java
@@ -88,9 +88,8 @@ public class Avl301ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
DateBuilder dateBuilder = new DateBuilder()
.setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
diff --git a/src/org/traccar/protocol/BceProtocolDecoder.java b/src/org/traccar/protocol/BceProtocolDecoder.java
index b472ac6c9..a023e60c5 100644
--- a/src/org/traccar/protocol/BceProtocolDecoder.java
+++ b/src/org/traccar/protocol/BceProtocolDecoder.java
@@ -21,6 +21,7 @@ import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
import org.traccar.helper.BitUtil;
+import org.traccar.helper.UnitsConverter;
import org.traccar.model.CellTower;
import org.traccar.model.Network;
import org.traccar.model.Position;
@@ -67,8 +68,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
while (buf.readerIndex() < dataEnd) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
int structEnd = buf.readUnsignedByte() + buf.readerIndex();
@@ -94,7 +94,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
position.setValid(true);
position.setLongitude(buf.readFloat());
position.setLatitude(buf.readFloat());
- position.setSpeed(buf.readUnsignedByte());
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
int gps = buf.readUnsignedByte();
position.set(Position.KEY_SATELLITES, gps & 0xf);
diff --git a/src/org/traccar/protocol/BlackKiteProtocolDecoder.java b/src/org/traccar/protocol/BlackKiteProtocolDecoder.java
index 561d7c18b..7fc39fc7c 100644
--- a/src/org/traccar/protocol/BlackKiteProtocolDecoder.java
+++ b/src/org/traccar/protocol/BlackKiteProtocolDecoder.java
@@ -76,8 +76,7 @@ public class BlackKiteProtocolDecoder extends BaseProtocolDecoder {
List<Position> positions = new LinkedList<>();
Set<Integer> tags = new HashSet<>();
boolean hasLocation = false;
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
while (buf.readerIndex() < length) {
@@ -89,7 +88,7 @@ public class BlackKiteProtocolDecoder extends BaseProtocolDecoder {
}
tags.clear();
hasLocation = false;
- position = new Position();
+ position = new Position(getProtocolName());
}
tags.add(tag);
diff --git a/src/org/traccar/protocol/BoxProtocolDecoder.java b/src/org/traccar/protocol/BoxProtocolDecoder.java
index 562731657..63238bcef 100644
--- a/src/org/traccar/protocol/BoxProtocolDecoder.java
+++ b/src/org/traccar/protocol/BoxProtocolDecoder.java
@@ -77,9 +77,8 @@ public class BoxProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
position.setTime(parser.nextDateTime());
diff --git a/src/org/traccar/protocol/CalAmpProtocolDecoder.java b/src/org/traccar/protocol/CalAmpProtocolDecoder.java
index 557e2d6e6..f717d3c5d 100644
--- a/src/org/traccar/protocol/CalAmpProtocolDecoder.java
+++ b/src/org/traccar/protocol/CalAmpProtocolDecoder.java
@@ -66,9 +66,8 @@ public class CalAmpProtocolDecoder extends BaseProtocolDecoder {
private Position decodePosition(DeviceSession deviceSession, int type, ChannelBuffer buf) {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
position.setTime(new Date(buf.readUnsignedInt() * 1000));
if (type != MSG_MINI_EVENT_REPORT) {
diff --git a/src/org/traccar/protocol/CarTrackProtocolDecoder.java b/src/org/traccar/protocol/CarTrackProtocolDecoder.java
index 3064bbb35..94215379d 100644
--- a/src/org/traccar/protocol/CarTrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/CarTrackProtocolDecoder.java
@@ -65,8 +65,7 @@ public class CarTrackProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/CarcellProtocolDecoder.java b/src/org/traccar/protocol/CarcellProtocolDecoder.java
index fc5710f09..52b777b81 100644
--- a/src/org/traccar/protocol/CarcellProtocolDecoder.java
+++ b/src/org/traccar/protocol/CarcellProtocolDecoder.java
@@ -85,8 +85,7 @@ public class CarcellProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_ARCHIVE, parser.next().equals("%"));
position.setValid(true);
diff --git a/src/org/traccar/protocol/CarscopProtocolDecoder.java b/src/org/traccar/protocol/CarscopProtocolDecoder.java
index 2a081bcdd..7f9dcc3b7 100644
--- a/src/org/traccar/protocol/CarscopProtocolDecoder.java
+++ b/src/org/traccar/protocol/CarscopProtocolDecoder.java
@@ -73,9 +73,8 @@ public class CarscopProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
DateBuilder dateBuilder = new DateBuilder()
.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
diff --git a/src/org/traccar/protocol/CastelProtocol.java b/src/org/traccar/protocol/CastelProtocol.java
index db9df0674..d5ba5cd55 100644
--- a/src/org/traccar/protocol/CastelProtocol.java
+++ b/src/org/traccar/protocol/CastelProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -21,6 +21,7 @@ import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
+import org.traccar.model.Command;
import java.nio.ByteOrder;
import java.util.List;
@@ -29,6 +30,9 @@ public class CastelProtocol extends BaseProtocol {
public CastelProtocol() {
super("castel");
+ setSupportedDataCommands(
+ Command.TYPE_ENGINE_STOP,
+ Command.TYPE_ENGINE_RESUME);
}
@Override
@@ -37,6 +41,7 @@ public class CastelProtocol extends BaseProtocol {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0));
+ pipeline.addLast("objectEncoder", new CastelProtocolEncoder());
pipeline.addLast("objectDecoder", new CastelProtocolDecoder(CastelProtocol.this));
}
};
@@ -46,6 +51,7 @@ public class CastelProtocol extends BaseProtocol {
server = new TrackerServer(new ConnectionlessBootstrap(), getName()) {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("objectEncoder", new CastelProtocolEncoder());
pipeline.addLast("objectDecoder", new CastelProtocolDecoder(CastelProtocol.this));
}
};
diff --git a/src/org/traccar/protocol/CastelProtocolDecoder.java b/src/org/traccar/protocol/CastelProtocolDecoder.java
index 5eedc69f9..44a5e213c 100644
--- a/src/org/traccar/protocol/CastelProtocolDecoder.java
+++ b/src/org/traccar/protocol/CastelProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -96,12 +96,12 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder {
public static final short MSG_CC_LOGIN = 0x4001;
public static final short MSG_CC_LOGIN_RESPONSE = (short) 0x8001;
public static final short MSG_CC_HEARTBEAT = 0x4206;
+ public static final short MSG_CC_PETROL_CONTROL = 0x4583;
public static final short MSG_CC_HEARTBEAT_RESPONSE = (short) 0x8206;
private Position readPosition(DeviceSession deviceSession, ChannelBuffer buf) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -131,8 +131,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder {
private Position createPosition(DeviceSession deviceSession) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
@@ -401,7 +400,6 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder {
return null;
}
-
private Object decodeCc(
Channel channel, SocketAddress remoteAddress, ChannelBuffer buf,
int version, ChannelBuffer id, int type, DeviceSession deviceSession) {
@@ -459,6 +457,47 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder {
return null;
}
+ private Object decodeMpip(
+ Channel channel, SocketAddress remoteAddress, ChannelBuffer buf,
+ int version, ChannelBuffer id, int type, DeviceSession deviceSession) {
+
+ if (type == 0x4001) {
+
+ sendResponse(channel, remoteAddress, version, id, (short) type, null);
+
+ return readPosition(deviceSession, buf);
+
+ } else if (type == 0x2001) {
+
+ sendResponse(channel, remoteAddress, id, (short) 0x1001);
+
+ buf.readUnsignedInt(); // index
+ buf.readUnsignedInt(); // unix time
+ buf.readUnsignedByte();
+
+ return readPosition(deviceSession, buf);
+
+ } else if (type == 0x4201 || type == 0x4202 || type == 0x4206) {
+
+ return readPosition(deviceSession, buf);
+
+ } else if (type == 0x4204) {
+
+ List<Position> positions = new LinkedList<>();
+
+ for (int i = 0; i < 8; i++) {
+ Position position = readPosition(deviceSession, buf);
+ buf.skipBytes(31);
+ positions.add(position);
+ }
+
+ return positions;
+
+ }
+
+ return null;
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -482,31 +521,15 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- if (version == -1) {
-
- if (type == 0x2001) {
-
- sendResponse(channel, remoteAddress, id, (short) 0x1001);
-
- buf.readUnsignedInt(); // index
- buf.readUnsignedInt(); // unix time
- buf.readUnsignedByte();
-
- return readPosition(deviceSession, buf);
-
- }
-
- } else if (version == 3 || version == 4) {
-
- return decodeSc(channel, remoteAddress, buf, version, id, type, deviceSession);
-
- } else {
-
- return decodeCc(channel, remoteAddress, buf, version, id, type, deviceSession);
-
+ switch (version) {
+ case -1:
+ return decodeMpip(channel, remoteAddress, buf, version, id, type, deviceSession);
+ case 3:
+ case 4:
+ return decodeSc(channel, remoteAddress, buf, version, id, type, deviceSession);
+ default:
+ return decodeCc(channel, remoteAddress, buf, version, id, type, deviceSession);
}
-
- return null;
}
}
diff --git a/src/org/traccar/protocol/CastelProtocolEncoder.java b/src/org/traccar/protocol/CastelProtocolEncoder.java
new file mode 100644
index 000000000..806dac19e
--- /dev/null
+++ b/src/org/traccar/protocol/CastelProtocolEncoder.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018 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.buffer.ChannelBuffers;
+import org.traccar.BaseProtocolEncoder;
+import org.traccar.Context;
+import org.traccar.helper.Checksum;
+import org.traccar.helper.Log;
+import org.traccar.model.Command;
+
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+
+public class CastelProtocolEncoder extends BaseProtocolEncoder {
+
+ private ChannelBuffer encodeContent(long deviceId, short type, ChannelBuffer content) {
+ ChannelBuffer buf = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ String uniqueId = Context.getIdentityManager().getById(deviceId).getUniqueId();
+
+ buf.writeByte('@');
+ buf.writeByte('@');
+
+ buf.writeShort(2 + 2 + 1 + 20 + 2 + content.readableBytes() + 2 + 2); // length
+
+ buf.writeByte(1); // protocol version
+
+ buf.writeBytes(uniqueId.getBytes(StandardCharsets.US_ASCII));
+ buf.writeZero(20 - uniqueId.length());
+
+ buf.writeShort(ChannelBuffers.swapShort(type));
+ buf.writeBytes(content);
+
+ buf.writeShort(Checksum.crc16(Checksum.CRC16_X25, buf.toByteBuffer()));
+
+ buf.writeByte('\r');
+ buf.writeByte('\n');
+
+ return buf;
+ }
+
+ @Override
+ protected Object encodeCommand(Command command) {
+ ChannelBuffer content = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ switch (command.getType()) {
+ case Command.TYPE_ENGINE_STOP:
+ content.writeByte(1);
+ return encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content);
+ case Command.TYPE_ENGINE_RESUME:
+ content.writeByte(0);
+ return encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content);
+ default:
+ Log.warning(new UnsupportedOperationException(command.getType()));
+ break;
+ }
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/protocol/CautelaProtocol.java b/src/org/traccar/protocol/CautelaProtocol.java
new file mode 100644
index 000000000..89ab7a1d0
--- /dev/null
+++ b/src/org/traccar/protocol/CautelaProtocol.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2018 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.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder;
+import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+
+public class CautelaProtocol extends BaseProtocol {
+
+ public CautelaProtocol() {
+ super("cautela");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(new ServerBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024));
+ pipeline.addLast("stringEncoder", new StringEncoder());
+ pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("objectDecoder", new CautelaProtocolDecoder(CautelaProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/CautelaProtocolDecoder.java b/src/org/traccar/protocol/CautelaProtocolDecoder.java
new file mode 100644
index 000000000..d7bf4fb51
--- /dev/null
+++ b/src/org/traccar/protocol/CautelaProtocolDecoder.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2018 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.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.DateBuilder;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.util.regex.Pattern;
+
+public class CautelaProtocolDecoder extends BaseProtocolDecoder {
+
+ public CautelaProtocolDecoder(CautelaProtocol protocol) {
+ super(protocol);
+ }
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .number("(d+),") // type
+ .number("(d+),") // imei
+ .number("(dd),(dd),(dd),") // date (ddmmyy)
+ .number("(-?d+.d+),") // latitude
+ .number("(-?d+.d+),") // longitude
+ .number("(dd)(dd),") // time (hhmm)
+ .any()
+ .compile();
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ Parser parser = new Parser(PATTERN, (String) msg);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ String type = parser.next();
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ DateBuilder dateBuilder = new DateBuilder();
+ dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
+
+ position.setValid(true);
+ position.setLatitude(parser.nextDouble());
+ position.setLongitude(parser.nextDouble());
+
+ dateBuilder.setHour(parser.nextInt()).setMinute(parser.nextInt());
+ position.setTime(dateBuilder.getDate());
+
+ return position;
+ }
+
+}
diff --git a/src/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/org/traccar/protocol/CellocatorProtocolDecoder.java
index 7ef013e28..67db9aa7d 100644
--- a/src/org/traccar/protocol/CellocatorProtocolDecoder.java
+++ b/src/org/traccar/protocol/CellocatorProtocolDecoder.java
@@ -100,8 +100,7 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder {
if (type == MSG_CLIENT_STATUS) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(deviceUniqueId));
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/CguardProtocolDecoder.java b/src/org/traccar/protocol/CguardProtocolDecoder.java
index 54f83fb73..2e20537c8 100644
--- a/src/org/traccar/protocol/CguardProtocolDecoder.java
+++ b/src/org/traccar/protocol/CguardProtocolDecoder.java
@@ -58,8 +58,7 @@ public class CguardProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(parser.nextDateTime());
@@ -84,8 +83,7 @@ public class CguardProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, parser.nextDateTime());
diff --git a/src/org/traccar/protocol/CityeasyProtocolDecoder.java b/src/org/traccar/protocol/CityeasyProtocolDecoder.java
index 9a614730f..7a1d8119d 100644
--- a/src/org/traccar/protocol/CityeasyProtocolDecoder.java
+++ b/src/org/traccar/protocol/CityeasyProtocolDecoder.java
@@ -91,8 +91,7 @@ public class CityeasyProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (parser.hasNext(15)) {
diff --git a/src/org/traccar/protocol/ContinentalProtocol.java b/src/org/traccar/protocol/ContinentalProtocol.java
new file mode 100644
index 000000000..e2b1226cf
--- /dev/null
+++ b/src/org/traccar/protocol/ContinentalProtocol.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 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.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
+import org.traccar.BaseProtocol;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+
+public class ContinentalProtocol extends BaseProtocol {
+
+ public ContinentalProtocol() {
+ super("continental");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(new ServerBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2));
+ pipeline.addLast("objectDecoder", new ContinentalProtocolDecoder(ContinentalProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/ContinentalProtocolDecoder.java b/src/org/traccar/protocol/ContinentalProtocolDecoder.java
new file mode 100644
index 000000000..726d9e16b
--- /dev/null
+++ b/src/org/traccar/protocol/ContinentalProtocolDecoder.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2018 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.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.util.Date;
+
+public class ContinentalProtocolDecoder extends BaseProtocolDecoder {
+
+ public ContinentalProtocolDecoder(ContinentalProtocol protocol) {
+ super(protocol);
+ }
+
+ public static final int MSG_KEEPALIVE = 0x00;
+ public static final int MSG_STATUS = 0x02;
+ public static final int MSG_ACK = 0x06;
+ public static final int MSG_NACK = 0x15;
+
+ private void sendResponse(Channel channel, long serialNumber) {
+ if (channel != null) {
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer();
+
+ response.writeByte('S');
+ response.writeByte('V');
+ response.writeShort(2 + 2 + 1 + 4 + 2); // length
+ response.writeByte(1); // version
+ response.writeInt((int) serialNumber);
+ response.writeByte(0); // product
+ response.writeByte(MSG_ACK);
+
+ channel.write(response);
+ }
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ buf.skipBytes(2); // header
+ buf.readUnsignedShort(); // length
+ buf.readUnsignedByte(); // software version
+
+ long serialNumber = buf.readUnsignedInt();
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(serialNumber));
+ if (deviceSession == null) {
+ return null;
+ }
+
+ sendResponse(channel, serialNumber);
+
+ buf.readUnsignedByte(); // product
+
+ int type = buf.readUnsignedByte();
+
+ if (type == MSG_STATUS) {
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setFixTime(new Date(buf.readUnsignedInt() * 1000L));
+
+ buf.readUnsignedByte();
+ position.setLatitude(buf.readMedium() / 3600.0);
+
+ buf.readUnsignedByte();
+ position.setLongitude(buf.readMedium() / 3600.0);
+
+ position.setCourse(buf.readUnsignedShort());
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort()));
+
+ position.setValid(buf.readUnsignedByte() > 0);
+
+ position.setDeviceTime(new Date(buf.readUnsignedInt() * 1000L));
+
+ position.set(Position.KEY_EVENT, buf.readUnsignedShort());
+ position.set(Position.KEY_INPUT, buf.readUnsignedShort());
+ position.set(Position.KEY_OUTPUT, buf.readUnsignedShort());
+ position.set(Position.KEY_BATTERY, buf.readUnsignedByte());
+ position.set(Position.KEY_DEVICE_TEMP, buf.readByte());
+
+ buf.readUnsignedShort(); // reserved
+
+ return position;
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/org/traccar/protocol/CradlepointProtocolDecoder.java
index e8f95a60c..f74830756 100644
--- a/src/org/traccar/protocol/CradlepointProtocolDecoder.java
+++ b/src/org/traccar/protocol/CradlepointProtocolDecoder.java
@@ -65,8 +65,7 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
int time = parser.nextInt();
diff --git a/src/org/traccar/protocol/DishaProtocolDecoder.java b/src/org/traccar/protocol/DishaProtocolDecoder.java
index ab0a63215..a4e567b34 100644
--- a/src/org/traccar/protocol/DishaProtocolDecoder.java
+++ b/src/org/traccar/protocol/DishaProtocolDecoder.java
@@ -65,8 +65,7 @@ public class DishaProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/org/traccar/protocol/DmtHttpProtocolDecoder.java
index dbcc7a6f8..200a20759 100644
--- a/src/org/traccar/protocol/DmtHttpProtocolDecoder.java
+++ b/src/org/traccar/protocol/DmtHttpProtocolDecoder.java
@@ -64,8 +64,7 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder {
JsonArray records = root.getJsonArray("Records");
for (int i = 0; i < records.size(); i++) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
JsonObject record = records.getJsonObject(i);
diff --git a/src/org/traccar/protocol/DmtProtocolDecoder.java b/src/org/traccar/protocol/DmtProtocolDecoder.java
index 39462a469..30a6ae13a 100644
--- a/src/org/traccar/protocol/DmtProtocolDecoder.java
+++ b/src/org/traccar/protocol/DmtProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2018 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.
@@ -21,6 +21,7 @@ import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
import org.traccar.helper.BitUtil;
+import org.traccar.helper.DateBuilder;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
@@ -42,144 +43,241 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_DATA_RECORD = 0x04;
public static final int MSG_COMMIT = 0x05;
public static final int MSG_COMMIT_RESPONSE = 0x06;
+ public static final int MSG_DATA_RECORD_64 = 0x10;
+
+ public static final int MSG_CANNED_REQUEST_1 = 0x14;
+ public static final int MSG_CANNED_RESPONSE_1 = 0x15;
+ public static final int MSG_CANNED_REQUEST_2 = 0x22;
+ public static final int MSG_CANNED_RESPONSE_2 = 0x23;
+
+ private void sendResponse(Channel channel, int type, ChannelBuffer content) {
+ if (channel != null) {
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ response.writeByte(0x02); response.writeByte(0x55); // header
+ response.writeByte(type);
+ response.writeShort(content != null ? content.readableBytes() : 0);
+ if (content != null) {
+ response.writeBytes(content);
+ }
+ channel.write(response);
+ }
+ }
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ private List<Position> decodeFixed64(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
- ChannelBuffer buf = (ChannelBuffer) msg;
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
- buf.skipBytes(2); // header
+ List<Position> positions = new LinkedList<>();
- int type = buf.readUnsignedByte();
+ while (buf.readableBytes() >= 64) {
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
- buf.readUnsignedShort(); // length
+ buf.readByte(); // type
- if (type == MSG_HELLO) {
+ position.set(Position.KEY_INDEX, buf.readUnsignedInt());
- buf.readUnsignedInt(); // device serial number
+ long time = buf.readUnsignedInt();
+ position.setTime(new DateBuilder()
+ .setYear((int) (2000 + (time & 0x3F)))
+ .setMonth((int) (time >> 6) & 0xF)
+ .setDay((int) (time >> 10) & 0x1F)
+ .setHour((int) (time >> 15) & 0x1F)
+ .setMinute((int) (time >> 20) & 0x3F)
+ .setSecond((int) (time >> 26) & 0x3F)
+ .getDate());
- DeviceSession deviceSession = getDeviceSession(
- channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII));
+ position.setLongitude(buf.readInt() * 0.0000001);
+ position.setLatitude(buf.readInt() * 0.0000001);
+ position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort()));
+ position.setCourse(buf.readUnsignedByte() * 2);
+ position.setAltitude(buf.readShort());
- if (channel != null) {
- ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
- response.writeByte(0x02); response.writeByte(0x55); // header
- response.writeByte(MSG_HELLO_RESPONSE);
- response.writeShort(4 + 4);
- response.writeInt((int) (System.currentTimeMillis() / 1000));
- response.writeInt(deviceSession != null ? 0 : 1); // flags
- channel.write(response);
- }
+ buf.readUnsignedShort(); // position accuracy
+ buf.readUnsignedByte(); // speed accuracy
- } else if (type == MSG_COMMIT) {
+ position.set(Position.KEY_EVENT, buf.readUnsignedByte());
- if (channel != null) {
- ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
- response.writeByte(0x02); response.writeByte(0x55); // header
- response.writeByte(MSG_COMMIT_RESPONSE);
- response.writeShort(1);
- response.writeByte(1); // flags (success)
- channel.write(response);
- }
+ position.setValid(BitUtil.check(buf.readByte(), 0));
- } else if (type == MSG_DATA_RECORD) {
+ position.set(Position.KEY_INPUT, buf.readUnsignedInt());
+ position.set(Position.KEY_OUTPUT, buf.readUnsignedShort());
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
- if (deviceSession == null) {
- return null;
+ for (int i = 1; i <= 5; i++) {
+ position.set(Position.PREFIX_ADC + i, buf.readShort());
}
- List<Position> positions = new LinkedList<>();
+ position.set(Position.KEY_DEVICE_TEMP, buf.readByte());
- while (buf.readable()) {
+ buf.readShort(); // accelerometer x
+ buf.readShort(); // accelerometer y
+ buf.readShort(); // accelerometer z
- int recordEnd = buf.readerIndex() + buf.readUnsignedShort();
+ buf.skipBytes(8); // device id
- Position position = new Position();
- position.setProtocol(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
+ position.set(Position.KEY_PDOP, buf.readUnsignedShort() * 0.01);
- position.set(Position.KEY_INDEX, buf.readUnsignedInt());
+ buf.skipBytes(2); // reserved
- position.setDeviceTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); // since 1 Jan 2013
+ buf.readUnsignedShort(); // checksum
- position.set(Position.KEY_EVENT, buf.readUnsignedByte());
+ positions.add(position);
+ }
- while (buf.readerIndex() < recordEnd) {
+ return positions;
+ }
- int fieldId = buf.readUnsignedByte();
- int fieldLength = buf.readUnsignedByte();
- int fieldEnd = buf.readerIndex() + (fieldLength == 255 ? buf.readUnsignedShort() : fieldLength);
+ private List<Position> decodeStandard(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
- if (fieldId == 0) {
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
- position.setFixTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000));
- position.setLatitude(buf.readInt() * 0.0000001);
- position.setLongitude(buf.readInt() * 0.0000001);
- position.setAltitude(buf.readShort());
- position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort()));
+ List<Position> positions = new LinkedList<>();
- buf.readUnsignedByte(); // speed accuracy
+ while (buf.readable()) {
+ int recordEnd = buf.readerIndex() + buf.readUnsignedShort();
- position.setCourse(buf.readUnsignedByte() * 2);
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
- position.set(Position.KEY_PDOP, buf.readUnsignedByte() * 0.1);
+ position.set(Position.KEY_INDEX, buf.readUnsignedInt());
- position.setAccuracy(buf.readUnsignedByte());
- position.setValid(buf.readUnsignedByte() != 0);
+ position.setDeviceTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); // since 1 Jan 2013
- } else if (fieldId == 2) {
+ position.set(Position.KEY_EVENT, buf.readUnsignedByte());
- int input = buf.readInt();
- int output = buf.readUnsignedShort();
- int status = buf.readUnsignedShort();
+ while (buf.readerIndex() < recordEnd) {
- position.set(Position.KEY_IGNITION, BitUtil.check(input, 0));
+ int fieldId = buf.readUnsignedByte();
+ int fieldLength = buf.readUnsignedByte();
+ int fieldEnd = buf.readerIndex() + (fieldLength == 255 ? buf.readUnsignedShort() : fieldLength);
- position.set(Position.KEY_INPUT, input);
- position.set(Position.KEY_OUTPUT, output);
- position.set(Position.KEY_STATUS, status);
+ if (fieldId == 0) {
- } else if (fieldId == 6) {
+ position.setFixTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000));
+ position.setLatitude(buf.readInt() * 0.0000001);
+ position.setLongitude(buf.readInt() * 0.0000001);
+ position.setAltitude(buf.readShort());
+ position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort()));
- while (buf.readerIndex() < fieldEnd) {
- switch (buf.readUnsignedByte()) {
- case 1:
- position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001);
- break;
- case 2:
- position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01);
- break;
- case 3:
- position.set(Position.KEY_DEVICE_TEMP, buf.readShort() * 0.01);
- break;
- case 4:
- position.set(Position.KEY_RSSI, buf.readUnsignedShort());
- break;
- case 5:
- position.set("solarPower", buf.readUnsignedShort() * 0.001);
- break;
- default:
- break;
- }
- }
+ buf.readUnsignedByte(); // speed accuracy
- }
+ position.setCourse(buf.readUnsignedByte() * 2);
- buf.readerIndex(fieldEnd);
+ position.set(Position.KEY_PDOP, buf.readUnsignedByte() * 0.1);
- }
+ position.setAccuracy(buf.readUnsignedByte());
+ position.setValid(buf.readUnsignedByte() != 0);
+
+ } else if (fieldId == 2) {
+
+ int input = buf.readInt();
+ int output = buf.readUnsignedShort();
+ int status = buf.readUnsignedShort();
+
+ position.set(Position.KEY_IGNITION, BitUtil.check(input, 0));
+
+ position.set(Position.KEY_INPUT, input);
+ position.set(Position.KEY_OUTPUT, output);
+ position.set(Position.KEY_STATUS, status);
+
+ } else if (fieldId == 6) {
+
+ while (buf.readerIndex() < fieldEnd) {
+ switch (buf.readUnsignedByte()) {
+ case 1:
+ position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001);
+ break;
+ case 2:
+ position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01);
+ break;
+ case 3:
+ position.set(Position.KEY_DEVICE_TEMP, buf.readShort() * 0.01);
+ break;
+ case 4:
+ position.set(Position.KEY_RSSI, buf.readUnsignedShort());
+ break;
+ case 5:
+ position.set("solarPower", buf.readUnsignedShort() * 0.001);
+ break;
+ default:
+ break;
+ }
+ }
- if (position.getFixTime() == null) {
- getLastLocation(position, position.getDeviceTime());
}
- positions.add(position);
+ buf.readerIndex(fieldEnd);
+
+ }
+ if (position.getFixTime() == null) {
+ getLastLocation(position, position.getDeviceTime());
}
- return positions;
+ positions.add(position);
+ }
+
+ return positions;
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ buf.skipBytes(2); // header
+
+ int type = buf.readUnsignedByte();
+ int length = buf.readUnsignedShort();
+
+ if (type == MSG_HELLO) {
+
+ buf.readUnsignedInt(); // device serial number
+
+ DeviceSession deviceSession = getDeviceSession(
+ channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII));
+
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ if (length == 51) {
+ response.writeByte(0); // reserved
+ response.writeInt(0); // reserved
+ } else {
+ response.writeInt((int) ((System.currentTimeMillis() - 1356998400000L) / 1000));
+ response.writeInt(deviceSession != null ? 0 : 1); // flags
+ }
+
+ sendResponse(channel, MSG_HELLO_RESPONSE, response);
+
+ } else if (type == MSG_COMMIT) {
+
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ response.writeByte(1); // flags (success)
+ sendResponse(channel, MSG_COMMIT_RESPONSE, response);
+
+ } else if (type == MSG_CANNED_REQUEST_1) {
+
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ response.writeBytes(new byte[12]);
+ sendResponse(channel, MSG_CANNED_RESPONSE_1, response);
+
+ } else if (type == MSG_CANNED_REQUEST_2) {
+
+ sendResponse(channel, MSG_CANNED_RESPONSE_2, null);
+
+ } else if (type == MSG_DATA_RECORD_64) {
+
+ return decodeFixed64(channel, remoteAddress, buf);
+
+ } else if (type == MSG_DATA_RECORD) {
+
+ return decodeStandard(channel, remoteAddress, buf);
}
diff --git a/src/org/traccar/protocol/DwayProtocolDecoder.java b/src/org/traccar/protocol/DwayProtocolDecoder.java
index 121681588..8ddd62b83 100644
--- a/src/org/traccar/protocol/DwayProtocolDecoder.java
+++ b/src/org/traccar/protocol/DwayProtocolDecoder.java
@@ -76,8 +76,7 @@ public class DwayProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setValid(true);
diff --git a/src/org/traccar/protocol/EasyTrackProtocolDecoder.java b/src/org/traccar/protocol/EasyTrackProtocolDecoder.java
index 799254b65..16ced37ae 100644
--- a/src/org/traccar/protocol/EasyTrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/EasyTrackProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2018 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.
@@ -54,6 +54,31 @@ public class EasyTrackProtocolDecoder extends BaseProtocolDecoder {
.any()
.compile();
+ private String decodeAlarm(long status) {
+ if ((status & 0x02000000) > 0) {
+ return Position.ALARM_GEOFENCE_ENTER;
+ }
+ if ((status & 0x04000000) > 0) {
+ return Position.ALARM_GEOFENCE_EXIT;
+ }
+ if ((status & 0x08000000) > 0) {
+ return Position.ALARM_LOW_BATTERY;
+ }
+ if ((status & 0x20000000) > 0) {
+ return Position.ALARM_VIBRATION;
+ }
+ if ((status & 0x80000000) > 0) {
+ return Position.ALARM_OVERSPEED;
+ }
+ if ((status & 0x00010000) > 0) {
+ return Position.ALARM_SOS;
+ }
+ if ((status & 0x00040000) > 0) {
+ return Position.ALARM_POWER_CUT;
+ }
+ return null;
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -63,8 +88,7 @@ public class EasyTrackProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
@@ -96,7 +120,10 @@ public class EasyTrackProtocolDecoder extends BaseProtocolDecoder {
position.setSpeed(UnitsConverter.knotsFromKph(parser.nextHexInt(0) / 100.0));
position.setCourse(parser.nextHexInt(0) / 100.0);
- position.set(Position.KEY_STATUS, parser.next());
+ long status = parser.nextHexLong();
+ position.set(Position.KEY_STATUS, status);
+ position.set(Position.KEY_ALARM, decodeAlarm(status));
+
position.set("signal", parser.next());
position.set(Position.KEY_POWER, parser.nextDouble(0));
position.set("oil", parser.nextHexInt(0));
diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java
index 98a9f7d6d..0ed81c925 100644
--- a/src/org/traccar/protocol/EelinkProtocolDecoder.java
+++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java
@@ -115,9 +115,8 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder {
private Position decodeOld(DeviceSession deviceSession, ChannelBuffer buf, int type, int index) {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
position.set(Position.KEY_INDEX, index);
@@ -173,9 +172,8 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder {
private Position decodeNew(DeviceSession deviceSession, ChannelBuffer buf, int index) {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
position.set(Position.KEY_INDEX, index);
@@ -282,9 +280,8 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder {
private Position decodeResult(DeviceSession deviceSession, ChannelBuffer buf, int index) {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
position.set(Position.KEY_INDEX, index);
@@ -362,9 +359,8 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder {
} else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2) {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
getLastLocation(position, null);
diff --git a/src/org/traccar/protocol/EelinkProtocolEncoder.java b/src/org/traccar/protocol/EelinkProtocolEncoder.java
index 76865a039..4d2d86e68 100644
--- a/src/org/traccar/protocol/EelinkProtocolEncoder.java
+++ b/src/org/traccar/protocol/EelinkProtocolEncoder.java
@@ -18,10 +18,10 @@ package org.traccar.protocol;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.traccar.BaseProtocolEncoder;
+import org.traccar.helper.DataConverter;
import org.traccar.helper.Log;
import org.traccar.model.Command;
-import javax.xml.bind.DatatypeConverter;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -47,7 +47,7 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder {
ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
if (connectionless) {
- buf.writeBytes(ChannelBuffers.wrappedBuffer(DatatypeConverter.parseHexBinary('0' + uniqueId)));
+ buf.writeBytes(ChannelBuffers.wrappedBuffer(DataConverter.parseHex('0' + uniqueId)));
}
buf.writeByte(0x67);
diff --git a/src/org/traccar/protocol/EgtsFrameDecoder.java b/src/org/traccar/protocol/EgtsFrameDecoder.java
new file mode 100644
index 000000000..71ffc1811
--- /dev/null
+++ b/src/org/traccar/protocol/EgtsFrameDecoder.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 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 EgtsFrameDecoder extends FrameDecoder {
+
+ @Override
+ protected Object decode(
+ ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception {
+
+ if (buf.readableBytes() < 10) {
+ return null;
+ }
+
+ int headerLength = buf.getUnsignedByte(buf.readerIndex() + 3);
+ int frameLength = buf.getUnsignedShort(buf.readerIndex() + 5);
+
+ int length = headerLength + frameLength + (frameLength > 0 ? 2 : 0);
+
+ if (buf.readableBytes() >= length) {
+ return buf.readBytes(length);
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/protocol/EgtsProtocol.java b/src/org/traccar/protocol/EgtsProtocol.java
new file mode 100644
index 000000000..13ec6c9a7
--- /dev/null
+++ b/src/org/traccar/protocol/EgtsProtocol.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 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.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.traccar.BaseProtocol;
+import org.traccar.TrackerServer;
+
+import java.nio.ByteOrder;
+import java.util.List;
+
+public class EgtsProtocol extends BaseProtocol {
+
+ public EgtsProtocol() {
+ super("egts");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("frameDecoder", new EgtsFrameDecoder());
+ pipeline.addLast("objectDecoder", new EgtsProtocolDecoder(EgtsProtocol.this));
+ }
+ };
+ server.setEndianness(ByteOrder.LITTLE_ENDIAN);
+ serverList.add(server);
+ }
+
+}
diff --git a/src/org/traccar/protocol/EgtsProtocolDecoder.java b/src/org/traccar/protocol/EgtsProtocolDecoder.java
new file mode 100644
index 000000000..420701e6c
--- /dev/null
+++ b/src/org/traccar/protocol/EgtsProtocolDecoder.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2018 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.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.BitUtil;
+import org.traccar.helper.Checksum;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+public class EgtsProtocolDecoder extends BaseProtocolDecoder {
+
+ public EgtsProtocolDecoder(EgtsProtocol protocol) {
+ super(protocol);
+ }
+
+ public static final int PT_RESPONSE = 0;
+ public static final int PT_APPDATA = 1;
+ public static final int PT_SIGNED_APPDATA = 2;
+
+ public static final int SERVICE_AUTH = 1;
+ public static final int SERVICE_TELEDATA = 2;
+ public static final int SERVICE_COMMANDS = 4;
+ public static final int SERVICE_FIRMWARE = 9;
+ public static final int SERVICE_ECALL = 10;
+
+ public static final int MSG_RECORD_RESPONSE = 0;
+ public static final int MSG_TERM_IDENTITY = 1;
+ public static final int MSG_MODULE_DATA = 2;
+ public static final int MSG_VEHICLE_DATA = 3;
+ public static final int MSG_AUTH_PARAMS = 4;
+ public static final int MSG_AUTH_INFO = 5;
+ public static final int MSG_SERVICE_INFO = 6;
+ public static final int MSG_RESULT_CODE = 7;
+ public static final int MSG_POS_DATA = 16;
+ public static final int MSG_EXT_POS_DATA = 17;
+ public static final int MSG_AD_SENSORS_DATA = 18;
+ public static final int MSG_COUNTERS_DATA = 19;
+ public static final int MSG_STATE_DATA = 20;
+ public static final int MSG_LOOPIN_DATA = 22;
+ public static final int MSG_ABS_DIG_SENS_DATA = 23;
+ public static final int MSG_ABS_AN_SENS_DATA = 24;
+ public static final int MSG_ABS_CNTR_DATA = 25;
+ public static final int MSG_ABS_LOOPIN_DATA = 26;
+ public static final int MSG_LIQUID_LEVEL_SENSOR = 27;
+ public static final int MSG_PASSENGERS_COUNTERS = 28;
+
+ private int packetId;
+
+ private void sendResponse(
+ Channel channel, int packetType, int index, int serviceType, int type, ChannelBuffer content) {
+ if (channel != null) {
+
+ ChannelBuffer data = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ data.writeByte(type);
+ data.writeShort(content.readableBytes());
+ data.writeBytes(content);
+
+ ChannelBuffer record = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ record.writeShort(data.readableBytes());
+ record.writeShort(index);
+ record.writeByte(1 << 6); // flags
+ record.writeByte(serviceType);
+ record.writeByte(serviceType);
+ record.writeBytes(data);
+ int recordChecksum = Checksum.crc16(Checksum.CRC16_CCITT_FALSE, record.toByteBuffer());
+
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ response.writeByte(1); // protocol version
+ response.writeByte(0); // security key id
+ response.writeByte(0); // flags
+ response.writeByte(5 + 2 + 2 + 2); // header length
+ response.writeByte(0); // encoding
+ response.writeShort(record.readableBytes());
+ response.writeShort(packetId++);
+ response.writeByte(packetType);
+ response.writeByte(Checksum.crc8(Checksum.CRC8_EGTS, response.toByteBuffer()));
+ response.writeBytes(record);
+ response.writeShort(recordChecksum);
+
+ channel.write(response);
+
+ }
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ buf.skipBytes(buf.getUnsignedByte(buf.readerIndex() + 3));
+
+ List<Position> positions = new LinkedList<>();
+
+ while (buf.readableBytes() > 2) {
+
+ int length = buf.readUnsignedShort();
+ int index = buf.readUnsignedShort();
+ int recordFlags = buf.readUnsignedByte();
+
+ if (BitUtil.check(recordFlags, 0)) {
+ buf.readUnsignedInt(); // object id
+ }
+
+ if (BitUtil.check(recordFlags, 1)) {
+ buf.readUnsignedInt(); // event id
+ }
+ if (BitUtil.check(recordFlags, 2)) {
+ buf.readUnsignedInt(); // time
+ }
+
+ int serviceType = buf.readUnsignedByte();
+ buf.readUnsignedByte(); // recipient service type
+
+ int recordEnd = buf.readerIndex() + length;
+
+ Position position = new Position(getProtocolName());
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession != null) {
+ position.setDeviceId(deviceSession.getDeviceId());
+ }
+
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ response.writeShort(index);
+ response.writeByte(0); // success
+ sendResponse(channel, PT_RESPONSE, index, serviceType, MSG_RECORD_RESPONSE, response);
+
+ while (buf.readerIndex() < recordEnd) {
+ int type = buf.readUnsignedByte();
+ int end = buf.readUnsignedShort() + buf.readerIndex();
+
+ if (type == MSG_TERM_IDENTITY) {
+
+ buf.readUnsignedInt(); // object id
+ int flags = buf.readUnsignedByte();
+
+ if (BitUtil.check(flags, 0)) {
+ buf.readUnsignedShort(); // home dispatcher identifier
+ }
+ if (BitUtil.check(flags, 1)) {
+ getDeviceSession(
+ channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII).trim());
+ }
+ if (BitUtil.check(flags, 2)) {
+ getDeviceSession(
+ channel, remoteAddress, buf.readBytes(16).toString(StandardCharsets.US_ASCII).trim());
+ }
+ if (BitUtil.check(flags, 3)) {
+ buf.skipBytes(3); // language identifier
+ }
+ if (BitUtil.check(flags, 5)) {
+ buf.skipBytes(3); // network identifier
+ }
+ if (BitUtil.check(flags, 6)) {
+ buf.readUnsignedShort(); // buffer size
+ }
+ if (BitUtil.check(flags, 7)) {
+ getDeviceSession(
+ channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII).trim());
+ }
+
+ response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ response.writeByte(0); // success
+ sendResponse(channel, PT_APPDATA, index, serviceType, MSG_RESULT_CODE, response);
+
+ } else if (type == MSG_POS_DATA) {
+
+ position.setTime(new Date((buf.readUnsignedInt() + 1262304000) * 1000)); // since 2010-01-01
+ position.setLatitude(buf.readUnsignedInt() * 90.0 / 0xFFFFFFFFL);
+ position.setLongitude(buf.readUnsignedInt() * 180.0 / 0xFFFFFFFFL);
+
+ int flags = buf.readUnsignedByte();
+ position.setValid(BitUtil.check(flags, 0));
+ if (BitUtil.check(flags, 5)) {
+ position.setLatitude(-position.getLatitude());
+ }
+ if (BitUtil.check(flags, 6)) {
+ position.setLongitude(-position.getLongitude());
+ }
+
+ int speed = buf.readUnsignedShort();
+ position.setSpeed(UnitsConverter.knotsFromKph(BitUtil.to(speed, 14) * 0.1));
+ position.setCourse(buf.readUnsignedByte() + (BitUtil.check(speed, 15) ? 0x100 : 0));
+
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 100);
+ position.set(Position.KEY_INPUT, buf.readUnsignedByte());
+ position.set(Position.KEY_EVENT, buf.readUnsignedByte());
+
+ if (BitUtil.check(flags, 7)) {
+ position.setAltitude(buf.readMedium());
+ }
+
+ } else if (type == MSG_EXT_POS_DATA) {
+
+ int flags = buf.readUnsignedByte();
+
+ if (BitUtil.check(flags, 0)) {
+ position.set(Position.KEY_VDOP, buf.readUnsignedShort());
+ }
+ if (BitUtil.check(flags, 1)) {
+ position.set(Position.KEY_HDOP, buf.readUnsignedShort());
+ }
+ if (BitUtil.check(flags, 2)) {
+ position.set(Position.KEY_PDOP, buf.readUnsignedShort());
+ }
+ if (BitUtil.check(flags, 3)) {
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+ }
+
+ } else if (type == MSG_AD_SENSORS_DATA) {
+
+ buf.readUnsignedByte(); // inputs flags
+
+ position.set(Position.KEY_OUTPUT, buf.readUnsignedByte());
+
+ buf.readUnsignedByte(); // adc flags
+
+ }
+
+ buf.readerIndex(end);
+ }
+
+ if (serviceType == SERVICE_TELEDATA && deviceSession != null) {
+ positions.add(position);
+ }
+ }
+
+ return positions.isEmpty() ? null : positions;
+ }
+
+}
diff --git a/src/org/traccar/protocol/EnforaProtocolDecoder.java b/src/org/traccar/protocol/EnforaProtocolDecoder.java
index f0b79aa1f..c5500c3b3 100644
--- a/src/org/traccar/protocol/EnforaProtocolDecoder.java
+++ b/src/org/traccar/protocol/EnforaProtocolDecoder.java
@@ -95,8 +95,7 @@ public class EnforaProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
diff --git a/src/org/traccar/protocol/EskyProtocolDecoder.java b/src/org/traccar/protocol/EskyProtocolDecoder.java
index b509d821f..60ef4f846 100644
--- a/src/org/traccar/protocol/EskyProtocolDecoder.java
+++ b/src/org/traccar/protocol/EskyProtocolDecoder.java
@@ -65,8 +65,7 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_SATELLITES, parser.nextInt());
diff --git a/src/org/traccar/protocol/ExtremTracProtocolDecoder.java b/src/org/traccar/protocol/ExtremTracProtocolDecoder.java
index 79e3306df..553720f1e 100644
--- a/src/org/traccar/protocol/ExtremTracProtocolDecoder.java
+++ b/src/org/traccar/protocol/ExtremTracProtocolDecoder.java
@@ -61,8 +61,7 @@ public class ExtremTracProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
diff --git a/src/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/org/traccar/protocol/FifotrackProtocolDecoder.java
index 304f6a2c3..cb7a23315 100644
--- a/src/org/traccar/protocol/FifotrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/FifotrackProtocolDecoder.java
@@ -78,8 +78,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_ALARM, parser.next());
diff --git a/src/org/traccar/protocol/FlespiProtocolDecoder.java b/src/org/traccar/protocol/FlespiProtocolDecoder.java
index 6cba234e5..526e10fa2 100644
--- a/src/org/traccar/protocol/FlespiProtocolDecoder.java
+++ b/src/org/traccar/protocol/FlespiProtocolDecoder.java
@@ -60,9 +60,8 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder {
if (deviceSession == null) {
continue;
}
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
decodePosition(message, position);
positions.add(position);
}
@@ -124,7 +123,7 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder {
return true;
case "din":
case "dout":
- position.set((name.equals("din") ? Position.KEY_INPUT : Position.KEY_OUTPUT),
+ position.set(name.equals("din") ? Position.KEY_INPUT : Position.KEY_OUTPUT,
((JsonNumber) value).intValue());
return true;
case "gps.vehicle.mileage":
diff --git a/src/org/traccar/protocol/FlexCommProtocolDecoder.java b/src/org/traccar/protocol/FlexCommProtocolDecoder.java
index f401145b9..8bd4dcee0 100644
--- a/src/org/traccar/protocol/FlexCommProtocolDecoder.java
+++ b/src/org/traccar/protocol/FlexCommProtocolDecoder.java
@@ -78,8 +78,7 @@ public class FlexCommProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_STATUS, parser.nextInt());
diff --git a/src/org/traccar/protocol/FlextrackProtocolDecoder.java b/src/org/traccar/protocol/FlextrackProtocolDecoder.java
index ab2e4d24c..8f7525147 100644
--- a/src/org/traccar/protocol/FlextrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/FlextrackProtocolDecoder.java
@@ -103,8 +103,7 @@ public class FlextrackProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
sendAcknowledgement(channel, parser.next());
diff --git a/src/org/traccar/protocol/FoxProtocolDecoder.java b/src/org/traccar/protocol/FoxProtocolDecoder.java
index 9b2cf0e1d..16f8fce27 100644
--- a/src/org/traccar/protocol/FoxProtocolDecoder.java
+++ b/src/org/traccar/protocol/FoxProtocolDecoder.java
@@ -88,8 +88,7 @@ public class FoxProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_STATUS, parser.nextInt(0));
diff --git a/src/org/traccar/protocol/FreedomProtocolDecoder.java b/src/org/traccar/protocol/FreedomProtocolDecoder.java
index 56b6b9e19..28456c617 100644
--- a/src/org/traccar/protocol/FreedomProtocolDecoder.java
+++ b/src/org/traccar/protocol/FreedomProtocolDecoder.java
@@ -53,8 +53,7 @@ public class FreedomProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/GalileoProtocolDecoder.java b/src/org/traccar/protocol/GalileoProtocolDecoder.java
index 3944b37de..d8a1651bb 100644
--- a/src/org/traccar/protocol/GalileoProtocolDecoder.java
+++ b/src/org/traccar/protocol/GalileoProtocolDecoder.java
@@ -20,6 +20,7 @@ import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
+import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
import java.net.SocketAddress;
@@ -117,7 +118,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder {
position.setTime(new Date(buf.readUnsignedInt() * 1000));
break;
case 0x33:
- position.setSpeed(buf.readUnsignedShort() * 0.0539957);
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1));
position.setCourse(buf.readUnsignedShort() * 0.1);
break;
case 0x34:
@@ -248,11 +249,10 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder {
boolean hasLocation = false;
DeviceSession deviceSession = null;
- Position position = new Position();
+ Position position = new Position(getProtocolName());
while (buf.readerIndex() < length) {
- // Check if new message started
int tag = buf.readUnsignedByte();
if (tags.contains(tag)) {
if (hasLocation && position.getFixTime() != null) {
@@ -260,7 +260,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder {
}
tags.clear();
hasLocation = false;
- position = new Position();
+ position = new Position(getProtocolName()); // new position starts
}
tags.add(tag);
@@ -278,13 +278,6 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder {
}
- if (hasLocation && position.getFixTime() != null) {
- positions.add(position);
- } else if (position.getAttributes().containsKey(Position.KEY_RESULT)) {
- getLastLocation(position, null);
- positions.add(position);
- }
-
if (deviceSession == null) {
deviceSession = getDeviceSession(channel, remoteAddress);
if (deviceSession == null) {
@@ -292,10 +285,17 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder {
}
}
+ if (hasLocation && position.getFixTime() != null) {
+ positions.add(position);
+ } else if (position.getAttributes().containsKey(Position.KEY_RESULT)) {
+ position.setDeviceId(deviceSession.getDeviceId());
+ getLastLocation(position, null);
+ positions.add(position);
+ }
+
sendReply(channel, buf.readUnsignedShort());
for (Position p : positions) {
- p.setProtocol(getProtocolName());
p.setDeviceId(deviceSession.getDeviceId());
}
diff --git a/src/org/traccar/protocol/GatorProtocolDecoder.java b/src/org/traccar/protocol/GatorProtocolDecoder.java
index 2ad4be3d3..9cd746f51 100644
--- a/src/org/traccar/protocol/GatorProtocolDecoder.java
+++ b/src/org/traccar/protocol/GatorProtocolDecoder.java
@@ -90,8 +90,7 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder {
if (type == MSG_POSITION_DATA || type == MSG_ROLLCALL_RESPONSE
|| type == MSG_ALARM_DATA || type == MSG_BLIND_AREA) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, "1" + id, id);
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/GenxProtocolDecoder.java b/src/org/traccar/protocol/GenxProtocolDecoder.java
index 3b38227dc..d4a348ce1 100644
--- a/src/org/traccar/protocol/GenxProtocolDecoder.java
+++ b/src/org/traccar/protocol/GenxProtocolDecoder.java
@@ -48,8 +48,7 @@ public class GenxProtocolDecoder extends BaseProtocolDecoder {
String[] values = ((String) msg).split(",");
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setValid(true);
for (int i = 0; i < Math.min(values.length, reportColumns.length); i++) {
diff --git a/src/org/traccar/protocol/Gl100ProtocolDecoder.java b/src/org/traccar/protocol/Gl100ProtocolDecoder.java
index 945edfff0..405090695 100644
--- a/src/org/traccar/protocol/Gl100ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gl100ProtocolDecoder.java
@@ -72,8 +72,7 @@ public class Gl100ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java
index 071960e49..ba3baaa75 100644
--- a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java
@@ -108,8 +108,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder {
time += 1;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
switch (BitUtil.from(buf.getUnsignedByte(buf.readerIndex()), 8 - 2)) {
@@ -156,8 +155,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder {
for (int i = 0; i < count; i++) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_BATTERY_LEVEL, battery);
@@ -206,8 +204,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder {
private Position decodeEvent(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
int type = buf.readUnsignedByte();
@@ -313,8 +310,7 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder {
private Position decodeInformation(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
int type = buf.readUnsignedByte();
diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java
index 9429cff2f..ff300d429 100644
--- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2018 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.
@@ -210,7 +210,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
.number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
.number("(d{15}|x{14}),") // imei
.expression("[^,]*,") // device name
- .number("x{8},") // mask
+ .number("(x{8}),") // mask
.number("(d+)?,") // power
.number("d{1,2},") // report type
.number("d{1,2},") // count
@@ -356,8 +356,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
channel.write("+SACK:GTHBD," + protocolVersion + "," + parser.next() + "$", remoteAddress);
}
} else {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, parser.nextDateTime());
position.setValid(false);
@@ -372,8 +371,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
if (parser.matches()) {
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession != null) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
return position;
}
@@ -431,8 +429,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
parser.next(); // odometer or external power
- position.set(Position.KEY_BATTERY, parser.nextDouble(0));
- position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1);
+ position.set(Position.KEY_BATTERY, parser.nextDouble());
+ position.set(Position.KEY_CHARGE, parser.nextInt() == 1);
position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
@@ -446,7 +444,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
getLastLocation(position, parser.nextDateTime());
- position.set(Position.KEY_INDEX, parser.nextHexInt(0));
+ position.set(Position.KEY_INDEX, parser.nextHexInt());
return position;
}
@@ -459,8 +457,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
}
position.set("deviceType", parser.next());
- position.set(Position.KEY_VERSION_FW, parser.nextHexInt(0));
- position.set(Position.KEY_VERSION_HW, parser.nextHexInt(0));
+ position.set(Position.KEY_VERSION_FW, parser.nextHexInt());
+ position.set(Position.KEY_VERSION_HW, parser.nextHexInt());
getLastLocation(position, parser.nextDateTime());
@@ -468,8 +466,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
}
private void decodeLocation(Position position, Parser parser) {
- int hdop = parser.nextInt(0);
- position.setValid(hdop > 0);
+ Integer hdop = parser.nextInt();
+ position.setValid(hdop == null || hdop > 0);
position.set(Position.KEY_HDOP, hdop);
position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
@@ -478,25 +476,27 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
if (parser.hasNext(8)) {
position.setValid(true);
- position.setLongitude(parser.nextDouble(0));
- position.setLatitude(parser.nextDouble(0));
+ position.setLongitude(parser.nextDouble());
+ position.setLatitude(parser.nextDouble());
position.setTime(parser.nextDateTime());
} else {
getLastLocation(position, null);
}
if (parser.hasNext(6)) {
- int mcc = parser.nextInt(0);
- int mnc = parser.nextInt(0);
+ int mcc = parser.nextInt();
+ int mnc = parser.nextInt();
if (parser.hasNext(2)) {
- position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(0), parser.nextInt(0))));
+ position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(), parser.nextInt())));
}
if (parser.hasNext(2)) {
- position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(0), parser.nextHexInt(0))));
+ position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt())));
}
}
- position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000);
+ if (parser.hasNext()) {
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
+ }
}
private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) {
@@ -511,16 +511,22 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_TEMP + 1, parser.nextInt());
position.set(Position.KEY_FUEL_CONSUMPTION, parser.next());
position.set("dtcsClearedDistance", parser.nextInt());
- position.set("odbConnect", parser.nextInt(0) == 1);
+ if (parser.hasNext()) {
+ position.set("odbConnect", parser.nextInt() == 1);
+ }
position.set("dtcsNumber", parser.nextInt());
position.set("dtcsCodes", parser.next());
position.set(Position.KEY_THROTTLE, parser.nextInt());
position.set(Position.KEY_FUEL_LEVEL, parser.nextInt());
- position.set(Position.KEY_OBD_ODOMETER, parser.nextInt(0) * 1000);
+ if (parser.hasNext()) {
+ position.set(Position.KEY_OBD_ODOMETER, parser.nextInt() * 1000);
+ }
decodeLocation(position, parser);
- position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000);
+ if (parser.hasNext()) {
+ position.set(Position.KEY_OBD_ODOMETER, (int) (parser.nextDouble() * 1000));
+ }
decodeDeviceTime(position, parser);
@@ -528,8 +534,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
}
private Object decodeCan(Channel channel, SocketAddress remoteAddress, String sentence) throws ParseException {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
int index = 0;
String[] values = sentence.split(",");
@@ -557,14 +562,14 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
if (BitUtil.check(reportMask, 3)) {
position.set("totalFuelConsumption", Double.parseDouble(values[index++]));
}
- if (BitUtil.check(reportMask, 5)) {
- position.set(Position.KEY_RPM, Integer.parseInt(values[index++]));
+ if (BitUtil.check(reportMask, 5) && !values[index++].isEmpty()) {
+ position.set(Position.KEY_RPM, Integer.parseInt(values[index - 1]));
}
- if (BitUtil.check(reportMask, 4)) {
- position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(Integer.parseInt(values[index++])));
+ if (BitUtil.check(reportMask, 4) && !values[index++].isEmpty()) {
+ position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(Integer.parseInt(values[index - 1])));
}
- if (BitUtil.check(reportMask, 6)) {
- position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[index++]));
+ if (BitUtil.check(reportMask, 6) && !values[index++].isEmpty()) {
+ position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[index - 1]));
}
if (BitUtil.check(reportMask, 7) && !values[index++].isEmpty()) {
position.set(Position.KEY_FUEL_CONSUMPTION, Double.parseDouble(values[index - 1].substring(1)));
@@ -652,14 +657,14 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
private void decodeStatus(Position position, Parser parser) {
if (parser.hasNext(3)) {
- int ignition = parser.nextHexInt(0);
+ int ignition = parser.nextHexInt();
if (BitUtil.check(ignition, 4)) {
position.set(Position.KEY_IGNITION, false);
} else if (BitUtil.check(ignition, 5)) {
position.set(Position.KEY_IGNITION, true);
}
- position.set(Position.KEY_INPUT, parser.nextHexInt(0));
- position.set(Position.KEY_OUTPUT, parser.nextHexInt(0));
+ position.set(Position.KEY_INPUT, parser.nextHexInt());
+ position.set(Position.KEY_OUTPUT, parser.nextHexInt());
}
}
@@ -677,12 +682,11 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
LinkedList<Position> positions = new LinkedList<>();
String vin = parser.next();
- int power = parser.nextInt(0);
+ Integer power = parser.nextInt();
Parser itemParser = new Parser(PATTERN_LOCATION, parser.next());
while (itemParser.find()) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_VIN, vin);
@@ -696,15 +700,18 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
decodeLocation(position, parser);
- // power value only on some devices
- if (power > 10) {
- position.set(Position.KEY_POWER, power);
+ if (power != null && power > 10) {
+ position.set(Position.KEY_POWER, power * 0.001); // only on some devices
}
- position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000);
+ if (parser.hasNext()) {
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
+ }
position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
- position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000);
+ if (parser.hasNext()) {
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
+ }
position.set(Position.KEY_HOURS, parser.next());
position.set(Position.PREFIX_ADC + 1, parser.next());
position.set(Position.PREFIX_ADC + 2, parser.next());
@@ -735,14 +742,15 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
return null;
}
+ long mask = parser.nextHexLong();
+
LinkedList<Position> positions = new LinkedList<>();
- int power = parser.nextInt(0);
+ Integer power = parser.nextInt();
Parser itemParser = new Parser(PATTERN_LOCATION, parser.next());
while (itemParser.find()) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
decodeLocation(position, itemParser);
@@ -754,8 +762,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
decodeLocation(position, parser);
- position.set(Position.KEY_POWER, power);
- position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000);
+ if (power != null) {
+ position.set(Position.KEY_POWER, power * 0.001);
+ }
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
position.set(Position.KEY_HOURS, parser.next());
position.set(Position.PREFIX_ADC + 1, parser.next());
position.set(Position.PREFIX_ADC + 2, parser.next());
@@ -765,14 +775,37 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
int index = 0;
String[] data = parser.next().split(",");
- if (data.length > 1) {
- int deviceType = Integer.parseInt(data[index++]);
- if (deviceType == 2) {
- int deviceCount = Integer.parseInt(data[index++]);
- for (int i = 1; i <= deviceCount; i++) {
- index++; // id
- index++; // type
- position.set(Position.PREFIX_TEMP + i, (short) Integer.parseInt(data[index++], 16) * 0.0625);
+
+ index += 1; // device type
+
+ if (BitUtil.check(mask, 0)) {
+ index += 1; // digital fuel sensor data
+ }
+
+ if (BitUtil.check(mask, 1)) {
+ int deviceCount = Integer.parseInt(data[index++]);
+ for (int i = 1; i <= deviceCount; i++) {
+ index += 1; // id
+ index += 1; // type
+ if (!data[index++].isEmpty()) {
+ position.set(Position.PREFIX_TEMP + i, (short) Integer.parseInt(data[index - 1], 16) * 0.0625);
+ }
+ }
+ }
+
+ if (BitUtil.check(mask, 2)) {
+ index += 1; // can data
+ }
+
+ if (BitUtil.check(mask, 3) || BitUtil.check(mask, 4)) {
+ int deviceCount = Integer.parseInt(data[index++]);
+ for (int i = 1; i <= deviceCount; i++) {
+ index += 1; // type
+ if (BitUtil.check(mask, 3)) {
+ position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(data[index++]));
+ }
+ if (BitUtil.check(mask, 4)) {
+ index += 1; // volume
}
}
}
@@ -796,7 +829,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
decodeLocation(position, parser);
position.set(Position.KEY_HOURS, parser.next());
- position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000);
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
decodeDeviceTime(position, parser);
@@ -814,7 +847,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
decodeLocation(position, parser);
- position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000);
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
decodeDeviceTime(position, parser);
@@ -832,7 +865,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
Network network = new Network();
- parser.nextInt(0); // count
+ parser.nextInt(); // count
Matcher matcher = Pattern.compile("([0-9a-fA-F]{12}),(-?\\d+),,,,").matcher(parser.next());
while (matcher.find()) {
String mac = matcher.group(1).replaceAll("(..)", "$1:");
@@ -842,7 +875,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
position.setNetwork(network);
- position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0));
+ position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
return position;
}
@@ -880,7 +913,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- int reportType = parser.nextInt(0);
+ int reportType = parser.nextInt();
if (type.equals("NMR")) {
position.set(Position.KEY_MOTION, reportType == 1);
} else if (type.equals("SOS")) {
@@ -889,10 +922,14 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
decodeLocation(position, parser);
- position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000);
- position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0));
+ if (parser.hasNext()) {
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
+ }
+ position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
- position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000);
+ if (parser.hasNext()) {
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
+ }
decodeDeviceTime(position, parser);
@@ -910,7 +947,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- int hdop = parser.nextInt(0);
+ int hdop = parser.nextInt();
position.setValid(hdop > 0);
position.set(Position.KEY_HDOP, hdop);
@@ -919,8 +956,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
position.setAltitude(parser.nextDouble(0));
if (parser.hasNext(2)) {
- position.setLongitude(parser.nextDouble(0));
- position.setLatitude(parser.nextDouble(0));
+ position.setLongitude(parser.nextDouble());
+ position.setLatitude(parser.nextDouble());
} else {
getLastLocation(position, null);
}
@@ -931,7 +968,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
if (parser.hasNext(4)) {
position.setNetwork(new Network(CellTower.from(
- parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0))));
+ parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt())));
}
decodeDeviceTime(position, parser);
diff --git a/src/org/traccar/protocol/GlobalSatProtocolDecoder.java b/src/org/traccar/protocol/GlobalSatProtocolDecoder.java
index c45a937d4..4361e0c2f 100644
--- a/src/org/traccar/protocol/GlobalSatProtocolDecoder.java
+++ b/src/org/traccar/protocol/GlobalSatProtocolDecoder.java
@@ -76,8 +76,7 @@ public class GlobalSatProtocolDecoder extends BaseProtocolDecoder {
}
String[] values = sentence.split(",");
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
for (int formatIndex = 0, valueIndex = 1; formatIndex < format.length()
&& valueIndex < values.length; formatIndex++) {
@@ -207,8 +206,7 @@ public class GlobalSatProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/GlobeKeeperProtocol.java b/src/org/traccar/protocol/GlobeKeeperProtocol.java
new file mode 100644
index 000000000..9231c067c
--- /dev/null
+++ b/src/org/traccar/protocol/GlobeKeeperProtocol.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 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.bootstrap.ConnectionlessBootstrap;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+
+public class GlobeKeeperProtocol extends BaseProtocol {
+
+ public GlobeKeeperProtocol() {
+ super("globekeeper");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("stringEncoder", new StringEncoder());
+ pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("objectDecoder", new GlobeKeeperProtocolDecoder(GlobeKeeperProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/GlobeKeeperProtocolDecoder.java b/src/org/traccar/protocol/GlobeKeeperProtocolDecoder.java
new file mode 100644
index 000000000..c4daf4409
--- /dev/null
+++ b/src/org/traccar/protocol/GlobeKeeperProtocolDecoder.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018 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.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.util.regex.Pattern;
+
+public class GlobeKeeperProtocolDecoder extends BaseProtocolDecoder {
+
+ public GlobeKeeperProtocolDecoder(GlobeKeeperProtocol protocol) {
+ super(protocol);
+ }
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .number("(d+);") // imei
+ .number("(dddd)-(dd)-(dd) ") // date
+ .number("(dd):(dd):(dd);") // time
+ .number("(-?d+,d+);") // latitude
+ .number("(-?d+,d+);") // longitude
+ .any()
+ .compile();
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ Parser parser = new Parser(PATTERN, (String) msg);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setTime(parser.nextDateTime());
+
+ position.setValid(true);
+ position.setLongitude(Double.parseDouble(parser.next().replace(',', '.')));
+ position.setLatitude(Double.parseDouble(parser.next().replace(',', '.')));
+
+ return position;
+ }
+
+}
diff --git a/src/org/traccar/protocol/GnxProtocolDecoder.java b/src/org/traccar/protocol/GnxProtocolDecoder.java
index 2274ec164..b3a636d14 100644
--- a/src/org/traccar/protocol/GnxProtocolDecoder.java
+++ b/src/org/traccar/protocol/GnxProtocolDecoder.java
@@ -80,8 +80,7 @@ public class GnxProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/org/traccar/protocol/GoSafeProtocolDecoder.java
index 62f6212e2..0fa1934da 100644
--- a/src/org/traccar/protocol/GoSafeProtocolDecoder.java
+++ b/src/org/traccar/protocol/GoSafeProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -45,75 +45,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
.number("(d+),") // imei
.number("(dd)(dd)(dd)") // time (hhmmss)
.number("(dd)(dd)(dd),") // date (ddmmyy)
- .expression("(.*)#?") // data
- .compile();
-
- private static final Pattern PATTERN_ITEM = new PatternBuilder()
- .number("(x+)?,").optional() // event
- .groupBegin()
- .text("SYS:")
- .expression("[^,]*,")
- .groupEnd("?")
- .groupBegin()
- .text("GPS:")
- .expression("([AV]);") // validity
- .number("(d+);") // satellites
- .number("([NS])(d+.d+);") // latitude
- .number("([EW])(d+.d+);") // longitude
- .number("(d+)?;") // speed
- .number("(d+);") // course
- .number("(d+);") // altitude
- .number("(d+.d+)") // hdop
- .number(";(d+.d+)").optional() // vdop
- .expression(",?")
- .groupEnd()
- .groupBegin()
- .text("GSM:")
- .number("d*;") // registration
- .number("d*;") // gsm signal
- .number("(d+);") // mcc
- .number("(d+);") // mnc
- .number("(x+);") // lac
- .number("(x+);") // cid
- .number("(-d+)") // rssi
- .expression("[^,]*,?")
- .groupEnd("?")
- .groupBegin()
- .text("COT:")
- .number("(d+)") // odometer
- .number("(?:;d+:d+:d+)?") // engine hours
- .expression(",?")
- .groupEnd("?")
- .groupBegin()
- .text("ADC:")
- .number("(d+.d+)") // power
- .number("(?:;(d+.d+))?,?") // battery
- .groupEnd("?")
- .groupBegin()
- .text("DTT:")
- .number("(x+);") // status
- .number("(x+)?;") // io
- .number("(x+);") // geo-fence 0-119
- .number("(x+);") // geo-fence 120-155
- .number("(x+)") // event status
- .number("(?:;(x+))?,?") // packet type
- .groupEnd("?")
- .groupBegin()
- .text("ETD:").expression("([^,]+),?")
- .groupEnd("?")
- .groupBegin()
- .text("OBD:")
- .number("(x+),?")
- .groupEnd("?")
- .groupBegin()
- .text("FUL:").expression("[^,]*,?")
- .groupEnd("?")
- .groupBegin()
- .text("TRU:").expression("[^,]*,?")
- .groupEnd("?")
- .groupBegin()
- .text("TAG:").expression("([^,]+),?")
- .groupEnd("?")
+ .expression("([^#]*)#?") // data
.compile();
private static final Pattern PATTERN_OLD = new PatternBuilder()
@@ -133,71 +65,138 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
.any()
.compile();
- private Position decodePosition(DeviceSession deviceSession, Parser parser, Date time) {
+ private void decodeFragment(Position position, String fragment) {
+ int dataIndex = fragment.indexOf(':');
+ int index = 0;
+ String[] values = fragment.substring(dataIndex + 1).split(";");
+ switch (fragment.substring(0, dataIndex)) {
+ case "GPS":
+ position.setValid(values[index++].equals("A"));
+ position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++]));
+ position.setLatitude(Double.parseDouble(values[index].substring(1)));
+ if (values[index++].charAt(0) == 'S') {
+ position.setLatitude(-position.getLatitude());
+ }
+ position.setLongitude(Double.parseDouble(values[index].substring(1)));
+ if (values[index++].charAt(0) == 'W') {
+ position.setLongitude(-position.getLongitude());
+ }
+ if (!values[index++].isEmpty()) {
+ position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(values[index - 1])));
+ }
+ position.setCourse(Integer.parseInt(values[index++]));
+ position.setAltitude(Integer.parseInt(values[index++]));
+ if (index < values.length) {
+ position.set(Position.KEY_HDOP, Double.parseDouble(values[index++]));
+ }
+ if (index < values.length) {
+ position.set(Position.KEY_VDOP, Double.parseDouble(values[index++]));
+ }
+ break;
+ case "GSM":
+ index += 1; // registration status
+ index += 1; // signal strength
+ position.setNetwork(new Network(CellTower.from(
+ Integer.parseInt(values[index++]), Integer.parseInt(values[index++]),
+ Integer.parseInt(values[index++], 16), Integer.parseInt(values[index++], 16),
+ Integer.parseInt(values[index++]))));
+ break;
+ case "COT":
+ if (index < values.length) {
+ position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index++]));
+ }
+ if (index < values.length) {
+ String[] hours = values[index].split("-");
+ position.set(Position.KEY_HOURS, Integer.parseInt(hours[0])
+ + Integer.parseInt(hours[0]) / 60.0 + Integer.parseInt(hours[0]) / 3600.0);
+ }
+ break;
+ case "ADC":
+ position.set(Position.KEY_POWER, Double.parseDouble(values[index++]));
+ if (index < values.length) {
+ position.set(Position.KEY_BATTERY, Double.parseDouble(values[index++]));
+ }
+ if (index < values.length) {
+ position.set(Position.PREFIX_ADC + 1, Double.parseDouble(values[index++]));
+ }
+ if (index < values.length) {
+ position.set(Position.PREFIX_ADC + 2, Double.parseDouble(values[index++]));
+ }
+ break;
+ case "DTT":
+ position.set(Position.KEY_STATUS, Integer.parseInt(values[index++], 16));
+ if (!values[index++].isEmpty()) {
+ int io = Integer.parseInt(values[index - 1], 16);
+ position.set(Position.KEY_IGNITION, BitUtil.check(io, 0));
+ position.set(Position.PREFIX_IN + 1, BitUtil.check(io, 1));
+ position.set(Position.PREFIX_IN + 2, BitUtil.check(io, 2));
+ position.set(Position.PREFIX_IN + 3, BitUtil.check(io, 3));
+ position.set(Position.PREFIX_IN + 4, BitUtil.check(io, 4));
+ position.set(Position.PREFIX_OUT + 1, BitUtil.check(io, 5));
+ position.set(Position.PREFIX_OUT + 2, BitUtil.check(io, 6));
+ position.set(Position.PREFIX_OUT + 3, BitUtil.check(io, 7));
+ }
+ position.set(Position.KEY_GEOFENCE, values[index++] + values[index++]);
+ position.set("eventStatus", values[index++]);
+ if (index < values.length) {
+ position.set("packetType", values[index++]);
+ }
+ break;
+ case "ETD":
+ position.set("eventData", values[index++]);
+ break;
+ case "OBD":
+ position.set("obd", values[index++]);
+ break;
+ case "TAG":
+ position.set("tagData", values[index++]);
+ break;
+ case "IWD":
+ if (index < values.length && values[index + 1].equals("0")) {
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, values[index + 2]);
+ }
+ break;
+ default:
+ break;
+ }
+ }
- Position position = new Position();
- position.setProtocol(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
+ private Object decodeData(DeviceSession deviceSession, Date time, String data) {
- if (time != null) {
- position.setTime(time);
- }
+ List<Position> positions = new LinkedList<>();
+ Position position = null;
+ int index = 0;
+ String[] fragments = data.split(",");
- position.set(Position.KEY_EVENT, parser.next());
+ while (index < fragments.length) {
- position.setValid(parser.next().equals("A"));
- position.set(Position.KEY_SATELLITES, parser.nextInt());
+ if (fragments[index].isEmpty() || Character.isDigit(fragments[index].charAt(0))) {
- position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG));
- position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG));
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
- position.setCourse(parser.nextDouble(0));
- position.setAltitude(parser.nextDouble(0));
+ if (position != null) {
+ positions.add(position);
+ }
- position.set(Position.KEY_HDOP, parser.nextDouble(0));
- position.set(Position.KEY_VDOP, parser.nextDouble(0));
+ position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+ position.setTime(time);
- if (parser.hasNext(5)) {
- position.setNetwork(new Network(CellTower.from(parser.nextInt(0), parser.nextInt(0),
- parser.nextHexInt(0), parser.nextHexInt(0), parser.nextInt(0))));
- }
- if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextInt(0));
- }
- position.set(Position.KEY_POWER, parser.nextDouble());
- position.set(Position.KEY_BATTERY, parser.nextDouble());
-
- if (parser.hasNext(6)) {
- position.set(Position.KEY_STATUS, parser.nextHexLong());
- Integer io = parser.nextHexInt();
- if (io != null) {
- position.set(Position.KEY_IGNITION, BitUtil.check(io, 0));
- position.set(Position.PREFIX_IN + 1, BitUtil.check(io, 1));
- position.set(Position.PREFIX_IN + 2, BitUtil.check(io, 2));
- position.set(Position.PREFIX_IN + 3, BitUtil.check(io, 3));
- position.set(Position.PREFIX_IN + 4, BitUtil.check(io, 4));
- position.set(Position.PREFIX_OUT + 1, BitUtil.check(io, 5));
- position.set(Position.PREFIX_OUT + 2, BitUtil.check(io, 6));
- position.set(Position.PREFIX_OUT + 3, BitUtil.check(io, 7));
- }
- position.set(Position.KEY_GEOFENCE, parser.next() + parser.next());
- position.set("eventStatus", parser.next());
- position.set("packetType", parser.next());
- }
+ if (!fragments[index++].isEmpty()) {
+ position.set(Position.KEY_EVENT, Integer.parseInt(fragments[index - 1]));
+ }
- if (parser.hasNext()) {
- position.set("eventData", parser.next());
- }
+ } else {
+
+ decodeFragment(position, fragments[index++]);
+
+ }
- if (parser.hasNext()) {
- position.set("obd", parser.next());
}
- if (parser.hasNext()) {
- position.set("tagData", parser.next());
+ if (position != null) {
+ positions.add(position);
}
- return position;
+ return positions;
}
@Override
@@ -226,8 +225,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
if (pattern == PATTERN_OLD) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -248,18 +246,12 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
} else {
- Date time = null;
+ Date time = new Date();
if (parser.hasNext(6)) {
time = parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY);
}
- List<Position> positions = new LinkedList<>();
- Parser itemParser = new Parser(PATTERN_ITEM, parser.next());
- while (itemParser.find()) {
- positions.add(decodePosition(deviceSession, itemParser, time));
- }
-
- return positions;
+ return decodeData(deviceSession, time, parser.next());
}
}
diff --git a/src/org/traccar/protocol/GotopProtocolDecoder.java b/src/org/traccar/protocol/GotopProtocolDecoder.java
index f938887e2..29e8d87dd 100644
--- a/src/org/traccar/protocol/GotopProtocolDecoder.java
+++ b/src/org/traccar/protocol/GotopProtocolDecoder.java
@@ -55,8 +55,7 @@ public class GotopProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/Gps056ProtocolDecoder.java b/src/org/traccar/protocol/Gps056ProtocolDecoder.java
index 7248365b0..ccb389250 100644
--- a/src/org/traccar/protocol/Gps056ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gps056ProtocolDecoder.java
@@ -93,8 +93,7 @@ public class Gps056ProtocolDecoder extends BaseProtocolDecoder {
} else if (type.startsWith("GPSL")) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -116,8 +115,7 @@ public class Gps056ProtocolDecoder extends BaseProtocolDecoder {
} else if (type.startsWith("SYNC")) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java
index 099047aa0..f32d22c00 100644
--- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gps103ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2018 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.
@@ -26,6 +26,7 @@ import org.traccar.model.Network;
import org.traccar.model.Position;
import java.net.SocketAddress;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Gps103ProtocolDecoder extends BaseProtocolDecoder {
@@ -38,10 +39,19 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder {
.text("imei:")
.number("(d+),") // imei
.expression("([^,]+),") // alarm
+ .groupBegin()
.number("(dd)/?(dd)/?(dd) ?") // local date (yymmdd)
.number("(dd):?(dd)(?:dd)?,") // local time (hhmmss)
+ .or()
+ .number("d*,")
+ .groupEnd()
.expression("([^,]+)?,") // rfid
- .expression("[FL],") // full / low
+ .groupBegin()
+ .text("L,,,")
+ .number("(x+),,") // lac
+ .number("(x+),,,") // cid
+ .or()
+ .text("F,")
.groupBegin()
.number("(dd)(dd)(dd).d+") // time utc (hhmmss)
.or()
@@ -63,24 +73,10 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder {
.expression("([^,;]+)?,?")
.expression("([^,;]+)?,?")
.expression("([^,;]+)?,?")
+ .groupEnd()
.any()
.compile();
- private static final Pattern PATTERN_NETWORK = new PatternBuilder()
- .text("imei:")
- .number("(d+),") // imei
- .expression("[^,]+,") // alarm
- .number("d*,,")
- .text("L,,,")
- .number("(x+),,") // lac
- .number("(x+),,,") // cid
- .any()
- .compile();
-
- private static final Pattern PATTERN_HANDSHAKE = new PatternBuilder()
- .number("##,imei:(d+),A")
- .compile();
-
private static final Pattern PATTERN_OBD = new PatternBuilder()
.text("imei:")
.number("(d+),") // imei
@@ -143,86 +139,9 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder {
}
}
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
-
- String sentence = (String) msg;
-
- // Send response #1
- if (sentence.contains("##")) {
- if (channel != null) {
- channel.write("LOAD", remoteAddress);
- Parser handshakeParser = new Parser(PATTERN_HANDSHAKE, sentence);
- if (handshakeParser.matches()) {
- getDeviceSession(channel, remoteAddress, handshakeParser.next());
- }
- }
- return null;
- }
-
- // Send response #2
- if (!sentence.isEmpty() && Character.isDigit(sentence.charAt(0))) {
- if (channel != null) {
- channel.write("ON", remoteAddress);
- }
- int start = sentence.indexOf("imei:");
- if (start >= 0) {
- sentence = sentence.substring(start);
- } else {
- return null;
- }
- }
+ private Position decodeRegular(Channel channel, SocketAddress remoteAddress, String sentence) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
-
- Parser 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.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0))));
-
- return position;
-
- }
-
- parser = new Parser(PATTERN_OBD, sentence);
- if (parser.matches()) {
-
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession == null) {
- return null;
- }
- position.setDeviceId(deviceSession.getDeviceId());
-
- getLastLocation(position, parser.nextDateTime());
-
- position.set(Position.KEY_ODOMETER, parser.nextInt(0));
- parser.nextDouble(0); // instant fuel consumption
- position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextDouble(0));
- position.set(Position.KEY_HOURS, parser.nextInt());
- position.set(Position.KEY_OBD_SPEED, parser.nextInt(0));
- position.set(Position.KEY_ENGINE_LOAD, parser.next());
- position.set(Position.KEY_COOLANT_TEMP, parser.nextInt());
- position.set(Position.KEY_THROTTLE, parser.next());
- position.set(Position.KEY_RPM, parser.nextInt(0));
- position.set(Position.KEY_BATTERY, parser.nextDouble(0));
- position.set(Position.KEY_DTCS, parser.next().replace(',', ' ').trim());
-
- return position;
-
- }
-
- parser = new Parser(PATTERN, sentence);
+ Parser parser = new Parser(PATTERN, sentence);
if (!parser.matches()) {
return null;
}
@@ -232,6 +151,8 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder {
if (deviceSession == null) {
return null;
}
+
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
String alarm = parser.next();
@@ -263,36 +184,115 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid);
}
- String utcHours = parser.next();
- String utcMinutes = parser.next();
+ if (parser.hasNext(2)) {
- dateBuilder.setTime(localHours, localMinutes, parser.nextInt(0));
+ getLastLocation(position, null);
- // Timezone calculation
- if (utcHours != null && utcMinutes != null) {
- int deltaMinutes = (localHours - Integer.parseInt(utcHours)) * 60;
- deltaMinutes += localMinutes - Integer.parseInt(utcMinutes);
- if (deltaMinutes <= -12 * 60) {
- deltaMinutes += 24 * 60;
- } else if (deltaMinutes > 12 * 60) {
- deltaMinutes -= 24 * 60;
+ position.setNetwork(new Network(CellTower.fromLacCid(parser.nextHexInt(0), parser.nextHexInt(0))));
+
+ } else {
+
+ String utcHours = parser.next();
+ String utcMinutes = parser.next();
+
+ dateBuilder.setTime(localHours, localMinutes, parser.nextInt(0));
+
+ // Timezone calculation
+ if (utcHours != null && utcMinutes != null) {
+ int deltaMinutes = (localHours - Integer.parseInt(utcHours)) * 60;
+ deltaMinutes += localMinutes - Integer.parseInt(utcMinutes);
+ if (deltaMinutes <= -12 * 60) {
+ deltaMinutes += 24 * 60;
+ } else if (deltaMinutes > 12 * 60) {
+ deltaMinutes -= 24 * 60;
+ }
+ dateBuilder.addMinute(-deltaMinutes);
+ }
+ position.setTime(dateBuilder.getDate());
+
+ position.setValid(parser.next().equals("A"));
+ position.setFixTime(position.getDeviceTime());
+ position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_HEM));
+ position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_HEM));
+ position.setSpeed(parser.nextDouble(0));
+ position.setCourse(parser.nextDouble(0));
+ position.setAltitude(parser.nextDouble(0));
+
+ for (int i = 1; i <= 5; i++) {
+ position.set(Position.PREFIX_IO + i, parser.next());
}
- dateBuilder.addMinute(-deltaMinutes);
+
}
- position.setTime(dateBuilder.getDate());
- position.setValid(parser.next().equals("A"));
- position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_HEM));
- position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN_HEM));
- position.setSpeed(parser.nextDouble(0));
- position.setCourse(parser.nextDouble(0));
- position.setAltitude(parser.nextDouble(0));
+ return position;
+ }
+
+ private Position decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) {
+
+ Parser parser = new Parser(PATTERN_OBD, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
- for (int i = 1; i <= 5; i++) {
- position.set(Position.PREFIX_IO + i, parser.next());
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ if (deviceSession == null) {
+ return null;
}
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ getLastLocation(position, parser.nextDateTime());
+
+ position.set(Position.KEY_ODOMETER, parser.nextInt(0));
+ parser.nextDouble(0); // instant fuel consumption
+ position.set(Position.KEY_FUEL_CONSUMPTION, parser.nextDouble(0));
+ position.set(Position.KEY_HOURS, parser.nextInt());
+ position.set(Position.KEY_OBD_SPEED, parser.nextInt(0));
+ position.set(Position.KEY_ENGINE_LOAD, parser.next());
+ position.set(Position.KEY_COOLANT_TEMP, parser.nextInt());
+ position.set(Position.KEY_THROTTLE, parser.next());
+ position.set(Position.KEY_RPM, parser.nextInt(0));
+ position.set(Position.KEY_BATTERY, parser.nextDouble(0));
+ position.set(Position.KEY_DTCS, parser.next().replace(',', ' ').trim());
+
return position;
}
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ String sentence = (String) msg;
+
+ if (sentence.contains("##")) {
+ if (channel != null) {
+ channel.write("LOAD", remoteAddress);
+ Matcher matcher = Pattern.compile("##,imei:(\\d+),A").matcher(sentence);
+ if (matcher.matches()) {
+ getDeviceSession(channel, remoteAddress, matcher.group(1));
+ }
+ }
+ return null;
+ }
+
+ if (!sentence.isEmpty() && Character.isDigit(sentence.charAt(0))) {
+ if (channel != null) {
+ channel.write("ON", remoteAddress);
+ }
+ int start = sentence.indexOf("imei:");
+ if (start >= 0) {
+ sentence = sentence.substring(start);
+ } else {
+ return null;
+ }
+ }
+
+ if (sentence.contains("OBD")) {
+ return decodeObd(channel, remoteAddress, sentence);
+ } else {
+ return decodeRegular(channel, remoteAddress, sentence);
+ }
+ }
+
}
diff --git a/src/org/traccar/protocol/GpsGateProtocolDecoder.java b/src/org/traccar/protocol/GpsGateProtocolDecoder.java
index ca1d6453e..5c7096276 100644
--- a/src/org/traccar/protocol/GpsGateProtocolDecoder.java
+++ b/src/org/traccar/protocol/GpsGateProtocolDecoder.java
@@ -118,8 +118,7 @@ public class GpsGateProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -143,8 +142,7 @@ public class GpsGateProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java b/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java
index f65f5b2bb..ca5bdcbed 100644
--- a/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java
+++ b/src/org/traccar/protocol/GpsMarkerProtocolDecoder.java
@@ -61,8 +61,7 @@ public class GpsMarkerProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/GpsmtaProtocolDecoder.java b/src/org/traccar/protocol/GpsmtaProtocolDecoder.java
index 11777bece..c71162078 100644
--- a/src/org/traccar/protocol/GpsmtaProtocolDecoder.java
+++ b/src/org/traccar/protocol/GpsmtaProtocolDecoder.java
@@ -57,8 +57,7 @@ public class GpsmtaProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/GranitProtocolDecoder.java b/src/org/traccar/protocol/GranitProtocolDecoder.java
index 8e935ae9e..50d879bb4 100644
--- a/src/org/traccar/protocol/GranitProtocolDecoder.java
+++ b/src/org/traccar/protocol/GranitProtocolDecoder.java
@@ -158,8 +158,7 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder {
if (deviceSession != null && indexTilde == -1) {
String bufString = buf.toString(StandardCharsets.US_ASCII);
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date());
@@ -186,8 +185,7 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder {
if (channel != null) {
sendResponseCurrent(channel, deviceId, unixTime);
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date(unixTime * 1000));
@@ -219,8 +217,7 @@ public class GranitProtocolDecoder extends BaseProtocolDecoder {
int timeIncrement = buf.getUnsignedShort(buf.readerIndex() + 120);
for (int i = 0; i < 6; i++) {
if (buf.getUnsignedByte(buf.readerIndex()) != 0xFE) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date((unixTime + i * timeIncrement) * 1000));
decodeStructure(buf, position);
diff --git a/src/org/traccar/protocol/Gt02ProtocolDecoder.java b/src/org/traccar/protocol/Gt02ProtocolDecoder.java
index a520bff13..a4f1a4161 100644
--- a/src/org/traccar/protocol/Gt02ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gt02ProtocolDecoder.java
@@ -47,8 +47,7 @@ public class Gt02ProtocolDecoder extends BaseProtocolDecoder {
buf.skipBytes(2); // header
buf.readByte(); // size
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
// Zero for location messages
int power = buf.readUnsignedByte();
diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java
index 37f64ee02..3e5ebc8c5 100644
--- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2018 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.
@@ -44,20 +44,10 @@ import java.util.regex.Pattern;
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);
-
- if (Context.getConfig().hasKey(getProtocolName() + ".timezone")) {
- forceTimeZone = true;
- timeZone.setRawOffset(Context.getConfig().getInteger(getProtocolName() + ".timezone") * 1000);
- }
}
public static final int MSG_LOGIN = 0x01;
@@ -172,7 +162,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
}
}
- private void sendResponse(Channel channel, boolean extended, int type, ChannelBuffer content) {
+ private void sendResponse(Channel channel, boolean extended, int type, int index, ChannelBuffer content) {
if (channel != null) {
ChannelBuffer response = ChannelBuffers.dynamicBuffer();
int length = 5 + (content != null ? content.readableBytes() : 0);
@@ -187,7 +177,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
if (content != null) {
response.writeBytes(content);
}
- response.writeShort(++serverIndex);
+ response.writeShort(index);
response.writeShort(Checksum.crc16(Checksum.CRC16_X25,
response.toByteBuffer(2, response.writerIndex() - 2)));
response.writeByte('\r'); response.writeByte('\n'); // ending
@@ -201,12 +191,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
content.writeInt(pictureId);
content.writeInt(photo.writerIndex());
content.writeShort(Math.min(photo.writableBytes(), 1024));
- sendResponse(channel, false, MSG_X1_PHOTO_DATA, content);
+ sendResponse(channel, false, MSG_X1_PHOTO_DATA, 0, content);
}
- private boolean decodeGps(Position position, ChannelBuffer buf, boolean hasLength) {
+ private boolean decodeGps(Position position, ChannelBuffer buf, boolean hasLength, TimeZone timezone) {
- DateBuilder dateBuilder = new DateBuilder(timeZone)
+ DateBuilder dateBuilder = new DateBuilder(timezone)
.setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
.setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte());
position.setTime(dateBuilder.getDate());
@@ -389,6 +379,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
if (deviceSession == null) {
return null;
}
+ if (deviceSession.getTimeZone() == null) {
+ deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId()));
+ }
}
if (type == MSG_LOGIN) {
@@ -396,6 +389,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1);
buf.readUnsignedShort(); // type
+ deviceSession = getDeviceSession(channel, remoteAddress, imei);
+ if (deviceSession != null && deviceSession.getTimeZone() == null) {
+ deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId()));
+ }
+
if (dataLength > 10) {
int extensionBits = buf.readUnsignedShort();
int hours = (extensionBits >> 4) / 100;
@@ -404,20 +402,24 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
if ((extensionBits & 0x8) != 0) {
offset = -offset;
}
- if (!forceTimeZone) {
- timeZone.setRawOffset(offset * 1000);
+ if (deviceSession != null) {
+ TimeZone timeZone = deviceSession.getTimeZone();
+ if (timeZone.getRawOffset() == 0) {
+ timeZone.setRawOffset(offset * 1000);
+ deviceSession.setTimeZone(timeZone);
+ }
}
+
}
- if (getDeviceSession(channel, remoteAddress, imei) != null) {
- sendResponse(channel, false, type, null);
+ if (deviceSession != null) {
+ sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null);
}
} else if (type == MSG_HEARTBEAT) {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
getLastLocation(position, null);
@@ -426,7 +428,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_IGNITION, BitUtil.check(status, 1));
position.set(Position.KEY_CHARGE, BitUtil.check(status, 2));
- sendResponse(channel, false, type, null);
+ sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null);
return position;
@@ -437,7 +439,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
content.writeByte(response.length());
content.writeInt(0);
content.writeBytes(response.getBytes(StandardCharsets.US_ASCII));
- sendResponse(channel, true, MSG_ADDRESS_RESPONSE, content);
+ sendResponse(channel, true, MSG_ADDRESS_RESPONSE, 0, content);
} else if (type == MSG_TIME_REQUEST) {
@@ -449,17 +451,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
content.writeByte(calendar.get(Calendar.HOUR_OF_DAY));
content.writeByte(calendar.get(Calendar.MINUTE));
content.writeByte(calendar.get(Calendar.SECOND));
- sendResponse(channel, false, MSG_TIME_REQUEST, content);
+ sendResponse(channel, false, MSG_TIME_REQUEST, 0, content);
} else if (type == MSG_X1_GPS) {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
buf.readUnsignedInt(); // data and alarm
- decodeGps(position, buf, false);
+ decodeGps(position, buf, false, deviceSession.getTimeZone());
buf.readUnsignedShort(); // terminal info
@@ -501,9 +502,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
private Object decodeWifi(ChannelBuffer buf, DeviceSession deviceSession) throws Exception {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
DateBuilder dateBuilder = new DateBuilder()
.setYear(BcdUtil.readInteger(buf, 2))
@@ -540,16 +540,15 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
private Object decodeBasicOther(Channel channel, ChannelBuffer buf,
DeviceSession deviceSession, int type, int dataLength) throws Exception {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
if (type == MSG_LBS_MULTIPLE || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI
|| type == MSG_LBS_2 || type == MSG_WIFI_3) {
boolean longFormat = type == MSG_LBS_2 || type == MSG_WIFI_3;
- DateBuilder dateBuilder = new DateBuilder(timeZone)
+ DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone())
.setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
.setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte());
@@ -595,7 +594,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
} else if (isSupported(type)) {
if (hasGps(type)) {
- decodeGps(position, buf, false);
+ decodeGps(position, buf, false, deviceSession.getTimeZone());
} else {
getLastLocation(position, null);
}
@@ -622,7 +621,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
buf.skipBytes(dataLength);
if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) {
- sendResponse(channel, false, type, null);
+ sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null);
}
return null;
@@ -636,7 +635,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_GEOFENCE, buf.readUnsignedByte());
}
- sendResponse(channel, false, type, null);
+ sendResponse(channel, false, type, buf.getShort(buf.writerIndex() - 6), null);
return position;
}
@@ -648,9 +647,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
+ if (deviceSession.getTimeZone() == null) {
+ deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId()));
+ }
+
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
buf.readUnsignedShort(); // length
int type = buf.readUnsignedByte();
@@ -711,13 +713,14 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
sendPhotoRequest(channel, pictureId);
} else {
Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId());
- Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg");
+ position.set(
+ Position.KEY_IMAGE, 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)) {
+ if (!decodeGps(position, buf, true, deviceSession.getTimeZone())) {
getLastLocation(position, position.getDeviceTime());
}
@@ -756,7 +759,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
buf.skipBytes(buf.readUnsignedByte()); // reserved extension
- sendResponse(channel, true, type, null);
+ sendResponse(channel, true, type, buf.getShort(buf.writerIndex() - 6), null);
return position;
diff --git a/src/org/traccar/protocol/Gt30ProtocolDecoder.java b/src/org/traccar/protocol/Gt30ProtocolDecoder.java
index 51135c80a..27081a108 100644
--- a/src/org/traccar/protocol/Gt30ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gt30ProtocolDecoder.java
@@ -84,8 +84,7 @@ public class Gt30ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (parser.hasNext()) {
diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java
index 4414870d2..9764adf04 100644
--- a/src/org/traccar/protocol/H02ProtocolDecoder.java
+++ b/src/org/traccar/protocol/H02ProtocolDecoder.java
@@ -101,8 +101,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
private Position decodeBinary(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
buf.readByte(); // marker
@@ -267,8 +266,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (parser.hasNext()) {
@@ -348,8 +346,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -388,8 +385,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -422,8 +418,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -461,7 +456,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
switch (marker) {
case "*":
- String sentence = buf.toString(StandardCharsets.US_ASCII);
+ String sentence = buf.toString(StandardCharsets.US_ASCII).trim();
int typeStart = sentence.indexOf(',', sentence.indexOf(',') + 1) + 1;
int typeEnd = sentence.indexOf(',', typeStart);
if (typeEnd > 0) {
diff --git a/src/org/traccar/protocol/HaicomProtocolDecoder.java b/src/org/traccar/protocol/HaicomProtocolDecoder.java
index 37898a9bc..94ec93cfb 100644
--- a/src/org/traccar/protocol/HaicomProtocolDecoder.java
+++ b/src/org/traccar/protocol/HaicomProtocolDecoder.java
@@ -62,8 +62,7 @@ public class HaicomProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/HomtecsProtocolDecoder.java b/src/org/traccar/protocol/HomtecsProtocolDecoder.java
index 508de173c..f4ae54d1f 100644
--- a/src/org/traccar/protocol/HomtecsProtocolDecoder.java
+++ b/src/org/traccar/protocol/HomtecsProtocolDecoder.java
@@ -66,8 +66,7 @@ public class HomtecsProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(parser.nextDateTime(Parser.DateTimeFormat.YMD_HMS));
diff --git a/src/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/org/traccar/protocol/HuaShengProtocolDecoder.java
index 96f87fd94..88f23b28c 100644
--- a/src/org/traccar/protocol/HuaShengProtocolDecoder.java
+++ b/src/org/traccar/protocol/HuaShengProtocolDecoder.java
@@ -103,8 +103,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
int status = buf.readUnsignedShort();
diff --git a/src/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/org/traccar/protocol/HuabaoProtocolDecoder.java
index c31c6af1c..8643f39af 100644
--- a/src/org/traccar/protocol/HuabaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/HuabaoProtocolDecoder.java
@@ -129,8 +129,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder {
} else if (type == MSG_LOCATION_REPORT) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedInt()));
diff --git a/src/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/org/traccar/protocol/HuabaoProtocolEncoder.java
index 7d6f0510d..d1889bf5e 100644
--- a/src/org/traccar/protocol/HuabaoProtocolEncoder.java
+++ b/src/org/traccar/protocol/HuabaoProtocolEncoder.java
@@ -18,10 +18,10 @@ package org.traccar.protocol;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.traccar.BaseProtocolEncoder;
+import org.traccar.helper.DataConverter;
import org.traccar.helper.Log;
import org.traccar.model.Command;
-import javax.xml.bind.DatatypeConverter;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -31,10 +31,10 @@ public class HuabaoProtocolEncoder extends BaseProtocolEncoder {
protected Object encodeCommand(Command command) {
ChannelBuffer id = ChannelBuffers.wrappedBuffer(
- DatatypeConverter.parseHexBinary(getUniqueId(command.getDeviceId())));
+ DataConverter.parseHex(getUniqueId(command.getDeviceId())));
ChannelBuffer data = ChannelBuffers.dynamicBuffer();
- byte[] time = DatatypeConverter.parseHexBinary(new SimpleDateFormat("yyMMddHHmmss").format(new Date()));
+ byte[] time = DataConverter.parseHex(new SimpleDateFormat("yyMMddHHmmss").format(new Date()));
switch (command.getType()) {
case Command.TYPE_ENGINE_STOP:
diff --git a/src/org/traccar/protocol/HunterProProtocolDecoder.java b/src/org/traccar/protocol/HunterProProtocolDecoder.java
index b1e3f84a2..fa470c065 100644
--- a/src/org/traccar/protocol/HunterProProtocolDecoder.java
+++ b/src/org/traccar/protocol/HunterProProtocolDecoder.java
@@ -56,8 +56,7 @@ public class HunterProProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/IdplProtocolDecoder.java b/src/org/traccar/protocol/IdplProtocolDecoder.java
index e56a0f022..9990e0da5 100644
--- a/src/org/traccar/protocol/IdplProtocolDecoder.java
+++ b/src/org/traccar/protocol/IdplProtocolDecoder.java
@@ -69,8 +69,7 @@ public class IdplProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_TYPE, parser.nextInt(0));
diff --git a/src/org/traccar/protocol/IntellitracProtocolDecoder.java b/src/org/traccar/protocol/IntellitracProtocolDecoder.java
index 4a526376e..5b66fa7ec 100644
--- a/src/org/traccar/protocol/IntellitracProtocolDecoder.java
+++ b/src/org/traccar/protocol/IntellitracProtocolDecoder.java
@@ -72,8 +72,7 @@ public class IntellitracProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/Ivt401ProtocolDecoder.java b/src/org/traccar/protocol/Ivt401ProtocolDecoder.java
index f209ee09e..d2f1d3d69 100644
--- a/src/org/traccar/protocol/Ivt401ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Ivt401ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2018 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.
@@ -43,7 +43,7 @@ public class Ivt401ProtocolDecoder extends BaseProtocolDecoder {
.number("(d+),") // speed
.number("(d+),") // course
.number("(-?d+.?d*),") // altitude
- .number("(d+),") // satellites
+ .number("d+,") // satellites or battery status
.number("(d),") // gps status
.number("(d+),") // rssi
.number("(d+),") // input
@@ -51,6 +51,30 @@ public class Ivt401ProtocolDecoder extends BaseProtocolDecoder {
.number("(d+.d+),") // adc
.number("(d+.d+),") // power
.number("(d+.d+),") // battery
+ .number("(-?d+.?d*),") // pcb temp
+ .expression("([^,]+),") // temp
+ .number("(d+),") // movement
+ .number("(d+.d+),") // acceleration
+ .number("(-?d+),") // tilt
+ .number("(d+),") // trip
+ .number("(d+),") // odometer
+ .groupBegin()
+ .number("([01]),") // overspeed
+ .number("[01],") // input 2 misuse
+ .number("[01],") // immobilizer
+ .number("[01],") // temperature alert
+ .number("[0-2]+,") // geofence
+ .number("([0-3]),") // harsh driving
+ .number("[01],") // reconnect
+ .number("([01]),") // low battery
+ .number("([01]),") // power disconnected
+ .number("[01],") // gps failure
+ .number("([01]),") // towing
+ .number("[01],") // server unreachable
+ .number("[128],") // sleep mode
+ .expression("([^,]+)?,") // driver id
+ .number("d+,") // sms count
+ .groupEnd("?")
.any()
.compile();
@@ -68,8 +92,7 @@ public class Ivt401ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
@@ -79,17 +102,79 @@ public class Ivt401ProtocolDecoder extends BaseProtocolDecoder {
position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt()));
position.setCourse(parser.nextInt());
position.setAltitude(parser.nextDouble());
-
- position.set(Position.KEY_SATELLITES, parser.nextInt());
-
position.setValid(parser.nextInt() > 0);
position.set(Position.KEY_RSSI, parser.nextInt());
- position.set(Position.KEY_INPUT, parser.nextBinInt());
- position.set(Position.KEY_OUTPUT, parser.nextBinInt());
+
+ String input = parser.next();
+ for (int i = 0; i < input.length(); i++) {
+ int value = Character.getNumericValue(input.charAt(i));
+ if (value < 2) {
+ position.set(Position.PREFIX_IN + (i + 1), value > 0);
+ }
+ }
+
+ String output = parser.next();
+ for (int i = 0; i < output.length(); i++) {
+ position.set(Position.PREFIX_OUT + (i + 1), Character.getNumericValue(output.charAt(i)) > 0);
+ }
+
position.set(Position.PREFIX_ADC + 1, parser.nextDouble());
position.set(Position.KEY_POWER, parser.nextDouble());
position.set(Position.KEY_BATTERY, parser.nextDouble());
+ position.set(Position.KEY_DEVICE_TEMP, parser.nextDouble());
+
+ String temp = parser.next();
+ if (temp.startsWith("M")) {
+ int index = 1;
+ int startIndex = 1;
+ int endIndex;
+ while (startIndex < temp.length()) {
+ endIndex = temp.indexOf('-', startIndex + 1);
+ if (endIndex < 0) {
+ endIndex = temp.indexOf('+', startIndex + 1);
+ }
+ if (endIndex < 0) {
+ endIndex = temp.length();
+ }
+ if (endIndex > 0) {
+ double value = Double.parseDouble(temp.substring(startIndex, endIndex));
+ position.set(Position.PREFIX_TEMP + index++, value);
+ }
+ startIndex = endIndex;
+ }
+ } else {
+ position.set(Position.PREFIX_TEMP + 1, Double.parseDouble(temp));
+ }
+
+ position.set(Position.KEY_MOTION, parser.nextInt() > 0);
+ position.set(Position.KEY_ACCELERATION, parser.nextDouble());
+
+ parser.nextInt(); // tilt
+ parser.nextInt(); // trip state
+
+ position.set(Position.KEY_ODOMETER, parser.nextLong());
+
+ if (parser.hasNext(6)) {
+ position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_OVERSPEED : null);
+ switch (parser.nextInt()) {
+ case 1:
+ position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION);
+ break;
+ case 2:
+ position.set(Position.KEY_ALARM, Position.ALARM_BRAKING);
+ break;
+ case 3:
+ position.set(Position.KEY_ALARM, Position.ALARM_CORNERING);
+ break;
+ default:
+ break;
+ }
+ position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_LOW_BATTERY : null);
+ position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_POWER_CUT : null);
+ position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_TOW : null);
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
+ }
return position;
}
diff --git a/src/org/traccar/protocol/JpKorjarProtocolDecoder.java b/src/org/traccar/protocol/JpKorjarProtocolDecoder.java
index 654b3e3d0..8766115ce 100644
--- a/src/org/traccar/protocol/JpKorjarProtocolDecoder.java
+++ b/src/org/traccar/protocol/JpKorjarProtocolDecoder.java
@@ -60,8 +60,7 @@ public class JpKorjarProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java
index e935c1449..f5d8a79a4 100644
--- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java
@@ -73,8 +73,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder {
while (buf.readableBytes() > 1) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -215,8 +214,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setLongitude(parser.nextCoordinate());
@@ -274,8 +272,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder {
String type = parser.next();
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
diff --git a/src/org/traccar/protocol/KenjiProtocolDecoder.java b/src/org/traccar/protocol/KenjiProtocolDecoder.java
index 4216da0c3..374cb9c25 100644
--- a/src/org/traccar/protocol/KenjiProtocolDecoder.java
+++ b/src/org/traccar/protocol/KenjiProtocolDecoder.java
@@ -76,8 +76,7 @@ public class KenjiProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/KhdProtocolDecoder.java b/src/org/traccar/protocol/KhdProtocolDecoder.java
index d63219736..2f29a16f8 100644
--- a/src/org/traccar/protocol/KhdProtocolDecoder.java
+++ b/src/org/traccar/protocol/KhdProtocolDecoder.java
@@ -36,17 +36,10 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder {
private String readSerialNumber(ChannelBuffer buf) {
int b1 = buf.readUnsignedByte();
- int b2 = buf.readUnsignedByte();
- if (b2 > 0x80) {
- b2 -= 0x80;
- }
- int b3 = buf.readUnsignedByte();
- if (b3 > 0x80) {
- b3 -= 0x80;
- }
+ int b2 = buf.readUnsignedByte() - 0x80;
+ int b3 = buf.readUnsignedByte() - 0x80;
int b4 = buf.readUnsignedByte();
- String serialNumber = String.format("%02d%02d%02d%02d", b1, b2, b3, b4);
- return String.valueOf(Long.parseLong(serialNumber));
+ return String.format("%02d%02d%02d%02d", b1, b2, b3, b4);
}
public static final int MSG_LOGIN = 0xB1;
@@ -71,8 +64,7 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder {
if (type == MSG_ON_DEMAND || type == MSG_POSITION_UPLOAD || type == MSG_POSITION_REUPLOAD
|| type == MSG_ALARM || type == MSG_REPLY || type == MSG_PERIPHERAL) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, readSerialNumber(buf));
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/KhdProtocolEncoder.java b/src/org/traccar/protocol/KhdProtocolEncoder.java
index 618e43dad..cb26c757a 100644
--- a/src/org/traccar/protocol/KhdProtocolEncoder.java
+++ b/src/org/traccar/protocol/KhdProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -27,7 +27,7 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder {
public static final int MSG_CUT_OIL = 0x39;
public static final int MSG_RESUME_OIL = 0x38;
- private ChannelBuffer encodeCommand(int command) {
+ private ChannelBuffer encodeCommand(int command, String uniqueId) {
ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
@@ -37,7 +37,12 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder {
buf.writeByte(command);
buf.writeShort(6); // size
- buf.writeInt(0); // terminal id
+ uniqueId = "00000000".concat(uniqueId);
+ uniqueId = uniqueId.substring(uniqueId.length() - 8);
+ buf.writeByte(Integer.parseInt(uniqueId.substring(0, 2)));
+ buf.writeByte(Integer.parseInt(uniqueId.substring(2, 4)) + 0x80);
+ buf.writeByte(Integer.parseInt(uniqueId.substring(4, 6)) + 0x80);
+ buf.writeByte(Integer.parseInt(uniqueId.substring(6, 8)));
buf.writeByte(Checksum.xor(buf.toByteBuffer()));
buf.writeByte(0x0D); // ending
@@ -48,11 +53,13 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder {
@Override
protected Object encodeCommand(Command command) {
+ String uniqueId = getUniqueId(command.getDeviceId());
+
switch (command.getType()) {
case Command.TYPE_ENGINE_STOP:
- return encodeCommand(MSG_CUT_OIL);
+ return encodeCommand(MSG_CUT_OIL, uniqueId);
case Command.TYPE_ENGINE_RESUME:
- return encodeCommand(MSG_RESUME_OIL);
+ return encodeCommand(MSG_RESUME_OIL, uniqueId);
default:
Log.warning(new UnsupportedOperationException(command.getType()));
break;
diff --git a/src/org/traccar/protocol/L100ProtocolDecoder.java b/src/org/traccar/protocol/L100ProtocolDecoder.java
index 618448080..de966d7af 100644
--- a/src/org/traccar/protocol/L100ProtocolDecoder.java
+++ b/src/org/traccar/protocol/L100ProtocolDecoder.java
@@ -83,8 +83,7 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/LaipacProtocolDecoder.java b/src/org/traccar/protocol/LaipacProtocolDecoder.java
index 32d4ff0e6..bfaff9ec4 100644
--- a/src/org/traccar/protocol/LaipacProtocolDecoder.java
+++ b/src/org/traccar/protocol/LaipacProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2018 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.
@@ -22,6 +22,8 @@ import org.traccar.helper.Checksum;
import org.traccar.helper.DateBuilder;
import org.traccar.helper.Parser;
import org.traccar.helper.PatternBuilder;
+import org.traccar.model.CellTower;
+import org.traccar.model.Network;
import org.traccar.model.Position;
import java.net.SocketAddress;
@@ -45,11 +47,45 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
.number("(d+.d+),") // speed
.number("(d+.d+),") // course
.number("(dd)(dd)(dd),") // date (ddmmyy)
- .expression("(.),") // type
- .expression("[^*]+").text("*")
+ .expression("([abZXTSMHFE86430]),") // event code
+ .expression("([\\d.]+),") // battery voltage
+ .number("(d+),") // current mileage
+ .number("(d),") // gps status
+ .number("(d+),") // adc1
+ .number("(d+)") // adc2
+ .number(",(xxxx)") // lac
+ .number("(xxxx),") // cid
+ .number("(ddd)") // mcc
+ .number("(ddd)") // mnc
+ .optional(4)
+ .text("*")
.number("(xx)") // checksum
.compile();
+ private String decodeAlarm(String event) {
+ switch (event) {
+ case "Z":
+ return Position.ALARM_LOW_BATTERY;
+ case "X":
+ return Position.ALARM_GEOFENCE_ENTER;
+ case "T":
+ return Position.ALARM_TAMPERING;
+ case "H":
+ return Position.ALARM_POWER_OFF;
+ case "8":
+ return Position.ALARM_SHOCK;
+ case "7":
+ case "4":
+ return Position.ALARM_GEOFENCE_EXIT;
+ case "6":
+ return Position.ALARM_OVERSPEED;
+ case "3":
+ return Position.ALARM_SOS;
+ default:
+ return null;
+ }
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -71,8 +107,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -80,6 +115,7 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
String status = parser.next();
position.setValid(status.toUpperCase().equals("A"));
+ position.set(Position.KEY_STATUS, status);
position.setLatitude(parser.nextCoordinate());
position.setLongitude(parser.nextCoordinate());
@@ -89,25 +125,37 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
position.setTime(dateBuilder.getDate());
- String type = parser.next();
+ String event = parser.next();
+ position.set(Position.KEY_ALARM, decodeAlarm(event));
+ position.set(Position.KEY_EVENT, event);
+ position.set(Position.KEY_BATTERY, Double.parseDouble(parser.next().replaceAll("\\.", "")) * 0.001);
+ position.set(Position.KEY_ODOMETER, parser.nextDouble());
+ position.set(Position.KEY_GPS, parser.nextInt());
+ position.set(Position.PREFIX_ADC + 1, parser.nextDouble() * 0.001);
+ position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001);
+
+ Integer lac = parser.nextHexInt();
+ Integer cid = parser.nextHexInt();
+ Integer mcc = parser.nextInt();
+ Integer mnc = parser.nextInt();
+ if (lac != null && cid != null && mcc != null && mnc != null) {
+ position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid)));
+ }
+
String checksum = parser.next();
if (channel != null) {
-
- if (Character.isLowerCase(status.charAt(0))) {
- String response = "$EAVACK," + type + "," + checksum;
- response += Checksum.nmea(response);
+ if (event.equals("3")) {
+ channel.write("$AVCFG,00000000,d*31\r\n");
+ } else if (event.equals("X") || event.equals("4")) {
+ channel.write("$AVCFG,00000000,x*2D\r\n");
+ } else if (event.equals("Z")) {
+ channel.write("$AVCFG,00000000,z*2F\r\n");
+ } else if (Character.isLowerCase(status.charAt(0))) {
+ String response = "$EAVACK," + event + "," + checksum;
+ response += Checksum.nmea(response) + "\r\n";
channel.write(response);
}
-
- if (type.equals("S") || type.equals("T")) {
- channel.write("$AVCFG,00000000,t*21");
- } else if (type.equals("3")) {
- channel.write("$AVCFG,00000000,d*31");
- } else if (type.equals("X") || type.equals("4")) {
- channel.write("$AVCFG,00000000,x*2D");
- }
-
}
return position;
diff --git a/src/org/traccar/protocol/M2cProtocolDecoder.java b/src/org/traccar/protocol/M2cProtocolDecoder.java
index b0f40a88c..c11136f4c 100644
--- a/src/org/traccar/protocol/M2cProtocolDecoder.java
+++ b/src/org/traccar/protocol/M2cProtocolDecoder.java
@@ -75,8 +75,7 @@ public class M2cProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_INDEX, parser.nextInt());
diff --git a/src/org/traccar/protocol/M2mProtocolDecoder.java b/src/org/traccar/protocol/M2mProtocolDecoder.java
index a3c2ada2f..b30919865 100644
--- a/src/org/traccar/protocol/M2mProtocolDecoder.java
+++ b/src/org/traccar/protocol/M2mProtocolDecoder.java
@@ -68,8 +68,7 @@ public class M2mProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
diff --git a/src/org/traccar/protocol/MaestroProtocolDecoder.java b/src/org/traccar/protocol/MaestroProtocolDecoder.java
index 7d779a0a0..6068c93b9 100644
--- a/src/org/traccar/protocol/MaestroProtocolDecoder.java
+++ b/src/org/traccar/protocol/MaestroProtocolDecoder.java
@@ -70,8 +70,7 @@ public class MaestroProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setValid(parser.nextInt(0) == 1);
diff --git a/src/org/traccar/protocol/ManPowerProtocolDecoder.java b/src/org/traccar/protocol/ManPowerProtocolDecoder.java
index 6cff8b961..0b1c410c3 100644
--- a/src/org/traccar/protocol/ManPowerProtocolDecoder.java
+++ b/src/org/traccar/protocol/ManPowerProtocolDecoder.java
@@ -57,8 +57,7 @@ public class ManPowerProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java
index ad0f20a24..14d39e0cc 100644
--- a/src/org/traccar/protocol/MegastekProtocolDecoder.java
+++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2018 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.
@@ -147,8 +147,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
if (!parseLocation(location, position)) {
return null;
}
@@ -251,7 +250,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
.number("(d+),") // mcc
.number("(d+),") // mnc
.number("(xxxx),") // lac
- .number("(xxxx),") // cid
+ .number("(x+),") // cid
.number("(d+)?,") // gsm
.expression("([01]+)?,") // input
.expression("([01]+)?,") // output
@@ -269,7 +268,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
.number("(d+)?,") // rfid
.expression("[^,]*,")
.number("(d+)?,") // battery
- .expression("([^,]*);") // alert
+ .expression("([^,]*)") // alert
.any()
.compile();
@@ -285,8 +284,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (parser.next().equals("S")) {
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index 435e2ab14..9f7b8abf7 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -346,8 +346,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
String sentence = buf.readBytes(endIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII);
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position = decodeRegular(position, sentence);
@@ -403,8 +402,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
} else {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
if (command == MSG_ALARM) {
short alarmCode = buf.readUnsignedByte();
diff --git a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java
index 2e0a1e84c..340d947e3 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java
@@ -19,10 +19,10 @@ import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.Checksum;
+import org.traccar.helper.DataConverter;
import org.traccar.helper.Log;
import org.traccar.model.Command;
-import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.util.TimeZone;
@@ -44,7 +44,7 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder {
buf.writeShort(2 + 2 + 7 + 2 + content.readableBytes() + 2 + 2); // message length
- buf.writeBytes(DatatypeConverter.parseHexBinary((getUniqueId(deviceId) + "FFFFFFFFFFFFFF").substring(0, 14)));
+ buf.writeBytes(DataConverter.parseHex((getUniqueId(deviceId) + "FFFFFFFFFFFFFF").substring(0, 14)));
buf.writeShort(type);
diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
index b0195d09f..6fee0fd9f 100644
--- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java
@@ -126,8 +126,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
@@ -257,7 +256,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
if (values.length > 5 && !values[5].isEmpty()) {
String[] data = values[5].split("\\|");
- boolean started = data[0].charAt(0) == '0';
+ boolean started = data[0].charAt(1) == '0';
position.set("taximeterOn", started);
position.set("taximeterStart", data[1]);
if (data.length > 2) {
@@ -287,8 +286,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
while (buf.readableBytes() >= 0x34) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_EVENT, buf.readUnsignedByte());
@@ -361,8 +359,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
int count = buf.readUnsignedShort();
for (int i = 0; i < count; i++) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
buf.readUnsignedShort(); // length
@@ -381,6 +378,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
case 0x06:
position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
break;
+ case 0x07:
+ position.set(Position.KEY_RSSI, buf.readUnsignedByte());
+ break;
default:
buf.readUnsignedByte();
break;
@@ -400,6 +400,12 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
case 0x0B:
position.setAltitude(buf.readShort());
break;
+ case 0x19:
+ position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01);
+ break;
+ case 0x1A:
+ position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01);
+ break;
default:
buf.readUnsignedShort();
break;
@@ -419,6 +425,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
case 0x04:
position.setTime(new Date((946684800 + buf.readUnsignedInt()) * 1000)); // 2000-01-01
break;
+ case 0x0D:
+ position.set("runtime", buf.readUnsignedInt());
+ break;
default:
buf.readUnsignedInt();
break;
@@ -437,9 +446,9 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
return positions;
}
- private void requestPhotoPacket(Channel channel, String imei, int index) {
+ private void requestPhotoPacket(Channel channel, String imei, String file, int index) {
if (channel != null) {
- String content = "D00,camera_picture.jpg," + index;
+ String content = "D00," + file + "," + index;
int length = 1 + imei.length() + 1 + content.length() + 5;
String response = String.format("@@O%02d,%s,%s*", length, imei, content);
response += Checksum.sum(response) + "\r\n";
@@ -461,11 +470,14 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
switch (type) {
case "D00":
if (photo == null) {
- return null;
+ photo = ChannelBuffers.dynamicBuffer();
}
- index = buf.indexOf(index + 1 + type.length() + 1, buf.writerIndex(), (byte) ',') + 1;
+ index = index + 1 + type.length() + 1;
int endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ',');
+ String file = buf.toString(index, endIndex - index, StandardCharsets.US_ASCII);
+ index = endIndex + 1;
+ endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ',');
int total = Integer.parseInt(buf.toString(index, endIndex - index, StandardCharsets.US_ASCII));
index = endIndex + 1;
endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ',');
@@ -475,8 +487,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
photo.writeBytes(buf.readBytes(buf.readableBytes() - 1 - 2 - 2));
if (current == total - 1) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(getDeviceSession(channel, remoteAddress, imei).getDeviceId());
getLastLocation(position, null);
@@ -487,13 +498,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder {
return position;
} else {
if ((current + 1) % 8 == 0) {
- requestPhotoPacket(channel, imei, current + 1);
+ requestPhotoPacket(channel, imei, file, current + 1);
}
return null;
}
case "D03":
photo = ChannelBuffers.dynamicBuffer();
- requestPhotoPacket(channel, imei, 0);
+ requestPhotoPacket(channel, imei, "camera_picture.jpg", 0);
return null;
case "CCC":
return decodeBinaryC(channel, remoteAddress, buf);
diff --git a/src/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/org/traccar/protocol/MeitrackProtocolEncoder.java
index b10a751c1..f73d74de9 100644
--- a/src/org/traccar/protocol/MeitrackProtocolEncoder.java
+++ b/src/org/traccar/protocol/MeitrackProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -49,7 +49,8 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder {
case Command.TYPE_ALARM_DISARM:
return formatCommand(command, 'M', "C01,0,22022");
case Command.TYPE_REQUEST_PHOTO:
- return formatCommand(command, 'D', "D03,1,camera_picture.jpg");
+ int index = command.getInteger(Command.KEY_INDEX);
+ return formatCommand(command, 'D', "D03," + (index > 0 ? index : 1) + ",camera_picture.jpg");
case Command.TYPE_SEND_SMS:
return formatCommand(command, 'f', "C02,0,"
+ attributes.get(Command.KEY_PHONE) + "," + attributes.get(Command.KEY_MESSAGE));
diff --git a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java
index 8e6e56e80..ab046eca3 100644
--- a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java
+++ b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java
@@ -146,8 +146,7 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
String type = sentence.substring(1, 2);
diff --git a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java b/src/org/traccar/protocol/MiniFinderProtocolEncoder.java
index 486f406a5..d3f49b4e4 100644
--- a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java
+++ b/src/org/traccar/protocol/MiniFinderProtocolEncoder.java
@@ -25,25 +25,25 @@ public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements
@Override
public String formatValue(String key, Object value) {
-
- if (key.equals(Command.KEY_ENABLE)) {
- return (Boolean) value ? "1" : "0";
- } else if (key.equals(Command.KEY_TIMEZONE)) {
- return String.format("%+03d", TimeZone.getTimeZone((String) value).getRawOffset() / 3600000);
- } else if (key.equals(Command.KEY_INDEX)) {
- switch (((Number) value).intValue()) {
- case 0:
- return "A";
- case 1:
- return "B";
- case 2:
- return "C";
- default:
- return null;
- }
+ switch (key) {
+ case Command.KEY_ENABLE:
+ return (Boolean) value ? "1" : "0";
+ case Command.KEY_TIMEZONE:
+ return String.format("%+03d", TimeZone.getTimeZone((String) value).getRawOffset() / 3600000);
+ case Command.KEY_INDEX:
+ switch (((Number) value).intValue()) {
+ case 0:
+ return "A";
+ case 1:
+ return "B";
+ case 2:
+ return "C";
+ default:
+ return null;
+ }
+ default:
+ return null;
}
-
- return null;
}
@Override
diff --git a/src/org/traccar/protocol/Mta6ProtocolDecoder.java b/src/org/traccar/protocol/Mta6ProtocolDecoder.java
index 0fda94eef..c26e00c56 100644
--- a/src/org/traccar/protocol/Mta6ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Mta6ProtocolDecoder.java
@@ -120,8 +120,7 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder {
try {
while (buf.readable()) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
short flags = buf.readUnsignedByte();
@@ -200,9 +199,8 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder {
}
private Position parseFormatA1(DeviceSession deviceSession, ChannelBuffer buf) {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
short flags = buf.readUnsignedByte();
diff --git a/src/org/traccar/protocol/MtxProtocolDecoder.java b/src/org/traccar/protocol/MtxProtocolDecoder.java
index d7b572670..412eac493 100644
--- a/src/org/traccar/protocol/MtxProtocolDecoder.java
+++ b/src/org/traccar/protocol/MtxProtocolDecoder.java
@@ -68,8 +68,7 @@ public class MtxProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/MxtProtocolDecoder.java b/src/org/traccar/protocol/MxtProtocolDecoder.java
index 6d82e4a4b..9fe1924c0 100644
--- a/src/org/traccar/protocol/MxtProtocolDecoder.java
+++ b/src/org/traccar/protocol/MxtProtocolDecoder.java
@@ -82,8 +82,7 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder {
if (type == MSG_POSITION) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
buf.readUnsignedByte(); // protocol
diff --git a/src/org/traccar/protocol/NavigilProtocolDecoder.java b/src/org/traccar/protocol/NavigilProtocolDecoder.java
index 360b9c81c..4f3b4ad74 100644
--- a/src/org/traccar/protocol/NavigilProtocolDecoder.java
+++ b/src/org/traccar/protocol/NavigilProtocolDecoder.java
@@ -81,8 +81,7 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder {
private Position parseUnitReport(
DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setValid(true);
position.set(Position.KEY_INDEX, sequenceNumber);
@@ -116,8 +115,7 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder {
private Position parseTg2Report(
DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setValid(true);
position.set(Position.KEY_INDEX, sequenceNumber);
@@ -154,8 +152,7 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder {
private Position parsePositionReport(
DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber, long timestamp) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_INDEX, sequenceNumber);
position.setDeviceId(deviceSession.getDeviceId());
@@ -177,8 +174,7 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder {
private Position parsePositionReport2(
DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber, long timestamp) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_INDEX, sequenceNumber);
position.setDeviceId(deviceSession.getDeviceId());
@@ -202,8 +198,7 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder {
private Position parseSnapshot4(
DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_INDEX, sequenceNumber);
position.setDeviceId(deviceSession.getDeviceId());
@@ -241,8 +236,7 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder {
private Position parseTrackingData(
DeviceSession deviceSession, ChannelBuffer buf, int sequenceNumber, long timestamp) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_INDEX, sequenceNumber);
position.setDeviceId(deviceSession.getDeviceId());
diff --git a/src/org/traccar/protocol/NavisProtocolDecoder.java b/src/org/traccar/protocol/NavisProtocolDecoder.java
index 8d4e367ab..6881fb8ed 100644
--- a/src/org/traccar/protocol/NavisProtocolDecoder.java
+++ b/src/org/traccar/protocol/NavisProtocolDecoder.java
@@ -76,8 +76,7 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder {
}
private ParseResult parsePosition(DeviceSession deviceSession, ChannelBuffer buf) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
diff --git a/src/org/traccar/protocol/NoranProtocolDecoder.java b/src/org/traccar/protocol/NoranProtocolDecoder.java
index 990f50484..e10332ece 100644
--- a/src/org/traccar/protocol/NoranProtocolDecoder.java
+++ b/src/org/traccar/protocol/NoranProtocolDecoder.java
@@ -80,8 +80,7 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder {
newFormat = true;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
if (type == MSG_CONTROL_RESPONSE) {
buf.readUnsignedInt(); // GIS ip
diff --git a/src/org/traccar/protocol/NvsProtocolDecoder.java b/src/org/traccar/protocol/NvsProtocolDecoder.java
index 0e82fae69..db8347d3c 100644
--- a/src/org/traccar/protocol/NvsProtocolDecoder.java
+++ b/src/org/traccar/protocol/NvsProtocolDecoder.java
@@ -76,8 +76,7 @@ public class NvsProtocolDecoder extends BaseProtocolDecoder {
int count = buf.readUnsignedByte();
for (int i = 0; i < count; i++) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date(buf.readUnsignedInt() * 1000));
diff --git a/src/org/traccar/protocol/ObdDongleProtocolDecoder.java b/src/org/traccar/protocol/ObdDongleProtocolDecoder.java
index e5ae5e93f..5310c90fd 100644
--- a/src/org/traccar/protocol/ObdDongleProtocolDecoder.java
+++ b/src/org/traccar/protocol/ObdDongleProtocolDecoder.java
@@ -91,8 +91,7 @@ public class ObdDongleProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte(); // event id
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date(buf.readUnsignedInt() * 1000));
diff --git a/src/org/traccar/protocol/OigoProtocolDecoder.java b/src/org/traccar/protocol/OigoProtocolDecoder.java
index 54360c932..2874d0455 100644
--- a/src/org/traccar/protocol/OigoProtocolDecoder.java
+++ b/src/org/traccar/protocol/OigoProtocolDecoder.java
@@ -68,8 +68,7 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_EVENT, buf.readUnsignedByte());
@@ -178,8 +177,7 @@ public class OigoProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
buf.skipBytes(8); // imsi
diff --git a/src/org/traccar/protocol/OkoProtocolDecoder.java b/src/org/traccar/protocol/OkoProtocolDecoder.java
index e86acf0b8..0ebe63ca3 100644
--- a/src/org/traccar/protocol/OkoProtocolDecoder.java
+++ b/src/org/traccar/protocol/OkoProtocolDecoder.java
@@ -72,8 +72,7 @@ public class OkoProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
diff --git a/src/org/traccar/protocol/OpenGtsProtocol.java b/src/org/traccar/protocol/OpenGtsProtocol.java
new file mode 100644
index 000000000..a0246ba1b
--- /dev/null
+++ b/src/org/traccar/protocol/OpenGtsProtocol.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 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.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
+import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+
+public class OpenGtsProtocol extends BaseProtocol {
+
+ public OpenGtsProtocol() {
+ super("opengts");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(new ServerBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("httpEncoder", new HttpResponseEncoder());
+ pipeline.addLast("httpDecoder", new HttpRequestDecoder());
+ pipeline.addLast("objectDecoder", new OpenGtsProtocolDecoder(OpenGtsProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/OpenGtsProtocolDecoder.java b/src/org/traccar/protocol/OpenGtsProtocolDecoder.java
new file mode 100644
index 000000000..ba8f434d8
--- /dev/null
+++ b/src/org/traccar/protocol/OpenGtsProtocolDecoder.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2018 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.channel.Channel;
+import org.jboss.netty.handler.codec.http.HttpRequest;
+import org.jboss.netty.handler.codec.http.HttpResponseStatus;
+import org.jboss.netty.handler.codec.http.QueryStringDecoder;
+import org.traccar.BaseHttpProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.DateBuilder;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class OpenGtsProtocolDecoder extends BaseHttpProtocolDecoder {
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .text("$GPRMC,")
+ .number("(dd)(dd)(dd),") // time (hhmmss)
+ .expression("([AV]),") // validity
+ .number("(d+)(dd.d+),") // latitude
+ .expression("([NS]),")
+ .number("(d+)(dd.d+),") // longitude
+ .expression("([EW]),")
+ .number("(d+.d+),") // speed
+ .number("(d+.d+),") // course
+ .number("(dd)(dd)(dd),") // date (ddmmyy)
+ .any()
+ .compile();
+
+ public OpenGtsProtocolDecoder(OpenGtsProtocol protocol) {
+ super(protocol);
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ HttpRequest request = (HttpRequest) msg;
+ QueryStringDecoder decoder = new QueryStringDecoder(request.getUri());
+ Map<String, List<String>> params = decoder.getParameters();
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+
+ for (Map.Entry<String, List<String>> entry : params.entrySet()) {
+ String value = entry.getValue().get(0);
+ switch (entry.getKey()) {
+ case "id":
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value);
+ if (deviceSession == null) {
+ sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
+ return null;
+ }
+ position.setDeviceId(deviceSession.getDeviceId());
+ break;
+ case "gprmc":
+ Parser parser = new Parser(PATTERN, value);
+ if (!parser.matches()) {
+ sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
+ return null;
+ }
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
+
+ position.setValid(parser.next().equals("A"));
+ position.setLatitude(parser.nextCoordinate());
+ position.setLongitude(parser.nextCoordinate());
+ position.setSpeed(parser.nextDouble(0));
+ position.setCourse(parser.nextDouble(0));
+
+ dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
+ position.setTime(dateBuilder.getDate());
+ break;
+ case "alt":
+ position.setAltitude(Double.parseDouble(value));
+ break;
+ case "batt":
+ position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value));
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (position.getDeviceId() != 0) {
+ sendResponse(channel, HttpResponseStatus.OK);
+ return position;
+ } else {
+ sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
+ return null;
+ }
+ }
+
+}
diff --git a/src/org/traccar/protocol/OrionProtocolDecoder.java b/src/org/traccar/protocol/OrionProtocolDecoder.java
index c65924337..ada864fba 100644
--- a/src/org/traccar/protocol/OrionProtocolDecoder.java
+++ b/src/org/traccar/protocol/OrionProtocolDecoder.java
@@ -79,9 +79,8 @@ public class OrionProtocolDecoder extends BaseProtocolDecoder {
for (int i = 0; i < (header & 0x0f); i++) {
- Position position = new Position();
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setProtocol(getProtocolName());
position.set(Position.KEY_EVENT, buf.readUnsignedByte());
buf.readUnsignedByte(); // length
diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java
index 61855311a..03abdd588 100644
--- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java
+++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java
@@ -53,8 +53,7 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder {
params = decoder.getParameters();
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setValid(true);
Network network = new Network();
diff --git a/src/org/traccar/protocol/OwnTracksProtocolDecoder.java b/src/org/traccar/protocol/OwnTracksProtocolDecoder.java
index 49d1cff96..120995dfb 100644
--- a/src/org/traccar/protocol/OwnTracksProtocolDecoder.java
+++ b/src/org/traccar/protocol/OwnTracksProtocolDecoder.java
@@ -50,8 +50,7 @@ public class OwnTracksProtocolDecoder extends BaseHttpProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setValid(true);
position.setLatitude(root.getJsonNumber("lat").doubleValue());
diff --git a/src/org/traccar/protocol/PathAwayProtocolDecoder.java b/src/org/traccar/protocol/PathAwayProtocolDecoder.java
index 1c4531612..845a5e892 100644
--- a/src/org/traccar/protocol/PathAwayProtocolDecoder.java
+++ b/src/org/traccar/protocol/PathAwayProtocolDecoder.java
@@ -72,8 +72,7 @@ public class PathAwayProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
diff --git a/src/org/traccar/protocol/PiligrimProtocolDecoder.java b/src/org/traccar/protocol/PiligrimProtocolDecoder.java
index 9d5bb9e24..f2ec16c59 100644
--- a/src/org/traccar/protocol/PiligrimProtocolDecoder.java
+++ b/src/org/traccar/protocol/PiligrimProtocolDecoder.java
@@ -97,8 +97,7 @@ public class PiligrimProtocolDecoder extends BaseProtocolDecoder {
if (type == MSG_GPS || type == MSG_GPS_SENSORS) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
diff --git a/src/org/traccar/protocol/PretraceProtocolDecoder.java b/src/org/traccar/protocol/PretraceProtocolDecoder.java
index 77d94068f..24d707a1c 100644
--- a/src/org/traccar/protocol/PretraceProtocolDecoder.java
+++ b/src/org/traccar/protocol/PretraceProtocolDecoder.java
@@ -71,8 +71,7 @@ public class PretraceProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setValid(parser.next().equals("A"));
diff --git a/src/org/traccar/protocol/PricolProtocolDecoder.java b/src/org/traccar/protocol/PricolProtocolDecoder.java
index a33e19b90..577665dcc 100644
--- a/src/org/traccar/protocol/PricolProtocolDecoder.java
+++ b/src/org/traccar/protocol/PricolProtocolDecoder.java
@@ -47,8 +47,7 @@ public class PricolProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set("eventType", buf.readUnsignedByte());
diff --git a/src/org/traccar/protocol/ProgressProtocolDecoder.java b/src/org/traccar/protocol/ProgressProtocolDecoder.java
index 1820ea926..d85b6acb3 100644
--- a/src/org/traccar/protocol/ProgressProtocolDecoder.java
+++ b/src/org/traccar/protocol/ProgressProtocolDecoder.java
@@ -96,8 +96,7 @@ public class ProgressProtocolDecoder extends BaseProtocolDecoder {
}
for (int j = 0; j < recordCount; j++) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (type == MSG_LOGMSG) {
diff --git a/src/org/traccar/protocol/Pt3000ProtocolDecoder.java b/src/org/traccar/protocol/Pt3000ProtocolDecoder.java
index c36be7976..f4540afe8 100644
--- a/src/org/traccar/protocol/Pt3000ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Pt3000ProtocolDecoder.java
@@ -56,8 +56,7 @@ public class Pt3000ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/Pt502FrameDecoder.java b/src/org/traccar/protocol/Pt502FrameDecoder.java
index 252c8dd02..4d3e9b4d5 100644
--- a/src/org/traccar/protocol/Pt502FrameDecoder.java
+++ b/src/org/traccar/protocol/Pt502FrameDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2014 - 2018 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.
@@ -20,6 +20,8 @@ import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
+import java.nio.charset.StandardCharsets;
+
public class Pt502FrameDecoder extends FrameDecoder {
private static final int BINARY_HEADER = 5;
@@ -28,26 +30,41 @@ public class Pt502FrameDecoder extends FrameDecoder {
protected Object decode(
ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception {
- if (buf.readableBytes() < BINARY_HEADER) {
+ if (buf.readableBytes() < 10) {
return null;
}
- if (buf.getUnsignedByte(buf.readerIndex()) == 0xbf) {
- buf.skipBytes(BINARY_HEADER);
- }
+ if (buf.getUnsignedByte(buf.readerIndex()) == 0xbf
+ && buf.toString(buf.readerIndex() + BINARY_HEADER, 4, StandardCharsets.US_ASCII).equals("$PHD")) {
- int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '\r');
- if (index < 0) {
- index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '\n');
- }
+ int length = buf.getUnsignedShort(buf.readerIndex() + 3);
+ if (buf.readableBytes() >= length) {
+ buf.skipBytes(BINARY_HEADER);
+ ChannelBuffer result = buf.readBytes(length - BINARY_HEADER - 2);
+ buf.skipBytes(2); // line break
+ return result;
+ }
+
+ } else {
- if (index > 0) {
- ChannelBuffer result = buf.readBytes(index - buf.readerIndex());
- while (buf.readable()
- && (buf.getByte(buf.readerIndex()) == '\r' || buf.getByte(buf.readerIndex()) == '\n')) {
- buf.skipBytes(1);
+ if (buf.getUnsignedByte(buf.readerIndex()) == 0xbf) {
+ buf.skipBytes(BINARY_HEADER);
}
- return result;
+
+ int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '\r');
+ if (index < 0) {
+ index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '\n');
+ }
+
+ if (index > 0) {
+ ChannelBuffer result = buf.readBytes(index - buf.readerIndex());
+ while (buf.readable()
+ && (buf.getByte(buf.readerIndex()) == '\r' || buf.getByte(buf.readerIndex()) == '\n')) {
+ buf.skipBytes(1);
+ }
+ return result;
+ }
+
}
return null;
diff --git a/src/org/traccar/protocol/Pt502Protocol.java b/src/org/traccar/protocol/Pt502Protocol.java
index 0116422c2..f7d0d04a2 100644
--- a/src/org/traccar/protocol/Pt502Protocol.java
+++ b/src/org/traccar/protocol/Pt502Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -17,7 +17,6 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
@@ -45,7 +44,6 @@ public class Pt502Protocol extends BaseProtocol {
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new Pt502FrameDecoder());
pipeline.addLast("stringEncoder", new StringEncoder());
- pipeline.addLast("stringDecoder", new StringDecoder());
pipeline.addLast("objectEncoder", new Pt502ProtocolEncoder());
pipeline.addLast("objectDecoder", new Pt502ProtocolDecoder(Pt502Protocol.this));
}
diff --git a/src/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/org/traccar/protocol/Pt502ProtocolDecoder.java
index 330ba7643..76e7ee1bf 100644
--- a/src/org/traccar/protocol/Pt502ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Pt502ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org)
* Copyright 2012 Luis Parada (luis.parada@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +16,11 @@
*/
package org.traccar.protocol;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
+import org.traccar.Context;
import org.traccar.DeviceSession;
import org.traccar.helper.DateBuilder;
import org.traccar.helper.Parser;
@@ -25,13 +28,14 @@ import org.traccar.helper.PatternBuilder;
import org.traccar.model.Position;
import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
import java.util.regex.Pattern;
public class Pt502ProtocolDecoder extends BaseProtocolDecoder {
private static final int MAX_CHUNK_SIZE = 960;
- private byte[] photo;
+ private ChannelBuffer photo;
public Pt502ProtocolDecoder(Pt502Protocol protocol) {
super(protocol);
@@ -85,26 +89,15 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder {
}
}
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ private Position decodePosition(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN, (String) msg);
+ Parser parser = new Parser(PATTERN, sentence);
if (!parser.matches()) {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
-
- String type = parser.next();
-
- if (type.startsWith("PHO") && channel != null) {
- photo = new byte[Integer.parseInt(type.substring(3))];
- channel.write("#PHD0," + Math.min(photo.length, MAX_CHUNK_SIZE) + "\r\n");
- }
-
- position.set(Position.KEY_ALARM, decodeAlarm(type));
+ Position position = new Position(getProtocolName());
+ position.set(Position.KEY_ALARM, decodeAlarm(parser.next()));
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
@@ -147,4 +140,71 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder {
return position;
}
+ private void requestPhotoFragment(Channel channel) {
+ if (channel != null) {
+ int offset = photo.writerIndex();
+ int size = Math.min(photo.writableBytes(), MAX_CHUNK_SIZE);
+ channel.write("#PHD" + offset + "," + size + "\r\n");
+ }
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ int typeEndIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ',');
+ String type = buf.toString(buf.readerIndex(), typeEndIndex - buf.readerIndex(), StandardCharsets.US_ASCII);
+
+ if (type.startsWith("$PHD")) {
+
+ int dataIndex = buf.indexOf(typeEndIndex + 1, buf.writerIndex(), (byte) ',') + 1;
+ buf.readerIndex(dataIndex);
+
+ if (photo != null) {
+
+ photo.writeBytes(buf.readBytes(buf.readableBytes()));
+
+ if (photo.writableBytes() > 0) {
+
+ requestPhotoFragment(channel);
+
+ } else {
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId();
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ getLastLocation(position, null);
+
+ position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg"));
+
+ photo = null;
+
+ return position;
+
+ }
+
+ }
+
+ } else {
+
+ if (type.startsWith("$PHO")) {
+ int size = Integer.parseInt(type.split("-")[0].substring(4));
+ if (size > 0) {
+ photo = ChannelBuffers.buffer(size);
+ requestPhotoFragment(channel);
+ }
+ }
+
+ return decodePosition(channel, remoteAddress, buf.toString(StandardCharsets.US_ASCII));
+
+ }
+
+ return null;
+ }
+
}
diff --git a/src/org/traccar/protocol/Pt60Protocol.java b/src/org/traccar/protocol/Pt60Protocol.java
new file mode 100644
index 000000000..857790efd
--- /dev/null
+++ b/src/org/traccar/protocol/Pt60Protocol.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2018 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.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.handler.codec.string.StringDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.CharacterDelimiterFrameDecoder;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+
+public class Pt60Protocol extends BaseProtocol {
+
+ public Pt60Protocol() {
+ super("pt60");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(new ServerBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, "@R#@"));
+ pipeline.addLast("stringEncoder", new StringEncoder());
+ pipeline.addLast("stringDecoder", new StringDecoder());
+ pipeline.addLast("objectDecoder", new Pt60ProtocolDecoder(Pt60Protocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/Pt60ProtocolDecoder.java b/src/org/traccar/protocol/Pt60ProtocolDecoder.java
new file mode 100644
index 000000000..c87c22c5f
--- /dev/null
+++ b/src/org/traccar/protocol/Pt60ProtocolDecoder.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018 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.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.regex.Pattern;
+
+public class Pt60ProtocolDecoder extends BaseProtocolDecoder {
+
+ public Pt60ProtocolDecoder(Pt60Protocol protocol) {
+ super(protocol);
+ }
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .text("@G#@,") // header
+ .number("Vdd,") // protocol version
+ .number("d,") // type
+ .number("(d+),") // imei
+ .number("(d+),") // imsi
+ .number("(dddd)(dd)(dd)") // date (yyyymmdd)
+ .number("(dd)(dd)(dd),") // time (hhmmss)
+ .number("(-?d+.d+);") // latitude
+ .number("(-?d+.d+),") // longitude
+ .compile();
+
+ private void sendResponse(Channel channel) {
+ if (channel != null) {
+ DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+ channel.write("@G#@,V01,38," + dateFormat.format(new Date()) + ",@R#@");
+ }
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ sendResponse(channel);
+
+ Parser parser = new Parser(PATTERN, (String) msg);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next(), parser.next());
+ if (deviceSession == null) {
+ return null;
+ }
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setValid(true);
+ position.setTime(parser.nextDateTime());
+ position.setLatitude(parser.nextDouble());
+ position.setLongitude(parser.nextDouble());
+
+ return position;
+ }
+
+}
diff --git a/src/org/traccar/protocol/RaveonProtocolDecoder.java b/src/org/traccar/protocol/RaveonProtocolDecoder.java
index cbe6026a2..ac52493ad 100644
--- a/src/org/traccar/protocol/RaveonProtocolDecoder.java
+++ b/src/org/traccar/protocol/RaveonProtocolDecoder.java
@@ -68,8 +68,7 @@ public class RaveonProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.HEM_DEG_MIN));
diff --git a/src/org/traccar/protocol/RecodaProtocolDecoder.java b/src/org/traccar/protocol/RecodaProtocolDecoder.java
index 8db582d35..7bd4d3dae 100644
--- a/src/org/traccar/protocol/RecodaProtocolDecoder.java
+++ b/src/org/traccar/protocol/RecodaProtocolDecoder.java
@@ -64,8 +64,7 @@ public class RecodaProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date(buf.readLong()));
diff --git a/src/org/traccar/protocol/RitiProtocolDecoder.java b/src/org/traccar/protocol/RitiProtocolDecoder.java
index 5c298e8c5..637867908 100644
--- a/src/org/traccar/protocol/RitiProtocolDecoder.java
+++ b/src/org/traccar/protocol/RitiProtocolDecoder.java
@@ -56,8 +56,7 @@ public class RitiProtocolDecoder extends BaseProtocolDecoder {
buf.skipBytes(2); // header
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(buf.readUnsignedShort()));
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/RoboTrackFrameDecoder.java b/src/org/traccar/protocol/RoboTrackFrameDecoder.java
new file mode 100644
index 000000000..af215103c
--- /dev/null
+++ b/src/org/traccar/protocol/RoboTrackFrameDecoder.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2018 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 RoboTrackFrameDecoder extends FrameDecoder {
+
+ private int messageLength(ChannelBuffer buf) {
+ switch ((int) buf.getByte(buf.readerIndex())) {
+ case RoboTrackProtocolDecoder.MSG_ID:
+ return 69;
+ case RoboTrackProtocolDecoder.MSG_ACK:
+ return 3;
+ case RoboTrackProtocolDecoder.MSG_GPS:
+ case RoboTrackProtocolDecoder.MSG_GSM:
+ case RoboTrackProtocolDecoder.MSG_IMAGE_START:
+ return 24;
+ case RoboTrackProtocolDecoder.MSG_IMAGE_DATA:
+ return 8 + buf.getUnsignedShort(buf.readerIndex() + 1);
+ case RoboTrackProtocolDecoder.MSG_IMAGE_END:
+ return 6;
+ default:
+ return Integer.MAX_VALUE;
+ }
+ }
+
+ @Override
+ protected Object decode(
+ ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception {
+
+ int length = messageLength(buf);
+
+ if (buf.readableBytes() >= length) {
+ return buf.readBytes(length);
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/protocol/RoboTrackProtocol.java b/src/org/traccar/protocol/RoboTrackProtocol.java
new file mode 100644
index 000000000..382cb1c2f
--- /dev/null
+++ b/src/org/traccar/protocol/RoboTrackProtocol.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 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.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.traccar.BaseProtocol;
+import org.traccar.TrackerServer;
+
+import java.nio.ByteOrder;
+import java.util.List;
+
+public class RoboTrackProtocol extends BaseProtocol {
+
+ public RoboTrackProtocol() {
+ super("robotrack");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ TrackerServer server = new TrackerServer(new ServerBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("frameDecoder", new RoboTrackFrameDecoder());
+ pipeline.addLast("objectDecoder", new RoboTrackProtocolDecoder(RoboTrackProtocol.this));
+ }
+ };
+ server.setEndianness(ByteOrder.LITTLE_ENDIAN);
+ serverList.add(server);
+ }
+
+}
diff --git a/src/org/traccar/protocol/RoboTrackProtocolDecoder.java b/src/org/traccar/protocol/RoboTrackProtocolDecoder.java
new file mode 100644
index 000000000..4f27fb08e
--- /dev/null
+++ b/src/org/traccar/protocol/RoboTrackProtocolDecoder.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2018 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.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.BitUtil;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.CellTower;
+import org.traccar.model.Network;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+
+public class RoboTrackProtocolDecoder extends BaseProtocolDecoder {
+
+ public RoboTrackProtocolDecoder(RoboTrackProtocol protocol) {
+ super(protocol);
+ }
+
+ public static final int MSG_ID = 0x00;
+ public static final int MSG_ACK = 0x80;
+ public static final int MSG_GPS = 0x03;
+ public static final int MSG_GSM = 0x04;
+ public static final int MSG_IMAGE_START = 0x06;
+ public static final int MSG_IMAGE_DATA = 0x07;
+ public static final int MSG_IMAGE_END = 0x08;
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ int type = buf.readUnsignedByte();
+
+ if (type == MSG_ID) {
+
+ buf.skipBytes(16); // name
+
+ String imei = buf.readBytes(15).toString(StandardCharsets.US_ASCII);
+
+ if (getDeviceSession(channel, remoteAddress, imei) != null && channel != null) {
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
+ response.writeByte(MSG_ACK);
+ response.writeByte(0x01); // success
+ response.writeByte(0x66); // checksum
+ channel.write(response);
+ }
+
+ } else if (type == MSG_GPS || type == MSG_GSM) {
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setDeviceTime(new Date(buf.readUnsignedInt() * 1000));
+
+ if (type == MSG_GPS) {
+
+ position.setValid(true);
+ position.setFixTime(position.getDeviceTime());
+ position.setLatitude(buf.readInt() * 0.000001);
+ position.setLongitude(buf.readInt() * 0.000001);
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readByte()));
+
+ } else {
+
+ getLastLocation(position, position.getDeviceTime());
+
+ position.setNetwork(new Network(CellTower.from(
+ buf.readUnsignedShort(), buf.readUnsignedShort(),
+ buf.readUnsignedShort(), buf.readUnsignedShort())));
+
+ buf.readUnsignedByte(); // reserved
+
+ }
+
+ int value = buf.readUnsignedByte();
+
+ position.set(Position.KEY_SATELLITES, BitUtil.to(value, 4));
+ position.set(Position.KEY_RSSI, BitUtil.between(value, 4, 7));
+ position.set(Position.KEY_MOTION, BitUtil.check(value, 7));
+
+ value = buf.readUnsignedByte();
+
+ position.set(Position.KEY_CHARGE, BitUtil.check(value, 0));
+
+ for (int i = 1; i <= 4; i++) {
+ position.set(Position.PREFIX_IN + i, BitUtil.check(value, i));
+ }
+
+ position.set(Position.KEY_BATTERY_LEVEL, BitUtil.from(value, 5) * 100 / 7);
+ position.set(Position.KEY_DEVICE_TEMP, buf.readByte());
+
+ for (int i = 1; i <= 3; i++) {
+ position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort());
+ }
+
+ return position;
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/org/traccar/protocol/RuptelaProtocolDecoder.java
index 8752d30c0..7b11cc5c3 100644
--- a/src/org/traccar/protocol/RuptelaProtocolDecoder.java
+++ b/src/org/traccar/protocol/RuptelaProtocolDecoder.java
@@ -20,10 +20,10 @@ import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
+import org.traccar.helper.DataConverter;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
-import javax.xml.bind.DatatypeConverter;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Date;
@@ -49,8 +49,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_EXTENDED_RECORDS = 68;
private Position decodeCommandResponse(DeviceSession deviceSession, int type, ChannelBuffer buf) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
@@ -135,8 +134,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder {
int count = buf.readUnsignedByte();
for (int i = 0; i < count; i++) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date(buf.readUnsignedInt() * 1000));
@@ -198,7 +196,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder {
}
if (channel != null) {
- channel.write(ChannelBuffers.wrappedBuffer(DatatypeConverter.parseHexBinary("0002640113bc")));
+ channel.write(ChannelBuffers.wrappedBuffer(DataConverter.parseHex("0002640113bc")));
}
return positions;
@@ -210,8 +208,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder {
int count = buf.readUnsignedByte();
for (int i = 0; i < count; i++) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
buf.readUnsignedByte(); // reserved
@@ -232,7 +229,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder {
}
if (channel != null) {
- channel.write(ChannelBuffers.wrappedBuffer(DatatypeConverter.parseHexBinary("00026d01c4a4")));
+ channel.write(ChannelBuffers.wrappedBuffer(DataConverter.parseHex("00026d01c4a4")));
}
return positions;
diff --git a/src/org/traccar/protocol/SanavProtocolDecoder.java b/src/org/traccar/protocol/SanavProtocolDecoder.java
index 151c55795..714bb15d5 100644
--- a/src/org/traccar/protocol/SanavProtocolDecoder.java
+++ b/src/org/traccar/protocol/SanavProtocolDecoder.java
@@ -59,8 +59,7 @@ public class SanavProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/org/traccar/protocol/SigfoxProtocolDecoder.java
index 7cf57681f..b454e00fa 100644
--- a/src/org/traccar/protocol/SigfoxProtocolDecoder.java
+++ b/src/org/traccar/protocol/SigfoxProtocolDecoder.java
@@ -22,12 +22,12 @@ import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.traccar.BaseHttpProtocolDecoder;
import org.traccar.DeviceSession;
+import org.traccar.helper.DataConverter;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
import javax.json.Json;
import javax.json.JsonObject;
-import javax.xml.bind.DatatypeConverter;
import java.io.StringReader;
import java.net.SocketAddress;
import java.net.URLDecoder;
@@ -55,14 +55,13 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date(json.getInt("time") * 1000L));
ChannelBuffer buf = ChannelBuffers.wrappedBuffer(
- ByteOrder.LITTLE_ENDIAN, DatatypeConverter.parseHexBinary(json.getString("data")));
+ ByteOrder.LITTLE_ENDIAN, DataConverter.parseHex(json.getString("data")));
int type = buf.readUnsignedByte() >> 4;
if (type == 0) {
diff --git a/src/org/traccar/protocol/SiwiProtocolDecoder.java b/src/org/traccar/protocol/SiwiProtocolDecoder.java
index 198df24d5..66b6465fa 100644
--- a/src/org/traccar/protocol/SiwiProtocolDecoder.java
+++ b/src/org/traccar/protocol/SiwiProtocolDecoder.java
@@ -70,8 +70,7 @@ public class SiwiProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_EVENT, parser.next());
diff --git a/src/org/traccar/protocol/SkypatrolProtocolDecoder.java b/src/org/traccar/protocol/SkypatrolProtocolDecoder.java
index f4dded972..a85595a07 100644
--- a/src/org/traccar/protocol/SkypatrolProtocolDecoder.java
+++ b/src/org/traccar/protocol/SkypatrolProtocolDecoder.java
@@ -67,8 +67,7 @@ public class SkypatrolProtocolDecoder extends BaseProtocolDecoder {
// Binary position report
if (apiNumber == 5 && commandType == 2 && messageType == 1 && BitUtil.check(mask, 0)) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
if (BitUtil.check(mask, 1)) {
position.set(Position.KEY_STATUS, buf.readUnsignedInt());
diff --git a/src/org/traccar/protocol/SmokeyProtocolDecoder.java b/src/org/traccar/protocol/SmokeyProtocolDecoder.java
index 2dcfeb86f..9c4cb4e21 100644
--- a/src/org/traccar/protocol/SmokeyProtocolDecoder.java
+++ b/src/org/traccar/protocol/SmokeyProtocolDecoder.java
@@ -84,8 +84,7 @@ public class SmokeyProtocolDecoder extends BaseProtocolDecoder {
if (type == MSG_DATE_RECORD) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_VERSION_FW, buf.readUnsignedShort());
diff --git a/src/org/traccar/protocol/SpotProtocolDecoder.java b/src/org/traccar/protocol/SpotProtocolDecoder.java
index ed6a03c5f..a8e666a32 100644
--- a/src/org/traccar/protocol/SpotProtocolDecoder.java
+++ b/src/org/traccar/protocol/SpotProtocolDecoder.java
@@ -72,8 +72,7 @@ public class SpotProtocolDecoder extends BaseHttpProtocolDecoder {
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, xPath.evaluate("esnName", node));
if (deviceSession != null) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setValid(true);
@@ -81,6 +80,8 @@ public class SpotProtocolDecoder extends BaseHttpProtocolDecoder {
position.setLatitude(Double.parseDouble(xPath.evaluate("latitude", node)));
position.setLongitude(Double.parseDouble(xPath.evaluate("longitude", node)));
+ position.set(Position.KEY_EVENT, xPath.evaluate("messageType", node));
+
positions.add(position);
}
diff --git a/src/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/org/traccar/protocol/StarLinkProtocolDecoder.java
index 79f013fac..f2c9d2c50 100644
--- a/src/org/traccar/protocol/StarLinkProtocolDecoder.java
+++ b/src/org/traccar/protocol/StarLinkProtocolDecoder.java
@@ -111,8 +111,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setValid(true);
diff --git a/src/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/org/traccar/protocol/Stl060ProtocolDecoder.java
index 26817a5c8..64d4655c5 100644
--- a/src/org/traccar/protocol/Stl060ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Stl060ProtocolDecoder.java
@@ -75,8 +75,7 @@ public class Stl060ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java
index 6dfc6f77f..b739e699b 100644
--- a/src/org/traccar/protocol/SuntechProtocolDecoder.java
+++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java
@@ -21,6 +21,8 @@ import org.traccar.Context;
import org.traccar.DeviceSession;
import org.traccar.helper.BitUtil;
import org.traccar.helper.UnitsConverter;
+import org.traccar.model.CellTower;
+import org.traccar.model.Network;
import org.traccar.model.Position;
import java.net.SocketAddress;
@@ -76,8 +78,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
if (type.equals("Emergency") || type.equals("Alert")) {
@@ -157,7 +158,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
}
}
- private Position decode235(
+ private Position decode2356(
Channel channel, SocketAddress remoteAddress, String protocol, String[] values) throws ParseException {
int index = 0;
@@ -172,12 +173,11 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_TYPE, type);
- if (protocol.equals("ST300") || protocol.equals("ST500")) {
+ if (protocol.equals("ST300") || protocol.equals("ST500") || protocol.equals("ST600")) {
index += 1; // model
}
@@ -188,7 +188,12 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
position.setTime(dateFormat.parse(values[index++] + values[index++]));
if (!protocol.equals("ST500")) {
- index += 1; // cell
+ int cid = Integer.parseInt(values[index++], 16);
+ if (protocol.equals("ST600")) {
+ position.setNetwork(new Network(CellTower.from(
+ Integer.parseInt(values[index++]), Integer.parseInt(values[index++]),
+ Integer.parseInt(values[index++], 16), cid, Integer.parseInt(values[index++]))));
+ }
}
position.setLatitude(Double.parseDouble(values[index++]));
@@ -289,8 +294,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_TYPE, type);
@@ -372,7 +376,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
} else if (values[0].equals("ST910")) {
return decode9(channel, remoteAddress, values);
} else {
- return decode235(channel, remoteAddress, values[0].substring(0, 5), values);
+ return decode2356(channel, remoteAddress, values[0].substring(0, 5), values);
}
}
diff --git a/src/org/traccar/protocol/SupermateProtocolDecoder.java b/src/org/traccar/protocol/SupermateProtocolDecoder.java
index d9b58a7f4..be325ea29 100644
--- a/src/org/traccar/protocol/SupermateProtocolDecoder.java
+++ b/src/org/traccar/protocol/SupermateProtocolDecoder.java
@@ -65,8 +65,7 @@ public class SupermateProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
String imei = parser.next();
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java
index bfddf74ac..be3cb5f67 100644
--- a/src/org/traccar/protocol/T55ProtocolDecoder.java
+++ b/src/org/traccar/protocol/T55ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2018 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.
@@ -110,8 +110,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
if (deviceSession != null) {
position.setDeviceId(deviceSession.getDeviceId());
@@ -165,8 +164,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -188,8 +186,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date());
@@ -209,8 +206,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(parser.nextDateTime());
@@ -254,9 +250,11 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
} else if (sentence.startsWith("$PCPTI")) {
getDeviceSession(channel, remoteAddress, sentence.substring(7, sentence.indexOf(",", 7)));
} else if (sentence.startsWith("IMEI")) {
- getDeviceSession(channel, remoteAddress, sentence.substring(5, sentence.length()));
+ getDeviceSession(channel, remoteAddress, sentence.substring(5));
+ } else if (sentence.startsWith("$IMEI")) {
+ getDeviceSession(channel, remoteAddress, sentence.substring(6));
} else if (sentence.startsWith("$GPFID")) {
- deviceSession = getDeviceSession(channel, remoteAddress, sentence.substring(7, sentence.length()));
+ deviceSession = getDeviceSession(channel, remoteAddress, sentence.substring(7));
if (deviceSession != null && position != null) {
Position position = this.position;
position.setDeviceId(deviceSession.getDeviceId());
diff --git a/src/org/traccar/protocol/T57ProtocolDecoder.java b/src/org/traccar/protocol/T57ProtocolDecoder.java
index db5f94cbb..65dfc46e3 100644
--- a/src/org/traccar/protocol/T57ProtocolDecoder.java
+++ b/src/org/traccar/protocol/T57ProtocolDecoder.java
@@ -63,8 +63,7 @@ public class T57ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
diff --git a/src/org/traccar/protocol/T800xProtocolDecoder.java b/src/org/traccar/protocol/T800xProtocolDecoder.java
index 6430b1344..1fd37864e 100644
--- a/src/org/traccar/protocol/T800xProtocolDecoder.java
+++ b/src/org/traccar/protocol/T800xProtocolDecoder.java
@@ -105,8 +105,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder {
if (type == MSG_GPS || type == MSG_ALARM) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_INDEX, index);
diff --git a/src/org/traccar/protocol/T800xProtocolEncoder.java b/src/org/traccar/protocol/T800xProtocolEncoder.java
index 6ed5dbccd..038a5e51a 100644
--- a/src/org/traccar/protocol/T800xProtocolEncoder.java
+++ b/src/org/traccar/protocol/T800xProtocolEncoder.java
@@ -18,10 +18,10 @@ package org.traccar.protocol;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.traccar.BaseProtocolEncoder;
+import org.traccar.helper.DataConverter;
import org.traccar.helper.Log;
import org.traccar.model.Command;
-import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
public class T800xProtocolEncoder extends BaseProtocolEncoder {
@@ -39,7 +39,7 @@ public class T800xProtocolEncoder extends BaseProtocolEncoder {
buf.writeByte(T800xProtocolDecoder.MSG_COMMAND);
buf.writeShort(7 + 8 + 1 + content.length());
buf.writeShort(1); // serial number
- buf.writeBytes(DatatypeConverter.parseHexBinary("0" + getUniqueId(command.getDeviceId())));
+ buf.writeBytes(DataConverter.parseHex("0" + getUniqueId(command.getDeviceId())));
buf.writeByte(MODE_SETTING);
buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII));
diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java
index e7117a5c9..a7aa9dd96 100644
--- a/src/org/traccar/protocol/TaipProtocolDecoder.java
+++ b/src/org/traccar/protocol/TaipProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2018 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.
@@ -47,7 +47,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder {
.groupEnd("?")
.number("(d{5})") // seconds
.or()
- .expression("(?:RGP|RCQ|RBR)") // type
+ .expression("(?:RGP|RCQ|RCV|RBR)") // type
.number("(dd)?") // event
.number("(dd)(dd)(dd)") // date (mmddyy)
.number("(dd)(dd)(dd)") // time (hhmmss)
@@ -62,12 +62,33 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder {
.number("(ddd)") // speed
.number("(ddd)") // course
.groupBegin()
+ .number("([023])") // fix mode
+ .number("xx") // data age
+ .number("(xx)") // input
+ .number("(dd)") // event
+ .number("(dd)") // hdop
+ .or()
+ .groupBegin()
.number("(xx)") // input
.number("(xx)") // satellites
.number("(ddd)") // battery
.number("(x{8})") // odometer
.number("[01]") // gps power
+ .groupBegin()
+ .number("([023])") // fix mode
+ .number("(dd)") // pdop
+ .number("dd") // satellites
+ .number("xxxx") // data age
+ .number("[01]") // modem power
+ .number("[0-5]") // gsm status
+ .number("(dd)") // rssi
+ .number("([-+]dddd)") // temperature 1
+ .number("xx") // seconds from last
+ .number("([-+]dddd)") // temperature 2
+ .number("xx") // seconds from last
+ .groupEnd("?")
.groupEnd("?")
+ .groupEnd()
.any()
.compile();
@@ -101,9 +122,9 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
+ Boolean valid = null;
Integer event = null;
if (parser.hasNext(3)) {
@@ -117,27 +138,6 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder {
event = parser.nextInt();
}
- if (event != null) {
- switch (event) {
- case 22:
- position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION);
- break;
- case 23:
- position.set(Position.KEY_ALARM, Position.ALARM_BRAKING);
- break;
- case 24:
- position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT);
- break;
- case 26:
- case 28:
- position.set(Position.KEY_ALARM, Position.ALARM_CORNERING);
- break;
- default:
- position.set(Position.KEY_EVENT, event);
- break;
- }
- }
-
if (parser.hasNext(6)) {
position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
}
@@ -155,13 +155,51 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder {
position.setCourse(parser.nextDouble(0));
if (parser.hasNext(4)) {
+ valid = parser.nextInt() > 0;
+ int input = parser.nextHexInt();
+ position.set(Position.KEY_IGNITION, BitUtil.check(input, 7));
+ position.set(Position.KEY_INPUT, input);
+ event = parser.nextInt();
+ position.set(Position.KEY_HDOP, parser.nextInt());
+ }
+
+ if (parser.hasNext(4)) {
position.set(Position.KEY_INPUT, parser.nextHexInt(0));
position.set(Position.KEY_SATELLITES, parser.nextHexInt(0));
position.set(Position.KEY_BATTERY, parser.nextInt(0));
position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0));
}
- position.setValid(true);
+ if (parser.hasNext(4)) {
+ valid = parser.nextInt() > 0;
+ position.set(Position.KEY_PDOP, parser.nextInt());
+ position.set(Position.KEY_RSSI, parser.nextInt());
+ position.set(Position.PREFIX_TEMP + 1, parser.nextInt() * 0.01);
+ position.set(Position.PREFIX_TEMP + 2, parser.nextInt() * 0.01);
+ }
+
+ position.setValid(valid != null ? valid : true);
+
+ if (event != null) {
+ position.set(Position.KEY_EVENT, event);
+ switch (event) {
+ case 22:
+ position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION);
+ break;
+ case 23:
+ position.set(Position.KEY_ALARM, Position.ALARM_BRAKING);
+ break;
+ case 24:
+ position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT);
+ break;
+ case 26:
+ case 28:
+ position.set(Position.KEY_ALARM, Position.ALARM_CORNERING);
+ break;
+ default:
+ break;
+ }
+ }
String[] attributes = null;
beginIndex = sentence.indexOf(';');
@@ -231,14 +269,13 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder {
if (deviceSession != null) {
if (channel != null) {
if (messageIndex != null) {
- String response = ">ACK;" + messageIndex + ";ID=" + uniqueId + ";*";
+ String response = ">ACK;ID=" + uniqueId + ";" + messageIndex + ";*";
response += String.format("%02X", Checksum.xor(response)) + "<";
channel.write(response, remoteAddress);
} else {
channel.write(uniqueId, remoteAddress);
}
}
-
return position;
}
diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java
index 2c0d714c6..197db059b 100644
--- a/src/org/traccar/protocol/TelicProtocolDecoder.java
+++ b/src/org/traccar/protocol/TelicProtocolDecoder.java
@@ -87,8 +87,7 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
index 80f0045d5..d2069e6c9 100644
--- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
+++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2018 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.
@@ -69,6 +69,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
public static final int CODEC_GH3000 = 0x07;
public static final int CODEC_FM4X00 = 0x08;
public static final int CODEC_12 = 0x0C;
+ public static final int CODEC_16 = 0x10;
private void decodeSerial(Position position, ChannelBuffer buf) {
@@ -132,7 +133,10 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1);
break;
case 78:
- position.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", readValue(buf, length, false)));
+ long driverUniqueId = readValue(buf, length, false);
+ if (driverUniqueId != 0) {
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId));
+ }
break;
case 80:
position.set("workMode", readValue(buf, length, false));
@@ -344,7 +348,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
}
// Read 8 byte data
- if (codec == CODEC_FM4X00) {
+ if (codec == CODEC_FM4X00 || codec == CODEC_16) {
int cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
decodeOtherParameter(position, buf.readUnsignedByte(), buf, 8);
@@ -381,8 +385,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
}
for (int i = 0; i < count; i++) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
diff --git a/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java b/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java
index 4a97fa1a1..f7dd18f51 100644
--- a/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java
+++ b/src/org/traccar/protocol/ThinkRaceProtocolDecoder.java
@@ -87,8 +87,7 @@ public class ThinkRaceProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(new Date(buf.readUnsignedInt() * 1000));
diff --git a/src/org/traccar/protocol/Tk102ProtocolDecoder.java b/src/org/traccar/protocol/Tk102ProtocolDecoder.java
index 41d5b7436..50dd45676 100644
--- a/src/org/traccar/protocol/Tk102ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Tk102ProtocolDecoder.java
@@ -117,8 +117,7 @@ public class Tk102ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
diff --git a/src/org/traccar/protocol/Tk103Protocol.java b/src/org/traccar/protocol/Tk103Protocol.java
index 6ef9c0a56..e23982c74 100644
--- a/src/org/traccar/protocol/Tk103Protocol.java
+++ b/src/org/traccar/protocol/Tk103Protocol.java
@@ -47,7 +47,8 @@ public class Tk103Protocol extends BaseProtocol {
Command.TYPE_REBOOT_DEVICE,
Command.TYPE_SET_ODOMETER,
Command.TYPE_ENGINE_STOP,
- Command.TYPE_ENGINE_RESUME);
+ Command.TYPE_ENGINE_RESUME,
+ Command.TYPE_OUTPUT_CONTROL);
}
@Override
diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java
index eda29e3f8..22a73469f 100644
--- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java
@@ -228,8 +228,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
@@ -263,8 +262,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
@@ -286,8 +284,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
decodeType(position, parser.next(), "0");
@@ -331,8 +328,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
@@ -380,8 +376,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
boolean alternative = parser.next() != null;
diff --git a/src/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/org/traccar/protocol/Tk103ProtocolEncoder.java
index 946f3ad73..3ec562cc3 100644
--- a/src/org/traccar/protocol/Tk103ProtocolEncoder.java
+++ b/src/org/traccar/protocol/Tk103ProtocolEncoder.java
@@ -97,6 +97,8 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder {
return formatCommand(command, "({%s}AV010)", Command.KEY_UNIQUE_ID);
case Command.TYPE_ENGINE_RESUME:
return formatCommand(command, "({%s}AV011)", Command.KEY_UNIQUE_ID);
+ case Command.TYPE_OUTPUT_CONTROL:
+ return formatCommand(command, "({%s}AV00{%s})", Command.KEY_UNIQUE_ID, Command.KEY_DATA);
default:
Log.warning(new UnsupportedOperationException(command.getType()));
return null;
diff --git a/src/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/org/traccar/protocol/Tlt2hProtocolDecoder.java
index cbc851de0..a5a195afa 100644
--- a/src/org/traccar/protocol/Tlt2hProtocolDecoder.java
+++ b/src/org/traccar/protocol/Tlt2hProtocolDecoder.java
@@ -57,6 +57,45 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder {
.any()
.compile();
+ private void decodeStatus(Position position, String status) {
+ switch (status) {
+ case "AUTOSTART":
+ case "AUTO":
+ position.set(Position.KEY_IGNITION, true);
+ break;
+ case "AUTOSTOP":
+ case "AUTOLOW":
+ position.set(Position.KEY_IGNITION, false);
+ break;
+ case "TOWED":
+ position.set(Position.KEY_ALARM, Position.ALARM_TOW);
+ break;
+ case "SOS":
+ position.set(Position.KEY_ALARM, Position.ALARM_SOS);
+ break;
+ case "DEF":
+ position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT);
+ break;
+ case "BLP":
+ position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY);
+ break;
+ case "CLP":
+ position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER);
+ break;
+ case "OS":
+ position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT);
+ break;
+ case "RS":
+ position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER);
+ break;
+ case "OVERSPEED":
+ position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED);
+ break;
+ default:
+ break;
+ }
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -84,8 +123,7 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder {
parser = new Parser(PATTERN_POSITION, message);
if (parser.matches()) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
parser.next(); // base station info
@@ -102,7 +140,7 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder {
dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
position.setTime(dateBuilder.getDate());
- position.set(Position.KEY_STATUS, status);
+ decodeStatus(position, status);
positions.add(position);
}
diff --git a/src/org/traccar/protocol/TlvProtocolDecoder.java b/src/org/traccar/protocol/TlvProtocolDecoder.java
index 41d65be09..0cf68acb8 100644
--- a/src/org/traccar/protocol/TlvProtocolDecoder.java
+++ b/src/org/traccar/protocol/TlvProtocolDecoder.java
@@ -83,8 +83,7 @@ public class TlvProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setValid(true);
diff --git a/src/org/traccar/protocol/TmgFrameDecoder.java b/src/org/traccar/protocol/TmgFrameDecoder.java
index 549c42466..c39cf03ac 100644
--- a/src/org/traccar/protocol/TmgFrameDecoder.java
+++ b/src/org/traccar/protocol/TmgFrameDecoder.java
@@ -37,13 +37,10 @@ public class TmgFrameDecoder extends FrameDecoder {
if (buffer.getByte(guessedIndex) != (byte) '$' || buffer.writerIndex() - guessedIndex < 5) {
return false;
}
- if (buffer.getByte(guessedIndex + 4) == ','
+ return buffer.getByte(guessedIndex + 4) == ','
&& isLetter(buffer.getByte(guessedIndex + 1))
&& isLetter(buffer.getByte(guessedIndex + 2))
- && isLetter(buffer.getByte(guessedIndex + 3))) {
- return true;
- }
- return false;
+ && isLetter(buffer.getByte(guessedIndex + 3));
}
});
diff --git a/src/org/traccar/protocol/TmgProtocolDecoder.java b/src/org/traccar/protocol/TmgProtocolDecoder.java
index 4a3055932..cb10eedd7 100644
--- a/src/org/traccar/protocol/TmgProtocolDecoder.java
+++ b/src/org/traccar/protocol/TmgProtocolDecoder.java
@@ -99,8 +99,7 @@ public class TmgProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
switch (type) {
diff --git a/src/org/traccar/protocol/TopflytechProtocolDecoder.java b/src/org/traccar/protocol/TopflytechProtocolDecoder.java
index 837ca2557..b3a8fa845 100644
--- a/src/org/traccar/protocol/TopflytechProtocolDecoder.java
+++ b/src/org/traccar/protocol/TopflytechProtocolDecoder.java
@@ -53,8 +53,7 @@ public class TopflytechProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/TotemProtocolDecoder.java b/src/org/traccar/protocol/TotemProtocolDecoder.java
index a3e8c9921..5a2c203d2 100644
--- a/src/org/traccar/protocol/TotemProtocolDecoder.java
+++ b/src/org/traccar/protocol/TotemProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2018 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.
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
+import org.traccar.helper.BitUtil;
import org.traccar.helper.DateBuilder;
import org.traccar.helper.Parser;
import org.traccar.helper.PatternBuilder;
@@ -131,7 +132,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder {
private static final Pattern PATTERN4 = new PatternBuilder()
.text("$$") // header
.number("dddd") // length
- .expression("A[ABC]") // type
+ .number("(xx)") // type
.number("(d+)|") // imei
.number("(x{8})") // status
.number("(dd)(dd)(dd)") // date (yymmdd)
@@ -163,7 +164,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder {
.any()
.compile();
- private String decodeAlarm(Short value) {
+ private String decodeAlarm123(int value) {
switch (value) {
case 0x01:
return Position.ALARM_SOS;
@@ -182,10 +183,31 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder {
}
}
+ private String decodeAlarm4(int value) {
+ switch (value) {
+ case 0x01:
+ return Position.ALARM_SOS;
+ case 0x02:
+ return Position.ALARM_OVERSPEED;
+ case 0x04:
+ return Position.ALARM_GEOFENCE_EXIT;
+ case 0x05:
+ return Position.ALARM_GEOFENCE_ENTER;
+ case 0x40:
+ return Position.ALARM_SHOCK;
+ case 0x42:
+ return Position.ALARM_ACCELERATION;
+ case 0x43:
+ return Position.ALARM_BRAKING;
+ default:
+ return null;
+ }
+ }
+
private boolean decode12(Position position, Parser parser, Pattern pattern) {
if (parser.hasNext()) {
- position.set(Position.KEY_ALARM, decodeAlarm(Short.parseShort(parser.next(), 16)));
+ position.set(Position.KEY_ALARM, decodeAlarm123(Short.parseShort(parser.next(), 16)));
}
DateBuilder dateBuilder = new DateBuilder();
int year = 0, month = 0, day = 0;
@@ -221,12 +243,23 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_HDOP, parser.nextDouble());
}
- position.set(Position.PREFIX_IO + 1, parser.next());
+ int io = parser.nextBinInt();
if (pattern == PATTERN1) {
+ for (int i = 1; i <= 4; i++) {
+ position.set(Position.PREFIX_IN + i, BitUtil.check(io, 3 + i));
+ }
position.set(Position.KEY_BATTERY, parser.nextDouble(0) * 0.01);
} else {
+ position.set(Position.KEY_ANTENNA, BitUtil.check(io, 0));
+ position.set(Position.KEY_CHARGE, BitUtil.check(io, 1));
+ for (int i = 1; i <= 6; i++) {
+ position.set(Position.PREFIX_IN + i, BitUtil.check(io, 1 + i));
+ }
position.set(Position.KEY_BATTERY, parser.nextDouble(0) * 0.1);
}
+ for (int i = 1; i <= 4; i++) {
+ position.set(Position.PREFIX_OUT + i, BitUtil.check(io, 7 + i));
+ }
position.set(Position.KEY_POWER, parser.nextDouble(0));
position.set(Position.PREFIX_ADC + 1, parser.next());
@@ -245,7 +278,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder {
private boolean decode3(Position position, Parser parser) {
if (parser.hasNext()) {
- position.set(Position.KEY_ALARM, decodeAlarm(Short.parseShort(parser.next(), 16)));
+ position.set(Position.KEY_ALARM, decodeAlarm123(Short.parseShort(parser.next(), 16)));
}
position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
@@ -276,7 +309,26 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder {
private boolean decode4(Position position, Parser parser) {
- position.set(Position.KEY_STATUS, parser.next());
+ long status = parser.nextHexLong();
+
+ position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 1) ? Position.ALARM_SOS : null);
+ position.set(Position.KEY_IGNITION, BitUtil.check(status, 32 - 2));
+ position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 3) ? Position.ALARM_OVERSPEED : null);
+ position.set(Position.KEY_CHARGE, BitUtil.check(status, 32 - 4));
+ position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 5) ? Position.ALARM_GEOFENCE_EXIT : null);
+ position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 6) ? Position.ALARM_GEOFENCE_ENTER : null);
+ position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 32 - 9));
+ position.set(Position.PREFIX_OUT + 2, BitUtil.check(status, 32 - 10));
+ position.set(Position.PREFIX_OUT + 3, BitUtil.check(status, 32 - 11));
+ position.set(Position.PREFIX_OUT + 4, BitUtil.check(status, 32 - 12));
+ position.set(Position.PREFIX_IN + 2, BitUtil.check(status, 32 - 13));
+ position.set(Position.PREFIX_IN + 3, BitUtil.check(status, 32 - 14));
+ position.set(Position.PREFIX_IN + 4, BitUtil.check(status, 32 - 15));
+ position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 16) ? Position.ALARM_SHOCK : null);
+ position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 18) ? Position.ALARM_LOW_BATTERY : null);
+ position.set(Position.KEY_ALARM, BitUtil.check(status, 32 - 22) ? Position.ALARM_JAMMING : null);
+
+ position.setValid(BitUtil.check(status, 32 - 20));
position.setTime(parser.nextDateTime());
@@ -300,7 +352,6 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_HDOP, parser.nextDouble(0));
position.set(Position.KEY_ODOMETER, parser.nextInt(0) * 1000);
- position.setValid(true);
position.setLatitude(parser.nextCoordinate());
position.setLongitude(parser.nextCoordinate());
@@ -329,8 +380,11 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
+
+ if (pattern == PATTERN4) {
+ position.set(Position.KEY_ALARM, decodeAlarm4(parser.nextHexInt()));
+ }
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/Tr20ProtocolDecoder.java b/src/org/traccar/protocol/Tr20ProtocolDecoder.java
index 403a2fda2..579d575b0 100644
--- a/src/org/traccar/protocol/Tr20ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Tr20ProtocolDecoder.java
@@ -70,8 +70,7 @@ public class Tr20ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/Tr900ProtocolDecoder.java b/src/org/traccar/protocol/Tr900ProtocolDecoder.java
index 7dbdc5697..0ce4158e4 100644
--- a/src/org/traccar/protocol/Tr900ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Tr900ProtocolDecoder.java
@@ -63,8 +63,7 @@ public class Tr900ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/TrackboxProtocolDecoder.java b/src/org/traccar/protocol/TrackboxProtocolDecoder.java
index 7e542af93..2c113fb76 100644
--- a/src/org/traccar/protocol/TrackboxProtocolDecoder.java
+++ b/src/org/traccar/protocol/TrackboxProtocolDecoder.java
@@ -77,8 +77,7 @@ public class TrackboxProtocolDecoder extends BaseProtocolDecoder {
}
sendResponse(channel);
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
diff --git a/src/org/traccar/protocol/TrakMateProtocolDecoder.java b/src/org/traccar/protocol/TrakMateProtocolDecoder.java
index 8965a18b4..293c13fad 100644
--- a/src/org/traccar/protocol/TrakMateProtocolDecoder.java
+++ b/src/org/traccar/protocol/TrakMateProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 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.
@@ -17,23 +17,18 @@ package org.traccar.protocol;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
-import org.traccar.Context;
import org.traccar.DeviceSession;
import org.traccar.helper.Parser;
import org.traccar.helper.PatternBuilder;
import org.traccar.model.Position;
import java.net.SocketAddress;
-import java.util.TimeZone;
import java.util.regex.Pattern;
public class TrakMateProtocolDecoder extends BaseProtocolDecoder {
- private final TimeZone timeZone = TimeZone.getTimeZone("UTC");
-
public TrakMateProtocolDecoder(TrakMateProtocol protocol) {
super(protocol);
- timeZone.setRawOffset(Context.getConfig().getInteger(getProtocolName() + ".timezone") * 1000);
}
private static final Pattern PATTERN_SRT = new PatternBuilder()
@@ -112,8 +107,7 @@ public class TrakMateProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setLatitude(parser.nextDouble(0));
@@ -139,8 +133,7 @@ public class TrakMateProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
parser.next(); // seq
@@ -170,8 +163,7 @@ public class TrakMateProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
parser.next(); // seq
diff --git a/src/org/traccar/protocol/TramigoProtocolDecoder.java b/src/org/traccar/protocol/TramigoProtocolDecoder.java
index b1e28e17d..2605346a9 100644
--- a/src/org/traccar/protocol/TramigoProtocolDecoder.java
+++ b/src/org/traccar/protocol/TramigoProtocolDecoder.java
@@ -61,8 +61,7 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder {
long id = buf.readUnsignedInt();
buf.readUnsignedInt(); // time
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.set(Position.KEY_INDEX, index);
position.setValid(true);
diff --git a/src/org/traccar/protocol/TrvProtocolDecoder.java b/src/org/traccar/protocol/TrvProtocolDecoder.java
index 918748f7b..e0cebc9a5 100644
--- a/src/org/traccar/protocol/TrvProtocolDecoder.java
+++ b/src/org/traccar/protocol/TrvProtocolDecoder.java
@@ -144,8 +144,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
@@ -167,8 +166,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
diff --git a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java
index 5e30d0994..0134f4764 100644
--- a/src/org/traccar/protocol/Tt8850ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Tt8850ProtocolDecoder.java
@@ -69,8 +69,7 @@ public class Tt8850ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/TytanProtocolDecoder.java b/src/org/traccar/protocol/TytanProtocolDecoder.java
index de0330250..a65ad4cfc 100644
--- a/src/org/traccar/protocol/TytanProtocolDecoder.java
+++ b/src/org/traccar/protocol/TytanProtocolDecoder.java
@@ -146,8 +146,7 @@ public class TytanProtocolDecoder extends BaseProtocolDecoder {
while (buf.readableBytes() > 2) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
int end = buf.readerIndex() + buf.readUnsignedByte();
diff --git a/src/org/traccar/protocol/TzoneProtocolDecoder.java b/src/org/traccar/protocol/TzoneProtocolDecoder.java
index 079ad3126..984891bb6 100644
--- a/src/org/traccar/protocol/TzoneProtocolDecoder.java
+++ b/src/org/traccar/protocol/TzoneProtocolDecoder.java
@@ -128,8 +128,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_VERSION_HW, hardware);
diff --git a/src/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/org/traccar/protocol/UlbotechProtocolDecoder.java
index 31a3d2cfe..5499518a1 100644
--- a/src/org/traccar/protocol/UlbotechProtocolDecoder.java
+++ b/src/org/traccar/protocol/UlbotechProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -19,7 +19,6 @@ import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
-import org.traccar.Context;
import org.traccar.DeviceSession;
import org.traccar.helper.BitUtil;
import org.traccar.helper.Checksum;
@@ -39,11 +38,8 @@ import java.util.regex.Pattern;
public class UlbotechProtocolDecoder extends BaseProtocolDecoder {
- private final long timeZone;
-
public UlbotechProtocolDecoder(UlbotechProtocol protocol) {
super(protocol);
- timeZone = Context.getConfig().getInteger(getProtocolName() + ".timezone", 0);
}
private static final short DATA_GPS = 0x01;
@@ -188,8 +184,7 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -216,13 +211,16 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ if (deviceSession.getTimeZone() == null) {
+ deviceSession.setTimeZone(getTimeZone(deviceSession.getDeviceId()));
+ }
+
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
long seconds = buf.readUnsignedInt() & 0x7fffffffL;
seconds += 946684800L; // 2000-01-01 00:00
- seconds -= timeZone;
+ seconds -= deviceSession.getTimeZone().getRawOffset() / 1000;
Date time = new Date(seconds * 1000);
boolean hasLocation = false;
diff --git a/src/org/traccar/protocol/UproProtocolDecoder.java b/src/org/traccar/protocol/UproProtocolDecoder.java
index 7a0dca8a2..28f3d0249 100644
--- a/src/org/traccar/protocol/UproProtocolDecoder.java
+++ b/src/org/traccar/protocol/UproProtocolDecoder.java
@@ -116,8 +116,7 @@ public class UproProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
String type = parser.next();
diff --git a/src/org/traccar/protocol/V680ProtocolDecoder.java b/src/org/traccar/protocol/V680ProtocolDecoder.java
index 079a8eb08..caa06a863 100644
--- a/src/org/traccar/protocol/V680ProtocolDecoder.java
+++ b/src/org/traccar/protocol/V680ProtocolDecoder.java
@@ -70,8 +70,7 @@ public class V680ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession;
if (parser.hasNext()) {
diff --git a/src/org/traccar/protocol/VisiontekProtocolDecoder.java b/src/org/traccar/protocol/VisiontekProtocolDecoder.java
index f32c9fbfe..33c555c6b 100644
--- a/src/org/traccar/protocol/VisiontekProtocolDecoder.java
+++ b/src/org/traccar/protocol/VisiontekProtocolDecoder.java
@@ -81,8 +81,7 @@ public class VisiontekProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next(), parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java
index 2ae24efbb..d08107b16 100644
--- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Vt200ProtocolDecoder.java
@@ -68,8 +68,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder {
if (type == 0x2086 || type == 0x2084 || type == 0x2082) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
buf.readUnsignedByte(); // data type
@@ -85,7 +84,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder {
if (!BitUtil.check(flags, 1)) {
position.setLatitude(-position.getLatitude());
}
- if (!BitUtil.check(flags, 1)) {
+ if (!BitUtil.check(flags, 2)) {
position.setLongitude(-position.getLongitude());
}
@@ -103,8 +102,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder {
} else if (type == 0x3088) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
diff --git a/src/org/traccar/protocol/VtfmsProtocolDecoder.java b/src/org/traccar/protocol/VtfmsProtocolDecoder.java
index 5fb687e6d..dc2171022 100644
--- a/src/org/traccar/protocol/VtfmsProtocolDecoder.java
+++ b/src/org/traccar/protocol/VtfmsProtocolDecoder.java
@@ -106,8 +106,7 @@ public class VtfmsProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_ALARM, decodeAlarm(parser.nextInt()));
diff --git a/src/org/traccar/protocol/WatchFrameDecoder.java b/src/org/traccar/protocol/WatchFrameDecoder.java
index 826a8b4d0..0009ef30f 100644
--- a/src/org/traccar/protocol/WatchFrameDecoder.java
+++ b/src/org/traccar/protocol/WatchFrameDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2018 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.
@@ -25,47 +25,66 @@ import java.nio.charset.StandardCharsets;
public class WatchFrameDecoder extends FrameDecoder {
- public static final int MESSAGE_HEADER = 20;
-
@Override
protected Object decode(
ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception {
- if (buf.readableBytes() >= MESSAGE_HEADER) {
- ChannelBuffer lengthBuffer = ChannelBuffers.dynamicBuffer();
- buf.getBytes(buf.readerIndex() + MESSAGE_HEADER - 4 - 1, lengthBuffer, 4);
- int length = Integer.parseInt(lengthBuffer.toString(StandardCharsets.US_ASCII), 16) + MESSAGE_HEADER + 1;
- if (buf.readableBytes() >= length) {
- ChannelBuffer frame = ChannelBuffers.dynamicBuffer();
- int endIndex = buf.readerIndex() + length;
- while (buf.readerIndex() < endIndex) {
- byte b = buf.readByte();
- if (b == 0x7D) {
- switch (buf.readByte()) {
- case 0x01:
- frame.writeByte(0x7D);
- break;
- case 0x02:
- frame.writeByte(0x5B);
- break;
- case 0x03:
- frame.writeByte(0x5D);
- break;
- case 0x04:
- frame.writeByte(0x2C);
- break;
- case 0x05:
- frame.writeByte(0x2A);
- break;
- default:
- throw new IllegalArgumentException();
- }
- } else {
- frame.writeByte(b);
+ int idIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*') + 1;
+ if (idIndex <= 0) {
+ return null;
+ }
+
+ int lengthIndex = buf.indexOf(idIndex, buf.writerIndex(), (byte) '*') + 1;
+ if (lengthIndex <= 0) {
+ return null;
+ }
+
+ int payloadIndex = buf.indexOf(lengthIndex, buf.writerIndex(), (byte) '*');
+ if (payloadIndex < 0) {
+ return null;
+ }
+
+ if (payloadIndex + 5 < buf.writerIndex() && buf.getByte(payloadIndex + 5) == '*'
+ && buf.toString(payloadIndex + 1, 4, StandardCharsets.US_ASCII).matches("\\p{XDigit}+")) {
+ lengthIndex = payloadIndex + 1;
+ payloadIndex = buf.indexOf(lengthIndex, buf.writerIndex(), (byte) '*');
+ if (payloadIndex < 0) {
+ return null;
+ }
+ }
+
+ int length = Integer.parseInt(
+ buf.toString(lengthIndex, payloadIndex - lengthIndex, StandardCharsets.US_ASCII), 16);
+ if (buf.readableBytes() >= payloadIndex + 1 + length + 1) {
+ ChannelBuffer frame = ChannelBuffers.dynamicBuffer();
+ int endIndex = buf.readerIndex() + payloadIndex + 1 + length + 1;
+ while (buf.readerIndex() < endIndex) {
+ byte b = buf.readByte();
+ if (b == 0x7D) {
+ switch (buf.readByte()) {
+ case 0x01:
+ frame.writeByte(0x7D);
+ break;
+ case 0x02:
+ frame.writeByte(0x5B);
+ break;
+ case 0x03:
+ frame.writeByte(0x5D);
+ break;
+ case 0x04:
+ frame.writeByte(0x2C);
+ break;
+ case 0x05:
+ frame.writeByte(0x2A);
+ break;
+ default:
+ throw new IllegalArgumentException();
}
+ } else {
+ frame.writeByte(b);
}
- return frame;
}
+ return frame;
}
return null;
diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java
index 86dc9456d..b58c3b6a1 100644
--- a/src/org/traccar/protocol/WatchProtocolDecoder.java
+++ b/src/org/traccar/protocol/WatchProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -48,7 +48,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
.expression("([NS]),")
.number(" *(-?d+.d+),") // longitude
.expression("([EW])?,")
- .number("(d+.d+),") // speed
+ .number("(d+.?d*),") // speed
.number("(d+.?d*),") // course
.number("(d+.?d*),") // altitude
.number("(d+),") // satellites
@@ -60,10 +60,15 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
.expression("(.*)") // cell and wifi
.compile();
- private void sendResponse(Channel channel, String manufacturer, String id, String content) {
+ private void sendResponse(Channel channel, String id, String index, String content) {
if (channel != null) {
- channel.write(String.format(
- "[%s*%s*%04x*%s]", manufacturer, id, content.length(), content));
+ if (index != null) {
+ channel.write(String.format(
+ "[%s*%s*%s*%04x*%s]", manufacturer, id, index, content.length(), content));
+ } else {
+ channel.write(String.format(
+ "[%s*%s*%04x*%s]", manufacturer, id, content.length(), content));
+ }
}
}
@@ -92,8 +97,38 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- private void decodeTail(Position position, String data) {
- String[] values = data.split(",");
+ private Position decodePosition(DeviceSession deviceSession, String data) {
+
+ Parser parser = new Parser(PATTERN_POSITION, data);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
+
+ position.setValid(parser.next().equals("A"));
+ position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
+ position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
+ position.setCourse(parser.nextDouble(0));
+ position.setAltitude(parser.nextDouble(0));
+
+ position.set(Position.KEY_SATELLITES, parser.nextInt(0));
+ position.set(Position.KEY_RSSI, parser.nextInt(0));
+ position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0));
+
+ position.set(Position.KEY_STEPS, parser.nextInt(0));
+
+ int status = parser.nextHexInt(0);
+ position.set(Position.KEY_ALARM, decodeAlarm(status));
+ if (BitUtil.check(status, 4)) {
+ position.set(Position.KEY_MOTION, true);
+ }
+
+ String[] values = parser.next().split(",");
int index = 0;
Network network = new Network();
@@ -122,6 +157,19 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) {
position.setNetwork(network);
}
+
+ return position;
+ }
+
+ private boolean hasIndex;
+ private String manufacturer;
+
+ public boolean getHasIndex() {
+ return hasIndex;
+ }
+
+ public String getManufacturer() {
+ return manufacturer;
}
@Override
@@ -131,22 +179,34 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
ChannelBuffer buf = (ChannelBuffer) msg;
buf.skipBytes(1); // header
- String manufacturer = buf.readBytes(2).toString(StandardCharsets.US_ASCII);
+ manufacturer = buf.readBytes(2).toString(StandardCharsets.US_ASCII);
buf.skipBytes(1); // delimiter
- String id = buf.readBytes(10).toString(StandardCharsets.US_ASCII);
+ int idIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*');
+ String id = buf.readBytes(idIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII);
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id);
if (deviceSession == null) {
return null;
}
buf.skipBytes(1); // delimiter
+
+ String index = null;
+ int contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*');
+ if (contentIndex + 5 < buf.writerIndex() && buf.getByte(contentIndex + 5) == '*'
+ && buf.toString(contentIndex + 1, 4, StandardCharsets.US_ASCII).matches("\\p{XDigit}+")) {
+ int indexLength = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*') - buf.readerIndex();
+ hasIndex = true;
+ index = buf.readBytes(indexLength).toString(StandardCharsets.US_ASCII);
+ buf.skipBytes(1); // delimiter
+ }
+
buf.skipBytes(4); // length
buf.skipBytes(1); // delimiter
buf.writerIndex(buf.writerIndex() - 1); // ignore ending
- int contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ',');
+ contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ',');
if (contentIndex < 0) {
contentIndex = buf.writerIndex();
}
@@ -157,15 +217,18 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
buf.readerIndex(contentIndex + 1);
}
- if (type.equals("LK")) {
+ if (type.equals("INIT")) {
+
+ sendResponse(channel, id, index, "INIT,1");
+
+ } else if (type.equals("LK")) {
- sendResponse(channel, manufacturer, id, "LK");
+ sendResponse(channel, id, index, "LK");
if (buf.readable()) {
String[] values = buf.toString(StandardCharsets.US_ASCII).split(",");
if (values.length >= 3) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
@@ -179,62 +242,38 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
} else if (type.equals("UD") || type.equals("UD2") || type.equals("UD3")
|| type.equals("AL") || type.equals("WT")) {
- if (type.equals("AL")) {
- sendResponse(channel, manufacturer, id, "AL");
- }
-
- Parser parser = new Parser(PATTERN_POSITION, buf.toString(StandardCharsets.US_ASCII));
- if (!parser.matches()) {
- return null;
- }
-
- Position position = new Position();
- position.setProtocol(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
-
- position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
+ Position position = decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII));
- position.setValid(parser.next().equals("A"));
- position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
- position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
- position.setCourse(parser.nextDouble(0));
- position.setAltitude(parser.nextDouble(0));
-
- position.set(Position.KEY_SATELLITES, parser.nextInt(0));
- position.set(Position.KEY_RSSI, parser.nextInt(0));
- position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0));
-
- position.set(Position.KEY_STEPS, parser.nextInt(0));
-
- int status = parser.nextHexInt(0);
- position.set(Position.KEY_ALARM, decodeAlarm(status));
- if (BitUtil.check(status, 4)) {
- position.set(Position.KEY_MOTION, true);
+ if (type.equals("AL")) {
+ if (position != null) {
+ position.set(Position.KEY_ALARM, Position.ALARM_SOS);
+ }
+ sendResponse(channel, id, index, "AL");
}
- decodeTail(position, parser.next());
-
return position;
} else if (type.equals("TKQ")) {
- sendResponse(channel, manufacturer, id, "TKQ");
+ sendResponse(channel, id, index, "TKQ");
- } else if (type.equals("PULSE") || type.equals("heart")) {
+ } else if (type.equals("PULSE") || type.equals("heart") || type.equals("bphrt")) {
if (buf.readable()) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(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);
+ String[] values = buf.toString(StandardCharsets.US_ASCII).split(",");
+ int valueIndex = 0;
+
+ if (type.equals("bphrt")) {
+ position.set("pressureHigh", values[valueIndex++]);
+ position.set("pressureLow", values[valueIndex++]);
+ }
+ position.set("pulse", values[valueIndex]);
return position;
@@ -242,8 +281,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
} else if (type.equals("img")) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
@@ -256,8 +294,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
} else if (type.equals("TK")) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, null);
diff --git a/src/org/traccar/protocol/WatchProtocolEncoder.java b/src/org/traccar/protocol/WatchProtocolEncoder.java
index d2d3b52d1..4c87f3abd 100644
--- a/src/org/traccar/protocol/WatchProtocolEncoder.java
+++ b/src/org/traccar/protocol/WatchProtocolEncoder.java
@@ -15,11 +15,12 @@
*/
package org.traccar.protocol;
+import org.jboss.netty.channel.Channel;
import org.traccar.StringProtocolEncoder;
+import org.traccar.helper.DataConverter;
import org.traccar.helper.Log;
import org.traccar.model.Command;
-import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
@@ -41,12 +42,27 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin
return null;
}
+ protected String formatCommand(Channel channel, Command command, String format, String... keys) {
+
+ boolean hasIndex = false;
+ String manufacturer = "CS";
+ if (channel != null) {
+ WatchProtocolDecoder decoder = channel.getPipeline().get(WatchProtocolDecoder.class);
+ if (decoder != null) {
+ hasIndex = decoder.getHasIndex();
+ manufacturer = decoder.getManufacturer();
+ }
+ }
- @Override
- protected String formatCommand(Command command, String format, String... keys) {
String content = formatCommand(command, format, this, keys);
- return String.format("[CS*%s*%04x*%s]",
- getUniqueId(command.getDeviceId()), content.length(), content);
+
+ if (hasIndex) {
+ return String.format("[%s*%s*0001*%04x*%s]",
+ manufacturer, getUniqueId(command.getDeviceId()), content.length(), content);
+ } else {
+ return String.format("[%s*%s*%04x*%s]",
+ manufacturer, getUniqueId(command.getDeviceId()), content.length(), content);
+ }
}
private int getEnableFlag(Command command) {
@@ -68,7 +84,7 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin
}
private String getBinaryData(Command command) {
- byte[] data = DatatypeConverter.parseHexBinary(command.getString(Command.KEY_DATA));
+ byte[] data = DataConverter.parseHex(command.getString(Command.KEY_DATA));
int encodedLength = data.length;
for (byte b : data) {
@@ -96,37 +112,37 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin
}
@Override
- protected Object encodeCommand(Command command) {
+ protected Object encodeCommand(Channel channel, Command command) {
switch (command.getType()) {
case Command.TYPE_CUSTOM:
- return formatCommand(command, command.getString(Command.KEY_DATA));
+ return formatCommand(channel, command, command.getString(Command.KEY_DATA));
case Command.TYPE_POSITION_SINGLE:
- return formatCommand(command, "RG");
+ return formatCommand(channel, command, "RG");
case Command.TYPE_SOS_NUMBER:
- return formatCommand(command, "SOS{%s},{%s}", Command.KEY_INDEX, Command.KEY_PHONE);
+ return formatCommand(channel, command, "SOS{%s},{%s}", Command.KEY_INDEX, Command.KEY_PHONE);
case Command.TYPE_ALARM_SOS:
- return formatCommand(command, "SOSSMS," + getEnableFlag(command));
+ return formatCommand(channel, command, "SOSSMS," + getEnableFlag(command));
case Command.TYPE_ALARM_BATTERY:
- return formatCommand(command, "LOWBAT," + getEnableFlag(command));
+ return formatCommand(channel, command, "LOWBAT," + getEnableFlag(command));
case Command.TYPE_REBOOT_DEVICE:
- return formatCommand(command, "RESET");
+ return formatCommand(channel, command, "RESET");
case Command.TYPE_ALARM_REMOVE:
- return formatCommand(command, "REMOVE," + getEnableFlag(command));
+ return formatCommand(channel, command, "REMOVE," + getEnableFlag(command));
case Command.TYPE_SILENCE_TIME:
- return formatCommand(command, "SILENCETIME,{%s}", Command.KEY_DATA);
+ return formatCommand(channel, command, "SILENCETIME,{%s}", Command.KEY_DATA);
case Command.TYPE_ALARM_CLOCK:
- return formatCommand(command, "REMIND,{%s}", Command.KEY_DATA);
+ return formatCommand(channel, command, "REMIND,{%s}", Command.KEY_DATA);
case Command.TYPE_SET_PHONEBOOK:
- return formatCommand(command, "PHB,{%s}", Command.KEY_DATA);
+ return formatCommand(channel, command, "PHB,{%s}", Command.KEY_DATA);
case Command.TYPE_VOICE_MESSAGE:
- return formatCommand(command, "TK," + getBinaryData(command));
+ return formatCommand(channel, command, "TK," + getBinaryData(command));
case Command.TYPE_POSITION_PERIODIC:
- return formatCommand(command, "UPLOAD,{%s}", Command.KEY_FREQUENCY);
+ return formatCommand(channel, command, "UPLOAD,{%s}", Command.KEY_FREQUENCY);
case Command.TYPE_SET_TIMEZONE:
- return formatCommand(command, "LZ,,{%s}", Command.KEY_TIMEZONE);
+ return formatCommand(channel, command, "LZ,,{%s}", Command.KEY_TIMEZONE);
case Command.TYPE_SET_INDICATOR:
- return formatCommand(command, "FLOWER,{%s}", Command.KEY_DATA);
+ return formatCommand(channel, command, "FLOWER,{%s}", Command.KEY_DATA);
default:
Log.warning(new UnsupportedOperationException(command.getType()));
break;
diff --git a/src/org/traccar/protocol/WialonProtocolDecoder.java b/src/org/traccar/protocol/WialonProtocolDecoder.java
index 4eb3b9b8e..5bc3e9972 100644
--- a/src/org/traccar/protocol/WialonProtocolDecoder.java
+++ b/src/org/traccar/protocol/WialonProtocolDecoder.java
@@ -80,8 +80,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
@@ -179,8 +178,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
} else if (sentence.startsWith("#M#")) {
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
if (deviceSession != null) {
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, new Date());
position.setValid(false);
diff --git a/src/org/traccar/protocol/WondexProtocolDecoder.java b/src/org/traccar/protocol/WondexProtocolDecoder.java
index e27745f38..a0fa436e4 100644
--- a/src/org/traccar/protocol/WondexProtocolDecoder.java
+++ b/src/org/traccar/protocol/WondexProtocolDecoder.java
@@ -70,17 +70,17 @@ public class WondexProtocolDecoder extends BaseProtocolDecoder {
return null;
} else if (buf.toString(StandardCharsets.US_ASCII).startsWith("$OK:")
|| buf.toString(StandardCharsets.US_ASCII).startsWith("$ERR:")
- || buf.toString(StandardCharsets.US_ASCII).startsWith("$MSG:")) {
+ || buf.toString(StandardCharsets.US_ASCII).startsWith("$MSG:")) {
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, new Date());
position.set(Position.KEY_RESULT, buf.toString(StandardCharsets.US_ASCII));
return position;
+
} else {
Parser parser = new Parser(PATTERN, buf.toString(StandardCharsets.US_ASCII));
@@ -88,8 +88,7 @@ public class WondexProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
@@ -120,6 +119,7 @@ public class WondexProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_OUTPUT, parser.next());
return position;
+
}
}
diff --git a/src/org/traccar/protocol/XexunProtocolDecoder.java b/src/org/traccar/protocol/XexunProtocolDecoder.java
index bb4b4f48c..a06a86021 100644
--- a/src/org/traccar/protocol/XexunProtocolDecoder.java
+++ b/src/org/traccar/protocol/XexunProtocolDecoder.java
@@ -106,8 +106,7 @@ public class XexunProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
if (full) {
position.set("serial", parser.next());
diff --git a/src/org/traccar/protocol/XirgoProtocolDecoder.java b/src/org/traccar/protocol/XirgoProtocolDecoder.java
index b1442170d..461503af1 100644
--- a/src/org/traccar/protocol/XirgoProtocolDecoder.java
+++ b/src/org/traccar/protocol/XirgoProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2018 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.
@@ -95,6 +95,71 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder {
.any()
.compile();
+ private void decodeEvent(Position position, int event) {
+
+ position.set(Position.KEY_EVENT, event);
+
+ switch (event) {
+ case 4001:
+ case 4003:
+ case 6011:
+ case 6013:
+ position.set(Position.KEY_IGNITION, true);
+ break;
+ case 4002:
+ case 4004:
+ case 6012:
+ case 6014:
+ position.set(Position.KEY_IGNITION, false);
+ break;
+ case 4005:
+ position.set(Position.KEY_CHARGE, false);
+ break;
+ case 6002:
+ position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED);
+ break;
+ case 6006:
+ position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION);
+ break;
+ case 6007:
+ position.set(Position.KEY_ALARM, Position.ALARM_BRAKING);
+ break;
+ case 6008:
+ position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER);
+ break;
+ case 6009:
+ position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT);
+ break;
+ case 6010:
+ position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED);
+ break;
+ case 6016:
+ position.set(Position.KEY_ALARM, Position.ALARM_IDLE);
+ break;
+ case 6017:
+ position.set(Position.KEY_ALARM, Position.ALARM_TOW);
+ break;
+ case 6030:
+ case 6071:
+ position.set(Position.KEY_MOTION, true);
+ break;
+ case 6031:
+ position.set(Position.KEY_MOTION, false);
+ break;
+ case 6032:
+ position.set(Position.KEY_ALARM, Position.ALARM_PARKING);
+ break;
+ case 6090:
+ position.set(Position.KEY_ALARM, Position.ALARM_REMOVING);
+ break;
+ case 6091:
+ position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY);
+ break;
+ default:
+ break;
+ }
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -125,8 +190,7 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder {
}
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
@@ -134,7 +198,7 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder {
}
position.setDeviceId(deviceSession.getDeviceId());
- position.set(Position.KEY_EVENT, parser.next());
+ decodeEvent(position, parser.nextInt());
position.setTime(parser.nextDateTime());
diff --git a/src/org/traccar/protocol/Xt013ProtocolDecoder.java b/src/org/traccar/protocol/Xt013ProtocolDecoder.java
index f1214fdb4..a92afd778 100644
--- a/src/org/traccar/protocol/Xt013ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Xt013ProtocolDecoder.java
@@ -65,8 +65,7 @@ public class Xt013ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
diff --git a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java
index 15e8558be..1be943e98 100644
--- a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java
@@ -20,10 +20,10 @@ import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.Context;
import org.traccar.DeviceSession;
+import org.traccar.helper.DataConverter;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
-import javax.xml.bind.DatatypeConverter;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Date;
@@ -95,7 +95,7 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
Pattern pattern = Pattern.compile(":wycfg pcr\\[\\d+\\] ([0-9a-fA-F]{2})[0-9a-fA-F]{2}([0-9a-fA-F]+)");
Matcher matcher = pattern.matcher(configString);
while (matcher.find()) {
- formats.put(Short.parseShort(matcher.group(1), 16), DatatypeConverter.parseHexBinary(matcher.group(2)));
+ formats.put(Short.parseShort(matcher.group(1), 16), DataConverter.parseHex(matcher.group(2)));
}
}
@@ -116,11 +116,10 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
for (byte tag : format) {
- switch ((int) tag) {
+ switch (tag) {
case 0x03:
DeviceSession deviceSession = getDeviceSession(
channel, remoteAddress, String.valueOf(buf.readUnsignedInt()));
diff --git a/src/org/traccar/protocol/YwtProtocolDecoder.java b/src/org/traccar/protocol/YwtProtocolDecoder.java
index 6a98ab9e7..3182b838d 100644
--- a/src/org/traccar/protocol/YwtProtocolDecoder.java
+++ b/src/org/traccar/protocol/YwtProtocolDecoder.java
@@ -76,8 +76,7 @@ public class YwtProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
String type = parser.next();