aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/traccar/BaseProtocolDecoder.java8
-rw-r--r--src/main/java/org/traccar/BaseProtocolEncoder.java25
-rw-r--r--src/main/java/org/traccar/StringProtocolEncoder.java6
-rw-r--r--src/main/java/org/traccar/config/Keys.java7
-rw-r--r--src/main/java/org/traccar/database/ConnectionManager.java2
-rw-r--r--src/main/java/org/traccar/database/DeviceManager.java57
-rw-r--r--src/main/java/org/traccar/database/IdentityManager.java19
-rw-r--r--src/main/java/org/traccar/handler/CopyAttributesHandler.java2
-rw-r--r--src/main/java/org/traccar/handler/FilterHandler.java2
-rw-r--r--src/main/java/org/traccar/handler/GeolocationHandler.java1
-rw-r--r--src/main/java/org/traccar/handler/events/FuelDropEventHandler.java2
-rw-r--r--src/main/java/org/traccar/handler/events/OverspeedEventHandler.java2
-rw-r--r--src/main/java/org/traccar/helper/DateBuilder.java4
-rw-r--r--src/main/java/org/traccar/model/Network.java6
-rw-r--r--src/main/java/org/traccar/model/Position.java3
-rw-r--r--src/main/java/org/traccar/protocol/AdmProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/AdmProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java194
-rw-r--r--src/main/java/org/traccar/protocol/AtrackProtocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java40
-rw-r--r--src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java13
-rw-r--r--src/main/java/org/traccar/protocol/BceProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/BceProtocolDecoder.java94
-rw-r--r--src/main/java/org/traccar/protocol/BceProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java4
-rw-r--r--src/main/java/org/traccar/protocol/CarcellProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java2
-rw-r--r--src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/CastelProtocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/CastelProtocolDecoder.java242
-rw-r--r--src/main/java/org/traccar/protocol/CastelProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/CellocatorProtocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java67
-rw-r--r--src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java44
-rw-r--r--src/main/java/org/traccar/protocol/CityeasyProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/DmtProtocolDecoder.java3
-rw-r--r--src/main/java/org/traccar/protocol/EelinkProtocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java3
-rw-r--r--src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java6
-rw-r--r--src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java32
-rw-r--r--src/main/java/org/traccar/protocol/EnforaProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/EsealProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/EsealProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/FifotrackProtocol.java2
-rw-r--r--src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java54
-rw-r--r--src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java5
-rw-r--r--src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java3
-rw-r--r--src/main/java/org/traccar/protocol/GalileoProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java6
-rw-r--r--src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/GatorProtocolDecoder.java8
-rw-r--r--src/main/java/org/traccar/protocol/Gl200Protocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java18
-rw-r--r--src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java70
-rw-r--r--src/main/java/org/traccar/protocol/GotopProtocolDecoder.java4
-rw-r--r--src/main/java/org/traccar/protocol/Gps103Protocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/GranitProtocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/GranitProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/Gt06Protocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java134
-rw-r--r--src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java21
-rw-r--r--src/main/java/org/traccar/protocol/H02Protocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/H02ProtocolDecoder.java9
-rw-r--r--src/main/java/org/traccar/protocol/H02ProtocolEncoder.java9
-rw-r--r--src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java32
-rw-r--r--src/main/java/org/traccar/protocol/HuabaoProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java31
-rw-r--r--src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/ItsProtocolDecoder.java29
-rw-r--r--src/main/java/org/traccar/protocol/ItsProtocolEncoder.java5
-rw-r--r--src/main/java/org/traccar/protocol/Jt600FrameDecoder.java2
-rw-r--r--src/main/java/org/traccar/protocol/Jt600Protocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java9
-rw-r--r--src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/KhdProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/KhdProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/LaipacProtocol.java10
-rw-r--r--src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java178
-rw-r--r--src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java57
-rw-r--r--src/main/java/org/traccar/protocol/LeafSpyProtocol.java40
-rw-r--r--src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java139
-rw-r--r--src/main/java/org/traccar/protocol/MeiligaoProtocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/MeitrackProtocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java9
-rw-r--r--src/main/java/org/traccar/protocol/MictrackProtocol.java47
-rw-r--r--src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java181
-rw-r--r--src/main/java/org/traccar/protocol/MiniFinderProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java29
-rw-r--r--src/main/java/org/traccar/protocol/NavisetFrameDecoder.java39
-rw-r--r--src/main/java/org/traccar/protocol/NavisetProtocol.java34
-rw-r--r--src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java249
-rw-r--r--src/main/java/org/traccar/protocol/NoranProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/NoranProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/PacificTrackProtocol.java33
-rw-r--r--src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java104
-rw-r--r--src/main/java/org/traccar/protocol/PluginProtocol.java39
-rw-r--r--src/main/java/org/traccar/protocol/PluginProtocolDecoder.java93
-rw-r--r--src/main/java/org/traccar/protocol/PretraceProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/Pt215FrameDecoder.java55
-rw-r--r--src/main/java/org/traccar/protocol/Pt215Protocol.java34
-rw-r--r--src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java118
-rw-r--r--src/main/java/org/traccar/protocol/Pt502Protocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java39
-rw-r--r--src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java171
-rw-r--r--src/main/java/org/traccar/protocol/RstProtocol.java37
-rw-r--r--src/main/java/org/traccar/protocol/RstProtocolDecoder.java128
-rw-r--r--src/main/java/org/traccar/protocol/RuptelaProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java5
-rw-r--r--src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java125
-rw-r--r--src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java58
-rw-r--r--src/main/java/org/traccar/protocol/SuntechProtocol.java2
-rw-r--r--src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java50
-rw-r--r--src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/SviasProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/SviasProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/T55ProtocolDecoder.java35
-rw-r--r--src/main/java/org/traccar/protocol/T800xProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/T800xProtocolDecoder.java169
-rw-r--r--src/main/java/org/traccar/protocol/T800xProtocolEncoder.java22
-rw-r--r--src/main/java/org/traccar/protocol/TechTltProtocol.java2
-rw-r--r--src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java53
-rw-r--r--src/main/java/org/traccar/protocol/TelicProtocolDecoder.java36
-rw-r--r--src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java8
-rw-r--r--src/main/java/org/traccar/protocol/TeltonikaProtocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java14
-rw-r--r--src/main/java/org/traccar/protocol/TeltonikaProtocolEncoder.java5
-rw-r--r--src/main/java/org/traccar/protocol/Tk103Protocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java11
-rw-r--r--src/main/java/org/traccar/protocol/TotemProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/TotemProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/TramigoFrameDecoder.java4
-rw-r--r--src/main/java/org/traccar/protocol/TrvProtocolDecoder.java10
-rw-r--r--src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java59
-rw-r--r--src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java5
-rw-r--r--src/main/java/org/traccar/protocol/UproProtocolDecoder.java67
-rw-r--r--src/main/java/org/traccar/protocol/WatchProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/WatchProtocolDecoder.java15
-rw-r--r--src/main/java/org/traccar/protocol/WatchProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/WialonProtocol.java23
-rw-r--r--src/main/java/org/traccar/protocol/WialonProtocolDecoder.java49
-rw-r--r--src/main/java/org/traccar/protocol/WialonProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/WondexProtocol.java8
-rw-r--r--src/main/java/org/traccar/protocol/WondexProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/XexunProtocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/XexunProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/XirgoProtocol.java6
-rw-r--r--src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java2
-rw-r--r--src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/Xrb28Protocol.java4
-rw-r--r--src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java7
-rw-r--r--src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java20
-rw-r--r--src/main/java/org/traccar/reports/Stops.java2
-rw-r--r--src/main/java/org/traccar/reports/Summary.java2
-rw-r--r--src/main/java/org/traccar/reports/Trips.java2
-rw-r--r--src/test/java/org/traccar/TestIdentityManager.java15
-rw-r--r--src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/AquilaProtocolDecoderTest.java25
-rw-r--r--src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java22
-rw-r--r--src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java10
-rw-r--r--src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java6
-rw-r--r--src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java8
-rw-r--r--src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java2
-rw-r--r--src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java25
-rw-r--r--src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java2
-rw-r--r--src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java12
-rw-r--r--src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java2
-rw-r--r--src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java9
-rw-r--r--src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java13
-rw-r--r--src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java8
-rw-r--r--src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java26
-rw-r--r--src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java2
-rw-r--r--src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java24
-rw-r--r--src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java2
-rw-r--r--src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java9
-rw-r--r--src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java2
-rw-r--r--src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java25
-rw-r--r--src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java21
-rw-r--r--src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java2
-rw-r--r--src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java37
-rw-r--r--src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java2
-rw-r--r--src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java6
-rw-r--r--src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java19
-rw-r--r--src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java30
-rw-r--r--src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java32
-rw-r--r--src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java27
-rw-r--r--src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java8
-rw-r--r--src/test/java/org/traccar/protocol/Pt215FrameDecoderTest.java27
-rw-r--r--src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java21
-rw-r--r--src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java14
-rw-r--r--src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java21
-rw-r--r--src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java26
-rw-r--r--src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java14
-rw-r--r--src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java5
-rw-r--r--src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java7
-rw-r--r--src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java5
-rw-r--r--src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java13
-rw-r--r--src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java8
-rw-r--r--src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java6
-rw-r--r--src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java23
-rw-r--r--src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java54
-rw-r--r--src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java6
-rw-r--r--src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java3
-rw-r--r--src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java6
-rw-r--r--src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java4
-rw-r--r--src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java17
-rw-r--r--src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java6
-rw-r--r--src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java6
-rw-r--r--src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java7
-rw-r--r--src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java2
-rw-r--r--src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java6
-rw-r--r--src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java8
-rw-r--r--src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java5
247 files changed, 4255 insertions, 1034 deletions
diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java
index aa5be612e..e6e02c2d6 100644
--- a/src/main/java/org/traccar/BaseProtocolDecoder.java
+++ b/src/main/java/org/traccar/BaseProtocolDecoder.java
@@ -86,7 +86,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder {
protected TimeZone getTimeZone(long deviceId, String defaultTimeZone) {
TimeZone result = TimeZone.getTimeZone(defaultTimeZone);
- String timeZoneName = identityManager.lookupAttributeString(deviceId, "decoder.timezone", null, true);
+ String timeZoneName = identityManager.lookupAttributeString(deviceId, "decoder.timezone", null, false, true);
if (timeZoneName != null) {
result = TimeZone.getTimeZone(timeZoneName);
} else {
@@ -143,7 +143,13 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder {
}
public DeviceSession getDeviceSession(Channel channel, SocketAddress remoteAddress, String... uniqueIds) {
+ return getDeviceSession(channel, remoteAddress, false, uniqueIds);
+ }
+
+ public DeviceSession getDeviceSession(
+ Channel channel, SocketAddress remoteAddress, boolean ignoreCache, String... uniqueIds) {
if (channel != null && BasePipelineFactory.getHandler(channel.pipeline(), HttpRequestDecoder.class) != null
+ || ignoreCache || config.getBoolean(getProtocolName() + ".ignoreSessionCache")
|| config.getBoolean("decoder.ignoreSessionCache")) {
long deviceId = findDeviceId(remoteAddress, uniqueIds);
if (deviceId != 0) {
diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java
index d7625e4b8..b6df07b98 100644
--- a/src/main/java/org/traccar/BaseProtocolEncoder.java
+++ b/src/main/java/org/traccar/BaseProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,25 +22,32 @@ import io.netty.channel.ChannelPromise;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.traccar.model.Command;
-import org.traccar.model.Device;
public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(BaseProtocolEncoder.class);
+ private static final String PROTOCOL_UNKNOWN = "unknown";
+
+ private final Protocol protocol;
+
+ public BaseProtocolEncoder(Protocol protocol) {
+ this.protocol = protocol;
+ }
+
+ public String getProtocolName() {
+ return protocol != null ? protocol.getName() : PROTOCOL_UNKNOWN;
+ }
+
protected String getUniqueId(long deviceId) {
return Context.getIdentityManager().getById(deviceId).getUniqueId();
}
protected void initDevicePassword(Command command, String defaultPassword) {
if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) {
- Device device = Context.getIdentityManager().getById(command.getDeviceId());
- String password = device.getString(Command.KEY_DEVICE_PASSWORD);
- if (password != null) {
- command.set(Command.KEY_DEVICE_PASSWORD, password);
- } else {
- command.set(Command.KEY_DEVICE_PASSWORD, defaultPassword);
- }
+ String password = Context.getIdentityManager()
+ .getDevicePassword(command.getDeviceId(), getProtocolName(), defaultPassword);
+ command.set(Command.KEY_DEVICE_PASSWORD, password);
}
}
diff --git a/src/main/java/org/traccar/StringProtocolEncoder.java b/src/main/java/org/traccar/StringProtocolEncoder.java
index 1945ae174..d9acce7f0 100644
--- a/src/main/java/org/traccar/StringProtocolEncoder.java
+++ b/src/main/java/org/traccar/StringProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,10 @@ import java.util.Map;
public abstract class StringProtocolEncoder extends BaseProtocolEncoder {
+ public StringProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
public interface ValueFormatter {
String formatValue(String key, Object value);
}
diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java
index a000329e2..2c5dcefd5 100644
--- a/src/main/java/org/traccar/config/Keys.java
+++ b/src/main/java/org/traccar/config/Keys.java
@@ -197,8 +197,9 @@ public final class Keys {
"time.protocols", String.class);
/**
- * Replaces coordinates with last known if change is less than a 'coordinates.error' meters. Helps to avoid
- * coordinates jumps during parking period.
+ * Replaces coordinates with last known if change is less than a 'coordinates.minError' meters
+ * or more than a 'coordinates.maxError' meters. Helps to avoid coordinates jumps during parking period
+ * or jumps to zero coordinates.
*/
public static final ConfigKey COORDINATES_FILTER = new ConfigKey(
"coordinates.filter", Boolean.class);
@@ -214,7 +215,7 @@ public final class Keys {
* Position is also marked as 'invalid'.
*/
public static final ConfigKey COORDINATES_MAX_ERROR = new ConfigKey(
- "filter.maxError", Integer.class);
+ "coordinates.maxError", Integer.class);
/**
* Enable to save device IP addresses information. Disabled by default.
diff --git a/src/main/java/org/traccar/database/ConnectionManager.java b/src/main/java/org/traccar/database/ConnectionManager.java
index 8bae1ea93..dd0071143 100644
--- a/src/main/java/org/traccar/database/ConnectionManager.java
+++ b/src/main/java/org/traccar/database/ConnectionManager.java
@@ -157,7 +157,7 @@ public class ConnectionManager {
event = Main.getInjector().getInstance(OverspeedEventHandler.class)
.updateOverspeedState(deviceState, Context.getDeviceManager().
- lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false));
+ lookupAttributeDouble(deviceId, OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, true, false));
if (event != null) {
result.putAll(event);
}
diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java
index de4607d1f..fa95adeb2 100644
--- a/src/main/java/org/traccar/database/DeviceManager.java
+++ b/src/main/java/org/traccar/database/DeviceManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.traccar.config.Config;
import org.traccar.Context;
+import org.traccar.model.Command;
import org.traccar.model.Device;
import org.traccar.model.DeviceState;
import org.traccar.model.DeviceAccumulators;
@@ -114,6 +115,24 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity
return devicesByUniqueId.get(uniqueId);
}
+ @Override
+ public String getDevicePassword(long id, String protocol, String defaultPassword) {
+
+ String password = lookupAttributeString(id, Command.KEY_DEVICE_PASSWORD, null, false, false);
+ if (password != null) {
+ return password;
+ }
+
+ if (protocol != null) {
+ password = Context.getConfig().getString(protocol + "." + Command.KEY_DEVICE_PASSWORD);
+ if (password != null) {
+ return password;
+ }
+ }
+
+ return defaultPassword;
+ }
+
public Device getDeviceByPhone(String phone) {
return devicesByPhone.get(phone);
}
@@ -312,8 +331,8 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity
@Override
public boolean lookupAttributeBoolean(
- long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) {
- Object result = lookupAttribute(deviceId, attributeName, lookupConfig);
+ long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig) {
+ Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig);
if (result != null) {
return result instanceof String ? Boolean.parseBoolean((String) result) : (Boolean) result;
}
@@ -322,14 +341,15 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity
@Override
public String lookupAttributeString(
- long deviceId, String attributeName, String defaultValue, boolean lookupConfig) {
- Object result = lookupAttribute(deviceId, attributeName, lookupConfig);
+ long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) {
+ Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig);
return result != null ? (String) result : defaultValue;
}
@Override
- public int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig) {
- Object result = lookupAttribute(deviceId, attributeName, lookupConfig);
+ public int lookupAttributeInteger(
+ long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig) {
+ Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig);
if (result != null) {
return result instanceof String ? Integer.parseInt((String) result) : ((Number) result).intValue();
}
@@ -338,8 +358,8 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity
@Override
public long lookupAttributeLong(
- long deviceId, String attributeName, long defaultValue, boolean lookupConfig) {
- Object result = lookupAttribute(deviceId, attributeName, lookupConfig);
+ long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig) {
+ Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig);
if (result != null) {
return result instanceof String ? Long.parseLong((String) result) : ((Number) result).longValue();
}
@@ -347,15 +367,15 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity
}
public double lookupAttributeDouble(
- long deviceId, String attributeName, double defaultValue, boolean lookupConfig) {
- Object result = lookupAttribute(deviceId, attributeName, lookupConfig);
+ long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig) {
+ Object result = lookupAttribute(deviceId, attributeName, lookupServer, lookupConfig);
if (result != null) {
return result instanceof String ? Double.parseDouble((String) result) : ((Number) result).doubleValue();
}
return defaultValue;
}
- private Object lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) {
+ private Object lookupAttribute(long deviceId, String attributeName, boolean lookupServer, boolean lookupConfig) {
Object result = null;
Device device = getById(deviceId);
if (device != null) {
@@ -375,13 +395,12 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity
}
}
}
- if (result == null) {
- if (lookupConfig) {
- result = Context.getConfig().getString(attributeName);
- } else {
- Server server = Context.getPermissionsManager().getServer();
- result = server.getAttributes().get(attributeName);
- }
+ if (result == null && lookupServer) {
+ Server server = Context.getPermissionsManager().getServer();
+ result = server.getAttributes().get(attributeName);
+ }
+ if (result == null && lookupConfig) {
+ result = Context.getConfig().getString(attributeName);
}
}
return result;
diff --git a/src/main/java/org/traccar/database/IdentityManager.java b/src/main/java/org/traccar/database/IdentityManager.java
index 6228a0f75..af6a6ce71 100644
--- a/src/main/java/org/traccar/database/IdentityManager.java
+++ b/src/main/java/org/traccar/database/IdentityManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,18 +26,25 @@ public interface IdentityManager {
Device getByUniqueId(String uniqueId) throws Exception;
+ String getDevicePassword(long id, String protocol, String defaultPassword);
+
Position getLastPosition(long deviceId);
boolean isLatestPosition(Position position);
- boolean lookupAttributeBoolean(long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig);
+ boolean lookupAttributeBoolean(
+ long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig);
- String lookupAttributeString(long deviceId, String attributeName, String defaultValue, boolean lookupConfig);
+ String lookupAttributeString(
+ long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig);
- int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig);
+ int lookupAttributeInteger(
+ long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig);
- long lookupAttributeLong(long deviceId, String attributeName, long defaultValue, boolean lookupConfig);
+ long lookupAttributeLong(
+ long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig);
- double lookupAttributeDouble(long deviceId, String attributeName, double defaultValue, boolean lookupConfig);
+ double lookupAttributeDouble(
+ long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig);
}
diff --git a/src/main/java/org/traccar/handler/CopyAttributesHandler.java b/src/main/java/org/traccar/handler/CopyAttributesHandler.java
index 6a0966d33..3cd7d144d 100644
--- a/src/main/java/org/traccar/handler/CopyAttributesHandler.java
+++ b/src/main/java/org/traccar/handler/CopyAttributesHandler.java
@@ -33,7 +33,7 @@ public class CopyAttributesHandler extends BaseDataHandler {
@Override
protected Position handlePosition(Position position) {
String attributesString = identityManager.lookupAttributeString(
- position.getDeviceId(), "processing.copyAttributes", "", true);
+ position.getDeviceId(), "processing.copyAttributes", "", false, true);
if (attributesString.isEmpty()) {
attributesString = Position.KEY_DRIVER_UNIQUE_ID;
} else {
diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java
index dceaede01..7cd9153c1 100644
--- a/src/main/java/org/traccar/handler/FilterHandler.java
+++ b/src/main/java/org/traccar/handler/FilterHandler.java
@@ -130,7 +130,7 @@ public class FilterHandler extends BaseDataHandler {
private boolean skipAttributes(Position position) {
if (skipAttributes) {
String attributesString = Context.getIdentityManager().lookupAttributeString(
- position.getDeviceId(), "filter.skipAttributes", "", true);
+ position.getDeviceId(), "filter.skipAttributes", "", false, true);
for (String attribute : attributesString.split("[ ,]")) {
if (position.getAttributes().containsKey(attribute)) {
return true;
diff --git a/src/main/java/org/traccar/handler/GeolocationHandler.java b/src/main/java/org/traccar/handler/GeolocationHandler.java
index c7b39e491..0e78322c8 100644
--- a/src/main/java/org/traccar/handler/GeolocationHandler.java
+++ b/src/main/java/org/traccar/handler/GeolocationHandler.java
@@ -65,7 +65,6 @@ public class GeolocationHandler extends ChannelInboundHandlerAdapter {
position.setAltitude(0);
position.setSpeed(0);
position.setCourse(0);
- position.set(Position.KEY_RSSI, 0);
ctx.fireChannelRead(position);
}
diff --git a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java
index 59de61bba..bc1426b86 100644
--- a/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/FuelDropEventHandler.java
@@ -47,7 +47,7 @@ public class FuelDropEventHandler extends BaseEventHandler {
}
double fuelDropThreshold = identityManager
- .lookupAttributeDouble(device.getId(), ATTRIBUTE_FUEL_DROP_THRESHOLD, 0, false);
+ .lookupAttributeDouble(device.getId(), ATTRIBUTE_FUEL_DROP_THRESHOLD, 0, true, false);
if (fuelDropThreshold > 0) {
Position lastPosition = identityManager.getLastPosition(position.getDeviceId());
diff --git a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java
index 157bb64e0..e534df9de 100644
--- a/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java
+++ b/src/main/java/org/traccar/handler/events/OverspeedEventHandler.java
@@ -120,7 +120,7 @@ public class OverspeedEventHandler extends BaseEventHandler {
return null;
}
- double speedLimit = deviceManager.lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, false);
+ double speedLimit = deviceManager.lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, true, false);
double geofenceSpeedLimit = 0;
long overspeedGeofenceId = 0;
diff --git a/src/main/java/org/traccar/helper/DateBuilder.java b/src/main/java/org/traccar/helper/DateBuilder.java
index 6e1b779f0..9752f6977 100644
--- a/src/main/java/org/traccar/helper/DateBuilder.java
+++ b/src/main/java/org/traccar/helper/DateBuilder.java
@@ -69,7 +69,9 @@ public class DateBuilder {
public DateBuilder setCurrentDate() {
Calendar now = Calendar.getInstance(calendar.getTimeZone());
- return setYear(now.get(Calendar.YEAR)).setMonth(now.get(Calendar.MONTH)).setDay(now.get(Calendar.DAY_OF_MONTH));
+ return setYear(now.get(Calendar.YEAR))
+ .setMonth(now.get(Calendar.MONTH) + 1)
+ .setDay(now.get(Calendar.DAY_OF_MONTH));
}
public DateBuilder setHour(int hour) {
diff --git a/src/main/java/org/traccar/model/Network.java b/src/main/java/org/traccar/model/Network.java
index 2d56950f1..4d67fc5d8 100644
--- a/src/main/java/org/traccar/model/Network.java
+++ b/src/main/java/org/traccar/model/Network.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,6 +30,10 @@ public class Network {
addCellTower(cellTower);
}
+ public Network(WifiAccessPoint wifiAccessPoint) {
+ addWifiAccessPoint(wifiAccessPoint);
+ }
+
private Integer homeMobileCountryCode;
public Integer getHomeMobileCountryCode() {
diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java
index 6032dc588..2c0e22c9e 100644
--- a/src/main/java/org/traccar/model/Position.java
+++ b/src/main/java/org/traccar/model/Position.java
@@ -82,6 +82,9 @@ public class Position extends Message {
public static final String KEY_BLOCKED = "blocked";
public static final String KEY_DOOR = "door";
public static final String KEY_AXLE_WEIGHT = "axleWeight";
+ public static final String KEY_G_SENSOR = "gSensor";
+ public static final String KEY_ICCID = "iccid";
+ public static final String KEY_PHONE = "phone";
public static final String KEY_DTCS = "dtcs";
public static final String KEY_OBD_SPEED = "obdSpeed"; // knots
diff --git a/src/main/java/org/traccar/protocol/AdmProtocol.java b/src/main/java/org/traccar/protocol/AdmProtocol.java
index 08f932ceb..93b1e355a 100644
--- a/src/main/java/org/traccar/protocol/AdmProtocol.java
+++ b/src/main/java/org/traccar/protocol/AdmProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ public class AdmProtocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 1, -3, 0, true));
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new AdmProtocolEncoder());
+ pipeline.addLast(new AdmProtocolEncoder(AdmProtocol.this));
pipeline.addLast(new AdmProtocolDecoder(AdmProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java b/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java
index e76bc2ddc..1c3dfc156 100644
--- a/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
* Copyright 2017 Anatoliy Golubev (darth.naihil@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,9 +18,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class AdmProtocolEncoder extends StringProtocolEncoder {
+ public AdmProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java
index 57af5e366..3c43ddf2a 100644
--- a/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/AquilaProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,15 +17,11 @@ package org.traccar.protocol;
import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
-import org.traccar.Context;
import org.traccar.DeviceSession;
-import org.traccar.NetworkMessage;
import org.traccar.Protocol;
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;
@@ -134,9 +130,11 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
.number("xx") // checksum
.compile();
- private Position decodeA(Channel channel, SocketAddress remoteAddress, String sentence) {
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
- Parser parser = new Parser(PATTERN_A, sentence);
+ Parser parser = new Parser(PATTERN_A, (String) msg);
if (!parser.matches()) {
return null;
}
@@ -218,186 +216,4 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
return position;
}
- private static final Pattern PATTERN_B_1 = new PatternBuilder()
- .text("$")
- .expression("[^,]+,") // header
- .expression("[^,]+,") // client
- .expression("[^,]+,") // firmware version
- .expression(".{2},") // packet 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 static final Pattern PATTERN_B_2 = new PatternBuilder()
- .text("$")
- .expression("[^,]+,") // header
- .expression("[^,]+,") // client
- .expression("(.{3}),") // message type
- .number("(d+),") // imei
- .expression(".{2},") // packet type
- .number("(dd)(dd)(dddd)") // date (ddmmyyyy)
- .number("(dd)(dd)(dd),") // time (hhmmss)
- .expression("([AV]),") // validity
- .number("(-?d+.d+),") // latitude
- .expression("([NS]),")
- .number("(-?d+.d+),") // longitude
- .expression("([EW]),")
- .number("(-?d+.d+),") // altitude
- .number("(d+.d+),") // speed
- .any()
- .compile();
-
- private Position decodeB2(Channel channel, SocketAddress remoteAddress, String sentence) {
-
- Parser parser = new Parser(PATTERN_B_2, sentence);
- if (!parser.matches()) {
- return null;
- }
-
- String type = parser.next();
- String id = parser.next();
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id);
- if (deviceSession == null) {
- 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.setAltitude(parser.nextDouble());
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble()));
-
- if (type.equals("EMR") && channel != null) {
- String password = Context.getIdentityManager().lookupAttributeString(
- deviceSession.getDeviceId(), getProtocolName() + ".password", "aquila123", true);
- channel.writeAndFlush(new NetworkMessage(
- "#set$" + id + "@" + password + "#EMR_MODE:0*", remoteAddress));
- }
-
- return position;
- }
-
- private Position decodeB1(Channel channel, SocketAddress remoteAddress, String sentence) {
-
- Parser parser = new Parser(PATTERN_B_1, sentence);
- if (!parser.matches()) {
- return null;
- }
-
- String id = parser.next();
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id);
- 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());
-
- if (parser.nextInt() == 1) {
- position.set(Position.KEY_ALARM, Position.ALARM_SOS);
- }
-
- 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;
- }
-
- private Position decodeB(Channel channel, SocketAddress remoteAddress, String sentence) {
- if (sentence.contains("EMR") || sentence.contains("SEM")) {
- return decodeB2(channel, remoteAddress, sentence);
- } else {
- return decodeB1(channel, remoteAddress, sentence);
- }
- }
-
- @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/main/java/org/traccar/protocol/AtrackProtocol.java b/src/main/java/org/traccar/protocol/AtrackProtocol.java
index 8e5cfe9ff..429708b26 100644
--- a/src/main/java/org/traccar/protocol/AtrackProtocol.java
+++ b/src/main/java/org/traccar/protocol/AtrackProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,14 +29,14 @@ public class AtrackProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new AtrackFrameDecoder());
- pipeline.addLast(new AtrackProtocolEncoder());
+ pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this));
pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this));
}
});
addServer(new TrackerServer(true, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new AtrackProtocolEncoder());
+ pipeline.addLast(new AtrackProtocolEncoder(AtrackProtocol.this));
pipeline.addLast(new AtrackProtocolDecoder(AtrackProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java
index 71bb6791c..53f04234d 100644
--- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,6 +84,10 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
this.custom = custom;
}
+ public void setForm(String form) {
+ this.form = form;
+ }
+
private static void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) {
if (channel != null) {
ByteBuf response = Unpooled.buffer(12);
@@ -156,7 +160,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_THROTTLE, Integer.parseInt(values[i]));
break;
case "ET":
- position.set(Position.PREFIX_TEMP + 1, Integer.parseInt(values[i]));
+ position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[i]));
break;
case "FL":
position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(values[i]));
@@ -167,6 +171,36 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
case "AV1":
position.set(Position.PREFIX_ADC + 1, Integer.parseInt(values[i]));
break;
+ case "CD":
+ position.set(Position.KEY_ICCID, values[i]);
+ break;
+ case "EH":
+ position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(Integer.parseInt(values[i]) * 0.1));
+ break;
+ case "IA":
+ position.set("intakeTemp", Integer.parseInt(values[i]));
+ break;
+ case "EL":
+ position.set(Position.KEY_ENGINE_LOAD, Integer.parseInt(values[i]));
+ break;
+ case "HA":
+ if (Integer.parseInt(values[i]) > 0) {
+ position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION);
+ }
+ break;
+ case "HB":
+ if (Integer.parseInt(values[i]) > 0) {
+ position.set(Position.KEY_ALARM, Position.ALARM_BRAKING);
+ }
+ break;
+ case "HC":
+ if (Integer.parseInt(values[i]) > 0) {
+ position.set(Position.KEY_ALARM, Position.ALARM_CORNERING);
+ }
+ break;
+ case "MT":
+ position.set(Position.KEY_MOTION, Integer.parseInt(values[i]) > 0);
+ break;
default:
break;
}
@@ -274,7 +308,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte(); // pending code status
break;
case "CD":
- readString(buf); // sim cid
+ position.set(Position.KEY_ICCID, readString(buf));
break;
case "CM":
buf.readLong(); // imsi
diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java
index 1e085cb26..d803ae391 100644
--- a/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,11 +18,16 @@ package org.traccar.protocol;
import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
public class AtrackProtocolEncoder extends BaseProtocolEncoder {
+ public AtrackProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java
index 16a31162a..37836ad5f 100644
--- a/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/AvemaProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,17 +48,19 @@ public class AvemaProtocolDecoder extends BaseProtocolDecoder {
.number("(d+),") // event
.number("(d+.d+),") // odometer
.number("(d+),") // input
- .number("(d+.d+)V,") // adc 1
- .number("(d+.d+)V,") // adc 2
+ .number("(d+.d+)V?,") // adc 1
+ .number("(d+.d+)V?,") // adc 2
.number("(d+),") // output
.number("(d),") // roaming
.number("(d+),") // rssi
.number("d,") // communication system
- .number("(ddd)") // mcc
- .number("(dd),") // mnc
+ .number("(ddd)-?") // mcc
+ .number("(d+),") // mnc
.number("(x+),") // lac
.number("(x+),") // cid
+ .number("(d+.d+),").optional() // battery
.number("([^,]+)?") // rfid
+ .any()
.compile();
@Override
@@ -99,6 +101,7 @@ public class AvemaProtocolDecoder extends BaseProtocolDecoder {
position.setNetwork(new Network(CellTower.from(
parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt(), rssi)));
+ position.set(Position.KEY_BATTERY, parser.nextDouble());
position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
return position;
diff --git a/src/main/java/org/traccar/protocol/BceProtocol.java b/src/main/java/org/traccar/protocol/BceProtocol.java
index 6453a05a9..c5e1dd04c 100644
--- a/src/main/java/org/traccar/protocol/BceProtocol.java
+++ b/src/main/java/org/traccar/protocol/BceProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ public class BceProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new BceFrameDecoder());
- pipeline.addLast(new BceProtocolEncoder());
+ pipeline.addLast(new BceProtocolEncoder(BceProtocol.this));
pipeline.addLast(new BceProtocolDecoder(BceProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java
index ad7271f2f..30f9bb1f3 100644
--- a/src/main/java/org/traccar/protocol/BceProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/BceProtocolDecoder.java
@@ -29,6 +29,7 @@ import org.traccar.model.Network;
import org.traccar.model.Position;
import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@@ -106,31 +107,31 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte(); // acceleration pedal
}
if (BitUtil.check(mask, 2)) {
- buf.readUnsignedIntLE(); // total fuel used
+ position.set(Position.KEY_FUEL_USED, buf.readUnsignedIntLE());
}
if (BitUtil.check(mask, 3)) {
- buf.readUnsignedByte(); // fuel level
+ position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte());
}
if (BitUtil.check(mask, 4)) {
- buf.readUnsignedShortLE(); // engine speed
+ position.set(Position.KEY_RPM, buf.readUnsignedShortLE());
}
if (BitUtil.check(mask, 5)) {
- buf.readUnsignedIntLE(); // total hours
+ position.set(Position.KEY_HOURS, buf.readUnsignedIntLE());
}
if (BitUtil.check(mask, 6)) {
- buf.readUnsignedIntLE(); // total distance
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE());
}
if (BitUtil.check(mask, 7)) {
- buf.readUnsignedByte(); // engine coolant
+ position.set(Position.KEY_COOLANT_TEMP, (int) buf.readByte());
}
if (BitUtil.check(mask, 8)) {
- buf.readUnsignedByte(); // fuel level 2
+ position.set("fuel2", buf.readUnsignedByte());
}
if (BitUtil.check(mask, 9)) {
- buf.readUnsignedByte(); // engine load
+ position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte());
}
if (BitUtil.check(mask, 10)) {
- buf.readUnsignedShortLE(); // service distance
+ position.set(Position.KEY_ODOMETER_SERVICE, buf.readUnsignedShortLE());
}
if (BitUtil.check(mask, 11)) {
buf.skipBytes(8); // sensors
@@ -142,7 +143,7 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
buf.skipBytes(8); // trailer id
}
if (BitUtil.check(mask, 14)) {
- buf.readUnsignedShortLE(); // fuel rate
+ position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShortLE());
}
}
@@ -152,10 +153,10 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedShortLE(); // fuel economy
}
if (BitUtil.check(mask, 1)) {
- buf.readUnsignedIntLE(); // fuel consumption
+ position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedIntLE());
}
if (BitUtil.check(mask, 2)) {
- buf.readUnsignedMediumLE(); // axle weight
+ position.set(Position.KEY_AXLE_WEIGHT, buf.readUnsignedMediumLE());
}
if (BitUtil.check(mask, 3)) {
buf.readUnsignedByte(); // mil status
@@ -169,6 +170,70 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
if (BitUtil.check(mask, 6)) {
position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readLongLE()));
}
+ if (BitUtil.check(mask, 7)) {
+ buf.readUnsignedShortLE(); // dallas temperature
+ }
+ if (BitUtil.check(mask, 8)) {
+ buf.readUnsignedShortLE(); // dallas humidity
+ }
+ if (BitUtil.check(mask, 9)) {
+ buf.skipBytes(6); // lls group 1
+ }
+ if (BitUtil.check(mask, 10)) {
+ buf.skipBytes(6); // lls group 2
+ }
+ if (BitUtil.check(mask, 11)) {
+ buf.skipBytes(21); // j1979 group 1
+ }
+ if (BitUtil.check(mask, 12)) {
+ buf.skipBytes(20); // j1979 dtc
+ }
+ if (BitUtil.check(mask, 13)) {
+ buf.skipBytes(9); // j1708 group 1
+ }
+ if (BitUtil.check(mask, 14)) {
+ buf.skipBytes(21); // driving quality
+ }
+ }
+
+ private void decodeMask4(ByteBuf buf, int mask, Position position) {
+
+ if (BitUtil.check(mask, 0)) {
+ buf.readUnsignedIntLE();
+ }
+ if (BitUtil.check(mask, 1)) {
+ buf.skipBytes(30); // lls group 3
+ }
+ if (BitUtil.check(mask, 2)) {
+ buf.readUnsignedIntLE(); // instant fuel consumption
+ }
+ if (BitUtil.check(mask, 3)) {
+ buf.skipBytes(10); // axle weight group
+ }
+ if (BitUtil.check(mask, 4)) {
+ buf.readUnsignedByte();
+ }
+ if (BitUtil.check(mask, 5)) {
+ buf.readUnsignedShortLE();
+ }
+ if (BitUtil.check(mask, 6)) {
+ buf.readUnsignedByte(); // maximum acceleration
+ buf.readUnsignedByte(); // maximum deceleration
+ buf.readUnsignedByte(); // maximum cornering
+ }
+ if (BitUtil.check(mask, 7)) {
+ buf.skipBytes(16);
+ }
+ if (BitUtil.check(mask, 8)) {
+ buf.skipBytes(40); // temperature sensors
+ }
+ if (BitUtil.check(mask, 9)) {
+ position.set("driver1", buf.readCharSequence(16, StandardCharsets.US_ASCII).toString().trim());
+ position.set("driver2", buf.readCharSequence(16, StandardCharsets.US_ASCII).toString().trim());
+ }
+ if (BitUtil.check(mask, 10)) {
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE());
+ }
}
@Override
@@ -230,6 +295,11 @@ public class BceProtocolDecoder extends BaseProtocolDecoder {
mask = masks.get(2);
decodeMask3(buf, mask, position);
}
+
+ if (masks.size() >= 4) {
+ mask = masks.get(3);
+ decodeMask4(buf, mask, position);
+ }
}
buf.readerIndex(structEnd);
diff --git a/src/main/java/org/traccar/protocol/BceProtocolEncoder.java b/src/main/java/org/traccar/protocol/BceProtocolEncoder.java
index 1bbf3db12..53ac51581 100644
--- a/src/main/java/org/traccar/protocol/BceProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/BceProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +20,14 @@ import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class BceProtocolEncoder extends BaseProtocolEncoder {
+ public BceProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java
index 31416d7f1..dad0ae774 100644
--- a/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/CalAmpProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -153,7 +153,7 @@ public class CalAmpProtocolDecoder extends BaseProtocolDecoder {
int content = buf.readUnsignedByte();
if (BitUtil.check(content, 0)) {
- String id = ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()));
+ String id = ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())).replace("f", "");
getDeviceSession(channel, remoteAddress, id);
}
diff --git a/src/main/java/org/traccar/protocol/CarcellProtocol.java b/src/main/java/org/traccar/protocol/CarcellProtocol.java
index 0c305efcb..f08ab3bd9 100644
--- a/src/main/java/org/traccar/protocol/CarcellProtocol.java
+++ b/src/main/java/org/traccar/protocol/CarcellProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ public class CarcellProtocol extends BaseProtocol {
pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '\r'));
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new CarcellProtocolEncoder());
+ pipeline.addLast(new CarcellProtocolEncoder(CarcellProtocol.this));
pipeline.addLast(new CarcellProtocolDecoder(CarcellProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java
index 344b2f1ea..ec640ba71 100644
--- a/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/CarcellProtocolDecoder.java
@@ -155,7 +155,7 @@ public class CarcellProtocolDecoder extends BaseProtocolDecoder {
Double mainVoltage = parser.nextDouble(0) / 100d;
position.set(Position.KEY_POWER, mainVoltage);
- position.set("iccid", parser.next());
+ position.set(Position.KEY_ICCID, parser.next());
}
return position;
diff --git a/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java b/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java
index e8f0081a0..083fe9a9e 100644
--- a/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class CarcellProtocolEncoder extends StringProtocolEncoder {
+ public CarcellProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/CastelProtocol.java b/src/main/java/org/traccar/protocol/CastelProtocol.java
index 9b854afc3..44c52d68f 100644
--- a/src/main/java/org/traccar/protocol/CastelProtocol.java
+++ b/src/main/java/org/traccar/protocol/CastelProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,14 +32,14 @@ public class CastelProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1024, 2, 2, -4, 0, true));
- pipeline.addLast(new CastelProtocolEncoder());
+ pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this));
pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this));
}
});
addServer(new TrackerServer(true, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new CastelProtocolEncoder());
+ pipeline.addLast(new CastelProtocolEncoder(CastelProtocol.this));
pipeline.addLast(new CastelProtocolDecoder(CastelProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java
index 0541adf6f..03e4b25fd 100644
--- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,6 +84,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder {
public static final short MSG_SC_HEARTBEAT_RESPONSE = (short) 0x9003;
public static final short MSG_SC_GPS = 0x4001;
public static final short MSG_SC_PID_DATA = 0x4002;
+ public static final short MSG_SC_G_SENSOR = 0x4003;
public static final short MSG_SC_SUPPORTED_PID = 0x4004;
public static final short MSG_SC_OBD_DATA = 0x4005;
public static final short MSG_SC_DTCS_PASSENGER = 0x4006;
@@ -290,152 +291,179 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder {
Channel channel, SocketAddress remoteAddress, ByteBuf buf,
int version, ByteBuf id, short type, DeviceSession deviceSession) {
- if (type == MSG_SC_HEARTBEAT) {
-
- sendResponse(channel, remoteAddress, version, id, MSG_SC_HEARTBEAT_RESPONSE, null);
-
- } else if (type == MSG_SC_LOGIN || type == MSG_SC_LOGOUT || type == MSG_SC_GPS
- || type == MSG_SC_ALARM || type == MSG_SC_CURRENT_LOCATION || type == MSG_SC_FUEL) {
-
- if (type == MSG_SC_LOGIN) {
- ByteBuf response = Unpooled.buffer(10);
- response.writeIntLE(0xFFFFFFFF);
- response.writeShortLE(0);
- response.writeIntLE((int) (System.currentTimeMillis() / 1000));
- sendResponse(channel, remoteAddress, version, id, MSG_SC_LOGIN_RESPONSE, response);
- }
-
- if (type == MSG_SC_GPS) {
- buf.readUnsignedByte(); // historical
- } else if (type == MSG_SC_ALARM) {
- buf.readUnsignedIntLE(); // alarm
- } else if (type == MSG_SC_CURRENT_LOCATION) {
- buf.readUnsignedShortLE();
- }
-
- buf.readUnsignedIntLE(); // ACC ON time
- buf.readUnsignedIntLE(); // UTC time
- long odometer = buf.readUnsignedIntLE();
- long tripOdometer = buf.readUnsignedIntLE();
- long fuelConsumption = buf.readUnsignedIntLE();
- buf.readUnsignedShortLE(); // current fuel consumption
- long status = buf.readUnsignedIntLE();
- buf.skipBytes(8);
-
- int count = buf.readUnsignedByte();
+ Position position;
+ int count;
+
+ switch (type) {
+
+ case MSG_SC_HEARTBEAT:
+ sendResponse(channel, remoteAddress, version, id, MSG_SC_HEARTBEAT_RESPONSE, null);
+ return null;
+
+ case MSG_SC_LOGIN:
+ case MSG_SC_LOGOUT:
+ case MSG_SC_GPS:
+ case MSG_SC_ALARM:
+ case MSG_SC_CURRENT_LOCATION:
+ case MSG_SC_FUEL:
+ if (type == MSG_SC_LOGIN) {
+ ByteBuf response = Unpooled.buffer(10);
+ response.writeIntLE(0xFFFFFFFF);
+ response.writeShortLE(0);
+ response.writeIntLE((int) (System.currentTimeMillis() / 1000));
+ sendResponse(channel, remoteAddress, version, id, MSG_SC_LOGIN_RESPONSE, response);
+ }
- List<Position> positions = new LinkedList<>();
+ if (type == MSG_SC_GPS) {
+ buf.readUnsignedByte(); // historical
+ } else if (type == MSG_SC_ALARM) {
+ buf.readUnsignedIntLE(); // alarm
+ } else if (type == MSG_SC_CURRENT_LOCATION) {
+ buf.readUnsignedShortLE();
+ }
- for (int i = 0; i < count; i++) {
- Position position = readPosition(deviceSession, buf);
- position.set(Position.KEY_ODOMETER, odometer);
- position.set(Position.KEY_ODOMETER_TRIP, tripOdometer);
- position.set(Position.KEY_FUEL_CONSUMPTION, fuelConsumption);
- position.set(Position.KEY_STATUS, status);
- positions.add(position);
- }
+ buf.readUnsignedIntLE(); // ACC ON time
+ buf.readUnsignedIntLE(); // UTC time
+ long odometer = buf.readUnsignedIntLE();
+ long tripOdometer = buf.readUnsignedIntLE();
+ long fuelConsumption = buf.readUnsignedIntLE();
+ buf.readUnsignedShortLE(); // current fuel consumption
+ long status = buf.readUnsignedIntLE();
+ buf.skipBytes(8);
+
+ count = buf.readUnsignedByte();
+
+ List<Position> positions = new LinkedList<>();
+
+ for (int i = 0; i < count; i++) {
+ position = readPosition(deviceSession, buf);
+ position.set(Position.KEY_ODOMETER, odometer);
+ position.set(Position.KEY_ODOMETER_TRIP, tripOdometer);
+ position.set(Position.KEY_FUEL_CONSUMPTION, fuelConsumption);
+ position.set(Position.KEY_STATUS, status);
+ positions.add(position);
+ }
- if (type == MSG_SC_ALARM) {
- int alarmCount = buf.readUnsignedByte();
- for (int i = 0; i < alarmCount; i++) {
- if (buf.readUnsignedByte() != 0) {
- int alarm = buf.readUnsignedByte();
- for (Position position : positions) {
- decodeAlarm(position, alarm);
+ if (type == MSG_SC_ALARM) {
+ int alarmCount = buf.readUnsignedByte();
+ for (int i = 0; i < alarmCount; i++) {
+ if (buf.readUnsignedByte() != 0) {
+ int alarm = buf.readUnsignedByte();
+ for (Position p : positions) {
+ decodeAlarm(p, alarm);
+ }
+ buf.readUnsignedShortLE(); // description
+ buf.readUnsignedShortLE(); // threshold
}
- buf.readUnsignedShortLE(); // description
- buf.readUnsignedShortLE(); // threshold
+ }
+ } else if (type == MSG_SC_FUEL) {
+ for (Position p : positions) {
+ p.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE());
}
}
- } else if (type == MSG_SC_FUEL) {
- for (Position position : positions) {
- position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE());
- }
- }
- if (!positions.isEmpty()) {
- return positions;
- }
+ return positions.isEmpty() ? null : positions;
- } else if (type == MSG_SC_GPS_SLEEP) {
+ case MSG_SC_GPS_SLEEP:
+ buf.readUnsignedIntLE(); // device time
+ return readPosition(deviceSession, buf);
- buf.readUnsignedIntLE(); // device time
+ case MSG_SC_AGPS_REQUEST:
+ return readPosition(deviceSession, buf);
- return readPosition(deviceSession, buf);
+ case MSG_SC_PID_DATA:
+ position = createPosition(deviceSession);
- } else if (type == MSG_SC_AGPS_REQUEST) {
+ decodeStat(position, buf);
- return readPosition(deviceSession, buf);
+ buf.readUnsignedShortLE(); // sample rate
+ decodeObd(position, buf, true);
- } else if (type == MSG_SC_PID_DATA) {
+ return position;
- Position position = createPosition(deviceSession);
+ case MSG_SC_G_SENSOR:
+ position = createPosition(deviceSession);
- decodeStat(position, buf);
+ decodeStat(position, buf);
- buf.readUnsignedShortLE(); // sample rate
- decodeObd(position, buf, true);
+ buf.readUnsignedShortLE(); // sample rate
- return position;
+ count = buf.readUnsignedByte();
- } else if (type == MSG_SC_DTCS_PASSENGER) {
+ StringBuilder data = new StringBuilder("[");
+ for (int i = 0; i < count; i++) {
+ if (i > 0) {
+ data.append(",");
+ }
+ data.append("[");
+ data.append(buf.readShortLE() * 0.015625);
+ data.append(",");
+ data.append(buf.readShortLE() * 0.015625);
+ data.append(",");
+ data.append(buf.readShortLE() * 0.015625);
+ data.append("]");
+ }
+ data.append("]");
- Position position = createPosition(deviceSession);
+ position.set(Position.KEY_G_SENSOR, data.toString());
- decodeStat(position, buf);
+ return position;
- buf.readUnsignedByte(); // flag
- position.add(ObdDecoder.decodeCodes(ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))));
+ case MSG_SC_DTCS_PASSENGER:
+ position = createPosition(deviceSession);
- return position;
+ decodeStat(position, buf);
- } else if (type == MSG_SC_OBD_DATA) {
+ buf.readUnsignedByte(); // flag
+ position.add(ObdDecoder.decodeCodes(ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))));
- Position position = createPosition(deviceSession);
+ return position;
- decodeStat(position, buf);
+ case MSG_SC_OBD_DATA:
+ position = createPosition(deviceSession);
- buf.readUnsignedByte(); // flag
- decodeObd(position, buf, false);
+ decodeStat(position, buf);
- return position;
+ buf.readUnsignedByte(); // flag
+ decodeObd(position, buf, false);
- } else if (type == MSG_SC_CELL) {
+ return position;
- Position position = createPosition(deviceSession);
+ case MSG_SC_CELL:
+ position = createPosition(deviceSession);
- decodeStat(position, buf);
+ decodeStat(position, buf);
- position.setNetwork(new Network(
- CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE())));
+ position.setNetwork(new Network(
+ CellTower.fromLacCid(buf.readUnsignedShortLE(), buf.readUnsignedShortLE())));
- return position;
+ return position;
- } else if (type == MSG_SC_QUERY_RESPONSE) {
+ case MSG_SC_QUERY_RESPONSE:
+ position = createPosition(deviceSession);
- Position position = createPosition(deviceSession);
+ buf.readUnsignedShortLE(); // index
+ buf.readUnsignedByte(); // response count
+ buf.readUnsignedByte(); // response index
- buf.readUnsignedShortLE(); // index
- buf.readUnsignedByte(); // response count
- buf.readUnsignedByte(); // response index
+ int failureCount = buf.readUnsignedByte();
+ for (int i = 0; i < failureCount; i++) {
+ buf.readUnsignedShortLE(); // tag
+ }
- int failureCount = buf.readUnsignedByte();
- for (int i = 0; i < failureCount; i++) {
- buf.readUnsignedShortLE(); // tag
- }
+ int successCount = buf.readUnsignedByte();
+ for (int i = 0; i < successCount; i++) {
+ buf.readUnsignedShortLE(); // tag
+ position.set(Position.KEY_RESULT,
+ buf.readSlice(buf.readUnsignedShortLE()).toString(StandardCharsets.US_ASCII));
+ }
- int successCount = buf.readUnsignedByte();
- for (int i = 0; i < successCount; i++) {
- buf.readUnsignedShortLE(); // tag
- position.set(Position.KEY_RESULT,
- buf.readSlice(buf.readUnsignedShortLE()).toString(StandardCharsets.US_ASCII));
- }
+ return position;
- return position;
+ default:
+ return null;
}
-
- return null;
}
private Object decodeCc(
diff --git a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java
index e1f78e7c1..dc694da28 100644
--- a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,11 +21,16 @@ import org.traccar.BaseProtocolEncoder;
import org.traccar.Context;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
public class CastelProtocolEncoder extends BaseProtocolEncoder {
+ public CastelProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeContent(long deviceId, short type, ByteBuf content) {
ByteBuf buf = Unpooled.buffer(0);
diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocol.java b/src/main/java/org/traccar/protocol/CellocatorProtocol.java
index a52170dc9..d910877cf 100644
--- a/src/main/java/org/traccar/protocol/CellocatorProtocol.java
+++ b/src/main/java/org/traccar/protocol/CellocatorProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,14 +29,14 @@ public class CellocatorProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new CellocatorFrameDecoder());
- pipeline.addLast(new CellocatorProtocolEncoder());
+ pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this));
pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this));
}
});
addServer(new TrackerServer(true, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new CellocatorProtocolEncoder());
+ pipeline.addLast(new CellocatorProtocolEncoder(CellocatorProtocol.this));
pipeline.addLast(new CellocatorProtocolDecoder(CellocatorProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java
index 14d14f4b6..aa13a0aa2 100644
--- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java
@@ -43,29 +43,52 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_SERVER_ACKNOWLEDGE = 4;
- private byte commandCount;
+ public static ByteBuf encodeContent(int type, int uniqueId, int packetNumber, ByteBuf content) {
+
+ ByteBuf buf = Unpooled.buffer();
+ buf.writeByte('M');
+ buf.writeByte('C');
+ buf.writeByte('G');
+ buf.writeByte('P');
+ buf.writeByte(type);
+ buf.writeIntLE(uniqueId);
+ buf.writeByte(packetNumber);
+ buf.writeIntLE(0); // authentication code
+ buf.writeBytes(content);
+
+ byte checksum = 0;
+ for (int i = 4; i < buf.writerIndex(); i++) {
+ checksum += buf.getByte(i);
+ }
+ buf.writeByte(checksum);
+
+ return buf;
+ }
private void sendResponse(Channel channel, SocketAddress remoteAddress, long deviceId, byte packetNumber) {
if (channel != null) {
- ByteBuf reply = Unpooled.buffer(28);
- reply.writeByte('M');
- reply.writeByte('C');
- reply.writeByte('G');
- reply.writeByte('P');
- reply.writeByte(MSG_SERVER_ACKNOWLEDGE);
- reply.writeIntLE((int) deviceId);
- reply.writeByte(commandCount++);
- reply.writeIntLE(0); // authentication code
- reply.writeByte(0);
- reply.writeByte(packetNumber);
- reply.writeZero(11);
-
- byte checksum = 0;
- for (int i = 4; i < 27; i++) {
- checksum += reply.getByte(i);
- }
- reply.writeByte(checksum);
+ ByteBuf content = Unpooled.buffer();
+ content.writeByte(0);
+ content.writeByte(packetNumber);
+ content.writeZero(11);
+ ByteBuf reply = encodeContent(MSG_SERVER_ACKNOWLEDGE, (int) deviceId, packetNumber, content);
+ channel.writeAndFlush(new NetworkMessage(reply, remoteAddress));
+ }
+ }
+
+ private void sendModuleResponse(Channel channel, SocketAddress remoteAddress, long deviceId, byte packetNumber) {
+ if (channel != null) {
+ ByteBuf content = Unpooled.buffer();
+ content.writeByte(0x80);
+ content.writeShortLE(10); // modules length
+ content.writeIntLE(0); // reserved
+ content.writeByte(9); // ack module type
+ content.writeShortLE(3); // module length
+ content.writeByte(0); // ack
+ content.writeShortLE(0); // reserved
+
+ ByteBuf reply = encodeContent(MSG_CLIENT_MODULAR_EXT, (int) deviceId, packetNumber, content);
channel.writeAndFlush(new NetworkMessage(reply, remoteAddress));
}
}
@@ -225,7 +248,11 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder {
}
byte packetNumber = buf.readByte();
- sendResponse(channel, remoteAddress, deviceUniqueId, packetNumber);
+ if (type == MSG_CLIENT_MODULAR_EXT) {
+ sendModuleResponse(channel, remoteAddress, deviceUniqueId, packetNumber);
+ } else {
+ sendResponse(channel, remoteAddress, deviceUniqueId, packetNumber);
+ }
if (type == MSG_CLIENT_STATUS) {
return decodeStatus(buf, deviceSession, alternative);
diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java
index 0382dbbc7..76fa67686 100644
--- a/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,27 +19,26 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class CellocatorProtocolEncoder extends BaseProtocolEncoder {
- private ByteBuf encodeContent(long deviceId, int command, int data1, int data2) {
+ public CellocatorProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ public static ByteBuf encodeContent(int type, int uniqueId, int packetNumber, ByteBuf content) {
- ByteBuf buf = Unpooled.buffer(0);
+ ByteBuf buf = Unpooled.buffer();
buf.writeByte('M');
buf.writeByte('C');
buf.writeByte('G');
buf.writeByte('P');
- buf.writeByte(0);
- buf.writeIntLE(Integer.parseInt(getUniqueId(deviceId)));
- buf.writeByte(0); // command numerator
+ buf.writeByte(type);
+ buf.writeIntLE(uniqueId);
+ buf.writeByte(packetNumber);
buf.writeIntLE(0); // authentication code
- buf.writeByte(command);
- buf.writeByte(command);
- buf.writeByte(data1);
- buf.writeByte(data1);
- buf.writeByte(data2);
- buf.writeByte(data2);
- buf.writeIntLE(0); // command specific data
+ buf.writeBytes(content);
byte checksum = 0;
for (int i = 4; i < buf.writerIndex(); i++) {
@@ -50,6 +49,23 @@ public class CellocatorProtocolEncoder extends BaseProtocolEncoder {
return buf;
}
+ private ByteBuf encodeCommand(long deviceId, int command, int data1, int data2) {
+
+ ByteBuf content = Unpooled.buffer();
+ content.writeByte(command);
+ content.writeByte(command);
+ content.writeByte(data1);
+ content.writeByte(data1);
+ content.writeByte(data2);
+ content.writeByte(data2);
+ content.writeIntLE(0); // command specific data
+
+ ByteBuf buf = encodeContent(0, Integer.parseInt(getUniqueId(deviceId)), 0, content);
+ content.release();
+
+ return buf;
+ }
+
@Override
protected Object encodeCommand(Command command) {
@@ -57,7 +73,7 @@ public class CellocatorProtocolEncoder extends BaseProtocolEncoder {
case Command.TYPE_OUTPUT_CONTROL:
int data = Integer.parseInt(command.getString(Command.KEY_DATA)) << 4
+ command.getInteger(Command.KEY_INDEX);
- return encodeContent(command.getDeviceId(), 0x03, data, 0);
+ return encodeCommand(command.getDeviceId(), 0x03, data, 0);
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocol.java b/src/main/java/org/traccar/protocol/CityeasyProtocol.java
index f4b49c9ff..8ab4ce93a 100644
--- a/src/main/java/org/traccar/protocol/CityeasyProtocol.java
+++ b/src/main/java/org/traccar/protocol/CityeasyProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ public class CityeasyProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0));
- pipeline.addLast(new CityeasyProtocolEncoder());
+ pipeline.addLast(new CityeasyProtocolEncoder(CityeasyProtocol.this));
pipeline.addLast(new CityeasyProtocolDecoder(CityeasyProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java b/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java
index 350fdf0ab..934105862 100644
--- a/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,9 +22,14 @@ import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class CityeasyProtocolEncoder extends BaseProtocolEncoder {
+ public CityeasyProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeContent(int type, ByteBuf content) {
ByteBuf buf = Unpooled.buffer();
diff --git a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java
index c49f06d65..58a5a88e3 100644
--- a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -208,6 +208,7 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder {
position.set("solarPower", buf.readUnsignedShortLE() * 0.001);
break;
default:
+ buf.readUnsignedShortLE(); // other
break;
}
}
diff --git a/src/main/java/org/traccar/protocol/EelinkProtocol.java b/src/main/java/org/traccar/protocol/EelinkProtocol.java
index de4ea971b..8a055d643 100644
--- a/src/main/java/org/traccar/protocol/EelinkProtocol.java
+++ b/src/main/java/org/traccar/protocol/EelinkProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,14 +34,14 @@ public class EelinkProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2));
- pipeline.addLast(new EelinkProtocolEncoder(false));
+ pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, false));
pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this));
}
});
addServer(new TrackerServer(true, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new EelinkProtocolEncoder(true));
+ pipeline.addLast(new EelinkProtocolEncoder(EelinkProtocol.this, true));
pipeline.addLast(new EelinkProtocolDecoder(EelinkProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java
index a6fd94b83..41d76f37f 100644
--- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java
@@ -412,7 +412,8 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder {
return decodeNew(deviceSession, buf, type, index);
- } else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2) {
+ } else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2
+ || type == MSG_OBD && buf.readableBytes() == 4) {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java
index 8f33441fb..3673c35b3 100644
--- a/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.DataConverter;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -28,7 +29,8 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder {
private boolean connectionless;
- public EelinkProtocolEncoder(boolean connectionless) {
+ public EelinkProtocolEncoder(Protocol protocol, boolean connectionless) {
+ super(protocol);
this.connectionless = connectionless;
}
diff --git a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java
index b9fcb2f44..9f0baf6b2 100644
--- a/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/EgtsProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,8 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
+ private boolean useObjectIdAsDeviceId = true;
+
public static final int PT_RESPONSE = 0;
public static final int PT_APPDATA = 1;
public static final int PT_SIGNED_APPDATA = 2;
@@ -68,7 +70,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder {
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;
+ public static final int MSG_PASSENGERS_COUNTERS = 28;
private int packetId;
@@ -121,11 +123,18 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder {
ByteBuf buf = (ByteBuf) msg;
+ List<Position> positions = new LinkedList<>();
+
+ short headerLength = buf.getUnsignedByte(buf.readerIndex() + 3);
int index = buf.getUnsignedShort(buf.readerIndex() + 5 + 2);
- buf.skipBytes(buf.getUnsignedByte(buf.readerIndex() + 3));
+ short packetType = buf.getUnsignedByte(buf.readerIndex() + 5 + 2 + 2);
+ buf.skipBytes(headerLength);
- List<Position> positions = new LinkedList<>();
+ if (packetType == PT_RESPONSE) {
+ return null;
+ }
+ long objectId = 0L;
while (buf.readableBytes() > 2) {
int length = buf.readUnsignedShortLE();
@@ -133,7 +142,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder {
int recordFlags = buf.readUnsignedByte();
if (BitUtil.check(recordFlags, 0)) {
- buf.readUnsignedIntLE(); // object id
+ objectId = buf.readUnsignedIntLE();
}
if (BitUtil.check(recordFlags, 1)) {
@@ -164,6 +173,7 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder {
int end = buf.readUnsignedShortLE() + buf.readerIndex();
if (type == MSG_TERM_IDENTITY) {
+ useObjectIdAsDeviceId = false;
buf.readUnsignedIntLE(); // object id
int flags = buf.readUnsignedByte();
@@ -254,8 +264,16 @@ public class EgtsProtocolDecoder extends BaseProtocolDecoder {
buf.readerIndex(end);
}
- if (serviceType == SERVICE_TELEDATA && deviceSession != null) {
- positions.add(position);
+ if (serviceType == SERVICE_TELEDATA && position.getValid()) {
+ if (useObjectIdAsDeviceId && objectId != 0L) {
+ deviceSession = getDeviceSession(channel, remoteAddress, true, String.valueOf(objectId));
+ if (deviceSession != null) {
+ position.setDeviceId(deviceSession.getDeviceId());
+ }
+ }
+ if (deviceSession != null) {
+ positions.add(position);
+ }
}
}
diff --git a/src/main/java/org/traccar/protocol/EnforaProtocol.java b/src/main/java/org/traccar/protocol/EnforaProtocol.java
index f78e4b377..e462ab322 100644
--- a/src/main/java/org/traccar/protocol/EnforaProtocol.java
+++ b/src/main/java/org/traccar/protocol/EnforaProtocol.java
@@ -32,14 +32,14 @@ public class EnforaProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, -2, 2));
- pipeline.addLast(new EnforaProtocolEncoder());
+ pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this));
pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this));
}
});
addServer(new TrackerServer(true, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new EnforaProtocolEncoder());
+ pipeline.addLast(new EnforaProtocolEncoder(EnforaProtocol.this));
pipeline.addLast(new EnforaProtocolDecoder(EnforaProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java b/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java
index a46e6367d..8cc24dc0f 100644
--- a/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
* Copyright 2017 Jose Castellanos
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,11 +20,16 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
public class EnforaProtocolEncoder extends StringProtocolEncoder {
+ public EnforaProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeContent(String content) {
ByteBuf buf = Unpooled.buffer();
diff --git a/src/main/java/org/traccar/protocol/EsealProtocol.java b/src/main/java/org/traccar/protocol/EsealProtocol.java
index 7a27c617d..fc1d342e1 100644
--- a/src/main/java/org/traccar/protocol/EsealProtocol.java
+++ b/src/main/java/org/traccar/protocol/EsealProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ public class EsealProtocol extends BaseProtocol {
pipeline.addLast(new LineBasedFrameDecoder(1024));
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new EsealProtocolEncoder());
+ pipeline.addLast(new EsealProtocolEncoder(EsealProtocol.this));
pipeline.addLast(new EsealProtocolDecoder(EsealProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java b/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java
index b9bcc5b0a..6ee305ed8 100644
--- a/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class EsealProtocolEncoder extends StringProtocolEncoder {
+ public EsealProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocol.java b/src/main/java/org/traccar/protocol/FifotrackProtocol.java
index d1c3cf695..4a0a12ed3 100644
--- a/src/main/java/org/traccar/protocol/FifotrackProtocol.java
+++ b/src/main/java/org/traccar/protocol/FifotrackProtocol.java
@@ -32,7 +32,7 @@ public class FifotrackProtocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new FifotrackFrameDecoder());
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new FifotrackProtocolEncoder());
+ pipeline.addLast(new FifotrackProtocolEncoder(FifotrackProtocol.this));
pipeline.addLast(new FifotrackProtocolDecoder(FifotrackProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java
index 2e728a918..40e146e0b 100644
--- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java
@@ -60,7 +60,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder {
.number("(-?d+),") // altitude
.number("(d+),") // odometer
.number("d+,") // runtime
- .number("(xxxx),") // status
+ .number("(x{4,8}),") // status
.number("(x+)?,") // input
.number("(x+)?,") // output
.number("(d+)|") // mcc
@@ -69,7 +69,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder {
.number("(x+),") // cid
.number("([x|]+)") // adc
.expression(",([^,]+)") // rfid
- .expression(",([^*]+)").optional(2) // sensors
+ .expression(",([^*]*)").optional(2) // sensors
.any()
.compile();
@@ -105,6 +105,24 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder {
}
}
+ private String decodeAlarm(Integer alarm) {
+ if (alarm != null) {
+ switch (alarm) {
+ case 2:
+ return Position.ALARM_SOS;
+ case 14:
+ return Position.ALARM_LOW_POWER;
+ case 15:
+ return Position.ALARM_POWER_CUT;
+ case 16:
+ return Position.ALARM_POWER_RESTORED;
+ default:
+ return null;
+ }
+ }
+ return null;
+ }
+
private Object decodeLocation(
Channel channel, SocketAddress remoteAddress, String sentence) {
@@ -121,35 +139,33 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.set(Position.KEY_ALARM, parser.next());
+ position.set(Position.KEY_ALARM, decodeAlarm(parser.nextInt()));
position.setTime(parser.nextDateTime());
position.setValid(parser.next().equals("A"));
- position.setLatitude(parser.nextDouble(0));
- position.setLongitude(parser.nextDouble(0));
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt(0)));
- position.setCourse(parser.nextInt(0));
- position.setAltitude(parser.nextInt(0));
-
- position.set(Position.KEY_ODOMETER, parser.nextLong(0));
- position.set(Position.KEY_STATUS, parser.nextHexInt(0));
- if (parser.hasNext()) {
- position.set(Position.KEY_INPUT, parser.nextHexInt(0));
- }
- if (parser.hasNext()) {
- position.set(Position.KEY_OUTPUT, parser.nextHexInt(0));
- }
+ position.setLatitude(parser.nextDouble());
+ position.setLongitude(parser.nextDouble());
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt()));
+ position.setCourse(parser.nextInt());
+ position.setAltitude(parser.nextInt());
+
+ position.set(Position.KEY_ODOMETER, parser.nextLong());
+ position.set(Position.KEY_STATUS, parser.nextHexLong());
+ position.set(Position.KEY_INPUT, parser.nextHexInt());
+ position.set(Position.KEY_OUTPUT, parser.nextHexInt());
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())));
String[] adc = parser.next().split("\\|");
for (int i = 0; i < adc.length; i++) {
position.set(Position.PREFIX_ADC + (i + 1), Integer.parseInt(adc[i], 16));
}
- position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
+ if (parser.hasNext()) {
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(parser.nextHexInt()));
+ }
if (parser.hasNext()) {
String[] sensors = parser.next().split("\\|");
diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java
index ff0a2e56e..a4e69b47b 100644
--- a/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java
@@ -18,9 +18,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class FifotrackProtocolEncoder extends StringProtocolEncoder {
+ public FifotrackProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private Object formatCommand(Command command, String content) {
String uniqueId = getUniqueId(command.getDeviceId());
int length = 1 + uniqueId.length() + 3 + content.length();
diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java
index 86da3943e..7405fb6ef 100644
--- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java
@@ -21,6 +21,7 @@ import io.netty.handler.codec.http.HttpResponseStatus;
import org.traccar.BaseHttpProtocolDecoder;
import org.traccar.DeviceSession;
import org.traccar.Protocol;
+import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
import javax.json.Json;
@@ -102,7 +103,7 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder {
position.setLongitude(((JsonNumber) value).doubleValue());
return true;
case "position.speed":
- position.setSpeed(((JsonNumber) value).doubleValue());
+ position.setSpeed(UnitsConverter.knotsFromKph(((JsonNumber) value).doubleValue()));
return true;
case "position.direction":
position.setCourse(((JsonNumber) value).doubleValue());
diff --git a/src/main/java/org/traccar/protocol/GalileoProtocol.java b/src/main/java/org/traccar/protocol/GalileoProtocol.java
index 9b7fe1a4b..a1570c9b0 100644
--- a/src/main/java/org/traccar/protocol/GalileoProtocol.java
+++ b/src/main/java/org/traccar/protocol/GalileoProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ public class GalileoProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new GalileoFrameDecoder());
- pipeline.addLast(new GalileoProtocolEncoder());
+ pipeline.addLast(new GalileoProtocolEncoder(GalileoProtocol.this));
pipeline.addLast(new GalileoProtocolDecoder(GalileoProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java
index 5b843324c..dfaedd695 100644
--- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java
@@ -318,7 +318,9 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte(); // part number
photo.writeBytes(buf, length - 1);
- } else {
+ sendResponse(channel, 0x07, buf.readUnsignedShortLE());
+
+ } else if (photo != null) {
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId();
@@ -334,8 +336,6 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder {
}
- sendResponse(channel, 0x07, buf.readUnsignedShortLE());
-
return position;
}
diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java
index 3b2145e74..cd068b251 100644
--- a/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,11 +20,16 @@ import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
public class GalileoProtocolEncoder extends BaseProtocolEncoder {
+ public GalileoProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeText(String uniqueId, String text) {
ByteBuf buf = Unpooled.buffer(256);
diff --git a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java
index 31500bae6..043839be9 100644
--- a/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/GatorProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -120,8 +120,10 @@ public class GatorProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_STATUS, buf.readUnsignedByte());
position.set("key", buf.readUnsignedByte());
- position.set("oil", buf.readUnsignedShort() / 10.0);
- position.set(Position.KEY_POWER, buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01);
+
+ position.set(Position.PREFIX_ADC + 1, buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01);
+ position.set(Position.PREFIX_ADC + 2, buf.readUnsignedByte() + buf.readUnsignedByte() * 0.01);
+
position.set(Position.KEY_ODOMETER, buf.readUnsignedInt());
return position;
diff --git a/src/main/java/org/traccar/protocol/Gl200Protocol.java b/src/main/java/org/traccar/protocol/Gl200Protocol.java
index c5343dae0..e2d0c6d2a 100644
--- a/src/main/java/org/traccar/protocol/Gl200Protocol.java
+++ b/src/main/java/org/traccar/protocol/Gl200Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ public class Gl200Protocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new Gl200FrameDecoder());
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new Gl200ProtocolEncoder());
+ pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this));
pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this));
}
});
@@ -44,7 +44,7 @@ public class Gl200Protocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new Gl200ProtocolEncoder());
+ pipeline.addLast(new Gl200ProtocolEncoder(Gl200Protocol.this));
pipeline.addLast(new Gl200ProtocolDecoder(Gl200Protocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java
index 285106c67..32307446b 100644
--- a/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class Gl200ProtocolEncoder extends StringProtocolEncoder {
+ public Gl200ProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java
index 5a0ff4197..283dbeb37 100644
--- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -119,9 +119,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
.compile();
private static final Pattern PATTERN_LOCATION = new PatternBuilder()
- .number("(d{1,2})?,") // hdop
+ .number("(d{1,2}.?d?)?,") // hdop
.number("(d{1,3}.d)?,") // speed
- .number("(d{1,3})?,") // course
+ .number("(d{1,3}.?d?)?,") // course
.number("(-?d{1,5}.d)?,") // altitude
.number("(-?d{1,3}.d{6})?,") // longitude
.number("(-?d{1,2}.d{6})?,") // latitude
@@ -184,7 +184,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
.number("(d+)?,") // power
.number("d{1,2},").optional() // report type
.number("d{1,2},").optional() // count
- .number(",").optional() // reserved
+ .number("d*,").optional() // reserved
.number("(d+),").optional() // battery
.expression("((?:")
.expression(PATTERN_LOCATION.pattern())
@@ -202,6 +202,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
.or()
.number("(d{1,7}.d)?,").optional() // odometer
.number("(d{1,3})?,") // battery
+ .or()
+ .number("(-?d),") // rssi
+ .number("(d{1,3}),") // battery
.groupEnd()
.any()
.number("(dddd)(dd)(dd)") // date (yyyymmdd)
@@ -514,7 +517,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
}
private void decodeLocation(Position position, Parser parser) {
- Integer hdop = parser.nextInt();
+ Double hdop = parser.nextDouble();
position.setValid(hdop == null || hdop > 0);
position.set(Position.KEY_HDOP, hdop);
@@ -848,6 +851,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
}
position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
+ position.set(Position.KEY_RSSI, parser.nextInt());
+ position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
decodeDeviceTime(position, parser);
if (ignoreFixTime) {
@@ -1224,8 +1229,11 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
case "CAN":
result = decodeCan(channel, remoteAddress, sentence);
break;
+ case "CTN":
case "FRI":
case "GEO":
+ case "RTL":
+ case "DOG":
case "STR":
result = decodeFri(channel, remoteAddress, sentence);
break;
diff --git a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java
index 95ef18f20..76278070e 100644
--- a/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/GoSafeProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,8 @@ import org.traccar.model.Network;
import org.traccar.model.Position;
import java.net.SocketAddress;
-import java.util.Date;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
@@ -45,8 +46,6 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
.text("*GS") // header
.number("d+,") // protocol version
.number("(d+),") // imei
- .number("(dd)(dd)(dd)") // time (hhmmss)
- .number("(dd)(dd)(dd),") // date (ddmmyy)
.expression("([^#]*)#?") // data
.compile();
@@ -68,6 +67,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
.compile();
private void decodeFragment(Position position, String fragment) {
+
int dataIndex = fragment.indexOf(':');
int index = 0;
String[] values;
@@ -76,6 +76,7 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
} else {
values = fragment.substring(dataIndex + 1).split(";");
}
+
switch (fragment.substring(0, dataIndex)) {
case "GPS":
position.setValid(values[index++].equals("A"));
@@ -162,8 +163,15 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
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]);
+ while (index < values.length) {
+ int sensorIndex = Integer.parseInt(values[index++]);
+ int dataType = Integer.parseInt(values[index++]);
+ if (dataType == 0) {
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, values[index++]);
+ } else if (dataType == 1) {
+ index += 1; // temperature sensor serial number
+ position.set(Position.PREFIX_TEMP + sensorIndex, Double.parseDouble(values[index++]));
+ }
}
break;
default:
@@ -171,42 +179,27 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
}
}
- private Object decodeData(DeviceSession deviceSession, Date time, String data) {
-
- List<Position> positions = new LinkedList<>();
- Position position = null;
- int index = 0;
- String[] fragments = data.split(",");
+ private Position decodePosition(DeviceSession deviceSession, String sentence) throws ParseException {
- while (index < fragments.length) {
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
- if (fragments[index].isEmpty() || Character.isDigit(fragments[index].charAt(0))) {
-
- if (position != null) {
- positions.add(position);
- }
+ int index = 0;
+ String[] fragments = sentence.split(",");
- position = new Position(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
- position.setTime(time);
+ position.setTime(new SimpleDateFormat("HHmmssddMMyy").parse(fragments[index++]));
- if (!fragments[index++].isEmpty()) {
- position.set(Position.KEY_EVENT, Integer.parseInt(fragments[index - 1]));
+ for (; index < fragments.length; index += 1) {
+ if (!fragments[index].isEmpty()) {
+ if (fragments[index].matches("\\p{XDigit}+")) {
+ position.set(Position.KEY_EVENT, Integer.parseInt(fragments[index], 16));
+ } else {
+ decodeFragment(position, fragments[index]);
}
-
- } else {
-
- decodeFragment(position, fragments[index++]);
-
}
-
}
- if (position != null) {
- positions.add(position);
- }
-
- return positions;
+ return position;
}
@Override
@@ -256,12 +249,11 @@ public class GoSafeProtocolDecoder extends BaseProtocolDecoder {
} else {
- Date time = new Date();
- if (parser.hasNext(6)) {
- time = parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY);
+ List<Position> positions = new LinkedList<>();
+ for (String item : parser.next().split("\\$")) {
+ positions.add(decodePosition(deviceSession, item));
}
-
- return decodeData(deviceSession, time, parser.next());
+ return positions;
}
}
diff --git a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java
index 2ef975fe5..a867451aa 100644
--- a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@ public class GotopProtocolDecoder extends BaseProtocolDecoder {
.number("DATE:(dd)(dd)(dd),") // date (yyddmm)
.number("TIME:(dd)(dd)(dd),") // time (hhmmss)
.number("LAT:(d+.d+)([NS]),") // latitude
- .number("LOT:(d+.d+)([EW]),") // longitude
+ .number("LO[NT]:(d+.d+)([EW]),") // longitude
.text("Speed:").number("(d+.d+),") // speed
.expression("([^,]+),") // status
.number("(d+)?") // course
diff --git a/src/main/java/org/traccar/protocol/Gps103Protocol.java b/src/main/java/org/traccar/protocol/Gps103Protocol.java
index 6272a3fd1..5356387ce 100644
--- a/src/main/java/org/traccar/protocol/Gps103Protocol.java
+++ b/src/main/java/org/traccar/protocol/Gps103Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ public class Gps103Protocol extends BaseProtocol {
pipeline.addLast(new CharacterDelimiterFrameDecoder(2048, false, "\r\n", "\n", ";", "*"));
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new Gps103ProtocolEncoder());
+ pipeline.addLast(new Gps103ProtocolEncoder(Gps103Protocol.this));
pipeline.addLast(new Gps103ProtocolDecoder(Gps103Protocol.this));
}
});
@@ -51,7 +51,7 @@ public class Gps103Protocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new Gps103ProtocolEncoder());
+ pipeline.addLast(new Gps103ProtocolEncoder(Gps103Protocol.this));
pipeline.addLast(new Gps103ProtocolDecoder(Gps103Protocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java
index 47ef2f333..7128823ed 100644
--- a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class Gps103ProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter {
+ public Gps103ProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
public String formatValue(String key, Object value) {
diff --git a/src/main/java/org/traccar/protocol/GranitProtocol.java b/src/main/java/org/traccar/protocol/GranitProtocol.java
index 6785f2a2e..244c3977b 100644
--- a/src/main/java/org/traccar/protocol/GranitProtocol.java
+++ b/src/main/java/org/traccar/protocol/GranitProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
* Copyright 2017 - 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,7 +28,7 @@ public class GranitProtocol extends BaseProtocol {
Command.TYPE_IDENTIFICATION,
Command.TYPE_REBOOT_DEVICE,
Command.TYPE_POSITION_SINGLE);
- setTextCommandEncoder(new GranitProtocolSmsEncoder());
+ setTextCommandEncoder(new GranitProtocolSmsEncoder(this));
setSupportedTextCommands(
Command.TYPE_REBOOT_DEVICE,
Command.TYPE_POSITION_PERIODIC);
@@ -36,7 +36,7 @@ public class GranitProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new GranitFrameDecoder());
- pipeline.addLast(new GranitProtocolEncoder());
+ pipeline.addLast(new GranitProtocolEncoder(GranitProtocol.this));
pipeline.addLast(new GranitProtocolDecoder(GranitProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java b/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java
index 6345ff971..66c2a4973 100644
--- a/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,9 +21,14 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class GranitProtocolEncoder extends BaseProtocolEncoder {
+ public GranitProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeCommand(String commandString) {
ByteBuf buffer = Unpooled.buffer();
buffer.writeBytes(commandString.getBytes(StandardCharsets.US_ASCII));
diff --git a/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java b/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java
index 7d5518c17..7dd4b2d77 100644
--- a/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java
+++ b/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
* Copyright 2017 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,9 +18,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class GranitProtocolSmsEncoder extends StringProtocolEncoder {
+ public GranitProtocolSmsEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected String encodeCommand(Command command) {
switch (command.getType()) {
diff --git a/src/main/java/org/traccar/protocol/Gt06Protocol.java b/src/main/java/org/traccar/protocol/Gt06Protocol.java
index 6e5435cd4..9ec8de098 100644
--- a/src/main/java/org/traccar/protocol/Gt06Protocol.java
+++ b/src/main/java/org/traccar/protocol/Gt06Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ public class Gt06Protocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new Gt06FrameDecoder());
- pipeline.addLast(new Gt06ProtocolEncoder());
+ pipeline.addLast(new Gt06ProtocolEncoder(Gt06Protocol.this));
pipeline.addLast(new Gt06ProtocolDecoder(Gt06Protocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java
index 4665290c3..e1ff0b6b6 100644
--- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java
@@ -81,11 +81,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_X1_PHOTO_INFO = 0x35;
public static final int MSG_X1_PHOTO_DATA = 0x36;
public static final int MSG_WIFI_2 = 0x69;
+ public static final int MSG_GPS_MODULAR = 0x70;
public static final int MSG_COMMAND_0 = 0x80;
public static final int MSG_COMMAND_1 = 0x81;
public static final int MSG_COMMAND_2 = 0x82;
public static final int MSG_TIME_REQUEST = 0x8A;
public static final int MSG_INFO = 0x94;
+ public static final int MSG_RFID = 0x9B;
public static final int MSG_STRING_INFO = 0x21;
public static final int MSG_GPS_2 = 0xA0;
public static final int MSG_LBS_2 = 0xA1;
@@ -101,6 +103,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_MULTIMEDIA = 0x21;
public static final int MSG_BMS_2 = 0x40;
public static final int MSG_MULTIMEDIA_2 = 0x41;
+ public static final int MSG_ALARM = 0x95;
private static boolean isSupported(int type) {
return hasGps(type) || hasLbs(type) || hasStatus(type);
@@ -748,6 +751,39 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0);
}
+ } else if (type == MSG_ALARM) {
+
+ DateBuilder dateBuilder = new DateBuilder(deviceSession.getTimeZone())
+ .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
+ .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte());
+
+ getLastLocation(position, dateBuilder.getDate());
+
+ short alarmType = buf.readUnsignedByte();
+
+ switch (alarmType) {
+ case 0x80:
+ position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION);
+ break;
+ case 0x87:
+ position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED);
+ break;
+ case 0x90:
+ position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION);
+ break;
+ case 0x91:
+ position.set(Position.KEY_ALARM, Position.ALARM_BRAKING);
+ break;
+ case 0x92:
+ position.set(Position.KEY_ALARM, Position.ALARM_CORNERING);
+ break;
+ default:
+ position.set(Position.KEY_ALARM, Position.ALARM_GENERAL);
+ break;
+ }
+
+ position.set("alarmValue", buf.readShort());
+
} else {
if (dataLength > 0) {
@@ -814,7 +850,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
getLastLocation(position, null);
if (subType == 0x00) {
- position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01);
+ position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.01);
return position;
} else if (subType == 0x05) {
int flags = buf.readUnsignedByte();
@@ -824,7 +860,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
} else if (subType == 0x0a) {
buf.skipBytes(8); // imei
buf.skipBytes(8); // imsi
- position.set("iccid", ByteBufUtil.hexDump(buf.readSlice(8)));
+ position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(8)));
return position;
} else if (subType == 0x0d) {
if (buf.getByte(buf.readerIndex()) != '!') {
@@ -942,6 +978,22 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
return position;
+ } else if (type == MSG_RFID) {
+
+ getLastLocation(position, null);
+
+ buf.readUnsignedByte(); // external device type code
+ buf.readUnsignedByte(); // card type
+ position.set(
+ Position.KEY_DRIVER_UNIQUE_ID,
+ buf.readCharSequence(buf.readableBytes() - 9, StandardCharsets.US_ASCII).toString());
+
+ return position;
+
+ } else if (type == MSG_GPS_MODULAR) {
+
+ return decodeExtendedModular(channel, buf, deviceSession, type);
+
} else {
return decodeExtendedOther(channel, buf, deviceSession, type);
@@ -951,6 +1003,84 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder {
return null;
}
+ private Object decodeExtendedModular(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) {
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ while (buf.readableBytes() > 6) {
+ int moduleType = buf.readUnsignedShort();
+ int moduleLength = buf.readUnsignedShort();
+ switch (moduleType) {
+ case 0x18:
+ position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01);
+ break;
+ case 0x28:
+ position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1);
+ break;
+ case 0x29:
+ position.set(Position.KEY_INDEX, buf.readUnsignedInt());
+ break;
+ case 0x2a:
+ int input = buf.readUnsignedByte();
+ position.set(Position.KEY_DOOR, BitUtil.to(input, 4) > 0);
+ position.set("tamper", BitUtil.from(input, 4) > 0);
+ break;
+ case 0x2b:
+ int event = buf.readUnsignedByte();
+ switch (event) {
+ case 0x11:
+ position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY);
+ break;
+ case 0x12:
+ position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER);
+ break;
+ case 0x13:
+ position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT);
+ break;
+ case 0x14:
+ position.set(Position.KEY_ALARM, Position.ALARM_REMOVING);
+ break;
+ default:
+ break;
+ }
+ position.set(Position.KEY_EVENT, event);
+ break;
+ case 0x2e:
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE());
+ break;
+ case 0x33:
+ position.setTime(new Date(buf.readUnsignedInt() * 1000));
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+ position.setAltitude(buf.readShort());
+
+ double latitude = buf.readUnsignedInt() / 60.0 / 30000.0;
+ double longitude = buf.readUnsignedInt() / 60.0 / 30000.0;
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
+
+ int flags = buf.readUnsignedShort();
+ position.setCourse(BitUtil.to(flags, 10));
+ position.setValid(BitUtil.check(flags, 12));
+
+ if (!BitUtil.check(flags, 10)) {
+ latitude = -latitude;
+ }
+ if (BitUtil.check(flags, 11)) {
+ longitude = -longitude;
+ }
+
+ position.setLatitude(latitude);
+ position.setLongitude(longitude);
+ break;
+ default:
+ buf.skipBytes(moduleLength);
+ break;
+ }
+ }
+
+ return position;
+ }
+
private Object decodeExtendedOther(Channel channel, ByteBuf buf, DeviceSession deviceSession, int type) {
Position position = null;
diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java
index 05560229f..9115ba10f 100644
--- a/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Gt06ProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,14 +21,20 @@ import org.traccar.BaseProtocolEncoder;
import org.traccar.Context;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
public class Gt06ProtocolEncoder extends BaseProtocolEncoder {
+ public Gt06ProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeContent(long deviceId, String content) {
- boolean language = Context.getIdentityManager().lookupAttributeBoolean(deviceId, "gt06.language", false, true);
+ boolean language = Context.getIdentityManager()
+ .lookupAttributeBoolean(deviceId, getProtocolName() + ".language", false, false, true);
ByteBuf buf = Unpooled.buffer();
@@ -61,13 +67,18 @@ public class Gt06ProtocolEncoder extends BaseProtocolEncoder {
protected Object encodeCommand(Command command) {
boolean alternative = Context.getIdentityManager().lookupAttributeBoolean(
- command.getDeviceId(), "gt06.alternative", false, true);
+ command.getDeviceId(), getProtocolName() + ".alternative", false, false, true);
+
+ String password = Context.getIdentityManager()
+ .getDevicePassword(command.getDeviceId(), getProtocolName(), "123456");
switch (command.getType()) {
case Command.TYPE_ENGINE_STOP:
- return encodeContent(command.getDeviceId(), alternative ? "DYD,123456#" : "Relay,1#");
+ return encodeContent(command.getDeviceId(),
+ alternative ? "DYD," + password + "#" : "Relay,1#");
case Command.TYPE_ENGINE_RESUME:
- return encodeContent(command.getDeviceId(), alternative ? "HFYD,123456#" : "Relay,0#");
+ return encodeContent(command.getDeviceId(),
+ alternative ? "HFYD," + password + "#" : "Relay,0#");
case Command.TYPE_CUSTOM:
return encodeContent(command.getDeviceId(), command.getString(Command.KEY_DATA));
default:
diff --git a/src/main/java/org/traccar/protocol/H02Protocol.java b/src/main/java/org/traccar/protocol/H02Protocol.java
index 251beac5e..b897d83ad 100644
--- a/src/main/java/org/traccar/protocol/H02Protocol.java
+++ b/src/main/java/org/traccar/protocol/H02Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@ public class H02Protocol extends BaseProtocol {
int messageLength = Context.getConfig().getInteger(getName() + ".messageLength");
pipeline.addLast(new H02FrameDecoder(messageLength));
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new H02ProtocolEncoder());
+ pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this));
pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this));
}
});
@@ -46,7 +46,7 @@ public class H02Protocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new H02ProtocolEncoder());
+ pipeline.addLast(new H02ProtocolEncoder(H02Protocol.this));
pipeline.addLast(new H02ProtocolDecoder(H02Protocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java
index 22bbe4441..137689a67 100644
--- a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java
@@ -554,9 +554,18 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder {
String sentence = buf.toString(StandardCharsets.US_ASCII).trim();
int typeStart = sentence.indexOf(',', sentence.indexOf(',') + 1) + 1;
int typeEnd = sentence.indexOf(',', typeStart);
+ if (typeEnd < 0) {
+ typeEnd = sentence.indexOf('#', typeStart);
+ }
if (typeEnd > 0) {
String type = sentence.substring(typeStart, typeEnd);
switch (type) {
+ case "V0":
+ case "HTBT":
+ if (channel != null) {
+ channel.writeAndFlush(new NetworkMessage(sentence, remoteAddress));
+ }
+ return null;
case "NBR":
return decodeLbs(sentence, channel, remoteAddress);
case "LINK":
diff --git a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java
index 614a07dd1..7a765332c 100644
--- a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java
@@ -1,6 +1,6 @@
/*
* Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com)
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.traccar.protocol;
import org.traccar.Context;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.util.Date;
@@ -26,6 +27,10 @@ public class H02ProtocolEncoder extends StringProtocolEncoder {
private static final String MARKER = "HQ";
+ public H02ProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private Object formatCommand(Date time, String uniqueId, String type, String... params) {
StringBuilder result = new StringBuilder(
@@ -55,7 +60,7 @@ public class H02ProtocolEncoder extends StringProtocolEncoder {
case Command.TYPE_POSITION_PERIODIC:
String frequency = command.getAttributes().get(Command.KEY_FREQUENCY).toString();
if (Context.getIdentityManager().lookupAttributeBoolean(
- command.getDeviceId(), "h02.alternative", false, true)) {
+ command.getDeviceId(), getProtocolName() + ".alternative", false, false, true)) {
return formatCommand(time, uniqueId, "D1", frequency);
} else {
return formatCommand(time, uniqueId, "S71", "22", frequency);
diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
index 8a937a194..9449e2d5c 100644
--- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java
@@ -83,7 +83,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
int subtype = buf.readUnsignedShort();
int length = buf.readUnsignedShort() - 4;
if (subtype == 0x0003) {
- String imei = buf.readSlice(length).toString(StandardCharsets.US_ASCII);
+ String imei = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString();
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
if (deviceSession != null && channel != null) {
ByteBuf content = Unpooled.buffer();
@@ -117,7 +117,7 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_IGNITION, BitUtil.check(status, 14));
position.set(Position.KEY_EVENT, buf.readUnsignedShort());
- String time = buf.readSlice(12).toString(StandardCharsets.US_ASCII);
+ String time = buf.readCharSequence(12, StandardCharsets.US_ASCII).toString();
DateBuilder dateBuilder = new DateBuilder()
.setYear(Integer.parseInt(time.substring(0, 2)))
@@ -138,9 +138,33 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_ODOMETER, buf.readUnsignedShort() * 1000);
while (buf.readableBytes() > 4) {
- buf.readUnsignedShort(); // subtype
+ int subtype = buf.readUnsignedShort();
int length = buf.readUnsignedShort() - 4;
- buf.skipBytes(length);
+ switch (subtype) {
+ case 0x0001:
+ position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40);
+ position.set(Position.KEY_RPM, buf.readUnsignedShort());
+ position.set("averageSpeed", buf.readUnsignedByte());
+ buf.readUnsignedShort(); // interval fuel consumption
+ position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01);
+ position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort());
+ position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01);
+ position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4);
+ buf.readUnsignedInt(); // trip id
+ break;
+ case 0x0005:
+ position.set(Position.KEY_RSSI, buf.readUnsignedByte());
+ position.set(Position.KEY_HDOP, buf.readUnsignedByte());
+ buf.readUnsignedInt(); // run time
+ break;
+ case 0x0009:
+ position.set(
+ Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString());
+ break;
+ default:
+ buf.skipBytes(length);
+ break;
+ }
}
sendResponse(channel, MSG_POSITION_RSP, index, null);
diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocol.java b/src/main/java/org/traccar/protocol/HuabaoProtocol.java
index 44c9f7ac7..791672b85 100644
--- a/src/main/java/org/traccar/protocol/HuabaoProtocol.java
+++ b/src/main/java/org/traccar/protocol/HuabaoProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ public class HuabaoProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new HuabaoFrameDecoder());
- pipeline.addLast(new HuabaoProtocolEncoder());
+ pipeline.addLast(new HuabaoProtocolEncoder(HuabaoProtocol.this));
pipeline.addLast(new HuabaoProtocolDecoder(HuabaoProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java
index 6e2e1377b..fceefa73a 100644
--- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java
@@ -58,7 +58,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder {
buf.writeShort(type);
buf.writeShort(data.readableBytes());
buf.writeBytes(id);
- buf.writeShort(1); // index
+ buf.writeShort(0); // index
buf.writeBytes(data);
data.release();
buf.writeByte(Checksum.xor(buf.nioBuffer(1, buf.readableBytes() - 1)));
@@ -131,7 +131,7 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder {
ByteBuf response = Unpooled.buffer();
response.writeShort(index);
response.writeByte(RESULT_SUCCESS);
- response.writeBytes("authentication".getBytes(StandardCharsets.US_ASCII));
+ response.writeBytes(ByteBufUtil.hexDump(id).getBytes(StandardCharsets.US_ASCII));
channel.writeAndFlush(new NetworkMessage(
formatMessage(MSG_TERMINAL_REGISTER_RESPONSE, id, response), remoteAddress));
}
@@ -197,20 +197,44 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder {
while (buf.readableBytes() > 2) {
int subtype = buf.readUnsignedByte();
int length = buf.readUnsignedByte();
+ int endIndex = buf.readerIndex() + length;
switch (subtype) {
case 0x01:
position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100);
break;
+ case 0x02:
+ position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1);
+ break;
case 0x30:
position.set(Position.KEY_RSSI, buf.readUnsignedByte());
break;
case 0x31:
position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
break;
+ case 0x91:
+ position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.1);
+ position.set(Position.KEY_RPM, buf.readUnsignedShort());
+ position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte());
+ position.set(Position.KEY_THROTTLE, buf.readUnsignedByte() * 100 / 255);
+ position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte() * 100 / 255);
+ position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40);
+ buf.readUnsignedShort();
+ position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01);
+ buf.readUnsignedShort();
+ buf.readUnsignedInt();
+ buf.readUnsignedShort();
+ position.set(Position.KEY_FUEL_USED, buf.readUnsignedShort() * 0.01);
+ break;
+ case 0x94:
+ if (length > 0) {
+ position.set(
+ Position.KEY_VIN, buf.readCharSequence(length, StandardCharsets.US_ASCII).toString());
+ }
+ break;
default:
- buf.skipBytes(length);
break;
}
+ buf.readerIndex(endIndex);
}
return position;
@@ -233,3 +257,4 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder {
}
}
+
diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java
index 7759790c4..40d07230d 100644
--- a/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/HuabaoProtocolEncoder.java
@@ -21,17 +21,22 @@ import org.traccar.BaseProtocolEncoder;
import org.traccar.Context;
import org.traccar.helper.DataConverter;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.text.SimpleDateFormat;
import java.util.Date;
public class HuabaoProtocolEncoder extends BaseProtocolEncoder {
+ public HuabaoProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
boolean alternative = Context.getIdentityManager().lookupAttributeBoolean(
- command.getDeviceId(), "huabao.alternative", false, true);
+ command.getDeviceId(), getProtocolName() + ".alternative", false, false, true);
ByteBuf id = Unpooled.wrappedBuffer(
DataConverter.parseHex(getUniqueId(command.getDeviceId())));
diff --git a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java
index 8c1b9b480..d76d9c92e 100644
--- a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java
@@ -44,7 +44,7 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder {
.expression("[^,]+,") // vendor
.expression("[^,]+,") // firmware version
.expression("(..),") // status
- .number("(d+),") // event
+ .number("(d+),").optional() // event
.expression("([LH]),") // history
.or()
.expression("([^,]+),") // type
@@ -56,7 +56,7 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder {
.expression("[^,]*,") // vehicle registration
.number("([01]),").optional() // valid
.groupEnd()
- .number("(dd),?(dd),?(dddd),") // date (ddmmyyyy)
+ .number("(dd),?(dd),?(d{2,4}),") // date (ddmmyyyy)
.number("(dd),?(dd),?(dd),") // time (hhmmss)
.expression("([01AV]),").optional() // valid
.number("(d+.d+),([NS]),") // latitude
@@ -69,16 +69,15 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder {
.number("(d+.?d*),") // altitude
.number("d+.?d*,") // pdop
.number("d+.?d*,") // hdop
- .expression("[^,]*,")
+ .expression("[^,]*,") // operator
.number("([01]),") // ignition
.number("([01]),") // charging
.number("(d+.?d*),") // power
.number("(d+.?d*),") // battery
.number("([01]),") // emergency
.expression("[CO]?,") // tamper
- .number("((?:x+,){5}") // main cell
- .number("(?:-?x+,){12})") // other cells
- .number("([01]{4}),") // inputs
+ .expression("(.*),") // cells
+ .number("([012]{4}),") // inputs
.number("([01]{2}),") // outputs
.groupBegin()
.number("d+,") // index
@@ -202,16 +201,22 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder {
int lac = Integer.parseInt(cells[3], 16);
int cid = Integer.parseInt(cells[4], 16);
Network network = new Network(CellTower.from(mcc, mnc, lac, cid, Integer.parseInt(cells[0])));
- for (int i = 0; i < 4; i++) {
- lac = Integer.parseInt(cells[5 + 3 * i + 1], 16);
- cid = Integer.parseInt(cells[5 + 3 * i + 2], 16);
- if (lac > 0 && cid > 0) {
- network.addCellTower(CellTower.from(mcc, mnc, lac, cid));
+ if (!cells[5].startsWith("(")) {
+ for (int i = 0; i < 4; i++) {
+ lac = Integer.parseInt(cells[5 + 3 * i + 1], 16);
+ cid = Integer.parseInt(cells[5 + 3 * i + 2], 16);
+ if (lac > 0 && cid > 0) {
+ network.addCellTower(CellTower.from(mcc, mnc, lac, cid));
+ }
}
}
position.setNetwork(network);
- position.set(Position.KEY_INPUT, parser.nextBinInt());
+ String input = parser.next();
+ if (input.charAt(input.length() - 1) == '2') {
+ input = input.substring(0, input.length() - 1) + '0';
+ }
+ position.set(Position.KEY_INPUT, Integer.parseInt(input, 2));
position.set(Position.KEY_OUTPUT, parser.nextBinInt());
}
diff --git a/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java b/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java
index ebbbd87cd..f82b8e3ac 100644
--- a/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java
@@ -17,9 +17,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class ItsProtocolEncoder extends StringProtocolEncoder {
+ public ItsProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java b/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java
index b5d060ecc..bfefb94a7 100644
--- a/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java
+++ b/src/main/java/org/traccar/protocol/Jt600FrameDecoder.java
@@ -35,7 +35,7 @@ public class Jt600FrameDecoder extends BaseFrameDecoder {
char type = (char) buf.getByte(buf.readerIndex());
if (type == '$') {
- boolean longFormat = buf.getUnsignedByte(buf.readerIndex() + 1) == 0x75;
+ boolean longFormat = Jt600ProtocolDecoder.isLongFormat(buf, buf.readerIndex() + 1);
int length = buf.getUnsignedShort(buf.readerIndex() + (longFormat ? 8 : 7)) + 10;
if (length <= buf.readableBytes()) {
return buf.readRetainedSlice(length);
diff --git a/src/main/java/org/traccar/protocol/Jt600Protocol.java b/src/main/java/org/traccar/protocol/Jt600Protocol.java
index 97c5fa6ce..37c82f741 100644
--- a/src/main/java/org/traccar/protocol/Jt600Protocol.java
+++ b/src/main/java/org/traccar/protocol/Jt600Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ public class Jt600Protocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new Jt600FrameDecoder());
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new Jt600ProtocolEncoder());
+ pipeline.addLast(new Jt600ProtocolEncoder(Jt600Protocol.this));
pipeline.addLast(new Jt600ProtocolDecoder(Jt600Protocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java
index 1351706e2..f456cd1ef 100644
--- a/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Jt600ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -86,13 +86,17 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder {
}
+ static boolean isLongFormat(ByteBuf buf, int flagIndex) {
+ return buf.getUnsignedByte(flagIndex) >> 4 == 0x7;
+ }
+
private List<Position> decodeBinary(ByteBuf buf, Channel channel, SocketAddress remoteAddress) {
List<Position> positions = new LinkedList<>();
buf.readByte(); // header
- boolean longFormat = buf.getUnsignedByte(buf.readerIndex()) == 0x75;
+ boolean longFormat = isLongFormat(buf, buf.readerIndex());
String id = String.valueOf(Long.parseLong(ByteBufUtil.hexDump(buf.readSlice(5))));
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id);
@@ -170,6 +174,7 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder {
if (protocolVersion == 0x17) {
buf.readUnsignedByte(); // geofence id
buf.skipBytes(3); // reserved
+ buf.skipBytes(buf.readableBytes() - 1);
}
} else if (version == 1) {
diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java
index fe5c63c32..199467a38 100644
--- a/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,14 @@ import java.util.TimeZone;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class Jt600ProtocolEncoder extends StringProtocolEncoder {
+ public Jt600ProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/KhdProtocol.java b/src/main/java/org/traccar/protocol/KhdProtocol.java
index cec7158ed..f77f4c311 100644
--- a/src/main/java/org/traccar/protocol/KhdProtocol.java
+++ b/src/main/java/org/traccar/protocol/KhdProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ public class KhdProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LengthFieldBasedFrameDecoder(512, 3, 2));
- pipeline.addLast(new KhdProtocolEncoder());
+ pipeline.addLast(new KhdProtocolEncoder(KhdProtocol.this));
pipeline.addLast(new KhdProtocolDecoder(KhdProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java
index c66129283..4a8df26c8 100644
--- a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,12 +20,17 @@ import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class KhdProtocolEncoder extends BaseProtocolEncoder {
public static final int MSG_CUT_OIL = 0x39;
public static final int MSG_RESUME_OIL = 0x38;
+ public KhdProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeCommand(int command, String uniqueId) {
ByteBuf buf = Unpooled.buffer();
diff --git a/src/main/java/org/traccar/protocol/LaipacProtocol.java b/src/main/java/org/traccar/protocol/LaipacProtocol.java
index 923b08a16..1d561dbd2 100644
--- a/src/main/java/org/traccar/protocol/LaipacProtocol.java
+++ b/src/main/java/org/traccar/protocol/LaipacProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
+import org.traccar.model.Command;
import org.traccar.BaseProtocol;
import org.traccar.PipelineBuilder;
import org.traccar.TrackerServer;
@@ -25,12 +26,19 @@ import org.traccar.TrackerServer;
public class LaipacProtocol extends BaseProtocol {
public LaipacProtocol() {
+
+ setSupportedDataCommands(
+ Command.TYPE_CUSTOM,
+ Command.TYPE_POSITION_SINGLE,
+ Command.TYPE_REBOOT_DEVICE);
+
addServer(new TrackerServer(false, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LineBasedFrameDecoder(1024));
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
+ pipeline.addLast(new LaipacProtocolEncoder(LaipacProtocol.this));
pipeline.addLast(new LaipacProtocolDecoder(LaipacProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java
index 2f3cbb1b9..0c72568f3 100644
--- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package org.traccar.protocol;
import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
+import org.traccar.Context;
import org.traccar.DeviceSession;
import org.traccar.NetworkMessage;
import org.traccar.Protocol;
@@ -37,29 +38,44 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
- private static final Pattern PATTERN = new PatternBuilder()
+ public static final String DEFAULT_DEVICE_PASSWORD = "00000000";
+
+ private static final Pattern PATTERN_EAVSYS = new PatternBuilder()
+ .text("$EAVSYS,")
+ .expression("([^,]+),") // identifier
+ .expression("([0-9]+),") // iccid
+ .expression("(\\+?[0-9]+)?,") // sim phone number
+ .expression("(?:[^,]*),") // owner name
+ .expression("([^,]*)?") // firmware version
+ .text("*")
+ .number("(xx)") // checksum
+ .compile();
+
+ private static final Pattern PATTERN_AVRMC = new PatternBuilder()
.text("$AVRMC,")
.expression("([^,]+),") // identifier
.number("(dd)(dd)(dd),") // time (hhmmss)
.expression("([AVRPavrp]),") // validity
.number("(dd)(dd.d+),") // latitude
- .expression("([NS]),")
+ .expression("([NS]),") // latitude hemisphere
.number("(ddd)(dd.d+),") // longitude
- .number("([EW]),")
+ .number("([EW]),") // longitude hemisphere
.number("(d+.d+),") // speed
.number("(d+.d+),") // course
.number("(dd)(dd)(dd),") // date (ddmmyy)
- .expression("([abZXTSMHFE86430]),") // event code
+ .expression("([0-9A-Za-z]),") // 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
+ .number(",(xxxx|x)") // lac | lac+cid = 0
+ .number("(xxxx),") // cid | nothing
+ .number("(ddd|d)") // mcc | mcc+mnc = 0
+ .number("(ddd)") // mnc | nothing
.optional(4)
+ .expression(",([^*]*)") // anything remaining (be forward compatible)
+ .optional(1)
.text("*")
.number("(xx)") // checksum
.compile();
@@ -68,6 +84,8 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
switch (event) {
case "Z":
return Position.ALARM_LOW_BATTERY;
+ case "Y":
+ return Position.ALARM_TOW;
case "X":
return Position.ALARM_GEOFENCE_ENTER;
case "T":
@@ -81,6 +99,8 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
return Position.ALARM_GEOFENCE_EXIT;
case "6":
return Position.ALARM_OVERSPEED;
+ case "5":
+ return Position.ALARM_POWER_CUT;
case "3":
return Position.ALARM_SOS;
default:
@@ -88,23 +108,77 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
}
}
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ private String decodeEvent(String event, Position position) {
- String sentence = (String) msg;
+ if (event.length() == 1) {
+ char inputStatus = event.charAt(0);
+ if (inputStatus >= 'A' && inputStatus <= 'D') {
+ int inputStatusInt = inputStatus - 'A';
+ position.set(Position.PREFIX_IN + 1, inputStatusInt & 1);
+ position.set(Position.PREFIX_IN + 2, inputStatusInt & 2);
+ return null;
+ }
+ }
- if (sentence.startsWith("$ECHK") && channel != null) {
- channel.writeAndFlush(new NetworkMessage(sentence + "\r\n", remoteAddress)); // heartbeat
- return null;
+ return event;
+ }
+
+ private void sendEventResponse(
+ String event, String devicePassword, Channel channel, SocketAddress remoteAddress) {
+
+ String responseCode = null;
+
+ switch (event) {
+ case "3":
+ responseCode = "d";
+ break;
+ case "S":
+ case "T":
+ responseCode = "t";
+ break;
+ case "X":
+ case "4":
+ responseCode = "x";
+ break;
+ case "Y":
+ responseCode = "y";
+ break;
+ case "Z":
+ responseCode = "z";
+ break;
+ default:
+ break;
+ }
+
+ if (responseCode != null) {
+ String response = "$AVCFG," + devicePassword + "," + responseCode;
+ response += Checksum.nmea(response) + "\r\n";
+ channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
+ }
+
+ }
+
+ private void sendAcknowledge(
+ String status, String event, String checksum, Channel channel, SocketAddress remoteAddress) {
+
+ if (Character.isLowerCase(status.charAt(0))) {
+ String response = "$EAVACK," + event + "," + checksum;
+ response += Checksum.nmea(response) + "\r\n";
+ channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
}
- Parser parser = new Parser(PATTERN, sentence);
+ }
+
+ protected Object decodeEavsys(
+ String sentence, Channel channel, SocketAddress remoteAddress) {
+
+ Parser parser = new Parser(PATTERN_EAVSYS, sentence);
if (!parser.matches()) {
return null;
}
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ DeviceSession deviceSession =
+ getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
return null;
}
@@ -112,6 +186,32 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
+ getLastLocation(position, null);
+
+ position.set(Position.KEY_ICCID, parser.next());
+ position.set(Position.KEY_PHONE, parser.next());
+ position.set(Position.KEY_VERSION_FW, parser.next());
+
+ return position;
+ }
+
+ protected Object decodeAvrmc(
+ String sentence, Channel channel, SocketAddress remoteAddress) {
+
+ Parser parser = new Parser(PATTERN_AVRMC, 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());
DateBuilder dateBuilder = new DateBuilder()
.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
@@ -130,9 +230,9 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
String event = parser.next();
position.set(Position.KEY_ALARM, decodeAlarm(event));
- position.set(Position.KEY_EVENT, event);
+ position.set(Position.KEY_EVENT, decodeEvent(event, position));
position.set(Position.KEY_BATTERY, Double.parseDouble(parser.next().replaceAll("\\.", "")) * 0.001);
- position.set(Position.KEY_ODOMETER, parser.nextDouble());
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
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);
@@ -145,23 +245,39 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid)));
}
+ parser.next(); // unused
+
String checksum = parser.next();
if (channel != null) {
- if (event.equals("3")) {
- channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,d*31\r\n", remoteAddress));
- } else if (event.equals("X") || event.equals("4")) {
- channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,x*2D\r\n", remoteAddress));
- } else if (event.equals("Z")) {
- channel.writeAndFlush(new NetworkMessage("$AVCFG,00000000,z*2F\r\n", remoteAddress));
- } else if (Character.isLowerCase(status.charAt(0))) {
- String response = "$EAVACK," + event + "," + checksum;
- response += Checksum.nmea(response) + "\r\n";
- channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
- }
+
+ sendAcknowledge(status, event, checksum, channel, remoteAddress);
+
+ String devicePassword = Context.getIdentityManager()
+ .getDevicePassword(deviceSession.getDeviceId(), getProtocolName(), DEFAULT_DEVICE_PASSWORD);
+ sendEventResponse(event, devicePassword, channel, remoteAddress);
}
return position;
}
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ String sentence = (String) msg;
+
+ if (sentence.startsWith("$ECHK")) {
+ if (channel != null) {
+ channel.writeAndFlush(new NetworkMessage(sentence + "\r\n", remoteAddress));
+ }
+ } else if (sentence.startsWith("$EAVSYS")) {
+ return decodeEavsys(sentence, channel, remoteAddress);
+ } else if (sentence.startsWith("$AVRMC")) {
+ return decodeAvrmc(sentence, channel, remoteAddress);
+ }
+
+ return null;
+ }
+
}
diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java
new file mode 100644
index 000000000..343ac9431
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import org.traccar.StringProtocolEncoder;
+import org.traccar.model.Command;
+import org.traccar.helper.Checksum;
+import org.traccar.Protocol;
+
+public class LaipacProtocolEncoder extends StringProtocolEncoder {
+
+ public LaipacProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ @Override
+ protected String formatCommand(Command command, String format, String... keys) {
+ String sentence = super.formatCommand(command, "$" + format, keys);
+ sentence += Checksum.nmea(sentence) + "\r\n";
+ return sentence;
+ }
+
+ @Override
+ protected Object encodeCommand(Command command) {
+
+ initDevicePassword(command, LaipacProtocolDecoder.DEFAULT_DEVICE_PASSWORD);
+
+ switch (command.getType()) {
+ case Command.TYPE_CUSTOM:
+ return formatCommand(command, "{%s}",
+ Command.KEY_DATA);
+ case Command.TYPE_POSITION_SINGLE:
+ return formatCommand(command, "AVREQ,{%s},1",
+ Command.KEY_DEVICE_PASSWORD);
+ case Command.TYPE_REBOOT_DEVICE:
+ return formatCommand(command, "AVRESET,{%s},{%s}",
+ Command.KEY_UNIQUE_ID, Command.KEY_DEVICE_PASSWORD);
+ default:
+ return null;
+ }
+
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocol.java b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java
new file mode 100644
index 000000000..05f63a2d7
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/LeafSpyProtocol.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 Jesse Hills (jesserockz@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.handler.codec.http.HttpObjectAggregator;
+import io.netty.handler.codec.http.HttpRequestDecoder;
+import io.netty.handler.codec.http.HttpResponseEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class LeafSpyProtocol extends BaseProtocol {
+
+ public LeafSpyProtocol() {
+ addServer(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new HttpResponseEncoder());
+ pipeline.addLast(new HttpRequestDecoder());
+ pipeline.addLast(new HttpObjectAggregator(16384));
+ pipeline.addLast(new LeafSpyProtocolDecoder(LeafSpyProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java
new file mode 100644
index 000000000..5b352a961
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 Jesse Hills (jesserockz@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.DefaultFullHttpResponse;
+import io.netty.handler.codec.http.HttpResponse;
+import io.netty.handler.codec.http.HttpResponseStatus;
+import io.netty.handler.codec.http.HttpVersion;
+import io.netty.handler.codec.http.QueryStringDecoder;
+import org.traccar.BaseHttpProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.Protocol;
+import org.traccar.model.Position;
+import org.traccar.NetworkMessage;
+
+import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+public class LeafSpyProtocolDecoder extends BaseHttpProtocolDecoder {
+
+ public LeafSpyProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ @Override
+ protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ FullHttpRequest request = (FullHttpRequest) msg;
+ QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
+ Map<String, List<String>> params = decoder.parameters();
+ if (params.isEmpty()) {
+ decoder = new QueryStringDecoder(request.content().toString(StandardCharsets.US_ASCII), false);
+ params = decoder.parameters();
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setValid(true);
+
+ for (Map.Entry<String, List<String>> entry : params.entrySet()) {
+ for (String value : entry.getValue()) {
+ switch (entry.getKey()) {
+ case "pass":
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value);
+ if (deviceSession == null) {
+ sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
+ return null;
+ }
+ position.setDeviceId(deviceSession.getDeviceId());
+ break;
+ case "Lat":
+ position.setLatitude(Double.parseDouble(value));
+ break;
+ case "Long":
+ position.setLongitude(Double.parseDouble(value));
+ break;
+ case "RPM":
+ position.set(Position.KEY_RPM, Integer.parseInt(value));
+ position.setSpeed(convertSpeed(Double.parseDouble(value) / 63, "kmh"));
+ break;
+ case "Elv":
+ position.setAltitude(Double.parseDouble(value));
+ break;
+ case "SOC":
+ position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value));
+ break;
+ case "user":
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, value);
+ break;
+ case "ChrgMode":
+ position.set(Position.KEY_CHARGE, Integer.parseInt(value) != 0);
+ break;
+ case "Odo":
+ position.set(Position.KEY_OBD_ODOMETER, Integer.parseInt(value) * 1000);
+ break;
+ default:
+ try {
+ position.set(entry.getKey(), Double.parseDouble(value));
+ } catch (NumberFormatException e) {
+ switch (value) {
+ case "true":
+ position.set(entry.getKey(), true);
+ break;
+ case "false":
+ position.set(entry.getKey(), false);
+ break;
+ default:
+ position.set(entry.getKey(), value);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (position.getFixTime() == null) {
+ position.setTime(new Date());
+ }
+
+ if (position.getLatitude() == 0 && position.getLongitude() == 0) {
+ getLastLocation(position, position.getDeviceTime());
+ }
+
+ if (position.getDeviceId() != 0) {
+ if (channel != null) {
+ HttpResponse response = new DefaultFullHttpResponse(
+ HttpVersion.HTTP_1_1,
+ HttpResponseStatus.OK,
+ Unpooled.copiedBuffer("\"status\":\"0\"", StandardCharsets.US_ASCII));
+ channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress()));
+ }
+ return position;
+ } else {
+ sendResponse(channel, HttpResponseStatus.BAD_REQUEST);
+ return null;
+ }
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java
index c307c7318..e8a66e49f 100644
--- a/src/main/java/org/traccar/protocol/MeiligaoProtocol.java
+++ b/src/main/java/org/traccar/protocol/MeiligaoProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,14 +36,14 @@ public class MeiligaoProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new MeiligaoFrameDecoder());
- pipeline.addLast(new MeiligaoProtocolEncoder());
+ pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this));
pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this));
}
});
addServer(new TrackerServer(true, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new MeiligaoProtocolEncoder());
+ pipeline.addLast(new MeiligaoProtocolEncoder(MeiligaoProtocol.this));
pipeline.addLast(new MeiligaoProtocolDecoder(MeiligaoProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java
index 57cbbe0fc..36e94195c 100644
--- a/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,12 +21,17 @@ import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.Checksum;
import org.traccar.helper.DataConverter;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
import java.util.TimeZone;
public class MeiligaoProtocolEncoder extends BaseProtocolEncoder {
+ public MeiligaoProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeContent(long deviceId, int type, ByteBuf content) {
ByteBuf buf = Unpooled.buffer();
diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocol.java b/src/main/java/org/traccar/protocol/MeitrackProtocol.java
index c887cd3a0..7439ea611 100644
--- a/src/main/java/org/traccar/protocol/MeitrackProtocol.java
+++ b/src/main/java/org/traccar/protocol/MeitrackProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ public class MeitrackProtocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new MeitrackFrameDecoder());
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new MeitrackProtocolEncoder());
+ pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this));
pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this));
}
});
@@ -45,7 +45,7 @@ public class MeitrackProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new MeitrackProtocolEncoder());
+ pipeline.addLast(new MeitrackProtocolEncoder(MeitrackProtocol.this));
pipeline.addLast(new MeitrackProtocolDecoder(MeitrackProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java
index abb6ec9d4..354e81434 100644
--- a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +19,16 @@ import org.traccar.Context;
import org.traccar.StringProtocolEncoder;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.util.Map;
public class MeitrackProtocolEncoder extends StringProtocolEncoder {
+ public MeitrackProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private Object formatCommand(Command command, char dataId, String content) {
String uniqueId = getUniqueId(command.getDeviceId());
int length = 1 + uniqueId.length() + 1 + content.length() + 5;
@@ -38,7 +43,7 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder {
Map<String, Object> attributes = command.getAttributes();
boolean alternative = Context.getIdentityManager().lookupAttributeBoolean(
- command.getDeviceId(), "meitrack.alternative", false, true);
+ command.getDeviceId(), getProtocolName() + ".alternative", false, false, true);
switch (command.getType()) {
case Command.TYPE_POSITION_SINGLE:
diff --git a/src/main/java/org/traccar/protocol/MictrackProtocol.java b/src/main/java/org/traccar/protocol/MictrackProtocol.java
new file mode 100644
index 000000000..c8d64fd81
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/MictrackProtocol.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.handler.codec.LineBasedFrameDecoder;
+import io.netty.handler.codec.string.StringDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class MictrackProtocol extends BaseProtocol {
+
+ public MictrackProtocol() {
+ addServer(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new LineBasedFrameDecoder(1024));
+ pipeline.addLast(new StringEncoder());
+ pipeline.addLast(new StringDecoder());
+ pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this));
+ }
+ });
+ addServer(new TrackerServer(true, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new StringEncoder());
+ pipeline.addLast(new StringDecoder());
+ pipeline.addLast(new MictrackProtocolDecoder(MictrackProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java
new file mode 100644
index 000000000..a2fccb707
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.Protocol;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.CellTower;
+import org.traccar.model.Network;
+import org.traccar.model.Position;
+import org.traccar.model.WifiAccessPoint;
+
+import java.net.SocketAddress;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class MictrackProtocolDecoder extends BaseProtocolDecoder {
+
+ public MictrackProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ private Date decodeTime(String data) throws ParseException {
+ DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss");
+ dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ return dateFormat.parse(data);
+ }
+
+ private String decodeAlarm(int event) {
+ switch (event) {
+ case 5:
+ return Position.ALARM_SOS;
+ case 8:
+ return Position.ALARM_LOW_BATTERY;
+ case 9:
+ return Position.ALARM_GEOFENCE_ENTER;
+ case 10:
+ return Position.ALARM_GEOFENCE_EXIT;
+ case 12:
+ return Position.ALARM_POWER_OFF;
+ default:
+ return null;
+ }
+ }
+
+ private void decodeLocation(Position position, String data) throws ParseException {
+ int index = 0;
+ String[] values = data.split("\\+");
+
+ position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++]));
+
+ position.setValid(true);
+ position.setTime(decodeTime(values[index++]));
+ position.setLatitude(Double.parseDouble(values[index++]));
+ position.setLongitude(Double.parseDouble(values[index++]));
+ position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++])));
+ position.setCourse(Integer.parseInt(values[index++]));
+
+ int event = Integer.parseInt(values[index++]);
+ position.set(Position.KEY_ALARM, decodeAlarm(event));
+ position.set(Position.KEY_EVENT, event);
+ position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.001);
+ }
+
+ private void decodeCell(Network network, String data) {
+ String[] values = data.split(",");
+ int length = values.length % 5 == 0 ? 5 : 4;
+ for (int i = 0; i < values.length / length; i++) {
+ int mnc = Integer.parseInt(values[i * length]);
+ int cid = Integer.parseInt(values[i * length + 1]);
+ int lac = Integer.parseInt(values[i * length + 2]);
+ int mcc = Integer.parseInt(values[i * length + 3]);
+ network.addCellTower(CellTower.from(mcc, mnc, lac, cid));
+ }
+ }
+
+ private void decodeWifi(Network network, String data) {
+ String[] values = data.split(",");
+ for (int i = 0; i < values.length / 2; i++) {
+ network.addWifiAccessPoint(WifiAccessPoint.from(values[i * 2], Integer.parseInt(values[i * 2 + 1])));
+ }
+ }
+
+ private void decodeNetwork(Position position, String data, boolean hasWifi, boolean hasCell) throws ParseException {
+ int index = 0;
+ String[] values = data.split("\\+");
+
+ getLastLocation(position, decodeTime(values[index++]));
+
+ Network network = new Network();
+
+ if (hasWifi) {
+ decodeWifi(network, values[index++]);
+ }
+
+ if (hasCell) {
+ decodeCell(network, values[index++]);
+ }
+
+ position.setNetwork(network);
+
+ int event = Integer.parseInt(values[index++]);
+ position.set(Position.KEY_ALARM, decodeAlarm(event));
+ position.set(Position.KEY_EVENT, event);
+ position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.001);
+ }
+
+ private void decodeStatus(Position position, String data) throws ParseException {
+ int index = 0;
+ String[] values = data.split("\\+");
+
+ position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++]));
+
+ getLastLocation(position, decodeTime(values[index++]));
+
+ index += 4; // fix values
+
+ int event = Integer.parseInt(values[index++]);
+ position.set(Position.KEY_ALARM, decodeAlarm(event));
+ position.set(Position.KEY_EVENT, event);
+ position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.001);
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ String[] fragments = ((String) msg).split(";");
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, fragments[2]);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ switch (fragments[3]) {
+ case "R0":
+ decodeLocation(position, fragments[4]);
+ break;
+ case "R1":
+ decodeNetwork(position, fragments[4], true, false);
+ break;
+ case "R2":
+ case "R3":
+ decodeNetwork(position, fragments[4], false, true);
+ break;
+ case "R12":
+ case "R13":
+ decodeNetwork(position, fragments[4], true, true);
+ break;
+ case "RH":
+ decodeStatus(position, fragments[4]);
+ break;
+ default:
+ return null;
+ }
+
+ return position;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java
index d4a154053..82534ecd8 100644
--- a/src/main/java/org/traccar/protocol/MiniFinderProtocol.java
+++ b/src/main/java/org/traccar/protocol/MiniFinderProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@ public class MiniFinderProtocol extends BaseProtocol {
pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ';'));
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new MiniFinderProtocolEncoder());
+ pipeline.addLast(new MiniFinderProtocolEncoder(MiniFinderProtocol.this));
pipeline.addLast(new MiniFinderProtocolDecoder(MiniFinderProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java
index 7a3d5b226..36fb9fc2f 100644
--- a/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,14 @@ import java.util.TimeZone;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter {
+ public MiniFinderProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
public String formatValue(String key, Object value) {
switch (key) {
diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java
index 51b32ae3e..b6f257d2c 100644
--- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java
@@ -33,6 +33,7 @@ import org.traccar.model.WifiAccessPoint;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
+import java.util.Date;
public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder {
@@ -72,8 +73,13 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder {
ByteBuf buf = (ByteBuf) msg;
buf.readUnsignedByte(); // header
+ int flags = buf.readUnsignedByte();
+ buf.readUnsignedShortLE(); // length
+ buf.readUnsignedShortLE(); // checksum
+ int index = buf.readUnsignedShortLE();
+ int type = buf.readUnsignedByte();
- if (BitUtil.check(buf.readUnsignedByte(), 4) && channel != null) {
+ if (BitUtil.check(flags, 4) && channel != null) {
ByteBuf content = Unpooled.buffer();
content.writeByte(MSG_RESPONSE);
@@ -82,21 +88,16 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder {
ByteBuf response = Unpooled.buffer();
response.writeByte(0xAB); // header
- response.writeByte(0); // properties
- response.writeShortLE(3);
+ response.writeByte(0x00); // properties
+ response.writeShortLE(content.readableBytes());
response.writeShortLE(Checksum.crc16(Checksum.CRC16_XMODEM, content.nioBuffer()));
- response.writeShortLE(0); // index
+ response.writeShortLE(index);
response.writeBytes(content);
content.release();
channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
}
- buf.readUnsignedShortLE(); // length
- buf.readUnsignedShortLE(); // checksum
- buf.readUnsignedShortLE(); // index
- int type = buf.readUnsignedByte();
-
if (type == MSG_DATA) {
Position position = new Position(getProtocolName());
@@ -116,6 +117,10 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder {
case 0x02:
position.set(Position.KEY_ALARM, decodeAlarm(buf.readIntLE()));
break;
+ case 0x14:
+ position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte());
+ position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001);
+ break;
case 0x20:
position.setLatitude(buf.readIntLE() * 0.0000001);
position.setLongitude(buf.readIntLE() * 0.0000001);
@@ -149,6 +154,12 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder {
mac.substring(0, mac.length() - 1), rssi));
}
break;
+ case 0x24:
+ position.setTime(new Date(buf.readUnsignedIntLE() * 1000));
+ long status = buf.readUnsignedIntLE();
+ position.set(Position.KEY_BATTERY_LEVEL, BitUtil.from(status, 24));
+ position.set(Position.KEY_STATUS, status);
+ break;
case 0x40:
buf.readUnsignedIntLE(); // timestamp
int heartRate = buf.readUnsignedByte();
diff --git a/src/main/java/org/traccar/protocol/NavisetFrameDecoder.java b/src/main/java/org/traccar/protocol/NavisetFrameDecoder.java
new file mode 100644
index 000000000..e5e13b305
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/NavisetFrameDecoder.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import org.traccar.BaseFrameDecoder;
+import org.traccar.helper.BitUtil;
+
+public class NavisetFrameDecoder extends BaseFrameDecoder {
+
+ @Override
+ protected Object decode(
+ ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {
+
+ int length = 2 + BitUtil.to(buf.getUnsignedShortLE(buf.readerIndex()), 12) + 2;
+
+ if (buf.readableBytes() >= length) {
+ return buf.readRetainedSlice(length);
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/NavisetProtocol.java b/src/main/java/org/traccar/protocol/NavisetProtocol.java
new file mode 100644
index 000000000..78755ea4d
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/NavisetProtocol.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import org.traccar.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class NavisetProtocol extends BaseProtocol {
+
+ public NavisetProtocol() {
+ addServer(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new NavisetFrameDecoder());
+ pipeline.addLast(new NavisetProtocolDecoder(NavisetProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java
new file mode 100644
index 000000000..10d71d76c
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/NavisetProtocolDecoder.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.NetworkMessage;
+import org.traccar.Protocol;
+import org.traccar.helper.BitUtil;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+public class NavisetProtocolDecoder extends BaseProtocolDecoder {
+
+ public NavisetProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ public static final int MSG_HEADER = 0b00;
+ public static final int MSG_DATA = 0b01;
+ public static final int MSG_RESPONSE = 0b10;
+ public static final int MSG_RESERVE = 0b11;
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ByteBuf buf = (ByteBuf) msg;
+
+ if (channel != null) {
+ ByteBuf response = Unpooled.buffer();
+ response.writeByte(0x01);
+ response.writeShortLE(buf.getUnsignedShortLE(buf.writerIndex() - 2));
+ channel.writeAndFlush(new NetworkMessage(response, channel.remoteAddress()));
+ }
+
+ int length = buf.readUnsignedShortLE();
+ int type = BitUtil.between(length, 14, 16);
+ buf.readUnsignedShortLE(); // device number
+
+ if (type == MSG_HEADER) {
+
+ getDeviceSession(channel, remoteAddress, buf.readCharSequence(15, StandardCharsets.US_ASCII).toString());
+
+ } else if (type == MSG_DATA) {
+
+ List<Position> positions = new LinkedList<>();
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ int blockMask = buf.readUnsignedByte();
+
+ while (buf.readableBytes() > 2) {
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.set(Position.KEY_INDEX, buf.readUnsignedShortLE());
+ position.set(Position.KEY_STATUS, buf.readUnsignedByte());
+ position.setValid(true);
+ position.setTime(new Date(buf.readUnsignedIntLE() * 1000));
+ position.setLatitude(buf.readUnsignedIntLE() * 0.000001);
+ position.setLongitude(buf.readUnsignedIntLE() * 0.000001);
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE() * 0.1));
+
+ if (BitUtil.check(blockMask, 0)) {
+ int dataMask = buf.readUnsignedByte();
+ if (BitUtil.check(dataMask, 0)) {
+ int satellites = buf.readUnsignedByte();
+ position.setValid(BitUtil.check(satellites, 7));
+ position.set(Position.KEY_SATELLITES, BitUtil.to(satellites, 7));
+ }
+ if (BitUtil.check(dataMask, 1)) {
+ position.setCourse(buf.readUnsignedShortLE() * 0.1);
+ }
+ if (BitUtil.check(dataMask, 2)) {
+ position.setAltitude(buf.readShortLE());
+ }
+ if (BitUtil.check(dataMask, 3)) {
+ position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1);
+ }
+ if (BitUtil.check(dataMask, 4)) {
+ position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001);
+ position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001);
+ }
+ if (BitUtil.check(dataMask, 5)) {
+ position.set(Position.KEY_INPUT, buf.readUnsignedByte());
+ position.set(Position.KEY_OUTPUT, buf.readUnsignedByte());
+ }
+ if (BitUtil.check(dataMask, 6)) {
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE());
+ }
+ if (BitUtil.check(dataMask, 7)) {
+ buf.skipBytes(6); // accelerometer
+ }
+ }
+
+ if (BitUtil.check(blockMask, 1)) {
+ int dataMask = buf.readUnsignedByte();
+ for (int i = 0; i < 8; i++) {
+ if (BitUtil.check(dataMask, i)) {
+ position.set(Position.PREFIX_ADC + (i + 1), buf.readUnsignedShortLE());
+ }
+ }
+ }
+
+ if (BitUtil.check(blockMask, 2)) {
+ int dataMask = buf.readUnsignedByte();
+ if (BitUtil.check(dataMask, 0)) {
+ position.set(Position.KEY_DEVICE_TEMP, (int) buf.readByte());
+ }
+ if (BitUtil.check(dataMask, 1)) {
+ buf.skipBytes(6); // key code
+ }
+ if (BitUtil.check(dataMask, 2)) {
+ position.set(Position.PREFIX_TEMP + 1, (int) buf.readByte());
+ position.set(Position.PREFIX_TEMP + 2, (int) buf.readByte());
+ }
+ if (BitUtil.check(dataMask, 3)) {
+ position.set(Position.PREFIX_TEMP + 3, (int) buf.readByte());
+ position.set(Position.PREFIX_TEMP + 4, (int) buf.readByte());
+ }
+ if (BitUtil.check(dataMask, 4)) {
+ position.set(Position.PREFIX_TEMP + 5, (int) buf.readByte());
+ position.set(Position.PREFIX_TEMP + 6, (int) buf.readByte());
+ position.set(Position.PREFIX_TEMP + 7, (int) buf.readByte());
+ position.set(Position.PREFIX_TEMP + 8, (int) buf.readByte());
+ }
+ if (BitUtil.check(dataMask, 5)) {
+ position.set(Position.KEY_HOURS, buf.readUnsignedShortLE() / 60.0);
+ }
+ if (BitUtil.check(dataMask, 6)) {
+ buf.readUnsignedByte(); // extra status
+ }
+ if (BitUtil.check(dataMask, 7)) {
+ buf.readUnsignedByte(); // geofence
+ }
+ }
+
+ if (BitUtil.check(blockMask, 3)) {
+ int dataMask = buf.readUnsignedByte();
+ if (BitUtil.check(dataMask, 0)) {
+ position.set("fuel1", buf.readUnsignedShortLE());
+ }
+ if (BitUtil.check(dataMask, 1)) {
+ position.set("fuel2", buf.readUnsignedShortLE());
+ }
+ if (BitUtil.check(dataMask, 2)) {
+ position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShortLE());
+ }
+ if (BitUtil.check(dataMask, 3)) {
+ buf.skipBytes(18);
+ }
+ if (BitUtil.check(dataMask, 4)) {
+ buf.readUnsignedByte(); // fuel 1 temperature
+ }
+ if (BitUtil.check(dataMask, 5)) {
+ buf.readUnsignedByte(); // fuel 2 temperature
+ }
+ if (BitUtil.check(dataMask, 6)) {
+ buf.readUnsignedShortLE(); // fuel 1 frequency
+ }
+ if (BitUtil.check(dataMask, 7)) {
+ buf.readUnsignedShortLE(); // fuel 2 frequency
+ }
+ }
+
+ if (BitUtil.check(blockMask, 4)) {
+ int dataMask = buf.readUnsignedByte();
+ if (BitUtil.check(dataMask, 0)) {
+ buf.readUnsignedByte(); // fuel level (percentage)
+ position.set(Position.KEY_RPM, buf.readUnsignedShortLE());
+ position.set(Position.KEY_COOLANT_TEMP, (int) buf.readByte());
+ }
+ if (BitUtil.check(dataMask, 1)) {
+ buf.readUnsignedIntLE(); // fuel consumption
+ }
+ if (BitUtil.check(dataMask, 2)) {
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE());
+ }
+ for (int i = 3; i < 8; i++) {
+ if (BitUtil.check(dataMask, i)) {
+ buf.readUnsignedShortLE(); // axle weight
+ }
+ }
+ }
+
+ if (BitUtil.check(blockMask, 4)) {
+ int dataMask = buf.readUnsignedByte();
+ if (BitUtil.check(dataMask, 0)) {
+ buf.readUnsignedByte(); // speed
+ }
+ if (BitUtil.check(dataMask, 1)) {
+ buf.readUnsignedMediumLE(); // prefix S
+ }
+ if (BitUtil.check(dataMask, 2)) {
+ buf.readUnsignedIntLE(); // prefix P
+ }
+ if (BitUtil.check(dataMask, 3)) {
+ buf.readUnsignedIntLE(); // prefix A or B
+ }
+ if (BitUtil.check(dataMask, 4)) {
+ buf.readUnsignedShortLE(); // prefix R
+ }
+ if (BitUtil.check(dataMask, 5)) {
+ buf.skipBytes(26);
+ }
+ if (BitUtil.check(dataMask, 6)) {
+ buf.readUnsignedIntLE(); // reserved
+ }
+ if (BitUtil.check(dataMask, 7)) {
+ buf.readUnsignedIntLE(); // reserved
+ }
+ }
+
+ positions.add(position);
+ }
+
+ return positions;
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/NoranProtocol.java b/src/main/java/org/traccar/protocol/NoranProtocol.java
index 9f3078d6d..3df364c30 100644
--- a/src/main/java/org/traccar/protocol/NoranProtocol.java
+++ b/src/main/java/org/traccar/protocol/NoranProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ public class NoranProtocol extends BaseProtocol {
addServer(new TrackerServer(true, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new NoranProtocolEncoder());
+ pipeline.addLast(new NoranProtocolEncoder(NoranProtocol.this));
pipeline.addLast(new NoranProtocolDecoder(NoranProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java b/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java
index 92826c8b2..e02a1313c 100644
--- a/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +19,16 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
public class NoranProtocolEncoder extends BaseProtocolEncoder {
+ public NoranProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeContent(String content) {
ByteBuf buf = Unpooled.buffer(12 + 56);
diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocol.java b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java
new file mode 100644
index 000000000..08991ab64
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/PacificTrackProtocol.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import org.traccar.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class PacificTrackProtocol extends BaseProtocol {
+
+ public PacificTrackProtocol() {
+ addServer(new TrackerServer(true, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new PacificTrackProtocolDecoder(PacificTrackProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java
new file mode 100644
index 000000000..199348c54
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.Protocol;
+import org.traccar.helper.BitUtil;
+import org.traccar.helper.DateBuilder;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+
+public class PacificTrackProtocolDecoder extends BaseProtocolDecoder {
+
+ public PacificTrackProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ public static int readBitExt(ByteBuf buf) {
+ int result = 0;
+ while (buf.isReadable()) {
+ int b = buf.readUnsignedByte();
+ result <<= 7;
+ result += BitUtil.to(b, 7);
+ if (BitUtil.check(b, 7)) {
+ break;
+ }
+ }
+ return result;
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ByteBuf buf = (ByteBuf) msg;
+
+ buf.readByte(); // frame start
+ readBitExt(buf); // frame control
+ readBitExt(buf); // frame length
+
+ DeviceSession deviceSession = null;
+ Position position = new Position(getProtocolName());
+
+ while (buf.isReadable()) {
+
+ int segmentId = readBitExt(buf);
+ int segmentLength = readBitExt(buf);
+
+ switch (segmentId) {
+ case 0x01:
+ position.set(Position.KEY_EVENT, readBitExt(buf));
+ break;
+ case 0x10:
+ position.setValid(BitUtil.check(buf.readUnsignedByte(), 4));
+ int date = buf.readUnsignedByte();
+ DateBuilder dateBuilder = new DateBuilder()
+ .setDate(2000 + BitUtil.from(date, 4), BitUtil.to(date, 4), buf.readUnsignedByte())
+ .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte());
+ position.setTime(dateBuilder.getDate());
+ position.setLatitude(buf.readUnsignedInt() / 1000000.0 - 90.0);
+ position.setLongitude(buf.readUnsignedInt() / 1000000.0 - 180.0);
+ int speedAndCourse = buf.readUnsignedMedium();
+ position.setCourse(BitUtil.from(speedAndCourse, 12));
+ position.setSpeed(UnitsConverter.knotsFromKph(BitUtil.to(speedAndCourse, 12)));
+ position.set(Position.KEY_INDEX, buf.readUnsignedShort());
+ break;
+ case 0x100:
+ String imei = ByteBufUtil.hexDump(buf.readSlice(8)).substring(1);
+ deviceSession = getDeviceSession(channel, remoteAddress, imei);
+ break;
+ default:
+ buf.skipBytes(segmentLength);
+ break;
+ }
+ }
+
+ if (deviceSession != null) {
+ position.setDeviceId(deviceSession.getDeviceId());
+ return position;
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/PluginProtocol.java b/src/main/java/org/traccar/protocol/PluginProtocol.java
new file mode 100644
index 000000000..d5f28da9d
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/PluginProtocol.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.handler.codec.string.StringDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.CharacterDelimiterFrameDecoder;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class PluginProtocol extends BaseProtocol {
+
+ public PluginProtocol() {
+ addServer(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, '#'));
+ pipeline.addLast(new StringEncoder());
+ pipeline.addLast(new StringDecoder());
+ pipeline.addLast(new PluginProtocolDecoder(PluginProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java
new file mode 100644
index 000000000..106889ee0
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.Protocol;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.util.regex.Pattern;
+
+public class PluginProtocolDecoder extends BaseProtocolDecoder {
+
+ public PluginProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .expression("[^0-9,]*,?")
+ .number("([^,]+),") // device id
+ .number("(dddd)(dd)(dd)") // date (yyyymmdd)
+ .number("(dd)(dd)(dd),") // time (hhmmss)
+ .number("(-?d+.d+),") // longitude
+ .number("(-?d+.d+),") // latitude
+ .number("(d+),") // speed
+ .number("(d+),") // course
+ .number("(-?d+),") // altitude
+ .number("(-?d+),") // satellites
+ .number("d+,") // type
+ .number("(d+),") // odometer
+ .number("(d+),") // status
+ .expression("[^,]*,")
+ .expression("[^,]*,")
+ .text("0")
+ .groupBegin()
+ .text(",+,")
+ .number("(d+),") // event
+ .groupEnd("?")
+ .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.setValid(true);
+ position.setTime(parser.nextDateTime());
+ position.setLongitude(parser.nextDouble());
+ position.setLatitude(parser.nextDouble());
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt()));
+ position.setCourse(parser.nextInt());
+ position.setAltitude(parser.nextInt());
+
+ position.set(Position.KEY_SATELLITES, parser.nextInt());
+ position.set(Position.KEY_ODOMETER, parser.nextInt());
+ position.set(Position.KEY_STATUS, parser.nextInt());
+ position.set(Position.KEY_EVENT, parser.nextInt());
+
+ return position;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/PretraceProtocol.java b/src/main/java/org/traccar/protocol/PretraceProtocol.java
index f753cbdb4..9d35c1c2f 100644
--- a/src/main/java/org/traccar/protocol/PretraceProtocol.java
+++ b/src/main/java/org/traccar/protocol/PretraceProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ public class PretraceProtocol extends BaseProtocol {
pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, ')'));
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new PretraceProtocolEncoder());
+ pipeline.addLast(new PretraceProtocolEncoder(PretraceProtocol.this));
pipeline.addLast(new PretraceProtocolDecoder(PretraceProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java
index 9cf951e3b..1083a252e 100644
--- a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,14 @@ import org.traccar.BaseProtocolEncoder;
import org.traccar.Context;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class PretraceProtocolEncoder extends BaseProtocolEncoder {
+ public PretraceProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private String formatCommand(String uniqueId, String data) {
String content = uniqueId + data;
return String.format("(%s^%02X)", content, Checksum.xor(content));
diff --git a/src/main/java/org/traccar/protocol/Pt215FrameDecoder.java b/src/main/java/org/traccar/protocol/Pt215FrameDecoder.java
new file mode 100644
index 000000000..0b3bae914
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/Pt215FrameDecoder.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import org.traccar.BaseFrameDecoder;
+
+public class Pt215FrameDecoder extends BaseFrameDecoder {
+
+ private ByteBuf decodeFrame(ByteBuf buf, int length) {
+ if (buf.readableBytes() >= length) {
+ return buf.readRetainedSlice(length);
+ }
+ return null;
+ }
+
+ @Override
+ protected Object decode(
+ ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {
+
+ if (buf.readableBytes() < 5) {
+ return null;
+ }
+
+ int type = buf.getUnsignedByte(buf.readerIndex() + 2 + 1);
+ switch (type) {
+ case Pt215ProtocolDecoder.MSG_LOGIN:
+ return decodeFrame(buf, 15);
+ case Pt215ProtocolDecoder.MSG_GPS_REALTIME:
+ case Pt215ProtocolDecoder.MSG_GPS_OFFLINE:
+ return decodeFrame(buf, 27);
+ case Pt215ProtocolDecoder.MSG_STATUS:
+ return decodeFrame(buf, 11);
+ default:
+ return null;
+
+ }
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/Pt215Protocol.java b/src/main/java/org/traccar/protocol/Pt215Protocol.java
new file mode 100644
index 000000000..31ddc2c7a
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/Pt215Protocol.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import org.traccar.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class Pt215Protocol extends BaseProtocol {
+
+ public Pt215Protocol() {
+ addServer(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new Pt215FrameDecoder());
+ pipeline.addLast(new Pt215ProtocolDecoder(Pt215Protocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java
new file mode 100644
index 000000000..48ce7dede
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/Pt215ProtocolDecoder.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.NetworkMessage;
+import org.traccar.Protocol;
+import org.traccar.helper.BitUtil;
+import org.traccar.helper.DateBuilder;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+
+public class Pt215ProtocolDecoder extends BaseProtocolDecoder {
+
+ public Pt215ProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ public static final int MSG_LOGIN = 0x01;
+ public static final int MSG_HEARTBEAT = 0x08;
+ public static final int MSG_GPS_REALTIME = 0x10;
+ public static final int MSG_GPS_OFFLINE = 0x11;
+ public static final int MSG_STATUS = 0x13;
+
+ private void sendResponse(
+ Channel channel, SocketAddress remoteAddress, int type, ByteBuf content) {
+ if (channel != null) {
+ ByteBuf response = Unpooled.buffer();
+ response.writeByte('X');
+ response.writeByte('X');
+ response.writeByte(content != null ? 1 + content.readableBytes() : 1);
+ response.writeByte(type);
+ if (content != null) {
+ response.writeBytes(content);
+ content.release();
+ }
+ response.writeByte('\r');
+ response.writeByte('\n');
+ channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
+ }
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ByteBuf buf = (ByteBuf) msg;
+
+ buf.skipBytes(2); // header
+ buf.readUnsignedByte(); // length
+ int type = buf.readUnsignedByte();
+
+ if (type == MSG_LOGIN) {
+
+ getDeviceSession(channel, remoteAddress, ByteBufUtil.hexDump(buf.readSlice(8)).substring(1));
+ sendResponse(channel, remoteAddress, type, null);
+
+ } else if (type == MSG_GPS_OFFLINE || type == MSG_GPS_REALTIME) {
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ sendResponse(channel, remoteAddress, type, buf.retainedSlice(buf.readerIndex(), 6));
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
+ .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte());
+ position.setTime(dateBuilder.getDate());
+
+ double latitude = buf.readUnsignedInt() / 60.0 / 30000.0;
+ double longitude = buf.readUnsignedInt() / 60.0 / 30000.0;
+
+ int flags = buf.readUnsignedShort();
+ position.setCourse(BitUtil.to(flags, 10));
+ position.setValid(BitUtil.check(flags, 12));
+
+ if (!BitUtil.check(flags, 10)) {
+ latitude = -latitude;
+ }
+ if (BitUtil.check(flags, 11)) {
+ longitude = -longitude;
+ }
+
+ position.setLatitude(latitude);
+ position.setLongitude(longitude);
+
+ return position;
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/Pt502Protocol.java b/src/main/java/org/traccar/protocol/Pt502Protocol.java
index 5afb9451d..56444fb42 100644
--- a/src/main/java/org/traccar/protocol/Pt502Protocol.java
+++ b/src/main/java/org/traccar/protocol/Pt502Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ public class Pt502Protocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new Pt502FrameDecoder());
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new Pt502ProtocolEncoder());
+ pipeline.addLast(new Pt502ProtocolEncoder(Pt502Protocol.this));
pipeline.addLast(new Pt502ProtocolDecoder(Pt502Protocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java
index ed18208cc..ba08b16ae 100644
--- a/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,14 @@ import java.util.TimeZone;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class Pt502ProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter {
+ public Pt502ProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
public String formatValue(String key, Object value) {
if (key.equals(Command.KEY_TIMEZONE)) {
diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java
new file mode 100644
index 000000000..c9db10610
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocol.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.handler.codec.LineBasedFrameDecoder;
+import io.netty.handler.codec.string.StringDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class RaceDynamicsProtocol extends BaseProtocol {
+
+ public RaceDynamicsProtocol() {
+ addServer(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new LineBasedFrameDecoder(1500));
+ pipeline.addLast(new StringEncoder());
+ pipeline.addLast(new StringDecoder());
+ pipeline.addLast(new RaceDynamicsProtocolDecoder(RaceDynamicsProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java
new file mode 100644
index 000000000..f441bf8ed
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/RaceDynamicsProtocolDecoder.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.NetworkMessage;
+import org.traccar.Protocol;
+import org.traccar.helper.DateBuilder;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+public class RaceDynamicsProtocolDecoder extends BaseProtocolDecoder {
+
+ public RaceDynamicsProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ public static final int MSG_LOGIN = 12;
+ public static final int MSG_LOCATION = 15;
+
+ private static final Pattern PATTERN_LOGIN = new PatternBuilder()
+ .text("$GPRMC,")
+ .number("d+,") // type
+ .number("d{6},") // date
+ .number("d{6},") // time
+ .number("(d{15}),")
+ .compile();
+
+ private static final Pattern PATTERN_LOCATION = new PatternBuilder()
+ .number("(dd)(dd)(dd),") // time (hhmmss)
+ .expression("([AV]),") // validity
+ .number("(dd)(dd.d+),") // latitude
+ .expression("([NS]),")
+ .number("(ddd)(dd.d+),") // longitude
+ .expression("([EW]),")
+ .number("(d+),") // speed
+ .number("(dd)(dd)(dd),") // date (ddmmyy)
+ .number("(-?d+),") // altitude
+ .number("(d+),") // satellites
+ .number("([01]),") // ignition
+ .number("(d+),") // index
+ .text("%,")
+ .number("([^,]+),") // ibutton
+ .number("d+,") // acceleration
+ .number("d+,") // deceleration
+ .number("[01],") // cruise control
+ .number("[01],") // seat belt
+ .number("[01],") // wrong ibutton
+ .number("(d+),") // power
+ .number("[01],") // power status
+ .number("(d+),") // battery
+ .number("([01]),") // panic
+ .number("d+,")
+ .number("d+,")
+ .number("(d),") // overspeed
+ .number("d+,") // speed limit
+ .number("d+,") // tachometer
+ .number("d+,d+,d+,") // aux
+ .number("d+,") // geofence id
+ .number("d+,") // road speed type
+ .number("d+,") // ibutton count
+ .number("(d),") // overdriver alert
+ .any()
+ .compile();
+
+ private String imei;
+
+ private void sendResponse(Channel channel, SocketAddress remoteAddress, int type) {
+ if (channel != null) {
+ String response = String.format(
+ "$GPRMC,%1$d,%2$td%2$tm%2$ty,%2$tH%2$tM%2$tS,%3$s,\r\n", type, new Date(), imei);
+ channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
+ }
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ String sentence = (String) msg;
+
+ int type = Integer.parseInt(sentence.substring(7, 9));
+
+ if (type == MSG_LOGIN) {
+
+ Parser parser = new Parser(PATTERN_LOGIN, sentence);
+ if (parser.matches()) {
+ imei = parser.next();
+ getDeviceSession(channel, remoteAddress, imei);
+ sendResponse(channel, remoteAddress, type);
+ }
+
+ } else if (type == MSG_LOCATION) {
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ List<Position> positions = new LinkedList<>();
+
+ for (String data : sentence.substring(17, sentence.length() - 3).split(",#,#,")) {
+ Parser parser = new Parser(PATTERN_LOCATION, data);
+ if (parser.matches()) {
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
+
+ position.setValid(parser.next().equals("A"));
+ position.setLatitude(parser.nextCoordinate());
+ position.setLongitude(parser.nextCoordinate());
+ position.setSpeed(parser.nextDouble());
+
+ dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ position.setTime(dateBuilder.getDate());
+
+ position.setAltitude(parser.nextInt());
+ position.set(Position.KEY_SATELLITES, parser.nextInt());
+ position.set(Position.KEY_IGNITION, parser.nextInt() == 1);
+ position.set(Position.KEY_INDEX, parser.nextInt());
+ position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
+ position.set(Position.KEY_POWER, parser.nextInt() * 0.01);
+ position.set(Position.KEY_BATTERY, parser.nextInt() * 0.01);
+ position.set(Position.KEY_ALARM, parser.nextInt() > 0 ? Position.ALARM_SOS : null);
+ position.set(Position.KEY_ALARM, parser.nextInt() > 0 ? Position.ALARM_OVERSPEED : null);
+
+ int overDriver = parser.nextInt();
+ if (overDriver > 0) {
+ position.set("overDriver", overDriver);
+ }
+
+ positions.add(position);
+
+ }
+ }
+
+ sendResponse(channel, remoteAddress, type);
+
+ return positions;
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/RstProtocol.java b/src/main/java/org/traccar/protocol/RstProtocol.java
new file mode 100644
index 000000000..10d11d493
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/RstProtocol.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.handler.codec.string.StringDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import org.traccar.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+public class RstProtocol extends BaseProtocol {
+
+ public RstProtocol() {
+ addServer(new TrackerServer(true, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new StringEncoder());
+ pipeline.addLast(new StringDecoder());
+ pipeline.addLast(new RstProtocolDecoder(RstProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/RstProtocolDecoder.java b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java
new file mode 100644
index 000000000..071200d6d
--- /dev/null
+++ b/src/main/java/org/traccar/protocol/RstProtocolDecoder.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.NetworkMessage;
+import org.traccar.Protocol;
+import org.traccar.helper.Parser;
+import org.traccar.helper.PatternBuilder;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.util.regex.Pattern;
+
+public class RstProtocolDecoder extends BaseProtocolDecoder {
+
+ public RstProtocolDecoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .text("RST;")
+ .expression("([AL]);") // archive
+ .expression("([^,]+);") // model
+ .expression("(.{5});") // firmware
+ .number("(d{9});") // serial number
+ .number("(d+);") // index
+ .number("(d+);") // type
+ .number("(dd)-(dd)-(dddd) ") // event date
+ .number("(dd):(dd):(dd);") // event time
+ .number("(dd)-(dd)-(dddd) ") // fix date
+ .number("(dd):(dd):(dd);") // fix time
+ .number("(-?d+.d+);") // latitude
+ .number("(-?d+.d+);") // longitude
+ .number("(d+);") // speed
+ .number("(d+);") // course
+ .number("(-?d+);") // altitude
+ .number("([01]);") // valid
+ .number("(d+);") // satellites
+ .number("(d+);") // hdop
+ .number("(xx);") // inputs 1
+ .number("(xx);") // inputs 2
+ .number("(xx);") // inputs 3
+ .number("(xx);") // outputs 1
+ .number("(xx);") // outputs 2
+ .number("(d+.d+);") // power
+ .number("(d+.d+);") // battery
+ .number("(d+);") // odometer
+ .number("(d+);") // rssi
+ .number("(xx);") // temperature
+ .number("x{4};") // sensors
+ .number("(xx);") // status 1
+ .number("(xx);") // status 2
+ .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 archive = parser.next();
+ String model = parser.next();
+ String firmware = parser.next();
+ String serial = parser.next();
+ int index = parser.nextInt();
+ int type = parser.nextInt();
+
+ if (channel != null && archive.equals("A")) {
+ String response = "RST;A;" + model + ";" + firmware + ";" + serial + ";" + index + ";" + type + ";FIM;";
+ channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, serial);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setDeviceTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
+ position.setFixTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
+ position.setLatitude(parser.nextDouble());
+ position.setLongitude(parser.nextDouble());
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt()));
+ position.setCourse(parser.nextInt());
+ position.setAltitude(parser.nextInt());
+ position.setValid(parser.nextInt() > 0);
+
+ position.set(Position.KEY_SATELLITES, parser.nextInt());
+ position.set(Position.KEY_HDOP, parser.nextInt());
+ position.set(Position.PREFIX_IN + 1, parser.nextHexInt());
+ position.set(Position.PREFIX_IN + 2, parser.nextHexInt());
+ position.set(Position.PREFIX_IN + 3, parser.nextHexInt());
+ position.set(Position.PREFIX_OUT + 1, parser.nextHexInt());
+ position.set(Position.PREFIX_OUT + 2, parser.nextHexInt());
+ position.set(Position.KEY_POWER, parser.nextDouble());
+ position.set(Position.KEY_BATTERY, parser.nextDouble());
+ position.set(Position.KEY_ODOMETER, parser.nextInt());
+ position.set(Position.KEY_RSSI, parser.nextInt());
+ position.set(Position.PREFIX_TEMP + 1, (int) parser.nextHexInt().byteValue());
+ position.set(Position.KEY_STATUS, parser.nextHexInt() << 8 + parser.nextHexInt());
+
+ return position;
+ }
+
+}
diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocol.java b/src/main/java/org/traccar/protocol/RuptelaProtocol.java
index a574293cd..b8f72336b 100644
--- a/src/main/java/org/traccar/protocol/RuptelaProtocol.java
+++ b/src/main/java/org/traccar/protocol/RuptelaProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ public class RuptelaProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 2, 0));
- pipeline.addLast(new RuptelaProtocolEncoder());
+ pipeline.addLast(new RuptelaProtocolEncoder(RuptelaProtocol.this));
pipeline.addLast(new RuptelaProtocolDecoder(RuptelaProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java
index 96d0da5a7..51967403d 100644
--- a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java
@@ -20,11 +20,16 @@ import io.netty.buffer.Unpooled;
import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.Checksum;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
public class RuptelaProtocolEncoder extends BaseProtocolEncoder {
+ public RuptelaProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeContent(int type, ByteBuf content) {
ByteBuf buf = Unpooled.buffer();
diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java
index d7836b35d..f9c79fb5b 100644
--- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.traccar.protocol;
import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpRequest;
@@ -25,7 +26,9 @@ import org.traccar.DeviceSession;
import org.traccar.Protocol;
import org.traccar.helper.DataConverter;
import org.traccar.helper.UnitsConverter;
+import org.traccar.model.Network;
import org.traccar.model.Position;
+import org.traccar.model.WifiAccessPoint;
import javax.json.Json;
import javax.json.JsonObject;
@@ -46,8 +49,11 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder {
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
FullHttpRequest request = (FullHttpRequest) msg;
- JsonObject json = Json.createReader(new StringReader(URLDecoder.decode(
- request.content().toString(StandardCharsets.UTF_8).split("=")[0], "UTF-8"))).readObject();
+ String content = request.content().toString(StandardCharsets.UTF_8);
+ if (!content.startsWith("{")) {
+ content = URLDecoder.decode(content.split("=")[0], "UTF-8");
+ }
+ JsonObject json = Json.createReader(new StringReader(content)).readObject();
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, json.getString("device"));
if (deviceSession == null) {
@@ -58,32 +64,101 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- position.setTime(new Date(json.getInt("time") * 1000L));
-
- ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(json.getString("data")));
- try {
- int type = buf.readUnsignedByte() >> 4;
- if (type == 0) {
-
- position.setValid(true);
- position.setLatitude(buf.readIntLE() * 0.0000001);
- position.setLongitude(buf.readIntLE() * 0.0000001);
- position.setCourse(buf.readUnsignedByte() * 2);
- position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
-
- position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.025);
-
- } else {
-
- getLastLocation(position, position.getDeviceTime());
+ if (json.containsKey("time")) {
+ position.setTime(new Date(json.getInt("time") * 1000L));
+ } else {
+ position.setTime(new Date());
+ }
+ if (json.containsKey("location")) {
+
+ JsonObject location = json.getJsonObject("location");
+
+ position.setValid(true);
+ position.setLatitude(location.getJsonNumber("lat").doubleValue());
+ position.setLongitude(location.getJsonNumber("lng").doubleValue());
+
+ } else {
+
+ String data = json.getString(json.containsKey("data") ? "data" : "payload");
+ ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(data));
+ try {
+ int event = buf.readUnsignedByte();
+ if (event >> 4 == 0) {
+
+ position.setValid(true);
+ position.setLatitude(buf.readIntLE() * 0.0000001);
+ position.setLongitude(buf.readIntLE() * 0.0000001);
+ position.setCourse(buf.readUnsignedByte() * 2);
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
+
+ position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.025);
+
+ } else {
+
+ position.set(Position.KEY_EVENT, event);
+ if (event == 0x22 || event == 0x62) {
+ position.set(Position.KEY_ALARM, Position.ALARM_SOS);
+ }
+
+ while (buf.isReadable()) {
+ int type = buf.readUnsignedByte();
+ switch (type) {
+ case 0x01:
+ position.setValid(true);
+ position.setLatitude(buf.readMedium());
+ position.setLongitude(buf.readMedium());
+ break;
+ case 0x02:
+ position.setValid(true);
+ position.setLatitude(buf.readFloat());
+ position.setLongitude(buf.readFloat());
+ break;
+ case 0x03:
+ position.set(Position.PREFIX_TEMP + 1, buf.readByte() * 0.5);
+ break;
+ case 0x04:
+ position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.1);
+ break;
+ case 0x05:
+ position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte());
+ break;
+ case 0x06:
+ String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:");
+ position.setNetwork(new Network(WifiAccessPoint.from(
+ mac.substring(0, mac.length() - 1), buf.readUnsignedByte())));
+ break;
+ case 0x07:
+ buf.skipBytes(10); // wifi extended
+ break;
+ case 0x08:
+ buf.skipBytes(6); // accelerometer
+ break;
+ case 0x09:
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
+ break;
+ default:
+ buf.readUnsignedByte(); // fence number
+ break;
+ }
+ }
+
+ }
+ } finally {
+ buf.release();
}
- } finally {
- buf.release();
}
- position.set(Position.KEY_RSSI, json.getJsonNumber("rssi").doubleValue());
- position.set(Position.KEY_INDEX, json.getInt("seqNumber"));
+ if (position.getLatitude() == 0 && position.getLongitude() == 0) {
+ getLastLocation(position, position.getDeviceTime());
+ }
+
+ if (json.containsKey("rssi")) {
+ position.set(Position.KEY_RSSI, json.getJsonNumber("rssi").doubleValue());
+ }
+ if (json.containsKey("seqNumber")) {
+ position.set(Position.KEY_INDEX, json.getInt("seqNumber"));
+ }
sendResponse(channel, HttpResponseStatus.OK);
return position;
diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java
index ed5f81c1c..bad6f03a9 100644
--- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,21 +34,7 @@ import java.util.regex.Pattern;
public class StarLinkProtocolDecoder extends BaseProtocolDecoder {
- private String[] dataTags;
- private DateFormat dateFormat;
-
- public StarLinkProtocolDecoder(Protocol protocol) {
- super(protocol);
-
- String format = Context.getConfig().getString(
- getProtocolName() + ".format", "#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#,"
- + "#IN1#,#IN2#,#IN3#,#IN4#,#OUT1#,#OUT2#,#OUT3#,#OUT4#,#LAC#,#CID#,#VIN#,#VBAT#,#DEST#,#IGN#,#ENG#");
- dataTags = format.split(",");
-
- dateFormat = new SimpleDateFormat(
- Context.getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss"));
- dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
- }
+ public static final int MSG_EVENT_REPORT = 6;
private static final Pattern PATTERN = new PatternBuilder()
.expression(".") // protocol head
@@ -61,7 +47,27 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder {
.number("xx") // checksum
.compile();
- public static final int MSG_EVENT_REPORT = 6;
+ private String[] dataTags;
+ private DateFormat dateFormat;
+
+ public StarLinkProtocolDecoder(Protocol protocol) {
+ super(protocol);
+
+ setFormat(Context.getConfig().getString(
+ getProtocolName() + ".format", "#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#,"
+ + "#IN1#,#IN2#,#IN3#,#IN4#,#OUT1#,#OUT2#,#OUT3#,#OUT4#,#LAC#,#CID#,#VIN#,#VBAT#,#DEST#,#IGN#,#ENG#"));
+
+ setDateFormat(Context.getConfig().getString(getProtocolName() + ".dateFormat", "yyMMddHHmmss"));
+ }
+
+ public void setFormat(String format) {
+ dataTags = format.split(",");
+ }
+
+ public void setDateFormat(String dateFormat) {
+ this.dateFormat = new SimpleDateFormat(dateFormat);
+ this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
private double parseCoordinate(String value) {
int minutesIndex = value.indexOf('.') - 2;
@@ -151,31 +157,19 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder {
position.setCourse(Integer.parseInt(data[i]));
break;
case "#ODO#":
- position.set(Position.KEY_ODOMETER, Long.parseLong(data[i]) * 1000);
+ position.set(Position.KEY_ODOMETER, (long) (Double.parseDouble(data[i]) * 1000));
break;
case "#IN1#":
- position.set(Position.PREFIX_IN + 1, Integer.parseInt(data[i]));
- break;
case "#IN2#":
- position.set(Position.PREFIX_IN + 2, Integer.parseInt(data[i]));
- break;
case "#IN3#":
- position.set(Position.PREFIX_IN + 3, Integer.parseInt(data[i]));
- break;
case "#IN4#":
- position.set(Position.PREFIX_IN + 4, Integer.parseInt(data[i]));
+ position.set(Position.PREFIX_IN + dataTags[i].charAt(3), Integer.parseInt(data[i]));
break;
case "#OUT1#":
- position.set(Position.PREFIX_OUT + 1, Integer.parseInt(data[i]));
- break;
case "#OUT2#":
- position.set(Position.PREFIX_OUT + 2, Integer.parseInt(data[i]));
- break;
case "#OUT3#":
- position.set(Position.PREFIX_OUT + 3, Integer.parseInt(data[i]));
- break;
case "#OUT4#":
- position.set(Position.PREFIX_OUT + 4, Integer.parseInt(data[i]));
+ position.set(Position.PREFIX_OUT + dataTags[i].charAt(3), Integer.parseInt(data[i]));
break;
case "#LAC#":
if (!data[i].isEmpty()) {
diff --git a/src/main/java/org/traccar/protocol/SuntechProtocol.java b/src/main/java/org/traccar/protocol/SuntechProtocol.java
index 48d6e81c1..7e2c20e6f 100644
--- a/src/main/java/org/traccar/protocol/SuntechProtocol.java
+++ b/src/main/java/org/traccar/protocol/SuntechProtocol.java
@@ -39,7 +39,7 @@ public class SuntechProtocol extends BaseProtocol {
pipeline.addLast(new SuntechFrameDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new SuntechProtocolEncoder());
+ pipeline.addLast(new SuntechProtocolEncoder(SuntechProtocol.this));
pipeline.addLast(new SuntechProtocolDecoder(SuntechProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java
index bd485ca70..e40096a77 100644
--- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java
@@ -50,7 +50,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
public int getProtocolType(long deviceId) {
return Context.getIdentityManager().lookupAttributeInteger(
- deviceId, getProtocolName() + ".protocolType", protocolType, true);
+ deviceId, getProtocolName() + ".protocolType", protocolType, false, true);
}
public void setHbm(boolean hbm) {
@@ -59,7 +59,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
public boolean isHbm(long deviceId) {
return Context.getIdentityManager().lookupAttributeBoolean(
- deviceId, getProtocolName() + ".hbm", hbm, true);
+ deviceId, getProtocolName() + ".hbm", hbm, false, true);
}
public void setIncludeAdc(boolean includeAdc) {
@@ -68,7 +68,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
public boolean isIncludeAdc(long deviceId) {
return Context.getIdentityManager().lookupAttributeBoolean(
- deviceId, getProtocolName() + ".includeAdc", includeAdc, true);
+ deviceId, getProtocolName() + ".includeAdc", includeAdc, false, true);
}
public void setIncludeRpm(boolean includeRpm) {
@@ -77,7 +77,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
public boolean isIncludeRpm(long deviceId) {
return Context.getIdentityManager().lookupAttributeBoolean(
- deviceId, getProtocolName() + ".includeRpm", includeRpm, true);
+ deviceId, getProtocolName() + ".includeRpm", includeRpm, false, true);
}
public void setIncludeTemp(boolean includeTemp) {
@@ -86,7 +86,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
public boolean isIncludeTemp(long deviceId) {
return Context.getIdentityManager().lookupAttributeBoolean(
- deviceId, getProtocolName() + ".includeTemp", includeTemp, true);
+ deviceId, getProtocolName() + ".includeTemp", includeTemp, false, true);
}
private Position decode9(
@@ -326,12 +326,40 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
case "UEX":
int remaining = Integer.parseInt(values[index++]);
while (remaining > 0) {
- String value = values[index++];
- String[] pair = value.split("=");
- if (pair.length >= 2) {
- position.set(pair[0].toLowerCase(), pair[1].trim());
+ String attribute = values[index++];
+ if (attribute.startsWith("CabAVL")) {
+ String[] data = attribute.split(",");
+ double fuel1 = Double.parseDouble(data[2]);
+ if (fuel1 > 0) {
+ position.set("fuel1", fuel1);
+ }
+ double fuel2 = Double.parseDouble(data[3]);
+ if (fuel2 > 0) {
+ position.set("fuel2", fuel2);
+ }
+ } else {
+ String[] pair = attribute.split("=");
+ if (pair.length >= 2) {
+ String value = pair[1].trim();
+ if (value.contains(".")) {
+ value = value.substring(0, value.indexOf('.'));
+ }
+ switch (pair[0].charAt(0)) {
+ case 't':
+ position.set(Position.PREFIX_TEMP + pair[0].charAt(2), Integer.parseInt(value, 16));
+ break;
+ case 'N':
+ position.set("fuel" + pair[0].charAt(2), Integer.parseInt(value, 16));
+ break;
+ case 'Q':
+ position.set("drivingQuality", Integer.parseInt(value, 16));
+ break;
+ default:
+ break;
+ }
+ }
}
- remaining -= value.length() + 1;
+ remaining -= attribute.length() + 1;
}
break;
default:
@@ -393,7 +421,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
String type = values[index++];
- if (!type.equals("STT")) {
+ if (!type.equals("STT") && !type.equals("ALT")) {
return null;
}
diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java
index 90fa4aa39..6dae42ad5 100644
--- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class SuntechProtocolEncoder extends StringProtocolEncoder {
+ public SuntechProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/SviasProtocol.java b/src/main/java/org/traccar/protocol/SviasProtocol.java
index f01f28389..accfa173f 100644
--- a/src/main/java/org/traccar/protocol/SviasProtocol.java
+++ b/src/main/java/org/traccar/protocol/SviasProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ public class SviasProtocol extends BaseProtocol {
pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "]"));
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new SviasProtocolEncoder());
+ pipeline.addLast(new SviasProtocolEncoder(SviasProtocol.this));
pipeline.addLast(new SviasProtocolDecoder(SviasProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java b/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java
index 8bfbef119..2607d7bd1 100644
--- a/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
* Copyright 2018 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,9 +18,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class SviasProtocolEncoder extends StringProtocolEncoder {
+ public SviasProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
switch (command.getType()) {
diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java
index ba231a635..b75addfae 100644
--- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java
@@ -96,6 +96,19 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
.any()
.compile();
+ private static final Pattern PATTERN_GPIOP = new PatternBuilder()
+ .text("$GPIOP,")
+ .number("[01]{8},") // inputs
+ .number("[01]{8},") // outputs
+ .number("d+.d+,") // adc 1
+ .number("d+.d+,") // adc 2
+ .number("d+.d+,") // adc 3
+ .number("d+.d+,") // adc 4
+ .number("(d+.d+),") // power
+ .number("(d+.d+)") // battery
+ .any()
+ .compile();
+
private Position position = null;
private Position decodeGprmc(
@@ -103,7 +116,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel)
&& Context.getIdentityManager().lookupAttributeBoolean(
- deviceSession.getDeviceId(), getProtocolName() + ".ack", false, true)) {
+ deviceSession.getDeviceId(), getProtocolName() + ".ack", false, false, true)) {
channel.writeAndFlush(new NetworkMessage("OK1\r\n", remoteAddress));
}
@@ -225,6 +238,24 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
return position;
}
+ private Position decodeGpiop(DeviceSession deviceSession, String sentence) {
+
+ Parser parser = new Parser(PATTERN_GPIOP, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ getLastLocation(position, null);
+
+ position.set(Position.KEY_POWER, parser.nextDouble());
+ position.set(Position.KEY_BATTERY, parser.nextDouble());
+
+ return position;
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -275,6 +306,8 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder {
return decodeGprma(deviceSession, sentence);
} else if (sentence.startsWith("$TRCCR") && deviceSession != null) {
return decodeTrccr(deviceSession, sentence);
+ } else if (sentence.startsWith("$GPIOP")) {
+ return decodeGpiop(deviceSession, sentence);
}
return null;
diff --git a/src/main/java/org/traccar/protocol/T800xProtocol.java b/src/main/java/org/traccar/protocol/T800xProtocol.java
index 85749d0cf..8b91265cb 100644
--- a/src/main/java/org/traccar/protocol/T800xProtocol.java
+++ b/src/main/java/org/traccar/protocol/T800xProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ public class T800xProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 3, 2, -5, 0));
- pipeline.addLast(new T800xProtocolEncoder());
+ pipeline.addLast(new T800xProtocolEncoder(T800xProtocol.this));
pipeline.addLast(new T800xProtocolDecoder(T800xProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
index 96fb7f96a..9b146ec90 100644
--- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java
@@ -31,19 +31,30 @@ import org.traccar.model.CellTower;
import org.traccar.model.Network;
import org.traccar.model.Position;
+import java.math.BigInteger;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
+import java.util.Date;
public class T800xProtocolDecoder extends BaseProtocolDecoder {
+ private short header = DEFAULT_HEADER;
+
+ public short getHeader() {
+ return header;
+ }
+
public T800xProtocolDecoder(Protocol protocol) {
super(protocol);
}
+ public static final short DEFAULT_HEADER = 0x2323;
+
public static final int MSG_LOGIN = 0x01;
public static final int MSG_GPS = 0x02;
public static final int MSG_HEARTBEAT = 0x03;
public static final int MSG_ALARM = 0x04;
+ public static final int MSG_NETWORK = 0x05;
public static final int MSG_COMMAND = 0x81;
private void sendResponse(Channel channel, short header, int type, int index, ByteBuf imei, int alarm) {
@@ -91,13 +102,24 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder {
}
}
+ private Date readDate(ByteBuf buf) {
+ return new DateBuilder()
+ .setYear(BcdUtil.readInteger(buf, 2))
+ .setMonth(BcdUtil.readInteger(buf, 2))
+ .setDay(BcdUtil.readInteger(buf, 2))
+ .setHour(BcdUtil.readInteger(buf, 2))
+ .setMinute(BcdUtil.readInteger(buf, 2))
+ .setSecond(BcdUtil.readInteger(buf, 2))
+ .getDate();
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
- short header = buf.readShort();
+ header = buf.readShort();
int type = buf.readUnsignedByte();
buf.readUnsignedShort(); // length
int index = buf.readUnsignedShort();
@@ -109,9 +131,32 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder {
return null;
}
+ if (type != MSG_GPS && type != MSG_ALARM) {
+ sendResponse(channel, header, type, index, imei, 0);
+ }
+
if (type == MSG_GPS || type == MSG_ALARM) {
- return decodePosition(channel, deviceSession, buf, header, type, index, imei);
+ return decodePosition(channel, deviceSession, buf, type, index, imei);
+
+ } else if (type == MSG_NETWORK) {
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ getLastLocation(position, readDate(buf));
+
+ position.set(Position.KEY_OPERATOR, buf.readCharSequence(
+ buf.readUnsignedByte(), StandardCharsets.UTF_16LE).toString());
+ position.set("networkTechnology", buf.readCharSequence(
+ buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString());
+ position.set("networkBand", buf.readCharSequence(
+ buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString());
+ buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII); // imsi
+ position.set(Position.KEY_ICCID, buf.readCharSequence(
+ buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString());
+
+ return position;
} else if (type == MSG_COMMAND) {
@@ -124,77 +169,77 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_RESULT, buf.toString(StandardCharsets.UTF_16LE));
- sendResponse(channel, header, type, index, imei, 0);
-
return position;
}
- sendResponse(channel, header, type, index, imei, 0);
-
return null;
}
private Position decodePosition(
Channel channel, DeviceSession deviceSession,
- ByteBuf buf, short header, int type, int index, ByteBuf imei) {
+ ByteBuf buf, int type, int index, ByteBuf imei) {
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_INDEX, index);
- buf.readUnsignedShort(); // acc on interval
- buf.readUnsignedShort(); // acc off interval
- buf.readUnsignedByte(); // angle compensation
- buf.readUnsignedShort(); // distance compensation
+ if (header != 0x2727) {
+
+ buf.readUnsignedShort(); // acc on interval
+ buf.readUnsignedShort(); // acc off interval
+ buf.readUnsignedByte(); // angle compensation
+ buf.readUnsignedShort(); // distance compensation
- position.set(Position.KEY_RSSI, BitUtil.to(buf.readUnsignedShort(), 7));
+ position.set(Position.KEY_RSSI, BitUtil.to(buf.readUnsignedShort(), 7));
+
+ }
int status = buf.readUnsignedByte();
position.set(Position.KEY_SATELLITES, BitUtil.to(status, 5));
- buf.readUnsignedByte(); // gsensor manager status
- buf.readUnsignedByte(); // other flags
- buf.readUnsignedByte(); // heartbeat
- buf.readUnsignedByte(); // relay status
- buf.readUnsignedShort(); // drag alarm setting
-
- int io = buf.readUnsignedShort();
- position.set(Position.KEY_IGNITION, BitUtil.check(io, 14));
- position.set("ac", BitUtil.check(io, 13));
- for (int i = 0; i <= 2; i++) {
- position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(io, 7 + i));
- }
+ if (header != 0x2727) {
- position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort());
- position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort());
+ buf.readUnsignedByte(); // gsensor manager status
+ buf.readUnsignedByte(); // other flags
+ buf.readUnsignedByte(); // heartbeat
+ buf.readUnsignedByte(); // relay status
+ buf.readUnsignedShort(); // drag alarm setting
+
+ int io = buf.readUnsignedShort();
+ position.set(Position.KEY_IGNITION, BitUtil.check(io, 14));
+ position.set("ac", BitUtil.check(io, 13));
+ for (int i = 0; i <= 2; i++) {
+ position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(io, 7 + i));
+ }
+
+ position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort());
+ position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort());
+
+ }
int alarm = buf.readUnsignedByte();
position.set(Position.KEY_ALARM, decodeAlarm(alarm));
- buf.readUnsignedByte(); // reserved
+ if (header != 0x2727) {
- position.set(Position.KEY_ODOMETER, buf.readUnsignedInt());
+ buf.readUnsignedByte(); // reserved
- int battery = BcdUtil.readInteger(buf, 2);
- if (battery == 0) {
- battery = 100;
- }
- position.set(Position.KEY_BATTERY, battery);
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedInt());
- DateBuilder dateBuilder = new DateBuilder()
- .setYear(BcdUtil.readInteger(buf, 2))
- .setMonth(BcdUtil.readInteger(buf, 2))
- .setDay(BcdUtil.readInteger(buf, 2))
- .setHour(BcdUtil.readInteger(buf, 2))
- .setMinute(BcdUtil.readInteger(buf, 2))
- .setSecond(BcdUtil.readInteger(buf, 2));
+ int battery = BcdUtil.readInteger(buf, 2);
+ if (battery == 0) {
+ battery = 100;
+ }
+ position.set(Position.KEY_BATTERY, battery);
+
+ }
if (BitUtil.check(status, 6)) {
position.setValid(!BitUtil.check(status, 7));
- position.setTime(dateBuilder.getDate());
+ position.setTime(readDate(buf));
position.setAltitude(buf.readFloatLE());
position.setLongitude(buf.readFloatLE());
position.setLatitude(buf.readFloatLE());
@@ -203,7 +248,7 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder {
} else {
- getLastLocation(position, dateBuilder.getDate());
+ getLastLocation(position, readDate(buf));
int mcc = buf.readUnsignedShortLE();
int mnc = buf.readUnsignedShortLE();
@@ -219,8 +264,46 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder {
}
- if (buf.readableBytes() >= 2) {
+ if (header == 0x2727) {
+
+ byte[] accelerationBytes = new byte[5];
+ buf.readBytes(accelerationBytes);
+ long acceleration = new BigInteger(accelerationBytes).longValue();
+ double accelerationZ = BitUtil.between(acceleration, 8, 15) + BitUtil.between(acceleration, 4, 8) * 0.1;
+ if (!BitUtil.check(acceleration, 15)) {
+ accelerationZ = -accelerationZ;
+ }
+ double accelerationY = BitUtil.between(acceleration, 20, 27) + BitUtil.between(acceleration, 16, 20) * 0.1;
+ if (!BitUtil.check(acceleration, 27)) {
+ accelerationY = -accelerationY;
+ }
+ double accelerationX = BitUtil.between(acceleration, 28, 32) + BitUtil.between(acceleration, 32, 39) * 0.1;
+ if (!BitUtil.check(acceleration, 39)) {
+ accelerationX = -accelerationX;
+ }
+ position.set(Position.KEY_G_SENSOR, "[" + accelerationX + "," + accelerationY + "," + accelerationZ + "]");
+
+ position.set(Position.KEY_BATTERY_LEVEL, BcdUtil.readInteger(buf, 2));
+ position.set(Position.KEY_DEVICE_TEMP, (int) buf.readByte());
+ position.set("lightSensor", BcdUtil.readInteger(buf, 2) * 0.1);
+ position.set(Position.KEY_BATTERY, BcdUtil.readInteger(buf, 2) * 0.1);
+ position.set("solarPanel", BcdUtil.readInteger(buf, 2) * 0.1);
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedInt());
+
+ int inputStatus = buf.readUnsignedShort();
+ position.set(Position.KEY_IGNITION, BitUtil.check(inputStatus, 2));
+ position.set(Position.KEY_RSSI, BitUtil.between(inputStatus, 4, 11));
+
+ buf.readUnsignedShort(); // ignition on upload interval
+ buf.readUnsignedInt(); // ignition off upload interval
+ buf.readUnsignedByte(); // angle upload interval
+ buf.readUnsignedShort(); // distance upload interval
+ buf.readUnsignedByte(); // heartbeat
+
+ } else if (buf.readableBytes() >= 2) {
+
position.set(Position.KEY_POWER, BcdUtil.readInteger(buf, 4) * 0.01);
+
}
sendResponse(channel, header, type, index, imei, alarm);
diff --git a/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java b/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java
index 34f30b147..74587c8b1 100644
--- a/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,11 @@ package org.traccar.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.DataConverter;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
@@ -29,12 +31,15 @@ public class T800xProtocolEncoder extends BaseProtocolEncoder {
public static final int MODE_BROADCAST = 0x02;
public static final int MODE_FORWARD = 0x03;
- private ByteBuf encodeContent(Command command, String content) {
+ public T800xProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
+ private ByteBuf encodeContent(Command command, short header, String content) {
ByteBuf buf = Unpooled.buffer();
- buf.writeByte('%');
- buf.writeByte('%');
+ buf.writeShort(header);
buf.writeByte(T800xProtocolDecoder.MSG_COMMAND);
buf.writeShort(7 + 8 + 1 + content.length());
buf.writeShort(1); // serial number
@@ -46,11 +51,16 @@ public class T800xProtocolEncoder extends BaseProtocolEncoder {
}
@Override
- protected Object encodeCommand(Command command) {
+ protected Object encodeCommand(Channel channel, Command command) {
+
+ short header = T800xProtocolDecoder.DEFAULT_HEADER;
+ if (channel != null) {
+ header = channel.pipeline().get(T800xProtocolDecoder.class).getHeader();
+ }
switch (command.getType()) {
case Command.TYPE_CUSTOM:
- return encodeContent(command, command.getString(Command.KEY_DATA));
+ return encodeContent(command, header, command.getString(Command.KEY_DATA));
default:
return null;
}
diff --git a/src/main/java/org/traccar/protocol/TechTltProtocol.java b/src/main/java/org/traccar/protocol/TechTltProtocol.java
index 69a12532c..0cffb452d 100644
--- a/src/main/java/org/traccar/protocol/TechTltProtocol.java
+++ b/src/main/java/org/traccar/protocol/TechTltProtocol.java
@@ -29,7 +29,7 @@ public class TechTltProtocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new Ardi01ProtocolDecoder(TechTltProtocol.this));
+ pipeline.addLast(new TechTltProtocolDecoder(TechTltProtocol.this));
}
});
}
diff --git a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java
index bad289060..17f5c80fa 100644
--- a/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/TechTltProtocolDecoder.java
@@ -35,6 +35,15 @@ public class TechTltProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
+ private static final Pattern PATTERN_STATUS = new PatternBuilder()
+ .number("(d+),") // id
+ .text("INFOGPRS,")
+ .number("V Bat=(d+.d),") // battery
+ .number("TEMP=(d+),") // temperature
+ .expression("[^,]*,")
+ .number("(d+)") // rssi
+ .compile();
+
private static final Pattern PATTERN_POSITION = new PatternBuilder()
.number("(d+)") // id
.text("*POS=Y,")
@@ -52,11 +61,33 @@ public class TechTltProtocolDecoder extends BaseProtocolDecoder {
.number("(d+)") // cid
.compile();
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ private Position decodeStatus(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_POSITION, (String) msg);
+ Parser parser = new Parser(PATTERN_STATUS, 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());
+
+ getLastLocation(position, null);
+
+ position.set(Position.KEY_BATTERY, parser.nextDouble());
+ position.set(Position.KEY_DEVICE_TEMP, parser.nextInt());
+ position.set(Position.KEY_RSSI, parser.nextInt());
+
+ return position;
+ }
+
+ private Position decodeLocation(Channel channel, SocketAddress remoteAddress, String sentence) {
+
+ Parser parser = new Parser(PATTERN_POSITION, sentence);
if (!parser.matches()) {
return null;
}
@@ -84,4 +115,18 @@ public class TechTltProtocolDecoder extends BaseProtocolDecoder {
return position;
}
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ String sentence = ((String) msg).trim();
+ if (sentence.contains("INFO")) {
+ return decodeStatus(channel, remoteAddress, sentence);
+ } else if (sentence.contains("POS")) {
+ return decodeLocation(channel, remoteAddress, sentence);
+ } else {
+ return null;
+ }
+ }
+
}
diff --git a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java
index 6d5e8f21e..457687b2e 100644
--- a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2014 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,8 +42,8 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder {
.number("(dd)(dd)(dd)") // date (ddmmyy)
.number("(dd)(dd)(dd),") // time (hhmmss)
.groupBegin()
- .number("(ddd)(dd)(dddd),") // longitude
- .number("(dd)(dd)(dddd),") // latitude
+ .number("(-?d{9}),") // longitude
+ .number("(-?d{8}),") // latitude
.or()
.number("(-?d+),") // longitude
.number("(-?d+),") // latitude
@@ -88,17 +88,16 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- Position position = new Position(getProtocolName());
-
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
return null;
}
+
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
- int event = parser.nextInt(0);
+ int event = parser.nextInt();
position.set(Position.KEY_EVENT, event);
-
position.set(Position.KEY_ALARM, decodeAlarm(event));
if (event == 11) {
@@ -109,25 +108,22 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder {
position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS));
- if (parser.hasNext(6)) {
- position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN));
- position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_MIN_MIN));
+ if (parser.hasNext(2)) {
+ position.setLongitude(parser.nextDouble() / 1000000);
+ position.setLatitude(parser.nextDouble() / 1000000);
}
if (parser.hasNext(2)) {
- position.setLongitude(parser.nextDouble(0) / 10000);
- position.setLatitude(parser.nextDouble(0) / 10000);
+ position.setLongitude(parser.nextDouble() / 10000);
+ position.setLatitude(parser.nextDouble() / 10000);
}
- position.setValid(parser.nextInt(0) != 1);
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
- position.setCourse(parser.nextDouble(0));
-
- if (parser.hasNext()) {
- position.set(Position.KEY_SATELLITES, parser.nextInt(0));
- }
+ position.setValid(parser.nextInt() != 1);
+ position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble()));
+ position.setCourse(parser.nextDouble());
- position.set(Position.KEY_BATTERY, parser.nextInt(0));
+ position.set(Position.KEY_SATELLITES, parser.nextInt());
+ position.set(Position.KEY_BATTERY, parser.nextInt());
return position;
}
diff --git a/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java
index 4d4d79d8d..c30fee6e3 100644
--- a/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java
+++ b/src/main/java/org/traccar/protocol/TeltonikaFrameDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,12 +29,14 @@ public class TeltonikaFrameDecoder extends BaseFrameDecoder {
protected Object decode(
ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {
- // Check minimum length
+ while (buf.isReadable() && buf.getByte(buf.readerIndex()) == (byte) 0xff) {
+ buf.skipBytes(1);
+ }
+
if (buf.readableBytes() < MESSAGE_MINIMUM_LENGTH) {
return null;
}
- // Read packet
int length = buf.getUnsignedShort(buf.readerIndex());
if (length > 0) {
if (buf.readableBytes() >= (length + 2)) {
diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java
index eef9662d7..5817b86be 100644
--- a/src/main/java/org/traccar/protocol/TeltonikaProtocol.java
+++ b/src/main/java/org/traccar/protocol/TeltonikaProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,14 +29,14 @@ public class TeltonikaProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new TeltonikaFrameDecoder());
- pipeline.addLast(new TeltonikaProtocolEncoder());
+ pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this));
pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false));
}
});
addServer(new TrackerServer(true, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
- pipeline.addLast(new TeltonikaProtocolEncoder());
+ pipeline.addLast(new TeltonikaProtocolEncoder(TeltonikaProtocol.this));
pipeline.addLast(new TeltonikaProtocolDecoder(TeltonikaProtocol.this, true));
}
});
diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java
index 485df833a..c634d2438 100644
--- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java
@@ -157,7 +157,19 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
}
if (readable) {
- position.set(Position.KEY_RESULT, buf.readSlice(length).toString(StandardCharsets.US_ASCII));
+ String data = buf.readSlice(length).toString(StandardCharsets.US_ASCII).trim();
+ if (data.startsWith("UUUUww") && data.endsWith("SSS")) {
+ String[] values = data.substring(6, data.length() - 4).split(";");
+ for (int i = 0; i < 8; i++) {
+ position.set("axle" + (i + 1), Double.parseDouble(values[i]));
+ }
+ position.set("loadTruck", Double.parseDouble(values[8]));
+ position.set("loadTrailer", Double.parseDouble(values[9]));
+ position.set("totalTruck", Double.parseDouble(values[10]));
+ position.set("totalTrailer", Double.parseDouble(values[11]));
+ } else {
+ position.set(Position.KEY_RESULT, data);
+ }
} else {
position.set(Position.KEY_RESULT, ByteBufUtil.hexDump(buf.readSlice(length)));
}
diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolEncoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolEncoder.java
index 5380cf3a0..8a614618a 100644
--- a/src/main/java/org/traccar/protocol/TeltonikaProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolEncoder.java
@@ -19,6 +19,7 @@ import org.traccar.BaseProtocolEncoder;
import org.traccar.helper.Checksum;
import org.traccar.helper.DataConverter;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -27,6 +28,10 @@ import java.nio.charset.StandardCharsets;
public class TeltonikaProtocolEncoder extends BaseProtocolEncoder {
+ public TeltonikaProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private ByteBuf encodeContent(byte[] content) {
ByteBuf buf = Unpooled.buffer();
diff --git a/src/main/java/org/traccar/protocol/Tk103Protocol.java b/src/main/java/org/traccar/protocol/Tk103Protocol.java
index fa83133e2..ff0bedfb7 100644
--- a/src/main/java/org/traccar/protocol/Tk103Protocol.java
+++ b/src/main/java/org/traccar/protocol/Tk103Protocol.java
@@ -1,6 +1,6 @@
/*
* Copyright 2017 Christoph Krey (c@ckrey.de)
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ public class Tk103Protocol extends BaseProtocol {
pipeline.addLast(new Tk103FrameDecoder());
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new Tk103ProtocolEncoder());
+ pipeline.addLast(new Tk103ProtocolEncoder(Tk103Protocol.this));
pipeline.addLast(new Tk103ProtocolDecoder(Tk103Protocol.this));
}
});
@@ -60,7 +60,7 @@ public class Tk103Protocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new Tk103ProtocolEncoder());
+ pipeline.addLast(new Tk103ProtocolEncoder(Tk103Protocol.this));
pipeline.addLast(new Tk103ProtocolDecoder(Tk103Protocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java
index 98edc8cb5..a8aa84105 100644
--- a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java
@@ -1,6 +1,6 @@
/*
* Copyright 2017 Christoph Krey (c@ckrey.de)
- * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,16 +19,19 @@ package org.traccar.protocol;
import org.traccar.Context;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class Tk103ProtocolEncoder extends StringProtocolEncoder {
private final boolean forceAlternative;
- public Tk103ProtocolEncoder() {
+ public Tk103ProtocolEncoder(Protocol protocol) {
+ super(protocol);
this.forceAlternative = false;
}
- public Tk103ProtocolEncoder(boolean forceAlternative) {
+ public Tk103ProtocolEncoder(Protocol protocol, boolean forceAlternative) {
+ super(protocol);
this.forceAlternative = forceAlternative;
}
@@ -40,7 +43,7 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder {
protected Object encodeCommand(Command command) {
boolean alternative = forceAlternative || Context.getIdentityManager().lookupAttributeBoolean(
- command.getDeviceId(), "tk103.alternative", false, true);
+ command.getDeviceId(), getProtocolName() + ".alternative", false, false, true);
initDevicePassword(command, "123456");
diff --git a/src/main/java/org/traccar/protocol/TotemProtocol.java b/src/main/java/org/traccar/protocol/TotemProtocol.java
index 66e1ec4f1..f8cda8358 100644
--- a/src/main/java/org/traccar/protocol/TotemProtocol.java
+++ b/src/main/java/org/traccar/protocol/TotemProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ public class TotemProtocol extends BaseProtocol {
pipeline.addLast(new TotemFrameDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new TotemProtocolEncoder());
+ pipeline.addLast(new TotemProtocolEncoder(TotemProtocol.this));
pipeline.addLast(new TotemProtocolDecoder(TotemProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java
index b5049859d..3bbb92031 100644
--- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java
@@ -1,6 +1,6 @@
/*
* Copyright 2015 Irving Gonzalez
- * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,9 +18,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class TotemProtocolEncoder extends StringProtocolEncoder {
+ public TotemProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java b/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java
index aaaaccb60..e4c94dc77 100644
--- a/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java
+++ b/src/main/java/org/traccar/protocol/TramigoFrameDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ public class TramigoFrameDecoder extends BaseFrameDecoder {
length = buf.getUnsignedShort(buf.readerIndex() + 6);
}
- if (length >= buf.readableBytes()) {
+ if (length <= buf.readableBytes()) {
return buf.readRetainedSlice(length);
}
diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java
index b63385187..05312b820 100644
--- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,8 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder {
private static final Pattern PATTERN = new PatternBuilder()
.expression("[A-Z]{2,3}")
- .number("APdd")
+ .expression("[A-Z]P")
+ .number("dd")
.number("(dd)(dd)(dd)") // date (yymmdd)
.expression("([AV])") // validity
.number("(dd)(dd.d+)") // latitude
@@ -57,7 +58,8 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder {
.number("(ddd)") // battery
.number("(d)") // acc
.number("(dd)") // arm status
- .number("(dd),") // working mode
+ .number("(dd)") // working mode
+ .number("(?:[0-2]{3})?,")
.number("(d+),") // mcc
.number("(d+),") // mnc
.number("(d+),") // lac
@@ -181,7 +183,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder {
return position;
- } else if (type.equals("AP01") || type.equals("AP10")) {
+ } else if (type.equals("AP01") || type.equals("AP10") || type.equals("YP03")) {
Parser parser = new Parser(PATTERN, sentence);
if (!parser.matches()) {
diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java
index 87b44a4b2..4f6854098 100644
--- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import org.traccar.DeviceSession;
import org.traccar.Protocol;
import org.traccar.helper.BitUtil;
import org.traccar.helper.DateBuilder;
+import org.traccar.helper.UnitsConverter;
import org.traccar.model.CellTower;
import org.traccar.model.Network;
import org.traccar.model.Position;
@@ -67,7 +68,17 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder {
return false;
}
- position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+ if (hardware == 0x413) {
+ buf.readUnsignedByte(); // status
+ } else {
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+ }
+
+ if (hardware == 0x413) {
+ position.setFixTime(new DateBuilder()
+ .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
+ .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate());
+ }
double lat;
double lon;
@@ -80,25 +91,39 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder {
lon = buf.readUnsignedInt() / 100000.0 / 60.0;
}
- position.setFixTime(new DateBuilder()
- .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
- .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate());
+ if (hardware == 0x413) {
- position.setSpeed(buf.readUnsignedShort() * 0.01);
+ position.set(Position.KEY_HDOP, buf.readUnsignedShort() * 0.1);
- position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium());
+ position.setAltitude(buf.readUnsignedShort());
+ position.setCourse(buf.readUnsignedShort());
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1));
+
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
+
+ } else {
+
+ position.setFixTime(new DateBuilder()
+ .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
+ .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate());
+
+ position.setSpeed(buf.readUnsignedShort() * 0.01);
+
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium());
+
+ int flags = buf.readUnsignedShort();
+ position.setCourse(BitUtil.to(flags, 9));
+ if (!BitUtil.check(flags, 10)) {
+ lat = -lat;
+ }
+ position.setLatitude(lat);
+ if (BitUtil.check(flags, 9)) {
+ lon = -lon;
+ }
+ position.setLongitude(lon);
+ position.setValid(BitUtil.check(flags, 11));
- int flags = buf.readUnsignedShort();
- position.setCourse(BitUtil.to(flags, 9));
- if (!BitUtil.check(flags, 10)) {
- lat = -lat;
- }
- position.setLatitude(lat);
- if (BitUtil.check(flags, 9)) {
- lon = -lon;
}
- position.setLongitude(lon);
- position.setValid(BitUtil.check(flags, 11));
buf.readerIndex(blockEnd);
diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java
index 0a2a59e23..7fec0bf8b 100644
--- a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java
@@ -237,12 +237,13 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder {
case DATA_GPS:
hasLocation = true;
- position.setValid(true);
position.setLatitude(buf.readInt() / 1000000.0);
position.setLongitude(buf.readInt() / 1000000.0);
position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort()));
position.setCourse(buf.readUnsignedShort());
- position.set(Position.KEY_HDOP, buf.readUnsignedShort());
+ int hdop = buf.readUnsignedShort();
+ position.setValid(hdop < 9999);
+ position.set(Position.KEY_HDOP, hdop * 0.01);
break;
case DATA_LBS:
diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java
index dc7a9200d..873b22006 100644
--- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -89,6 +89,13 @@ public class UproProtocolDecoder extends BaseProtocolDecoder {
}
}
+ private String decodeAlarm(int alarm) {
+ if (BitUtil.check(alarm, 2)) {
+ return Position.ALARM_TAMPERING;
+ }
+ return null;
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -160,9 +167,25 @@ public class UproProtocolDecoder extends BaseProtocolDecoder {
position.setSpeed(
Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1);
break;
+ case 'G':
+ position.setAltitude(
+ Integer.parseInt(data.readSlice(6).toString(StandardCharsets.US_ASCII)) * 0.1);
+ break;
case 'K':
position.set("statusExtended", data.toString(StandardCharsets.US_ASCII));
break;
+ case 'M':
+ position.set(Position.KEY_BATTERY_LEVEL,
+ Integer.parseInt(data.readSlice(3).toString(StandardCharsets.US_ASCII)) * 0.1);
+ break;
+ case 'N':
+ position.set(Position.KEY_RSSI,
+ Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII)));
+ break;
+ case 'O':
+ position.set(Position.KEY_SATELLITES,
+ Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII)));
+ break;
case 'P':
if (data.readableBytes() >= 16) {
position.setNetwork(new Network(CellTower.from(
@@ -188,25 +211,53 @@ public class UproProtocolDecoder extends BaseProtocolDecoder {
case 'S':
position.set("obdTraffic", ByteBufUtil.hexDump(data));
break;
- case 'T':
- position.set(Position.KEY_BATTERY_LEVEL,
- Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII)));
- break;
case 'V':
position.set(Position.KEY_POWER,
Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1);
break;
+ case 'W':
+ position.set(Position.KEY_ALARM,
+ decodeAlarm(Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))));
+ break;
+ case 'X':
+ Network network = new Network();
+ int mcc = 0, mnc = 0;
+ String[] cells = data.toString(StandardCharsets.US_ASCII).split(";");
+ if (!cells[0].startsWith("(")) {
+ for (int i = 0; i < cells.length; i++) {
+ String[] values = cells[i].split(",");
+ int index = 0;
+ if (i == 0) {
+ mcc = Integer.parseInt(values[index++]);
+ mnc = Integer.parseInt(values[index++]);
+ }
+ network.addCellTower(CellTower.from(
+ mcc, mnc,
+ Integer.parseInt(values[index++]),
+ Integer.parseInt(values[index++]),
+ Integer.parseInt(values[index])));
+ }
+ position.setNetwork(network);
+ }
+ break;
+ case 'Y':
+ position.set(Position.KEY_POWER,
+ Integer.parseInt(data.readSlice(5).toString(StandardCharsets.US_ASCII)) * 0.001);
+ break;
default:
break;
}
}
- if (position.getLatitude() != 0 && position.getLongitude() != 0) {
- return position;
+ if (position.getLatitude() == 0 || position.getLongitude() == 0) {
+ if (position.getAttributes().isEmpty()) {
+ return null;
+ }
+ getLastLocation(position, position.getDeviceTime());
}
- return null;
+ return position;
}
}
diff --git a/src/main/java/org/traccar/protocol/WatchProtocol.java b/src/main/java/org/traccar/protocol/WatchProtocol.java
index fe285e70d..6dc3bf9fb 100644
--- a/src/main/java/org/traccar/protocol/WatchProtocol.java
+++ b/src/main/java/org/traccar/protocol/WatchProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@ public class WatchProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new WatchFrameDecoder());
- pipeline.addLast(new WatchProtocolEncoder());
+ pipeline.addLast(new WatchProtocolEncoder(WatchProtocol.this));
pipeline.addLast(new WatchProtocolDecoder(WatchProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java
index 70b207e9b..0647afdee 100644
--- a/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/WatchProtocolDecoder.java
@@ -249,8 +249,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
}
}
- } else if (type.equals("UD") || type.equals("UD2") || type.equals("UD3")
- || type.equals("AL") || type.equals("WT")) {
+ } else if (type.startsWith("UD") || type.equals("AL") || type.equals("WT")) {
Position position = decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII));
@@ -267,7 +266,10 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
sendResponse(channel, id, index, "TKQ");
- } else if (type.equals("PULSE") || type.equals("heart") || type.equals("bphrt")) {
+ } else if (type.equalsIgnoreCase("PULSE")
+ || type.equalsIgnoreCase("HEART")
+ || type.equalsIgnoreCase("BLOOD")
+ || type.equalsIgnoreCase("BPHRT")) {
if (buf.isReadable()) {
@@ -279,11 +281,14 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
String[] values = buf.toString(StandardCharsets.US_ASCII).split(",");
int valueIndex = 0;
- if (type.equals("bphrt")) {
+ if (type.equalsIgnoreCase("BPHRT") || type.equalsIgnoreCase("BLOOD")) {
position.set("pressureHigh", values[valueIndex++]);
position.set("pressureLow", values[valueIndex++]);
}
- position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[valueIndex]));
+
+ if (valueIndex <= values.length - 1) {
+ position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[valueIndex]));
+ }
return position;
diff --git a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java
index 264aec81f..b433dfd2a 100644
--- a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import io.netty.channel.Channel;
import org.traccar.StringProtocolEncoder;
import org.traccar.helper.DataConverter;
import org.traccar.model.Command;
+import org.traccar.Protocol;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
@@ -32,6 +33,10 @@ import java.util.TimeZone;
public class WatchProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter {
+ public WatchProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
public String formatValue(String key, Object value) {
if (key.equals(Command.KEY_TIMEZONE)) {
diff --git a/src/main/java/org/traccar/protocol/WialonProtocol.java b/src/main/java/org/traccar/protocol/WialonProtocol.java
index 06b54dceb..fd183dd2c 100644
--- a/src/main/java/org/traccar/protocol/WialonProtocol.java
+++ b/src/main/java/org/traccar/protocol/WialonProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,14 +38,31 @@ public class WialonProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new LineBasedFrameDecoder(4 * 1024));
- pipeline.addLast(new StringEncoder());
boolean utf8 = Context.getConfig().getBoolean(getName() + ".utf8");
if (utf8) {
+ pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8));
pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8));
} else {
+ pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
}
- pipeline.addLast(new WialonProtocolEncoder());
+ pipeline.addLast(new WialonProtocolEncoder(WialonProtocol.this));
+ pipeline.addLast(new WialonProtocolDecoder(WialonProtocol.this));
+ }
+ });
+ addServer(new TrackerServer(true, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast(new LineBasedFrameDecoder(4 * 1024));
+ boolean utf8 = Context.getConfig().getBoolean(getName() + ".utf8");
+ if (utf8) {
+ pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8));
+ pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8));
+ } else {
+ pipeline.addLast(new StringEncoder());
+ pipeline.addLast(new StringDecoder());
+ }
+ pipeline.addLast(new WialonProtocolEncoder(WialonProtocol.this));
pipeline.addLast(new WialonProtocolDecoder(WialonProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java
index 42ff3177e..8488ca2d1 100644
--- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java
@@ -38,6 +38,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
+ private static final Pattern PATTERN_ANY = new PatternBuilder()
+ .expression("([^#]*)?") // imei
+ .text("#") // start byte
+ .expression("([^#]+)") // type
+ .text("#") // separator
+ .expression("(.*)") // message
+ .compile();
+
private static final Pattern PATTERN = new PatternBuilder()
.number("(dd)(dd)(dd);") // date (ddmmyy)
.number("(dd)(dd)(dd);") // time (hhmmss)
@@ -62,7 +70,8 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
private void sendResponse(Channel channel, SocketAddress remoteAddress, String type, Integer number) {
if (channel != null) {
StringBuilder response = new StringBuilder("#A");
- response.append(type.substring(1));
+ response.append(type);
+ response.append("#");
if (number != null) {
response.append(number);
}
@@ -71,9 +80,9 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
}
}
- private Position decodePosition(Channel channel, SocketAddress remoteAddress, String substring) {
+ private Position decodePosition(Channel channel, SocketAddress remoteAddress, String id, String substring) {
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id);
if (deviceSession == null) {
return null;
}
@@ -135,12 +144,20 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
String sentence = (String) msg;
- String type = sentence.substring(0, sentence.indexOf('#', 1) + 1);
+
+ Parser parser = new Parser(PATTERN_ANY, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ String id = parser.next();
+ String type = parser.next();
+ String data = parser.next();
switch (type) {
- case "#L#":
- String[] values = sentence.substring(3).split(";");
+ case "L":
+ String[] values = data.split(";");
String imei = values[0].indexOf('.') >= 0 ? values[1] : values[0];
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
@@ -149,14 +166,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
}
break;
- case "#P#":
+ case "P":
sendResponse(channel, remoteAddress, type, null); // heartbeat
break;
- case "#D#":
- case "#SD#":
+ case "D":
+ case "SD":
Position position = decodePosition(
- channel, remoteAddress, sentence.substring(sentence.indexOf('#', 1) + 1));
+ channel, remoteAddress, id, data);
if (position != null) {
sendResponse(channel, remoteAddress, type, 1);
@@ -164,12 +181,12 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
}
break;
- case "#B#":
- String[] messages = sentence.substring(sentence.indexOf('#', 1) + 1).split("\\|");
+ case "B":
+ String[] messages = data.split("\\|");
List<Position> positions = new LinkedList<>();
for (String message : messages) {
- position = decodePosition(channel, remoteAddress, message);
+ position = decodePosition(channel, remoteAddress, id, message);
if (position != null) {
position.set(Position.KEY_ARCHIVE, true);
positions.add(position);
@@ -182,14 +199,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
}
break;
- case "#M#":
- deviceSession = getDeviceSession(channel, remoteAddress);
+ case "M":
+ deviceSession = getDeviceSession(channel, remoteAddress, id);
if (deviceSession != null) {
position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
getLastLocation(position, new Date());
position.setValid(false);
- position.set(Position.KEY_RESULT, sentence.substring(sentence.indexOf('#', 1) + 1));
+ position.set(Position.KEY_RESULT, data);
sendResponse(channel, remoteAddress, type, 1);
return position;
}
diff --git a/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java b/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java
index 9ff1631eb..c45edf00d 100644
--- a/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
* Copyright 2016 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,9 +18,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class WialonProtocolEncoder extends StringProtocolEncoder {
+ public WialonProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
switch (command.getType()) {
diff --git a/src/main/java/org/traccar/protocol/WondexProtocol.java b/src/main/java/org/traccar/protocol/WondexProtocol.java
index 8c6283d66..035dd9160 100644
--- a/src/main/java/org/traccar/protocol/WondexProtocol.java
+++ b/src/main/java/org/traccar/protocol/WondexProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@ import io.netty.handler.codec.string.StringEncoder;
public class WondexProtocol extends BaseProtocol {
public WondexProtocol() {
- setTextCommandEncoder(new WondexProtocolEncoder());
setSupportedCommands(
Command.TYPE_GET_DEVICE_STATUS,
Command.TYPE_GET_MODEM_STATUS,
@@ -33,12 +32,13 @@ public class WondexProtocol extends BaseProtocol {
Command.TYPE_POSITION_SINGLE,
Command.TYPE_GET_VERSION,
Command.TYPE_IDENTIFICATION);
+ setTextCommandEncoder(new WondexProtocolEncoder(this));
addServer(new TrackerServer(false, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new WondexFrameDecoder());
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new WondexProtocolEncoder());
+ pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this));
pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this));
}
});
@@ -46,7 +46,7 @@ public class WondexProtocol extends BaseProtocol {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new StringEncoder());
- pipeline.addLast(new WondexProtocolEncoder());
+ pipeline.addLast(new WondexProtocolEncoder(WondexProtocol.this));
pipeline.addLast(new WondexProtocolDecoder(WondexProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java
index f9e8eeb9b..e9bb23d15 100644
--- a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class WondexProtocolEncoder extends StringProtocolEncoder {
+ public WondexProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/XexunProtocol.java b/src/main/java/org/traccar/protocol/XexunProtocol.java
index 0005270fb..401844e7b 100644
--- a/src/main/java/org/traccar/protocol/XexunProtocol.java
+++ b/src/main/java/org/traccar/protocol/XexunProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@ public class XexunProtocol extends BaseProtocol {
}
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new XexunProtocolEncoder());
+ pipeline.addLast(new XexunProtocolEncoder(XexunProtocol.this));
pipeline.addLast(new XexunProtocolDecoder(XexunProtocol.this, full));
}
});
diff --git a/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java b/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java
index 515cfbbd0..fc849fe15 100644
--- a/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/XexunProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class XexunProtocolEncoder extends StringProtocolEncoder {
+ public XexunProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/XirgoProtocol.java b/src/main/java/org/traccar/protocol/XirgoProtocol.java
index 4979fda5d..1be5b6c4b 100644
--- a/src/main/java/org/traccar/protocol/XirgoProtocol.java
+++ b/src/main/java/org/traccar/protocol/XirgoProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ public class XirgoProtocol extends BaseProtocol {
pipeline.addLast(new CharacterDelimiterFrameDecoder(1024, "##"));
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new XirgoProtocolEncoder());
+ pipeline.addLast(new XirgoProtocolEncoder(XirgoProtocol.this));
pipeline.addLast(new XirgoProtocolDecoder(XirgoProtocol.this));
}
});
@@ -44,7 +44,7 @@ public class XirgoProtocol extends BaseProtocol {
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new StringEncoder());
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new XirgoProtocolEncoder());
+ pipeline.addLast(new XirgoProtocolEncoder(XirgoProtocol.this));
pipeline.addLast(new XirgoProtocolDecoder(XirgoProtocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java
index 08809307f..4d0cc314b 100644
--- a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java
@@ -266,7 +266,7 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder {
position.setValid(Integer.parseInt(values[i]) == 3);
break;
case "SI":
- position.set("iccid", values[i]);
+ position.set(Position.KEY_ICCID, values[i]);
break;
case "IG":
int ignition = Integer.parseInt(values[i]);
diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java
index dd5e30cca..aa85e9e0e 100644
--- a/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,14 @@ package org.traccar.protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class XirgoProtocolEncoder extends StringProtocolEncoder {
+ public XirgoProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
@Override
protected Object encodeCommand(Command command) {
diff --git a/src/main/java/org/traccar/protocol/Xrb28Protocol.java b/src/main/java/org/traccar/protocol/Xrb28Protocol.java
index b1f1c34fb..5d8af418b 100644
--- a/src/main/java/org/traccar/protocol/Xrb28Protocol.java
+++ b/src/main/java/org/traccar/protocol/Xrb28Protocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@ public class Xrb28Protocol extends BaseProtocol {
pipeline.addLast(new LineBasedFrameDecoder(1024));
pipeline.addLast(new StringEncoder(StandardCharsets.ISO_8859_1));
pipeline.addLast(new StringDecoder());
- pipeline.addLast(new Xrb28ProtocolEncoder());
+ pipeline.addLast(new Xrb28ProtocolEncoder(Xrb28Protocol.this));
pipeline.addLast(new Xrb28ProtocolDecoder(Xrb28Protocol.this));
}
});
diff --git a/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java
index 617639312..3e69af329 100644
--- a/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2018 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,9 +18,14 @@ package org.traccar.protocol;
import io.netty.channel.Channel;
import org.traccar.BaseProtocolEncoder;
import org.traccar.model.Command;
+import org.traccar.Protocol;
public class Xrb28ProtocolEncoder extends BaseProtocolEncoder {
+ public Xrb28ProtocolEncoder(Protocol protocol) {
+ super(protocol);
+ }
+
private String formatCommand(Command command, String content) {
return String.format("\u00ff\u00ff*SCOS,OM,%s,%s#\n", getUniqueId(command.getDeviceId()), content);
}
diff --git a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java
index 819011a50..c132f194b 100644
--- a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -59,7 +59,7 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
0x26, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x57, 0x58, 0x59, 0x5a, 0x6b, 0x6f, 0x7A,
0x7B, 0x7C, 0x7d, 0x7E, 0x7F, 0x80, 0x81, 0x82,
- 0x83, 0x84, 0x85, 0x86
+ 0x83, 0x84, 0x85, 0x86, 0xc8
};
int[] l4 = {
0x03, 0x06, 0x07, 0x08, 0x0e, 0x0f, 0x10, 0x11,
@@ -80,12 +80,13 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
TAG_LENGTH_MAP.put(i, 4);
}
TAG_LENGTH_MAP.put(0x95, 24);
+ TAG_LENGTH_MAP.put(0xD0, 21);
}
private static int getTagLength(int tag) {
Integer length = TAG_LENGTH_MAP.get(tag);
if (length == null) {
- throw new IllegalArgumentException("Unknown tag: " + tag);
+ throw new IllegalArgumentException(String.format("Unknown tag: 0x%02X", tag));
}
return length;
}
@@ -93,7 +94,7 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
private Map<Short, byte[]> formats = new HashMap<>();
public void setConfig(String configString) {
- Pattern pattern = Pattern.compile(":wycfg pcr\\[\\d+\\] ([0-9a-fA-F]{2})[0-9a-fA-F]{2}([0-9a-fA-F]+)");
+ 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), DataConverter.parseHex(matcher.group(2)));
@@ -119,7 +120,8 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
Position position = new Position(getProtocolName());
- for (byte tag : format) {
+ for (byte b : format) {
+ int tag = b & 0xFF;
switch (tag) {
case 0x03:
DeviceSession deviceSession = getDeviceSession(
@@ -177,6 +179,14 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder {
case 0x65:
position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII));
break;
+ case 0x6C:
+ buf.readUnsignedByte(); // mil
+ int ecuCount = buf.readUnsignedByte();
+ for (int i = 0; i < ecuCount; i++) {
+ buf.readUnsignedByte(); // ecu id
+ buf.skipBytes(buf.readUnsignedByte() * 6);
+ }
+ break;
case 0x73:
position.set(Position.KEY_VERSION_FW, buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim());
break;
diff --git a/src/main/java/org/traccar/reports/Stops.java b/src/main/java/org/traccar/reports/Stops.java
index 98c9cef00..2036b0641 100644
--- a/src/main/java/org/traccar/reports/Stops.java
+++ b/src/main/java/org/traccar/reports/Stops.java
@@ -43,7 +43,7 @@ public final class Stops {
private static Collection<StopReport> detectStops(long deviceId, Date from, Date to) throws SQLException {
boolean ignoreOdometer = Context.getDeviceManager()
- .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true);
+ .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true);
IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class);
DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class);
diff --git a/src/main/java/org/traccar/reports/Summary.java b/src/main/java/org/traccar/reports/Summary.java
index 9810424d8..6d179a873 100644
--- a/src/main/java/org/traccar/reports/Summary.java
+++ b/src/main/java/org/traccar/reports/Summary.java
@@ -61,7 +61,7 @@ public final class Summary {
result.setMaxSpeed(position.getSpeed());
}
boolean ignoreOdometer = Context.getDeviceManager()
- .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true);
+ .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true);
result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer));
result.setAverageSpeed(speedSum / positions.size());
result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition));
diff --git a/src/main/java/org/traccar/reports/Trips.java b/src/main/java/org/traccar/reports/Trips.java
index 3cda65553..7c0cd6921 100644
--- a/src/main/java/org/traccar/reports/Trips.java
+++ b/src/main/java/org/traccar/reports/Trips.java
@@ -42,7 +42,7 @@ public final class Trips {
private static Collection<TripReport> detectTrips(long deviceId, Date from, Date to) throws SQLException {
boolean ignoreOdometer = Context.getDeviceManager()
- .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, true);
+ .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true);
IdentityManager identityManager = Main.getInjector().getInstance(IdentityManager.class);
DeviceManager deviceManager = Main.getInjector().getInstance(DeviceManager.class);
diff --git a/src/test/java/org/traccar/TestIdentityManager.java b/src/test/java/org/traccar/TestIdentityManager.java
index 0f7405dbd..af5dd22df 100644
--- a/src/test/java/org/traccar/TestIdentityManager.java
+++ b/src/test/java/org/traccar/TestIdentityManager.java
@@ -30,6 +30,11 @@ public final class TestIdentityManager implements IdentityManager {
}
@Override
+ public String getDevicePassword(long id, String protocol, String defaultPassword) {
+ return defaultPassword;
+ }
+
+ @Override
public Position getLastPosition(long deviceId) {
return null;
}
@@ -41,31 +46,31 @@ public final class TestIdentityManager implements IdentityManager {
@Override
public boolean lookupAttributeBoolean(
- long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) {
+ long deviceId, String attributeName, boolean defaultValue, boolean lookupServer, boolean lookupConfig) {
return defaultValue;
}
@Override
public String lookupAttributeString(
- long deviceId, String attributeName, String defaultValue, boolean lookupConfig) {
+ long deviceId, String attributeName, String defaultValue, boolean lookupServer, boolean lookupConfig) {
return "alarm,result";
}
@Override
public int lookupAttributeInteger(
- long deviceId, String attributeName, int defaultValue, boolean lookupConfig) {
+ long deviceId, String attributeName, int defaultValue, boolean lookupServer, boolean lookupConfig) {
return defaultValue;
}
@Override
public long lookupAttributeLong(
- long deviceId, String attributeName, long defaultValue, boolean lookupConfig) {
+ long deviceId, String attributeName, long defaultValue, boolean lookupServer, boolean lookupConfig) {
return defaultValue;
}
@Override
public double lookupAttributeDouble(
- long deviceId, String attributeName, double defaultValue, boolean lookupConfig) {
+ long deviceId, String attributeName, double defaultValue, boolean lookupServer, boolean lookupConfig) {
return defaultValue;
}
diff --git a/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java
index cb0a31ceb..fd6214c57 100644
--- a/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/AdmProtocolEncoderTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 - 2019 Anton Tananaev (anton@traccar.org)
* Copyright 2017 Anatoliy Golubev (darth.naihil@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,7 +27,7 @@ public class AdmProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- AdmProtocolEncoder encoder = new AdmProtocolEncoder();
+ AdmProtocolEncoder encoder = new AdmProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/AquilaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AquilaProtocolDecoderTest.java
index 793b2c646..489024ed5 100644
--- a/src/test/java/org/traccar/protocol/AquilaProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/AquilaProtocolDecoderTest.java
@@ -51,29 +51,4 @@ public class AquilaProtocolDecoderTest extends ProtocolTest {
}
- @Test
- public void testDecodeB() throws Exception {
-
- AquilaProtocolDecoder decoder = new AquilaProtocolDecoder(null);
-
- verifyPosition(decoder, text(
- "$Header,nliven,EMR,861693034634154,NM,09112017155133,A,12.976495,N,77.549713,E,906.0,0.0,23,G,KA01I2000,+919844098440*4B"));
-
- verifyPosition(decoder, text(
- "$EPB,iTriangle1,EMR,864495034445822,SP,03082018110730,A,22.829292,N,75.935806,E,543.0,0.0,0,G,KA01G1234,+9164061023*13"));
-
- verifyPosition(decoder, text(
- "$Header,iTriangle,1_37T02B0164MAIS_2,NR,1,L,864495034490141,KA01I2000,1,19042018,102926,22.846401,N,75.948952,E,0.0,311,5,578.0,3.80,3.67,AirTel,0,1,12.5,4.3,1,C,14,404,93,0456,16db,29,ebd8,0458,28,3843,18ab,25,072e,18ab,22,35da,0458,0000,00,031181,0.0,0.0,0,()*34"));
-
- verifyPosition(decoder, text(
- "$Header,nliven,1_37T02B0164MAIS,BR,6,L,861693034634154,KA01I2000,1,09112017,160702,12.976593,N,77.549782,E,25.1,344,15,911.0,1.04,0.68,Airtel,1,1,11.8,3.8,1,C,24,404,45,61b4,9ad9,31,9adb,61b4,35,ffff,0000,33,ffff,0000,31,ffff,0000,0001,00,000014,0.0,0.1,4,()*1E"));
-
- verifyPosition(decoder, text(
- "$Header,iTriangle,1_37T02B0164MAIS_2,NR,1,L,864495034490141,KA01I2000,1,31032018,122247,22.845999,N,75.949005,E,0.0,44,16,545.0,1.19,0.65,AirTel,1,1,12.0,4.3,0,C,13,404,93,0456,16db,27,16dd,0456,22,3843,18ab,19,ebd8,0458,14,072c,18ab,0101,00,003735,0.0,0.0,0,()*48"));
-
- verifyNull(decoder, text(
- "$Header,nliven,KA01I2000,861693034634154,1_37T02B0164MAIS,AIS140,12.976545,N,77.549759,E*50"));
-
- }
-
}
diff --git a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java
index 3a9382086..6b3dc3010 100644
--- a/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/AtrackProtocolDecoderTest.java
@@ -11,6 +11,9 @@ public class AtrackProtocolDecoderTest extends ProtocolTest {
AtrackProtocolDecoder decoder = new AtrackProtocolDecoder(null);
verifyPositions(decoder, buffer(
+ "@P,93D1,419,0,357766091026083,1557178589,1557178590,1557178590,-121899637,37406241,338,230,2809,8,0,0,0,0,,2000,2000,\r\n"));
+
+ verifyPositions(decoder, buffer(
"@P,3A34,146,41431,353816057242284,20180622015809,20180622015809,20180622015809,9720689,4014230,61,2,0,20,1,0,0,0,0,2000,2000,12160,42,624,002,20009,20014,\r\n"));
verifyPositions(decoder, buffer(
@@ -96,4 +99,23 @@ public class AtrackProtocolDecoderTest extends ProtocolTest {
}
+ @Test
+ public void testDecodeCustom() throws Exception {
+
+ AtrackProtocolDecoder decoder = new AtrackProtocolDecoder(null);
+
+ decoder.setCustom(true);
+
+ decoder.setForm("%AT%BV%MV%SA%VN%PD%IA%MP%EL%ET%FC%FL%RP%ML%MF%TR%EH%DL%EG%HA%HB%HC%IP%MT");
+
+ verifyPositions(decoder, buffer(
+ "@P,7E02,186,0,357766091026083,1558908265,1558908266,1558908266,-121900220,37407524,175,2,6,6,1,39,0,0,,2000,2000, ,3,40,142,12,JN8AZ1MU1BW066090,0,30,0,58,90,22,72,1187,0,1232,9,409,0,1,0,0,0,0,1\r\n"));
+
+ decoder.setForm("%AT%BV%CD%CE%CM%CN%DT%GN%GQ%GS%GV%LC%ME%MV%RL%SA%SM%CS%HT%VN%PD%IA%MP%EL%ET%FC%FL%RP%ML%MF%TR%EH%CR%DL%EG%HA%HB%HC%IP%MT%PF");
+
+ verifyPositions(decoder, buffer(
+ "@P,DCCE,422,5818,357766091026083,1557904779,1557904780,1557904780,-121899644,37406291,129,2,21,10,0,0,0,0,,2000,2000,,13,40,8942310017000752067,21096194,295050910083206,310260,0,FF00001F0393FF01001E0395FF01001E0394FF01001F0393FF02001D0393FF00001F0394FF0100200394FF01001F0393FF02001F0395FF0100200394,20,10,002C005C03B4,14953,357766091026083,125,38,11,0,1,Device:Fail,JN8AZ1MU1BW066090,0,0,0,0,0,99,0,0,0,0,0,264,5,0,0,0,0,0,0,0,0\r\n"));
+
+ }
+
}
diff --git a/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java
index d3be0b6d6..71bc83b4f 100644
--- a/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/AvemaProtocolDecoderTest.java
@@ -2,6 +2,7 @@ package org.traccar.protocol;
import org.junit.Test;
import org.traccar.ProtocolTest;
+import org.traccar.model.Position;
public class AvemaProtocolDecoderTest extends ProtocolTest {
@@ -10,7 +11,14 @@ public class AvemaProtocolDecoderTest extends ProtocolTest {
AvemaProtocolDecoder decoder = new AvemaProtocolDecoder(null);
- verifyNull(decoder, text(
+ verifyAttribute(decoder, text(
+ "1000000000,20190527072358,121.646024,25.062135,0,0,0,0,10,0.0,1,0.02,12.32,0,0,15,2,466-5,10275,0,0.01,65EB812A000104E0,8000001234,NormanChang"),
+ Position.KEY_DRIVER_UNIQUE_ID, "65EB812A000104E0");
+
+ verifyNotNull(decoder, text(
+ "1000000000,20190522093835,121.645898,25.062268,0,0,0,0,3,0.0,1,0.02,11.48,0,0,19,4,466-5,65534,56589841,0.01"));
+
+ verifyNotNull(decoder, text(
"8,20180927150956,19.154864,49.124862,7,56,0,12,3,0.0,0,0.02,14.01,0,0,26,0,219-2,65534,10255884,0.01"));
verifyPosition(decoder, text(
diff --git a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java
index 40ffbe5a5..9801b56cc 100644
--- a/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/BceProtocolDecoderTest.java
@@ -13,6 +13,12 @@ public class BceProtocolDecoderTest extends ProtocolTest {
verifyNull(decoder, binary(
"3ab90b71bc1503000300c10bff11"));
+ verifyPositions(decoder, binary(
+ "cdc3440cf31403001902a58c0a06e0ceb0009f4e4452419417e0ceb08bc0ffcf428014463627b24018104b425b1c508b00d16a9743d188da6e0110ce001455069262002e4c5adabb810200418728157501004229460377000bb4d04b10c000ffff335aa800000000000000000000000000a912963d0042313130303030313236313432303031202020202020202020202020202020203f2946030301f70100007b0400009f130000762700000a26e0ceb06f074e4452419427e0ceb08bc0ffcf42801446ee28b240a40f4b425c1c518a00df414c42d188936eff0fce001455069262002e4c5adabb810200417b28157501004c294603770008b4d04b10c000ffff4c5a89000000000000000000000000009a2c8c3b004231313030303031323631343230303120202020202020202020202020202020492946030301f80100007c040000a9130000802700009477e0ceb08bc0ffcf42801446eb2fb2405c0d4b425d1c53830089e07e43d188a56eff0fce001455069262002eb35700bb810200415227167501007e294603780000b4d04b10c000ffff995700000000000000000000000000008bd9f43b004231313030303031323631343230303120202020202020202020202020202020802946030301fd01000081040000e0130000b72700000a86e0ceb064464e4452410a96e0ceb000a54e4452410aa6e0ceb000914e4452410ab6e0ceb068334e4452410ac6e0ceb0009f4e4452410ac6e0ceb06f074e445241f4"));
+
+ verifyPositions(decoder, binary(
+ "cc2c5792c6160300b000a5520aa6c813ae64465343513840a7c813ae0bc0fd800080040036093f427884ea41001c900e00000000009088c562a301024156d12a004c00006df80c0000000086fb0200562a08005a000000000ac6c813ae0091534351380af6c813ae009f534351380af6c813ae6f075343513840f7c813ae0bc0fd800080040036093f427884ea41001c900e00000000009088f162a301024156d12a004c00006df80c0000000086fb0200562a08005a000000003f"));
+
verifyPositions(decoder, false, binary(
"76145792c61603003402a59b59a7f722aa8ac00080c086000121800000280f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff000059f7f722aa8ac00080c086000121800000260f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff00000a16f822aa6f07534352325917f822aa8ac00080c086000120800000190f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff00005957f822aa8ac00080c086000121800000240f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff00000a66f822aa6f07534352325967f822aa8ac00080c086000121a00000160f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff000059b7f822aa8ac00080c086000121800000170f9401056804d181006222ea4201000000000000008081008081008081008081000022ea4201000000000000ffffffffffff00000000ffffffffffff00000000ffffffffffff0000ef"));
diff --git a/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java
index bdcc1f9e8..be5877193 100644
--- a/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/BceProtocolEncoderTest.java
@@ -9,8 +9,8 @@ public class BceProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- BceProtocolEncoder encoder = new BceProtocolEncoder();
-
+ BceProtocolEncoder encoder = new BceProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_OUTPUT_CONTROL);
diff --git a/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java
index 5ed3f5dc8..7640484d4 100644
--- a/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/CalAmpProtocolDecoderTest.java
@@ -11,6 +11,9 @@ public class CalAmpProtocolDecoderTest extends ProtocolTest {
CalAmpProtocolDecoder decoder = new CalAmpProtocolDecoder(null);
verifyPosition(decoder, binary(
+ "8308352648068863398f01070102039c5cfc4dcd5cfc4dcd19913f5dcce1291e000033fa0000005801110800019aff9d6f0e13003e0b02000000000000000000"));
+
+ verifyPosition(decoder, binary(
"83051633033459010101028afd59ae7c1459ae7c140b06bbce2c01520e0000d916000001b900450900005affa50f091f00260d040000000f24000001b90000000000003714"));
verifyPosition(decoder, binary(
diff --git a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java
index 27f503b34..3c35398a6 100644
--- a/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/CastelProtocolDecoderTest.java
@@ -2,6 +2,7 @@ package org.traccar.protocol;
import org.junit.Test;
import org.traccar.ProtocolTest;
+import org.traccar.model.Position;
public class CastelProtocolDecoderTest extends ProtocolTest {
@@ -10,6 +11,13 @@ public class CastelProtocolDecoderTest extends ProtocolTest {
CastelProtocolDecoder decoder = new CastelProtocolDecoder(null);
+ verifyAttribute(decoder, binary(
+ "40403a00043231334744503230313830323133343300000000a002000001000001012011004d414c43333831434d4b4d353637313438c8fc0d0a"),
+ Position.KEY_RESULT, "MALC381CMKM567148");
+
+ verifyAttributes(decoder, binary(
+ "404043000432313357503230313830303138323400000000004005f064d95c8365d95c9f2f0100c50200004006000000000000040003440068000000000100f3660d0a"));
+
verifyAttributes(decoder, binary(
"40403a00043231335750323031373030363135360000000000a00200000100000101201100344a474446364545374a4230373632363056ff0d0a"));
diff --git a/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java
index bcb93a010..1864d9e84 100644
--- a/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/CastelProtocolEncoderTest.java
@@ -9,8 +9,8 @@ public class CastelProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- CastelProtocolEncoder encoder = new CastelProtocolEncoder();
-
+ CastelProtocolEncoder encoder = new CastelProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_ENGINE_STOP);
diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java
index d3066aa2d..523ad1d5c 100644
--- a/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/CellocatorProtocolDecoderTest.java
@@ -11,6 +11,9 @@ public class CellocatorProtocolDecoderTest extends ProtocolTest {
CellocatorProtocolDecoder decoder = new CellocatorProtocolDecoder(null);
verifyPosition(decoder, binary(
+ "4d4347500bde66220048165400cb0000000000080600000124161400061300050402095501aaf8218787fcac390100010000070700013133150f07131905001e000100000293001e00697e6f24148240040000000083400400000000844004000000008540040000000086400400000000874004000000008840040000000089400400000000814004000000008c4004000000008d4004000000008e4004000000009140040000000090400400000000804004000000008a400400000000974004000000008b4004000000009d4004000000009b400400000000da"));
+
+ verifyPosition(decoder, binary(
"4D4347500BA9880B00880A3900EE00000000000806000001210A140002B6001E0034419B1B1900400401000000014004000000000240046000000003400480000000044004DA0A0000054004000000000640045E000000074004310000000840042B000000094004870000000B4004B10B00000C4004590000000D40040000000010400465000000114004780C000012400465650700144004A4000000154004207F000016400400000000174004000000001E4004000000001F40040000000020400400000000214004000000002440040000000006130003040211D67DA4F7883AAF028403000001000007070001250A1004090E1905001E0001000062"));
verifyPosition(decoder, binary(
diff --git a/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java
index 89850fb5f..616640116 100644
--- a/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/CellocatorProtocolEncoderTest.java
@@ -11,8 +11,8 @@ public class CellocatorProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- CellocatorProtocolEncoder encoder = new CellocatorProtocolEncoder();
-
+ CellocatorProtocolEncoder encoder = new CellocatorProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_OUTPUT_CONTROL);
diff --git a/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java
index 7c03b7d5b..f0eede4bf 100644
--- a/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/CityeasyProtocolEncoderTest.java
@@ -9,7 +9,7 @@ public class CityeasyProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- CityeasyProtocolEncoder encoder = new CityeasyProtocolEncoder();
+ CityeasyProtocolEncoder encoder = new CityeasyProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java
index ae5e9353c..8977cf194 100644
--- a/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/DmtProtocolDecoderTest.java
@@ -14,6 +14,9 @@ public class DmtProtocolDecoderTest extends ProtocolTest {
"0255003300001b00003335333232393032373533393235310038393931353030303030303030313330343539340000000403041910780603"));
verifyPositions(decoder, false, binary(
+ "025504ab013d00c21a00004829900c0300154929900cbd163617b08a94c7fa003c07032c131a0302080300000000000300060f019b14037e0e0463000558140607213d00c31a0000ca29900c030015ca29900ca3033817bbb895c71401be0603b310190302080300000000000300060f019b14036d0e0463000558140607213d00c41a0000472a900c030015472a900c8d453817423e96c7fa000200040013270302080300000000000300060f019b1403840e0463000546140606213d00c51a0000c52a900c030015c52a900c184c3817c35296c724010400050016180302080300000000000300060f019b1403750e0463000547140606213d00c61a0000462b900c030015462b900cbd8a361703b495c710018c07085a10210302080300000000000300060f019b1403630e0463000546140606213d00c71a0000c52b900c030015c52b900cf6d63517455a94c7e9004c05035a10240302080300000000000300060f019b14036e0e0463000545140606213d00c81a00004b2c900c0300154b2c900c766d3517ddf093c7320107000d00102e0302080300000000000300060f019b1403750e046300054314060521"));
+
+ verifyPositions(decoder, false, binary(
"02551040000eaca40d00d2b8e562c51f9912f39a6bee00007e420091090903070100000000008b1065360000000000007fd401c4fcf2feffffffffffffffffee0000003f1b"));
verifyPositions(decoder, false, binary(
diff --git a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java
index e3cff9525..e24da3173 100644
--- a/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/EelinkProtocolDecoderTest.java
@@ -14,6 +14,10 @@ public class EelinkProtocolDecoderTest extends ProtocolTest {
verifyNull(decoder, binary(
"454C0027E753035254407167747167670100180002035254407167747100200205020500010432000086BD"));
+ verifyAttribute(decoder, binary(
+ "6767070006000e0077035d"),
+ Position.KEY_IGNITION, true);
+
verifyAttributes(decoder, binary(
"676707006502df5c89fde800bc3fa8030302005555045b555555057a5555550b225555550c105c55550d115555550e7e5555550f4555555510017b5555112b5555551f01ed5555208005b0012100005555407ad000004237f5555589000000498a0000aef78b00000000"));
diff --git a/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java
index e4502f919..616ca0b52 100644
--- a/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/EelinkProtocolEncoderTest.java
@@ -13,9 +13,9 @@ public class EelinkProtocolEncoderTest extends ProtocolTest {
command.setDeviceId(1);
command.setType(Command.TYPE_ENGINE_STOP);
- verifyCommand(new EelinkProtocolEncoder(false), command, binary("676780000f0000010000000052454c41592c3123"));
+ verifyCommand(new EelinkProtocolEncoder(null, false), command, binary("676780000f0000010000000052454c41592c3123"));
- verifyCommand(new EelinkProtocolEncoder(true), command, binary("454c001eb41a0123456789012345676780000f0000010000000052454c41592c3123"));
+ verifyCommand(new EelinkProtocolEncoder(null, true), command, binary("454c001eb41a0123456789012345676780000f0000010000000052454c41592c3123"));
}
diff --git a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java
index 237c849c5..523d095f2 100644
--- a/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/EgtsFrameDecoderTest.java
@@ -14,6 +14,9 @@ public class EgtsFrameDecoderTest extends ProtocolTest {
binary("0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2"),
decoder.decode(null, null, binary("0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2")));
+ verifyFrame(
+ binary("0100000b000300704300db0500006c27"),
+ decoder.decode(null, null, binary("0100000b000300704300db0500006c270100000b0003007143009d0600003c7e")));
}
}
diff --git a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java
index 2210893e7..2afb72e08 100644
--- a/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/EgtsProtocolDecoderTest.java
@@ -6,7 +6,30 @@ import org.traccar.ProtocolTest;
public class EgtsProtocolDecoderTest extends ProtocolTest {
@Test
- public void testDecode() throws Exception {
+ public void testDecodeWithObjectId() throws Exception {
+
+ EgtsProtocolDecoder decoder = new EgtsProtocolDecoder(null);
+
+ verifyNull(decoder, binary(
+ "0100020b002300020001871c00020000010105190000ab0800006247396e615734366347467a63336476636d513daadf"));
+
+ verifyPositions(decoder, binary(
+ "0100020b004600010001b81800030001f299c0d80202101500c9c52f1100552e9c80e4ca7911f5805b00000000031800040001f299c0d80202101500cbc52f1100612e9c00dbca79116c803e00000000037c13"));
+
+ verifyPositions(decoder, binary(
+ "0100020b005e01030001ed180005000162c72c9a0202101500c4c52f1100477e9f0047c979010000ad000000000318000600017ee0710c0202101500c9c52f11003ee59f8061e97a0100801b00000000031800070001b6eeb6c00202101500c7c52f110077669d00b9707a116a015600000000031800080001b6eeb6c00202101500cdc52f11007c669d004e717a117a0158000000000318000900018b4685f70202101500c8c52f11006ee09f0027ca7c11650079000000000318000a0001f299c0d80202101500c9c52f1100552e9c80e4ca7911f5805b000000000318000b0001f299c0d80202101500cbc52f1100612e9c00dbca79116c803e000000000318000c0001731347010202101500c7c52f1100a3699a80db3c7a010000e5000000000318000d0001c85285f70202101500cbc52f1100e8979900f3497b114d0101000000000318000e0001aa4358810202101500cdc52f11002d689a80ab427a0100009300000000032b9f"));
+
+ verifyNull(decoder, binary("0100000b0003006c430004010000acfb"));
+
+ verifyPositions(decoder, binary(
+ "0100000b0086035ddd016d18004f049579b000001e2fc11002021015001e2fc1107ac3919f59cc5c7a0b0000000000003000180050049579b00000242fc1100202101500242fc1100fb5919f2dbf5c7a0b0000000000003000180051049579b00000312fc1100202101500312fc110b899919f94cf5c7a0b00000000000030001e0052049579b00000ba62a2120202120900000003000000000000150500025c00000013070003000000000000180053049579b000004e2fc11002021015004e2fc11087ba919f8dd45c7a0b0000000000003000180054049579b00000552fc1100202101500552fc1106ecb919f2aec5c7a0b00000000000030001e0055049579b00000d562a2120202120900000003000000000000150500025c00000013070003000000000000180056049579b000005c2fc11002021015005c2fc11059d9919f54fa5c7a0b0000000000003000180057049579b000006e2fc11002021015006e2fc110309f919fc2db5c7a0b0000000000003000180058049579b00000762fc1100202101500762fc1104690919f94cf5c7a0b00000000000030001e0059049579b00000f662a2120202120900000003000000000000150500025c000000130700030000000000001e005a049579b000001463a2120202120900000003000000000000150500025c0000001307000300000000000018005b049579b00000b32fc1100202101500b32fc110c491919fa2c65c7a0b00000000000030001e005c049579b000003363a2120202120900000003000000000000150500025c0000001307000300000000000018005d049579b00000ca2fc1100202101500ca2fc11089b9919fd5f95c7a0b00000000000030001e005e049579b000005163a2120202120900000003000000000000150500025c000000130700030000000000001e005f049579b000006f63a2120202120900000003000000000000150500025c00000013070003000000000000180060049579b00000f42fc1100202101500f42fc11087ba919f43db5c7a0b0000000000003000180061049579b000000730c11002021015000730c110f9c3919fe1c65c7a0b0000000000003000180062049579b000000930c11002021015000930c1106ecb919f3ab65c7a0b00000000000030001e0063049579b000008d63a2120202120900000003000000000000150500025c00000013070003000000000000140064049579b00000ac63a2120202120900000003000000000000150500025c000000ce53"));
+
+ verifyNull(decoder, binary("0100000b00100091030072000100060000000002020003009203000009"));
+
+ }
+
+ @Test
+ public void testDecodeWithAuth() throws Exception {
EgtsProtocolDecoder decoder = new EgtsProtocolDecoder(null);
diff --git a/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java
index 16f00d69b..7bf4f844e 100644
--- a/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/EsealProtocolEncoderTest.java
@@ -11,7 +11,7 @@ public class EsealProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- EsealProtocolEncoder encoder = new EsealProtocolEncoder();
+ EsealProtocolEncoder encoder = new EsealProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java
index 11492fb6f..88a460854 100644
--- a/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/FifotrackProtocolDecoderTest.java
@@ -2,6 +2,7 @@ package org.traccar.protocol;
import org.junit.Test;
import org.traccar.ProtocolTest;
+import org.traccar.model.Position;
public class FifotrackProtocolDecoderTest extends ProtocolTest {
@@ -10,6 +11,17 @@ public class FifotrackProtocolDecoderTest extends ProtocolTest {
FifotrackProtocolDecoder decoder = new FifotrackProtocolDecoder(null);
+ verifyPosition(decoder, buffer(
+ "$$116,869270049149999,5,A01,4,190925080127,V,-15.804260,35.061506,0,0,1198,0,0,900000C0,02,0,650|10|12C|B24,18B|4C8|72,1,*01"));
+
+ verifyAttribute(decoder, buffer(
+ "$$123,869467049296388,B996,A01,2,190624131813,V,22.333746,113.590670,0,124,-1,26347,0,0004,00,0,460|0|2694|5A5D,174|0|0|0,B48CEB,*77"),
+ Position.KEY_ALARM, Position.ALARM_SOS);
+
+ verifyAttribute(decoder, buffer(
+ "$$125,869467049296388,548,A01,38,190619025856,A,22.333905,113.590261,0,12,60,16666,0,0000,00,0,460|0|2694|13F8,1A2|4C1|0|0,B4A067,*7A"),
+ Position.KEY_DRIVER_UNIQUE_ID, "11837543");
+
verifyNull(decoder, buffer(
"$$79,868345037864709,382,D05,190220085833,22.643210,114.018176,1,1,1,13152,23FFD339*25"));
diff --git a/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java
index 53ae8510a..b60313956 100644
--- a/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/FifotrackProtocolEncoderTest.java
@@ -11,8 +11,8 @@ public class FifotrackProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- FifotrackProtocolEncoder encoder = new FifotrackProtocolEncoder();
-
+ FifotrackProtocolEncoder encoder = new FifotrackProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_REQUEST_PHOTO);
diff --git a/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java
index 34423578d..6a68752bb 100644
--- a/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/GalileoProtocolEncoderTest.java
@@ -9,7 +9,7 @@ public class GalileoProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- GalileoProtocolEncoder encoder = new GalileoProtocolEncoder();
+ GalileoProtocolEncoder encoder = new GalileoProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java
index e2be99cb9..7e1ccb79d 100644
--- a/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/GatorProtocolDecoderTest.java
@@ -20,6 +20,9 @@ public class GatorProtocolDecoderTest extends ProtocolTest {
GatorProtocolDecoder decoder = new GatorProtocolDecoder(null);
verifyAttributes(decoder, binary(
+ "242480002600341cad190917022021812497260280594200000000c047010000135400009bb600ff00b90d"));
+
+ verifyAttributes(decoder, binary(
"2424800026364101b31608041108380273453415301532000000008000010000122800000124000000c40d"));
verifyNull(decoder, binary(
diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java
index 35a96a6cf..12e64cd6d 100644
--- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java
@@ -11,6 +11,13 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest {
Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(null);
+ verifyPositions(decoder, buffer(
+ "+RESP:GTFRI,423031,355154083021002,Bolt4G,0,0,0,0,1,1.0,0.2,0,245.3,-85.630193,42.975280,20190729185934,310,410,500b,B0E320F,31,-1,100,20190729185934,0010$"));
+
+ verifyAttribute(decoder, buffer(
+ "+RESP:GTCTN,440200,866427030007379,NOKIA3,0,0,2,,9,1,0.1,174,48.7,-1.061812,51.435270,20190717080549,0234,0015,0025,145A,,,0000,20190717081008,1D3B$"),
+ Position.KEY_BATTERY_LEVEL, 9);
+
verifyAttribute(decoder, buffer(
"+RESP:GTHBM,4B0101,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$"),
Position.KEY_ALARM, Position.ALARM_BRAKING);
@@ -203,7 +210,7 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest {
verifyPositions(decoder, buffer(
"+RESP:GTFRI,210102,A10000499AEF9B,,0,1,1,9,0.5,0,288.0,-76.902364,39.578828,20161101134124,,,,,00,73,20161101134123,009D$"));
- verifyAttributes(decoder, buffer(
+ verifyPositions(decoder, buffer(
"+RESP:GTRTL,210102,A10000499AEF9B,,0,0,1,10,0.2,0,305.4,-76.902274,39.578517,20161101155001,,,,,00,73,20161101155001,00A6$"));
verifyAttributes(decoder, buffer(
diff --git a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java
index 70c86bb23..2ad080219 100644
--- a/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/GoSafeProtocolDecoderTest.java
@@ -2,6 +2,7 @@ package org.traccar.protocol;
import org.junit.Test;
import org.traccar.ProtocolTest;
+import org.traccar.model.Position;
public class GoSafeProtocolDecoderTest extends ProtocolTest {
@@ -10,6 +11,18 @@ public class GoSafeProtocolDecoderTest extends ProtocolTest {
GoSafeProtocolDecoder decoder = new GoSafeProtocolDecoder(null);
+ verifyAttribute(decoder, text(
+ "*GS06,356449068350122,013519070819,,SYS:G6S;V3.37;V1.1.8,GPS:A;12;N23.169866;E113.450728;0;255;54;0.79,COT:18779;,ADC:12.66;0.58,DTT:4084;E1;0;0;0;1,IWD:0;1;ad031652643fff28;23.2;1;1;86031652504fff28;24.3;2;1;e603165252a5ff28;24.2;3;1;bb0416557da6ff28;24.0#"),
+ Position.PREFIX_TEMP + 3, 24.0);
+
+ verifyAttribute(decoder, text(
+ "*GS06,351535058659335,081234310719,,SYS:G6S;V3.37;V1.1.8,GPS:A;10;N23.169758;E113.450640;0;323;47;0.82,COT:18539;,ADC:10.81;4.07,DTT:4000;E0;0;0;0;1,IWD:0;1;9f00000655705d28;22.5#"),
+ Position.PREFIX_TEMP + 0, 22.5);
+
+ verifyAttribute(decoder, text(
+ "*GS06,359568052580548,091946150719,1C,SYS:G3C;V1.40;V1.0.4,GPS:A;5;S25.750200;E28.204858;0;0;1337;1.68,COT:,ADC:13.12;4.06,DTT:4004;C6;0;0;10000000;0$091948150719,,SYS:G3C;V1.40;V1.0.4,GPS:A;5;S25.750200;E28.204858;0;0;1337;1.68,COT:,ADC:12.96;4.06,DTT:4004;C6;0;0;0;1#"),
+ Position.KEY_EVENT, 0x1C);
+
verifyPositions(decoder, text(
"*GS06,860078024226974,101437211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;7;N3.052302;E101.787216;16;137;48;1.58,COT:4261733103,ADC:22.86;0.58;0.01,DTT:4004;E1;0;0;0;3$101439211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;8;N3.052265;E101.787200;12;152;46;1.31,COT:4261733103,ADC:22.98;0.58;0.01,DTT:4004;E1;0;0;0;3$101441211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;8;N3.052247;E101.787232;8;131;46;1.34,COT:4261733103,ADC:23.13;0.58;0.01,DTT:4004;E1;0;0;0;3$101510211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;8;N3.052150;E101.787152;0;131;40;0.97,COT:4261733160,ADC:22.88;0.58;0.01,DTT:4000;E1;0;0;0;1$101540211218,,SYS:G3SC;V3.36;V1.1.8,GPS:A;7;N3.052150;E101.787152;0;131;40;0.97,COT:4261733160,ADC:22.91;0.58;0.00,DTT:4000;E1;0;0;0;1#"));
diff --git a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java
index ca3ddfda8..23762f572 100644
--- a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java
@@ -17,6 +17,9 @@ public class GotopProtocolDecoderTest extends ProtocolTest {
"353327020412763,CMD-X"));
verifyPosition(decoder, text(
+ "867688038677542,ALM-D1,V,DATE:190709,TIME:185214,LAT:50.0422838N,LON:014.4504646E,Speed:004.3,081-20,05.68"));
+
+ verifyPosition(decoder, text(
"013226009991924,CMD-T,A,DATE:130802,TIME:153721,LAT:25.9757433S,LOT:028.1087816E,Speed:000.0,X-X-X-X-81-26,000,65501-00A0-4B8E"));
verifyPosition(decoder, text(
diff --git a/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java
index f888ee252..23a05fcee 100644
--- a/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/Gps103ProtocolEncoderTest.java
@@ -11,13 +11,13 @@ public class Gps103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodePositionPeriodic() throws Exception {
- Gps103ProtocolEncoder encoder = new Gps103ProtocolEncoder();
-
+ Gps103ProtocolEncoder encoder = new Gps103ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_POSITION_PERIODIC);
command.set(Command.KEY_FREQUENCY, 300);
-
+
assertEquals("**,imei:123456789012345,C,05m", encoder.encodeCommand(command));
}
@@ -25,7 +25,7 @@ public class Gps103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeCustom() throws Exception {
- Gps103ProtocolEncoder encoder = new Gps103ProtocolEncoder();
+ Gps103ProtocolEncoder encoder = new Gps103ProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java
index a6008e682..d31cac534 100644
--- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java
@@ -17,6 +17,21 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest {
verifyNull(decoder, binary(
"78780D01086471700328358100093F040D0A"));
+ verifyAttribute(decoder, binary(
+ "78780c95130a071223200100013ad10d0a"),
+ Position.KEY_ALARM, Position.ALARM_GENERAL);
+
+ verifyAttribute(decoder, binary(
+ "797900a87000000001020035000101003300125d7e3a180600d504b598f708814b3a001d1500340006125d7e39dc000011000a012e02620000000000000001000803537601000129800002000803102608593397620003000a89012608522933976266001800020172002b000114002c00045d7df3c70009000106000a000109002800010d002e00040000f25d002a000111002900040000017e0030000a000100b4000a00b402d0000591250d0a"),
+ Position.KEY_ALARM, Position.ALARM_REMOVING);
+
+ verifyPosition(decoder, binary(
+ "797900a87000000001020035000100003300125d62bf3a0800e804b5994308814a87001d5d00340006115d62bf29000011000a012e02620000000000000001000803537601000129800002000803102608593397620003000a8901260852293397626600180002017d002b000116002c00045d6278ea0009000108000a00010b002800010b002e00040000f0c1002a00010000290004000000be0030000a000100b4000a00b402d00006c5490d0a"));
+
+ verifyAttribute(decoder, binary(
+ "797900149b03023539303042343843454238410300139ba40d0a"),
+ Position.KEY_DRIVER_UNIQUE_ID, "5900B48CEB");
+
verifyPosition(decoder, binary(
"787821121303120b2524c70138e363085b549003d43301940057d200cd52c000006aa1ca0d0a"));
@@ -289,6 +304,17 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest {
verifyNull(decoder, binary(
"7878058A000688290D0A"));
+ verifyAttribute(decoder, binary(
+ "78780c95130a0209321c90000112800d0a"),
+ Position.KEY_ALARM, Position.ALARM_ACCELERATION);
+
+ verifyAttribute(decoder, binary(
+ "78780c95130a0209321c90000112800d0a"),
+ "alarmValue", 1);
+
+ verifyAttribute(decoder, binary(
+ "78780c95130a0209321c91000112800d0a"),
+ Position.KEY_ALARM, Position.ALARM_BRAKING);
}
}
diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java
index aceaef434..178c7b763 100644
--- a/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/Gt06ProtocolEncoderTest.java
@@ -9,8 +9,8 @@ public class Gt06ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- Gt06ProtocolEncoder encoder = new Gt06ProtocolEncoder();
-
+ Gt06ProtocolEncoder encoder = new Gt06ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_ENGINE_STOP);
diff --git a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java
index c69dffce7..31e4f2dee 100644
--- a/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/H02ProtocolDecoderTest.java
@@ -11,6 +11,9 @@ public class H02ProtocolDecoderTest extends ProtocolTest {
H02ProtocolDecoder decoder = new H02ProtocolDecoder(null);
+ verifyNull(decoder, buffer(
+ "*HQ,135790246811220,HTBT#"));
+
verifyPosition(decoder, binary(
"24702802061601234020031910125482600612695044000000ffffbbff000000000000000001760d04e2c9934d"));
diff --git a/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java
index a7ce3fc7e..155869b24 100644
--- a/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/H02ProtocolEncoderTest.java
@@ -14,7 +14,7 @@ import static org.junit.Assert.assertEquals;
public class H02ProtocolEncoderTest extends ProtocolTest {
- private H02ProtocolEncoder encoder = new H02ProtocolEncoder();
+ private H02ProtocolEncoder encoder = new H02ProtocolEncoder(null);
private Date time = Date.from(
LocalDateTime.of(LocalDate.now(), LocalTime.of(1, 2, 3)).atZone(ZoneOffset.systemDefault()).toInstant());
diff --git a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java
index 319d34e4c..6033bc744 100644
--- a/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/HuaShengProtocolDecoderTest.java
@@ -17,6 +17,9 @@ public class HuaShengProtocolDecoderTest extends ProtocolTest {
"c000000077aa0200000000000e000100143347315f48312e315f56312e30372e54000300133335353835353035303434303635380004000b3531323030303000050005010006000400070004000800050000090018383936313032353431343533333239313833360d000a000f796573696e7465726e6574c0"));
verifyPosition(decoder, binary(
+ "c000000060aa000000000000fa8000000031393037303431363434323700e9900affd61c1b00000000003a000000010015ffffff0000000000000004c2ffffffffff0005000a0d080000ca6a000900155741555a5a5a344730454e313133373233c0"));
+
+ verifyPosition(decoder, binary(
"c00000004baa0000000000000f8000000031363130323030373236333600e6d4f9ffcc78c700000022003600000001001500000000000000000000059bffffffffff0005000a040300000253c0"));
verifyPosition(decoder, binary(
diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java
index 771e6d28c..d0a0427c8 100644
--- a/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/HuabaoProtocolEncoderTest.java
@@ -11,8 +11,8 @@ public class HuabaoProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- HuabaoProtocolEncoder encoder = new HuabaoProtocolEncoder();
-
+ HuabaoProtocolEncoder encoder = new HuabaoProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_ENGINE_STOP);
diff --git a/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java
index 1992892df..4126c4e4f 100644
--- a/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/ItsProtocolDecoderTest.java
@@ -12,6 +12,12 @@ public class ItsProtocolDecoderTest extends ProtocolTest {
ItsProtocolDecoder decoder = new ItsProtocolDecoder(null);
verifyPosition(decoder, text(
+ "$,ID01,SAT,1.0.0,NR,1,L,868345034056903,DL3CAB1021,1,27052019,040234,28.359895,N,76.927879,E,0.0,285.6,12,254.9,1.4,0.7,IDEA,1,1,12.6,3.8,0,25,404,04,0138,0927,4ECD,0138,41,1C2B,0138,37,D77A,0138,34,D843,0138,33,0000,00,0.03,0.00,000091,A3,*"));
+
+ verifyPosition(decoder, text(
+ "$NMP,GPSBOX,1.6.8,NR,H,868997035844834,0000,1,220519,035419,28.6291409,N,77.3928299,E,015.2,157.40,07,197.86,2.1,1.0,airtel,1,1,13.3,4.1,0,O,31,404,10,0099,79b4,(-57,0099,334c,x,x,x,x,x,x,x,x,x),0012,00,000348,2,08.4,00.3,(0,0,0),CD*"));
+
+ verifyPosition(decoder, text(
"$RLP,N.A,2.0.2,NR,01,L,869867030181814,N.A,28022019,180155,1,28.688226,N,076.993570,E,0.0,80.26,17,201.0,0.89,0.60,VODAFONE I,0,1,25.0,4.20,0,C,14,404,11,415,F34A,51f7,415,13,840b,415,8,a3f7,0c2,5,ef77,415,5,0001,00,17888,47,*"));
verifyAttribute(decoder, text(
@@ -67,6 +73,24 @@ public class ItsProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, text(
"$,04,XYZ123,0.0.1,BR,06,L,861359034137271,MH12AB1234,0,00,00,0000,00,00,00,000.000000,N,000.000000,E,000.0,000.00,00,000.0,00.00,00.00,IDEAIN,1,1,00.0,3.8,1,O,17,404,22,2797,11b7,11b9,2797,-093,11b8,2797,-098,0000,0000,0000,0000,0000,0000,1000,00,000006,abd26284,"));
+ verifyNull(decoder, text(
+ "$Header,nliven,EMR,861693034634154,NM,09112017155133,A,12.976495,N,77.549713,E,906.0,0.0,23,G,KA01I2000,+919844098440*4B"));
+
+ verifyNull(decoder, text(
+ "$EPB,iTriangle1,EMR,864495034445822,SP,03082018110730,A,22.829292,N,75.935806,E,543.0,0.0,0,G,KA01G1234,+9164061023*13"));
+
+ verifyPosition(decoder, text(
+ "$Header,iTriangle,1_37T02B0164MAIS_2,NR,1,L,864495034490141,KA01I2000,1,19042018,102926,22.846401,N,75.948952,E,0.0,311,5,578.0,3.80,3.67,AirTel,0,1,12.5,4.3,1,C,14,404,93,0456,16db,29,ebd8,0458,28,3843,18ab,25,072e,18ab,22,35da,0458,0000,00,031181,0.0,0.0,0,()*34"));
+
+ verifyPosition(decoder, text(
+ "$Header,nliven,1_37T02B0164MAIS,BR,6,L,861693034634154,KA01I2000,1,09112017,160702,12.976593,N,77.549782,E,25.1,344,15,911.0,1.04,0.68,Airtel,1,1,11.8,3.8,1,C,24,404,45,61b4,9ad9,31,9adb,61b4,35,ffff,0000,33,ffff,0000,31,ffff,0000,0001,00,000014,0.0,0.1,4,()*1E"));
+
+ verifyPosition(decoder, text(
+ "$Header,iTriangle,1_37T02B0164MAIS_2,NR,1,L,864495034490141,KA01I2000,1,31032018,122247,22.845999,N,75.949005,E,0.0,44,16,545.0,1.19,0.65,AirTel,1,1,12.0,4.3,0,C,13,404,93,0456,16db,27,16dd,0456,22,3843,18ab,19,ebd8,0458,14,072c,18ab,0101,00,003735,0.0,0.0,0,()*48"));
+
+ verifyNull(decoder, text(
+ "$Header,nliven,KA01I2000,861693034634154,1_37T02B0164MAIS,AIS140,12.976545,N,77.549759,E*50"));
+
}
}
diff --git a/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java
index e7c4318b3..225edd643 100644
--- a/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/ItsProtocolEncoderTest.java
@@ -11,7 +11,7 @@ public class ItsProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- ItsProtocolEncoder encoder = new ItsProtocolEncoder();
+ ItsProtocolEncoder encoder = new ItsProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java
index ae0948987..e695624a9 100644
--- a/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/Jt600FrameDecoderTest.java
@@ -11,6 +11,10 @@ public class Jt600FrameDecoderTest extends ProtocolTest {
Jt600FrameDecoder decoder = new Jt600FrameDecoder();
verifyFrame(
+ binary("2478905197081711003405101917164812492365028134847d0a1c000002640c0000000020c032759600731000000f0f0f0f0f0f0f0f0f0f000702850274"),
+ decoder.decode(null, null, binary("2478905197081711003405101917164812492365028134847d0a1c000002640c0000000020c032759600731000000f0f0f0f0f0f0f0f0f0f000702850274")));
+
+ verifyFrame(
binary("24315011626912001b21111718095900000000000000000e0000005c000000000000000000"),
decoder.decode(null, null, binary("24315011626912001b21111718095900000000000000000e0000005c00000000000000000024315011626912001b22111708130400000000000000000e0000005a00000000000000000024315011626912001b22111708140400000000000000000e0000005a000000723e18a61b01")));
diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java
index 1ffa2a429..4a3c752cd 100644
--- a/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/Jt600ProtocolDecoderTest.java
@@ -12,6 +12,15 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest {
Jt600ProtocolDecoder decoder = new Jt600ProtocolDecoder(null);
verifyPositions(decoder, binary(
+ "2478807035371711003419081920061851380856003256223b000000000000070000000020c0ff965d54de1800000f0f0f0f0f0f0f0f0f0f02d600ea0a21"));
+
+ verifyPositions(decoder, binary(
+ "2475201509261611002313101503464722331560113555309F00000000002D0500CB206800F064109326381A03"));
+
+ verifyPositions(decoder, binary(
+ "2475810297431713003401010000030100000000000000000e000000000001000000000020e0641aba1b6f1b00000f0f0f0f0f0f0f0f0f0f000001942803"));
+
+ verifyPositions(decoder, binary(
"2440811188882400A209060908045322564025113242329F0598000001003F0000002D0009060908050322564025113242329F0598000001003F0000002D0009060908051322564025113242329F0598000001003F0000002D0009060908052322564025113242329F0598000001003F0000002D0009060908053322564025113242329F0598000001003F0000002D0009060908054322564025113242329F0598000001003F0000002D001F"));
verifyPositions(decoder, binary(
diff --git a/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java
index 100d7492a..c0b399c63 100644
--- a/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/Jt600ProtocolEncoderTest.java
@@ -7,7 +7,7 @@ import org.traccar.ProtocolTest;
import org.traccar.model.Command;
public class Jt600ProtocolEncoderTest extends ProtocolTest {
- Jt600ProtocolEncoder encoder = new Jt600ProtocolEncoder();
+ Jt600ProtocolEncoder encoder = new Jt600ProtocolEncoder(null);
Command command = new Command();
@Test
diff --git a/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java
index ab858041a..390defe6f 100644
--- a/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/KhdProtocolEncoderTest.java
@@ -9,8 +9,8 @@ public class KhdProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- KhdProtocolEncoder encoder = new KhdProtocolEncoder();
-
+ KhdProtocolEncoder encoder = new KhdProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_ENGINE_STOP);
diff --git a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java
index 31a0434bc..5b66ed865 100644
--- a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java
@@ -15,14 +15,14 @@ public class LaipacProtocolDecoderTest extends ProtocolTest {
verifyNull(decoder, text(
"$AVSYS,99999999,V1.50,SN0000103,32768*15"));
-
+
verifyNull(decoder, text(
"$ECHK,99999999,0*35"));
-
+
verifyNull(decoder, text(
"$AVSYS,MSG00002,14406,7046811160,64*1A"));
- verifyNull(decoder, text(
+ verifyAttributes(decoder, text(
"$EAVSYS,MSG00002,8931086013104404999,,Owner,0x52014406*76"));
verifyNull(decoder, text(
@@ -85,10 +85,10 @@ public class LaipacProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, text(
"$AVRMC,MSG00002,125517,R,5053.0442,N,00557.8694,E,0.00,0.00,240614,H,4076,167,1,0,0,0D7AB913,020408*75"));
-
+
verifyPosition(decoder, text(
"$AVRMC,MSG00002,043104,p,5114.4664,N,00534.3308,E,0.00,0.00,280614,0,4115,495,1,0,0,0D48C3DC,020408*52"));
-
+
verifyPosition(decoder, text(
"$AVRMC,MSG00002,050601,P,5114.4751,N,00534.3175,E,0.00,0.00,280614,0,4115,495,1,0,0,0D48C3DC,020408*7D"));
@@ -104,22 +104,29 @@ public class LaipacProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, text(
"$AVRMC,999999999999999,084514,r,5050.1314,N,00419.9719,E,0.68,306.39,120318,0,3882,84,1,0,0,3EE4A617,020610*4D"));
- //Alarm button
+ // Alarm button
verifyPosition(decoder, text(
"$AVRMC,358174067149865,142945,R,5050.1254,N,00420.0490,E,0.00,0.00,190318,3,3455,119,1,0,0,3EE4A617,020610*53"));
- //G-Sensor
+ // G-Sensor
verifyPosition(decoder, text(
"$AVRMC,358174067149865,143407,R,5050.1254,N,00420.0490,E,0.00,0.00,190318,8,3455,119,1,0,0,3EE4A617,020610*52"));
- //Powered off
+ // Powered off
verifyPosition(decoder, text(
"$AVRMC,358174067149865,143648,A,5050.1141,N,00420.0525,E,1.24,174.38,190318,H,3455,119,1,0,0,3EE4A617,020610*3E"));
- //No network
+ // No network
verifyPosition(decoder, text(
"$AVRMC,358174067149865,143747,R,5050.1124,N,00420.0542,E,1.34,161.96,190318,a,3416,119,1,0,0*7D"));
+ // Zero LAC, CID, MCC, MNC
+ verifyPosition(decoder, text(
+ "$AVRMC,358174067149865,143747,P,5050.1124,N,00420.0542,E,1.34,161.96,190318,A,3416,119,1,0,0,0,0*5F"));
+
+ // New unknown parameters
+ verifyPosition(decoder, text(
+ "$AVRMC,358174067149865,143747,P,5050.1124,N,00420.0542,E,1.34,161.96,190318,A,3416,119,1,0,0,0,0,0,0*5F"));
}
}
diff --git a/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java
new file mode 100644
index 000000000..7fe405ea8
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/LeafSpyProtocolDecoderTest.java
@@ -0,0 +1,21 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class LeafSpyProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ LeafSpyProtocolDecoder decoder = new LeafSpyProtocolDecoder(null);
+
+ verifyNull(decoder, request(
+ "/?Lat=60.0&Long=30.0"));
+
+ verifyPosition(decoder, request(
+ "/?user=driver&pass=123456&DevBat=80&Gids=200&Lat=60.0&Long=30.0&Elv=5&Seq=50&Trip=1&Odo=10000&SOC=99.99&AHr=55.00&BatTemp=15.2&Amb=12.0&Wpr=12&PlugState=0&ChrgMode=0&ChrgPwr=0&VIN=ZE0-000000&PwrSw=1&Tunits=C&RPM=1000"));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java
index ee4a869f9..d7aa25be8 100644
--- a/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/MeiligaoProtocolEncoderTest.java
@@ -9,7 +9,7 @@ public class MeiligaoProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- MeiligaoProtocolEncoder encoder = new MeiligaoProtocolEncoder();
+ MeiligaoProtocolEncoder encoder = new MeiligaoProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java
index b63ce5051..2b5054cee 100644
--- a/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java
@@ -11,8 +11,8 @@ public class MeitrackProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- MeitrackProtocolEncoder encoder = new MeitrackProtocolEncoder();
-
+ MeitrackProtocolEncoder encoder = new MeitrackProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_POSITION_SINGLE);
diff --git a/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java
new file mode 100644
index 000000000..794b2b57e
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/MictrackProtocolDecoderTest.java
@@ -0,0 +1,37 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class MictrackProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ MictrackProtocolDecoder decoder = new MictrackProtocolDecoder(null);
+
+ verifyPosition(decoder, text(
+ "MT;6;866425031361423;R0;10+190109091803+22.63827+114.02922+2.14+69+2+3744+113"),
+ position("2019-01-09 09:18:03.000", true, 22.63827, 114.02922));
+
+ verifyAttributes(decoder, text(
+ "MT;6;866425031377981;R1;190108024848+6a:db:54:5a:79:6d,-91,00:9a:cd:a2:e6:21,-94+3+3831+0"));
+
+ verifyAttributes(decoder, text(
+ "MT;1;866425031379169;R2;181129081017+0,21681,20616,460+4+3976+0"));
+
+ verifyAttributes(decoder, text(
+ "MT;1;866425031379169;R3;181129081017+0,167910723,14924,460,176+4+3976+0"));
+
+ verifyAttributes(decoder, text(
+ "MT;6;866425031377981;R12;190108024848+6a:db:54:5a:79:6d,-91,00:9a:cd:a2:e6:21,-94+0,21681,20616,460+3+3831+0"));
+
+ verifyAttributes(decoder, text(
+ "MT;6;866425031377981;R13;190108024848+6a:db:54:5a:79:6d,-91,00:9a:cd:a2:e6:21,-94+0,167910723,14924,460,176+3+3831+0"));
+
+ verifyAttributes(decoder, text(
+ "MT;5;866425031379169;RH;5+190116112648+0+0+0+0+11+3954+1"));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java
index e9422da9f..5de1346a2 100644
--- a/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/MiniFinderProtocolEncoderTest.java
@@ -11,7 +11,7 @@ public class MiniFinderProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- MiniFinderProtocolEncoder encoder = new MiniFinderProtocolEncoder();
+ MiniFinderProtocolEncoder encoder = new MiniFinderProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java
index 2b1fdf988..c0ce67cb6 100644
--- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java
@@ -10,6 +10,12 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest {
Minifinder2ProtocolDecoder decoder = new Minifinder2ProtocolDecoder(null);
+ verifyNull(decoder, binary(
+ "ab10150076f1320003100133353534363530373130323933303602105a"));
+
+ verifyPosition(decoder, binary(
+ "ab103f007e2533000110013335353436353037313032393330360930e09d245d210100000924b49e245d01025b201620e6c03b1ef367420400000000aa026d00c90e0000100110"));
+
verifyAttributes(decoder, binary(
"ab1845005d39370301100133353836383830303030303338303209245b92b55c84004b610502001000002221ca00050b4a005cc30f4a0056c80f4a003ba90e4a0055c8074a005dc3034a0057c8"));
diff --git a/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java b/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java
new file mode 100644
index 000000000..450f77144
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/NavisetFrameDecoderTest.java
@@ -0,0 +1,19 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class NavisetFrameDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ NavisetFrameDecoder decoder = new NavisetFrameDecoder();
+
+ verifyFrame(
+ binary("1310e4073836383230343030353935383436362a060716"),
+ decoder.decode(null, null, binary("1310e4073836383230343030353935383436362a060716")));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java
new file mode 100644
index 000000000..09ea10f1f
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/NavisetProtocolDecoderTest.java
@@ -0,0 +1,30 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class NavisetProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ NavisetProtocolDecoder decoder = new NavisetProtocolDecoder(null);
+
+ verifyNull(decoder, binary(
+ "1310e4073836383230343030353935383436362a060716"));
+
+ verifyPositions(decoder, binary(
+ "6b511a203f95162b7822515d78a92503042df6030000ff040000c4003f1922471000001af3000030e4503490e8ff00000000000000000000000000000000ff27000000000000808080808080808000000000ffdd0000000000000000000000000000000000000000000000210000000000ff00000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096160b7d22515d3ca92503e42cf6030000ff040000c7001ef521471000001af3000070e44034e0e8ff00000000000000000000000000000000ff27000000000000808080808080808000000000ffdd0000000000000000000000000000000000000000000000210000000000ff00000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000664a"));
+
+ verifyPositions(decoder, binary(
+ "b7501a203fab0d0bffcf4b5df0a82503a02cf6030000ff0c4200ba0007462a3a10000098280000f0f610fc4042ff00000000000000000000000000000000ff26000000000000808080808080808000000000ff000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008bff"));
+
+ verifyPositions(decoder, binary(
+ "b7501a203fda0d097fdc4b5d70aa2503c42cf6030000ff0fb40dea0006b12a3a100000b228000080f210044041ff00000000000000000000000000000000ff25000000000000808080808080808000000000ff1201000000000000000000000000000000000000000000001a0000000000ff00000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b603"));
+
+ verifyPositions(decoder, binary(
+ "14501a2000a50c0955a64b5db8a92503fc2cf603000084ab"));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java
index 38599e0ba..4991f1371 100644
--- a/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/NoranProtocolEncoderTest.java
@@ -9,8 +9,8 @@ public class NoranProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- NoranProtocolEncoder encoder = new NoranProtocolEncoder();
-
+ NoranProtocolEncoder encoder = new NoranProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_ENGINE_STOP);
diff --git a/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java
new file mode 100644
index 000000000..ade2804da
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/PacificTrackProtocolDecoderTest.java
@@ -0,0 +1,32 @@
+package org.traccar.protocol;
+
+import io.netty.buffer.Unpooled;
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+import static org.junit.Assert.assertEquals;
+
+public class PacificTrackProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testReadBitExt() {
+
+ assertEquals(0x35, PacificTrackProtocolDecoder.readBitExt(
+ Unpooled.wrappedBuffer(new byte[] { (byte) 0b10110101 })));
+
+ assertEquals(0x135, PacificTrackProtocolDecoder.readBitExt(
+ Unpooled.wrappedBuffer(new byte[] { (byte) 0b00000010, (byte) 0b10110101 })));
+ }
+
+
+ @Test
+ public void testDecode() throws Exception {
+
+ PacificTrackProtocolDecoder decoder = new PacificTrackProtocolDecoder(null);
+
+ verifyPosition(decoder, binary(
+ "fb82e80280883527530900009110818202c0909308990b122519076138fc03b3480205a3e80003a0834dd19fb08112c08f0143000e020000000100000014000101929f806328c0000f4240810a858ce011314334424a57464758444c3533313737330190868102100828cf"));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java
new file mode 100644
index 000000000..582ed9a5a
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/PluginProtocolDecoderTest.java
@@ -0,0 +1,27 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class PluginProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ PluginProtocolDecoder decoder = new PluginProtocolDecoder(null);
+
+ verifyPosition(decoder, text(
+ "$$STATUS,fleet40,20190704122622,26.259431,-29.027889,0,9,0,-1,2,19719,805315969,0,0,0"));
+
+ verifyPosition(decoder, text(
+ "$$ALARM801739,20190612121950,28.254067,-25.860494,0,0,0,-1,2,2,12595331,0,0,0,+,22,0,0,0,0,0,,0,0"));
+
+ verifyPosition(decoder, text(
+ "$$STATUS801739,20190528143943,28.254086,-25.860665,0,0,0,-1,2,78,11395,0,0,0"));
+
+ verifyPosition(decoder, text(
+ "50000,20150623184513,113.828759,22.709578,70,190,0,-1,2,155135681,805327235,1.32,-32.1,0"));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java
index 1b2780325..aa08ecea2 100644
--- a/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/PretraceProtocolEncoderTest.java
@@ -11,13 +11,13 @@ public class PretraceProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodePositionPeriodic() throws Exception {
- PretraceProtocolEncoder encoder = new PretraceProtocolEncoder();
-
+ PretraceProtocolEncoder encoder = new PretraceProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_POSITION_PERIODIC);
command.set(Command.KEY_FREQUENCY, 300);
-
+
assertEquals("(123456789012345D221300,300,,^69)", encoder.encodeCommand(command));
}
@@ -25,7 +25,7 @@ public class PretraceProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeCustom() throws Exception {
- PretraceProtocolEncoder encoder = new PretraceProtocolEncoder();
+ PretraceProtocolEncoder encoder = new PretraceProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/Pt215FrameDecoderTest.java b/src/test/java/org/traccar/protocol/Pt215FrameDecoderTest.java
new file mode 100644
index 000000000..2e3600b99
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/Pt215FrameDecoderTest.java
@@ -0,0 +1,27 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class Pt215FrameDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ Pt215FrameDecoder decoder = new Pt215FrameDecoder();
+
+ verifyFrame(
+ binary("58580d010359339075799656010d0a"),
+ decoder.decode(null, null, binary("58580d010359339075799656010d0a")));
+
+ verifyFrame(
+ binary("5858071340010819640d0a"),
+ decoder.decode(null, null, binary("5858071340010819640d0a")));
+
+ verifyFrame(
+ binary("585815101309160d0f0c9902b7015405f0e82404347afff7000d0a"),
+ decoder.decode(null, null, binary("585815101309160d0f0c9902b7015405f0e82404347afff7000d0a")));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java
new file mode 100644
index 000000000..59574aeee
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/Pt215ProtocolDecoderTest.java
@@ -0,0 +1,21 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class Pt215ProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ Pt215ProtocolDecoder decoder = new Pt215ProtocolDecoder(null);
+
+ verifyNull(decoder, binary(
+ "58580d010359339075435451010d0a"));
+
+ verifyNull(decoder, binary(
+ "585801080d0a"));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java
index a6c8bb50f..9e4a8a9a0 100644
--- a/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/Pt502ProtocolEncoderTest.java
@@ -11,7 +11,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeCustom() throws Exception {
- Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder();
+ Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
@@ -25,22 +25,22 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeOutputControl() throws Exception {
- Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder();
-
+ Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_OUTPUT_CONTROL);
command.set(Command.KEY_INDEX, 2);
command.set(Command.KEY_DATA, "1");
-
+
assertEquals("#OPC2,1\r\n", encoder.encodeCommand(command));
}
-
+
@Test
public void testEncodeTimezone() throws Exception {
- Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder();
+ Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
@@ -55,7 +55,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeAlarmSpeed() throws Exception {
- Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder();
+ Pt502ProtocolEncoder encoder = new Pt502ProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java
new file mode 100644
index 000000000..318cbdb51
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/RaceDynamicsProtocolDecoderTest.java
@@ -0,0 +1,21 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class RaceDynamicsProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ RaceDynamicsProtocolDecoder decoder = new RaceDynamicsProtocolDecoder(null);
+
+ verifyNull(decoder, text(
+ "$GPRMC,12,260819,100708,862549040661129,"));
+
+ verifyPositions(decoder, text(
+ "$GPRMC,15,04,H,#,100632,A,1255.5106,N,07738.2954,E,001,260819,0887,06,1,00011,%,0000000000000000,000,000,0,0,1,0713,0,416,0,255,000,0,000,3258,000,000,00,0000,000,00000,0,F3VF01,%,#,#,100633,A,1255.5107,N,07738.2955,E,001,260819,0887,06,1,00012,%,0000000000000000,000,000,0,0,1,0713,0,416,0,255,000,0,000,3453,000,000,00,0000,000,00000,0,F3VF01,%,#,#,100634,A,1255.5106,N,07738.2964,E,001,260819,0887,06,1,00013,%,0000000000000000,000,000,0,0,1,0713,0,392,0,255,000,0,000,3651,000,000,00,0000,000"));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java
new file mode 100644
index 000000000..66286776a
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/RstProtocolDecoderTest.java
@@ -0,0 +1,26 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+import org.traccar.model.Position;
+
+public class RstProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ RstProtocolDecoder decoder = new RstProtocolDecoder(null);
+
+ verifyAttribute(decoder, text(
+ "RST;A;RST-MINIv2;V7.00;008033985;1;7;30-08-2019 11:31:38;30-08-2019 11:31:15;-23.645868;-46.637741;0;226;828;0;10;0;00;20;00;1A;02;0.02;3.40;0;0;FE;0000;04;80;11;0;FIM;"),
+ Position.KEY_BATTERY, 3.40);
+
+ verifyPosition(decoder, text(
+ "RST;A;RST-MINIv2;V7.00;008033985;1;7;30-08-2019 11:31:38;30-08-2019 11:31:15;-23.645868;-46.637741;0;226;828;0;10;0;00;20;00;1A;02;0.02;3.40;0;0;FE;0000;04;80;11;0;FIM;"));
+
+ verifyPosition(decoder, text(
+ "RST;A;RST-MINIv2;V7.00;008033985;6;47;30-08-2019 19:01:13;30-08-2019 19:01:14;-23.645851;-46.637817;0;294;811;1;11;0;00;30;00;1A;02;3.82;4.16;0;0;FE;0000;02;40;71;000001F60A55;FIM;"));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java
index 8a00caa09..5868b07df 100644
--- a/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/RuptelaProtocolEncoderTest.java
@@ -9,8 +9,8 @@ public class RuptelaProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- RuptelaProtocolEncoder encoder = new RuptelaProtocolEncoder();
-
+ RuptelaProtocolEncoder encoder = new RuptelaProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_CUSTOM);
diff --git a/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java
index 48adb0ccb..a2cb021ef 100644
--- a/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/SigfoxProtocolDecoderTest.java
@@ -3,6 +3,7 @@ package org.traccar.protocol;
import io.netty.handler.codec.http.HttpMethod;
import org.junit.Test;
import org.traccar.ProtocolTest;
+import org.traccar.model.Position;
public class SigfoxProtocolDecoderTest extends ProtocolTest {
@@ -12,6 +13,19 @@ public class SigfoxProtocolDecoderTest extends ProtocolTest {
SigfoxProtocolDecoder decoder = new SigfoxProtocolDecoder(null);
verifyPosition(decoder, request(HttpMethod.POST, "/",
+ buffer("{ \"device\": \"49F941\", \"location\": {\"lat\":19.48954345634299,\"lng\":-99.09340606338463,\"radius\":1983,\"source\":2,\"status\":1} }")));
+
+ verifyAttribute(decoder, request(HttpMethod.POST, "/",
+ buffer("{ \"device\": \"40D310\", \"payload\": \"62\", \"time\": 1563043532, \"seqNumber\": 1076 }")),
+ Position.KEY_ALARM, Position.ALARM_SOS);
+
+ verifyAttributes(decoder, request(HttpMethod.POST, "/",
+ buffer("{ \"device\": \"40D310\", \"payload\": \"20061494480389f956042a\", \"time\": 1563043532, \"seqNumber\": 1076 }")));
+
+ verifyPosition(decoder, request(HttpMethod.POST, "/",
+ buffer("{ \"device\": \"1CEDCE\", \"payload\": \"2002419b4a91c2c6580e0564\", \"time\": 1559924939, \"seqNumber\": 87 }")));
+
+ verifyPosition(decoder, request(HttpMethod.POST, "/",
buffer("%7B++%22device%22%3A%222BF839%22%2C++%22time%22%3A1510605882%2C++%22duplicate%22%3Afalse%2C++%22snr%22%3A45.61%2C++%22station%22%3A%2235A9%22%2C++%22data%22%3A%2200bd6475e907398e562d01b9%22%2C++%22avgSnr%22%3A45.16%2C++%22lat%22%3A-38.0%2C++%22lng%22%3A145.0%2C++%22rssi%22%3A-98.00%2C++%22seqNumber%22%3A228+%7D=")));
}
diff --git a/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java
index 70e173284..97246a665 100644
--- a/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/StarLinkProtocolDecoderTest.java
@@ -49,6 +49,11 @@ public class StarLinkProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, text(
"$SLU006968,06,375154,170117052613,04,170117052612,+3203.2079,+03448.1369,000.0,300,085725,1,1,0,0,0,0,0,0,10422,36201,14.287,04.084,,1,0*5B"));
+ decoder.setFormat("#EDT#,#EID#,#PDT#,#LAT#,#LONG#,#SPD#,#HEAD#,#ODO#,#LAC#,#CID#,#VIN#,#VBAT#");
+
+ verifyPosition(decoder, text(
+ "$SLU352353083185436,06,85,190527214903,01,190527214903,+0614.1883,-07535.5033,000.0,000,000082.505,5070,50473,0,12.148,03.507,,100,0.02,35.0,1,1513,60,1,99*30"));
+
}
}
diff --git a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java
index cb5df63e6..304bc0fed 100644
--- a/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/SuntechProtocolDecoderTest.java
@@ -59,6 +59,13 @@ public class SuntechProtocolDecoderTest extends ProtocolTest {
SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(null);
verifyPosition(decoder, text(
+ "ALT;0520000295;3FFFFF;52;1.0.2;0;20190703;01:03:24;00004697;732;101;0002;59;+4.682583;-74.128142;0.00;0.00;6;1;00000000;00000000;9;1;;4.1;12.92;103188"));
+
+ verifyAttribute(decoder, text(
+ "ST300UEX;109003241;08;1026;20190425;17:36:04;04402;+04.722553;-074.052583;000.020;000.00;10;1;0;12.04;010000;51;CabAVL\"CabMensaje,0,58.5,-1.0,,,FinMensaje\"FinAVL\r\n;B1;0000000000;4.1;1"),
+ "fuel1", 58.5);
+
+ verifyPosition(decoder, text(
"ST600UEX;008728327;20;520;20190218;10:56:51;0bf1a893;334;20;2f19;18;+20.514195;-100.743597;000.015;000.00;9;1;3720808;12.89;000000;44;t_0=0D;N_0=0551.0;t_1=14;N_1=039F.0;Q_D=0B\r\n;9E;010440;4.1;1"));
verifyPosition(decoder, text(
diff --git a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java
index f21acdee7..c0511f2a1 100644
--- a/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/T55ProtocolDecoderTest.java
@@ -2,6 +2,7 @@ package org.traccar.protocol;
import org.junit.Test;
import org.traccar.ProtocolTest;
+import org.traccar.model.Position;
public class T55ProtocolDecoderTest extends ProtocolTest {
@@ -13,6 +14,10 @@ public class T55ProtocolDecoderTest extends ProtocolTest {
verifyNull(decoder, text(
"$DEVID,0x0103846677F21422*41"));
+ verifyAttribute(decoder, text(
+ "$GPIOP,01000000,00000000,0.00,0.00,0.00,0.00,4.69,4.24*49"),
+ Position.KEY_BATTERY, 4.24);
+
verifyPosition(decoder, text(
"660420156A0066AA$GPRMC,122806.0,A,0119.212178,N,10355.000942,E,0.0,,230119,0.0,E,A*27"));
diff --git a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java
index bfe06b5cd..28b3fc5c6 100644
--- a/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/T800xProtocolDecoderTest.java
@@ -11,6 +11,19 @@ public class T800xProtocolDecoderTest extends ProtocolTest {
T800xProtocolDecoder decoder = new T800xProtocolDecoder(null);
+ verifyPosition(decoder, binary(
+ "2727040049001b0866425039645728c916190604005240000000007739d2c25b681f420000000080000081000020174105000005458216001e000000f01e00001e30d0000000000000"));
+
+ verifyAttribute(decoder, binary(
+ "272705005e000108664250328807851905301107481054002d004d006f00620069006c006500074341542d4e42310a4c54452042414e4420340f333130323430323030303032333030143839303132343032303531303030323330303746"),
+ Position.KEY_OPERATOR, "T-Mobile");
+
+ verifyPosition(decoder, binary(
+ "272702004904a90866425032880785c800190530080350000000000705eec29bf50842000000000008008090502a003700000a9e358002003c000003841900001e3f90000000000000272702004904aa0866425032880785c800190530081851000000000705eec29bf50842000000000008008090602e003700000a9e358002003c000003841900001e3f90000000000000"));
+
+ verifyNull(decoder, binary(
+ "2727010017000108806168988888881016010207110111"));
+
verifyNull(decoder, binary(
"252501001504050880061689888888111111250350"));
diff --git a/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java
index e41b91281..9a628cdb6 100644
--- a/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/T800xProtocolEncoderTest.java
@@ -9,14 +9,16 @@ public class T800xProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- T800xProtocolEncoder encoder = new T800xProtocolEncoder();
-
+ T800xProtocolEncoder encoder = new T800xProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_CUSTOM);
command.set(Command.KEY_DATA, "RELAY,0000,On#");
- verifyCommand(encoder, command, binary("252581001e000101234567890123450152454c41592c303030302c4f6e23"));
+ verifyFrame(
+ binary("232381001e000101234567890123450152454c41592c303030302c4f6e23"),
+ encoder.encodeCommand(null, command));
}
diff --git a/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java
index bdbaec8aa..0b9eacb8d 100644
--- a/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/TaipProtocolDecoderTest.java
@@ -10,6 +10,9 @@ public class TaipProtocolDecoderTest extends ProtocolTest {
TaipProtocolDecoder decoder = new TaipProtocolDecoder(null);
+ verifyNull(decoder, text(
+ ">RLN25601000+297185103-0955755990+000059150000+0000000012000000000000000000000000000000000000000000000000000000000012;ID=3580;*48<"));
+
verifyPosition(decoder, text(
">RGP211217112154-2748332-058946350000000FF7F2100;ID=AA01;#0002;*2D<"));
diff --git a/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java
index 0fdd26a47..767f175fe 100644
--- a/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/TechTltProtocolDecoderTest.java
@@ -11,11 +11,11 @@ public class TechTltProtocolDecoderTest extends ProtocolTest {
TechTltProtocolDecoder decoder = new TechTltProtocolDecoder(null);
verifyPosition(decoder, text(
- "002422269*POS=Y,16:21:20,25/11/09,3809.8063N,01444.7438E,4.17,117.23,0.4,09,40076,56341"),
+ "002422269*POS=Y,16:21:20,25/11/09,3809.8063N,01444.7438E,4.17,117.23,0.4,09,40076,56341\r\n"),
position("2009-11-25 16:21:20.000", true, 38.16344, 14.74573));
- verifyNull(decoder, text(
- "002422269,INFOGPRS,V Bat=13.8,TEMP=23,I TIM,15"));
+ verifyAttributes(decoder, text(
+ "002422269,INFOGPRS,V Bat=13.8,TEMP=23,I TIM,15\r\n"));
}
diff --git a/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java
new file mode 100644
index 000000000..8d2e70bd4
--- /dev/null
+++ b/src/test/java/org/traccar/protocol/TeltonikaFrameDecoderTest.java
@@ -0,0 +1,23 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class TeltonikaFrameDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ TeltonikaFrameDecoder decoder = new TeltonikaFrameDecoder();
+
+ verifyFrame(
+ binary("000F313233343536373839303132333435"),
+ decoder.decode(null, null, binary("FF000F313233343536373839303132333435")));
+
+ verifyFrame(
+ binary("000F313233343536373839303132333435"),
+ decoder.decode(null, null, binary("000F313233343536373839303132333435")));
+
+ }
+
+}
diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java
index b515fbdc6..827e12a96 100644
--- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java
@@ -16,6 +16,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest {
"000F313233343536373839303132333435"));
verifyPositions(decoder, false, binary(
+ "000000000000004f0c01060000004755555555777730362e343b30342e323b30302e303b30302e303b30302e303b30302e303b30302e303b30302e303b30312e333b30302e303b31302e373b30302e303b5353530d0a010000e371"));
+
+ verifyPositions(decoder, false, binary(
"00000000000000100C010600000008010300010015D5C5010000D988"));
verifyPositions(decoder, binary(
diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java
index 5dc78c012..0318b9896 100644
--- a/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolEncoderTest.java
@@ -9,8 +9,8 @@ public class TeltonikaProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- TeltonikaProtocolEncoder encoder = new TeltonikaProtocolEncoder();
-
+ TeltonikaProtocolEncoder encoder = new TeltonikaProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_CUSTOM);
diff --git a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java
index 34b2acf86..d1dad8c92 100644
--- a/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/Tk103ProtocolEncoderTest.java
@@ -11,7 +11,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeOutputControl() {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder();
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
@@ -25,8 +25,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeEngineStop() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder();
-
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_ENGINE_STOP);
@@ -38,8 +38,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodePositionSingle() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder();
-
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_POSITION_SINGLE);
@@ -51,8 +51,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodePositionPeriodic() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder();
-
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_POSITION_PERIODIC);
@@ -65,8 +65,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodePositionStop() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder();
-
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_POSITION_STOP);
@@ -78,8 +78,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeGetVersion() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder();
-
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_GET_VERSION);
@@ -91,8 +91,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeRebootDevice() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder();
-
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_REBOOT_DEVICE);
@@ -104,8 +104,8 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeSetOdometer() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder();
-
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_SET_ODOMETER);
@@ -117,7 +117,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodePositionSingleAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -130,7 +130,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodePositionPeriodicAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -143,7 +143,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodePositionStopAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -156,7 +156,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeGetVersionAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -169,7 +169,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeRebootDeviceAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -182,7 +182,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeIdentificationAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -195,7 +195,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeSosOnAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -209,7 +209,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeSosOffAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -223,7 +223,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeCustom() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder();
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
@@ -237,7 +237,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeCustomAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -251,7 +251,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeSetConnectionAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
@@ -266,7 +266,7 @@ public class Tk103ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeSosNumberAlternative() throws Exception {
- Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(true);
+ Tk103ProtocolEncoder encoder = new Tk103ProtocolEncoder(null, true);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java
index 5a47f74cc..d8c54afbe 100644
--- a/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/TotemProtocolEncoderTest.java
@@ -11,13 +11,13 @@ public class TotemProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- TotemProtocolEncoder encoder = new TotemProtocolEncoder();
-
+ TotemProtocolEncoder encoder = new TotemProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(2);
command.setType(Command.TYPE_ENGINE_STOP);
command.set(Command.KEY_DEVICE_PASSWORD, "000000");
-
+
assertEquals("*000000,025,C,1#", encoder.encodeCommand(command));
}
diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java
index 2fdb86218..aceb9e122 100644
--- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java
@@ -13,6 +13,9 @@ public class TrvProtocolDecoderTest extends ProtocolTest {
verifyNull(decoder, text(
"TRVAP00352121088015548"));
+ verifyPosition(decoder, text(
+ "TRVYP03190805A1828.9242N07353.9423E000.0150716029.0010000810020201112,404,27,184,10229"));
+
verifyNotNull(decoder, text(
"IWAP02,zh_cn,0,6,260,1,11002|39252|9,11002|35112|23,11002|11043|24,11002|39253|24,11002|13751|24,11018|8102|26,3,a|c0-4a-00-b6-9c-f5|64&a|c0-4a-00-b6-9c-f5|64&a|18-a6-f7-92-35-da|84"));
diff --git a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java
index bd1fc71f4..f90497292 100644
--- a/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/TzoneProtocolDecoderTest.java
@@ -11,6 +11,9 @@ public class TzoneProtocolDecoderTest extends ProtocolTest {
TzoneProtocolDecoder decoder = new TzoneProtocolDecoder(null);
verifyAttributes(decoder, binary(
+ "545A004B2424041302000000086706003324776413030C0A1A2900180513030C0A1A25080F7E1028CAC830000A000F0000000005000AA53201633D05046000010009AA201737019408973B0032B0260D0A"));
+
+ verifyAttributes(decoder, binary(
"545a005b24240406010800000866050033819630120911071824000472bd8e5b0008aac01b07019b04bb002f00040b06161154000e100132ff2006161152000e080096ff4606161151000e1e0101ff1406161156000db6405bff490024469e0d0a"));
verifyAttributes(decoder, binary(
diff --git a/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java b/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java
index d3d0429d6..01d63bfa3 100644
--- a/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/UlbotechFrameDecoderTest.java
@@ -12,15 +12,15 @@ public class UlbotechFrameDecoderTest extends ProtocolTest {
UlbotechFrameDecoder decoder = new UlbotechFrameDecoder();
- assertEquals(
+ verifyFrame(
binary("f8010103515810532780699f7e2e3f010e015ee4c906bde45c00000000008b0304004000000404002c776005060373193622110b00240b00fee8ffff807dffff606d0b00fee9af000000af0000000b00feee7d78807dffffffff100101cc2af8"),
decoder.decode(null, null, binary("f8010103515810532780699f7e2e3f010e015ee4c906bde45c00000000008b0304004000000404002c776005060373193622110b00240b00fee8ffff807dffff606d0b00fee9af000000af0000000b00feee7d78807dffffffff100101cc2af8")));
- assertEquals(
+ verifyFrame(
binary("2a545330312c33353430343330353133383934363023"),
decoder.decode(null, null, binary("2a545330312c33353430343330353133383934363023")));
- assertEquals(
+ verifyFrame(
binary("f8010108679650230646339de69054010e015ee17506bde2c60000000000ac0304024000000404000009f705060390181422170711310583410c0000310d00312f834131018608040003130a100101136cf8"),
decoder.decode(null, null, binary("f8010108679650230646339de69054010e015ee17506bde2c60000000000ac0304024000000404000009f70005060390181422170711310583410c0000310d00312f834131018608040003130a100101136cf8")));
diff --git a/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java
index 1c29ccd4a..8c820183b 100644
--- a/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/UlbotechProtocolDecoderTest.java
@@ -17,6 +17,10 @@ public class UlbotechProtocolDecoderTest extends ProtocolTest {
"*TS01,868323025245751,134955140317,WFE:0#"));
verifyPosition(decoder, binary(
+ "f801010868323028799515251e10d3010e03b52df8ff99fde500000000270f030402020000040402c62a7e0506057c1929220d060800000000000000000f040071eb621001018536f8"),
+ position("2019-09-25 11:49:39.000", false, 62.20543, -6.68521));
+
+ verifyPosition(decoder, binary(
"f8010103515810532780699f7e2e3f010e015ee4c906bde45c00000000008b0304004000000404002c776005060373193622110b00240b00fee8ffff807dffff606d0b00fee9af000000af0000000b00feee7d78807dffffffff100101cc2af8"));
verifyPosition(decoder, binary(
diff --git a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java
index dbbe4591f..e43ff322e 100644
--- a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java
@@ -2,6 +2,7 @@ package org.traccar.protocol;
import org.junit.Test;
import org.traccar.ProtocolTest;
+import org.traccar.model.Position;
public class UproProtocolDecoderTest extends ProtocolTest {
@@ -10,6 +11,22 @@ public class UproProtocolDecoderTest extends ProtocolTest {
UproProtocolDecoder decoder = new UproProtocolDecoder(null);
+ verifyAttribute(decoder, buffer(
+ "*VK200867282036729446,BA&A1759265051877702037465660022210819&B0000000000&W00&G000030&M830&N26&O1706&o11&T0783#"),
+ Position.KEY_BATTERY_LEVEL, 83.0);
+
+ verifyAttributes(decoder, buffer(
+ "*VK201867282035754650,AH&B0000000000&W00&M990&N31&Z02&b2&T0458#"));
+
+ verifyAttributes(decoder, buffer(
+ "*VK201867282035455779,AH&B0000000000&W00&M940&N30&Z02&Y12922&T0268#"));
+
+ verifyPosition(decoder, buffer(
+ "*VK200867282035455779,BA&A0850065052928902036605660013170719&B0000000000&W00&G000030&M850&N20&O1808&o10&Y12922&T0081#"));
+
+ verifyAttributes(decoder, buffer(
+ "*VK200867282035455779,BA&X260,6,1016,13931,60;1016,13929,81;1016,14174,82;1016,13930,82&E190717103920&B0100000000&W00&G000030&M900&N23&O0000&o07&Y14014&T0015#"));
+
verifyPosition(decoder, buffer(
"*HQ200861810538000002,BA&A0206033302618209658563620115180119&B0100000040&C6328680=&F0039&R2710&V0036&T09&K50000&N04&P0200#"));
diff --git a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java
index 539e63253..c5753dc4d 100644
--- a/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/WatchProtocolDecoderTest.java
@@ -16,6 +16,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest {
WatchProtocolDecoder decoder = new WatchProtocolDecoder(null);
verifyPosition(decoder, buffer(
+ "[3G*2104134718*00A1*UD_WCDMA,161019,134938,A,43.373367,N,71.157615,W,22.0,350.206,279.717,17,28,79,0,0,00000000,1,1,310,410,23999,132013696,28,1,Home2,60:45:cb:cb:34:68,-93,8.263865]"));
+
+ verifyPosition(decoder, buffer(
"[ZJ*014111001332708*0075*0064*AL,040418,052156,A,22.536207,N,113.938673,E,0,0,0,5,100,82,1000,50,00100000,1,255,460,0,9340,3663,35]"));
verifyPosition(decoder, buffer(
@@ -24,6 +27,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest {
verifyAttributes(decoder, buffer(
"[3G*4700609403*0013*bphrt,120,79,73,,,,]"));
+ verifyAttributes(decoder, buffer(
+ "[ZJ*357653059860416*0007*000c*BLOOD,109,68]"));
+
verifyPosition(decoder, buffer(
"[3G*8308373902*0080*AL,230817,095346,A,47.083950,N,15.4821850,E,7.60,273.8,0.0,4,15,44,0,0,00200010,2,255,232,1,7605,42530,118,7605,58036,119,0,65.8]"));
diff --git a/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java
index a0631be3b..798213c7b 100644
--- a/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/WatchProtocolEncoderTest.java
@@ -9,8 +9,8 @@ public class WatchProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- WatchProtocolEncoder encoder = new WatchProtocolEncoder();
-
+ WatchProtocolEncoder encoder = new WatchProtocolEncoder(null);
+
Command command;
command = new Command();
@@ -60,7 +60,7 @@ public class WatchProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeTimezone() {
- WatchProtocolEncoder encoder = new WatchProtocolEncoder();
+ WatchProtocolEncoder encoder = new WatchProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java
index 40b0469ea..72e56fb44 100644
--- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java
@@ -26,6 +26,9 @@ public class WialonProtocolDecoderTest extends ProtocolTest {
"#D#101118;061143;0756.0930;N;12338.6403;E;18.223;99.766;-4.000;10;0.800;NA;NA;NA;NA;101_521347:1:521249,101_521126:1:6593598,101_521127:1:774780,101_521072_21.1:1:0,101_521072_21.2:1:71353;F24A"));
verifyPosition(decoder, text(
+ "99999999#D#101118;061143;0756.0930;N;12338.6403;E;18.223;99.766;-4.000;10;0.800;NA;NA;NA;NA;101_521347:1:521249,101_521126:1:6593598,101_521127:1:774780,101_521072_21.1:1:0,101_521072_21.2:1:71353;F24A"));
+
+ verifyPosition(decoder, text(
"#D#151216;135910;5321.1466;N;04441.7929;E;87;156;265.000000;12;1.000000;241;NA;NA;NA;odo:2:0.000000,total_fuel:1:430087,can_fls:1:201,can_taho:1:11623,can_mileage:1:140367515"));
verifyPosition(decoder, text(
@@ -36,6 +39,10 @@ public class WialonProtocolDecoderTest extends ProtocolTest {
position("2013-04-27 20:56:01.000", true, 55.74338, 37.66139));
verifyPosition(decoder, text(
+ "99999999#SD#270413;205601;5544.6025;N;03739.6834;E;1;2;3;4"),
+ position("2013-04-27 20:56:01.000", true, 55.74338, 37.66139));
+
+ verifyPosition(decoder, text(
"#SD#021214;065947;2237.7552;N;11404.8851;E;0.000;;170.9;5"));
verifyPosition(decoder, text(
diff --git a/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java
index 8209fc412..41fee2723 100644
--- a/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/WondexProtocolEncoderTest.java
@@ -10,7 +10,7 @@ public class WondexProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- WondexProtocolEncoder encoder = new WondexProtocolEncoder();
+ WondexProtocolEncoder encoder = new WondexProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(2);
diff --git a/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java
index dd2e939c9..0ff47cad3 100644
--- a/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/XirgoProtocolEncoderTest.java
@@ -11,14 +11,14 @@ public class XirgoProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncode() throws Exception {
- XirgoProtocolEncoder encoder = new XirgoProtocolEncoder();
-
+ XirgoProtocolEncoder encoder = new XirgoProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_OUTPUT_CONTROL);
command.set(Command.KEY_INDEX, 0);
command.set(Command.KEY_DATA, 1);
-
+
assertEquals("+XT:7005,2,1", encoder.encodeCommand(command));
}
diff --git a/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java
index 49476d694..27efbd6db 100644
--- a/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java
+++ b/src/test/java/org/traccar/protocol/Xrb28ProtocolEncoderTest.java
@@ -11,13 +11,13 @@ public class Xrb28ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodePositionPeriodic() {
- Xrb28ProtocolEncoder encoder = new Xrb28ProtocolEncoder();
-
+ Xrb28ProtocolEncoder encoder = new Xrb28ProtocolEncoder(null);
+
Command command = new Command();
command.setDeviceId(1);
command.setType(Command.TYPE_POSITION_PERIODIC);
command.set(Command.KEY_FREQUENCY, 300);
-
+
assertEquals("\u00ff\u00ff*SCOS,OM,123456789012345,D1,300#\n", encoder.encodeCommand(null, command));
}
@@ -25,7 +25,7 @@ public class Xrb28ProtocolEncoderTest extends ProtocolTest {
@Test
public void testEncodeCustom() {
- Xrb28ProtocolEncoder encoder = new Xrb28ProtocolEncoder();
+ Xrb28ProtocolEncoder encoder = new Xrb28ProtocolEncoder(null);
Command command = new Command();
command.setDeviceId(1);
diff --git a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java
index f4a78b5bd..6d49f2516 100644
--- a/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/Xt2400ProtocolDecoderTest.java
@@ -10,6 +10,11 @@ public class Xt2400ProtocolDecoderTest extends ProtocolTest {
Xt2400ProtocolDecoder decoder = new Xt2400ProtocolDecoder(null);
+ decoder.setConfig("\n::wycfg pcr[1] 012801030405060708090a1213c8545657585a656e7d2cd055595d5e71797a7b7c7e7f80818285866b\n");
+
+ verifyPosition(decoder, binary(
+ "010ae85be10801a05d52d590030b12d1f9330be9290a0000ff10008b00000000000000000000000000000000000000000000000000000000000000000000000000003839333032363930323031303036363039373733000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000"));
+
decoder.setConfig("\n:wycfg pcr[0] 001001030406070809570a13121714100565\n");
verifyPosition(decoder, binary(