From 6259ca71bc9c1963e049226a375e058af9dc29c0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Mar 2018 15:01:12 +1300 Subject: Update Java libraries --- pom.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 33b3a8092..81e9d49c2 100644 --- a/pom.xml +++ b/pom.xml @@ -4,14 +4,14 @@ 4.0.0 org.traccar traccar - 3.15-SNAPSHOT + 3.16-SNAPSHOT traccar https://www.traccar.org UTF-8 - 9.2.22.v20170606 + 9.2.24.v20180105 2.25.1 @@ -45,12 +45,12 @@ org.postgresql postgresql - 42.1.4.jre7 + 42.2.1.jre7 com.microsoft.sqlserver mssql-jdbc - 6.2.2.jre7 + 6.4.0.jre7 com.microsoft.azure @@ -61,7 +61,7 @@ com.zaxxer HikariCP-java7 - 2.4.13 + 2.4.13 io.netty @@ -126,7 +126,7 @@ org.liquibase liquibase-core - 3.5.3 + 3.5.5 javax.mail @@ -136,12 +136,12 @@ org.jxls jxls - 2.4.2 + 2.4.4 org.jxls jxls-poi - 1.0.13 + 1.0.14 org.apache.velocity @@ -161,7 +161,7 @@ org.mnode.ical4j ical4j - 2.0.4 + 2.0.5 com.fizzed @@ -187,7 +187,7 @@ maven-checkstyle-plugin - 2.17 + 3.0.0 checkstyle.xml @@ -290,7 +290,7 @@ org.codehaus.mojo extra-enforcer-rules - 1.0-beta-6 + 1.0-beta-7 @@ -320,7 +320,7 @@ maven-pmd-plugin - 3.8 + 3.9.0 -- cgit v1.2.3 From eedfb54d208ba48783cb9d03a775723660e9ff73 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Mar 2018 15:02:21 +1300 Subject: Fix PMD code issues --- src/org/traccar/api/MediaFilter.java | 2 +- src/org/traccar/protocol/FlespiProtocolDecoder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/traccar/api/MediaFilter.java b/src/org/traccar/api/MediaFilter.java index 4685ce05b..25e242b01 100644 --- a/src/org/traccar/api/MediaFilter.java +++ b/src/org/traccar/api/MediaFilter.java @@ -43,7 +43,7 @@ public class MediaFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletResponse httpResponse = ((HttpServletResponse) response); + HttpServletResponse httpResponse = (HttpServletResponse) response; try { HttpSession session = ((HttpServletRequest) request).getSession(false); Long userId = null; diff --git a/src/org/traccar/protocol/FlespiProtocolDecoder.java b/src/org/traccar/protocol/FlespiProtocolDecoder.java index be0e4a07f..526e10fa2 100644 --- a/src/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/org/traccar/protocol/FlespiProtocolDecoder.java @@ -123,7 +123,7 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { return true; case "din": case "dout": - position.set((name.equals("din") ? Position.KEY_INPUT : Position.KEY_OUTPUT), + position.set(name.equals("din") ? Position.KEY_INPUT : Position.KEY_OUTPUT, ((JsonNumber) value).intValue()); return true; case "gps.vehicle.mileage": -- cgit v1.2.3 From 37058629a3b39da810baeef92f70a6a5693d0f33 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Mar 2018 15:05:23 +1300 Subject: Update Traccar version --- setup/traccar.iss | 2 +- swagger.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/traccar.iss b/setup/traccar.iss index 96cd5fdc0..1d6501d31 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=3.15 +AppVersion=3.16 DefaultDirName={pf}\Traccar AlwaysRestart=yes OutputBaseFilename=traccar-setup diff --git a/swagger.json b/swagger.json index 265e7bfd5..e6c242a3e 100644 --- a/swagger.json +++ b/swagger.json @@ -1,7 +1,7 @@ { "swagger": "2.0", "info": { - "version": "3.15", + "version": "3.16", "title": "traccar" }, "host": "demo.traccar.org", -- cgit v1.2.3 From 4d7c36cbd2ec7f6e7d971f4de013603d4cb80d0e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Mar 2018 15:30:28 +1300 Subject: Fix setup script issues --- setup/setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup/setup.sh b/setup/setup.sh index 39a00d8e8..d2e5b2dec 100755 --- a/setup/setup.sh +++ b/setup/setup.sh @@ -9,7 +9,8 @@ then rm -r ../out rm /opt/traccar/setup.sh chmod -R go+rX /opt/traccar - /opt/traccar/bin/installDaemon.sh + cd /opt/traccar/bin/ + . /opt/traccar/bin/installDaemon.sh else echo 'Java 7 or higher is required' fi -- cgit v1.2.3 From a58b40a49e96f8fc876b88b6b10489f8532893d9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Mar 2018 16:23:06 +1300 Subject: Replace deprecated classes --- pom.xml | 5 +++ src/org/traccar/BaseProtocol.java | 4 +- src/org/traccar/ExtendedObjectDecoder.java | 4 +- src/org/traccar/api/SecurityRequestFilter.java | 4 +- src/org/traccar/api/resource/SessionResource.java | 6 +-- src/org/traccar/helper/DataConverter.java | 47 ++++++++++++++++++++++ src/org/traccar/helper/Hashing.java | 9 ++--- .../traccar/protocol/At2000ProtocolDecoder.java | 4 +- .../traccar/protocol/EelinkProtocolEncoder.java | 4 +- .../traccar/protocol/HuabaoProtocolEncoder.java | 6 +-- .../traccar/protocol/MeiligaoProtocolEncoder.java | 4 +- .../traccar/protocol/RuptelaProtocolDecoder.java | 6 +-- .../traccar/protocol/SigfoxProtocolDecoder.java | 4 +- src/org/traccar/protocol/T800xProtocolEncoder.java | 4 +- src/org/traccar/protocol/WatchProtocolEncoder.java | 4 +- .../traccar/protocol/Xt2400ProtocolDecoder.java | 4 +- test/org/traccar/ProtocolTest.java | 4 +- 17 files changed, 87 insertions(+), 36 deletions(-) create mode 100644 src/org/traccar/helper/DataConverter.java diff --git a/pom.xml b/pom.xml index 81e9d49c2..14de784f3 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,11 @@ joda-time 2.9.9 + + commons-codec + commons-codec + 1.11 + com.h2database h2 diff --git a/src/org/traccar/BaseProtocol.java b/src/org/traccar/BaseProtocol.java index 90b9f21f2..07adbea5e 100644 --- a/src/org/traccar/BaseProtocol.java +++ b/src/org/traccar/BaseProtocol.java @@ -18,9 +18,9 @@ package org.traccar; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.database.ActiveDevice; +import org.traccar.helper.DataConverter; import org.traccar.model.Command; -import javax.xml.bind.DatatypeConverter; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -79,7 +79,7 @@ public abstract class BaseProtocol implements Protocol { if (activeDevice.getChannel().getPipeline().get(StringEncoder.class) != null) { activeDevice.write(data); } else { - activeDevice.write(ChannelBuffers.wrappedBuffer(DatatypeConverter.parseHexBinary(data))); + activeDevice.write(ChannelBuffers.wrappedBuffer(DataConverter.parseHex(data))); } } else { throw new RuntimeException("Command " + command.getType() + " is not supported in protocol " + getName()); diff --git a/src/org/traccar/ExtendedObjectDecoder.java b/src/org/traccar/ExtendedObjectDecoder.java index 268e6f688..75a24212f 100644 --- a/src/org/traccar/ExtendedObjectDecoder.java +++ b/src/org/traccar/ExtendedObjectDecoder.java @@ -23,9 +23,9 @@ import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelUpstreamHandler; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.MessageEvent; +import org.traccar.helper.DataConverter; import org.traccar.model.Position; -import javax.xml.bind.DatatypeConverter; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Collection; @@ -39,7 +39,7 @@ public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler { ChannelBuffer buf = (ChannelBuffer) originalMessage; position.set(Position.KEY_ORIGINAL, ChannelBuffers.hexDump(buf, 0, buf.writerIndex())); } else if (originalMessage instanceof String) { - position.set(Position.KEY_ORIGINAL, DatatypeConverter.printHexBinary( + position.set(Position.KEY_ORIGINAL, DataConverter.printHex( ((String) originalMessage).getBytes(StandardCharsets.US_ASCII))); } } diff --git a/src/org/traccar/api/SecurityRequestFilter.java b/src/org/traccar/api/SecurityRequestFilter.java index 7024bdbc9..aace9f705 100644 --- a/src/org/traccar/api/SecurityRequestFilter.java +++ b/src/org/traccar/api/SecurityRequestFilter.java @@ -17,6 +17,7 @@ package org.traccar.api; import org.traccar.Context; import org.traccar.api.resource.SessionResource; +import org.traccar.helper.DataConverter; import org.traccar.helper.Log; import org.traccar.model.User; @@ -28,7 +29,6 @@ import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; -import javax.xml.bind.DatatypeConverter; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.sql.SQLException; @@ -43,7 +43,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { public static String[] decodeBasicAuth(String auth) { auth = auth.replaceFirst("[B|b]asic ", ""); - byte[] decodedBytes = DatatypeConverter.parseBase64Binary(auth); + byte[] decodedBytes = DataConverter.parseBase64(auth); if (decodedBytes != null && decodedBytes.length > 0) { return new String(decodedBytes, StandardCharsets.US_ASCII).split(":", 2); } diff --git a/src/org/traccar/api/resource/SessionResource.java b/src/org/traccar/api/resource/SessionResource.java index 2a0bd4364..fd331c766 100644 --- a/src/org/traccar/api/resource/SessionResource.java +++ b/src/org/traccar/api/resource/SessionResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.helper.DataConverter; import org.traccar.helper.LogAction; import org.traccar.model.User; @@ -34,7 +35,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import javax.xml.bind.DatatypeConverter; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; @@ -63,11 +63,11 @@ public class SessionResource extends BaseResource { if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals(USER_COOKIE_KEY)) { - byte[] emailBytes = DatatypeConverter.parseBase64Binary( + byte[] emailBytes = DataConverter.parseBase64( URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII.name())); email = new String(emailBytes, StandardCharsets.UTF_8); } else if (cookie.getName().equals(PASS_COOKIE_KEY)) { - byte[] passwordBytes = DatatypeConverter.parseBase64Binary( + byte[] passwordBytes = DataConverter.parseBase64( URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII.name())); password = new String(passwordBytes, StandardCharsets.UTF_8); } diff --git a/src/org/traccar/helper/DataConverter.java b/src/org/traccar/helper/DataConverter.java new file mode 100644 index 000000000..7abd4ae93 --- /dev/null +++ b/src/org/traccar/helper/DataConverter.java @@ -0,0 +1,47 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.helper; + +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.Hex; + +public final class DataConverter { + + private DataConverter() { + } + + public static byte[] parseHex(String string) { + try { + return Hex.decodeHex(string); + } catch (DecoderException e) { + throw new RuntimeException(e); + } + } + + public static String printHex(byte[] data) { + return Hex.encodeHexString(data); + } + + public static byte[] parseBase64(String string) { + return Base64.decodeBase64(string); + } + + public static String printBase64(byte[] data) { + return Base64.encodeBase64String(data); + } + +} diff --git a/src/org/traccar/helper/Hashing.java b/src/org/traccar/helper/Hashing.java index 3fcc124fa..e91310eda 100644 --- a/src/org/traccar/helper/Hashing.java +++ b/src/org/traccar/helper/Hashing.java @@ -17,7 +17,6 @@ package org.traccar.helper; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; -import javax.xml.bind.DatatypeConverter; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; @@ -75,13 +74,13 @@ public final class Hashing { RANDOM.nextBytes(salt); byte[] hash = function(password.toCharArray(), salt); return new HashingResult( - DatatypeConverter.printHexBinary(hash), - DatatypeConverter.printHexBinary(salt)); + DataConverter.printHex(hash), + DataConverter.printHex(salt)); } public static boolean validatePassword(String password, String hashHex, String saltHex) { - byte[] hash = DatatypeConverter.parseHexBinary(hashHex); - byte[] salt = DatatypeConverter.parseHexBinary(saltHex); + byte[] hash = DataConverter.parseHex(hashHex); + byte[] salt = DataConverter.parseHex(saltHex); return slowEquals(hash, function(password.toCharArray(), salt)); } diff --git a/src/org/traccar/protocol/At2000ProtocolDecoder.java b/src/org/traccar/protocol/At2000ProtocolDecoder.java index 06d80c497..e0f2b4278 100644 --- a/src/org/traccar/protocol/At2000ProtocolDecoder.java +++ b/src/org/traccar/protocol/At2000ProtocolDecoder.java @@ -20,13 +20,13 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.DataConverter; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; -import javax.xml.bind.DatatypeConverter; import java.net.SocketAddress; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; @@ -84,7 +84,7 @@ public class At2000ProtocolDecoder extends BaseProtocolDecoder { IvParameterSpec ivSpec = new IvParameterSpec(iv); SecretKeySpec keySpec = new SecretKeySpec( - DatatypeConverter.parseHexBinary("000102030405060708090a0b0c0d0e0f"), "AES"); + DataConverter.parseHex("000102030405060708090a0b0c0d0e0f"), "AES"); cipher = Cipher.getInstance("AES/CBC/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); diff --git a/src/org/traccar/protocol/EelinkProtocolEncoder.java b/src/org/traccar/protocol/EelinkProtocolEncoder.java index 76865a039..4d2d86e68 100644 --- a/src/org/traccar/protocol/EelinkProtocolEncoder.java +++ b/src/org/traccar/protocol/EelinkProtocolEncoder.java @@ -18,10 +18,10 @@ package org.traccar.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.DataConverter; import org.traccar.helper.Log; import org.traccar.model.Command; -import javax.xml.bind.DatatypeConverter; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; @@ -47,7 +47,7 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder { ChannelBuffer buf = ChannelBuffers.dynamicBuffer(); if (connectionless) { - buf.writeBytes(ChannelBuffers.wrappedBuffer(DatatypeConverter.parseHexBinary('0' + uniqueId))); + buf.writeBytes(ChannelBuffers.wrappedBuffer(DataConverter.parseHex('0' + uniqueId))); } buf.writeByte(0x67); diff --git a/src/org/traccar/protocol/HuabaoProtocolEncoder.java b/src/org/traccar/protocol/HuabaoProtocolEncoder.java index 7d6f0510d..d1889bf5e 100644 --- a/src/org/traccar/protocol/HuabaoProtocolEncoder.java +++ b/src/org/traccar/protocol/HuabaoProtocolEncoder.java @@ -18,10 +18,10 @@ package org.traccar.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.DataConverter; import org.traccar.helper.Log; import org.traccar.model.Command; -import javax.xml.bind.DatatypeConverter; import java.text.SimpleDateFormat; import java.util.Date; @@ -31,10 +31,10 @@ public class HuabaoProtocolEncoder extends BaseProtocolEncoder { protected Object encodeCommand(Command command) { ChannelBuffer id = ChannelBuffers.wrappedBuffer( - DatatypeConverter.parseHexBinary(getUniqueId(command.getDeviceId()))); + DataConverter.parseHex(getUniqueId(command.getDeviceId()))); ChannelBuffer data = ChannelBuffers.dynamicBuffer(); - byte[] time = DatatypeConverter.parseHexBinary(new SimpleDateFormat("yyMMddHHmmss").format(new Date())); + byte[] time = DataConverter.parseHex(new SimpleDateFormat("yyMMddHHmmss").format(new Date())); switch (command.getType()) { case Command.TYPE_ENGINE_STOP: diff --git a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java index 2e0a1e84c..340d947e3 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -19,10 +19,10 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.traccar.BaseProtocolEncoder; import org.traccar.helper.Checksum; +import org.traccar.helper.DataConverter; import org.traccar.helper.Log; import org.traccar.model.Command; -import javax.xml.bind.DatatypeConverter; import java.nio.charset.StandardCharsets; import java.util.TimeZone; @@ -44,7 +44,7 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { buf.writeShort(2 + 2 + 7 + 2 + content.readableBytes() + 2 + 2); // message length - buf.writeBytes(DatatypeConverter.parseHexBinary((getUniqueId(deviceId) + "FFFFFFFFFFFFFF").substring(0, 14))); + buf.writeBytes(DataConverter.parseHex((getUniqueId(deviceId) + "FFFFFFFFFFFFFF").substring(0, 14))); buf.writeShort(type); diff --git a/src/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/org/traccar/protocol/RuptelaProtocolDecoder.java index 87ee8246a..7b11cc5c3 100644 --- a/src/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -20,10 +20,10 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.DataConverter; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; -import javax.xml.bind.DatatypeConverter; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; @@ -196,7 +196,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { } if (channel != null) { - channel.write(ChannelBuffers.wrappedBuffer(DatatypeConverter.parseHexBinary("0002640113bc"))); + channel.write(ChannelBuffers.wrappedBuffer(DataConverter.parseHex("0002640113bc"))); } return positions; @@ -229,7 +229,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { } if (channel != null) { - channel.write(ChannelBuffers.wrappedBuffer(DatatypeConverter.parseHexBinary("00026d01c4a4"))); + channel.write(ChannelBuffers.wrappedBuffer(DataConverter.parseHex("00026d01c4a4"))); } return positions; diff --git a/src/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/org/traccar/protocol/SigfoxProtocolDecoder.java index 65ab2cc55..b454e00fa 100644 --- a/src/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -22,12 +22,12 @@ import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.HttpResponseStatus; import org.traccar.BaseHttpProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.DataConverter; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import javax.json.Json; import javax.json.JsonObject; -import javax.xml.bind.DatatypeConverter; import java.io.StringReader; import java.net.SocketAddress; import java.net.URLDecoder; @@ -61,7 +61,7 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { position.setTime(new Date(json.getInt("time") * 1000L)); ChannelBuffer buf = ChannelBuffers.wrappedBuffer( - ByteOrder.LITTLE_ENDIAN, DatatypeConverter.parseHexBinary(json.getString("data"))); + ByteOrder.LITTLE_ENDIAN, DataConverter.parseHex(json.getString("data"))); int type = buf.readUnsignedByte() >> 4; if (type == 0) { diff --git a/src/org/traccar/protocol/T800xProtocolEncoder.java b/src/org/traccar/protocol/T800xProtocolEncoder.java index 6ed5dbccd..038a5e51a 100644 --- a/src/org/traccar/protocol/T800xProtocolEncoder.java +++ b/src/org/traccar/protocol/T800xProtocolEncoder.java @@ -18,10 +18,10 @@ package org.traccar.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.DataConverter; import org.traccar.helper.Log; import org.traccar.model.Command; -import javax.xml.bind.DatatypeConverter; import java.nio.charset.StandardCharsets; public class T800xProtocolEncoder extends BaseProtocolEncoder { @@ -39,7 +39,7 @@ public class T800xProtocolEncoder extends BaseProtocolEncoder { buf.writeByte(T800xProtocolDecoder.MSG_COMMAND); buf.writeShort(7 + 8 + 1 + content.length()); buf.writeShort(1); // serial number - buf.writeBytes(DatatypeConverter.parseHexBinary("0" + getUniqueId(command.getDeviceId()))); + buf.writeBytes(DataConverter.parseHex("0" + getUniqueId(command.getDeviceId()))); buf.writeByte(MODE_SETTING); buf.writeBytes(content.getBytes(StandardCharsets.US_ASCII)); diff --git a/src/org/traccar/protocol/WatchProtocolEncoder.java b/src/org/traccar/protocol/WatchProtocolEncoder.java index d2d3b52d1..5206fbf10 100644 --- a/src/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/org/traccar/protocol/WatchProtocolEncoder.java @@ -16,10 +16,10 @@ package org.traccar.protocol; import org.traccar.StringProtocolEncoder; +import org.traccar.helper.DataConverter; import org.traccar.helper.Log; import org.traccar.model.Command; -import javax.xml.bind.DatatypeConverter; import java.nio.charset.StandardCharsets; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; @@ -68,7 +68,7 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin } private String getBinaryData(Command command) { - byte[] data = DatatypeConverter.parseHexBinary(command.getString(Command.KEY_DATA)); + byte[] data = DataConverter.parseHex(command.getString(Command.KEY_DATA)); int encodedLength = data.length; for (byte b : data) { diff --git a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java index 72be473c1..1be943e98 100644 --- a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -20,10 +20,10 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.helper.DataConverter; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; -import javax.xml.bind.DatatypeConverter; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; @@ -95,7 +95,7 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { Pattern pattern = Pattern.compile(":wycfg pcr\\[\\d+\\] ([0-9a-fA-F]{2})[0-9a-fA-F]{2}([0-9a-fA-F]+)"); Matcher matcher = pattern.matcher(configString); while (matcher.find()) { - formats.put(Short.parseShort(matcher.group(1), 16), DatatypeConverter.parseHexBinary(matcher.group(2))); + formats.put(Short.parseShort(matcher.group(1), 16), DataConverter.parseHex(matcher.group(2))); } } diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index e67b53aa8..75a98000b 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -5,11 +5,11 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.handler.codec.http.DefaultHttpRequest; import org.jboss.netty.handler.codec.http.HttpMethod; import org.jboss.netty.handler.codec.http.HttpVersion; +import org.traccar.helper.DataConverter; import org.traccar.model.CellTower; import org.traccar.model.Command; import org.traccar.model.Position; -import javax.xml.bind.DatatypeConverter; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.text.DateFormat; @@ -56,7 +56,7 @@ public class ProtocolTest extends BaseTest { protected ChannelBuffer binary(ByteOrder endianness, String... data) { return ChannelBuffers.wrappedBuffer( - endianness, DatatypeConverter.parseHexBinary(concatenateStrings(data))); + endianness, DataConverter.parseHex(concatenateStrings(data))); } protected String text(String... data) { -- cgit v1.2.3 From 0f63a6fc8388deebb4c5f4b0bbd506d48c941053 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 10 Mar 2018 17:32:11 +1300 Subject: Update submodule commit --- traccar-web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/traccar-web b/traccar-web index f08f6fa4b..464aa58c4 160000 --- a/traccar-web +++ b/traccar-web @@ -1 +1 @@ -Subproject commit f08f6fa4b20f003dd624656746a49237bbff2441 +Subproject commit 464aa58c49ac5e04d419a68b6ee5bcf9d0c36798 -- cgit v1.2.3 From 755874d6e42a68178db75d9037785fc8271382a1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 11 Mar 2018 08:56:53 +1300 Subject: Fix setup script issue (fix #3804) --- setup/setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/setup.sh b/setup/setup.sh index d2e5b2dec..51a139dd1 100755 --- a/setup/setup.sh +++ b/setup/setup.sh @@ -10,7 +10,7 @@ then rm /opt/traccar/setup.sh chmod -R go+rX /opt/traccar cd /opt/traccar/bin/ - . /opt/traccar/bin/installDaemon.sh + /opt/traccar/bin/installDaemon.sh else echo 'Java 7 or higher is required' fi -- cgit v1.2.3 From 8874b4bf69f38ef94d70bef2a8e4d52e0845fa77 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Mar 2018 00:51:46 +1300 Subject: Support STEPP 3 FALCOM messages --- src/org/traccar/protocol/T55ProtocolDecoder.java | 8 +++++--- test/org/traccar/protocol/T55ProtocolDecoderTest.java | 6 ++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java index dbc467993..be3cb5f67 100644 --- a/src/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/org/traccar/protocol/T55ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -250,9 +250,11 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { } else if (sentence.startsWith("$PCPTI")) { getDeviceSession(channel, remoteAddress, sentence.substring(7, sentence.indexOf(",", 7))); } else if (sentence.startsWith("IMEI")) { - getDeviceSession(channel, remoteAddress, sentence.substring(5, sentence.length())); + getDeviceSession(channel, remoteAddress, sentence.substring(5)); + } else if (sentence.startsWith("$IMEI")) { + getDeviceSession(channel, remoteAddress, sentence.substring(6)); } else if (sentence.startsWith("$GPFID")) { - deviceSession = getDeviceSession(channel, remoteAddress, sentence.substring(7, sentence.length())); + deviceSession = getDeviceSession(channel, remoteAddress, sentence.substring(7)); if (deviceSession != null && position != null) { Position position = this.position; position.setDeviceId(deviceSession.getDeviceId()); diff --git a/test/org/traccar/protocol/T55ProtocolDecoderTest.java b/test/org/traccar/protocol/T55ProtocolDecoderTest.java index 7f60a1807..ec699f111 100644 --- a/test/org/traccar/protocol/T55ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/T55ProtocolDecoderTest.java @@ -10,12 +10,18 @@ public class T55ProtocolDecoderTest extends ProtocolTest { T55ProtocolDecoder decoder = new T55ProtocolDecoder(new T55Protocol()); + verifyNull(decoder, text( + "$IMEI=355797031609284")); + verifyNull(decoder, text( "086415031C20")); verifyNull(decoder, text( "358244017671308")); + verifyPosition(decoder, text( + "$GPRMC,192350.000,V,0000.0000,N,00000.0000,E,,,110318,,*12")); + verifyPosition(decoder, text( "$GPRMC,073446.000,A,1255.5125,N,07738.2948,E,0.00,0.53,080316,D*71,11,865733027593268,1,090,086,123,456,789,987,12345")); -- cgit v1.2.3 From d5c79363d91f6ae8594fe2cdde447c7efefaa798 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Mar 2018 02:58:34 +1300 Subject: Support Lantrix T1700 TAIP protocol --- src/org/traccar/protocol/TaipProtocolDecoder.java | 72 ++++++++++++++-------- .../traccar/protocol/TaipProtocolDecoderTest.java | 3 + 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index 9555d19e9..a7aa9dd96 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,16 +62,23 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { .number("(ddd)") // speed .number("(ddd)") // course .groupBegin() + .number("([023])") // fix mode + .number("xx") // data age + .number("(xx)") // input + .number("(dd)") // event + .number("(dd)") // hdop + .or() + .groupBegin() .number("(xx)") // input .number("(xx)") // satellites .number("(ddd)") // battery .number("(x{8})") // odometer .number("[01]") // gps power .groupBegin() - .number("[23]") // fix mode + .number("([023])") // fix mode .number("(dd)") // pdop .number("dd") // satellites - .number("xxxx") // seconds from last + .number("xxxx") // data age .number("[01]") // modem power .number("[0-5]") // gsm status .number("(dd)") // rssi @@ -81,6 +88,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { .number("xx") // seconds from last .groupEnd("?") .groupEnd("?") + .groupEnd() .any() .compile(); @@ -116,6 +124,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); + Boolean valid = null; Integer event = null; if (parser.hasNext(3)) { @@ -129,27 +138,6 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { event = parser.nextInt(); } - if (event != null) { - switch (event) { - case 22: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 23: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 24: - position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); - break; - case 26: - case 28: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - default: - position.set(Position.KEY_EVENT, event); - break; - } - } - if (parser.hasNext(6)) { position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); } @@ -166,6 +154,15 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble(0))); position.setCourse(parser.nextDouble(0)); + if (parser.hasNext(4)) { + valid = parser.nextInt() > 0; + int input = parser.nextHexInt(); + position.set(Position.KEY_IGNITION, BitUtil.check(input, 7)); + position.set(Position.KEY_INPUT, input); + event = parser.nextInt(); + position.set(Position.KEY_HDOP, parser.nextInt()); + } + if (parser.hasNext(4)) { position.set(Position.KEY_INPUT, parser.nextHexInt(0)); position.set(Position.KEY_SATELLITES, parser.nextHexInt(0)); @@ -174,13 +171,35 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext(4)) { + valid = parser.nextInt() > 0; position.set(Position.KEY_PDOP, parser.nextInt()); position.set(Position.KEY_RSSI, parser.nextInt()); position.set(Position.PREFIX_TEMP + 1, parser.nextInt() * 0.01); position.set(Position.PREFIX_TEMP + 2, parser.nextInt() * 0.01); } - position.setValid(true); + position.setValid(valid != null ? valid : true); + + if (event != null) { + position.set(Position.KEY_EVENT, event); + switch (event) { + case 22: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 23: + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 24: + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + break; + case 26: + case 28: + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + default: + break; + } + } String[] attributes = null; beginIndex = sentence.indexOf(';'); @@ -250,14 +269,13 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { if (deviceSession != null) { if (channel != null) { if (messageIndex != null) { - String response = ">ACK;" + messageIndex + ";ID=" + uniqueId + ";*"; + String response = ">ACK;ID=" + uniqueId + ";" + messageIndex + ";*"; response += String.format("%02X", Checksum.xor(response)) + "<"; channel.write(response, remoteAddress); } else { channel.write(uniqueId, remoteAddress); } } - return position; } diff --git a/test/org/traccar/protocol/TaipProtocolDecoderTest.java b/test/org/traccar/protocol/TaipProtocolDecoderTest.java index a92e82498..264724ce9 100644 --- a/test/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TaipProtocolDecoderTest extends ProtocolTest { TaipProtocolDecoder decoder = new TaipProtocolDecoder(new TaipProtocol()); + verifyPosition(decoder, text( + ">RGP211217112154-2748332-058946350000000FF7F2100;ID=AA01;#0002;*2D<")); + verifyPosition(decoder, text( ">RCV12270218010247-3471349-058400030002057F001200020A1D013010600001509+0000FF+0000FF;#1DE2;ID=7196;*03<")); -- cgit v1.2.3 From 4f3cd9dae285cfbd0ff541911381c08f50b59435 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Mar 2018 04:56:12 +1300 Subject: Implement Castelcom fuel cut commands --- src/org/traccar/protocol/CastelProtocol.java | 8 ++- .../traccar/protocol/CastelProtocolDecoder.java | 1 + .../traccar/protocol/CastelProtocolEncoder.java | 73 ++++++++++++++++++++++ .../protocol/CastelProtocolEncoderTest.java | 22 +++++++ 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/org/traccar/protocol/CastelProtocolEncoder.java create mode 100644 test/org/traccar/protocol/CastelProtocolEncoderTest.java diff --git a/src/org/traccar/protocol/CastelProtocol.java b/src/org/traccar/protocol/CastelProtocol.java index db9df0674..d5ba5cd55 100644 --- a/src/org/traccar/protocol/CastelProtocol.java +++ b/src/org/traccar/protocol/CastelProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; +import org.traccar.model.Command; import java.nio.ByteOrder; import java.util.List; @@ -29,6 +30,9 @@ public class CastelProtocol extends BaseProtocol { public CastelProtocol() { super("castel"); + setSupportedDataCommands( + Command.TYPE_ENGINE_STOP, + Command.TYPE_ENGINE_RESUME); } @Override @@ -37,6 +41,7 @@ public class CastelProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2, -4, 0)); + pipeline.addLast("objectEncoder", new CastelProtocolEncoder()); pipeline.addLast("objectDecoder", new CastelProtocolDecoder(CastelProtocol.this)); } }; @@ -46,6 +51,7 @@ public class CastelProtocol extends BaseProtocol { server = new TrackerServer(new ConnectionlessBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("objectEncoder", new CastelProtocolEncoder()); pipeline.addLast("objectDecoder", new CastelProtocolDecoder(CastelProtocol.this)); } }; diff --git a/src/org/traccar/protocol/CastelProtocolDecoder.java b/src/org/traccar/protocol/CastelProtocolDecoder.java index ebd3d202c..44a5e213c 100644 --- a/src/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/org/traccar/protocol/CastelProtocolDecoder.java @@ -96,6 +96,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { public static final short MSG_CC_LOGIN = 0x4001; public static final short MSG_CC_LOGIN_RESPONSE = (short) 0x8001; public static final short MSG_CC_HEARTBEAT = 0x4206; + public static final short MSG_CC_PETROL_CONTROL = 0x4583; public static final short MSG_CC_HEARTBEAT_RESPONSE = (short) 0x8206; private Position readPosition(DeviceSession deviceSession, ChannelBuffer buf) { diff --git a/src/org/traccar/protocol/CastelProtocolEncoder.java b/src/org/traccar/protocol/CastelProtocolEncoder.java new file mode 100644 index 000000000..d69fc62cf --- /dev/null +++ b/src/org/traccar/protocol/CastelProtocolEncoder.java @@ -0,0 +1,73 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.traccar.BaseProtocolEncoder; +import org.traccar.Context; +import org.traccar.helper.Checksum; +import org.traccar.helper.Log; +import org.traccar.model.Command; + +import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; + +public class CastelProtocolEncoder extends BaseProtocolEncoder { + + private ChannelBuffer encodeContent(long deviceId, int type, ChannelBuffer content) { + ChannelBuffer buf = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + String uniqueId = Context.getIdentityManager().getById(deviceId).getUniqueId(); + + buf.writeByte('@'); + buf.writeByte('@'); + + buf.writeShort(2 + 2 + 1 + 20 + content.readableBytes()); // length + + buf.writeByte(4); // protocol version + + buf.writeBytes(uniqueId.getBytes(StandardCharsets.US_ASCII)); + buf.writeZero(20 - uniqueId.length()); + + buf.writeShort(type); + buf.writeBytes(content); + + buf.writeShort(Checksum.crc16(Checksum.CRC16_X25, buf.toByteBuffer())); + + buf.writeByte('\r'); + buf.writeByte('\n'); + + return buf; + } + + @Override + protected Object encodeCommand(Command command) { + ChannelBuffer content = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); + switch (command.getType()) { + case Command.TYPE_ENGINE_STOP: + content.writeByte(1); + return encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content); + case Command.TYPE_ENGINE_RESUME: + content.writeByte(0); + return encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content); + default: + Log.warning(new UnsupportedOperationException(command.getType())); + break; + } + return null; + } + +} diff --git a/test/org/traccar/protocol/CastelProtocolEncoderTest.java b/test/org/traccar/protocol/CastelProtocolEncoderTest.java new file mode 100644 index 000000000..6e519363f --- /dev/null +++ b/test/org/traccar/protocol/CastelProtocolEncoderTest.java @@ -0,0 +1,22 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; +import org.traccar.model.Command; + +public class CastelProtocolEncoderTest extends ProtocolTest { + + @Test + public void testEncode() throws Exception { + + CastelProtocolEncoder encoder = new CastelProtocolEncoder(); + + Command command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_ENGINE_STOP); + + verifyCommand(encoder, command, binary("40401a00043132333435363738393031323334350000000000834501c7280d0a")); + + } + +} -- cgit v1.2.3 From d8bbc2b6e8c1e7447f3e317747982b3c6362c66d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Mar 2018 05:21:58 +1300 Subject: Add new OBD PID parameters --- src/org/traccar/helper/ObdDecoder.java | 31 +++++++++------------- .../protocol/CastelProtocolDecoderTest.java | 3 +++ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/org/traccar/helper/ObdDecoder.java b/src/org/traccar/helper/ObdDecoder.java index 4bc3bcdfb..1bdcce352 100644 --- a/src/org/traccar/helper/ObdDecoder.java +++ b/src/org/traccar/helper/ObdDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,15 +29,6 @@ public final class ObdDecoder { private static final int MODE_FREEZE_FRAME = 0x02; private static final int MODE_CODES = 0x03; - private static final int PID_ENGINE_LOAD = 0x04; - private static final int PID_COOLANT_TEMPERATURE = 0x05; - private static final int PID_ENGINE_RPM = 0x0C; - private static final int PID_VEHICLE_SPEED = 0x0D; - private static final int PID_THROTTLE_POSITION = 0x11; - private static final int PID_MIL_DISTANCE = 0x21; - private static final int PID_FUEL_LEVEL = 0x2F; - private static final int PID_DISTANCE_CLEARED = 0x31; - public static Map.Entry decode(int mode, String value) { switch (mode) { case MODE_CURRENT: @@ -86,21 +77,25 @@ public final class ObdDecoder { public static Map.Entry decodeData(int pid, int value, boolean convert) { switch (pid) { - case PID_ENGINE_LOAD: + case 0x04: return createEntry(Position.KEY_ENGINE_LOAD, convert ? value * 100 / 255 : value); - case PID_COOLANT_TEMPERATURE: + case 0x05: return createEntry(Position.KEY_COOLANT_TEMP, convert ? value - 40 : value); - case PID_ENGINE_RPM: + case 0x0B: + return createEntry("mapIntake", value); + case 0x0C: return createEntry(Position.KEY_RPM, convert ? value / 4 : value); - case PID_VEHICLE_SPEED: + case 0x0D: return createEntry(Position.KEY_OBD_SPEED, value); - case PID_THROTTLE_POSITION: + case 0x0F: + return createEntry("intakeTemp", convert ? value - 40 : value); + case 0x11: return createEntry(Position.KEY_THROTTLE, convert ? value * 100 / 255 : value); - case PID_MIL_DISTANCE: + case 0x21: return createEntry("milDistance", value); - case PID_FUEL_LEVEL: + case 0x2F: return createEntry(Position.KEY_FUEL_LEVEL, convert ? value * 100 / 255 : value); - case PID_DISTANCE_CLEARED: + case 0x31: return createEntry("clearedDistance", value); default: return null; diff --git a/test/org/traccar/protocol/CastelProtocolDecoderTest.java b/test/org/traccar/protocol/CastelProtocolDecoderTest.java index 2dccf4a0a..cb44087a1 100644 --- a/test/org/traccar/protocol/CastelProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CastelProtocolDecoderTest.java @@ -12,6 +12,9 @@ public class CastelProtocolDecoderTest extends ProtocolTest { CastelProtocolDecoder decoder = new CastelProtocolDecoder(new CastelProtocol()); + verifyAttributes(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "4040560004323133474c3230313630303033363400000000004002a122a05a5423a05abe0f2a000000000007f1f90014000000040001640011170003001e000505210b210c210d210f2101062b58ef02001a25950d0a")); + verifyAttributes(decoder, binary(ByteOrder.LITTLE_ENDIAN, "404057000431303031313132353239393837000000000000004002C1F06952F0F169529C9111000000000069830000470000000400036401014C01030078000505210C210D210F21102101073BE8030064280AEB930D0A")); -- cgit v1.2.3 From b2ab0b471591494523b12e5f1810a481b2cd1a65 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Mar 2018 06:44:27 +1300 Subject: Cautela NMEA conversion protocol --- setup/default.xml | 1 + src/org/traccar/protocol/CautelaProtocol.java | 47 +++++++++++++ .../traccar/protocol/CautelaProtocolDecoder.java | 77 ++++++++++++++++++++++ .../protocol/CautelaProtocolDecoderTest.java | 18 +++++ 4 files changed, 143 insertions(+) create mode 100644 src/org/traccar/protocol/CautelaProtocol.java create mode 100644 src/org/traccar/protocol/CautelaProtocolDecoder.java create mode 100644 test/org/traccar/protocol/CautelaProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 6be2c08e3..81a3cd128 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -228,5 +228,6 @@ 5157 5158 5159 + 5160 diff --git a/src/org/traccar/protocol/CautelaProtocol.java b/src/org/traccar/protocol/CautelaProtocol.java new file mode 100644 index 000000000..89ab7a1d0 --- /dev/null +++ b/src/org/traccar/protocol/CautelaProtocol.java @@ -0,0 +1,47 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class CautelaProtocol extends BaseProtocol { + + public CautelaProtocol() { + super("cautela"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new CautelaProtocolDecoder(CautelaProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/CautelaProtocolDecoder.java b/src/org/traccar/protocol/CautelaProtocolDecoder.java new file mode 100644 index 000000000..94ba35c91 --- /dev/null +++ b/src/org/traccar/protocol/CautelaProtocolDecoder.java @@ -0,0 +1,77 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class CautelaProtocolDecoder extends BaseProtocolDecoder { + + public CautelaProtocolDecoder(CautelaProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .number("(d+),") // type + .number("(d+),") // imei + .number("(dd),(dd),(dd),") // date (ddmmyy) + .number("(-?d+.d+),") // longitude + .number("(-?d+.d+),") // latitude + .number("(dd)(dd),") // time (hhmm) + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + String type = parser.next(); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateBuilder dateBuilder = new DateBuilder(); + dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); + + position.setValid(true); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); + + dateBuilder.setHour(parser.nextInt()).setMinute(parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + return position; + } + +} diff --git a/test/org/traccar/protocol/CautelaProtocolDecoderTest.java b/test/org/traccar/protocol/CautelaProtocolDecoderTest.java new file mode 100644 index 000000000..4fd785c9f --- /dev/null +++ b/test/org/traccar/protocol/CautelaProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class CautelaProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + CautelaProtocolDecoder decoder = new CautelaProtocolDecoder(new CautelaProtocol()); + + verifyPosition(decoder, text( + "20,010907000000,14,02,18,16.816667,96.166667,1325,S,*2E")); + + } + +} -- cgit v1.2.3 From 51785ed622057269459c3abf6ba85d0001d71e71 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 12 Mar 2018 06:49:06 +1300 Subject: Fix Cautela coordinates decoding --- src/org/traccar/protocol/CautelaProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/traccar/protocol/CautelaProtocolDecoder.java b/src/org/traccar/protocol/CautelaProtocolDecoder.java index 94ba35c91..d7bf4fb51 100644 --- a/src/org/traccar/protocol/CautelaProtocolDecoder.java +++ b/src/org/traccar/protocol/CautelaProtocolDecoder.java @@ -36,8 +36,8 @@ public class CautelaProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // type .number("(d+),") // imei .number("(dd),(dd),(dd),") // date (ddmmyy) - .number("(-?d+.d+),") // longitude .number("(-?d+.d+),") // latitude + .number("(-?d+.d+),") // longitude .number("(dd)(dd),") // time (hhmm) .any() .compile(); @@ -65,8 +65,8 @@ public class CautelaProtocolDecoder extends BaseProtocolDecoder { dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setValid(true); - position.setLongitude(parser.nextDouble()); position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); dateBuilder.setHour(parser.nextInt()).setMinute(parser.nextInt()); position.setTime(dateBuilder.getDate()); -- cgit v1.2.3 From 708c38728c8c250ba7205cd7fd77182895d1ea07 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 13 Mar 2018 00:57:51 +1300 Subject: Remove missing GL200 parameters (fix #3805) --- .../traccar/protocol/Gl200TextProtocolDecoder.java | 96 +++++++++++++--------- 1 file changed, 57 insertions(+), 39 deletions(-) diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index c47764989..362fc38c7 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -429,8 +429,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { parser.next(); // odometer or external power - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); - position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + position.set(Position.KEY_CHARGE, parser.nextInt() == 1); position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); @@ -444,7 +444,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, parser.nextDateTime()); - position.set(Position.KEY_INDEX, parser.nextHexInt(0)); + position.set(Position.KEY_INDEX, parser.nextHexInt()); return position; } @@ -457,8 +457,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } position.set("deviceType", parser.next()); - position.set(Position.KEY_VERSION_FW, parser.nextHexInt(0)); - position.set(Position.KEY_VERSION_HW, parser.nextHexInt(0)); + position.set(Position.KEY_VERSION_FW, parser.nextHexInt()); + position.set(Position.KEY_VERSION_HW, parser.nextHexInt()); getLastLocation(position, parser.nextDateTime()); @@ -466,8 +466,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } private void decodeLocation(Position position, Parser parser) { - int hdop = parser.nextInt(0); - position.setValid(hdop > 0); + Integer hdop = parser.nextInt(); + position.setValid(hdop == null || hdop > 0); position.set(Position.KEY_HDOP, hdop); position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); @@ -476,25 +476,27 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext(8)) { position.setValid(true); - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); position.setTime(parser.nextDateTime()); } else { getLastLocation(position, null); } if (parser.hasNext(6)) { - int mcc = parser.nextInt(0); - int mnc = parser.nextInt(0); + int mcc = parser.nextInt(); + int mnc = parser.nextInt(); if (parser.hasNext(2)) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(0), parser.nextInt(0)))); + position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(), parser.nextInt()))); } if (parser.hasNext(2)) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(0), parser.nextHexInt(0)))); + position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt()))); } } - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + if (parser.hasNext()) { + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); + } } private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { @@ -509,16 +511,22 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); position.set(Position.KEY_FUEL_CONSUMPTION, parser.next()); position.set("dtcsClearedDistance", parser.nextInt()); - position.set("odbConnect", parser.nextInt(0) == 1); + if (parser.hasNext()) { + position.set("odbConnect", parser.nextInt() == 1); + } position.set("dtcsNumber", parser.nextInt()); position.set("dtcsCodes", parser.next()); position.set(Position.KEY_THROTTLE, parser.nextInt()); position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - position.set(Position.KEY_OBD_ODOMETER, parser.nextInt(0) * 1000); + if (parser.hasNext()) { + position.set(Position.KEY_OBD_ODOMETER, parser.nextInt() * 1000); + } decodeLocation(position, parser); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + if (parser.hasNext()) { + position.set(Position.KEY_OBD_ODOMETER, (int) (parser.nextDouble() * 1000)); + } decodeDeviceTime(position, parser); @@ -649,14 +657,14 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { private void decodeStatus(Position position, Parser parser) { if (parser.hasNext(3)) { - int ignition = parser.nextHexInt(0); + int ignition = parser.nextHexInt(); if (BitUtil.check(ignition, 4)) { position.set(Position.KEY_IGNITION, false); } else if (BitUtil.check(ignition, 5)) { position.set(Position.KEY_IGNITION, true); } - position.set(Position.KEY_INPUT, parser.nextHexInt(0)); - position.set(Position.KEY_OUTPUT, parser.nextHexInt(0)); + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.KEY_OUTPUT, parser.nextHexInt()); } } @@ -674,7 +682,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { LinkedList positions = new LinkedList<>(); String vin = parser.next(); - int power = parser.nextInt(0); + Integer power = parser.nextInt(); Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); while (itemParser.find()) { @@ -692,14 +700,18 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); - if (power > 10) { + if (power != null && power > 10) { position.set(Position.KEY_POWER, power * 0.001); // only on some devices } - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + if (parser.hasNext()) { + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); + } position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + if (parser.hasNext()) { + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); + } position.set(Position.KEY_HOURS, parser.next()); position.set(Position.PREFIX_ADC + 1, parser.next()); position.set(Position.PREFIX_ADC + 2, parser.next()); @@ -734,7 +746,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { LinkedList positions = new LinkedList<>(); - int power = parser.nextInt(0); + Integer power = parser.nextInt(); Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); while (itemParser.find()) { @@ -750,8 +762,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); - position.set(Position.KEY_POWER, power * 0.001); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + if (power != null) { + position.set(Position.KEY_POWER, power * 0.001); + } + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); position.set(Position.KEY_HOURS, parser.next()); position.set(Position.PREFIX_ADC + 1, parser.next()); position.set(Position.PREFIX_ADC + 2, parser.next()); @@ -813,7 +827,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); position.set(Position.KEY_HOURS, parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); decodeDeviceTime(position, parser); @@ -831,7 +845,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); decodeDeviceTime(position, parser); @@ -849,7 +863,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { Network network = new Network(); - parser.nextInt(0); // count + parser.nextInt(); // count Matcher matcher = Pattern.compile("([0-9a-fA-F]{12}),(-?\\d+),,,,").matcher(parser.next()); while (matcher.find()) { String mac = matcher.group(1).replaceAll("(..)", "$1:"); @@ -859,7 +873,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.setNetwork(network); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); return position; } @@ -897,7 +911,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return null; } - int reportType = parser.nextInt(0); + int reportType = parser.nextInt(); if (type.equals("NMR")) { position.set(Position.KEY_MOTION, reportType == 1); } else if (type.equals("SOS")) { @@ -906,10 +920,14 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { decodeLocation(position, parser); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); + if (parser.hasNext()) { + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); + } + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + if (parser.hasNext()) { + position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); + } decodeDeviceTime(position, parser); @@ -927,7 +945,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return null; } - int hdop = parser.nextInt(0); + int hdop = parser.nextInt(); position.setValid(hdop > 0); position.set(Position.KEY_HDOP, hdop); @@ -936,8 +954,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.setAltitude(parser.nextDouble(0)); if (parser.hasNext(2)) { - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); + position.setLongitude(parser.nextDouble()); + position.setLatitude(parser.nextDouble()); } else { getLastLocation(position, null); } @@ -948,7 +966,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext(4)) { position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); + parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt()))); } decodeDeviceTime(position, parser); -- cgit v1.2.3 From 612547f1b0cae5e0ba39359ed349799f2a87ca2f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 13 Mar 2018 01:00:09 +1300 Subject: Handle missing temperature (fix #3806) --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 4 +++- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 362fc38c7..ff300d429 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -787,7 +787,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { for (int i = 1; i <= deviceCount; i++) { index += 1; // id index += 1; // type - position.set(Position.PREFIX_TEMP + i, (short) Integer.parseInt(data[index++], 16) * 0.0625); + if (!data[index++].isEmpty()) { + position.set(Position.PREFIX_TEMP + i, (short) Integer.parseInt(data[index - 1], 16) * 0.0625); + } } } diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 9ec67273c..56a159768 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyPositions(decoder, buffer( + "+RESP:GTERI,310603,863286023345490,,00000002,,10,1,2,0.3,0,155.7,8.000000,52.000000,20171215213040,0262,0002,1450,9F13,00,1130.3,00539:27:19,,,110000,2,1,28FFD5239115034E,1,,20171215213041,27C7$")); + verifyPositions(decoder, buffer( "+RESP:GTERI,250C02,868789023691057,,00000019,,10,1,1,0.0,196,2258.0,-99.201807,19.559242,20180214002957,0334,0003,235B,7F8D,00,6786.7,,,,100,110000,1,0394,1,4,100.0,100.0,20180214003006,C72B$")); -- cgit v1.2.3 From ca72b34c7d7dcf2d6b20b87ce3f8cc26ac7911a1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 13 Mar 2018 01:55:23 +1300 Subject: Fix CT-03 init response --- src/org/traccar/protocol/WatchProtocolDecoder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index 1dd07a3f7..495803ab6 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -171,7 +171,11 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { buf.readerIndex(contentIndex + 1); } - if (type.equals("LK")) { + if (type.equals("INIT")) { + + sendResponse(channel, manufacturer, id, index, "INIT,1"); + + } else if (type.equals("LK")) { sendResponse(channel, manufacturer, id, index, "LK"); -- cgit v1.2.3 From 7264149967d2bee385afcab6a8435d4b77141a49 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 13 Mar 2018 02:05:48 +1300 Subject: Fix method length issue --- src/org/traccar/protocol/WatchProtocolDecoder.java | 69 +++++++++++----------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index 495803ab6..12ec3bd3f 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -97,8 +97,38 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { return null; } - private void decodeTail(Position position, String data) { - String[] values = data.split(","); + private Position decodePosition(DeviceSession deviceSession, String data) { + + Parser parser = new Parser(PATTERN_POSITION, data); + if (!parser.matches()) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); + position.setCourse(parser.nextDouble(0)); + position.setAltitude(parser.nextDouble(0)); + + position.set(Position.KEY_SATELLITES, parser.nextInt(0)); + position.set(Position.KEY_RSSI, parser.nextInt(0)); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); + + position.set(Position.KEY_STEPS, parser.nextInt(0)); + + int status = parser.nextHexInt(0); + position.set(Position.KEY_ALARM, decodeAlarm(status)); + if (BitUtil.check(status, 4)) { + position.set(Position.KEY_MOTION, true); + } + + String[] values = parser.next().split(","); int index = 0; Network network = new Network(); @@ -127,6 +157,8 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { if (network.getCellTowers() != null || network.getWifiAccessPoints() != null) { position.setNetwork(network); } + + return position; } @Override @@ -200,38 +232,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, manufacturer, id, index, "AL"); } - Parser parser = new Parser(PATTERN_POSITION, buf.toString(StandardCharsets.US_ASCII)); - if (!parser.matches()) { - return null; - } - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - position.setValid(parser.next().equals("A")); - position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - - position.set(Position.KEY_STEPS, parser.nextInt(0)); - - int status = parser.nextHexInt(0); - position.set(Position.KEY_ALARM, decodeAlarm(status)); - if (BitUtil.check(status, 4)) { - position.set(Position.KEY_MOTION, true); - } - - decodeTail(position, parser.next()); - - return position; + return decodePosition(deviceSession, buf.toString(StandardCharsets.US_ASCII)); } else if (type.equals("TKQ")) { -- cgit v1.2.3 From 709b02703cfd974bc17127f3e4683b9d96249eb9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 13 Mar 2018 06:40:50 +1300 Subject: Support ATrack fuel sensor --- src/org/traccar/protocol/AtrackProtocolDecoder.java | 17 +++++++++++++++-- .../org/traccar/protocol/AtrackProtocolDecoderTest.java | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java index 236b608d6..8138f0fcb 100644 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; import java.util.regex.Pattern; public class AtrackProtocolDecoder extends BaseProtocolDecoder { @@ -43,6 +44,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { private static final int MIN_DATA_LENGTH = 40; private boolean longDate; + private boolean decimalFuel; private boolean custom; private String form; @@ -52,6 +54,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { super(protocol); longDate = Context.getConfig().getBoolean(getProtocolName() + ".longDate"); + decimalFuel = Context.getConfig().getBoolean(getProtocolName() + ".decimalFuel"); custom = Context.getConfig().getBoolean(getProtocolName() + ".custom"); form = Context.getConfig().getString(getProtocolName() + ".form"); @@ -330,7 +333,17 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, buf.readShort() * 0.1); position.set(Position.PREFIX_TEMP + 2, buf.readShort() * 0.1); - position.set("message", readString(buf)); + String message = readString(buf); + if (message != null && !message.isEmpty()) { + Pattern pattern = Pattern.compile("FULS:F=(\\p{XDigit}+) t=(\\p{XDigit}+) N=(\\p{XDigit}+)"); + Matcher matcher = pattern.matcher(message); + if (matcher.find()) { + int value = Integer.parseInt(matcher.group(3), decimalFuel ? 10 : 16); + position.set(Position.KEY_FUEL_LEVEL, value * 0.1); + } else { + position.set("message", message); + } + } if (custom) { String form = this.form; diff --git a/test/org/traccar/protocol/AtrackProtocolDecoderTest.java b/test/org/traccar/protocol/AtrackProtocolDecoderTest.java index b5271f511..bd606c320 100644 --- a/test/org/traccar/protocol/AtrackProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AtrackProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class AtrackProtocolDecoderTest extends ProtocolTest { AtrackProtocolDecoder decoder = new AtrackProtocolDecoder(new AtrackProtocol()); + verifyPositions(decoder, binary( + "4050b5ed004a2523000310c83713f8c05a88b43e5a88b43f5a88b43f021e0ad5fffdc0a800f3020003059100080000000000000007d007d046554c533a463d3230393120743d3137204e3d3039303100")); + verifyAttributes(decoder, buffer( "$INFO=358683066267395,AX7,Rev.0.61 Build.1624,358683066267395,466924131626767,89886920041316267670,144,0,9,1,12,1,0\r\n")); -- cgit v1.2.3 From bb49f1e2c38e23860e87e1801edc456f30165d5f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 13 Mar 2018 16:46:42 +1300 Subject: DM G50 hello message response --- src/org/traccar/protocol/DmtProtocolDecoder.java | 15 ++++++++++----- test/org/traccar/protocol/DmtProtocolDecoderTest.java | 3 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/org/traccar/protocol/DmtProtocolDecoder.java b/src/org/traccar/protocol/DmtProtocolDecoder.java index 74db5a6f7..3739253f0 100644 --- a/src/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/org/traccar/protocol/DmtProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,8 +70,7 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(2); // header int type = buf.readUnsignedByte(); - - buf.readUnsignedShort(); // length + int length = buf.readUnsignedShort(); if (type == MSG_HELLO) { @@ -81,8 +80,14 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); - response.writeInt((int) ((System.currentTimeMillis() - 1356998400000L) / 1000)); - response.writeInt(deviceSession != null ? 0 : 1); // flags + if (length == 51) { + response.writeByte(0); // reserved + response.writeInt(0); // reserved + } else { + response.writeInt((int) ((System.currentTimeMillis() - 1356998400000L) / 1000)); + response.writeInt(deviceSession != null ? 0 : 1); // flags + } + sendResponse(channel, MSG_HELLO_RESPONSE, response); } else if (type == MSG_COMMIT) { diff --git a/test/org/traccar/protocol/DmtProtocolDecoderTest.java b/test/org/traccar/protocol/DmtProtocolDecoderTest.java index 2575d77ed..a83dcafe2 100644 --- a/test/org/traccar/protocol/DmtProtocolDecoderTest.java +++ b/test/org/traccar/protocol/DmtProtocolDecoderTest.java @@ -12,6 +12,9 @@ public class DmtProtocolDecoderTest extends ProtocolTest { DmtProtocolDecoder decoder = new DmtProtocolDecoder(new DmtProtocol()); + verifyNull(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "0255003300001b00003335333232393032373533393235310038393931353030303030303030313330343539340000000403041910780603")); + verifyNull(decoder, binary(ByteOrder.LITTLE_ENDIAN, "025500310038f90100333533333233303831363639373330003839363130313835303031383234383434363330002202010900000000")); -- cgit v1.2.3 From 2a30c9de983223a3af1070543975165ceb0710f9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Mar 2018 05:27:23 +1300 Subject: Option to ignore duplicate alarms --- setup/default.xml | 1 + src/org/traccar/events/AlertEventHandler.java | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/setup/default.xml b/setup/default.xml index 81a3cd128..8701ddc4c 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -19,6 +19,7 @@ ./logs/tracker-server.log true + true true ./media diff --git a/src/org/traccar/events/AlertEventHandler.java b/src/org/traccar/events/AlertEventHandler.java index 003ccb662..7db371c70 100644 --- a/src/org/traccar/events/AlertEventHandler.java +++ b/src/org/traccar/events/AlertEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,18 +19,34 @@ import java.util.Collections; import java.util.Map; import org.traccar.BaseEventHandler; +import org.traccar.Context; import org.traccar.model.Event; import org.traccar.model.Position; public class AlertEventHandler extends BaseEventHandler { + private final boolean ignoreDuplicateAlerts; + + public AlertEventHandler() { + ignoreDuplicateAlerts = Context.getConfig().getBoolean("event.ignoreDuplicateAlerts"); + } + @Override protected Map analyzePosition(Position position) { Object alarm = position.getAttributes().get(Position.KEY_ALARM); if (alarm != null) { - Event event = new Event(Event.TYPE_ALARM, position.getDeviceId(), position.getId()); - event.set(Position.KEY_ALARM, (String) alarm); - return Collections.singletonMap(event, position); + boolean ignoreAlert = false; + if (ignoreDuplicateAlerts) { + Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); + if (lastPosition != null && alarm.equals(lastPosition.getAttributes().get(Position.KEY_ALARM))) { + ignoreAlert = true; + } + } + if (!ignoreAlert) { + Event event = new Event(Event.TYPE_ALARM, position.getDeviceId(), position.getId()); + event.set(Position.KEY_ALARM, (String) alarm); + return Collections.singletonMap(event, position); + } } return null; } -- cgit v1.2.3 From 4ae3297dde98d292cd0c87141440f94312459b65 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Mar 2018 06:08:04 +1300 Subject: Include Teltonika RDIF if not zero --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 7 +++++-- test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 9e249247a..d2069e6c9 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -133,7 +133,10 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); break; case 78: - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", readValue(buf, length, false))); + long driverUniqueId = readValue(buf, length, false); + if (driverUniqueId != 0) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", driverUniqueId)); + } break; case 80: position.set("workMode", readValue(buf, length, false)); diff --git a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index c4fae52ff..d62eef4a0 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyPositions(decoder, false, binary( + "0000000000000035080100000161f37c50500020de5ba60ef11450000000000000000006040100b300b400ef000109002000014e0000000000000000010000be52")); + verifyPositions(decoder, false, binary( "000000000000008c08010000013feb55ff74000f0ea850209a690000940000120000001e09010002000300040016014703f0001504c8000c0900730a00460b00501300464306d7440000b5000bb60007422e9f180000cd0386ce000107c700000000f10000601a46000001344800000bb84900000bb84a00000bb84c00000000024e0000000000000000cf00000000000000000100003fca")); -- cgit v1.2.3 From 0aa78a779f764cad80d54d4710118212d52402c1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Mar 2018 07:09:40 +1300 Subject: Decode Xirgo events and alarms --- src/org/traccar/model/Position.java | 1 + src/org/traccar/protocol/XirgoProtocolDecoder.java | 65 +++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 981c2292f..49e3231c3 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -115,6 +115,7 @@ public class Position extends Message { public static final String ALARM_GPS_ANTENNA_CUT = "gpsAntennaCut"; public static final String ALARM_ACCIDENT = "accident"; public static final String ALARM_TOW = "tow"; + public static final String ALARM_IDLE = "idle"; public static final String ALARM_ACCELERATION = "hardAcceleration"; public static final String ALARM_BRAKING = "hardBraking"; public static final String ALARM_CORNERING = "hardCornering"; diff --git a/src/org/traccar/protocol/XirgoProtocolDecoder.java b/src/org/traccar/protocol/XirgoProtocolDecoder.java index 10dd298fd..1a753cb3e 100644 --- a/src/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/org/traccar/protocol/XirgoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -95,6 +95,67 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private void decodeEvent(Position position, int event) { + + position.set(Position.KEY_EVENT, event); + + switch (event) { + case 4005: + position.set(Position.KEY_CHARGE, false); + break; + case 6002: + position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + break; + case 6006: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 6007: + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + break; + case 6008: + position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + break; + case 6009: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; + case 6010: + position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); + break; + case 6011: + case 6013: + position.set(Position.KEY_IGNITION, true); + break; + case 6012: + case 6014: + position.set(Position.KEY_IGNITION, false); + break; + case 6016: + position.set(Position.KEY_ALARM, Position.ALARM_IDLE); + break; + case 6017: + position.set(Position.KEY_ALARM, Position.ALARM_TOW); + break; + case 6030: + case 6071: + position.set(Position.KEY_MOTION, true); + break; + case 6031: + position.set(Position.KEY_MOTION, false); + break; + case 6032: + position.set(Position.KEY_ALARM, Position.ALARM_PARKING); + break; + case 6090: + position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + break; + case 6091: + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + break; + default: + break; + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -133,7 +194,7 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { } position.setDeviceId(deviceSession.getDeviceId()); - position.set(Position.KEY_EVENT, parser.next()); + decodeEvent(position, parser.nextInt()); position.setTime(parser.nextDateTime()); -- cgit v1.2.3 From b04758893af970e7954571771c1e6c136d472f20 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Mar 2018 07:11:35 +1300 Subject: Additional Xirgo events --- src/org/traccar/protocol/XirgoProtocolDecoder.java | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/org/traccar/protocol/XirgoProtocolDecoder.java b/src/org/traccar/protocol/XirgoProtocolDecoder.java index 1a753cb3e..461503af1 100644 --- a/src/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/org/traccar/protocol/XirgoProtocolDecoder.java @@ -100,6 +100,18 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_EVENT, event); switch (event) { + case 4001: + case 4003: + case 6011: + case 6013: + position.set(Position.KEY_IGNITION, true); + break; + case 4002: + case 4004: + case 6012: + case 6014: + position.set(Position.KEY_IGNITION, false); + break; case 4005: position.set(Position.KEY_CHARGE, false); break; @@ -121,14 +133,6 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { case 6010: position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); break; - case 6011: - case 6013: - position.set(Position.KEY_IGNITION, true); - break; - case 6012: - case 6014: - position.set(Position.KEY_IGNITION, false); - break; case 6016: position.set(Position.KEY_ALARM, Position.ALARM_IDLE); break; -- cgit v1.2.3 From 7c7002e3b001b9e4f8f9a00f9a14dff87b5c9862 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 14 Mar 2018 07:58:15 +1300 Subject: Support Watch blood pressure --- src/org/traccar/protocol/WatchProtocolDecoder.java | 14 +++++++++----- test/org/traccar/protocol/WatchProtocolDecoderTest.java | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index 12ec3bd3f..325f2efd9 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -238,7 +238,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, manufacturer, id, index, "TKQ"); - } else if (type.equals("PULSE") || type.equals("heart")) { + } else if (type.equals("PULSE") || type.equals("heart") || type.equals("bphrt")) { if (buf.readable()) { @@ -247,10 +247,14 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, new Date()); - position.setValid(false); - String pulse = buf.toString(StandardCharsets.US_ASCII); - position.set("pulse", pulse); - position.set(Position.KEY_RESULT, pulse); + String[] values = buf.toString(StandardCharsets.US_ASCII).split(","); + int valueIndex = 0; + + if (type.equals("bphrt")) { + position.set("pressureLow", values[valueIndex++]); + position.set("pressureHigh", values[valueIndex++]); + } + position.set("pulse", values[valueIndex]); return position; diff --git a/test/org/traccar/protocol/WatchProtocolDecoderTest.java b/test/org/traccar/protocol/WatchProtocolDecoderTest.java index 657cb0640..6ba04bf8e 100644 --- a/test/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/test/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { WatchProtocolDecoder decoder = new WatchProtocolDecoder(new WatchProtocol()); + verifyAttributes(decoder, buffer( + "[3G*4700609403*0013*bphrt,120,79,73,,,,]")); + 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]")); -- cgit v1.2.3 From 9863a0a0c9e3f796679f0fda3ab1048a3bac2475 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 15 Mar 2018 06:05:03 +1300 Subject: Fix Watch pressure decoding --- src/org/traccar/protocol/WatchProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index 325f2efd9..c57279296 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -251,8 +251,8 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { int valueIndex = 0; if (type.equals("bphrt")) { - position.set("pressureLow", values[valueIndex++]); position.set("pressureHigh", values[valueIndex++]); + position.set("pressureLow", values[valueIndex++]); } position.set("pulse", values[valueIndex]); -- cgit v1.2.3 From 27a155908f6f460dde1a52c949cea7ee6625976a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 15 Mar 2018 16:05:10 +1300 Subject: Support DM G50 fixed 64 byte messages --- src/org/traccar/protocol/DmtProtocolDecoder.java | 262 +++++++++++++-------- .../traccar/protocol/DmtProtocolDecoderTest.java | 6 + 2 files changed, 175 insertions(+), 93 deletions(-) diff --git a/src/org/traccar/protocol/DmtProtocolDecoder.java b/src/org/traccar/protocol/DmtProtocolDecoder.java index 3739253f0..204d81820 100644 --- a/src/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/org/traccar/protocol/DmtProtocolDecoder.java @@ -21,6 +21,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; +import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -42,6 +43,7 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_DATA_RECORD = 0x04; public static final int MSG_COMMIT = 0x05; public static final int MSG_COMMIT_RESPONSE = 0x06; + public static final int MSG_DATA_RECORD_64 = 0x10; public static final int MSG_CANNED_REQUEST_1 = 0x14; public static final int MSG_CANNED_RESPONSE_1 = 0x15; @@ -61,6 +63,169 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { } } + private List decodeFixed64(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + List positions = new LinkedList<>(); + + while (buf.readableBytes() >= 64) { + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + buf.readByte(); // type + + position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + + long time = buf.readUnsignedInt(); + position.setTime(new DateBuilder() + .setYear((int) (2000 + (time & 0x3F))) + .setMonth((int) (time >> 6) & 0xF) + .setDay((int) (time >> 10) & 0x1F) + .setHour((int) (time >> 15) & 0x1F) + .setMinute((int) (time >> 20) & 0x3F) + .setSecond((int) (time >> 26) & 0x3F) + .getDate()); + + position.setLatitude(buf.readInt() * 0.0000001); + position.setLongitude(buf.readInt() * 0.0000001); + position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort())); + position.setCourse(buf.readUnsignedByte() * 2); + position.setAltitude(buf.readShort()); + + buf.readUnsignedShort(); // position accuracy + buf.readUnsignedByte(); // speed accuracy + + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + + position.setValid(BitUtil.check(buf.readByte(), 0)); + + position.set(Position.KEY_INPUT, buf.readUnsignedInt()); + position.set(Position.KEY_OUTPUT, buf.readUnsignedShort()); + + for (int i = 1; i <= 5; i++) { + position.set(Position.PREFIX_ADC + i, buf.readShort()); + } + + position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); + + buf.readShort(); // accelerometer x + buf.readShort(); // accelerometer y + buf.readShort(); // accelerometer z + + buf.skipBytes(8); // device id + + position.set(Position.KEY_PDOP, buf.readUnsignedShort() * 0.01); + + buf.skipBytes(2); // reserved + + buf.readUnsignedShort(); // checksum + + positions.add(position); + } + + return positions; + } + + private List decodeStandard(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + List positions = new LinkedList<>(); + + while (buf.readable()) { + int recordEnd = buf.readerIndex() + buf.readUnsignedShort(); + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + + position.setDeviceTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); // since 1 Jan 2013 + + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + + while (buf.readerIndex() < recordEnd) { + + int fieldId = buf.readUnsignedByte(); + int fieldLength = buf.readUnsignedByte(); + int fieldEnd = buf.readerIndex() + (fieldLength == 255 ? buf.readUnsignedShort() : fieldLength); + + if (fieldId == 0) { + + position.setFixTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); + position.setLatitude(buf.readInt() * 0.0000001); + position.setLongitude(buf.readInt() * 0.0000001); + position.setAltitude(buf.readShort()); + position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort())); + + buf.readUnsignedByte(); // speed accuracy + + position.setCourse(buf.readUnsignedByte() * 2); + + position.set(Position.KEY_PDOP, buf.readUnsignedByte() * 0.1); + + position.setAccuracy(buf.readUnsignedByte()); + position.setValid(buf.readUnsignedByte() != 0); + + } else if (fieldId == 2) { + + int input = buf.readInt(); + int output = buf.readUnsignedShort(); + int status = buf.readUnsignedShort(); + + position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); + + position.set(Position.KEY_INPUT, input); + position.set(Position.KEY_OUTPUT, output); + position.set(Position.KEY_STATUS, status); + + } else if (fieldId == 6) { + + while (buf.readerIndex() < fieldEnd) { + switch (buf.readUnsignedByte()) { + case 1: + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + break; + case 2: + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + break; + case 3: + position.set(Position.KEY_DEVICE_TEMP, buf.readShort() * 0.01); + break; + case 4: + position.set(Position.KEY_RSSI, buf.readUnsignedShort()); + break; + case 5: + position.set("solarPower", buf.readUnsignedShort() * 0.001); + break; + default: + break; + } + } + + } + + buf.readerIndex(fieldEnd); + + } + + if (position.getFixTime() == null) { + getLastLocation(position, position.getDeviceTime()); + } + + positions.add(position); + } + + return positions; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -106,102 +271,13 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, MSG_CANNED_RESPONSE_2, null); - } else if (type == MSG_DATA_RECORD) { - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } - - List positions = new LinkedList<>(); - - while (buf.readable()) { - - int recordEnd = buf.readerIndex() + buf.readUnsignedShort(); - - Position position = new Position(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_INDEX, buf.readUnsignedInt()); - - position.setDeviceTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); // since 1 Jan 2013 - - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - - while (buf.readerIndex() < recordEnd) { + } else if (type == MSG_DATA_RECORD_64) { - int fieldId = buf.readUnsignedByte(); - int fieldLength = buf.readUnsignedByte(); - int fieldEnd = buf.readerIndex() + (fieldLength == 255 ? buf.readUnsignedShort() : fieldLength); + return decodeFixed64(channel, remoteAddress, buf); - if (fieldId == 0) { - - position.setFixTime(new Date(1356998400000L + buf.readUnsignedInt() * 1000)); - position.setLatitude(buf.readInt() * 0.0000001); - position.setLongitude(buf.readInt() * 0.0000001); - position.setAltitude(buf.readShort()); - position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort())); - - buf.readUnsignedByte(); // speed accuracy - - position.setCourse(buf.readUnsignedByte() * 2); - - position.set(Position.KEY_PDOP, buf.readUnsignedByte() * 0.1); - - position.setAccuracy(buf.readUnsignedByte()); - position.setValid(buf.readUnsignedByte() != 0); - - } else if (fieldId == 2) { - - int input = buf.readInt(); - int output = buf.readUnsignedShort(); - int status = buf.readUnsignedShort(); - - position.set(Position.KEY_IGNITION, BitUtil.check(input, 0)); - - position.set(Position.KEY_INPUT, input); - position.set(Position.KEY_OUTPUT, output); - position.set(Position.KEY_STATUS, status); - - } else if (fieldId == 6) { - - while (buf.readerIndex() < fieldEnd) { - switch (buf.readUnsignedByte()) { - case 1: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); - break; - case 2: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - break; - case 3: - position.set(Position.KEY_DEVICE_TEMP, buf.readShort() * 0.01); - break; - case 4: - position.set(Position.KEY_RSSI, buf.readUnsignedShort()); - break; - case 5: - position.set("solarPower", buf.readUnsignedShort() * 0.001); - break; - default: - break; - } - } - - } - - buf.readerIndex(fieldEnd); - - } - - if (position.getFixTime() == null) { - getLastLocation(position, position.getDeviceTime()); - } - - positions.add(position); - - } + } else if (type == MSG_DATA_RECORD) { - return positions; + return decodeStandard(channel, remoteAddress, buf); } diff --git a/test/org/traccar/protocol/DmtProtocolDecoderTest.java b/test/org/traccar/protocol/DmtProtocolDecoderTest.java index a83dcafe2..2e386c48e 100644 --- a/test/org/traccar/protocol/DmtProtocolDecoderTest.java +++ b/test/org/traccar/protocol/DmtProtocolDecoderTest.java @@ -15,6 +15,12 @@ public class DmtProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary(ByteOrder.LITTLE_ENDIAN, "0255003300001b00003335333232393032373533393235310038393931353030303030303030313330343539340000000403041910780603")); + verifyPositions(decoder, false, binary(ByteOrder.LITTLE_ENDIAN, + "02551040000eaca40d00d2b8e562c51f9912f39a6bee00007e420091090903070100000000008b1065360000000000007fd401c4fcf2feffffffffffffffffee0000003f1b")); + + verifyPositions(decoder, false, binary(ByteOrder.LITTLE_ENDIAN, + "02551080000eada40d00d2b8e58ac51f9912f39a6bee00007e42007e090709070000000000009010fc330000000000007fc201a0fc04ffffffffffffffffffe5000000c5d00eaea40d00d2b8e58ac51f9912f39a6bee00007e42007e09070207000000000000851008340000000000007fc201a0fc04ff0000000000000000e5000000c96d")); + verifyNull(decoder, binary(ByteOrder.LITTLE_ENDIAN, "025500310038f90100333533333233303831363639373330003839363130313835303031383234383434363330002202010900000000")); -- cgit v1.2.3 From 411f12863460107187f1597b0bfd85627b1b413a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Mar 2018 01:20:29 +1300 Subject: Update Gisgraphy test case --- test/org/traccar/geocoder/GeocoderTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/org/traccar/geocoder/GeocoderTest.java b/test/org/traccar/geocoder/GeocoderTest.java index 1ddc43ad2..8cf6ac524 100644 --- a/test/org/traccar/geocoder/GeocoderTest.java +++ b/test/org/traccar/geocoder/GeocoderTest.java @@ -83,9 +83,9 @@ public class GeocoderTest { public void onFailure(Throwable e) { } }); - assertEquals("Rue du Jardinet, Paris, FR", waitAddress()); + assertEquals("Rue du Jardinet, Paris, Île-de-France, FR", waitAddress()); - assertEquals("Rue du Jardinet, Paris, FR", geocoder.getAddress(48.8530000, 2.3400000, null)); + assertEquals("Rue du Jardinet, Paris, Île-de-France, FR", geocoder.getAddress(48.8530000, 2.3400000, null)); } public void testOpenCage() throws InterruptedException { -- cgit v1.2.3 From 0933f39774235641b1f4bdd1e1402b71bf9be9ed Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Mar 2018 01:24:41 +1300 Subject: Fix DM G50 coordinates decoding --- src/org/traccar/protocol/DmtProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/traccar/protocol/DmtProtocolDecoder.java b/src/org/traccar/protocol/DmtProtocolDecoder.java index 204d81820..30a6ae13a 100644 --- a/src/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/org/traccar/protocol/DmtProtocolDecoder.java @@ -90,8 +90,8 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { .setSecond((int) (time >> 26) & 0x3F) .getDate()); - position.setLatitude(buf.readInt() * 0.0000001); position.setLongitude(buf.readInt() * 0.0000001); + position.setLatitude(buf.readInt() * 0.0000001); position.setSpeed(UnitsConverter.knotsFromCps(buf.readUnsignedShort())); position.setCourse(buf.readUnsignedByte() * 2); position.setAltitude(buf.readShort()); -- cgit v1.2.3 From 34a5b8ceaff6617a8958ce04fb6c7f65d1d19979 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Mar 2018 19:58:26 +1300 Subject: Fix Castel command encoding --- src/org/traccar/protocol/CastelProtocolEncoder.java | 4 ++-- test/org/traccar/protocol/CastelProtocolEncoderTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/org/traccar/protocol/CastelProtocolEncoder.java b/src/org/traccar/protocol/CastelProtocolEncoder.java index d69fc62cf..7ba33ca6d 100644 --- a/src/org/traccar/protocol/CastelProtocolEncoder.java +++ b/src/org/traccar/protocol/CastelProtocolEncoder.java @@ -28,7 +28,7 @@ import java.nio.charset.StandardCharsets; public class CastelProtocolEncoder extends BaseProtocolEncoder { - private ChannelBuffer encodeContent(long deviceId, int type, ChannelBuffer content) { + private ChannelBuffer encodeContent(long deviceId, short type, ChannelBuffer content) { ChannelBuffer buf = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0); String uniqueId = Context.getIdentityManager().getById(deviceId).getUniqueId(); @@ -42,7 +42,7 @@ public class CastelProtocolEncoder extends BaseProtocolEncoder { buf.writeBytes(uniqueId.getBytes(StandardCharsets.US_ASCII)); buf.writeZero(20 - uniqueId.length()); - buf.writeShort(type); + buf.writeShort(ChannelBuffers.swapShort(type)); buf.writeBytes(content); buf.writeShort(Checksum.crc16(Checksum.CRC16_X25, buf.toByteBuffer())); diff --git a/test/org/traccar/protocol/CastelProtocolEncoderTest.java b/test/org/traccar/protocol/CastelProtocolEncoderTest.java index 6e519363f..fc0a92c86 100644 --- a/test/org/traccar/protocol/CastelProtocolEncoderTest.java +++ b/test/org/traccar/protocol/CastelProtocolEncoderTest.java @@ -15,7 +15,7 @@ public class CastelProtocolEncoderTest extends ProtocolTest { command.setDeviceId(1); command.setType(Command.TYPE_ENGINE_STOP); - verifyCommand(encoder, command, binary("40401a00043132333435363738393031323334350000000000834501c7280d0a")); + verifyCommand(encoder, command, binary("40401a00043132333435363738393031323334350000000000458301fe6a0d0a")); } -- cgit v1.2.3 From 38c1ff9bccc1c417a0c2b412271aa7240a3b7db7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 16 Mar 2018 22:57:59 +1300 Subject: Implement Continental RVS protocol --- setup/default.xml | 1 + src/org/traccar/protocol/ContinentalProtocol.java | 43 ++++++++++ .../protocol/ContinentalProtocolDecoder.java | 93 ++++++++++++++++++++++ .../protocol/ContinentalProtocolDecoderTest.java | 25 ++++++ 4 files changed, 162 insertions(+) create mode 100644 src/org/traccar/protocol/ContinentalProtocol.java create mode 100644 src/org/traccar/protocol/ContinentalProtocolDecoder.java create mode 100644 test/org/traccar/protocol/ContinentalProtocolDecoderTest.java diff --git a/setup/default.xml b/setup/default.xml index 8701ddc4c..68465011e 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -230,5 +230,6 @@ 5158 5159 5160 + 5161 diff --git a/src/org/traccar/protocol/ContinentalProtocol.java b/src/org/traccar/protocol/ContinentalProtocol.java new file mode 100644 index 000000000..e2b1226cf --- /dev/null +++ b/src/org/traccar/protocol/ContinentalProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class ContinentalProtocol extends BaseProtocol { + + public ContinentalProtocol() { + super("continental"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 2)); + pipeline.addLast("objectDecoder", new ContinentalProtocolDecoder(ContinentalProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/ContinentalProtocolDecoder.java b/src/org/traccar/protocol/ContinentalProtocolDecoder.java new file mode 100644 index 000000000..2138eb39e --- /dev/null +++ b/src/org/traccar/protocol/ContinentalProtocolDecoder.java @@ -0,0 +1,93 @@ +/* + * Copyright 2018 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.Date; + +public class ContinentalProtocolDecoder extends BaseProtocolDecoder { + + public ContinentalProtocolDecoder(ContinentalProtocol protocol) { + super(protocol); + } + + public static final int MSG_KEEPALIVE = 0x00; + public static final int MSG_STATUS = 0x02; + public static final int MSG_ACK = 0x06; + public static final int MSG_NACK = 0x15; + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + buf.skipBytes(2); // header + buf.readUnsignedShort(); // length + buf.readUnsignedByte(); // software version + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.valueOf(buf.readUnsignedInt())); + if (deviceSession == null) { + return null; + } + + buf.readUnsignedByte(); // product + + int type = buf.readUnsignedByte(); + + if (type == MSG_STATUS) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setFixTime(new Date(buf.readUnsignedInt() * 1000L)); + + buf.readUnsignedByte(); + position.setLatitude(buf.readMedium() / 3600.0); + + buf.readUnsignedByte(); + position.setLongitude(buf.readMedium() / 3600.0); + + position.setCourse(buf.readUnsignedShort()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort())); + + position.setValid(buf.readUnsignedByte() > 0); + + position.setDeviceTime(new Date(buf.readUnsignedInt() * 1000L)); + + position.set(Position.KEY_EVENT, buf.readUnsignedShort()); + position.set(Position.KEY_INPUT, buf.readUnsignedShort()); + position.set(Position.KEY_OUTPUT, buf.readUnsignedShort()); + position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); + position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); + + buf.readUnsignedShort(); // reserved + + return position; + + } + + return null; + } + +} diff --git a/test/org/traccar/protocol/ContinentalProtocolDecoderTest.java b/test/org/traccar/protocol/ContinentalProtocolDecoderTest.java new file mode 100644 index 000000000..fbc7c3219 --- /dev/null +++ b/test/org/traccar/protocol/ContinentalProtocolDecoderTest.java @@ -0,0 +1,25 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class ContinentalProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + ContinentalProtocolDecoder decoder = new ContinentalProtocolDecoder(new ContinentalProtocol()); + + verifyPosition(decoder, binary( + "5356002A1100003039030243A68B5700FEB5AB00FD715F012700000143A68B57000E000000000C2F00000130"), + position("2005-12-19 10:28:39.000", true, -23.49027, -46.55138)); + + verifyPosition(decoder, binary( + "5356002a0d0010a12403025a9ea47f00feb48400fd6e63000c0000015a9ea480000e000100000c000000")); + + verifyPosition(decoder, binary( + "5356002a0d0010a1240302581b944100febed800fd9fa30139001300581c73fa000e000000000d000001")); + + } + +} -- cgit v1.2.3